summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/mstuff2.cc2
-rw-r--r--crawl-ref/source/religion.cc4
-rw-r--r--crawl-ref/source/skills.cc3
-rw-r--r--crawl-ref/source/skills2.cc7
-rw-r--r--stone_soup/crawl-ref/README.crawl_ref18
-rw-r--r--stone_soup/crawl-ref/build_nt.txt41
-rw-r--r--stone_soup/crawl-ref/docs/buglist.txt423
-rw-r--r--stone_soup/crawl-ref/docs/build_nt.txt56
-rw-r--r--stone_soup/crawl-ref/docs/changes.3401860
-rw-r--r--stone_soup/crawl-ref/docs/changes.4003278
-rw-r--r--stone_soup/crawl-ref/docs/crawl.61053
-rw-r--r--stone_soup/crawl-ref/docs/crawl.txt1250
-rw-r--r--stone_soup/crawl-ref/docs/messlog.txt562
-rw-r--r--stone_soup/crawl-ref/docs/todo.txt456
-rw-r--r--stone_soup/crawl-ref/docs/versions.txt782
-rw-r--r--stone_soup/crawl-ref/dolinks.sh8
-rw-r--r--stone_soup/crawl-ref/domake.sh12
-rw-r--r--stone_soup/crawl-ref/init.txt676
-rw-r--r--stone_soup/crawl-ref/licence.txt104
-rw-r--r--stone_soup/crawl-ref/mac/68K_Stub.r144
-rw-r--r--stone_soup/crawl-ref/mac/Crawl.r303
-rw-r--r--stone_soup/crawl-ref/mac/Crawl4.mcpbin211299 -> 0 bytes
-rw-r--r--stone_soup/crawl-ref/mac/Precomp (Common).h75
-rw-r--r--stone_soup/crawl-ref/mac/Precomp (Mac-D).pch++16
-rw-r--r--stone_soup/crawl-ref/mac/Precomp (Mac-R).pch++19
-rw-r--r--stone_soup/crawl-ref/mac/Precomp (Posix-D).pch++17
-rw-r--r--stone_soup/crawl-ref/mac/Precomp (Posix-R).pch++18
-rw-r--r--stone_soup/crawl-ref/macro.txt57
-rw-r--r--stone_soup/crawl-ref/readme.txt151
-rw-r--r--stone_soup/crawl-ref/source/AppHdr.h384
-rw-r--r--stone_soup/crawl-ref/source/Crawl.xcodeproj/project.pbxproj865
-rw-r--r--stone_soup/crawl-ref/source/FixAry.h68
-rw-r--r--stone_soup/crawl-ref/source/FixVec.h133
-rw-r--r--stone_soup/crawl-ref/source/Kills.cc1098
-rw-r--r--stone_soup/crawl-ref/source/Kills.h186
-rw-r--r--stone_soup/crawl-ref/source/MacString.cc199
-rw-r--r--stone_soup/crawl-ref/source/MacString.h71
-rw-r--r--stone_soup/crawl-ref/source/abl-show.cc2164
-rw-r--r--stone_soup/crawl-ref/source/abl-show.h51
-rw-r--r--stone_soup/crawl-ref/source/abyss.cc379
-rw-r--r--stone_soup/crawl-ref/source/abyss.h37
-rw-r--r--stone_soup/crawl-ref/source/acr.cc3201
-rw-r--r--stone_soup/crawl-ref/source/acrawl.gdtbin21643 -> 0 bytes
-rw-r--r--stone_soup/crawl-ref/source/acrawl.gprbin115246 -> 0 bytes
-rw-r--r--stone_soup/crawl-ref/source/beam.cc4520
-rw-r--r--stone_soup/crawl-ref/source/beam.h97
-rw-r--r--stone_soup/crawl-ref/source/chardump.cc1181
-rw-r--r--stone_soup/crawl-ref/source/chardump.h28
-rw-r--r--stone_soup/crawl-ref/source/cloud.cc130
-rw-r--r--stone_soup/crawl-ref/source/cloud.h22
-rw-r--r--stone_soup/crawl-ref/source/clua.cc2301
-rw-r--r--stone_soup/crawl-ref/source/clua.h122
-rw-r--r--stone_soup/crawl-ref/source/command.cc553
-rw-r--r--stone_soup/crawl-ref/source/command.h60
-rw-r--r--stone_soup/crawl-ref/source/crawl.gdtbin6182 -> 0 bytes
-rw-r--r--stone_soup/crawl-ref/source/crawl.gprbin11237 -> 0 bytes
-rw-r--r--stone_soup/crawl-ref/source/debug.cc2136
-rw-r--r--stone_soup/crawl-ref/source/debug.h148
-rw-r--r--stone_soup/crawl-ref/source/decks.cc906
-rw-r--r--stone_soup/crawl-ref/source/decks.h22
-rw-r--r--stone_soup/crawl-ref/source/defines.h208
-rw-r--r--stone_soup/crawl-ref/source/delay.cc559
-rw-r--r--stone_soup/crawl-ref/source/delay.h19
-rw-r--r--stone_soup/crawl-ref/source/describe.cc6799
-rw-r--r--stone_soup/crawl-ref/source/describe.h64
-rw-r--r--stone_soup/crawl-ref/source/direct.cc1503
-rw-r--r--stone_soup/crawl-ref/source/direct.h67
-rw-r--r--stone_soup/crawl-ref/source/dungeon.cc8641
-rw-r--r--stone_soup/crawl-ref/source/dungeon.h53
-rw-r--r--stone_soup/crawl-ref/source/effects.cc1508
-rw-r--r--stone_soup/crawl-ref/source/effects.h92
-rw-r--r--stone_soup/crawl-ref/source/enum.h3719
-rw-r--r--stone_soup/crawl-ref/source/externs.h850
-rw-r--r--stone_soup/crawl-ref/source/fight.cc4041
-rw-r--r--stone_soup/crawl-ref/source/fight.h52
-rw-r--r--stone_soup/crawl-ref/source/files.cc2112
-rw-r--r--stone_soup/crawl-ref/source/files.h92
-rw-r--r--stone_soup/crawl-ref/source/food.cc1379
-rw-r--r--stone_soup/crawl-ref/source/food.h68
-rw-r--r--stone_soup/crawl-ref/source/hiscores.cc1846
-rw-r--r--stone_soup/crawl-ref/source/hiscores.h35
-rw-r--r--stone_soup/crawl-ref/source/initfile.cc1790
-rw-r--r--stone_soup/crawl-ref/source/initfile.h103
-rw-r--r--stone_soup/crawl-ref/source/insult.cc672
-rw-r--r--stone_soup/crawl-ref/source/insult.h11
-rw-r--r--stone_soup/crawl-ref/source/invent.cc1027
-rw-r--r--stone_soup/crawl-ref/source/invent.h93
-rw-r--r--stone_soup/crawl-ref/source/it_use2.cc523
-rw-r--r--stone_soup/crawl-ref/source/it_use2.h43
-rw-r--r--stone_soup/crawl-ref/source/it_use3.cc1067
-rw-r--r--stone_soup/crawl-ref/source/it_use3.h44
-rw-r--r--stone_soup/crawl-ref/source/item_use.cc3289
-rw-r--r--stone_soup/crawl-ref/source/item_use.h136
-rw-r--r--stone_soup/crawl-ref/source/itemname.cc2421
-rw-r--r--stone_soup/crawl-ref/source/itemname.h113
-rw-r--r--stone_soup/crawl-ref/source/itemprop.cc2032
-rw-r--r--stone_soup/crawl-ref/source/itemprop.h142
-rw-r--r--stone_soup/crawl-ref/source/items.cc3070
-rw-r--r--stone_soup/crawl-ref/source/items.h144
-rw-r--r--stone_soup/crawl-ref/source/lev-pand.cc166
-rw-r--r--stone_soup/crawl-ref/source/lev-pand.h30
-rw-r--r--stone_soup/crawl-ref/source/libemx.cc233
-rw-r--r--stone_soup/crawl-ref/source/libemx.h38
-rw-r--r--stone_soup/crawl-ref/source/libmac.cc2116
-rw-r--r--stone_soup/crawl-ref/source/libmac.h86
-rw-r--r--stone_soup/crawl-ref/source/libunix.cc778
-rw-r--r--stone_soup/crawl-ref/source/libunix.h53
-rw-r--r--stone_soup/crawl-ref/source/libutil.cc730
-rw-r--r--stone_soup/crawl-ref/source/libutil.h217
-rw-r--r--stone_soup/crawl-ref/source/libw32c.cc838
-rw-r--r--stone_soup/crawl-ref/source/libw32c.h47
-rw-r--r--stone_soup/crawl-ref/source/lua/base.lua74
-rw-r--r--stone_soup/crawl-ref/source/lua/chnkdata.lua35
-rw-r--r--stone_soup/crawl-ref/source/lua/eat.lua97
-rw-r--r--stone_soup/crawl-ref/source/lua/gearset.lua206
-rw-r--r--stone_soup/crawl-ref/source/lua/gourmand.lua145
-rw-r--r--stone_soup/crawl-ref/source/lua/kills.lua240
-rw-r--r--stone_soup/crawl-ref/source/lua/runrest.lua108
-rw-r--r--stone_soup/crawl-ref/source/lua/safechunk.lua41
-rw-r--r--stone_soup/crawl-ref/source/lua/stash.lua32
-rw-r--r--stone_soup/crawl-ref/source/lua/wield.lua47
-rw-r--r--stone_soup/crawl-ref/source/machdr.h185
-rw-r--r--stone_soup/crawl-ref/source/macro.cc731
-rw-r--r--stone_soup/crawl-ref/source/macro.h63
-rw-r--r--stone_soup/crawl-ref/source/makefile44
-rw-r--r--stone_soup/crawl-ref/source/makefile.bor53
-rw-r--r--stone_soup/crawl-ref/source/makefile.bsd64
-rw-r--r--stone_soup/crawl-ref/source/makefile.dos53
-rw-r--r--stone_soup/crawl-ref/source/makefile.emx53
-rw-r--r--stone_soup/crawl-ref/source/makefile.lnx68
-rw-r--r--stone_soup/crawl-ref/source/makefile.mgw74
-rw-r--r--stone_soup/crawl-ref/source/makefile.obj69
-rw-r--r--stone_soup/crawl-ref/source/makefile.osx61
-rw-r--r--stone_soup/crawl-ref/source/makefile.sgi54
-rw-r--r--stone_soup/crawl-ref/source/makefile.sol68
-rw-r--r--stone_soup/crawl-ref/source/maps.cc3641
-rw-r--r--stone_soup/crawl-ref/source/maps.h25
-rw-r--r--stone_soup/crawl-ref/source/menu.cc501
-rw-r--r--stone_soup/crawl-ref/source/menu.h216
-rw-r--r--stone_soup/crawl-ref/source/message.cc640
-rw-r--r--stone_soup/crawl-ref/source/message.h95
-rw-r--r--stone_soup/crawl-ref/source/misc.cc1962
-rw-r--r--stone_soup/crawl-ref/source/misc.h143
-rw-r--r--stone_soup/crawl-ref/source/misc/header10
-rw-r--r--stone_soup/crawl-ref/source/misc/pfix6.pl312
-rw-r--r--stone_soup/crawl-ref/source/mon-data.h4379
-rw-r--r--stone_soup/crawl-ref/source/mon-pick.cc2827
-rw-r--r--stone_soup/crawl-ref/source/mon-pick.h58
-rw-r--r--stone_soup/crawl-ref/source/mon-spll.h773
-rw-r--r--stone_soup/crawl-ref/source/mon-util.cc2209
-rw-r--r--stone_soup/crawl-ref/source/mon-util.h440
-rw-r--r--stone_soup/crawl-ref/source/monplace.cc1405
-rw-r--r--stone_soup/crawl-ref/source/monplace.h83
-rw-r--r--stone_soup/crawl-ref/source/monspeak.cc2325
-rw-r--r--stone_soup/crawl-ref/source/monspeak.h8
-rw-r--r--stone_soup/crawl-ref/source/monstuff.cc5235
-rw-r--r--stone_soup/crawl-ref/source/monstuff.h151
-rw-r--r--stone_soup/crawl-ref/source/mstuff2.cc1768
-rw-r--r--stone_soup/crawl-ref/source/mstuff2.h101
-rw-r--r--stone_soup/crawl-ref/source/mt19937ar.cc229
-rw-r--r--stone_soup/crawl-ref/source/mt19937ar.h52
-rw-r--r--stone_soup/crawl-ref/source/mutation.cc2328
-rw-r--r--stone_soup/crawl-ref/source/mutation.h73
-rw-r--r--stone_soup/crawl-ref/source/newgame.cc4849
-rw-r--r--stone_soup/crawl-ref/source/newgame.h24
-rw-r--r--stone_soup/crawl-ref/source/ouch.cc1046
-rw-r--r--stone_soup/crawl-ref/source/ouch.h74
-rw-r--r--stone_soup/crawl-ref/source/output.cc818
-rw-r--r--stone_soup/crawl-ref/source/output.h32
-rw-r--r--stone_soup/crawl-ref/source/overmap.cc539
-rw-r--r--stone_soup/crawl-ref/source/overmap.h51
-rw-r--r--stone_soup/crawl-ref/source/player.cc4127
-rw-r--r--stone_soup/crawl-ref/source/player.h459
-rw-r--r--stone_soup/crawl-ref/source/randart.cc1995
-rw-r--r--stone_soup/crawl-ref/source/randart.h111
-rw-r--r--stone_soup/crawl-ref/source/religion.cc2762
-rw-r--r--stone_soup/crawl-ref/source/religion.h33
-rw-r--r--stone_soup/crawl-ref/source/shopping.cc1610
-rw-r--r--stone_soup/crawl-ref/source/shopping.h49
-rw-r--r--stone_soup/crawl-ref/source/skills.cc454
-rw-r--r--stone_soup/crawl-ref/source/skills.h26
-rw-r--r--stone_soup/crawl-ref/source/skills2.cc2366
-rw-r--r--stone_soup/crawl-ref/source/skills2.h97
-rw-r--r--stone_soup/crawl-ref/source/spells1.cc1199
-rw-r--r--stone_soup/crawl-ref/source/spells1.h142
-rw-r--r--stone_soup/crawl-ref/source/spells2.cc1602
-rw-r--r--stone_soup/crawl-ref/source/spells2.h179
-rw-r--r--stone_soup/crawl-ref/source/spells3.cc1093
-rw-r--r--stone_soup/crawl-ref/source/spells3.h142
-rw-r--r--stone_soup/crawl-ref/source/spells4.cc3155
-rw-r--r--stone_soup/crawl-ref/source/spells4.h62
-rw-r--r--stone_soup/crawl-ref/source/spl-book.cc1597
-rw-r--r--stone_soup/crawl-ref/source/spl-book.h68
-rw-r--r--stone_soup/crawl-ref/source/spl-cast.cc3572
-rw-r--r--stone_soup/crawl-ref/source/spl-cast.h49
-rw-r--r--stone_soup/crawl-ref/source/spl-data.h1468
-rw-r--r--stone_soup/crawl-ref/source/spl-util.cc792
-rw-r--r--stone_soup/crawl-ref/source/spl-util.h90
-rw-r--r--stone_soup/crawl-ref/source/stash.cc1607
-rw-r--r--stone_soup/crawl-ref/source/stash.h327
-rw-r--r--stone_soup/crawl-ref/source/stuff.cc1047
-rw-r--r--stone_soup/crawl-ref/source/stuff.h88
-rw-r--r--stone_soup/crawl-ref/source/tags.cc1894
-rw-r--r--stone_soup/crawl-ref/source/tags.h97
-rw-r--r--stone_soup/crawl-ref/source/transfor.cc574
-rw-r--r--stone_soup/crawl-ref/source/transfor.h48
-rw-r--r--stone_soup/crawl-ref/source/travel.cc2928
-rw-r--r--stone_soup/crawl-ref/source/travel.h356
-rw-r--r--stone_soup/crawl-ref/source/unrand.h1138
-rw-r--r--stone_soup/crawl-ref/source/version.h52
-rw-r--r--stone_soup/crawl-ref/source/view.cc4098
-rw-r--r--stone_soup/crawl-ref/source/view.h116
-rw-r--r--stone_soup/crawl-ref/source/winhdr.h70
-rw-r--r--stone_soup/crawl-ref/source/wpn-misc.cc199
-rw-r--r--stone_soup/crawl-ref/source/wpn-misc.h61
215 files changed, 6 insertions, 174296 deletions
diff --git a/crawl-ref/source/mstuff2.cc b/crawl-ref/source/mstuff2.cc
index f514ab8ddd..d4460a0697 100644
--- a/crawl-ref/source/mstuff2.cc
+++ b/crawl-ref/source/mstuff2.cc
@@ -1314,7 +1314,7 @@ bolt mons_spells( int spell_cast, int power )
case MS_POISON_ARROW:
strcpy( beam.beam_name, "poison arrow" );
- beam.damage = dice_def( 4, 5 + power / 4 );
+ beam.damage = dice_def( 4, 5 + power / 12 );
beam.colour = LIGHTGREEN;
beam.type = SYM_MISSILE;
beam.thrower = KILL_MON;
diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc
index 94cef35207..964840f972 100644
--- a/crawl-ref/source/religion.cc
+++ b/crawl-ref/source/religion.cc
@@ -2691,9 +2691,9 @@ void handle_god_time(void)
case GOD_SIF_MUNA:
// [dshaligram] Sif Muna is now very patient - has to be
- // to make up with the new spell training requirements, else
+ // to make up for the new spell training requirements, else
// it's practically impossible to get Master of Arcane status.
- if (one_chance_in(45))
+ if (one_chance_in(60))
lose_piety(1);
if (you.piety < 1)
excommunication();
diff --git a/crawl-ref/source/skills.cc b/crawl-ref/source/skills.cc
index 2c96373bf3..db7fe62372 100644
--- a/crawl-ref/source/skills.cc
+++ b/crawl-ref/source/skills.cc
@@ -418,8 +418,7 @@ static int exercise2( int exsk )
if (exsk == SK_FIGHTING)
calc_hp();
- if (exsk == SK_INVOCATIONS || exsk == SK_EVOCATIONS
- || exsk == SK_SPELLCASTING)
+ if (exsk == SK_INVOCATIONS || exsk == SK_SPELLCASTING)
{
calc_mp();
}
diff --git a/crawl-ref/source/skills2.cc b/crawl-ref/source/skills2.cc
index 6a6f468125..b4a0cbca9f 100644
--- a/crawl-ref/source/skills2.cc
+++ b/crawl-ref/source/skills2.cc
@@ -2178,14 +2178,11 @@ int calc_mp(void)
int spell_extra = (you.experience_level * you.skills[SK_SPELLCASTING]) / 4;
int invoc_extra = (you.experience_level * you.skills[SK_INVOCATIONS]) / 6;
- int evoc_extra = (you.experience_level * you.skills[SK_EVOCATIONS]) / 6;
- if (spell_extra > invoc_extra && spell_extra > evoc_extra)
+ if (spell_extra > invoc_extra)
enp += spell_extra;
- else if (invoc_extra > evoc_extra)
- enp += invoc_extra;
else
- enp += evoc_extra;
+ enp += invoc_extra;
you.max_magic_points = stepdown_value( enp, 9, 18, 45, 100 );
diff --git a/stone_soup/crawl-ref/README.crawl_ref b/stone_soup/crawl-ref/README.crawl_ref
deleted file mode 100644
index e52dd802de..0000000000
--- a/stone_soup/crawl-ref/README.crawl_ref
+++ /dev/null
@@ -1,18 +0,0 @@
-Dungeon Crawl (Stone Soup) Notes
-------- ----- ------ ----- -----
-
-What you have downloaded is *not* Linley's Dungeon Crawl. This is a somewhat
-experimental branch of the Dungeon Crawl Reference project (codenamed Stone
-Soup). Note that this is a branch, and is NOT the official Dungeon Crawl
-Reference.
-
-The goal of this version is to build on Dungeon Crawl Reference (which aims to
-be the stable base platform for experimentation and patches, and to fill in the
-gaps during times when Dungeon Crawl's main maintainer is not available) with
-good features drawn from sources such as Brent Ross' 4.1.2 alpha, and ideas
-from the community of Dungeon Crawl players and to keep development on Dungeon
-Crawl moving without destablizing game balance.
-
-Please do not send bug reports for this code to the main Dungeon Crawl
-maintainers -- the odds are good that the code that's causing you problems
-isn't code they wrote, and they won't be able to help you.
diff --git a/stone_soup/crawl-ref/build_nt.txt b/stone_soup/crawl-ref/build_nt.txt
deleted file mode 100644
index 4b5b4645ab..0000000000
--- a/stone_soup/crawl-ref/build_nt.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-Notes for building crawl with VACPP
------------------------------------
-* when including source, make sure source type is
- defined to be 'cpp' - VACPP doesn't know how to
- handle .cc extensions.
-* include libw32c.cc as a source object;
- ignore the other lib*.cc files
-* define the macro WIN32CONSOLE
-* MUST build with signedchars = yes
-* MUST build with emumsize = 4
-* target architecture should probably be 486 machines.
-
- According to jmf, targetting Pentium class machines
- implies Pentium-specific instructions which are
- actually slower on PPro/PII/PIII machines.
-
-Other than this, it's pretty straightforward.
-
-
-Notes for building crawl with Borland C++ 5.01
-----------------------------------------------
-Don't bother. Borland C++ 5.01 has a broken
-STL library that requires manual patching to get
-around. Use the free commandline tools from Borland
-instead.
-
-Notes for building crawl with Borland C++ 5.5 free commandline tools
---------------------------------------------------------------------
-* make sure your ilink32.cfg contains entries for at least lib and lib\psdk,
- for example:
- -L"g:\bcc55\lib;g:\bcc55\lib\psdk"
- (This may already be done if you've set up Borland for use with VIDE)
-
-* cd to the source directory and edit 'makefile'
- * set MAKEFILE=makefile.bor
- * comment out the OTHER=-j2 line
- * remove EXTRA_FLAGS=... from command (set flags in makefile.bor instead)
-
-* finally, type 'make all' ('make' may default to 'make debug' which isn't
- quite supported yet using the free tools)
-
diff --git a/stone_soup/crawl-ref/docs/buglist.txt b/stone_soup/crawl-ref/docs/buglist.txt
deleted file mode 100644
index c9a33b3b8c..0000000000
--- a/stone_soup/crawl-ref/docs/buglist.txt
+++ /dev/null
@@ -1,423 +0,0 @@
- Bugs Outstanding
-
-
-Compiling
-
-
-COMP01. [unknown - no date]:
-makefile.sgi for IRIX does not work -- no clue why
-
-COMP02. [unknown - no date]:
-DJGPP may puke up a lung on some of the very long functions if
-compiled using certain options -- sometimes simply running make
-again will work; sometimes changing the options will force compile
-
-
-
-
-Critical Errors
-
-
-CRIT01. [BCR - 10 Jan 2000]: weird crash bug: trying ctrl-numbers
-(for control movement under Linux) from the top of the keyboard and
-ctrl-4 apparently kills the program -- ran it in the debugger and
-it said it got a SIGQUIT signal in libc_read
-
-CRIT02. [unknown - no date]:
-skeletal warrior cast a spell and seg-faulted the game in the Abyss
-
-CRIT03. [unknown - no date]:
-sometimes leaving the Abyss through an exit sends game into an
-infinite loop -- hard to replicate, though
-
-CRIT04. [unknown - no date]:
-using stairs/portals sometimes misplaces the player, either into
-solid rock or onto bogus levels -- e.g., level 28 of the dungeon,
-level -1 of a sub-dungeon
-
-CRIT06. [jmf - 31 mar 2000]:
-Taking down stairs onto new level sometimes hangs the game.
-Hard to replicate.
-
-CRIT07. [jmf - 31 mar 2000]:
-Dungeons sometimes generated that feature off-the-edge corrodors.
-Monsters or player moving too close causes segfault.
-
-
-Platform Specific
-
-
-PLAT01. [unknown - no date]:
-Linux: various odd effects when playing in term -- may be
-terminfo's fault
-
-PLAT02. [DLB - 12 Jan 2000]:
-Playing under Linux, I am encountering an atrocious "garbaging" of
-the screen in Wizmode -- the screen fails to update properly after
-using the wizmode help function (&-?) ... has anyone else
-encountered this. Also, keypad support is very spotty under Linux,
-or at least mine ...
-
- [BCR - 12 Jan 2000]:
- Yeah, Linux support is still far from perfect. I've never been able
- to get shift or ctrl numpad keys to work in Linux, and have had
- various display problems. The wizmode help actually uses the same
- function as the regular help, so it should behave the same.
-
- [DLB - 20 Mar 2000]:
- Still no support under Linux console for keypad when in 'X'-map
- mode
-
-PLAT03. [BWR - 13 Jan 2000]:
-The escape key no longer seems to be cancelling my actions (ie.
-looking at spell lists, maps, etc.). This is a desired feature
-because I typically don't trust space in roguelike games. (This is
-under Solaris.)
-
- [DLB - 13 Jan 2000]:
- I noticed this "feature" under Linux, as well ... guess I am not
- the only one.
-
- [BWR - 18 Jan 2000]:
- I've looked at the escape problem and the problem is that at some
- point the keypad( stdscr, FALSE ) line turns into a TRUE. This ends
- up cooking escapes (it has to pause for a bit to wait to see if its
- an escape sequence and this screws up all the checks for escape).
- I've moved this into the #ifndef SOLARIS block with the scrollok.
- Everybody here uses roguelike keys except for those people who are
- luck to get terminals that will output the actual numbers in one of
- their modes, or have hacked their xmodmap to handle the keypad (to
- do pretty much the same).
-
-PLAT04. [BWR - 20 Mar 2000]:
-There's one other bug that we seem to have here (under Solaris).
-Occasionally the game hangs when changing levels. At first it was
-only happening to one person, so I thought it had something to do
-with his environment (I know he's giving incorrect term types to
-get colour, as well as doing some magic with xmodmap to get the
-keypad to work on some terminals), but it did happen to me once so
-I know its real. Nothing really special about the stairs I used,
-they were regular dungeon (I've noticed his games have hanged in
-sub-branches) and I had no monsters around me. This could be a
-problem with either level generation (I was going to a new level)
-or with the save level function. Don't have much time to look at
-either... keep your eyes open for it, if it doesn't happen anywhere
-else, its probably with the SOLARIS or SAVE_GAME_DIR code.
-
-PLAT05. [BCR - 9 Mar 2000]:
-Its not a big deal, but 2 and 8 on the numpad still don't work with
-ctrl for disarming traps. We should at least stick it in the
-buglist. (This is under Windows NT.)
-
- [LRH - 13 Mar 2000]:
- Re: the bug with ctrl-2 and -8 not working: IIRC The last time this
- happened it was as a result of the keyin variable in which
- keypresses entered in the main input loop are stored having been
- set either signed or unsigned, I don't remember which (just that it
- was the wrong one). The problem is that the values for ctrl-2/ 8
- are above 127, so when the variable declaration was changed they
- either started or stopped wrapping.
- Of course, it's a while since I've done any coding, so don't
- believe everything I say.
-
- [BCR - 13 Mar 2000]:
- I spent some time debugging today and it seems that the ctrl-8/2
- problem under NT is a library bug. The external getch() function
- doesn't return when you hit those keys. This maybe be a DJGPP
- thing. I have the borland compiler on this comp too, so if I get
- some time I will try setting it up and seeing if the problem is the
- same there as well...
-
-
-
-
-Display
-
-
-DISP01. [Graeme Dice <grdice@home.com> - 10 Jan 2000]:
-(small, cosmetic) bug with the new, cool XP-left-for-skills
-display: when one gains skills such that 3-4 digits of XP are
-removed, the right parenthesis is not removed (^R fixes)
-
-DISP02. [unknown - no date]:
-missing space when printing gold amounts?
-
-DISP03. [unknown - no date]:
-hunger status not redrawn with level change -- happens when
-engorged and I think also when full
-
- [BWR - no date]
- should be fixed now
-
- [JDJ - no date]
- still not fixed
-
-DISP04. [unknown - no date]:
-check for screen length problems and fix them -- e.g., map
-centering is still off base, line 12 (should this be shifted for
-longer windows?)
-
-DISP05. [BWR - 18 Jan 2000]:
-Speaking of the help screen, the help for the fast scroll on the
-map screen is still wrong: the commands are +/- not +/& like it
-implies.
-
-DISP06. [Tloma Desk - 7 Feb 2000]:
-When gaining level during zapping some bolt towards the top of the
-screen, part of bolt is drawn at the bottom of the screen.
-
-DISP07. [DLB - 17 Mar 2000]:
-the key for list weapons is not displayed after issuing a '?'
-command
-
-DISP08. [DLB - 18 Mar 2000]:
-The spell "Detect creatures" should be "Detect Creatures" (both
-words capitalized) when viewing list of spells known.
-
-
-
-
-Items
-
-
-ITEM01. [LRH - 12 Jan 2000]:
-When you eat a poisonous corpse while poison resistant, it always
-makes you ill (ie diseased) -- Should this be fixed?
-
- [BWR - 12 Jan 2000]:
- Almost certainly. Doesn't make sense to punish players like this.
-
-ITEM02. [unknown - no date]:
-"-5 stone" heavily enchanted to do *more* damage and costs 100
-
-ITEM03. [unknown - no date]:
-jewelry shop generated "+6", a missile weapon
-
-ITEM04. [unknown - no date]:
-found "an amulet of Cekugob" (an unrandart) that should identify as
-"the amulet of Cekugob" -- a 'V' check indicated none of its
-powers, but at least some of them were being applied to my
-character
-
-ITEM05. [unknown - no date]:
-an item is cursed if its "iplus" value is "big enough" -- however,
-"big enough" is >80 in some places, >130 in others, and perhaps
->120 in others (I'm not sure about the >120; I recall seeing it but
-can't find it now). Right now I have an artifact ring that I can't
-uncurse since the value used when uncursing is 130 and the value
-used when sticking is 80 -- the uncursing code checks against 80 on
-one hand and against 130 on the other
-
-ITEM06. [CDL - 18 Mar 2000]:
-I had just had a level 7 Spriggan Venom Mage, with all of his 24
-HP, die from reading a scroll of immolation. The official cause of
-death was listed as "killed by bad targetting".
-
- [DLB - 18 Mar 2000]:
- Appears that item_use::read_scroll() for
- SCR_IMMOLATION hands off a value of beam.thing_thrown as KILL_YOU
- to bang::explosion() and is eventually handled by these lines:
-
- if ( beam[0].thing_thrown == KILL_YOU
- || beam[0].thing_thrown == KILL_YOU_MISSILE )
- ouch(hurted, 0, KILLED_BY_TARGETTING);
- else if (beam[0].flavour == BEAM_SPORE) // cdl
- ouch(hurted, 0, KILLED_BY_SPORE);
- else
- ouch(hurted, beam[0].beam_source, KILLED_BY_BEAM);
-
- Problem is, there is no KILLED_BY_EXPLOSION, so unless someone
- wants to add that case, KILLED_BY_BURNING (now used by "liquid
- flames" in acr.cc only) would be the closest fit ...
- Maybe a better long-term solution would be to add to the KILLER
- enum cases for KILL_YOU_EXPLOSION and KILL_MON_EXPLOSION and work
- from there ??? Right now KILL_YOU and KILL_MON serve double duty
- for both direct (non-missile) and explosion kills -- separate them
- out???
-
-ITEM07. [Tloma Desk - 7 Feb 2000]:
-Magical staves are identified by fighting with them.
-
-ITEM08. [Tloma Desk - 7 Feb 2000]:
-Weapon descriptions are not complete - "It's ... enchanted to do
-more damage." part is missing
-
-ITEM09. [<taran@hotmail.com> - 17 Mar 2000]:
-Reading scroll of detect curse discovers artifact names.
-
-ITEM10. [CDL - 19 Mar 2000]:
-My current character has a spell staff of destruction with these
-spells:
-
- Spells Type Level
- a - Throw Frost Ice/Conjuration 2
- b - Bolt of Cold Ice/Conjuration 5
- c - Lightning Bolt Air/Conjuration 6
-
-I am unable to cast Throw Frost with it, but can cast the other two
-spells. I can't figure out the problem, but when I added enough
-print statements, the problem went away. :(
-There's something odd going on here, as
-dungeon::spellbook_template() gets called once with "spellbook" 13,
-rather than with 53 (the above staff).
-
-
-
-
-Monsters
-
-
-MONS01. [unknown - no date]:
-artefact weapons of Holy Wrath wielded by undead
-
-MONS02. [unknown - no date]:
-monsters shout upon seeing a player who cannot see them
-
-MONS03. [BWR - 13 Jan 2000]:
-Another thing that was noticed in this version. Polymorphing
-Sigmund (or any other named monster) resulted in "a giant beetle"
-changing its form. My guess is some confusion on which table is
-being indexed.
-
-MONS04. [BWR - 27 Jan 2000]:
-On the subject of summoning, a little thing (bug) that has been
-noticed around here... summoned monsters that die overtop of
-corpses, take the corpse with them.
-
-MONS05. [<taran@hotmail.com> - 17 Mar 2000]:
-You can use Yedremewhatewer "enslave undead" invocation to enslave
-shapeshifter acting as an undead. When it changes, the enslavement
-stays. I am not certain if this is a bug or a feature.
-
-
-
-
-Characters
-
-
-PLYR01. [unknown - no date]:
-currently possible to gain zero hp when gaining a level --
-safeguards should exist to prevent negative values, if not
-guaranteeing at least 1 hp per level
-
-PLYR02. [BWR - 12 Feb 2000]:
-calc_hp() and calc_ep() need to be called before you.hp is set so
-that race-classes that start with 5 Fighting don't start with 18/19
-hps (see Ogre Fighters).
-
-
-
-
-Inventory
-
-
-INVN01. [unknown - no date]:
-full inventory doesn't account for possible item stacking or for
-picking up gold
-
- [DLB - 19 Mar 2000]:
- When a player's pack is full, he/she is unable to pick up gold from
- the ground. This, at least should be allowable, if not also item
- stacking (see parent comment).
-
-INVN02. [unknown - no date]:
-inventory count bug: inventory counter occasionally gets out of
-sync (should either be moved or fixed)
-
-
-
-
-Combat Related
-
-
-COMB01. [unknown - no date]:
-EV seems to get screwed up after transforms -- it seems to get at
-the transform value when the player has no armour (calculated
-correctly once armour is on)
-
-
-
-
-Magic
-
-
-MAGI01. [LRH - 12 Jan 2000]:
-The burn_freeze function (which covers the spells burn, freeze,
-crush and arc) doesn't set a friendly creature targetted by it to
-hostile. It should. And I really should have gotten around to
-implementing these spells for monsters, so that ghosts can use
-them.
-
-MAGI02. [LRH - 13 Jan 2000]:
-Summon Shadow Creatures is now Ice/Summoning -- this seems very
-odd.
-
- [BWR - 13 Jan 2000]:
- Same here.
-
-MAGI03. [CDL - 18 Mar 2000]:
-This is in player.cc:
-
-if (you.sure_blade)
-{
- if (you.confusing_touch > 15)
- mpr( "You have a strong bond with your blade." );
- else if (you.confusing_touch > 5)
- mpr( "You have a bond with your blade." );
- else
- mpr( "Your bond with your blade is waning." );
-}
-
-The "confusing_touch"es in the body should probably be
-"sure_blade"s.
-
-
-
-
-Teleportation
-
-
-TELE01. [unknown - no date]:
-if you have teleport control you'll see a prompt that says:
-"You may choose your destination (press '.' or delete to select)."
-I somehow got into the habit of immediately blowing by this prompt
-without ever reading it so I was always flailing around whenever I
-tried to teleport. I've changed show_map() so that it accepts '\r'
-as well as '.' (which should be much more intuitive) but I don't
-see a check for the delete key in show_map() so I think the prompt
-is wrong
-
-TELE02. [unknown - no date]:
-teleport control is really wacky -- I'd expect to be able to use
-the return key to select the square but it seems to key off one of
-the keypad keys
-
-
-
-
-Targeting
-
-
-TARG01. [unknown - no date]:
-targeting is off at times (possible rounding errors)
-
-TARG02. [unknown - no date]:
-fired beams sometimes take the wrong route and can't hit targets in
-LOS
-
-
-
-
-Codebase
-
-
-CODE01. [unknown - no date]:
-in monsters enum, values 250 to 310 should be reserved for Uniques,
-but 260 to 280 are occupied by other monsters -- should move them
-if it won't mess anything else up (if moved, remember to alter
-ouch.cc check for placing 'a' is put in front of the unique's name
-in the scores) -- not really a bug.
-
-CODE02. [unknown - no date]:
-from the code, it appears that dropping items takes zero time
-
diff --git a/stone_soup/crawl-ref/docs/build_nt.txt b/stone_soup/crawl-ref/docs/build_nt.txt
deleted file mode 100644
index c6c7373eae..0000000000
--- a/stone_soup/crawl-ref/docs/build_nt.txt
+++ /dev/null
@@ -1,56 +0,0 @@
-Notes for building crawl with VACPP
------------------------------------
-* when including source, make sure source type is
- defined to be 'cpp' - VACPP doesn't know how to
- handle .cc extensions.
-* include libw32c.cc as a source object;
- ignore the other lib*.cc files
-* define the macro WIN32CONSOLE
-* MUST build with signedchars = yes
-* MUST build with enumsize = 4
-* target architecture should probably be 486 machines.
-
- According to jmf, targetting Pentium class machines
- implies Pentium-specific instructions which are
- actually slower on PPro/PII/PIII machines.
-
-Other than this, it's pretty straightforward.
-
-
-Notes for building crawl with Borland C++ 5.01
-----------------------------------------------
-* must alter the Tool information for CppCompile to
- 'understand' .cc extensions (in Advanced Tools Settings)
-* include libw32c.cc as source; ignore other lib*.cc files
-* define macro WIN32CONSOLE
-* MUST build with "Unsigned Characters" OFF
-* MUST build with "Allocate Enums as Ints" ON
-* MUST set search directories so that the Crawl Source directory
- is searched before the BC5\INCLUDE directory.
-* target architecture should probably be 486 machines
- (see note for VACPP)
-* helps to set Warnings to "Selected Subset only" or you
- get ZILLIONS of warnings. I usually turn off all the
- "Code Efficiency" warnings. :)
-* for best results, specify following in target expert:
- - Win32 Console Application (.exe)
- - _Everything_ unchecked
- - Static linking
-
-Notes for building crawl with mingw
-------------------------------------------
-* In makefile specify makefile.w32. Other notes:
- - make sure your path includes mingw binaries
- - set LIB to your mingw lib directory
- - set INCLUDE to your mingw include directory
- - the makefile defines WIN32CONSOLE like above
- - -Wall will generate a fair number of warnings
-* Tested on Win98 and Win2000.
-* Current build is not statically linked.
-* See notes above for target arch code gen switches
-* This is currently tested only with 2.95.2
- I anticipate no problems with mingw 3.0.1 but
- haven't had time to update yet.
-* This also currently doesn't statically link
-
-
diff --git a/stone_soup/crawl-ref/docs/changes.340 b/stone_soup/crawl-ref/docs/changes.340
deleted file mode 100644
index 2891d5c976..0000000000
--- a/stone_soup/crawl-ref/docs/changes.340
+++ /dev/null
@@ -1,1860 +0,0 @@
- Version 3.40 Changelog
-
- Note:
-
- This file documents the progressive development of Crawl 3.40. Much
- of it discusses specific changes to the codebase that may prove
- uninteresting to non-programmers. The devteam has made no great
- effort to clean up our comments.
-
- Do you seek a more accessible overview of the latest changes? Those
- answering "yes" should read the versions.txt entry for Crawl 3.40
- instead.
-
-
-=============
-Contributors:
-=============
-Gordon Lipford (lipford@ca.ibm.com)
-Linley Henzell (linley.henzell@student.adelaide.edu.au)
-Jesse Jones (jesjones@halcyon.com)
-Daniel Ligon (makmorn@qis.net)
-David Loewenstern (loewenstern@home.com)
-Brian Robinson (bcr19374@pegasus.cc.ucf.edu)
-Brent Ross (bwross@csclub.uwaterloo.ca)
-Josh Fishman (fishman@cs.nyu.edu)
-Don Brodale (lar@bway.net)
-
-
-Oct 30, 2000 (Brent Ross)
- -- add macro/function for Control('A') and such.
- -- remove "move[0]" (struct dist)
- -- remove "&beam[0]" (struct bolt)
- -- fixed some problems with elemental resistances
- -- added "easy_confirm" to rc file
- -- improved vampire's spell selection
- -- added merfolk race
- -- added wanderer class
- -- split out the monster speaking function from monstuff.cc
- -- fewer param monam() => ptr_monam()
- -- restore abilities potion gives no message
- -- move monster spells out of mon-util and into mon-spls
- -- added inv_randart_wpn_properties()
- -- fix berserk for mutations and others (paralyze too strong).
- -- make pandemonium gates rarer, special named demon pandemonium levels too
- -- does exp_needed require the species param -- removed
- -- returned Swords as "Orbs of Fire"
- -- returned quokka (added to low level regular dungeon monsters)
- -- easy_open is now an option
- -- added show_uncursed and easy_butcher options.
- -- slight modifications to divine retribution
- -- make weapon classes depend on different stats (USE_NEW_COMBAT_STATS)
- -- added/move startup messages to the new block after initialise()
- -- option to safeguard accidentally auto-removing and dropping armour
- -- added starting message describing chacter race/class
- -- make yesno() take a flag for "safe" cases... and option
- -- fixed the file locking mechanism
- -- moved some SOLARIS defined stuff (which really isn't Solaris dependant)
- to MULTIUSER.
- -- write player_title() as interface to skill_title() which will do the
- best calculating and call skill_title (which is still needed for ghosts)
- -- fixed bug: runes were being generated in the hive
- -- fixed bug: examined clouds wrongly identified
- -- added Simulacrum spell (creating a new Ice spell... I'm surprised
- that Ice/Necromancy aren't very closely related... this will help
- fix that).
- -- added Ball Lightning spell (replacing Electric Orb).
- -- fixed best_skill to use skill_points and species difficulty, instead
- of just the base level (which gave preference based on the order of
- the skills... this will only have that happen if the skill points
- are also equal, which is much less likely).
- -- adjustments to the spellbooks, and spellbook aquirement
- -- Warp adjustments
- - removed bend, warp/distortion brand from play
-
- - warp brand was raised in level and the miscast effects were
- added to the spell start and end (to limit the spell should it
- ever be brought back).
-
- - translocations also doesn't help with the miscast effects of
- distortion brands (it was reducing the terror wielding one, and
- these weapons easily outclass other brands for bonus damage and
- powerful effects... they should never be anywhere near usable
- as a reliable swap weapon, player's should have to seriously think
- before deciding to use one... and have to risk some real damage
- or banishment if they use them frequently).
-
- - reduced frequency of summoning "spatial vortices" as a miscast
- effect -- people were reliably getting them by dropping warp
- branded weapons (and it's random movement makes it much less
- a threat to the player, who will sit back and watch it mow down
- the other monsters in the room (who won't see it as a threat))
-
- - added Far Stike as a level one spell (the other spells were very
- overpowered (distortion weapons are gross and dangerous, using
- that code as "balanced" is wrong unless you're bringing over the
- danger as well... all three of warp attacks were also range 1, which
- is silly for Warpers, who should be world-class plinkers, not close
- combat munchkins). It's a much limited spell that allows the player
- to "hit" a monster in LOS (yes, that means like striking/airstrike
- so it's not really another magic missle) with their weapon
- (limits being: no magical special effects, no enchantment bonus,
- slow to cast (weapon swing is part of it, but it's also a spell
- so it will never take less than 10), max damage limited by
- translocation skill and weapon, with strength bonus/penalty
- applied, can be resisted (maybe change this to evaded?)). This
- should probably be the only translocation combat spell... let them
- go elsewhere for strong offensive.
-
- - made it so that blink will at least teleport the player to a square
- two squares away (makes blink a bit more usable, because it removes
- the annoying "I could have walked here" feelings).
-
- - added Swap, which allows the player to swap places with an
- adjacent monster. Isn't really that abusable as it uses the
- same swap code that's used for friendly monsters and that
- doesn't currently have insta-kill potential... that can be
- fixed later, but right now I'm calling it a "feature". Should
- it be fixed, this spell could be changes to give a higher resist
- and in insta-kill situations the monster could be allowed to
- "scatter" to any of the immediate surrounding squares as a
- save against death (player could get this too).
-
- - added Apportation, a simple utility spell that will move light
- objects to the player
-
- - added Evocation a high level teleport surrounding monsters
- away spell (even if resisted the monster still might be blinked)
-
- -- fixed BUG: nagas gaining breathe fire mutation (twice in this case) seem
- to lose the spit poison ability
-
- -- made it so that MULTIUSER will look for ~/.crawlrc (Un*x-type standard)
- -- pain, disrupt, far strike do a minimum of 1pt of damage to make up
- for the monsters saving throw (that 1pt is only really good early
- on when the character can use it to help stay alive, later on it
- means almost nothing... so it helps out begining characters, and
- makes the fact that the spell is going to be resisted fairly often
- at those levels a little less painful).
- -- made sure stabbing had a point of starting damage (it's silly to apply
- multipliers to zero or negative damage).
- -- returned "Toxins" to "Envenomations"
- -- spider form now makes spell casting slightly more difficult.
- -- changes "book of Assassinations" to "book of Stalking" (less confusing)
- -- fix for "buggy helmets"... normal helmets with item_dam == 0 were not
- being handled in the code (before they defaulted to nothing)... might
- still exist, but should be rarer (there is a chance that the high
- values of item_dam also occur).
- -- fix for "buggy potions"... potions ids were being generated in a wider
- range than there was descriptive words.
- -- lowered the magic resistance of the really low level monster to allow
- first level characters to deal with them better.
- -- enums for item_descriptions
- -- enums for monster bands
- -- added enums for monster spell templates (still need to be applied)
- -- fixed enchant_monster() so that slow and haste will work through it.
- -- changed player_fast_run() into player_movement_speed() and got rid
- of ATTR_WALK_SLOWLY as well... player_movement_speed() returns the
- movement rate so it's no longer "have running == 6".
- -- modified swap_monsters to handle habitats.
- -- tweaked failure rate for Trog Haste (which was in with the other haste
- and using Invocations).
- -- power level caps for spells (checks for most spells to verify that
- the effect is limited in some way as protection against potential
- extremely high power casting). Adjustments to spell damages/to-hit
- to work with the lower caps (that the play will run up against).
- -- added wizard command for filling up skill experience pool
-
- 29.july.2000 (Jesse Jones)
-
- * Changed NUM_SPELL_TYPES to 14 (from 32767!).
- * Misc very minor CodeWarrior tweaks.
- * Moved the source files into a new "Source" directory.
- * Switched to using bounds checked array classes for most arrays.
- * Fixed several places that were indexing past the end of arrays.
- * Renamed environ::sh_x, sh_y, sh_greed, sh_type, and sh_level so they start with shop.
- * Renamed MNG NON_MONSTER, MNST MAX_MONSTERS, ITEMS MAX_ITEMS, ING NON_ITEM,
- CLOUDS MAX_CLOUDS, CNG EMPTY_CLOUD, and NTRAPS MAX_TRAPS.
- * Fixed end_game so that it works with filenames longer than 6 characters.
- * Disabled USE_WARPER_BETTER_WEAPON.
- * Fixed misspelled "jewelry".
- * Removed SPELL_SWARM from the Book of Summonings.
- * Added Josh's "pick appropriate conjuration spellbook" code.
- * Added Gordon's Manticore fix.
- * Added the lnchType fix to the monster throw code.
- * Added Gordon's revised title changes.
-
-28.july.2000 (Gordon Lipford)
-
- all changes are GPL'd by Gordon Lipford (c) 2000
- in the event that the original Crawl license is found to be non-GPL,
- special permission to use the changes with Crawl is hereby granted.
-
- Bug Fixes:
- * Manticores will now use their spikes. They weren't being given any
- inventory in place_monster(), and then the throwing routine checked
- for inventory before letting them throw..
- * Player::level_change(): fixed up hit point penalty for halfings and
- gnomes (incomplete coding of HP adjustment). Rewrote hp and mp gained
- due to level so that it couldn't happen again.
- * item_use::wield_weapon(): smoothed out Translocator 'save' vs distortion
- effects when wielding/unwielding.
- * smoothed out hp bonus for fighting skill (in integer math, always
- divide _last_).
- * enchant weapon scrolls will affect missiles now (no branding though),
- if they aren't already heavily enchanted - same as weapons.
-
- Changes:
- * Completely reworked throwing for players _and_ monsters. Monsters are
- not nearly as good as players for the most part, but can still be
- rather scary. Hit Dice are (approximately) substituted for player skill,
- and monsters of high intelligence are much better shots now.
- - targeting any missile weapon benefits from high dex and throwing skill.
- In fact, effective bow/xbow/sling skill is limited to twice one's
- throwing. A warning is given on the skills screen if this limit is
- hampering the player.
- - darts, slings, and crossbows are easy to use. Bows and thrown weapons
- are harder, but bows improve a _lot_ with skill.
- - thrown weapons generally suck, but not horribly badly - they're still
- useful in a pinch if you have decent strength and throwing skill.
- - Strength has a different effect on the damage done from missiles:
- - Slings and bows benefit from strength, up to a point determined by
- the launcher's magical damage bonus. The launcher damage bonus is
- _not_ added into the damage calculation.
- - Thrown weapons benefit directly from strength, albeit at a lower rate.
- - Crossbows do not benefit from strength at all.
- - Crossbows benefit directly from magical launcher damage bonuses.
-
- * changed some of the class titles
- * updated display_mutations() so that more than 20 mutations will
- cause a -more- prompt and screen clear.
-
-28.july.2000 (Michal Valvoda)
-
- Changes in mutations::void display_mutations(void)
- - added innate abilities and weirdness to "Mutations & Other weirdness"
- screen and renamed it to "Innate abilities, weirdness & mutations".
- Innate abilities are colored LIGHTBLUE
-
-
-22.july.2000 (Josh Fishman)
-
- all changes are GPL'd by Josh Fishman (c) 2000
- in the event that the original Crawl license is found to be non-GPL,
- special permission to use the changes with Crawl is hereby granted.
-
- * AppHdr.h:
- added #defines:
-
- USE_SKILL_POOL_DRAIN
- - comment out to remove LRH's old skill-pool drain code, which makes the
- xp-pool drain faster when it is very full
-
- USE_WARPER_BETTER_WEAPON
- USE_WARPER_SPELL_BEND
- - start warpers with a {dagger/quarterstaff} of Distortion, or with the
- spell Bend, depending on which is commented out. the former is
- particularly evil for ogre-mages, since their default weapon can't dissect.
-
- * abl-show.cc:
- - Changed some `you breathe foo's to `you exhale foo's.
-
- Made transformation, species & mutation breath weapons mutually exclusive
- (so a naga with the `breathe flame' mutation can't spit poison). THIS IS
- NOT TOTALLY DONE, but somewhat better than before.
-
- + Added failure probabilities for some (not yet used) Invocations.
-
- * beam.cc:
-
- + Added BEAM_LAVA for player spell Bolt of Magma
- + N.B.: in some places hellfire and lava were conflated; I tried to
- separate them, but may have introduced bugs.
-
-
- * describe.cc:
-
- + Many changes to monster descriptions.
- + Chunk-of-flesh description now depends on your race, but not enough.
- For example, carnivores ought to like non-rotten meat.
- + Spell descriptions:
- - added Bolt of Magma
- - changed Freeze, Sleep and Mass Sleep to reflect new `Slow Snakes' code
- - Shadow Creatures has old description, to reflect its school
- - Summon Large Mammal -> Call Canine Familiar
- + Some changes to god descriptions
-
-
- * dungeon.cc:
-
- + Fixed "Entering..." bug (line 7215 or so)
-
-
- * it_use2.cc:
-
- + Added ZAP_MAGMA (for Bolt of Magma)
- + Fixed POT_MIGHT effect
-
-
- * it_use3.cc:
-
- + Fixed staff_spell() (wasn't letting player pick first spell sometimes).
- + STAFF_SMITING no longer gives you a one-choice menu, it just does it.
- + Non-Spell Staves no longer say "This staff has no spells in it." when
- (I)nvoked, they say "Nothing appears to happen.".
- + Less abusive message for putting on non-jewellery (with free spelling
- error!)
- + Jewellery messages now feature "put on" in some places where "wear" was.
-
- * mon-data.h:
-
- + Added flags M_COLD_BLOOD and M_WARM_BLOOD where IMO appropriate.
-
-
- * mon-pick.cc:
-
- + Removed MONS_RAKSHASA_FAKE from generateable monster lists.
- + Added Wargs, Wolves and Bears to generateable monster lists.
- - Wargs in Orc Mines
- - Wolves & Bears in the Lair
- + Moved mon_entry[] from within function to outside; made init code
- into its own function.
-
-
- * monstuff.cc:
-
- + Monster wounds messages: mon HPs left: was 1/4-1/3 => "horribly", now 1/6-1/3
- + (Glowing) Shapeshifters are no longer allowed to use Mage and Priest
- special powers, but still get their shape's physical abilities. So a
- shapeshifter in the form of an orc priest can't smite you, but one in
- dragon form could breathe fire.
- + Some spelling & grammar fixes to mon_speaks; MUCH MORE WORK NEEDED HERE!
-
-
- * newgame.cc:
-
- + Implemented USE_WARPER_BETTER_WEAPON and USE_WARPER_SPELL_BEND
-
- + Stalkers:
- - skills: no more THROWING or DARTS, now SPELLCASTING and ENCHANTMENTS
- - book: Book of Assassination
- + Draconians:
- - No longer allowed to be Enchanters -- they so suck at Enchantments
- - ... but now allowed to be Transmuters, since they're good at Transmigrations
- + Kobolds now allowed to be Death Knights.
- + Halflings now allowed to be Crusaders.
- + Removed strange random 1st level spell code -- now always give players the
- 1st spell in their spell-books.
-
-
- * player.cc:
-
- + Players transformed into Dragons and Air now protected from poison
- (as monsters of those types are immune).
- + Players transformed into Air no longer get air-magic boost, but still do
- get earth-magic penalty.
- + Centaurs and Spriggans don't lose their fast-running w/ BLADE_HANDS any more.
-
-
- * religion.cc:
-
- + simple_god_message() simplified
- + Reduced number of colors in god_speaks().
- + Changed some gain/lose piety messages to reflect what power was gained/lost.
- + Changed penence messages to reflect that gods don't summon, they send.
-
-
- * skills.cc:
-
- + Sludge Elves now bad at Enchantments, good at Transmigrations, worse
- at all forms of Elemental Magic (was experimental, not sure if it
- was discussed on crawl-dev). FIXME: change back?
-
-
- * spell.cc:
-
- + Added SPELL_BOLT_OF_MAGMA.
- + Spell type code now uses bitfields.
-
-
- * spells.cc:
-
- + Spell type code now uses bitfields.
-
-
- * spells2.cc:
-
- + Weapon branding code now works (brand_weapon()).
- - er, except for what may be a bug at the end: `power << 1' => `power * 2'
- + Ozocubu's Refrigeration and Freeze can now slow cold-blooded creatures.
- + summon_things now correctly pluralizes.
-
-
- * spells4.cc:
-
- + Added case TRAN_AIR to your_hand().
- + apply_area_one_neighboring_square() no longer gives unlimited trys.
- + cast_summon_large_mammal() no longer generates hogs or sheep, now just
- Jackals, Hounds and War Dogs.
- + cast_sticks_to_snakes() gives MONS_SNAKE for low-level large object snakes
- (as opposed to MONS_BROWN_SNAKEs).
- + sleep_monsters() is now only called from hibernation-spells:
- - Now cold resistance negates.
- - `Slow Snakes' (cold blood => may be slowed as well as put to sleep)
- + Fragmentation & Shatter:
- - Statues and magic traps no longer destroyed
- + Shuggoth Seeds: seed now requires MH_NORMAL, warm-blooded host
-
-
- * spl-book.cc:
-
- + Books of Minor Magic changed, hopefully for the better!
- - BoMM-II man still need some help; Ozocubu's Armour replacement?
- + Book of Flames loses BOLT_OF_FIRE, gains BOLT_OF_MAGMA
- + Book of Frost gains SLEEP, loses FREEZING_CLOUD
- + Book of Ice gets MASS_SLEEP and FREEZING_CLOUD
- + Changes to Enchantment books
- + New Book of Assassination
- + spellbook_template() copying loop used to count from 1 to SPELLBOOK_SIZE,
- I made it count from 0 (to fix the "can't-get-to-first-spell-in-staff" bug).
-
-
- * spl-data.h:
-
- + Spell structure now has one field for "level" (instead of 3 identical ones).
- + Spell schools are now encoded as bits in an unsigned int instead of in a
- special structure.
- + Some spells moved back to their old schools (from my (bad) recent changes).
-
-
- * spl-util.h & spl-util.cc:
-
- + Changes to use new, simple spell structure.
-
-
- * view.cc:
-
- + Removed "if (do_updates) mpr("Stealth checks...");" from DEBUG builds
- (it's too annoying).
- + Enum'd monster noises.
-
-
-21.jun.2000 (Michal Valvoda)
- Changes:
- monstuff.cc
- - completely reworked mons_speak routine
- - removed silence check required to call mons_speak (line 749)
- - lowered chance to speak to one_chance_in (7) (line 749)
- describe.cc
- - added many new monster descriptions (deep elves, unique monsters
- like Sigmund, Terence etc., killer bee larva ...)
- - changed some existing descriptions - made them more detailed
- - in case of some "smell" message add MUMMY check
-
-
-19.jun.2000 (Gordon Lipford)
- Changes:
-
- * replaced old losight() function with new one. It doesn't quite
- match the old one, but it's close enough.
- * externalized setLOSRadius() and added normal_vision and current_vision
- fields to the player structure. We have variable light sources, voila!
-
- - Note that using a radius of 0 screws up map memory and looks really dumb.
- I am not going to try to fix this.
- - In a similar vein, bumping into something should draw it on the map
- if you didn't know it was there already (ie you fumble blindly into a
- wall). I'm not going to do this either. :)
-
- * changed all level 1 'handle' references to level 2 'FILE *' for better
- portability. Whenever a function needs a File Descriptor, I have
- substituted fileno(handle) for just 'handle'.
- * added Windows 32 bit Console support. Screen redraws, loading, saving,
- and highscore updates are now VERY fast on Windows machines, even playing
- from a shared network drive. The NT DOS VDM, at least, was !@$#* crap.
-
-
-17.mar.2000 [Josh Fishman]
-
- Bug Fixes:
-
- * ability.cc: ABIL_BREATHE_FIRE gained power if player had MUT_SPIT_POISON
- -- changed to bonus if player has MUT_BREATHE_FIRE
- * beam.cc: poison_monster: fixed so TSO only gets pissed if it's YOUR
- poison (my broken code had him angry if ANY poisoning occured)
- * spells.cc: changed many miscast messages to passive "You are caught in"
- (rather than "You conjure up") because miscast_effect is called for all
- sorts of stuff (particularly divine punishments).
-
-
- Structural Changes:
-
- * moved much spellbook code to new file, spellbook.cc
- * removed a host of DUR_<BRAND_TYPE> entries; replaced with
- DUR_WEAPON_BRAND
- * cast_selective_amnesia(bool): was (void); bool used to determine if
- failure (and memory loss) is allowed. Sif Muna's invocation guarentees
- success.
-
- New Functions:
-
- * Confined to spells4.cc
-
-
-17.03.2000 [Don Brodale]
-
- BugFixes:
-
- * damage taken by player (misc.cc) for CLOUD_MIASMA was wrong --
- operator precedence at fault;
- * SPWPN_FROST changed to RING_SUSTAIN_ABILITIES in
- player::player_sust_abil() for EQ_LEFT_RING conditional (noted by
- Jukka);
- * misc::itrap() MI_AXE -> WPN_HAND_AXE and mstuff2::mons_trap()
- MI_SPEAR -> WPN_SPEAR, MI_AXE -> WPN_HAND_AXE to fix inappropriate
- item generation (noted by Brent);
- * newgame::new_game() stairs to Hall of Blades now
- "you.branch_stairs[STAIRS_VAULT] + 4" not
- "you.branch_stairs[STAIRS_CRYPT] + 4" to fix overmap inconsistency
- described by Jukko and confirmed by Linley;
- * dungeon::items() recoded to fix generation of skill manuals of
- SK_GREAT_SWORDS but not of SK_POISON_MAGIC and SK_INVOCATIONS
- (noted by Brent);
- * MS_STING was cased in mstuff2 to be BEAM_FIRE causing it to set
- scrolls afire (noted by <kathomps@julian.uwo.ca>) -- changed to
- BEAM_POISON, as it should have been all along;
- * CMD_LIST_WEAPONS in acr::input() '(' -> ')' (noted by Brent);
- * CMD_LIST_WEAPONS in liblinux::init_key_to_command() '(' -> ')' to
- match above change; and
- * half a bugfix: in food::eat_meat() Amulet of the Gourmand no
- longer renders contaminated or poisonous flesh clean -- now have
- to apply the other half enabling eating of rotten food as though
- it were [presumably] underlying corpse effect type.
-
- Structural Alterations:
-
- * commented many many of the header files -- need to comment and
- check rest, but can we keep these up to date, please?;
- * cleared out all tabs (some 500+ of them);
- * *massive* checking of function declarations in most of the source
- files and resulting clean-up of #includes and *.cc versus *.h
- declaration -- too many to list here, if anyone wants to see it,
- let me know;
- * #ifdef/#defn protection added to overmap.h, preventing multiple
- inclusions;
- * version.h -- BUILD_DATE advanced to "17 mar 2000" and VERSION
- changed to "3.40pr30";
- * standardized ordering of #includes atop files, alphabetized last
- set of #includes within each file, removed of duplicate entries
- where found;
- * duplicate #includes for message.h removed from files already
- #include-ing externs.h (which in turn #includes message.h);
- * removed setting you.redraw_hunger to 1 immediately prior or after
- calls to food::food_change(), as the function sets this value
- itself; and
- * replaced (here and there) the sum of "n calls to random2(a)" with
- "random2avg( (n*(a-1))+1, n )" -- for low values of n,
- distribution of returned value is analogous and this approach
- offers option to tweak distribution of value returned, too.
-
- New Functions:
-
- * food::can_ingest() added and inserted where appropriate -- option
- to suppress message included in case we want to tie routine to
- inventory list command to display whether something is edible by
- player.
-
- Changes to Existing Functions:
-
- * message added for change in burden state *to* unencumbered --
- don't know why there wasn't one in the first place, but actual
- message may require tweaking
- * acr.cc variable newc changed from type int to char to match value
- returned from newgame::new_game()
- * monplace::create_monster() automatic variable "int pets" removed
- -- didn't do anything except sit there and retain zero valuation
- * effects::lose_stat() recoded to use STAT_RANDOM (see below)
- * food::food_change() coding simplified as it was really far more
- complex than it had to be and confused, to boot
- * food::is_carnivore() removed -- replaced by food::can_ingest()
- (see above)
- * food::eat_from_floor() automatic variable "int gloggj" removed,
- all it held was returned value of eating(), but was never used
- * mutation.cc redundant codings replaced with calls to
- player::increase_stats() -- look for the comments: nulled-out
- gain/loss message strings for mutations affected by change
- * spells0::undead_can_memorize() -> undead_cannot_memorize() and
- recoded for more reasonable usage, to permit restriction of
- certain spells solely to the dead, and to allow the 'true' undead
- to use spells that the 'hungry' dead cannot (not possible before),
- etc.
- * view::losight() variables see, see_section, and behind are now
- bool and not (int / short int / char) -- some clean-up called for
- but I wasn't up for it
- * barehand_butcher added to food::butchery() to clarify coding
- * spells1::cast_fire_storm() variable summd its association with
- monster_place() removed
- * player::how_hungered() recoded so as to avoid need for goto:
- statement -- the accursed goto
- * standardized (to some extent) the way in which mons_lev.cc f(x)'s
- are coded
- * mutation::perma_mutate() rewritten for clarity, taking advantage
- of left-right evaluation of && conjoined conditionals
- * effects::recharge_wand() clean-up / clarified
- * spells1::cast_revivification() clarified a little bit
- * monstuff:mons_in_cloud() cleaned-up, optimized, and enumerated --
- no longer relies on (env.cloud_type[cl] % 100)
- * view::cloud_grid() cleaned-up
- * ouch::lose_level() lost some code that simply called random2() to
- no particular end
- * mons_lev::mons_level_abyss() -> mons_lev::mons_abyss(), to be more
- in line with mons_pan() as both simply check whether a monster
- "belongs"
- * functions that now return bool instead of char:
- + effects::forget_spell();
- + effects::lose_stat();
- + effects::recharge_wand();
- + fight::monsters_fight();
- + food::butchery();
- + food::eat_from_floor();
- + misc::scramble();
- + mons_lev::mons_level_abyss();
- + monstuff::curse_an_item();
- + monstuff::mons_speaks();
- + mstruct::mons_pan();
- + mutation::delete_mutation();
- + mutation::give_bad_mutation();
- + mutation::give_good_mutation();
- + mutation::mutation();
- + mutation::perma_mutate();
- + player::you_resist_magic();
- + transfor::can_equip();
- + transfor::transform(); and
- + monplace::empty_surrounds().
- * functions that now return bool instead of int:
- + transfor::remove_equipment();
- + monstuff::wounded_damaged() -- this may have to change if we
- add more types of monster hurt than wounded and damaged;
- + dungeon::treasure_area(); and
- + view::check_awaken().
- * functions that now return unsigned char instead of int:
- + player::player_energy();
- + player::player_fast_run();
- + player::player_spec_air();
- + player::player_spec_cold();
- + player::player_spec_conj();
- + player::player_spec_death();
- + player::player_spec_earth();
- + player::player_spec_ench();
- + player::player_spec_fire();
- + player::player_spec_holy();
- + player::player_spec_poison();
- + player::player_spec_summ(); and
- + player::player_sust_abil().
- * spells2::burn_freeze() now returns char instead of int;
- * dungeon::place_monster() parameter "char allow_bands" changed to
- "bool allow_bands" to clarify how this parameter is, in fact,
- used;
- * dungeon::place_monster() parameter "int type_place"
- changed/renamed to "bool is_summoning" to clarify how this
- parameter is, in fact, used;
- * dungeon::spotty_level() takes bool instead of char for first and
- third parameters (seeded and boxy);
- * food::eating() returns void instead of int -- always returned 0
- and the returned value never used elsewhere;
- * food::ghoul_eat_flesh() takes bool instead of char for only
- parameter;
- * item_use::wield_weapon() takes bool instead of char for only
- parameter;
- * misc::dart_trap() takes bool instead of int for first parameter;
- * misc::down_stairs() takes bool instead of char for first
- parameter;
- * misc::fall_into_a_pool() takes bool instead of char for first
- parameter;
- * misc::handle_traps() takes bool instead of char for third
- parameter;
- * monplace::empty_surrounds() takes bool instead of char for fourth
- parameter;
- * monplace::mons_place() parameter "int type_place" changed/renamed
- to "bool is_summoning" to clarify how this parameter is, in fact,
- used;
- * mstuff2::monster_abjuration() takes bool instead of char for
- second parameter;
- * mstuff2:monster_teleport() takes bool instead of char for second
- parameter;
- * player::increase_stats() takes unsigned char instead of char for
- only parameter, extended to handle random stat boost;
- * spells1::ice_armour() takes bool instead of char for second
- parameter; and
- * spells3::dancing_weapon() takes bool instead of char for second
- parameter.
-
- Enumerations and Defines:
-
- * MONS_MOLLUSC_LORD (255) added to enum MONSTERS -- deprecated but
- still referenced;
- * NUM_WANDS added;
- * STAT_RANDOM and NUM_STATS added;
- * NUM_DURATIONS added and kept at 30 (rather than true value)
- because setting it lower (I think) would cause savefile
- compatibility problems -- not fully useful unless we wish to break
- savefile compatibility;
- * MI_AXE (9) and MI_SPEAR (11) removed from enum MISSILES (see
- above);
- * enum MAP_SECTIONS added for dungeon.cc / maps.cc interaction --
- not fond of how maps are applied, so this may be temporary;
- * enum MONSTER_CATEGORIES and mstruct::monster_category() added to
- clarify certain conditional tests and keep comparison on
- MONS_foobar to equality or inequality for ranges -- this will be
- expanded and attached to similar entries in m_list.h (I ran outta
- time!);
- * enum CORPSE_EFFECTS added -- members mimic C_foo #defines and add
- a few new ones and another for rotting [see food::eat_meat()] --
- again, I ran outta time to extend application;
- * misc::in_a_cloud() fully enumerated out, no longer relies on
- switch (env.cloud_type[cl] % 100); and
- * much more general enumeration across codebase.
-
-
-06.03.2000 [Brent Ross]
-
- * removed strength loss from berserk penalty (acr.cc);
- * added Trog code to berserk (fight.cc, acr.cc);
- * reverted Berserkers and Paladins to their original weapons/skills
- -- actually, Paladins changed to sabres on Linley's suggestion
- (newgame.cc);
- * removed learning from stave combat (fight.cc);
- * made vorpal weapons less common, other egos more common?
- (dungeon.cc);
- * changes to makefile.sol;
- * increased armour penalty for spellcasting, lowered the reduction
- to penalty for armour skill (spells0.cc);
- * armour changes: elven armour is better for spellcasting, dwarven
- armour for AC from skill -- for everyone (player.cc, spells0.cc);
- * paralysis leaves player easier to hit (player.cc);
- * reduced Xom's prayer reponse rate (religion.cc);
- * added penance and gift timeouts for gods (files.cc, extern.h,
- religion.cc, newgame.cc, ability.cc):
- + divine_retribution() (religion.cc, decks.cc, spells.cc); and
- + added god_speaks() so that the other gods can use colourful
- text.
- * indented code;
- * improved the demonspawn AC mutations by boosting the number of
- levels for the lower ones;
- * extended spellbooks to 8 spells maximum ... restored levitation to
- Air, removed "Summon Elemental" from Ice (their "elemental" is
- really an Ice Beast, not benefitting from summoning Water
- Elementals); and
- * added Confusing Touch as a first level spell for enchanters and
- Sure Blade as a second level spell -- removed wand and gave them
- some enchanted darts.
-
-
-23.02.2000 [Don Brodale]
-
- BugFixes:
-
- * implemented Linley-suggested bugfix in misc.cc:down_stairs() to
- fix "Abyss bug" that was actually a/the "Pandemonium bug";
- * copied over new makefile.sol posted by bwross;
- * typo in dungeon.cc limited weapon given to elven mage-types to
- whips and sabres *only*;
- * item descriptions added to itemname.cc for BOOK_PARTY_TRICKS and
- BOOK_CANTRIPS (jmf/bcr forgot to do so?);
- * spells2::summon_elemental() would create sleeping elementals when
- summoned hostile to spellcaster; and
- * spells2::summon_things() -- apparent reversal of
- MONS_ABOMINATION_SMALL and MONS_ABOMINATION_LARGE [jdf flagged it
- first] fixed by correcting improper enumeration (see below).
-
- Gameplay Changes:
-
- * stalkers, assassins, and venom mages begin the game with knowlege
- of Poison Potions (c.f., Paladins/Healers possessing knowledge of
- Healing Potions).
-
- Structural Alterations:
-
- * externs.h now #includes enum.h -- already de facto standard, now
- openly the case;
- * moved files not directly related to current build into subfolder
- labeled "misc";
- * moved files removed from or "left behind" by the current build
- into subfolder labeled "unused";
- * proper #includes for decks.cc now in place;
- * redundant #include defines.h in invent.cc and mstruct.cc removed,
- already #include'd by externs.h;
- * changed some formulas resembling "menv[bk].type =
- MONS_ABOMINATION_SMALL + (random2(2)) * 26;" to conditional on
- coinflip(); and
- * flipped many conditional clause orderings to place function calls
- last to take advantage of short-circuit logic.
-
- New Functions:
-
- * stuff::coin_flip() to replace random2() when desired result is
- simply true or false -- does not use rand() or random() for return
- value, getting around "iffy" rand() implementations for low order
- bits (from *Numerical Recipies in C*);
- * stuff::one_chance_in() to clarify conditionals like ".. &&
- random2(foo) == 0 .." -- !one_chance_in() more intuitive than
- !random2(), too;
- * stuff::stepdown_value() to replace [and generalize] repeated
- conditional chains in spells2.cc;
- * stuff::table_lookup() to randomly return a value from an unbounded
- value list and associated probabilities; and
- * food::is_carnivore() to handle set conditional evaluation in
- food.cc and itemuse.cc.
-
- Changes to Existing Functions:
-
- * item_name::initial() -> item_name::clear_ids() to clarify what
- task this function performs;
- * extended random22() to accept any number of 'dice' for averaging,
- renamed to random2avg();
- * extended random40() to accept any limit, renamed random2limit();
- * "fixed" item_use::drink_fountain();
- * "fixed" spells2::cast_twisted() a bit -- needs more fixing still;
- * nested [in place of stacked] strings of conditional statements in
- player::you_resist_magic(), beam::check_monster_magres(),
- skills2::clac_ep() to eliminate needless value checking;
- * changed create_monster() call in spells2::summon_butter() to
- duration 22 [from 21] to match other summoning spells;
- * altered staff description routine in describe.cc to prepend "This
- staff";
- * dungeon::box_room() optimized for efficiency -- lopsided odds for
- placement of one (and only one) additional door reflects original
- algorithm [I cannot explain why it should be this way];
- * dungeon::city_level() clarified and optimized;
- * dungeon::place_shops() optimized a bit;
- * dungeon::plan_4() optimized a bit -- removed variable boxy_type,
- as it was useless;
- * dungeon::prepare_swamp() optimized slightly;
- * dungeon::generate_abyss() logic clarified;
- * it_use2::zappy() -- changed func_pass[5] for ZAP_ICE_STORM to
- BEAM_ICE (23) from BEAM_COLD (3) in accordance with comment and
- spell description;
- * shopping::shop_getch() removed entirely and replaced by
- stuff:get_ch() -- differed only in that the former returned char
- and the latter unsigned char [variable ft in shopping::in_a_shop()
- changed to unsigned char as a result];
- * spell::surge_power() -- replaced successive tests with one complex
- conditional to reduce number of tests required;
- * spells2::summon_swarm() cleaned-up to make creature selection
- clearer; added giant mosquito; red wasp -> wolf spider
- [reversion]; killer bee larvae -> scorpion [as commented];
- * spells2::summon_undead() cleaned-up by replacing successive
- conditional calls to rand2() with one switch call to rand2() per
- loop-through -- if odds look funny, it represents evaluation of
- original coding;
- * removed double assignment of numsc from spells2.cc:summon_swarm()
- and spells2.cc:summon_undead();
- * newgame::class_allowed() cases now uniformly list >disallowed<
- species for all classes [except hunter];
- * newgame.cc:init_player() -- eliminated redundant you.level_type
- initialization, general clean-up;
- * recoded describe::describe_potion() and describe::describe_food()
- to handle redundant wordings -- more cases involved, but fewer
- textual chunks duplicated;
- * functions that now return bool instead of int:
- dungeon::place_specific_trap(), fight::jelly_divide(),
- spells::which_spellbook(), and spells0::spell_type();
- * functions that now return bool instead of char:
- item_use::drink_fountain(), monstuff::random_near_space(),
- player::wearing_amulet(), spells::learn_a_spell(),
- misc::go_berserk(), spells2::brand_weapon(), and stuff::see_grd();
- * invent::invent() is now takes bool instead of char for second
- parameter;
- * overmap::print_level_name() now returns bool and takes bool as
- third parameter, which also means that already_printed is now type
- bool, too;
- * player::player_see_invis() now returns unsigned char instead of
- int; and
- * spells3::you_teleport2() now takes bool instead of char.
-
- Changes to Variables:
-
- * nulled out Great Swords array entries in skills2.cc -- no longer
- used;
- * uncommented the last four entries to the skills[][] array and
- deleted the fourth -- entries now match size of array as declared
- elsewhere;
- * converted some integer constants (foo = 59) to single-quoted
- characters (foo = ';') where appropriate; and
- * int item_sacr in religion::altar_prayer() deleted, as it was
- unused;
-
- Changes to In-Game Messages and Textual Elements:
-
- * VERSION set to "3.40pr" so people know this is not the final
- release;
- * BUILD_DATE set to "23 Feb 2000" -- I think we should use month
- abbreviation to avoid numerical confusion;
- * minor tweaking of messages relating to undead players;
- * special statue transformation message for gnomes added;
- * grammatical clean-up and rewording of all spell descriptions in
- describe.cc -- all checked, some changed a little;
- * "book of Useful Magic" -> "book of Practical Magic";
- * "book of Poisonings" -> "Young Poisoner's Handbook" (movie
- reference);
- * "book of Envenomations" -> "book of Toxins";
- * "book of Storms and Fire" -> "book of the Tempests";
- * "Anita" ->"Snorg" within its m_list.h entry;
- * "Sneaker" -> "Sneak" for stealthy types (did one become an old
- tennis shoe?);
- * "Assassin" -> "Blackguard" for stabbing to avoid confusion with
- character class;
- * "Thief" -> "Covert" for stealthy types to avoid confusion with
- character class;
- * "Axe Maniac" -> "Halberdier" for polearms -- category includes
- more than axes, so this is a better fit and avoids repetition of
- another "top level" skill name;
- * "Bombardier" -> "Flinger" for slings, as it is more descriptive of
- a slinger's actions;
- * "Crazy Person" -> "Whirler" and "Really Crazy Person" -> "Crazy
- Person" for slings -- the joke still remains, but some dignity is
- restored to slingers everywhere; and
- * "Igniter" -> "Firebug" and "Burner" -> "Arsonist" for Fire Magic.
-
- Enumerations and Defines:
-
- * COLORS #define applied to numerical values still present in
- m_list.h;
- * COLOR #defines applied to it_use2::zappy() for ZAPs not switched
- over from value numbers;
- * COLOR #defines applied to remaining codebase, where I could find
- references still using numerical values -- I think I overdid it a
- bit and need to go back and fix a particular set of replacements;
- * #define NO_MUT (in mutations.cc) replaced by last member in
- MUTATIONS: NUM_MUTATIONS;
- * #define NO_EQUIP replaced by last member in EQUIPMENT enum:
- NUM_EQUIP;
- * removed #defines (and references to them) for Tome of Destruction
- and Manuals in dungeon.cc -- superceded by BOOKS;
- * replaced 501 with ING where appropriate -- only scattered
- instances of bare 501's left in the source code;
- * MLAVAfoo and MWATERbar #defines restricted to use only in certain
- header files [m_list.h monsstat.h newmonst.h], with the exception
- of MLAVA4 used in monstuff.cc (what is it?) -- I'll clean these up
- later, but other than this, they are no longer used in the
- remainder of the codebase;
- * CLOUD_ENERGY -> CLOUD_PURP_SMOKE;
- * CLOUD_STICKY_FLAME -> CLOUD_BLACK_SMOKE;
- * MONS_SMALL_ABOMINATION -> MONS_ABOMINATION_LARGE and
- MONS_LARGE_ABOMINATION -> MONS_ABOMINATION_SMALL -- mistakenly
- reversed in enum sometime before;
- * MONS_ANITA -> MONS_SNORG -- regenerates and described as being a
- hairy troll, so must be Snorg;
- * MONS_FAKE_RAKSHASA -> MONS_RAKSHASA_FAKE;
- * MONS_SMALL_ZOMBIE -> MONS_ZOMBIE_SMALL;
- * MONS_BIG_ZOMBIE -> MONS_ZOMBIE_LARGE;
- * MS_SUMMON_LESSER_DEMON -> MS_SUMMON_DEMON_LESSER -- I like
- hierarchies;
- * MS_SUMMON_DEMON_1 -> MS_SUMMON_DEMON_GREATER -- _1 too similar to
- _I = potential typos;
- * MS_GERYON -> MS_SUMMON_BEAST -- more descriptive of actual
- function;
- * MS_SLOW_DUP -> MS_CONFUSE -- what it is according to
- monstuff.cc:handle_wand() - removed deprecate comment from enum.h;
- * NWPN_VAMPIRE_S_TOOTH -> NWPN_VAMPIRES_TOOTH -- just too awkward as
- it was;
- * added BURDEN_STATES -- applied to you.burden_state;
- * added DEMON_CLASS -- applied throughout;
- * added HUNGER_STATES -- applied to you.hunger_state;
- * added SPELLBOOK_CONTENTS -- applied throughout;
- * added UNDEAD_STATES -- applied to you.is_undead;
- * added SHOPS -- applied to env.sh_type[];
- * expanded CLOUD_TYPES: _SMOKEs, _MIASMA, _DEBUGGING, and most _MONS
- variations;
- * expanded DUNGEON FEATURES to include elements 208,209,210 (Dry
- Fountains VII and VIII and the PermaDry(tm) Fountain,
- respectively);
- * expanded OBJECT_CLASSES to include OBJ_GEMSTONES;
- * expanded SYMBOLS to include SYM_DEBUG;
- * expanded ZAPS to include added ZAP_ISKS_CROSS -- current use
- commented out in zappy(); and
- * mass enum'ing all over the codebase -- you name it, I tried to
- enumerate it.
-
-
-10.01.2000 [Brian Robinson]
-
- * From Josh Fishman:
- + lots of enumming, mostly spells;
- + Paladins get a long sword and long sword skill to start;
- + Spriggans may now be stalkers;
- + poisoning something already poisoned gives extra naughty;
- + more powerful staves added;
- + armour skill no longer affects penalty to spellcasting for
- wearing armor;
- + summon small mammals spell improved; and
- + Vehumet will protect against spell failures and preserve
- intelligence.
- * large characters receive a smaller spellcasting penalty for
- bearing large shields;
- * easy crawl bug in wizard mode fixed;
- * wiz commands for controlled blink and create up staircase added;
- * wiz help fixed so that all wiz commands now have help;
- * subspecies selection in newgame.cc changed to prevent duplication
- of information -- see the newgame.cc for details;
- * Ogre berserkers now start with Club skill level 3 and Maces skill
- level 1 -- the reverse of all other races, because they begin with
- clubs rather than axes;
- * Troll berserkers start with Unarmed skill level 3 and Dodging
- skill level 2, but no weapon skills -- because they start without
- weapons;
- * Halflings may now be assassins and warpers; and
- * Thieves start with more gold: random2(10) * 6 + random2(10) * 4.
-
-
-30.12.1999 [Brian Robinson]
-
- * linuxlib.* axed
- * versions.txt updated to reflect new release
- * version and build date #defines in version.h updated
- * a little more explanatory info added to init.txt
- * some completed tasks eliminated from todo.txt and bugs.txt
- * disclaimer added to this file
-
-
-27.12.1999 [Linley Henzell]
-
- * USE_NEW_RANDOM tuned to reasonable pace when an FP coprocessor is
- absent
- * many minor tweaks
-
-
-09.12.1999 [Linley Henzell]
-
- * new berserk code works with ctrl+direction attacks
- * savefiles deleted after death (under DOS, at least)
- * xp no longer awarded for killing creatures created friendly
- * a few new low-level monsters
- * new init.txt options:
- + colour-code play-screen map, like the 'X' map
- + remove monsters and clouds from map
- * horned characters can wear caps and hats
- * class names switched back into lower case (where appropriate)
- * informed when a monster's enchantments wear off (if in view)
- * more information provided when looking at a monster
- * monsters no longer cast animate dead when corpses aren't in sight
- * most abilities can be used while hungry (not starving)
- * monster invisibility can now wear off (it couldn't before)
- * deflect/repel missiles enchantments now affect missile traps
- * dexterity affects shield use
- * monster AI improvements:
- + strong monsters only pick up missiles if already carrying
- some
- + some improvements made to monster path-finding
- * USE_NEW_RANDOM rand() removed -- randart code relies on random()
- * ghosts deal 2/3 as much damage; xp value reduced
-
-
-18.11.1999 [Daniel Ligon]
-
- * shop prices right-justified
- * yellow Xom patch fixed
- * Xom will sometimes answer prayers
- * evasion strengthened
- * killed-by list enumerated; added "killed by an exploding spore"
- * many calls to 'random() % x' replaced with 'random2(x)'
- * calls to random3() and random4() eliminated
- * Makhleb's minor destruction toned down
- * amulets placed in the discovery listing
- * beginning spells fixed for kobold summoners
- * invisible undead referred to as "it"
- * Spriggan assassins permitted -- speed/low food requirements
- (Spriggan) greatly complement hand crossbow (assassin)
-
-
-15.10.1999 [Brian Robinson]
-
- * can acquire() food: royal jellies given to non-ghouls; royal
- jellies or chunks to ghouls (attempted a variety of foods; proved
- too big a pain)
- * '#define XOM_ACTS_YELLOW' added to AppHdr.h
- * acr.cc:srand() added for USE_NEW_RANDOM to work properly
-
-
-14.10.1999 [Brian Robinson]
-
- * fixed: problem where some super-long strings in describe.cc got
- cut up, causing a compiler error (where possible, please try to
- keep lines < 80 characters)
- * describe_god() enumerated in describe.cc
- * makefile.sgi option added to Makefile (doesn't work)
- * fixed bugs culled from bugs.txt
- * EasyCrawl(tm) door opening: walking into door opens it, running
- into door opens the door and stops player
- * GOD_NO_GOD case added to describe.cc:describe_religion() (it was
- an acr.cc special case, but that's gone now)
- * '#include <stdio.h>' added to fight.cc and spells2.cc because both
- call sprintf() (would compile/link properly without it under Linux
- but not DOS)
- * makefiles .dos, .emx, and .sol tweaked
-
-
-12.10.1999 [Brian Robinson]
-
- * version string changed to "3.40" and '#define BUILD_DATE' added to
- version.h for output alongside version number
- * '#define USE_NEW_RANDOM' added to AppHdr.h
- * duplicate/completed items removed from todo.txt (may have missed
- some -- only cut those marked "done")
- * inspect item command (in shops) changed to 'v'
- * contents of oldmakefiles directory archived as oldmake.zip
- * make distclean now deletes *.sav, *.lab, core, and *.0* (DOS and
- Linux)
- * fixed: some class names in newgame.cc were not capitalized
- * new random number generator added -- should be a little better
- than old RNG; uses rand() rather than random() to generate number
- (#define USE_NEW_RANDOM to enable)
- * wizmode fixes:
- + some creatures (e.g., necrophage) reduce max_hp (NAB:
- reduction to zero normally means death) -- in wizmode,
- negative max_hp results, triggering "you died, but its okay"
- message every turn; added "you.max_hp = abs(you.max_hp)" to
- the 'h' wizard command to correct negative max_hp
- + stethoscope unmapped from 's' key -- terribly annoying for
- me, since I can't rest with '5' under Linux (can still
- stethoscope by targetting or looking)
- + WIZARD compiled binaries append "Wiz" to any scores they
- generate
- + help screen added, accessed by keying in '&' then '?' (lists
- wizard commands in a fashion similar to normal help screen)
- + bugfix: Daniel's command code blocked wizard command
- * Daniel's patches:
- + '#define XOM_ACTS_YELLOW' to render Xom's messages in yellow
- + bugfix: Abyss crash bug
- + new wizmode commands: "banish" and "Xom acts"
- * 'v' and 'V' commands swapped -- examining an item seemed more
- likely (to me) than version check, so "examine" now lowercased
- * wizard option added to Makefile (same as debug but includes
- -DWIZARD)
- * weapons of reaching used to attack one monster behind another may
- instead hit the monster inbetween
- * giant races penalized less for using large shields; normal-sized
- monsters may be penalized slightly more, but only by one or so
- * debug.cc:error_message_to_player() added to output:
- "You have encountered a program bug.
- Please exit the level and save."
- (previous instances of this message replaced with calls to this
- function)
- * haste and slow counters in acr.cc changed to take into account
- amulet of resist slow: haste subtracts random2(2) each turn
- (rather than one -- which could have led to infinite haste, but
- let's not worry about that) and slow subtracts five (one
- previously) each turn
-
-
-02.10.1999 [Brian Robinson]
-
- * help screen reformatted to spot entries more readily (at a
- glance); added "more" capability so that [command summaries >
- screen size] prompt user for more, preventing screen overflow
- * amulet of maintain speed changed to the amulet of resist slowness:
- old item description mentioned both resist slow and a speed bonus,
- but the code only implemented resist slow -- wearing the amulet
- now grants +10 to any hasting and also to maximum possible hasting
- * some silly messages involving hasting and slowing changed
- * messages indicating spell-casting failure added to the raise dead
- functions, but I'm not sure they work (coding very confused here;
- may only work some of the time)
- * '#ifdef LINUX'-ed the acr.cc code [lines 663 - 676] which uses
- variables declared in another '#ifdef LINUX' block (something may
- be screwed up because I'm not sure what's going on here)
-
-
-29.09.1999 [Brian Robinson]
-
- * highscore() fixed so that it doesn't take so long
- * scores output padded with some whitespace to improve appearance
- * bugfix for 'a' being in scores (see bugs.txt and ouch.cc)
- * comments added to enum.h showing where unique monsters are
- * first argument removed from view.cc:draw_border() (same value
- always passed)
- * bugfix: player's score not always saved
- * some problems with the new makefiles noticed while compiling under
- DOS: any platform with its own library (e.g., liblinux) should be
- +='ed to OBJECTS in appropriate system-specific makefile
- * Makefile: noopt (no optimization) added to allow me to compile
- under DOS without headaches
-
-
-28.09.1999 [Daniel Ligon]
-
- * linuxlib.* renamed to liblinux.*
- * keypad for ncurses (Linux port) enabled
- * liblinux.cc:kbhit() will always return 0
- * big lookup table added to liblinux.cc to convert keypresses into
- commands
- * enumerated commands added to both enum.h and big switch statement
- in acr.cc
- * Brian's makefiles added
-
-
-24.09.1999 [Brent Ross]
-
- * bugfix for evasion
- * macro.cc:getch_mul() reverted
- * red devils have probablistic chance for (trident|demon trident|no
- weapon)
- * demon tridents correctly coloured
- * xp spending cap/MAX_SPENDING_LIMIT
- * broad axe, spiked flail, and great flail less common
- * floating point operations in update_corpses() reduced
- * all demonspawn scales/plates can be given at one or two levels
- * max_hp ceiling displayed when player's max_hp reduced
- * from Linley:
- + portal fixed so that it doesn't go below level 27
- + fixed checks for translocating in the Abyss
- + added fix for going to Pandemonium or the Abyss from Hell
- + note about using '+' for targeting added to various prompts
- + ghosts fade away only if they have fewer than half their hp
-
-
-12.09.1999 [Linley Henzell]
-
- * "Over-map" added
- * messages can be coloured -- just call set_colour() before mpr()
- * wild magic effects do more harm; increased likelihood of higher
- levels of effect
- * blink may not work and teleport takes longer in the Abyss
- * a few unrandarts tweaked
- * rewrote part of dungeon.cc weapon generation function; added
- weapon rarity function
- * some monsters receive a wider range of weapons
- * many high-powered demons have greater speeds
- * several changes to skills.cc; having many xp in the pool increases
- the cost of exercising
- * threshold values increased for special "you hit" messages and some
- grammar patched -- see fight.cc
- * three 'silly' monsters removed: dorgi, sword, and guardian robot
- * haste has a direct effect on time_taken, rather than being treated
- separately -- see player_speed()
- * boots of levitation allow permanent hovering
- * random events in Hell are much nastier
- * clouds can be overwritten by other clouds, sometimes -- see
- place_cloud()
- * monster mutation spell affects monsters as polymorph
- * new init.txt variable [verbose] determines level of detail about
- randarts and other magical items in character dump
- * monsters can cast 'direct' spells (e.g., smiting) over other
- monsters if targeting player
- * giants given the correct number of rocks
-
-
-09.09.1999 [Brent Ross]
-
- * damage lowered for some new weapons; tridents made heavier
- * some changes from Dustin Ragan added to the newgame screens
- * spellcasting reduced by weapon size [weight and/or speed]
- * from Linley:
- + verified helmet/helm colour initialisation to LIGHTCYAN
- + swapping item letters outputs both items affected
- + '=' fixed to '==' in randart.cc line 1515
- + bugfix: more scrolling problem under DOS
- + bugfix: problem with the ctrl-direction keys under DOS
- + subspecies selection made into compile time option
- + horns mutation removed as a possibility for minotaurs
- * Great Swords skill removed -- great swords/triple swords treated
- as long swords
- * Trolls + troll leather changed to no effect
- * gdbm stuff removed -- makes things simpler; better security can
- wait for new savefile implementation
- * hand-and-a-half weapons:
- + no bonus if weapon is cursed
- + 1-1/2 hand weapons don't get the speed bonus past 10
- + two-handed weapons can get as fast as speed 7 with skill
- + +random2(3) to hit
- + +random2(3) to dam [all two-handed weapons] applied after
- skill multipliers (i.e., with the dwarf and orc modifiers)
- * multiple shield blocks in a turn becomes increasingly difficult
- * fighters get dodging or armour skills on basis of starting armour
- * shields and large shields slow down attacks
-
-
-27.08.1999 [Brent Ross]
-
- * character dump includes '*' for level 27 skills
- * removing the "skill_change /= 2" line from spell skills was a bit
- hard on early spellcasters (it seems reasonable to give to
- low-level characters and phase out by mid-game, when it isn't
- needed)
- * bugfix: "Crush" required conjurations (hold over from Throw
- Pebble)
- * bugfix: having 1 xp in the pool permitted a lot of free practising
- * penalty increased for heavy armour, now more in line with the new
- shield penalty (are these values high enough?)
- * Linley's new weapon suggestions added: axe, spiked flail, great
- mace, great flail
- * damage increased for some maces and flails (swords are quick and
- accurate, maces and flails hit harder)
- * "Boots" changed to "Barding" in centaur/naga equipment lists
- * crystal plate mail somewhat resistant to corrosion
- * +/- markers added to skills screen for benefit of monochrome
- displays
- * bugfix: labyrinth problems
- * bugfix: LOS corner problem
- * bugfix: can now make with -DWIZARD
- * spellcasting/invocation interference removed
- * weapon additions: broad axe [rare, 15, +3, 17], trident [9, -2,
- 16], and demon trident [evil -- wielded by red devils: 15, -2, 16]
- * polearms/whips of reaching added
- * gladiators given choice of starting with trident
- * '#define USE_NEW_BERSERK' removed
- * bugfix: incorrect display of barding AC value
- * quite a bit of cleanup (converting ints to enums in the old code)
- * draconian AC gains clean-up; removed level four increase and gave
- two AC at start
- * knife added; guaranteed on the first three levels
- * bugfix: memorizing spells was impossible on some terminals
-
-
-08.08.1999 [Brent Ross]
-
- * bugfix: Orange Brains could hang game (MS_SUMMON_LEVEL spell in
- Abyss)
- * bugfix: monsters should no longer occur "under" the player
- * bugfix: portals weren't closed on way out, but hell gates were
- removed (now all are closed)
- * bugfix: cannot unlearn spells outside the array bounds
- * bugfix: manuals should auto-identify on the first read
- * bugfix: Healing book was available from acquirement/Sif Muna
- * missile launchers no longer train/use associated skill when used
- as melee weapons (bows/xbows will train/use maces/flails, slings
- use no skill)
- * Zot traps will no longer message their effects on monsters unless
- monster within LOS
- * bugfix: liquid flame could wrap around and last a long time
- * bugfix: whatever caused "program bugs" to occur in the Abyss
- * bugfix: number of cards in Decks of Power defaulted to 0 and thus
- gave 255 cards
- * Nemelex fixed to give cards instead of Bone Lanterns and Geryon
- Horns
- * bugfix: food was not updating with cards
- * bugfix: quick blades were getting free actions
- * spell points update when Invocations gained
- * granularity of skill gain upped to reduce "stage three":
- + number of learns from manuals upped to accommodate
- + monster xp values reduced to limit "stage two" effect
- * power of smiting again reduced (seems reasonable now)
- * teleport control restrictions (some areas will not allow
- controlled teleport)
- * runes may be stacked
- * invocations and spellcasting learning interfere with one another
- (like elemental magic)
- * increased rate of skill cost per level
- * removed division by two for cost of spellcasting skills
- * greater rarity for unique artefacts (all seem to enter quickly
- into any game, except the Sword of Power, for which the 50% chance
- against creation probably kept it out of my last game for a while)
- * evasion/shields were too good:
- + shield blocking difficulty raised a bit (from base 10 to 15)
- + player's evasion rolled in the monster to-hit check (so that
- a player with an EV of 30+ can still be hit)... added a 1/15
- chance of hitting regardless (players already got this
- advantage).
- * *.h guards moved to after the headers (cosmetic)
-
-
-30.07.1999 [Brent Ross]
-
- * bugfix: visiting Abyss from Hall of Blades resulted in an Abyss
- populated by blades
- * bugfix: problems with highscore entries running off end of the
- line
- * electrical and poison resistances no longer absolute -- 1/3 damage
- taken on successful resist (still no poisoning for those with
- poison resistance)
- * storm dragon breath can be resisted
- * draining will drain available xp pool, too
- * spell levels moved to a function to prevent amassing a large
- number of negative spells (forgot spell that didn't exist)
- * spellcasting more difficult to get
- * bugfix: plants stalking stairs
- * dragon armours reverted to original values -- resistances and
- benefits given are good enough (basic heavy armours were the ones
- in real need of improvement)
- * bugfix: distortion weapons (from Jesse)
- * bugfix: deflect missiles status wasn't listed on '@'
- * slime pit runes are only "possible" runes -- unlikely to get four
- of them now
- * stats added to "elf" dummy monster to allow elf zombies to live
- * added redraw after projected noise
- * bugfix: objects (runes, orb) were clobbered by items given to
- monsters.
- * monster descriptions with huge gaps in them were fixed
- * bugfix: shapeshifters shouldn't polymorph into dancing blades
- (numbers for names)
- * acquirement() better than before for jewelry
- * skills screen can handle more than 26 skills
- * levels of poisoning shown for '@'
- * traps more difficult to disarm as dungeon level increases
- * traps might trigger during attempts to disarm
- * all traps handled by handle_traps()
- * are the new traps too hard on monsters? (probably yes, so they
- take old damage amounts for now)
- * player_light_armour() added, which returns true if the player is
- in light or no armour
- * bugfix: non-flying monsters were flying over traps
- * polymorphed monsters not much of an easy xp trick anymore
- * xp calculation takes into account a monster's speed
- * plant learning capped (no more than first two levels of fighting
- skills)
- * some support added for explosions destroying potions/food on
- ground are only the correct things being destroyed? -- check
- bang.cc and destroy_item()
- * wearing heavy armour provides a minium percentage of damage
- reduction:
- + percent = (skill + base AC of body armour)
- + still needs application to monsters, but monsters don't
- convieniently know whether they possess hard armour (let
- alone armour skill) so this can probably wait
- * extra protection from shrapnel attacks provided by heavy armour
- only
-
-
-13.07.1999 [Brent Ross]
-
- * entrance to the Labyrinth blocked until debugged
- * wizmode code in acr.cc fixed; changed some commands to more easily
- remembered letters; added an identify
- * fixed some cases where cursed jewelry plusses are assumed to be
- based off 100 (creation code and many other cases suggest that
- it's 150)
- * random weapons, armour, and jewelry from acquirement() are now
- uncursed
- * demonspawn horns smoothed out so it's possible to get two levels
- * ranger changed to hunter
- * some gmon_use values changed (from Linley)
- * life protection descriptions changed
- * hunger_inc and ATTR_LIGHTNING_RESIST moved to functions in
- player() -- the attribute is now replaced with
- ATTR_DIVINE_LIGHTNING_PROTECTION (used to denote Makleb or Xom
- protecting player from a lightning attack)
- * checks added for the curses keypad enums
- * learning curve for throwing skill lowered
- * hand crossbows reduced in power
- * learning curve for traps and doors skill lowered
- * played with spellcasting staff identification
- * player ghosts fixed:
- + monsters regenerate hp while player is off level
- + ghosts regenerate and teleport away when player leaves the
- level
- * assassins changed from ninja to hand crossbow types; given
- enchanted dagger as well to help hand-to-hand
- * throwing exercise added to darts, hand axes, daggers, and spears;
- throwing skill bonus added for them, as well -- see item_use.cc
- * scythes, halberds, and glaives given a chance to be weapons of
- speed
-
-
-07.07.1999 [Brent Ross]
-
- * breath from ice-breathing dragons won't destroy walls
- * life protection now a (level/3) chance
- * bugfix: the 120/150 hp ghost thing
- * anticheat code and security db added for multiuser systems
- (requires gdbm)
- * only picking up items has associated delay with autopickup,
- walking over uninteresting stacks shouldn't cost any extra time
- * berserk players fail the check_awaken() test with monsters and do
- not spend experience on stealth
- * dexterity added to stealth
- * ogre magi given short swords instead of daggers
- * stabbing stun effect toned down
- * stabbing dex bonus toned down -- now limited by stabbing
- * assassins start with a dagger; thieves start with short sword and
- dagger
- * stat mods reversed for thief and assassin; assassins given unarmed
- combat
- * wizard stat mods changed to +7 int/+3 dex, making them smarter
- than other spellcasters
- * draconian rangers no longer start with leather armour
- * stealth toned down a bit (and again) in player.cc:check_stealth()
- * to-hit reduced for throw fire/frost and sting -- see
- it_use2.cc:zappy()
- * bugfix: repel/deflect missiles problem -- changed bad REPEL
- reference in acr.cc
- * message added to unwielding vampiric weapons
- * new keypad support hacked up for Unix
- * shots used up 1 in 3 times
- * bonus for crossbows' to hit and dam (item_use.cc)
- * magic resistance for elves (player.cc)
- * autopickup delay upped to 3 (one and two seem to be no delay at
- all)
- * opposing elemental staves can be identified (items.cc, spell.cc)
- * zipfile removal added to ouch.cc to prevent cheating
- * bugfix: view.cc STABBING check should be STEALTH for the no-yell
- check; lowered to a straight percentage check
- * Dwarven/Orc rangers given Dodging 1 (they were a bit short on
- skills)
- * HOrs get orcish bolts (newgame.cc) -- added MISSILES check in
- HILL_ORC check
- * gladiator/fighter modifications: (newgame.cc)
- + fighters: skills -- fighting 3, weapon 2, dodging/armour 2,
- shields 2, stabbing/stealth 1, throwing 2; stats -- str +7,
- dex +3
- + kobold/troll/ogre fighters: same as before
- + gladiators: skills -- fighting 3, weapon 3, dodging/armour 2,
- shields 1, unarmed combat 2; stats -- str +6, dex +4
- + comparision to previous values:
- o fighters: lost unarmed combat; +1 shields and +1
- throwing
- o gladiators: -1 dodging/armour and -1 shield; +2 unarmed
- combat
- o stat bonuses swapped
- o armor for gladiator/fighter switched
-
-
-22.06.1999 [Brent Ross]
-
- * new ranger weapon variations (halfling slingers, dwarven
- crossbowers)
- * Ranger/Reaver problem fixed -- 'R'angers are now 'r'angers (so
- capital letter R used only once)
- * stealth improvements:
- + monsters don't yell (2 * skill) % of the time -- see
- view.cc:monster_grid()
- + large races lose *2 modifier, small races receive *5/2 -- see
- player.cc:check_stealth()
- o Huge (x1): Troll, Ogre, Ogre Mage, Centaur
- o Awkward (x3/2): Minotaur, Draconians
- o Normal (x2): Everyone else
- o Small (x5/2): Halfling, Gnome, Kobold, Spriggan, Naga
- (Naga's aren't small, but they're good)
- + BEH_CHASING_I set for sleeping monsters who are stabbed
- + now a (skill + dex)% chance of stabbing fleeing or confused
- monsters -- see fight.cc
- + backstab effectiveness depends on the monsters behaviour:
- o sleeping monsters are easy targets -- lots of damage
- potential
- o fleeing and confused monsters -- not as much damage
- potential
- o other cases have even less damage potential
- + backstabbing more effective for daggers: daggers add dex/3
- damage before the multipliers -- see fight.cc
- * fight.cc:monster_dies() modified so that *any* summoned creature
- killed by player/pet won't call done_good()
- + Elivion/TSO/Zin have to be passed through (not a problem
- because they can't abuse summoning, anyway)
- + this could use a better fix (i.e., tracking who summoned
- which monsters would help a lot)
- * (Linley's suggestion) monster polymorph fixed to avoid NO_EXP
- monsters: added "mons_flag(targetc, M_NO_EXP_GAIN)" to do-while
- loop
- * (Jesse's suggestion) teleport control/blink spell combo removed:
- CONTROL_TELEPORT check removed from random_blink()
- * racial bonus added to worn armour in player_AC()
- * patched hunger status display bug: added food_change() and redraw
- to down_stairs
-
-
-17.06.1999 [Brian Robinson]
-
- Note: I've tried to annotate all my changes in the code with my
- initials [BCR] so you can grep for them to find my changes.
-
- * some small cleanup here and there
- * new makefile written for Linux
- * changes to the make process which should spare us future
- headaches:
- + OS_TYPE variable in the makefile that is automatically made
- into a #define during make process (should make it easy to
- keep the makefiles straight on the OS)
- + moved OBJECTS variable containing the list of the *.o files
- to a file called make.obj which is included into the makefile
- (should save a little space and keep all makefiles consistent
- on object requirements)
- * defines.h indented and added a header
- * some newgame.cc oddness fixed: various system dependent name
- checks were all messed up in a bunch of nested #ifdef stuff
- (sorted it out)
- * '#define MACROS' now does something: if defined, macros.h and
- macros.cc files will be used, otherwise they won't (right now,
- Crawl will not work correctly under Linux with MACROS defined --
- see bugs.txt)
-
-
-14.06.1999 [Brent Ross]
-
- Some changes I added from Linley:
-
- * bugfix for the Geryon bug
- * message added for berserkers chopping up corpses in rage
- * some incorrect enums in it_use3.cc (for Asmodeus's staff) changed
- * demonspawn xp penalty lowered to 140%
- * Elyvilon sacrifice code fixed to limit abuse
- * priest.cc and priest.h renamed to abyss.*
- * spellcasting penalties for wearing shields upped to +5/+15/+30
- from +0/+5/+15 [buckler/shield/large shield]
- * random stat increase added for Draconians
-
-
-13.06.1999 [Brent Ross]
-
- * Spriggans fully separated from the giant races, creating a
- separate block for tiny races in the armour wearing code
- * cursed rings identify themselves as "sticky cursed" when put on
- * weapon slot updates if player eats food that is being wielded
- * bugfix: black and grey scales reversed for demonspawn (with
- regards to number of levels gained)
- * for spells1.cc, blink() and random_blink(): weapons check removed
- because scan_randarts should be only requirement
- * bugfix: teleport control now works properly on blink (dependent on
- order of includes and target compiler/system)
- * #ifndef checking added around all *.h files to avoid problems
- similar to those above
- * full spell listing line added to character dumps
- * creaky doors are [DEX + (Stealth + Traps) / 2] checks; check added
- on closing doors, as well
- * base values of heavy armour upped by 1 or 2 points
- * spells3.cc:you_teleport() was another case of only checking the
- weapon slot for a property (hopefully, I've changed all these into
- scan_randarts)
- * mutation.cc:demonspawn() had MUT_FAST twice; changed the second to
- MUT_SHOCK_RESISTANCE (as the comment claimed)
- * strength damage bonus had an ugly discrete nature to it;
- multiplied the dammod values by 6 to get a smoother version of the
- same function
- * bugfix: screen needed to be refreshed after spell slot changes
- * new equipment listing commands:
- + ')' lists current, swap a, swap b, and default 'f'ire weapons
- + ']' lists worn armour
- + '"' lists worn jewelry (NB: '=' already used elsewhere)
- * bugfix: "shoot_skill = you.skills[SK_THROWING]" in item_use.cc was
- wrong (should clearly be CROSSBOWS when using a crossbow)
- * bugfix: handle_traps in misc() used env.trap_known instead of
- trap_known (env.trap_known doesn't seem to be referenced anywhere
- else)
- * bugfix: Vehumet's gift was still not quite correct
- * magical staves detection: staves may be detected over time or
- whenever appropriate magic is cast, depending on skill levels
- * Call Imp raised to a level three spell (too powerful for level
- two)
- * a little checking code added to dungeon.cc for monster armour
- plusses
- * bugfix: more line was misplaced on the recognized item screen
- * mix of my/DML's improvements applied to the temp file purging
- system
-
-
-02.06.1999 [David Loewenstern]
-
- * Makefile.dos added
- * define.h updated for compatibility with DJGPP
- * items.cc, monstuff.cc, mstuff2.cc, and spells.cc cleaned up
- (mostly corrected misassignments, unsigned<->signed, unused vars,
- etc.)
- * enums added to monstuff.cc, mstuff2.cc, beam.cc
- * enum.h updated as per above
- * autopickup added
- * '&' command functions only in debug mode
- * remove_ring() now uses inventory letter
- * fight.cc features more colourful "hits" (should be useful later to
- differentiate weapons)
- * bugfix: displaying top scores when no scorefile previously had
- existed
-
-
-30.05.1999 [Jesse Jones]
-
- * highscore() will print more scores on larger windows
- * worn cloaks no longer prevents wearing or removing body armor
- * worn armor can be dropped if it's uncursed
- * armor can be worn without removing the old armor
- * missing ponderous armor message added
- * from Brent:
- + bugfix: weapon line didn't always redraw after casting Blade
- Hands
- + detect_items() uses '~' instead of '*'
- + char_dump.cc dumps failure rates
- * wear_armour() changed to allow Spriggans to wear bucklers
- * quit only pops up save changes dialog if game_has_started is true
- (Mac)
- * AppHdr.h replaces config.h
- * all *.cc files include their header immediately after the AppHdr
- file
-
-
-??.05.1999 [Brent Ross]
-
- * GNU indent 1.91 [-bad -bli0 -i4 -npcs -npsl] applied to get the
- intended BSD indentation style into the code; sorted through some
- things indent won't fix (more cleanup needs to be done -- notably,
- vertical whitespace and breaking up big lines -- but should be
- more readable now; no more column 0 code!)
- * various changes to make code work with NUMBER_OF_LINES instead of
- 25
- * compile-time option to change default view to non-ibm graphics
- * ^R redraw screen command; screen redraws added to appropriate
- places
- * query added for normal saves (^X doesn't ask)
- * ^Y works now; ^Z suspend for Unix systems
- * refresh call added to beam.cc so beams are always visible
- * various things to deal with multiuser environment:
- + compressing save files
- + permissions handling
- + global lib directory for game files
- + changes in name validation and file name structure (added
- uid)
- * adjust item letter function now swaps items (instead of failing)
- * Selective Amnesia spell description is less confusing
- * targeting more intuitive for Angband players (t/space accepts
- targets), behaves better about canceling spells (added better
- abort)
- * unarmed combat fixed to the correct amount of time
- * bugfix: hunger/noisy wield bug where effects were not removed
- * bugfix: air staffs didn't grant resist lightning, yet took it away
- (i.e., left the resist with a value of 255, quite good unless you
- put on something of resist lightning later)
- * rings/wands/scrolls and such output a message when they are
- identified by use
- * fixed several cases where wielded object changed but the screen
- didn't update
- * bugfix: a triple level of a demonspawned mutation was never
- granted
- * patched bug where the inventory is full yet the count is wrong
- (this entire thing should be cleaned up)
- * curses attributes fixed so that alternate character sets aren't
- used under Solaris (this is probably good for any *nix not on a
- IBM alternate character set box)
- * water and earth elementals fixed for same
- * stone lined the finishing room so you can't dig through?
- * some rather silly ways of clearing areas of the screen (under
- curses) removed; proper curses functions used instead (much
- faster)
- * bugfix: going up or down stairs would clear the food status
- * bugfix: incorrect substitutions of new enums (i.e., "AC +=
- SP_HIGH_ELF; /* troll */")
- * bugfix: stat increases where comment noted "/* str or dex */", but
- "str or int" given instead
- * Troll's food consumption increased to better balance the race
- * Vehumet's gift giving code fixed to actually do what is intended
- * experience pool information added to front page
- * some of the duplicated titles (traps and doors) changed
- * stairs leading out of sub-dungeons changed to '<' character, to
- reflect the key required
- * portals coloured on the level map; all portals in Pandemonium are
- intentionally the same colour
- * kobolds receive stat increase every five levels
- * bugpatch: Demonspawn sometimes don't receive their mutations
- * Armour skill a bit better: get more in combat, a little more
- frequently otherwise; EV penalty is now recovered at skill/2
- * Sword of Power reduced in power (now +20 cap, HP/13 - 3)
- * creaking doors partially depend on skills (dex + traps + stealth,
- with benefits of last two dropping after a total of 10) instead of
- simply luck; levitation isn't a sure way to avoid this now
- * wield update inserted after reading scroll of recharging
- * high score file extended to SCORE_FILE_ENTRIES items (currently,
- only the first 15 are ever displayed)
- * USE_NEW_BERSERK:
- + berserk counter decrements faster when not attacking
- (currently using triagular progression)
- + butchery is not penalized (in fact, it resets penalty
- counter); eating isn't either (no reset, though)
- + exhausted counter added to count berserk fatigue
- + hopefully this will become part of a new, better standard
- berserk
- * skills fit onto screen by wrapping the first column (if required)
- * bugfix: RAP_PREVENT_TELEPORT and the like didn't do anything
- because they checked only the weapon, instead of using
- scan_randarts (hopefully, all the cases of this are fixed now)
- * bugfix: wield-amulet-that-you're-wearing bug
- * redraw for weapon when Blade Hands expires
- * #defines:
- + CRAWL_NAME -- auto sets player's name
- + CRAWL_PIZZA -- string describing player's choice of pizza;
- greater likelihood of incidence than others
- + USE_BSTRING_H -- handles the bstring.h/string include problem
- + NUMBER_OF_RUNES_NEEDED (defaults to 3) -- allows compiled
- games to limit entrance to Zot's domain only to those with a
- certain number of runes
- + USE_CURSES -- for things specific to curses and not just
- PLAIN_TERM.
- + USE_TCHARS_IOCTL, USE_UNIX_SIGNALS, USE_SELECT_FOR_DELAY --
- to solve various *nix variant problems should people need or
- want them
- + USE_ASCII_CHARACTERS -- sets the default to non-IBM character
- set
- + SAVE_DIR_PATH -- useful for setting a global lib directory
- for save files, bones files, and the score file
- + SHARED_FILES_CHMOD_VAL -- useful with SAVE_DIR_PATH on
- multi-user systems
- + SAVE_PACKAGE_CMD, LOAD_UNPACKAGE_CMD, PACKAGE_SUFFIX -- for
- people who want to use a program to compress and bundle their
- save games when they're not playing (not pretty, but good
- enough until we invent a better save file system)
- * "(q to drink)" added to fountain description when player steps
- over one
- * Greater Healings base upped to 50
- * Demonspawn transmuters added
- * Spriggans and Halflings consume less food (-1)
- * wizard's hats and caps are randomly coloured
- * carrying capactiy less dependent upon strength; pulled
- carrying_capacity code into a single function (as it's called from
- various different places); encumberance levels represent fractions
- of carrying capacity instead of earlier constant values
- * named artefact weapons slightly rarer; Sword of Power has 1 in 2
- check
-
-
-??.05.1999 [Jesse Jones]
-
- * bugfix: appeared to be three bugs involving extra semi-colons
- * file names can be longer than six characters and can include
- spaces
- * some debugging macros added
- * bugifx: dragon() wasn't handling fire drakes, which meant beam
- color was uninitialized.
- * getstr() only adds printable characters to the buffer (Mac)
- * mons_spells() now returns a struct instead of using an int array
- -- affects mstuff2.cc, mstuff.h, and handle_wand()
- * mons_near() now returns a bool. I've changed code like
- "mons_near(o) == 1" and "mons_near(i) != 0" to "mons_near(o)" and
- "!mons_near(i)"
- * print_description() no longer indexes past the end of the string.
- * minor changes made to the code to allow compilation with the
- "require function protypes" warning
- * UNUSED template function added to config.h
- * rewrote describe.cc and describe.h:
- + reformatted
- + string objects used in place of hard-coded char arrays
- + ten new functions split out from describe_item()
- + get_item_description() and is_random_artifact() added
- * rewrote chardump.cc
- + reformatted
- + string objects used
- + seven functions split out from dump_char
- + dumps artifact info
- * reformatted viewwindow2(); added some ASSERTs; split out
- get_ibm_symbol()
- * reformatted monster() and split out ten(!) new functions
- * reformatted mons_spells() and mons_cast(); mons_spells() case 49
- uses RED instead of (bogus) 20 for color
- * some ASSERTs added to seekmonster()
- * DEBUG renamed to WIZARD
- * DEBUG_BUILD renamed to DEBUG
- * manage_corpses() renamed to handle_time()
- * code changed to use new CORPSE_BODY and CORPSE_SKELETON enums
- * struct.h deleted
- * player::elapsed_time added (holds the total amount of elapsed time
- in the game)
- * level and game save routines tweaked to include a variable sized
- chunk of extra data
- * save level code saves a timestamp; load level code uses timestamp
- to update corpses and chunks
- * many player struct members renamed
- * all of the monsters, item_struct, and ghost_struct members renamed
- * comment blocks added to the top of all files
- * TRACE debug function added
- * you and env are no longer arrays
- * bugfix: display_char_status() displayed the wrong message if the
- player had magic contamination
- * look_around() no longer prints a prompt (so things like blink and
- open door no longer prompt "Press '?' for a monster description.")
- * show_map() accepts '\r' along with '.'
- * Cekugob no longer conveys resistances to fire and cold
- * spellbook_contents() prints unknown spells in light blue
- * show_map() draws shops in yellow
diff --git a/stone_soup/crawl-ref/docs/changes.400 b/stone_soup/crawl-ref/docs/changes.400
deleted file mode 100644
index e5d853b1f0..0000000000
--- a/stone_soup/crawl-ref/docs/changes.400
+++ /dev/null
@@ -1,3278 +0,0 @@
-9 August 2001, Michal Valvoda
- * Gordon's destroy_item() fix included
- * Complete clean-up of dungeon.cc::give_item() + few changes
- for example
- - Until now was a lot of items colored twice (by give_item()
- and by item_colour()) and sometimes differently
- - every item goes to right MSLOT-no more MISCELLANY in MSLOT_POTION
- - magical items (wands, scrolls, potions) distribution
- * repel undead is working again (in turn_undead() was missing call for
- behavior_event())
- * added messages for rotting chunks/corpses in player's inventory
- * message when Corona wears out + few other new messages
- * fixed some (I hope that all) problems with "polymorph other".
- As side effect of some solutions
- - MONS_HUMAN and MONS_ELF are now valid and fully functional
- polymorph targets
- - useless MONS_ANOTHER_LAVA_THING was changed to
- MONS_SALAMANDER (in case of problem switch it off in dungeon.cc,
- yes, there because water and lava monsters are generated differently)
- * Renamed MSLOT_UNASIGNED_I to MSLOT_MISCELLANY, added NUM_MISCELLANY
- * rewrote misc. object generation to use NUM_MISCELLANY.
- Not important for now but I have many new misc. objects I want to include
- after release and it will help later. Also new code is much more readable
- and easier to modificate.
- * inteligent monsters now pick up gold
- * added some new unrand artifacts
- (ring of Shadows is getting a bit tired :)
- * added underground rivers and lakes,
- improved water generation
- * 3 new compile options
- #define USE_NEW_UNRANDS - switches new unrands on
- #define USE_RIVERS - switches new underground rivers and lakes on
- #define MISSILE_TRAILS_OFF - turns misile trails off.
- - not optimal, but works well on
- many computers
- - defaultly unset
- * other minor fixes and updates
- * changes.400 updated
-
- Notes:
- ! generation of water and lava monsters isn't very nice, an it would be
- fine to change it one day
- ! spells in WIZARD mode probably should be cast with some power
-
-
-
-
-
-
-
-BUGLIST:
-
-
-LEGEND
-** outstanding bug; reproduced or definitely needs fixing
-xx outstanding bug report; unreproducable, currently unfixable,
- or not a candidate for 4.0.0 release
-== fixed and released in some form (alpha, beta, etc - see version.h)
--- fixed bug, not yet released
-
-
-
-
-** Various XXX and FIXME comments throughout code from Brent.
-
-== 1. Casting "Corona" at self shows message "The 0 hits you !" and
-hurts you (same for Hibernation, maybe also other spells.)
-
->> fixed Corona and Hibernation. Possible that other spells still
->> allow this goofy behavior.
-
-== 2. Dwarven hunters starts with CYAN leather armor (maybe also
-others). It should be BROWN.
-
-== 3. Missing space in message "You feel verybuoyant !" (same problem
-with "You feel morebuoyant !")
-
-== 4. No message when you quaff potion of restore abilities and nothing
-happens.
-
-> fixed by Brent?
-
-== 5. Maybe there should be some message when you cast "Static
-Discharge" and no monster around.
-
-== 6. Inscription on "Innate abilities, Weirdness & Mutations" screen
-should be centered (my fault).
-
-== 7. Polymorph and unpolymorph messages are really odd -
-e.g. I polymorphed kobold and I got message
- "The stone giantThe kobold evaporates and reforms as a stone giant."
-
-== 8. Empty ebony casket should be DARKGREY and not BLACK.
-
-== 9. Rare weapons (quick blade, double/triple sword etc.) aren't as
-rare as they should be.
-
-> line 2006 in dungeon.cc should be 1+random(10) <= rarity
-
-== 11. Missing space in "Elyvilondemands penance!". Of course, same
-problem with other gods.
-
-== 12. 2 messages when wearing crystal armor about that it's too
-cumbersome
-
-== 13. map under DOS is working bad - each next line is shifted by one
-character
-LRH - At line 1810 of view.cc, in the map function, there is a
-for loop involved in printing the map. At present it's
-for (i = 0; i < 79; i ++);. To work under DOS, the 79 should
-be 80, otherwise the map is skewed to the left and looks
-very ugly.
-
-== 14. stoneskin isn't working - if you look at cast_stoneskin() zou
-will see it does nothing with AC
-
-> I have a fix for this - basically remove the 'else' before the
-> transformation-AC-adjustment switch in player.cc::{player}_AC().
-
-> There's another "bug" there, too, which is that the corresponding
-> 'if' ought to include '|| you.attr[ATTR_TRANSFORMATION] =
-TRAN_BLADE_HANDS'.
-
-== 15. Saw "a buggy helmet"
- "a buggy orange potion"
- "a buggy red potion"
-
-== 16. Buggy targeting - can't hit monsters in LOS. Could fix.. both
- for throwing and beaming?
-
-== 17. A hill Orc Chaos Knight (Zom) started with 14/15 hit points. !?
-
-== 20.One more thing that needs cleaning: the new invisible monster code.
- You don't get a message when your missile hits a monster, but you
- *do* get a message when your missile *misses* an invisible monster.
- IMO if we do make invisible monsters harder to detect than they
- were, we ought to make these (absent) messages exactly opposite:
- no message for miss, yes message for hit.
-
-
-xx 21. wearing Troll Hide, read unknown scroll, ASSERT(index < SIZE) in
- FixVec fails, abortion, core.
-
-== 22. Amulet of Rage isn't auto-identified when put on, but ability is
- visible in 'A' menu.
-
-== 23. torment_monsters in spells4.cc asserts like crazy. It should have a line
-like:
- if (mon != NON_MONSTER) {
-
-> fixed again; player wasn't getting hit. Not adding magic resist.
-
-
-== 24. In dungeon.cc there's a huge function called builder() with some code at
- the bottom that looks like this:
-
- if ( you.where_are_you == BRANCH_HALL_OF_BLADES )
- {
- for (bi = 1; bi < GXM; bj++)
- for (bj = 1; bj < GYM; bi++)
- if ( grd[bi][bj] >= DNGN_STONE_STAIRS_DOWN_I && grd[bi][bj]
-<= DNGN_ROCK_STAIRS_UP )
- grd[bi][bj] = DNGN_FLOOR;
- }
-
- The increment in the for loops should be swapped.
-
-== 25. A backtrace does indeed reveal the problem. From line 2432 of
- monstuff.cc:
-
- for (count_x = 0; count_x < 3; count_x++)
- for (count_y = 0; count_y < 3; count_y++)
- {
- good_move[count_x][count_y] = true;
-
-...
-
- if ( grd[monster->x + count_x - 1][monster->y + count_y - 1] < okmove )
- {
- good_move[count_x][count_y] = false;
- continue;
- }
-
- There's a monster at (39, 69), the above loop references (38,70).
-
-== 26. This line
-
- unsigned char grik = grd[monster->x + mmov_x][monster->y + mmov_y];
-
- from monstuff.cc around line 2730 is also causing an ASSERT failure.
-
- GDL: in fact, there are a bunch of places in monstuff.cc where fleeing
- or confused monsters can try to "run off the map", apart from the
- 'good move' checking in bug 25 above.
-
-
-== 27. monsters equipped with missile weapons
- commonly associated with launchers who
- insist on tossing the missiles by hand.
-
-== 28.About line 909 of monstuff.cc is
-
- if ( show[monster->x - you.x_pos + 6][monster->y - you.y_pos + 6] )
-
- The electric eel is at (48,36), I'm at (55,32), so we're indexing (-1,10).
- The array show is 19x19, and I'm thinking the +6 should be +9.
-
- There's a similar construct for lava snakes a little further up.
-
-== 29. An indexing error in item_use.cc, line 3092 or so, after reading a scroll
- of enchant armour while not wearing body armour.
-
- you.inv_type[you.equip[EQ_BODY_ARMOUR]] is inspected even though
- you.equip[EQ_BODY_ARMOUR] is -1.
-
-
- do
- {
- affected = 1 + random2(6);
- }
- while ( you.equip[affected] == -1 );
-
- // NOTE: It is assumed that armour which changes in this way
- // does not change
- // into a form of armour with a different evasion modifier.
-
- if ( you.inv_type[you.equip[EQ_BODY_ARMOUR]] == ARM_DRAGON_HIDE
- || you.inv_type[you.equip[EQ_BODY_ARMOUR]] == ARM_ICE_DRAGON_HIDE
- .
- .
- .
- )
-
-== 31. I just disarmed a blade trap, and the game seemed to hang.
-
-Since TRAP_BLADE are of type DNGN_TRAP_MECHANICAL, this code in misc.cc,
-line 1492 or so, tries to make a stack of trap items:
-
- if ( trap_category(env.trap_type[i]) == DNGN_TRAP_MECHANICAL )
- {
- for (j = 0; j < 20; j++)
- {
- itrap(&beam[0], i); // places items (eg darts), which will automatically stack
-
- if ( j > 10 && one_chance_in(3) )
- break;
- }
- }
-
-But misc::itrap() doesn't create these blades, and instead:
-
- default:
- getch();
- break;
-
-waits for input. It seems like a very strange default. Ultimately,
-you can wait it out by moving back and forth. Then you find a few
-questionable item where the trap was.
-
-== 32. Banishing self to Abyss when you are at Abyss does really
- strange effects
- ("The 0 hits you !" - I really don't understand why)
- Propably it's connected with 0-beams problem -
- some spells shows message "The 0 hits you !" when cast at player
- I suggest some kind of check whenever is 0-beam casted (e.g. if
- its targeted at player then shows message "It's not good idea."
- or so)
-
-== 33. I don't know how it happened but I've found 2 off-screen corridors.
- (Btw. I hopped it was fixed)
-- Finally, what you've all been waiting for: a fix for the
-infamous "corridor off the screen bug" (or at least one of its
-aspects). In dungeon.cc in vault_grid(...), add the line
-(vgrid == '\0') ? DNGN_ROCK_WALL :
-amongst all of the other ones. The problem was that the
-vault code was null-terminating some of the lines of the map,
-causing the default of DNGN_FLOOR to be put in place of all
-the '\0's.
-
-== 34. Potions, scrolls & wands are not updated when wielded and used.
-
-== 35. I've already reported this one but I remind that -
- When zapping some bolt towards the top of the screen and
- gaining level during it the rest of the bolt is drawn at the
- bottom of the screen (at message lines)
-
-== 36. Missing space in message "<Servant>is recalled."
- e.g. "Mummyis recalled."
-
-== 37. Redundant space in message "You are diseased."
-
-== 38. Why is "demon whip of flaming" white ? I've found such one.
->> demon weapons are always given random colours.
->> MV: Should not be fixed now.
-
-== 39. "Summon Daeva" spell summons Angel.
- Why ? "Daeva" exists and it's possible
- to summon it during summon_ice_beast_etc()
-
-== 40. At fight.cc::monster_die() is line
- ( you.religion == GOD_VEHUMET
- && (!player_under_penance()
- && random2(you.piety) >= 20) )
- There should be 30 and not 20, because piety equal to 30 is limit
- for this ability (see religion.cc).
-
-== 41. It was mentioned already but -
- Descriptive messages like
- "It's lightly enchanted to do more damage."
- can never appear because of badly placed brackets - {}
- in describe.cc::describe_weapon()
- Program gets on line
- if ( item_dam >= NWPN_SINGING_SWORD )
- and if this fails the programs continues on the line
- int spec_ench = item_dam % 30;
- and it means it can't get to messages about enchantment.
-
- Or am I missing something ?
-
-== 42.In monstuff.cc::mons_speaks() is few times used sprintf() insteed
- of strcat(), e.g.
-
- sprintf(info, " %s \"Help!\"",
- coinflip() ? "yells" : "wails");
-
- Problem is that in the begining _info_ contains name of the monster
- but sprintf() deletes it. It means that output is
- e.g. " yells "Help!"" instead of "Sigmund yells "Help!""
-
-== 43. Which compile time options will be made standard? What are the the
- appropriate defaults for the config file (set in initfile.cc)? These
- have to be laid out before the release.
-
-SEPARATE_SELECTION_SCREENS_FOR_SUBSPECIES I vote no on this one. Could be made into an initfile or command
- line option if people really want it, but there just aren't enough
- subspecies to justify it.
-ALLOW_DRACONIAN_TYPE_SELECTION This one is typically considered "cheating". Part of the fun of
- being draconian is finding out what you actually are.
-USE_ELVISH_GLAMOUR_ABILITY Haven't really tried out glamour. The grey elf or two I've played
- that has had it has never really successfully used it.
-USE_BETTER_MINOR_MAGIC_BOOKS These should be okay now.
-USE_NEW_CLOUD_CODE This code is pretty cool, I sometimes wonder about potential
- twinkiness at high levels with this in a corridor (where it
- could fill quite a stretch reaching more than a half dozen
- squares from the center of the effect in a single turn).
- Maybe a safeguard should be added to keep the effect within
- a certain radius from the target?
-USE_SILENCE_CODE I've never been overly fond of silence. I don't like the
- way it cancels enemy priests and spellcasters.
-USE_HARDER_AC_RULES Things are more sane with is option, unless scaled demonspawn
- transformers turn into scaly spiders.
-USE_NEW_ALTAR_CODE I liked things a bit more random. I once had orcish mines with
- three Ely altars (which I thought was pretty interesting).
- Modifying this code so there's at least a chance of an outside
- altar would be nice.
-USE_NEW_MINIVAULTS These are probably okay.
-
-USE_GOD_COLOURS We do much worse than this right now with all the channels on.
-// > USE_GOD_COLOURS
-// Yes. Actually, this option should probably be either removed or replaced with
-a USE_MESSAGE_CHANNEL_COLOURS option or some such (gods are just part of
-this system now). Brings back to mind the possibility of specifying
-non-colour-based highlighting options like "stars", "capitalized",
-"indented", and such. Would have to switch from an enum to a bitfield,
-and the initfile parser would have to be adjusted, but other than that
-it would be simple to do.
-
-USE_OPTIONAL_WIZARD_DEATH Test option, don't need this.
-USE_LIGHTER_MAGIC_ITEMS These are reasonable.
-USE_NEW_TORMENT_CODE This is good.
-USE_SEMI_CONTROLLED_BLINK It's powerful, but as long as it needs the blink spell and
- a separate form of teleport control it's probably okay.
- As an all in one spell it's over powered (but that's only
- in the code for wizard mode testing right now).
-USE_NEW_COMBAT_STATS Not sure these really have much of an effect on anyone's
- game. Could be left out.
-USE_SPELLCASTER_AND_RANGER_WANDERER_TEMPLATES Not sure about the wanderers. The ranger and spellcaster templates
- might just be encouraging people to try and re-roll for twinkiness.
- Might be best with just the basic warrior wander type.
-USE_SKILL_POOL_DRAIN This one is pretty silly. There's no real reason to punish people
- who get a large pool (mostly from killing a large monster or two).
- To increase the cost because of that doesn't make much sense, and
- the skill cost doesn't need to be made any tighter (it might even
- be due for a bit of loosening).
-USE_NEW_RANDOM Should be default, the suggestion to reverse it into USE_OLD_RANDOM
- is probably good.
-
-From Michal:
-> SEPARATE_SELECTION_SCREENS_FOR_SUBSPECIES
-No.
-> ALLOW_DRACONIAN_TYPE_SELECTION
-No.
-> USE_ELVISH_GLAMOUR_ABILITY
-Yes. Works fine.
-> USE_BETTER_MINOR_MAGIC_BOOKS
-Yes.
-> USE_NEW_CLOUD_CODE
-Yes.
-> USE_SILENCE_CODE
-> I've never been overly fond of silence. I don't like the
-> way it cancels enemy priests and spellcasters.
-I don't think so.I vote for this.
-
-> USE_HARDER_AC_RULES
-Yes.
-> USE_NEW_ALTAR_CODE
-> I liked things a bit more random. I once had orcish mines with
-> three Ely altars (which I thought was pretty interesting).
-> Modifying this code so there's at least a chance of an outside
-> altar would be nice.
-Agree
-> USE_NEW_MINIVAULTS
-Yes.
-> USE_GOD_COLOURS
-Yes.
-> USE_OPTIONAL_WIZARD_DEATH
-> Test option, don't need this.
-Of course no.
-> USE_LIGHTER_MAGIC_ITEMS
-Yes.
-> USE_NEW_TORMENT_CODE
-Yes.
-> USE_SEMI_CONTROLLED_BLINK
-Yes.
-> USE_NEW_COMBAT_STATS
-> Not sure these really have much of an effect on anyone's
-> game. Could be left out.
-I think this one is OK, I vote for.
-
-> USE_SPELLCASTER_AND_RANGER_WANDERER_TEMPLATES
-Yes.
-> USE_SKILL_POOL_DRAIN
-No.
-
-xx 44. might want to branch off a version of the source for the next release,
- with the unused spells and code cut out (along with some of the
- unimporant comments). The full code would naturally still be used
- as the development code.
-
-** 45. documentation (crawl.txt, crawl.6 will probably need some changes)
-
-== 46. bow messages on skill screen might take up too much real estate
- (things are already tight for people on 24 line terminals once they
- get all the skills)
-
-== 47. very noisy gcc --Wall compile (it was bad before, I'm afraid I've
- made it worse, it's hard to tell I get a lot of warnings from
- curses that have to do with some unimportant system conflicts).
-
-Oh, in makefile.sol... one of the $(INCLUDES) is spelled INCLUDE
-
-== 48. giant spores sometimes seg fault when exploding (I added a simple check
- for NULL, but that's probably not the problem)
-
- ugly, ugly, ugly, ugly. But fixed. the problem was that spores
- were kind of cleaned up before exploding (so that the death message
- wouldn't come twice), but then they fell through to the "handle
- special ability" case the next time through the "monster action" loop
- and all hell broke loose.
-
-== 50. look into why you.equip[EQ_WEAPON] (aka weapon) is used in
- fight.cc::monster_fight() and monster_attack() (ie. when the
- player isn't even involved!)
-
- > no effect in monster_attack()
- > bizarre use in monster_fight() - the
- attacking monster gets several attributes of the player's
- weapon!!! This is clearly wrong.
- > MSLOT_WEAPON was also used in a couple places where hand_use
- was required.
-
-== 51. BUG: no "scores" file == segfault.
-
-> some pretty nasty bugs in the score file stuff. Cleaned up segfault
-> and some ranking bugs. Scores file is now proper text; Crawl can
-> still read old scores files. Scores of 0 no longer printed. No more
-> segfault on non-existent file.
-
-xx 52. 'X' (view map) causes core dumps on terminals larger than 64 lines?
-
-> could not repro on Win32. Tried 65 line terminal, 'X' look no problem.
-
-== 53. Anyway, up on onelist.com (or egroups.com, whatever)
-is an updated mon-spll.h file including the enums for
-MST_foo and a couple MS_foo that Brent had missed
-in the file ... note that the comments before these lines
-in mon-util.cc:
-
-static unsigned char mspell_list[][7] = {
-#include "mon-spll.h"
-};
-
-are duplicitous of those in mon-spll.h, and can probably
-be struck (or vice versa?) ... I had also thought that there
-was a MS_foo matching value 100 (the beastly equivalent
-of SPELL_NO_SPELL) ... maybe Gordon can add it in?
-clear application to mon-spll.h and monstuff::handle_spell().
-
-
-of course, one could go whole hog and add enum constants
-for the "slots" in the template (actually the position *less one*
-would be enummed, see handle_spell() and mons_spell_list()
-for details) ...
-
-
-these lines in monstuff::handle_spell() can be enummed
-with the appropriate MST_foo enum constants:
-
-int msecc = ((monster->type == MONS_HELLION) ? 30 :
- (monster->type == MONS_PANDEMONIUM_DEMON) ? 119
- : monster->number);
-
-[[ 30 == MST_BURNING_DEVIL, 119 == MST_GHOST ]]
-
-that 119 value also turns up in mon-until::mons_spell_list() ... but
-this gets into "overlap land" because these values are stored in the
-sec field of the monster struct, which stores a number of values
-unrelated to spell-casting (though I guess applying the template
-enum throughout the codebase is one way of sifting out when sec
-values are used for one purpose instead of another ...) *ANYWAY*
-
-== 54.In enum.h --
-
-/* these are for the player spell struct, we'll see what's what later
-*/
-
-#define SPELL_FOOD(x) (x)
-#define SPELL_MANA(x) (x)
-#define SPELL_LEVEL(x) (x)
-
-
-All of the above can be killed, as the macros are no longer used.
-
-The SPELL_EXCLUSION enumeration (right below the macro
-definitions) can also be killed, as I never implemented it, and in
-hindsight, if it is ever to be stuck back into the player spell
-data structures, there is a much better way of doing it. So, please
-yank these out, before someone gets hurt :P
-
-So, this bit in spl-util.cc can also be axed:
-
-/* //jmf: commented out; add field `restriction' to spell struct if desired
- // (and if anyone finds a use for such a thing)
- int spell_restriction( int which_spell, int which_restriction )
- {
- int this_restriction = (int) seekspell(which_spell)->restriction;
- return ( this_restriction == which_restriction );
- } // end spell_restriction()
-
- */
-
-
-== 55. Minor typo:
-
-MST_RAKSHAKA
-
-should be
-
-MST_RAKSHASA
-
-so that it matches up with the monster's actual
-name throughout the codebase. Nothing major,
-but it will require fixing (present in enum.h and
-the enummed mon-spll.h I just uploaded).
-
-== 56. "* * * LOW HITPOINT WARNING * * *
- You die..."
-
- At that point, it's really too late. The warning perhaps
- ought to occur at the beginning of the player's turn as
- opposed to when the character takes damage.
-
- I've also seen two warnings in one combat turn ... can't
- remember if death accounted for one of them.
-
-> The problem is that the check is you.hp... it should be (you.hp > 0)...
-> I quick-fixed that one while I was trying to get the code out the
-> door and missed.
-
-== 57. Hunger messages don't seem to appear, even if their color is set.
-
-> Gave general cleanup of food.cc; merged hunger_warning and food_change.
-> removed unnecessary modification of hunger status from level save/load,
-> fixed up some logic problems.
-
-
-== 59. Lot's of the enums in enum.h have trailing commas, eg
- enum CONFIRM_LEVEL
- {
- CONFIRM_NONE_EASY,
- CONFIRM_SAFE_EASY,
- CONFIRM_ALL_EASY,
- };
-I don't think this is legal in ANSI C.
-
-> Borland C++ didn't complain with Wall, so it's not a problem.
-
-== 61. In libmac.cc there's a function called FlashButton. The line that calls
-HiliteControl should look like this:
- HiliteControl(control, kControlEntireControl);
-
-== 62. In message.cc mpr's definition includes default arguments. This isn't
-legal C++ (only the declaration can have default arguments). The same
-applies to random_near_space and simple_monster_message in monstuff.cc,
-apply_random_around_player in spells4.cc, and yesno in stuff.cc.
-
-== 63. monspeak.cc needs to include monspeak.h at the top of the file, not
-monstuff.h.
-
-== 64. overmap.cc includes curses.h, this should be wrapped in #if !macintosh.
-
-> Acutally it should be wrapped if USE_CURSES is not defined. Which it is now.
-
-== 65. spl-util.cc should include the standard limits.h instead of the
-non-standard values.h and should use INT_MAX instead of MAXINT.
-
-== 66. The MacStuff directory should be deleted.
-
-== 67. Very Old Buglet:
- Spider Form spell turns one into a black 's', which corresponds
- in monsterland to a scorpion, while giving one all the features
- of the noble wolf spider, represented by a brown 's'.
-
-== 68. It's really not that bad. Worse is the fact that I noticed that
-breathe fire gives a bonus if the player is transformed (doesn't
-matter what: Ice Beast, Blade Hands, or Dragon)... that's a bug.
-
-== 69. player.cc - If you look at line 2312 you'll see that
- redraw_screen () is called. But it's problem under
- DOS because redraw_screen() is defined only under
- PLAIN_TERM.
- See stuff.cc - there is
- #ifdef PLAIN_TERM
- void redraw_screen( void );
-
-> got rid of all of the plain_term() wrappers around redraw_screen.
-> instead, redraw_screen() becomes a no-op for non-plain term systems.
-> I hate seeing #defines all over (supposedly) non-system dependent code!!!
-
-== 70. view.cc - at two place there is
-
- #ifdef DOS_TERM
- puttext(2, 1, 34, 17, buffy);
- #endif
-
- Probably it's possible to compile that with some compilers
- but not all and corretly it should be
-
- #ifdef DOS_TERM
- puttext(2, 1, 34, 17, buffy.buffer());
- #endif
-
-== 71. When you cast "Twist" spell and choose direction you'll always get
-message
-"There is no monster there!"
-even if it's not true. If you want to hit monster you have to target
-monster by using "*" or "+". At least this spell shouldn't ask for
-direction but for target.
-
-xx 72. After battle with guardian naga character is told he is not carrying anything.
-
-> don't see how this could happen.. g. nagas can't affect player inventory.
-> must have hit a key that tried to use an inv type you didn't have, or num_inv_items
-> got out of whack.
-
-xx 73. Some initial prompts not prompt colour. I'll have to document which.
-
-== 74. Throwing anything left seems to cause a segfault and core file ... hmmm ...
- item_use.cc, line 1294: DUMB BAD CODE! Throwing anything while weilding
- nothing results in a crash. Clearly someone plays neither Transmuters nor
- Monks. Clearly we need some function to safely get the current weapon.
-
-== 75. Throwing stuff while weak: I'm of the opinion that things thrown ought
- to land at least next to the player, while currently, large things end
- up at the player's feet. This annoys me - "I didn't say (d)rop, I said
- (t)hrow!".
-
-> it's a playability issue, especially with large amounts of items and
-> autopickup. All thrown objects will go at least 1 square - we'll
-> consider a 'throw' of a very heavy object equivalent to 'shove' it. :)
-
-== 77. line 234 of mon-util.cc ought to be:
- "if (mc == MONS_PLAYER_GHOST || mc == MONS_PANDEMONIUM_DEMON)"
- but instead it's:
- ""
-
- This will fix the elemental damage problem I was complaining about --
- clearly Linux does not automagically give clean pages.
-
-== 78. Remove trailing commas in enum.h
-
-== 79. Stores are still trying to sell me gold pieces, and at extortionary rates.
-
-== 81. + spells4.cc::418 assert failed: ASSERT( targs[i].x != 0 && targs[i].y != 0 );
- should this be ( targs[i].x || targs[i].y ) ? (YES)
-
-== 82. if (mons_flag(monster->type, M_SPEAKS) && one_chance_in(21)
- && !silenced(monster->x, monster->y))
-{
- mons_speaks(monster); // mv: removed silence check
-}
-
-That check for silence shouldn't be there, because mons_speaks()
-handles silence by itself - see monspeak.cc (Btw. I've already removed
-this check when I wrote mons_speak(), but somebody have returned
-it back *grin* ).
-
-== 83. However, in a couple places in acr.cc, there is code like this:
-
- if (grd[you.x_pos][you.y_pos] == DNGN_LAVA
- || grd[you.x_pos][you.y_pos] == DNGN_DEEP_WATER)
- {
- if (you.species == SP_MERFOLK)
- {
- mpr("You dive into the water and return to your normal form.");
- merfolk_start_swimming();
- }
-
- fall_into_a_pool(true, grd[you.x_pos][you.y_pos]);
- }
-
-== 84. // From: Daniel Ligon <makmorn@qis.net>
-[easy_butcher]
-// When I see it happen, I have no weapon in hand and no weapon in the
-// "a" slot. After hitting "D" to Dissect, I am prompted for a weapon.
-// I can choose a cursed weapon of either known or unknown status and will
-// receive a message that the weapon sticks to my hand. In both cases,
-// I return to unarmed after butchering - and the weapon is now identified
-// as being cursed.
-
-Okay, then the problem isn't with the original check... all that
-needs to be done is make sure that is the target weapon (after the
-call to wield_weapon which does all the validating and prompting)
-isn't removed if it's cursed. Should be a fairly simple check,
-although it has to validate if a weapon is wield first (of course).
-
-== 85. This seems to be a new bug (can't see an obvious cause)...
- Brain Worms seem to have a sticky flame attack now.
-
-> SOMETHING was(is?) setting mon->number to be equal to mon_type. This
-> was setting butterflies (MONS_BUTTERFLY == 66) to have a colour
-> of 66, and brain worms (MONS_BRAIN_WORM == 69) to have the
-> spell type of MST_MOTTLED_DRAGON (69). Why?? I don't know yet.
-
->> turned out to be define_zombie. Random zombies were not getting
->> zombified due to some parameters getting passed incorrectly from mons_place().
->> all quasi-zombies were getting correct mons->number set but then mon->type
->> was not being set.
-
-== 86. This appears in player.cc::player_hunger_rate()
-
- // jmf: hunger isn't fair while you can't eat
- // Actually, it is since you can detransform any time you like - bwr
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_AIR)
- return 0;
-
-Some testing reveals that in fact one cannot untransform ("You're too
-hungry.") nor even turn visible. If hunger was not meant to preclude
-these reversions, there's a bug in the ability code.
-
- - Josh
-I would guess that there is a bug in the ability code wrt
-untransform - I have not looked at the code for this in a
-while, but the "untransform" ability is likely lumped with
-all other abilities in terms of forcing a check of one's
-current hunger level before proceeding further into checks
-and then (finally) triggering the ability.
-
-Trivial fix, that is where the bug is: the ability code (98%
-certain) - it does not make sense to attach a hunger cost
-to detransformation, unless you wanted to curse players
-first learning how to transform with costs on both ends
-(it takes effort to change shape, effort to change back).
-
-The latter model of double-ended costs associated with
-transformations make sense, but I do not believe this was
-the intended model in Crawl.
-
-xx 87. PS: I was looking through player.cc because a white imp "chilled" my
- mummy assassin. Still looking for how that could happen.
-
-> everything seems to be WAD:
-> could have been wearing two rings of fire, or dragon armour, or had a
-> randart with cold susceptability. Mummy only gives resist, not immune.
-
-== 88. PPS: White imps seem to pick up darts & stuff, while red imps don't.
- IMHO that's exactly backwards. White imps are have a much better
- range attack than darts provide, while a dart-throwing red imp
- would be a major pain.
-
-> actually the issue is gmon_use (the last parameter in mon-data.h)
-> - red imps have 1 (opens doors) while white imps have 3 (doors,
-> weapons & armour). sorry not explicit enough.
-
->> No, make white_imp.gmon_res=1; red_imp.gmon_res=3. Current values
->> but reversed.
-
-== 89. PPPS: Noticed punctuation creep: "You can't weild a two handed weapon
- *AND* a shield at the same time." Patriots should conserve stars.
-
-== 90. The eat chunks on the ground prompt is uncoloured.
-Following prompts are coloured.
-
-== 91. Prompt & crashes: try doing an x-look while you
-can't see any monsters, then press '+'. You will
-get a nice, shiny new core file in your directory.
-
-The x-look prompt also claims to allow you to go
-to the current target using 'p', but does not. 'P'
-does nothing.
-
-== 92. Elves in their Halls seem to wear a lot of Orcish armour.
-
-== 93. > And finally to end on a good note...
-> I've love what has been done with the coloring, the autopickup and
-> the automatic door opening. This is *very* useful and as a user I
-> truly do appreciate the effort here. (It would still be nice to be
-> able to pick up gold when your slots are full but I'm not going to
-> complain.)
-
-Argh. I haven't checked the latest dev source (but I will
-this weekend), but is this still the case? If so, can Gordon
-please put it in the bug queue as something to fix for the
-upcoming release of 3.*cough* ???
-
-== 94.
-> I was descending through the Elven Halls, and reached level 6. On this
-> level were three stairwells down to level 7, and an entrance to the
-> Labyrinth.
->
-> It is my habit to descend/ascend each stairwell as I find them, since
-> the dungeon areas of crawl are sometimes disconnected. So I believe
-> the three stairwells on this level actually did lead to level 7.
->
-> After filling my gut on fresh elven meat, I descended in the Labyrinth,
-> spiraled in to the Minotaur, slew it, grabbed its stash, and ascended
-> back to the Elven Halls, appearing at one of the stairwells down.
->
-> But now all three of the down stairwells on this level lead to the
-> Labyrinth rather than level 7, and the Labyrinth is being mapped.
-
-I can verify that I had visited Elven Halls level 7 (I had saved a
-copy of my player files before entering the Labyrinth). As it happens,
-level 7 was the bottom of the Elven Halls with the Vault.
-
-I cleaned out the Vault, then returned to the Labyrinth. Once again
-returning from the Labyrinth caused all the stairwells on level 6 to
-lead to a mappable Labyrinth.
-
->> Fixed. up_stairs() was not correctly setting was_a_labyrinth in
->> the call to load(), and so the labyrinth level would get saved
->> _over_ the n+1 th 'real' level. REALLY BAD. Yuck. Bleah!
-
-== 95. Auto-butcher + Staff of Power + dagger in off slot.
-Every time a corpse is butchered max SP is reduced...
-
-This probably has to do with the fact that staves of power are one of
-the few things that are toggled on wield/unwield (a lot of the other
-properties are calculated as required).
-
-== 97. The routine mon-util::seekmonster() needs to check that
->
-> mon_entry[(*p_monsterid)]
->
-> is not -1 before returning
->
-> &mondata[mon_entry[(*p_monsterid)]]
->
-
-== 98. In my current game, I found an entrance to the Hall of Blades on
-> level 4 of the Vaults. I entered, killed a few weapons, and returned.
-> Upon returning, the game crashed. When I restarted, I was on level 1
-> of the Crypt. I exited the Crypt was back at the entrance I had found
-> on level 3 of the Vaults.
->
-
-- Fix for the Hall of Blades staircase bug... Although the
-staircases leading out of the HoB are called staircases "back
-to the crypt", and although the enum for them describes them
-as returning to the crypt, and although climbing one of them
-sends you to the crypt, they are in fact supposed to lead back
-to the vaults, and the level range of the HoB has been set
-accordingly. To fix:
- - Change the name of the enum DNGN_RETURN_CRYPT_II to
- DNGN_RETURN_VAULTS_II (may need to be _II or _III)
- - Change in direct.cc, in look_around(...), "A staircase
- leading back to the crypt" to "A staircase leading back to
- the vaults"
- - Do the same in item.cc in item_check(), where it tells you
- what you're standing on
- - And, finally, in up_stairs() in misc.cc, the case for
- DNGN_RETURN_VAULTS_II (or whatever it's changed to) needs to set
- you.where_are_you to BRANCH_VAULTS.
-
->> this code needs a complete overhaul to be more comprehensible,
->> but I don't know if I'm up to it at the moment. :\
-
-== 99. There was lava in the Crypt. I don't object to it, but it seems a
-> little out of character, much like Josh's observation that elves wear
-> a lot of orcish armour.
-
-== 100. Characters who might go berserk while fighting, say from the mutation
-> or wielding a randart, can have go_berserk() called on them while they're
-> already berserk.
-
->> which is fine. Fixed up berserk messages for all possible situations -
->> no more double messages, or inappropriate ones.
-
-== 101. I've run across a couple Borises in my current game. It must be a
-> popular name among Liches.
-
->> fixed. Bad range check in dungeon.cc.
-
-== 102. If a monster tries to mutate you and fails due to your resistance
-> to such, you get a message from mutate() - "You feel rather odd for a
-> moment." and from direct_effect() - "You feel very weird for a moment."
-
->> fixed all manner of mutation messages.
-
-== 103. Removing a ring of strength causes these messages:
->
-> You are being crushed by all of your possessions.
-> You possessions no longer seem quite so burdensome.
->
-> since this happens in item_use::remove_ring():
->
-> case RING_STRENGTH:
-> decrease_stats(STAT_STRENGTH, (you.inv_plus[ring_wear_2] % 100), true);
-> increase_stats(STAT_STRENGTH, 50, true);
-> break;
->
-> The suppress_msg flag of decrease_stats and increase_stats does not get
-> passed to player::burden_change(), which has no arguments.
->
-> It is interesting to compare that code with similar code to remove the
-> strength one gets from a randart ring. From it_use2::unuse_randart():
->
-> const int str_plus = inv_randart_wpn_properties( unw, 0, RAP_STRENGTH );
-> if (str_plus != 0)
-> {
-> you.strength -= str_plus;
-> you.max_strength -= str_plus;
-> you.redraw_strength = 1;
-> }
->
-
-== 104. There is a monster named "another lava thing". Not a bad name, but
-> it leads to "You kill the another lava thing!" messages. Perhaps a name
-> change to "mother of all lava things" or "lava thing's cousin".
-
-> "another lava thing" has no stats in mon-data.h, so it was
-> obviously a dummy placeholder and has been removed from possible
-> generation lists.
-
-== 105. Assorted typos:
->
-> You possessions no longer seem quite so burdensome.
-> You heara loud "Zot"!
->
-> File name: Minh.txt
-> File name: Minh.txted successfully.
-
-== 106. Something causes misformatting of the descriptions for
-> SPELL_APPORTATION and RING_TELEPORT_CONTROL;
-
-== 107. After I picked something up, I could drop one thing, but nothing after
-// that. I think we ought to have periodic checks that num_inv_items is
-// correct - recounting once per turn is not a significant calculation.
-
-Ah! There's the problem... that variable was deprecated a while back
-and replaced with explicit code in the standard places (because it
-was impossible to keep it up to date). If someone is actually making
-use of it again then of course the entire system is going to break
-down.
-
->> really deprecated this time.
-
-== 108. Fixed apply_area_within_radius(). Makes far fewer unnecessary calculations
- now.
-
-== 109. Fixed rendering slowdown on windows console.
-
-== 110. Scorefile reading doesn't pick up special characters like a-umlaut or e-ague
-
-== 111. I was in the Tomb, slaying mummies with style and grace, so naturally
-a fair amount of cursing of my stuff took place.
-
-The Ring of Shadows now has an inv_plus of 100, I assume since
-monstuff::curse_an_item() adds 100 to inv_plus. I can't remove it,
-since inv_plus > 80. It is not labeled as cursed and scrolls of remove
-curse are ineffective since inv_plus < 130. I suggest that, for now,
-curse_an_item() should leave randarts alone.
-
-As an aside, is "artefact" a valid variant spelling of "artifact"?
-
-
-== 112. Another result of the great Mummy slaying was that my flesh would
-rot away. I think display_char_status() should list this.
-
-
-xx 113. I came a across a butterfly which had color 66. I could not
-determine why (N.B. 66 is MONS_BUTTERFLY.. what's going on?!)
-
-> me neither. All calls to create butterflies should go through
-> define_monster(), which sets m->number to 0..15. See #85.
-
-== 114. in view.cc, inside the #ifdef DOS_TERM things there are some
-bad things happening to the puttext calls. buffer.buffer()
-should be replaced with buffer, and buffer2.buffer() (or is it
-buffer.buffer2()? I forget) should be replaced with buffer2.
-Otherwise it refuses to compile (this may be an incompatibility
-between borland C++ and djgpp, Gordon)
-
-MV: Buffer.buffer() should be only buffer. Problem is with _buffy_ which
-needs to be _buffy.buffer()_.
-
-== 115. Also in view.cc in noisy() at 1304 the distance function is
-being used wrongly. Change if (dist <= distance(... to
-if (dist >= distance(.... This problem caused most monsters on
-a level to wake up as soon as a noise was made, and was why
-characters were getting mobbed.
-
-== 116. the init file is broken, at least under DOS. It is reading
-in the player's name okay and is finding the other options,
-but when read_bool() tries to work out whether an option is
-followed by "true"/"1" or "false"/"0" it fails to detect
-anything and just goes with the default. I don't know how any
-of the weird code in initfile.cc works (what was wrong with
-the stdlib string functions?) but, at a guess, this might
-have to do with the way DOS writes End Of Line in its text
-files - if a line is concluded by something other than
-'\0' the string code might fail. But that's just a guess.
-
->> made a couple changes and it seems to work fine on win32..
->> but this is highly dependent on the compiler's implementation
->> of the standard string template (grrr!)
-
-== 117. A blank/empty scorefile will not be updated; scores of 0 not kept.
-
-> both fixed.
-
-== 118. If you aren't carrying anything except money, you can't drop it (money)
-
-> can now specify quantity of money to drop. Accepts any value.
-
-== 119. My character entered the Tomb, arriving in the upper left hand corner,
-at position (9,7). I tried to target, and failed the ASSERT for the
-mgrd array. This took place around line 1227 of direct.cc in the
-mons_find() routine. const int targ_x = you.x_pos + temp_xps - 17;
- const int targ_y = you.y_pos + temp_yps - 9;
- const int targ_mon = mgrd[ targ_x ][ targ_y ];
-
-In this case, you.y_pos is 7, temp_yps is 1, and so targ_y is -1.
-
-== 120. The Amulet of Cekugob does not stop one from teleporting when one
- has the teleport mutation.
-
-== 121. I entered Hell from level 22. When I exited Hell I was placed on
- dungeon level 27.
-
-BWR:I believe this was the better alternative of earlier problems dealing
-with returning to the main dungeon... used to be you could end up on
-level zero, or on a semi-random level inside solid rock. After those
-problems were fixed the portals seemed to work as above.
-
-== 122. When I returned to Hell, I was placed on one of the down stairwells.
-
-== 123. Remove which piece of jewellery?
- That isn't a piece of jewellry.
-
-Webster has jewelry, jeweled. Changed all occurances.
-
-
-== 124. Oops, that ring feels deathly cold.
- B - a cursed amulet of the gourmand (around neck)
-
-xx 126. I hit a giant spore with a bolt of poison flame, and the critter
-> didn't explode. It just disappeared.
-
-LRH writes:
-Not sure exactly, but I'm pretty sure that if you do enough
-damage to a spore with a single attack it will fail to explode.
-The relevant code should be in monster_die().
-
-== 127. A fire giant hit my Spriggan (AC: 5, EV: 13) with several fire balls
-> over a few turns, but none hurt much. I didn't get any messages about
-> resisting the effects. Is this the odd fire resistance problem?
-
->> monster fireball damage wasn't being set correctly.
-
-== 128. The Spriggan has strength 10 and dexterity 21. When he wields a bow
-> or crossbow, I get the message:
->
-> Your relatively low strength is limiting your use of this weapon.
->
-> I don't think strength has any effect with crossbow, and probably doesn't
-> effect bows.
-
-BWR: As a side note, is the low Throwing skill message still on the skills
-screen? Has anybody tested it with all the skills yet (there is a
-lack of room, and the screen should fit in 24 lines). Maybe that
-message would be better as a message when wielding the bow itself,
-although I'm not sure how much the mechanic is required (I typically
-upped Throwing skill along with Bows because it's a cheaper and faster
-way to up accuracy and damage than raising Bows alone).
-
-== 129. The file makefile.obj seems to be missing... this is a problem
- for most of the other makefiles which include it.
-
-== 130. The APPNAME in makefile.sol should probably be changed back to crawl.
-
-== 132. In spells0.cc should be also included stdio.h under DOS
-because sprintf() is used.
-
-xx 133. > Are you going to do the player-ghost/demonlord "structure" as well?
-//
- Um, dare I ask, why? I've never looked at this part of the code.
-BWR:
-It's currently an array of chars. It would probably be easier to
-understand as a struct with fields for AC, max HP, spells, resistances
-and such.
-
-== 134. When I cast Static Discharge, I get occasional fails of the ASSERT
-on line 419 of spells4.cc: for (int i = 0; i < targs_found; i++)
- {
- ASSERT( targs[i].x && targs[i].y );
- func( targs[i].x, targs[i].y, divided_power, 0 );
- }
-
-> Fixed. Brent's algorithm is sound, but his coding wasn't. :P
-
-== 135. When I use the Sif Muna granted ability of Selective Amnesia, I hit
-an array bounds assert in seekspell() - which is exactly:
-
-return &spelldata[plyrspell_list[spell]];
-
-The value of spell is 210 (SPELL_NO_SPELL), and so plyrspell_list[]
-goes out of bounds (it is not protected by the Fix[Ary|Vec] stuff)
-which then triggers spelldata[] going out of bounds.
-
->> plyrspell_list[xx] being set to SPELL_NO_SPELL _before_ call
->> to spell_power. stupid logic error.
-
-== 136. I swung my Staff of Air:
-
-You miss the imp.
-You miss the imp.the imp is jolted.
-You are wielding a staff of air.
-
-== 137. I'm wearing an amulet of the gourmand, but I never seem to get labelled
-as being Full (or Engorged).
-
->> is this a problem? Gourmand allows you to eat rotten/contaminated flesh,
->> how could this be related?
-
-== 138. Trolls can eat huge amount of chunks of flesh without becoming full
-
-> oops. Nobody could ever get full. Stupid logic error.
-
-== 139. Name in INI file causes crash unless all caps.
-
-xx 140. Non-Beams displayed one cell at a time (thanks to Michal)
-
-== 141. M_SPELLCASTER removed from ball lightning.
-
-== 142. All beams/missiles leave a visible trail now (at least until window
- redraw). Was too hard to get right w.r.t. killed creatures and cloud
- trails, and most liked it the other way anyways.
-
-== 143. Some enchantment beam behavior fixed.
-
-== 144. Update & examine command-line switches & options
-
-// - update & verify behavior of command line switches & options
-Monochrome isn't connected to anything. The "no colour" option could
-be handled by imposing a set of colour macros (if they were made widely
-available)... most monochrome systems can do bold/standout, although
-that typically ends up backwards or ugly (if it's done via reverse).
-Could possibly just be removed rather than bother with it.
-The "-nb" (no black) option is obsolete with colour macroing.
-Basic options to consider:
-- list scores (param for top X)
-- select race/class
-- character name (for loading and starting new character)
-- pointer to game directory (ala crawl_dir option)
-- pointer to initfile (ala CRAWL_RC environment variable)
-Later things can get fancy, but we should at least have those.
-
-xx 145. I'm playing the latest win32 binary pre-release (January 11).
-The first problem is that I can't get to the religion screen. To produce
-'^' with my keyboard I have to press <Shift> + <the button with ^>
-followed by a space. However, in Crawl this doesn't work (it used to work
-with earlier versions before this series of win32 binary pre-releases).
-All I get is 'Unknown command'.
-
-== 146. When zapping a wand of Draining at a line of Kobolds and Big Kobolds,
-: the game froze if something was killed. The game was recoverable, and
-: the bug repeated itself. Killing these by hand caused no problems.
-: Using this wand on other creatures caused no problems.
-
->> probably related to double-whammy monsters were suffering from poison/
->> draining. Hit dice might have gone below zero, etc.
-
-== 147. Any ranged attack that hits you has a chance of destroying
-: your scrolls, not just fire-based ones, and they all give the message
-: that your scroll has burst into flames. Confused the heck outta me
-: the first time it happened. "The puff of frost hits you! One of your
-: scrolls bursts into flames!"
-
-== 148.
-: 1 other thing I just thought of. When targetting in version 3.43
-: you could use the dot on the keypad to select the target. Now, to
-: use that dot, I have to use the shift button with it.
-
-xx 149. Also it seems like mummies have lost some of their cold resistance... I
-had trouble with an ice dragon that should probably have been real easy...
-on the other hand fire damage does not seem to be all that nasty to them
-anymore (I dunno about the mummy monster but this seems to be the case for
-mummy player chars, none of my equipment provided fire resistance).
-
-== 150. Fixed new description() problem. Oops.
-
-== 151. Changed some messages for burning and chilling monster attacks.
- note that mummies _could_ be chilled by melee attacks - "chilled" in fact
- means that the player resists cold. New messages are tied to actual
- extra damage from fire/cold.
-
-== 152. Fixed "always poison/drain" on beams/bolts that didn't actually
- hit (problem with side effects in check_mons_resists() ->
- mons_adjust_flavoured())
-
-xx 153. The level files for my characters don't seem to get deleted, even after
-the character dies. I'm assuming that they're meant to be deleted, as
-they used to be... or is there some reason that the game now keeps them?
-
-> can't repro - works fine on 2000.
-
-== 154. I found one of those checkerboard-like rooms with alternating wall and
-floor squares (you know what I mean? The ones where you can only move
-diagonally, sort of like the Hive, but occuring in the regular
-dungeon?)... it was made of metal walls, and had a small open area in the
-middle. There were some items which seem like they should have been
-placed inside the open area, but were inside the walls instead, and
-therefore inaccessible. I can't figure out how to get Crawl to dump a
-screenshot, but I'll recreate it here, using X to represent a wall.
-.X.XXXX
-X.X.[.X
-.X.X@)X
-X.XX!.X
-.X..XXX
-X...X.X
-.X.X'X.
-All three of the items around my character are inside walls; examining
-them says:
-You see a [item name] here.
-A metal wall.
-You can't move on to them or anything. Note that if you shifted them all
-three squares down and two to the left, they'd fit nicely in that little
-open area, which leads me to suspect that possibly that's where they were
-meant to be.
-
->> several places in dungeon.cc where this could happen. Think I've squished
->> them.
-
-== 155. I'd suggest killing /unused, but only after moving oldmaps.txt
-into /misc. Within /misc, scoretab.cc should probably be updated
-to the new scorefile format (or killed) and untab.pl should be
-killed, as it is an unreliable detab script - rh.bat seems
-near useless.
-
-In /Docs (why is this uppercase?), NEW.txt is empty, buglist.txt
-should be updated to the current status (about which, Gordon only
-knows), I need to migrate messlog into changes.340, changes.340
-needs to be renamed changes.400, the remaining files need to be
-updated.
-
-The old LOS code can die, I think I lost my fascination with it.
-I don't believe anyone else was defending its existence.
-
-== 156. On this topic, I get tons of warnings about FixVec.h and FixAry.h
-not having a final newline.   Could you add one to these?
-
-== 157. The compiler also noted a problem in dungeon.cc:
- if (you.where_are_you == BRANCH_CRYPT || you.where_are_you == BRANCH_TOMB)
- {
- if (type_floor == DNGN_LAVA)
- type_floor = DNGN_SHALLOW_WATER;
- if (type_2 == DNGN_LAVA)
- type_2 == DNGN_SHALLOW_WATER;
- }
-The last statement should probably be an assignment.
-
-== 158. Finally, I can't compile dungeon.cc at all:
-dungeon.cc: In function `void link_items ()':
-dungeon.cc:6395: warning: comparison between signed and unsigned integer expressions
-FixVec.h: In method `FixedVector<TYPE, SIZE>::FixedVector (TYPE, TYPE, ...)
-[with TYPE = char, int SIZE = 7]':
-dungeon.cc:7998:   instantiated from here FixVec.h:125: `char' is promoted to `int'
-when passed through `...' FixVec.h:125: (so you should pass `int' not `char' to `va_arg')
-
-This also affects spells4.cc (instantiated from line 729).
-
-== 159. Problems with print_description() under DOS?
-Stupid, stupid, stupid.. good god. used .data() instead of .c_str()
-
-== 160. Make Boris back into a non-Unique and give him appropriate mons_speak()
-
-== 161. More portable savefile format.
-
-== 162. Well, played with the new pre release, speed is the same (drat) and the
-ghoul food bug still exists... the one where they have to eat a meat
-ration to cure the 'hungry' status. Haven't hit on any other bugs yet but
-I've only run 3 characters who all had very short lives.
-
-== 164. Direct-effect monster castings (smiting, etc) would crash the
-game (forgot to set beam_source for non-beam type attacks).
-
-== 165. The warning messages given for wielding objects should also be given
-at the start of the game (if applicable).
-
-== 166. Anyways, I'm starting to
-think that the margin should be a little smaller, the 79 colomn one is
-just too wide to read comfortably... a 70 column one should be fine.
-
-== 167.
-// > All staves work like this - the special power can activate even if
-// > you miss your foe by a mile.
-// >
-// > Is this desired behavior?
-//
-// I would think not.
-
-** 168. Enable loading of 3.30/1.x chars & level files.
-
-== 169. When casting Corona and hitting somebody I'm allways getting
-additional message "Nothing appears to happen.".
-eg. The goblin is outlined in light.
- Nothing appears to happen.
-
- (silly logic problem)
-
-== 170. In ouch.cc is under DOS missing #include <file.h>
-
-== 171. There is still small problem with new print_description().
- Description window for DOS is (25,1,80,25) - see for example
- describe_spell(). It means that lineWidth in print_description()
- can't be 70 under DOS_TERM and should be 54 or so (of course
- those windows can be changed but it's much more work).
- DOS term and shoul be 54.
-
-== 172. I started a grey elf wizard and it begins play with an orcish robe, not an
-elven one. (flimsy coding)
-
-== 173.
-"You miss the ice beast.
-The ice beast hits you!
-The ice beastchills you.
-Ouch! That really hurt!"
-
-== 174. tag.h and monstuff.cc need final newlines
-
-== 175. tags.cc and files.cc include mem.h, but gcc doesn't come with one.
- The routine memcpy is declared in string.h, which is already included
- in these files, so commenting out worked for me.
-
-== 176. spells3.cc has the same problem with FixVec.h that dungeon.cc had
- in pr6.
-
-I guess around line 729 or so. :) g++ -Wall -DLINUX -g -DDEBUG -c spells3.cc
-FixVec.h: In method `FixedVector<TYPE, SIZE>::FixedVector (TYPE, TYPE, ...)
-[with TYPE = unsigned char, int SIZE = 7]':
-spells3.cc:729: instantiated from here
-FixVec.h:125: `unsigned char' is promoted to `int' when passed through `...'
-FixVec.h:125: (so you should pass `int' not `unsigned char' to `va_arg')
-
-== 177. Was just looking at that code, and noticed the comment about the
-"other five gods" (the one's the player cannot start the game
-worshipping). Anyways, that comment was added there before the
-always_greet option, which does meet the requirement for filling
-in the extra gods (since the real purpose of always_greet is to
-remind the player of some non-obvious details about their character
-in case they haven't been playing in a while (ie. race, class, deity,
-weapon penalty).
-
-== 178. Could you please put the string "-O2 -fno-strength-reduce" in your makefiles
-dealing with GCC? It'll speed up the game by a *huge* amount. (The
--fno-strength-reduce is to get around a bug in many versions of GCC.)
-Because of the exceeding slowness in the released versions, I compiled my own
-version, which leads to point
-
-== 179. Why in the name of Cthulu did you remove "#include <files.h>" from ouch.cc?
-To misquote Rufus Wainwright, "Cause all I get is instant errors/Instant errors
-Instant errors".
-
-== 180. Update scorefile format to a delimited ACSII numeric representation.
- (hmmm - will take some thought)
-
-xx 181. I am not sure if its a bug or not, but using pr7 on NT4, every now and
-again when I die, Crawl causes a general protection fault (or whatever its
-called in NT) and the game crashes. The good side to this is I don't lose
-my character and can go back to my last save and keep playing.
-
-> When I'm having a good character going ("good" being
-> 1000+ points or so), the game tends to crash when the character dies.
-
-== 182. I just got the mutation "you can exhale a cloud of poison" but I recieved
-no special ability to activate it. At the time of the mutation, I was
-wearing a ring of shadows that gave me the ability to turn invisible.
-Perhaps the ring interfered with it? Hope this helps.
-
-> data error in mutation.cc. Fixed. Nagas now get breathe poison
-> sometimes if they _would_ have got the spit poison mutation.
-
-jmf> That mutation ought only occur for Nagas. A non-Naga getting
-jmf> the mutation is a bug.
-
-xx 183. Move rand(), random(), srand(), srandom() to libxxx
-
-> behavior is too complicated..
-
-
-
-== 184. Files are not cleaned up in DOS - see end_game() in ouch.cc
-
-== 185. Fixed more monster spell crashing-if-kills-player problems.
-
-== 186. Quokkas have no mass, hence they never leave corpses.
-
-> That was there original stat, should probably be set to 200.
-
-== 187. I found lots of bug while using 'recall undead slave' skill.
-
-I noticed this bug as well. Seems the recall spell places your servants in
-spaces next to you, regardless if there is already something there or not.
-In effect, monsters which are stacked seem unable to move, including
-hostile monsters. When the top monster leaves the space the game places a
-"floor" tile there.
-
-> really, really dumb logic error - corrupted mgrd as a side effect!!
-
-== 188. Several piles of gold on the same spot should merge
-
->> so should other things. Fixed item_place() and drop_gold() appropriately.
-
-== 189. Merfolk hunters not available, NEWGAME.CC suggests they should
-
-== 190. Weld potion drank should dissappear from the screen
-
-== 191. First the bug: While in the Abyss, I came across an orange 8. Hit x and positioned
-the cursor over it to see what it was (thinking it was probably a type
-of golem I'd never seen or something) and it said:
-
->> There was a tiny bit of overlap between the area which got nuked and
->> the area that got transferred. Probably left pointers to invalid
->> items lying around, which would produce exactly this:
-
-!questionable item (c100, +0, p50, p(2)50, d0:q0)
-
-== 192. Now the complaint: Because you can use the letter keys to move around,
-the numeric pad
-has obviously been modified so that the numbers map on to the letter
-keys... but there is a problem with this, namely that 7 maps on to y,
-and can therefore be used to answer in the affirmative to a question.
-I now realize why easy_confirm exists, since some people no doubt use
-the letter keys to move and may accidentally say yes to something they
-didn't intend to... but for those of us who use the numeric pad, the
-option doesn't seem to make much sense, since your finger doesn't come
-near the 'y' key all that often, so I just had it set to all. Then I
-was in a situation with one of my best characters ever where there was
-lava directly north of me and I wanted to move northwest, but my
-finger hit directly between the two keys, basically hitting 8 then 7
-in rapid succession, plunging me into the lava and killing me. I
-suggest one of two things; either make the numeric pad work the same
-way as the letters ONLY for movement, since the only time other than
-movement when you're going to receive input from the numeric pad is
-when it's accidental, or at least put a warning in the init.txt where
-it talks about easy_confirm saying something like "WARNING TO KEYPAD
-USERS: The number 7 is mapped on to the letter 'y,' which can result
-in accidentally answering yes to questions; it is suggested that you
-leave easy_confirm off."
-
-== 193. > An orc priest who hellfired him.
-
->> fixed in general non-tracer spell cleanup. Oops.
-
-== 194. Scrolls of immolation don't do anything. The big fireball
-: appears on the screen, centred on you, but it doesn't damage you or
-: any of the creatures surrounding you, and doesn't have any other
-: effects. I'm assuming that this is a bug.
-
-> Good catch. Direct explosions were being treated as tracers. :P
-
-== 195. A more minor bug: if you read a scroll of teleportation, then
-: start butchering a corpse, you'll continue to butcher the corpse even
-: after you've teleported, successfully chopping it to pieces, even
-: though it hasn't come with you.
-
-== 196. Well, the title says it all, but, when I reach level 27 of the dungeon the game
-crashes (not a windows page fault, a 'dos page fault'). The character has not
-retrieved any of the runes of zot yet, so I figure I'll try again after getting
-one (or if that don't cure it 3 just in case). I'm on a windows 98 computer
-running the DOS compilation of pre release 7. I also had a few times on level
-26 where I couldn't move (alt tabbing out and forcing the game closed worked
-but I was set back a ways... so I made it a point to level level 26 hehe). One
-other thing I noticed was the dungeon clean up never happened (on level 25 but
-I had no problems on that level even after the floor was full). New monsters
-seemed to get weapons and armor but no more corpses once the floor was full.
-
-Something else I've always wondered about was the slime pits, are you supposed
-to get a rune of zot out of there or does the royal jelly 'eat' it or
-something, I've never gotten anything from there but it seems like it's the
-kind of place that would have one (specially with a monster that is no where
-else in the game sitting in a pre-fab dungeon).
-
- ...and then this follow-up on Feb 9th...
- I mention the runes because it was level 27 I was trying to enter when it
-crashed on me, I wasn't actually entering zot, just the level with all the
-gateways to zot. Was just trying to go down there to get a little more exp
-before I went to get the runes necessary to get into zot (the advantage of
-being a mummy... you can go do things in squirly order according to whim hehe
-
-mannix writes:
-
-Just confirmed it, lvl 27 is definitely a gaurenteed crash, even with 3
-(well, 4... got two in pandemonium... should that have been possible?) I
-still crashed when I tried to enter lvl 27. On the other hand I've found
-some fairly nifty places to explore for exp :). Another problem I found
-was that in a lot of areas the dungeon clean up is not nearly aggressive
-enough, I'd go so far as to say that when it happens all non-quest items
-should probably be removed, in some areas after spending a bit of time
-repeatedly killing random monsters (the joys of playing a mummy hehe) item
-drops would show up something like 'item 923589237 has dropped' (and
-that's a sure sign of impending doom, or at least a lock up on exit). I
-worked around the problem on one level by using my own clean up method...
-summoning imps/demons... some of them will pick up weapons (and in places
-like hall of blades that's all you'll normally see) and when they
-dissappear those items are gone for good.
-
-== 197. : Using a spell staff of smiting in melee combat reveals the following message:
-: You're wielding some sort of staff I've never heard of. (fight.cc)
-
-== 198. Trying to cast Apportation on a pile of gold crashes the game
- (division by zero)
-
-== 199. Draconian Hunters start with a club instead of a bow.
-
-> It's a little bit worse than that... The bow is clobbered into being
-> a club instead of the leather armour being turned into a robe (draconians
-> shouldn't being wearing leather armour since it doesn't fit).
-
-== 200. Need more aggressive item cleanup.
-
->> perhaps trigger this on item creation, if a spot can't be found.. go
->> through the item list destroying less valuable items or small piles of
->> gold.
-
-== 201. Teleporting a fish (by hitting it with weapon of distortion) might
-cause misc. problems - e.g. fish is teleported again and again
-(because it lands on the floor)
-
-> won't happen; checked & rewrote bits of monster_teleport() to be
-> more readable, but the code was fine.
-
-== 202. I was getting mutations after wielding/unwielding weapon of
-distortion
-
-> yes, it's in the code. Nice eh?
-
-== 203.Darts of bugginess found in shop
-
-> dumb logic in dungeon.cc::items()
-
-xx 204. Electric eels sometimes shoots lightning to strange (probably
-random) places and not at player.
-
-> don't see how.
-
-== 205. Put in a fix for scorefile lines longer than 80 chars (will break)
-
-== 206. a new score at the bottom of the list would not be added.
-
-== 207. Misc documentation changes from Don
-
-== 208. Won't get "Sorry, you can't target what you can't see." when you're
-just looking around.(with 'x')
-
-== 209. Improved 'C' command (gives XP left to go)
-
-== 210. Far strike & twist could not target with direction keys (they are
-pseudo-direct effects, which screwed stuff up. Argh!). Changed mode
-for those spells to DIR_TARGET, which means hitting a direction key will
-take player into targetting mode. No doubt will be hearing gripes about
-this too.
-
-== 211. Patched up multiuser compile.
-
-== 212. Quokkas don't generate corpses now. Someone else wants to revamp
-the corpse system, go for it.
-
-== 213. Easy butcher defaults to false now.
-
-== 214. Options for Race & Class added to init file
-
-== 215. Replace mutate() calls for miscast effects with addition to mutagenic
-radiation; perhaps all miscasts (may) add to this, and high level miscasts
-changed to give_bad_mutation?
-
->> done. all spell miscasts give small mutagens; high level spell miscasts
->> can get pretty nasty too, but still only small chances of mutation unless
->> you're also invisible/hasted/wielding nasty artifact.
->> missing a couple high level spells badly in quick succession can be really
->> nasty. I'll leave it as an easter egg. :)
-
-== 216. Monsters won't throw stuff if they can melee.
-
-== 218. Misc stylistic & code fixes from Jesse
-
-== 219. Charmed monsters will no longer be described as 'friendly'.
-
-== 220. Brave attempt made to use correct pronouns (introduced mons_pronoun)
-
-== 221. Shop names more visible when looking around & moving
-
-== 222. Can now pickup auto-combine items even with full pack
-
-== 223. scrolls of fear won't auto-identify if nobody is scared by them.
-
-== 224. "Killed by giant ant" when smitten from afar by Orc priest?
-
-> very subtle. Death_source can be zero, since it is an index into
-> the monster array. But I didn't think it could be - if killed by
-> monster#0, scores like this would be generated:
-:4:0:89:Methea:0:6:3::3:14:3:0:0:0::2:0:0:0:0:
-> which would be translated to "killed by a giant ant"
-
-== 225. Don't generate monsters in LOS?
-
-== 226. Get name after race & class (pretty easy now)
-
-== 227. Fixed up some job titles.
-
-xx 228. Game crash on character death; after equip list, but before hiscore list
-
-== 229. Massive speedup on win95/98. Fixed all cursor dance and buffering
-problems. Fullscreen is still pokey on most machines, but it's finally
-playable.
-
-== 230. No staircases to Zot on level 27 (dlevel == 26). It looks like a
- piece of code in dungeon.cc::builder() may be changing stairways to Zot
- to dungeon floors, regardless of level (occurs after place_branch_
- entrances())
-
-== 231. crawl -plain now actually uses non-gfx character set
-
-== 232. All female uniques are now properly gendered (missing break statement)
-
-== 233. Divine resistance messaged a bit better (w.r.t. Xom, Makhleb)
-
-== 234. messaging for vampiric attacks fixed up.
-
-== 235. Monsters generated on teleport traps will have unobtainable loot!
- > shouldn't generate them on tport traps any more.
-
-== 236. Fixed DOS include of <files.h>
-
-== 237. Fixed overly long string in '?' screen
-
-== 238. More multiuser fixups. Changed default makefile to linux.
-
-== 239. Moved god favor messages more in line with prayer messages (too confusing
- otherwise). Fixed a couple grammatical errors.
-
-== 240. Can't hit some monsters in LOS (rounding problem?)
- Need to rewrite for integer math. :P
-
-== 241. Crash on long player names (duh!)
-
-== 242. Miscellaneous spelling/grammatical errors
-
-== 243. Do something about this: probably remove from compile options. But leave
- bow/throwing warning in, as it is a _very_ important penalty.
-
- : One odd thing, though. I chose a Human Fighter with a short sword and when
- : I began the game I get "Your relatively low dexterity is limiting your use
- : of your weapon." Other than the three occurrences of "your" in this
- : sentence, I find it odd that 10 dexterity is too low to wield a short
- : sword. Or is this a bug?
-
- "Your relatively low <foo> is limiting use of your <weapon name>."
-
- Would be a slight alteration to kill one "your" and actually
- designate the weapon being affected (I know it is pretty clear
- that the only weapon affected is the one wielded, but I like
- some things spelled out).
-
- To avoid those excessively long weapon names with all the plusses
- and things, the weapon name string should probably be just the base
- weapon type (e.g., "short sword" instead of "+1, +2 short sword of
- orc-slaying and back-scratching"). As the str/dex modifiers are
- based on the base type and not all that other goodness, this seems
- an ok thing to do.
-
- Anyway ... I still think that this check ought to be performed
- prior to weapon selection by a player at start-up, so that he
- or she knows his/her character will be handicapped by the choice
- of one weapon type or another. I think that thread was raised
- briefly last week or so.
-
-== 244. The game crashes when I start a monk.
-
- In skills2::wield_warning(), these two statements need to be swapped:
-
- int wepType = you.inv_type[you.equip[EQ_WEAPON]];
-
- // early out - no weapon
- if (you.equip[EQ_WEAPON] == -1)
- return;
-
-
-== 246. Rewrote monster behavior routines.
-
-== 247. Cleaned up some function prototypes in dungeon.cc
-
-== 249. Put gendering into monspeak.cc
-
->> couldn't find anything.. wonder what Michal meant?
-
-== 250. More typos
-
-== 251. remove caps from filenames
-
-== 252. Summoned critter problems:
-From: "Ben Goetter" <goetter@m...>
-Sent: Thursday, March 15, 2001 9:45 PM
-Subject: Crawl 4.0pr10z 13 Mar report Bug report: summoned creatures are
-appearing in the same space as the
-caster. (Cast spell, summoned creature not visible; move one space,
-creature appears in space vacated by caster.)
-<FIXED>
-Date: Fri, 16 Mar 2001 09:00:41 PST
-From: tgord <clubs-mail@y...>
-Subject: Re: Crawl 4.00 pr10zf [Yahoo! Clubs: Linley's Dungeon Crawl]
-I've noticed that summoned monsters sometimes appear on the other sides of
-walls now. ^^^^^^^^^^^
-<FIXED, for player summons>
-
-== 253. Change messages for weidling awkward weps to show up only at
- values <= -4 (for real problems) and change message to "not taking
- full advantage of the weapon" or somesuch. More flavour, too..
- maybe messages like "you're too clumsy" for dex<10; others for
- high (but unbalanced) stats: "You'd be (a lot) better with
- that weapon if you were (stronger/more dextrous)"
-
-xx 254. Give Earth Elementalists a few stones (say 10-15) to help them
- get started?
-
->> addressed with the new, 'easier to run away from' monster AI?
-
-== 255. I thought someone had added the MST_* enum usage to mon-data.h,
-
-== 256. Would be nice if the wizard patch I put up in the files directory
- made it into the code.
-
-== 257.PS Oh, using crawl -scores leaves the terminal in a bad mode...
- stty sane is required to sort things out (either curses shouldn't be brought
- up with this option, or it should be shut down properly).
-
-Just change the exit() call to a stuff::end() call.
-// check for highscore list - must be done BEFORE libw32c init
- if (Options.sc_entries > 0)
- {
- cprintf(" Best Crawlers -"EOL);
- hiscores_print_list();
- end(0);
- } The argument to end() is the exit value. That should probably be 0,
-rather than 1, since there's no error here.
-
-== 258. This bug ( if it is a bug ) has been around for a while... it seems
-: that sometimes when you poison a monster and it dies from the poison,
-: it gives you exp, and other times it doesn't. Is there some logic
-: behind this? A low level character of mine just barely managed to
-: kill an OOD hippogriff using poison, and got gypped of the exp. =(
-
->> Very old problem in beam code; poison_monster was being called
->> incorrectly.
-
-xx 259. I once got a corpse from a summoned snake - I hadn't been
-able to reproduce it, but it's corroboration.
-
-== 260. Give monsters large bonus while target is MHITYOU and behavior is
- BEH_WANDER, during player stealth checks - monsters will still be on
- the lookout for the player.
-
- Give a small chance each clock tick of deleting the MHITYOU; i.e. monster
- 'forgets' about the player. Stupid monsters forget faster..
-
-== 261.
-I was playing a transmuter, and noted that I was getting "You
-punch the <foo>" messages while fighting in spider form. I'm not
-getting the unarmed punch attack, so I think the verb comes from
-fight::weapon_type_modify(), which doesn't take transformations into
-account:
-
-static int weapon_type_modify(int weapnum, char *noise, char *noise2,
- int damage)
-{
- int weap_type = WPN_UNKNOWN; if (damage >= HIT_WEAK)
- {
- if (weapnum == -1)
- weap_type = WPN_UNARMED;
- else
- {
- if (you.inv_class[weapnum] == OBJ_STAVES)
- weap_type = WPN_QUARTERSTAFF;
- else if (you.inv_class[weapnum] == OBJ_WEAPONS)
- weap_type = you.inv_type[weapnum];
- }
- } strcpy(noise2, ""); switch (weap_type)
- { ... case WPN_UNARMED:
- if (you.species == SP_TROLL || you.mutation[MUT_CLAWS])
- {
- if (damage < HIT_MED)
- strcpy(noise, "claw");
- else if (damage < HIT_STRONG)
- strcpy(noise, "mangle");
- else
- strcpy(noise, "eviscerate");
- }
- else
- {
- if (damage < HIT_MED)
- strcpy(noise, "punch");
- else
- strcpy(noise, "pummel");
- }
- return damage; ... }
-}
-
-xx 262.
-
-from Win32 precompiled pr10 on Windows 2000:
-
-You see here a white potion.
-B - a white potion
-Drink which item? (I choose B)
-You feel much better.
-Eat which item?
-That banana was delicious!
-B - a white potion
-You finish eating.
-
->> Must have had autopickup off, but I cannot reproduce.. think it
->> might have been fixed by fixes to message.cc
-
-== 263. When i name a character 'con' or 'Con' it freezes the game.
-
-== 264. Generate wandering monsters on/near stairs about 10% of the time,
- regardless of player position, but disallow banding and generate a
- message ("A %d enters from above/below!") if player is around.
-
-== 265. Has anyone else noticed that after a draconian dies, every high-score on the
- screen is listed as having been a draconian? When a non-draconian dies, the
- draconian is listed as having come from race "Yr".
-
-== 266. Cleaned up monster blinking.
-
-== 267. Monsters following up the stairs if they are "not aware" of the player (odd!)
-
-== 268. Some problems with monsters not following player position correctly, or
- just plain waggling back and forth when they should be beating on the player.
- Sigh.. gotta look closer at those movement routines. :P Not ready for
- prime time yet.
-
-== 269. Simple fix to handle_behavior()
-
-== 270. After a while, crawl again went of bounds, this time with this
- backtrace:
-
- #6 0x80e9119 in seekmonster (p_monsterid=0xbffff1e0) at mon-util.cc:816
- #7 0x80e91bc in mons_intel (mc=-1) at mon-util.cc:837
- #8 0x80db2a7 in behavior_event (mon=0x8247e90, event=1, param=0)
- at monstuff.cc:394
- #9 0x81339c7 in noisy (loudness=8 '\b', nois_x=45 '-', nois_y=34 '"')
- at view.cc:1249
- #10 0x8132927 in monster_grid (do_updates=true) at view.cc:941
- #11 0x8131bca in viewwindow2 (draw_it=0 '\000', do_updates=true) at view.cc:574
- #12 0x8052f76 in input () at acr.cc:2020
-
- The bad thing here is that line #7 has mc=-1, and seekmonster() will use
- that as an index.
-
-== 271. Could we tie this to smartitude? Killer Bees and other insects can
- forget that I exist when they can't see me while Liches ought to
- cast 'detect exact player loaction' and Dig or teleport their way
- to me, for a LOOOOOOOONG time after I damage one.
-
-== 272. Cleaned up abyss generation; there was a monster leak and some very strange
- code.
-
-== 273. Fixed minor screen redraw problem (screen should have updated before monsters'
- turn, but it wasn't. Caused some odd SFX artifacts, like beams/missiles going
- through walls)
-
-== 274. Fixed nasty bug with cornered monsters which had them looping from flee->
- cornered->seek->flee->...
-
-== 275. Fixed small logic error with perma-mutations
-
-== 276. I was invisible and an orc spotted me, shouted, and then came at me.
-
-== 277. gotta clean up monster target aquisition and release. Make more 'sensible'
->> Add 'persist' variable; which is # of turns a monster will go towards their
->> CURRENT target even if it is not in LOS anymore.
-
-== 278. Fixed type usage problem with quadrant_blink()
-
-== 279. Made monsters move a little more unpredictably along oblique paths
-
-== 280. Fixed up all cases I could find of friendly monsters frying players
- (NOTE: they might still do so as part of calculated plans to help the player
- out - some collateral damage is acceptable!)
-
-== 281. "The your cursed +1 robe is stuck to your body."
- "You are a elf wizard."
-
-== 282. Can't pick a target with Apportation spell.
-
->> works fine for me. Added a helpful message.
-
-== 283. It seems that sometimes monsters are not interested at you even if
- you shout ("!") at them. Or is it feature ?
-
->> nope, bug. Any noise coming from the player's position should alert
->> hostiles within range depending on the volume of the noise.
-
-== 284. Sometimes monsters (rats, bats and probably others) attacks you,
- but they are still described as "not interested".
-
->> fixed in direct.cc.
-
-== 285. I have also
- made some changes to the file attributes when it is compiled with MULTIUSER
- option turned on, since I think the player's save and level files should NOT
- be group writeable :), but the score file should be.
-
->> .sav and level files are private (600). Ghost and score files are not (664)
-
-== 286. There seems to be a more serious bug with summoning monsters in Crawl pr11:
-: I`ve found that summoned creatures aren`t giving any experience to your
-: character when they kill things any more, which makes summoners a bit crap.
-:
-: Also, when my Chaos Knight summoned a demon ( yquxy whatsit) it kept trying
-: to eat my intelligence and mutate me, which has never happened before.
-: Demons killing monsters didn`t give me any message from Makhleb either.
-
-Both fixed. #1 is logic problem, #2 is generic friendly fire problem.
-
-== 287.
- I'm playing pr11, DOS version. My merfolk healer was in a situation like
- this:
-
- ................. (water squares...
- ..;;.............
- .................
- .................
- .................
- .................
- .................
- ......;.......... water squares end)
- ......@.......... this is solid ground
-
- The placing of the symbols is not accurate.
- Now none of the eels could hit me with their blasts. The eel right next to
- my character kept shooting straight upwards and the two eels farther away
- kept missing me by my right side. At least one of them also hit the eel
- right next to me. I killed the nearest eel, after which the other two just
- kept missing me. My character was not invisible.
-
-: Also, it's not just electric eels. Storm dragons also tend to shoot in
-: the exact opposite direction to the character. Looks to me like it might
-: be a sign problem...
-
->> ugh. bad side effect from tracer explosions. Fixed.
-
-== 288. Fixed whopper of a bug with generation of fast monsters which often hung
- the game (especially in areas with lots of fast monsters, like the hive).
-
-== 289. Brent's balance patches
-
->> applied all, reduced missile damages by 1 to compensate. Gave daggers
->> and spears better chances to hit.
-
-== 290. The "temporarily insulated" message is weak... it's kind of
- confuing and looks a bit like a bug. Better would be a "god
- protected you" message after the explosion... that would tell
- both the source and the reason for the insulation.
-
->> agreed. Changed to post-divine blast message.
-
-== 291. Hate to follow up to myself, but a small thing was brought to
- my attention. Now that the dice for damage are one based, this
- means that Magic Dart is now really the best first level spell,
- this being because it uses the 3dX notation (ie dam > 100), so
- it does a minimum of three damage (which isn't bad) and always
- hits (which makes this too good for a spell which is very common).
-
- So I'm suggesting that the damage for Magic Dart be converted to:
-
- damage = 1 + (power / 2) (this is in it_use2.cc).
-
->> changed to 1+pow/4.
-
-== 292. The third ability gained by followers of Zin is pestilence. This summons
- a variety of bugs that hopefully will helpfully kill off whatever happens
- to be bugging you.
-
- Trouble is, every time my character uses it at least one my little
- chitinous friends gets killed. Zin doesn't like that, so my character
- feels guilty.
-
- The same thing happens with the fifth ability, Summon Guardian, but
- it's not so bad there. The summoned Angel (or Daeva, for fans of the
- TSO) can generally take care of itself, although I did lose a Daeva to
- a dragon once. Luckily it left behind a long sword of holy wrath to
- assuage my guilt.
-
->> add a flag to god-summoned critters so that their death doesn't cause
->> piety loss. Summoned friendlies will still give piety loss; the 'good'
->> gods don't appreciate you summoning beings as cannon fodder!
-
->> tried to apply the god_gift flag wherever it made sense; Zin Pestilence
->> was the only place I could find.
-
-== 293. Finally found and fixed 'critters summoned out of LOS' bug.
-
-== 294. Fixed logic problem in quadrant_blink()
-
-== 295. Fixed buffer overflow in acr.cc during char dumps.
-
-== 296. Fixed minor display problem in backlight_monsters()
-
-== 297. Added Guus' -plain and doc patches
-
-== 298. CHMOD_PUBLIC now uses 664 instead of 666.
-
-xx 299. Actually, there was at least the comment from the newsgroup
-about elven conjurors starting with the Ice/Air book (because
-they're better at Air than Earth and equal in Fire and Ice).
-The actual spells tend to lean a bit more to the Fire/Ice
-side so I really don't see why they shouldn't have the choice
-(or rather why anyone should have this auto-picked). Adding a
-selection screen and an initfile option wouldn't be that hard.
-
-== 300. Change magic dart damage to 2+power/4
-
-== 301.
->I'm wearing a ring of Shadows. When I try to take it off, it says
-: >that it's stuck to me. When I 'v'iew it, it says that it has a curse
-: >placed upon it. But it doesn't show up as cursed in my inventory
-: >list, and scrolls of remove curse don't work.
-:
-: Oh... and if it helps at all: I killed a mummy at a certain point,
-: with no apparent curse effect. This may be how the ring got cursed
-
->> the check for randart rings was looking for 200, but the actual
->> inv_dam value for randart rings is 201. "Pluses2" of 100 is not
->> well defined in the code... :(
-
-== 302. Abyss go to shits after abyss_teleport()
->> wasn't setting terrain to DNGN_UNSEEN. Was using old (stupid)
->> value of 30 (white triangle!)
-
-== 303. In fact, they seem able to sneak right up to alert monsters and still
-deliver the first blow. I think that such a blow should sometimes count
-as a stabbing attack, just as blows delivered to fleeing or confused
-monsters currently are. Currently such attacks have a
-
-random2(200) <= you.skills[SK_STABBING] + you.dex
-
-chance of being stabs.
-
->>Gave chance if monster isn't paying attention to you (foe != MHITYOU), but
->>stab bonus is much lower (3) than stabbing a sleeping/fleeing monster.
-
-== 304. Not sure if you saw my big report on roguelike.misc, since it hasn't
-: been fixed and doesn't seem to appear on the 'to do' list. The spell
-: 'Lee's Rapid Deconstruction' doesn't do any damage at present. It
-: occasionally destroys the wall which is targetted, but I detonated 20
-: walls next to a rat and didn't scratch it. This leaves Earth Mages
-: without an area-effect damage spell, which is rather detrimental to
-: their health :(.
-
->> Fixed. Needed subtle wrinkle in explosion map, as well as some
->> fixes to the spell itself.
-
-== 305. Currently, if you skip the first naming screen but use the second
-you can overwrite a previous game. Although this is unusual
-behaviour, it's not very desirable, it should at least warn
-about this and potentially give an option to load the old game.
-
->> fixed. good catch.
-
-== 306. Wielding a bunch of stones and trying to throw one of them,
-results in all of the stones being thrown (and potentially disappearing
-as well).
-
->> Very, very subtle bug in beam.cc inherited from original codebase.
->> Fixed.
-
-== 307. monster_move(monster);
- // reevaluate behavior, since the monster's
- // surroundings have changed (it moved)
- handle_behavior(monster);
-
- Some monsters are getting killed on their move, and then the
- code in handle_behavior() will fail an ASSERT since monster->type
- will be -1.
-
-== 308. After one hit with a poison dart, "the goblin looks rather
-more sickly". The non-"...more..." message is (repeatably)
-never shown. - Josh PS: Could we consolidate the poison-effect-namespace to either
-"ill" + "rather more ill" or "sickly" + "rather more sickly"?
-I favor the former.
-
->> oops. simple messaging problem. Similar prob. in sticky flame.
-
-== 309. Only one bug found - in newgame.cc (line 2222) should be used
-strnicmp() instead of strncmpi(), because the second one isn't
-existing function :)
-
-From BWR:
->Actually, we should probably avoid both, I don't think they're
->very stardard (BSDish systems will use "case" over "i").
->strncmp() is POSIX (among others) so it's okay, but the case
->insensitive compare almost always causes problems (if we're going
->to use it, we should probably have it defined somewhere, so it
->can be adjusted or handled by autoconf (should we go that route)).
-
->> correct - neither are POSIX. However it is being used in a DOS/win32
->> section only, and strnicmp() is the proper call as Michael pointed out.
-
-== 310. I've looked at monster pronouns and IMO (supported by dictionary)
- Erica and Frances should be female and Francis should be male.
-
- Probably also description of uniques could be slightly changed
-according their gender, for example
-Jessica - "An evil apprentice sorceress."
-
->> done.
-
-== 311.
-In either event, to get crawl to compile, the str<foo>cmp(x,y) == NULL
-in initfile.cc needs to be changed to "...== 0". The line is near 520.
-
-== 312. Change shops back to old [0][5+i] item location. Leave items
- carried (ie not on grid) at 0,0. Make sure to modify link_items();
- keep compatibility with old saved games.
-
-== 313. I think giving Ogre and Troll Fighters Dodging 2 is probably in order.
-
-== 314. Fleeing monsters were not taking advantage of the flexible movement
- code (Guus)
-
-== 315. Gave monsters a little better chance of sniffing out foes (stealthy
- players will fare better). After arriving at target x,y, will do a check
- for continuing on via ESP/noise/whatever.
-
-== 316. Removed ability of monsters to see through walls. :)
-
-== 317. : Just tried casting Tukima's dance while wielding an artifact weapon.
- : I get the message "You hear a popping sound." and although my artifact
- : stays in my hand, something that looks like a Shadow appears. Its
- : name: 36317738 iron wands. If you 'x' it and hit '?' it says "A
- : dancing weapon floating in the air." just as if the spell had worked
- : right. The thing even moves and attacks like a summoned monster, and
- : seems to have combat stats of some sort, since it can kill things.
- : When the spell expires, it says "The weapon drops from the air." as
- : normal, but the monster just ceases to exist; it doesn't leave a copy
- : of the weapon behind or anything. You can even summon several of
- : these "36317738 iron wands."
-
->> ugh, two separate logic problems in dancing_weapon(). Fixed.
-
-xx 318. I could be wrong, but I think that the Orcish Mines had no scrolls,
- potions, wands, rings, or amulets. Very odd. But since Gordon just
- rewrote dungeon.cc, we should wait for reports about pr13.
-
->> this is working exactly as designed, if I read the original code correctly.
-
-== 319. But I failed in my casting too often, and the
- buildup of mutagenic energy had some unfortunate effects. Even after I
- gained some levels in Divination, and my Success chance was up to Fair,
- I failed to successfully cast the spell sufficiently often that I mutated.
- So be wary of casting even second level spells.
-
- from BWR:
- We've have people getting mutations here from level one spells.
- I'm thinking that at the very least we need to lower the baseline
- for noticing that you're accumulating radiation... and possibly
- put in some warning messages so people know that they're getting
- a bit "hot" and that they need to take it easy for a while.
-
->> messaging much better. toned down nastiness from low level spell failure.
->> made my easter egg much less abusable.
-
-== 321. I do wonder that Zin wasn't upset when I zapped the Angel initially.
-
->> Zin is stupid and can't differentiate between a hurtful and helpful
->> spell. Perhaps a small subset could be classed as obviously harmful,
->> so that if you e.g. healed or hasted the daeve it wouldn't get pissed.
->> have to be done in beam.cc, I think... any non-enchantment would be
->> classified as harmful, I think. (?) Other enchantments would have to
->> go in a big if/switch.
-
->> this will also help to NOT piss monsters off if you're trying to help
->> them.
-
-== 322. 2) Item clean-up in the dungeon seems far more
- aggressive than before. I've dropped items,
- popped down a staircase and right back up,
- only to find everything I dropped gone, gone,
- gone! This would be on "cleared" levels where
- the likelihood of item overload is almost nil.
- Is this a change in gameplay that I missed? In
- pr13, I am finding myself holding onto *everything*
- because I *know* that if I drop it and leave the
- level it will simply disappear ... a PITA situation
- for low-strength characters wanting to stash some
- extra stuff for later.
-
->> oops. Somehow broke item save/reload for any item dropped by player
->> or monster. Took closer look, cleaned up horrible hacky code. :P
-
-== 324. Make random zombie generation reflect the actual level; it is currently
- random.
-
->> no more horribly OOD zombies.
-
-== 325. Monsters with OFFENSIVE spells in mspell[2] will still use them
- on the player (sigh..)
-
->> fixed all cases in mon-spell.h
-
-== 326. Accidentally doubled the number of monsters created w/ level.
-
-== 327. : Scrolls of fear appear to be bugged. Read one, got messages saying
- : that the monsters were frightened (ie, not "The blah resists."), but
- : they kept moving towards me and attacking me.
-
-== 328. In pr12, my Troll could see an unseen horror. He was not wearing any
- devices that could lend him see invisible, and orcish wizards were
- turning invisible earlier in the game.
-
->> oops. logic problem in mons_del_ench()
-
-== 329. Sigmund and other uniques appearing multiple times
-
->> logic error in dungeon.cc
-
-== 330. Magical staves are described using the old style (speed)
-
-== 332. Monsters walk into clouds, except for intelligent ones?? Check code:
-mannix writes:
-Now here's an idea to which I can warm: stupid animals
- thinking "where there's smoke, there's fire", and more
- intelligent critters in possession of the ability to
- discern betwen the two.
-
-== 333. Monster Placement: is there a place where, if you can't find a sensible
- location for a monster in a group, you just put that one anywyere?
- I think that's part of what makes monsters appear in LOS ... I just
- got a gnoll and two orcs.
-
->> stupid error in monplace.cc. Forgot that distance() function returns squared
->> values.
-
-== 334. Shapeshifters: one turned into a Swamp Worm. This ought not happen,
- as those are water-only monsters, despite their worm designation.
-
->> fixed. Won't let monster poly into water-based monster on land.
-
-== 335. dungeon.cc::pick_an_altar(): needs to have a case added, near line 5988:
- case BRANCH_SLIME_PITS:
- case BRANCH_ECUMENICAL_TEMPLE: //jmf: ADD THIS LINE
- altar_type = DNGN_FLOOR;
- break;
-
- ... to prevent "bonus" altars in the Temple. This was probably the
- original author's bug (i.e.: mine).
-
-== 336. So the city-like dungeon code has some sort of an off-by-one error.
- The "buildings" (squares with doors) once were separated by at least
- one space of floor; no longer! Furthermore, they once didn't overlap.
-
- The changes provide much more interesting cities, however the door
- generation hasn't quite caught up. I've seen things like:
-
- #########
- ####+...#
- #####...#
- #####...#
- #########
-
- ... where it's fairly obvious what went wrong. (I discovered these
- types of things when playing a gnome.)
-
- The quick fix would be to restore the 'air' around buildings, but
- IMHO that would be a loss. The new cities are so much cooler.
-
- A more complex fix would be in two steps:
-
- 1) make sure there's a passageway around the border of the level.
- A single sweep setting all those squares to floor would be fine.
-
->> tightened up door placement in box_room(); since both city_level()
->> and plan_4() use it, stuff works better now.
-
-== 337.
- Sticky Flame puts monsters in the player's thrall
-
- This last one is really bizarre, because it doesn't happen
- in the wizard mode compile (although I can take that character
- over to the normal version and have it happen there).
-
- It's intestesting to note that these monsters end up with
- enchantment number 30, which is one less than the sticky
- flame enchantments... in the wizard mode they seem to get
- enchantment number 60 (which is one less than the other
- set of monster sticky flame enchantments... also known
- as POISON_IV). I'm wondering if anyone else can verify
- this.
-
- I suspect that there's some problems in the enchantment system, which
- could be responsible for both of these. Looking at sticky flame today
- it seems that my sticky flame ends up as ENCH_POISON_III or _IV
- (59 or 60) regardless of playing crawl or wizcrawl. The in-thrall
- thing seems to not be happening right now. It occurs to me that I
- never actually got "burn" messages in pr12 when I was using napalm
- (I hit an Ice Dragon about six times with it and it never seemed
- to take any damage after the initial hit)... looking at the code now,
- I'm pretty sure I should have been (and that any appearance of working
- in the recent past might have in fact been delayed poisoning).
-
->> Fixed. sticky_flame_monster() was badly broken. gawd I bunged that up.
-
-== 338. As a side note, I now backstab bats quick often (I take it that
-this is a side effect of the new backstabing situtation). I'm
-not really sure I should be able to do that (or more to the point,
-does this mean I can expect regular backstabbing of ball lightning
-and spatial vortices which might be a bigger problem).
-
-== 339. In Win32 pr13, if you set class = C in init.txt, your character will be a
-priest ('c') instead of a wanderer ('C'). This happens regardless of if
-your race allows wanderers.
-
->> bug in initfile.cc
-
-== 340. Basically, nowdays if you turn a bat into an undead slave,
-it suddenly comes to it's senses and becomes an inadvertant
-killing machine (well against monsters that can't easily kill
-it in one hit), as it walks straight up to them and hits them
-3 or 4 times a round. Undead bats should still flutter around
-(that's what keeps them in check considering their amazing speed).
-
-== 341. I've run into some surprisingly powerful ghosts in pr13.
-They are only overly powerful in non-wizard compiles; the
-two times I switched to a wizard-compile they acted normal. One
-was casting MS_ENERGY_BOLT instead of either magic
-dart or throw flame (the two spells that character knew).
-
->> very bad indexing bug in ghost loading. Who knows what else
->> this was screwing up.. :P
-
-== 342. Some attempts to animate a skeleton result in a puff of smoke in addition
-(I think) to a new slave.
-
-== 343. We've had several reports here about necromancers zombies and skeletons
-actually getting poisoned from time to time by monsters. As far as
-I can tell this really shouldn't be happening.
-
->> probably a side-effect of messed up enchantment code.
-
-xx 344. If you start a game with -plain, Save, then continue the game without -plain,
-then the displayed map for remembered locations uses the -plain characters.
-
-If you start a game without -plain, Save, then continue the game with -plain,
-then the displayed map for remembered locations uses the extended characters.
-
-== 345. I haven't heard this one mentioned, but when wielding an ego item you
-typically get this:
-
-d - an elven short sword (weapon in hand)
-Wielding this short sword is a little awkward.
-It softly glows with a divine radiance!
-
-The elven short sword should be id'd as "holy wrath" in the first line...
-it was unid'd when I did this, so it looks like a simple case of moving
-the identify code to a place before the printing.
-
-xx 346. Breathing fire via the mutation prints this unnecessary line:
-" .\n"
-
-xx 347. I got a segfault when entering the abyss; wasn't playing under
-gdb, for some reason, so didn't get a stackdump. Sorry.
-
-== 348. Brent's XP patches
-
-== 349. Josh's sludge elf, etc patches
-
-== 350. In mon_util.c::define_monsters(), there are some mystical values
- assigned to m2_sec, some of which can be made more apparent by
- using the appropriate MST_* values.
-
-== 351. Actually, a thought just occured to me that the new stabbing
- code that gives occasional backstabs against flutterers, is
- probably very annoying to Paladins. We might need at least an
- additional check to prevent some of the excusable backstabs from
- being naughty... perhaps it's just as simple as only making
- attacks on fleeing, sleeping, and confused monsters call naughty
- (in which case, it might be reasonable to remove the random
- chance for TSO applying penance).
-
- One of the problems with confusion based stabbing is that some
- monsters are created with it, and most of those probably shouldn't
- be backstabable (various voritices, ball lightning, vapours). So
- maybe we might need some way of distinguishing if the stab is
- appropriate (or if not that, we should probably leave them off the
- above list for naughtiness).
-
->> new code to void backstabbing against flutterers (solely because
->> they are flutterers) and perma-confused critters (solely because
->> of confusion).
-
-== 352. in check_mons_magres(), the return value for the special "< 6"
- bonus is backwards. I'm probably to blame for not noticing that
- the function is logically backwards, I probably got confused by
- one of the cases in spells4.cc which use this function backwards
- (a few of which are my own).
-
-== 353. I added a "gotoxy( 18, 9 )" to the top of our direction function,
- which nicely solved the porblem where the cursor was left at the
- end of a prompt (ie for conjure flame).
-
-xx 354. We've had a report of skeletons picking up skeletons.
-
-xx 355. I've had several people reporting some oddness when returning
- to a level via a straight up and down... things like monsters
- completely disappearing and traps being created.
-
-== 356. pets seem to try and track the target monster even when they're
- on the wrong level. Basically, if you go down stairs and tell
- your pets to attack something and the go upstairs to try and
- bring more pets down, the upstairs pets will be running around
- wildly... going downstairs and killing the target made the
- upstairs pets return to the master homing behaviour.
-
->> simple fix. Set pet_target to MHITNOT on level change.
-
-== 357. The lastest in the bizarre happenings around here was a friendly
- player ghost... wonderful entertainment as it would should out
- things like "Run, I'll cover you" and such.
-
->> always a possible problem; some fields were left uninitialized from
->> monster_cleanup(), and never initialized in the ghost code!!
-
-== 358. Removed digging ability from Disrupt()
-
-== 359. Added 'random' beam that affects each cell as one of { fire,
- cold, magic, electricity, poison, negative energy, acid }. Only
- used in my easter egg so far.
-
-== 360. Maybe we should instead be considering shifting the greater
-vaults down to level 10+, and the lesser vaults to 7+ (there
-are many more mini-vaults (and better quality these days, and
-this does have the advantage removing dlev 4 guardian naga
-encounters... we've had several).
-
-== 361. Okay, compiled it up and the only problem was that link_items() is
-declared both static and extern (removed the static prototype).
-
-== 362. One other little problem: The magic resistance check for monsters
-is now correct, but there are some inappropriate calls to it over
-in spells4.cc (in particular Twist is currently unusable).
-
->> reversed the logic.. this was just too non-intuitive and backwards.
-
-== 363. Move the Crawl.mcp file out of the source folder.
-
-== 364. Add "#define ESCAPE 0x1B" to defines.h
-
-== 365. In eat_food() in food.cc add some code before the "You don't have
- any such object." case:
- if (keyin == ESCAPE)
- return;
-
-== 366. lava_spaces and water_spaces in builder_monsters() in dungeon.cc
-aren't inited. (This looks like a nasty bug).
-6) In quadrant_blink() in spells4.cc there's a line that reads "while
-(!done && random2(100) < pow--);". Please move the semi-colon to its
-own line.
-
-== 367. Snakes now flutter like bats did. They also display the "not interested
-in you" message when e'x'amined.
-
- Josh:
- I've had a batty frog and batty snake. Both had the old
- 'not interested in you' inspection message. Most frogs
- and snakes were not batty.
-
->> oops. Monster->flags was not being set to 0 at monster creation.
-
-== 368. in monstuff.cc::handle_spell(), the CONFUSION && !vapour
- should probably be changed to use M_CONFUSION to be generic.
-
-== 369. the contamination messages should probably be in the warning channel
-
-== 370. wizard's hats say they give AC, but they don't
-
-xx 371.Fireballs are rather larger than I remember.
-Mana explosions from magic accumulation are the same size (very big).
-I'm pretty sure the former is unintentional; is the latter?
-
-== 372. There's an illiterate "it's" in the description of Silence. The word
-ought to be "its". (This is a peeve of mine. "We hate's them, ye's
-presciou's!")
-
-beam.cc::2753
-- hearMsg = "You hear a gentle \'poof\'";
-+ hearMsg = "You hear a gentle \'poof\'.";
-
-== 373. I haven't seen any miscast effects except for the irradiation one.
-I think this is due to a loop in spell.cc which tries to figure out
-which school of miscast-effects applies to a given spell. The loop is
-a bit past line 300 and seems to ignore the new 'bitmap' representation
-of spell-schools. I know that miscast_effects is getting bogus sptyps.
-
-Full, real fix:
-unsigned int sptype = 0;
-do {
- sptype = 1 << (random2(SPTYP_LAST_EXPONENT+1));
-} while (!spell_typematch(spc2, sptype));
-
-== 374.
-newgame.cc::3410 + if (you.species == SP_HILL_DWARF ||
-+ you.species == SP_MOUNTAIN_DWARF)
-+ you.skills[SK_MACES_FLAILS] = 1;
-+ else
- you.skills[SK_SHORT_BLADES] = 1;
-
-== 375. Later in newgame.cc: Now that Sludge Elves suck at enchantments
-and conjurations, we could remove the options for them to be Conjurers,
-Reavers, Enchanters and Crusaders.
-
-** 376. Something is still deleting the ABJ_xx enchantment for summoned
-monsters. Don't know what though.
-
-== 377. Fixed magic resistance of normal & small snakes.
-
-== 378. case CLOUD_POISON:
- case CLOUD_POISON_MON:
- if (mons_res_poison(monster->type) > 0)
- continue;
- if (monster->hit_points >= random2avg(37, 4))
- continue;
- break;
-
-THIS IS WRONG VVV
-
- // dumb monsters can be fooled by smoke
- if (mons_intel(monster->type) > I_ANIMAL || coinflip())
- continue;
-
- // this isn't harmful, but dumb critters might think so.
- case CLOUD_GREY_SMOKE:
- case CLOUD_GREY_SMOKE_MON:
- if (mons_res_fire(monster->type) > 0
- || (monster->inv[MSLOT_ARMOUR] != NON_ITEM
- && mitm.special[monster->inv[MSLOT_ARMOUR]] % 30
- == SPARM_FIRE_RESISTANCE))
- {
- continue;
- }
-
-== 379. Brent's 'friend-brand' patch
-
-== 380. Undead should *not* have morale failures, nor should the dumber ones avoid
- flaming clouds of death (brown & white 'z's & 'Z's). Skeletal warriors
- might avoid FCoD since they do make one other intelligent decision (wrt/
- casting their spell), but they ought never run away.
-
->> who says running away is due to morale failure?
->> REALLY dumb (I_PLANT) creatures will now walk through harmful clouds.
->> this includes most of the shambling (mindless) undead
-
-== 381. quadrant_blink() from Brent
-Brent Ross <bwross@c...>
-
- In this method, what we're going to try for is the best match, and
- allow the number of choices to be based on power. The basic hope
- is that while even high power characters have to put up with some
- randomness, the diameter of the cone decreases making it more
- reliable.
-
- let line = line segment extending out from player in the chosen dir
- let best = NO_SQUARE
-
- for i = 1 to f(power)
- targ = random nearby square
- if (dist( targ, line ) < dist( best, line)) then
- best = targ
- else if (dist( targ, line ) == dist( best, line )) then
- // Not really sure we want this part, maybe we should throw in
- // a random to keep the distance sane.
- if (dist( targ, player ) > dist( best, player )) then
- best = targ
- endif
- endif
- endfor
-
- if (best == NO_SQUARE)
- mpr( "teleport control screwed up" )
- random_blink
- else
- player = best
- endif
-
-== 382. De-twink wanderers
-
->> undefined USE_SPELLCASTER_AND_RANGER_WANDERER_TEMPLATES until we have
->> "hedge" magic.
-
-== 383. Check that all spell books are listed for generation.. at least war chants
- is missing.
-
-== 384. Add "Blowgun" (launcher) and "needle" (ammo)
-: basically, go through all code looking for BOW, add blowgun
-: go through all code looking for ARROW, add needle
-: assassins now start w/ blowgun & needles
- except for deep elves; they get hand xbows since they tend to
- suck at HTH and will rely more on ranged damage.
-: some chance for needles of Foo? (dungeon.cc) just poisoned
-: some chance for blowguns of Foo? (dungeon.cc) of venom
-: must remember to add in to item generation tables. :)
-: change throw_it() so that blowguns and thrown darts are
- very quiet; all others make a noise - check fight.cc for
- a good noise value. Note that alert() is simply not called.
-: give a couple monsters blowguns & needles to start
-: needles get damaged far less often (but make them rarer;
- maybe only carried by assassinish-monsters.
-: Needle trap at higher levels; could be a source of needles?
-
-TODO: dungeon.cc::give_item() . which monsters have bguns/needles?
-other files not searched for WPN_BOW and MI_ARROW (our template for
-this stuff):
-
-== 385. fixed logic problem in cast_sandblast()
-
-== 386. If I cast a fire spell at something in the water, it leaves a trail of
-steam behind it. A fireball should have the same effect (but of course
-over a larger area)
-
-== 387. Josh' new diff (mostly Xom acts)
-
-== 388. A Skeletal Warrior just drank a potion of healing. This strikes me as
-wrong, from both pseudo-physiological and gameplay perspectives.
-
-== 389. I saw hellwing which polymorphed jackal to lava fish. Probably
-this is not bug but we should consider this.
-
-== 390. We've had
-someone complain here about his Ogre not being able to wear one.
-I thought we had decided that caps and wizard hats were wearable
-by all characters, regardless of headsize or horns.
-Anyone remember?
-
->> there's a comment in item_use about caps & wiz hats being
->> wearable by anyone "unless their head is too big (ogres, etc)"
-
-== 391. I've found a number of eggplants in pr15, err, 4.1.15
- (these were supposed to be MI_NEEDLE.. what happened!?)
-
-== 392.
-I made it to the Abyss... Now I'm stuck in this loop in
-dungeon::define_zombie(): while(true)
- {
- // this limit can be updated if mons->number goes >8 bits..
- test = random2(182); // not guaranteed to be valid, so..
- cls = mons_charclass(test);
- if (cls == MONS_PROGRAM_BUG || mons_rarity(cls) == 0)
- continue;
-
->> VERY tricky to fix correctly.. no wonder it was never done.
-
-(which monsters to allow as zombies in the abyss?)
-
-BWR:
-Or perhaps just picks with the base level set as high as
-possible... which will allow for Zombie Titans (which are high
-enough level that they're never "naturally" generated, I believ
-
-Well simulacrums are out right away. They don't appear naturally
-anywhere, due to the fact they sublimate away. On a similar note,
-ball lightning shouldn't be generated anywhere, but I believe I
-accidentally put them in the Realm of Zot... short lived creatures
-should have to be summoned in. As for zombie/skeletons or even spectres (which I don't believe
-are generated anywhere.... Spectral Warriors are generated,
-but they're like Skeletal Dragons in that they're completely
-different... don't think I've ever seen a Spectral "Thing"
-in any dungeon, at least not one I didn't create myself) are
-probably okay in the abyss... there are things like abominations,
-necrophages, skeletal dragons/warriors there already. Spectres
-might also be interesting in the Realm of Zot.
-
-== 393. Oh, dear. I think I might have left in a debugging bit that changes _all_
-generated traps to needle traps - they're supposed to be fairly rare, and only
-seen below level 3!
-
-== 394. It looks like the logic in poison_monster() needs adjusting, too, if you're
-getting credit for monsters done in by the poison from needle traps. Ah well.
-
-== 395. // * fixed: magical staves now described with new speed
-
-Actually, there's still one problem here. The '%' needs to be doubled,
-since the description string will eventually be fired through cprintf()...
-it currently gets dropped in both cases (weapon and stave).
-
-xx 396. An eloquent method of handling this would be to 'queue' shouting messages
-between character actions and conflating multiple shouts into a single
-message ("Several <foo>s shout" or whatever), possibly conflating by
-monster type ("Several <foo>s shout out! A <bar> yelps!") so that the
-player can be alerted to unique shouts and/or get the *flavor* of all
-the various bellowing beasties.
-
-== 397. Make zombie monsters appear a few levels (3-4?) earlier than their non-zombie
-counterparts
-
-== 398.
-> I was blowing needles at an orc wizard, and he very politely gathered
-> all the needles up for me. I appreciated him doing that rather than
-> casting those nasty spells at me. :)
-
-Now, I thought that logic had been fixed (at least, in the case
-of darts) such that monsters with potent HTH or spell attacks would
-not lower themselves to gather scattered items for characters :P
-
->> fixed better. Monsters won't pick up if there's not much there, they're
->> not wandering, and they already have ammo. Fleeing monsters never stop
->> to pick up ammo.
-
-== 399. Needle traps will poison the player even if he or she resists poison.
-
-xx 400. Some first level spells won't allow the player to target him- or herself.
-This means that a player can't use those spells to see if he or she
-resists their damage type. Knowing if one resists a damage type is useful
-when trying on mysterious rings.
-
->> need some restructuring to do this; burn_freeze() isn't set up to
->> actually affect the player. :P
-
-== 401. Personally,
-I think Ijyb should probably get an XP modifier of 5 (and even
-then is still worth 40 xp)
-
-== 403.
-I think some kind of notice should be given, when body wich is carried
-becomes rottens. And ghouls should definetly be able to see when
-chunks of meat become rotten. As should everyone else, I think.
-
->>mv: added appropriate messages
-
-
-== 404. My Draconian monk (not so difficult as you might think) got mangled
-by a goblin with seemingly limitless ammount of scrolls of summoning.
-He summoned like 5-7 abdominations before my monk got killed. And
-this was at level 2. Extremely bad luck or bug?
-
-== 405. Crash in pr14
-This occurred in the Realm of Zot, while attacking an Orb of Fire, which had
-just exploded.
-
->> very nasty. Fleeing monsters with "emergency" spells requiring tracers
->> would crash the game.
-
-xx 406.
-When using Stone Skin with Dragonian it says "Your skin feels harder"
-and "Your skin feels tender" instead of "Your scales feel harder" and
-"You scales feel softer".
-
->> These guys still have skin underneath all those scales..
-
-== 407. Fix quadrant blink again:
-Which gives us the one-step formula:
-
- dist = abs( (y - you.y_pos) * (tx - you.x_pos)
- - (x - you.x_pos) * (ty - you.y_pos) ) / s
-
- where (x,y) is the player's targeted square/vector,
- (tx,ty) is the spell's targeted square,
- (you.x_pos, you.y_pos) is the player's position,
-
- and s is the distance between (x,y) and (you.x_pos, you.y_pos).
-
-
- The important thing to notice here is that s is constant for all
- of the trials (one or root-2), and since we don't care about
- an accurate measurement (only a relative one between trials),
- we can reduce it to one
-
-== 408. Although, 'f' does fire needles correctly, the ')' command doesn't
- actually show that this is the case (see command.cc::list_weapons()).
-
-== 409. Poisoned needle gives messages in bad order. Patch from Guus.
-
-== 410. > I just noticed that my character has a Dex of 63. I've chosen every
- > ability increase to be in dex, and he occasionally wields an artefact
- > dagger that is +3 to dex. I don't think it relates to save files,
- > as I haven't saved the game in three days.
-
- The stat growth is caused by autobutchering when the butchering weapon
- has a stat bonus. I get the stat bonus when I wield the weapon, but do
- not relinquish the bonus when I unwield it.
-
->> ewww. this was ugly.
-
-xx 411. I was playing a Spriggan Transmuter when i entered the mines. I was
- overwhelmed by +10 Orcs so i went back up. One orc followed me. I
- then started running away until i was several spaces away, turned and
- cast disrupt killing the orc. As the orc died the stairs to the
- mines disappeared.
-
->> can't reproduce.
-
-== 412. I've been trying out Chaos Knights and the critters that Xom summons
- for you have this annoying habit of polymorphing the bad guys to
- *way* OOD monsters. For example, my last knight was level 3 and is
- listed at -19/28 HPs in the morgue file. This was one spell and he
- was at full health when it happened. Although this was before the
- latest patch so perhaps it's related to the other OOD problems.
-
-== 413. >I've seen that disorder message a few times too. The first time the
- >game hung when I tried to go back up to that level. After that I
- >avoided loading those levels again. :-) There really needs to be
- >better sanity checking here. It's not right that a bad level can be
- >generated and only found when the player stumbles across a bad pile
- >of items.
-
- From what I can remember, this kind of thing is almost
- certainly the result of bugs in either the monster inventory
- code or the code responsible for placing monster corpses on
- death. The behaviour where the player picks up an item and
- it doesn't get listed in the inventory tended to be caused
- by the existence of a link to an item with a quantity of 0
- (this also causes "a scrolls labelled SDFKLSFD" - when the
- quantity is zero it puts an 's' on 'scroll' but leaves the 'a'
- in front).
-
-== 414. Characters cannot exercise fighting, weapon, or unarmed combat skills
- against plants/fungi, so perhaps they shouldn't exercise stabbing.
- And plants/fungi should probably always appear disinterested.
-
- This assassin has also been paralyzing monsters, but can't seem to stab
- one afterwards.
-
-== 415. My assassin carefully approached his victim:
-
- Move the cursor around to observe a square.
- Press '?' for a monster description.
- A plant.
- It doesn't appear to be interested in you.
- Floor.
-
->> obviously need some kind of data-driven thingie here for stabbing / paying
->> attention.
-
-== 416. I fire a "Disrupt" at a worm just off screen (as I'm running away):
-
- You kill the worm!
- Nothing appears to happen.
-
-== 417. He was standing on a down stairwell. He had full view of each of the
- adjacent squares, but not all of distance 2 squares. He was at a little
- over half his hp, and I hit '5' to rest and recover.
-
- Suddenly there was a bellow, and a hydra was beside him. The hydra
- proceeded to lay the smack down, slaying the poor assassin. I guess
- it's poetic justice, since the assassin slew quite a few monsters
- by suddenly appearing beside them, fiery blade in hand.
-
->> almost definitely a result of the new 'near stairs' code. Needs some
->> refinement, I suppose. (evil grin)
-
-
-== 418. Elyvilon got upset when a needle trap killed a monster just after
- I had prayed. :)
-
-
-== 419. Over the course of the game I obtained around a dozen blowguns and only
- one crossbow, so they may be too numerous.
-
- (most blowguns came from the ground)
-
-== 420. Two minor quibbles on spell descriptions.
-
- a) Unlike the other brand weapon spell dscriptionss, the Poison Weapon
- spell description does not mention that the spell won't work on
- branded weapons.
-
- b) The description of the Disrupt spell says that the spell "disrupts the
- matter of another creature's body", but the spell also affects
- creatures with non-material bodies.
-
-== 421. Fixed formatting problem with randart descriptions
-
-== 422. Changed slaying to be a little less powerful.
-
-== 423. Butchering with bare hands and a short blade in slot a doesn't
-switch back to bare hands. (Naturally, I'm using the experimental
-auto switch when butchering -setting.)
-
-== 424. mons_speed() should be extern, remove static declaration from mon-util.
-
-** 425. I have a ring of Baldness that somehow got cursed and now I am
-stuck with it. Scrolls of remove curse have no effect.
-Its not bad ring, but the increased metabolism isn't nice.
-
-== 426. More inventory problems:
-while playing 4.0.0b16 I found two bugs:
-1) when picking up items from the floor, after picking them up - it says "no
-more items" (but it picks up the item). This bug is strange it happens only
-at the very beginning of the game. For some reason after descending to Level
-2 it has stopped from happening.
-
-2) picking up items from the same type: when you have say 2-chokos and there
-is on the floor another one then when you stand on top of it - it says
-3-chokos(it takes into account the ones you have in your inventory). Or the
-other solution is that when you pickit up from the floor it replaces your
-previous chokos with the last amount of that type picked up. (Because I had
-2 chokos and after picking 3 chokos = I got 3, so it could be either
-problem...dunno)
-
-== 427. Fix descrip. for rings of slaying.
-
-== 428. I met monsters with infinite potions. I hope it's also fixed.
-
-== 429.
- in monstuff.cc::handle_nearby_ability() should be also handled
- monsters behaviour - BEH_WANDER and BEH_SEEK, beacuse monsters speak
- even if they don't know about player. Also it looks that Giant
- eyeball can stare at player even if he isn't noticed (or if he is
- invisible, but it's probably feature)
-
-== 430. Michal's patch (new unrands?)
- >> mv: now included - not only unrands but mainly clean-ups and minor upgrades
-
-== 431. In view.cc:viewwindow2() was buffy changed from unsigned char to
- unsigned short (I'm talking about
- FixedVector <unsigned char, BUFFER_SIZE> buffy).
- But at least with my compiler it doesn't work and viewwindow2()
- doesn't show anything (only black screen). When I changed buffy back
- to unsigned char it started to work again.
-
-== 432. Giant eyeballs no longer stare at friends.
-
-== 433. You throw a dart.
- You throw a dart.
- You throw a poisoned orcish dart.
- You shoot a poisoned needle.
- You shoot a poisoned needle.
- You hear a grinding noise.
-
- ... with a dex 18 / darts 7 / throwing 4 player!
- This is repeatable, and at times, I managed to
- clear a rock wall with just two needles!!! Couple
- this with the durability of needles, and players
- have a poor-man's dig spell at their disposal.
-
-== 434.
-I think I will change this condition so that a
- monster with no ammo won't bother picking any up,
- unless their melee attack really sucks.
-
-== 435.
- You destroy the shapeshifter zombie!
-
- I sneak up on a defenseless cockroach and crush it with
- my quarterstaff, only to be messaged that my character's
- stabbing skill has increased. Is is just me, or does the
- idea of stabbing with a quarterstaff seem a bit off? I
- weakly suggest changing the name of the skill to something
- less tied to impaling weapon types. "Ambush" skill or
- "Bushwhack" skill or something similar.
-
->> no more shapeshifter zombies. Improved messaging for stabbing.
-
-** 436.
-
-
- Hi,
-
- Could you add a description of the / and * keys to the help screen? Keypad is
- not always useable, especially not with ctrl and shift keys, this might help
- some people. Patch attached.
-
-
-== 437.
- Note the extra space before the period:
-
- Methea's ghost stares at you . You feel cold.
-
-
- This is a common construction used (I presume)
- in mon_speak() [or whatever]. There should be
- a comma placed after the verb ['begs' in this
- case] for grammar's sake:
-
- Methea's ghost begs "Please don't hurt me!"
-
-== 439.
- Package: crawl
- Version: 1:4.0.0beta16-1
- Severity: minor
-
- Another small upstream gameplay issue. In the context of a rat I had
- summoned attacking a kobold which was wielding a poisoned dagger:
-
- The rat hits the kobold.
- The rat hits the kobold!
- The kobold hits the rat with a runed dagger!
- The rat looks ill.
- You kill the rat!
- That felt strangely unrewarding.
- The rat's corpse disappears in a puff of smoke!
-
- The rat was killed by the kobold (via poison), not by me, but the messages
- seem to indicate I killed it.
-
- This may be very tricky to reproduce, unfortunately :(
-
-== 440.
-> * removed: no more spellcasting wanderers, until such time as we
-> have some reasonable "hedge magic", which I will not add before
-> release.
-
- A healthy percentage of my wanderers still start out with magic
- skills.
-
- >> but not spells.
-
-
-== 442. Repel undead doesn't seem to actually repel the undead.
-
- >> mv: fixed
-
-== 443. The enslaved stay enslaved even when you attack them.
-
-== 444. Change 'points' to 'point' if points needed == 1 in 'C' message
-
-== 445.
-This is me and a summoned zombie vs. a goblin:
-
- You miss the goblin.
- The goblin hits you with a club!
- The giant cockroach zombie misses the goblin.
- The goblin fails to defend itself.
- You kill the goblin!
-
->> very possible. Goblin was concentrating on the cockroach (lucky
-you!)
-
-== 446. Add ???'s patch for FreeBSD support
-
-== 447. Zombie generation hangs in the various hells, the crypt, and probably
- slime pits, ecu. temple, and others.
-
- >> think I got all cases of levels with no zombifiable native life.
-
-== 448. Monster polymorph can hang in HoB:
- >> only valid monster for poly in HoB is Dancing weapon, which is EXPLICITLY
- NOT a valid poly target. So it hangs. Duh!
-
-== 449. Shapeshifters no longer gain the extra abilities (spells, specials)
- of their forms (they used to - I considered this a bug).
-
-== 450. Incredibly, monster enchantments were not being reset when a new level
- was generated. This is an absolute showstopper and has probably corrupted all
- games in progess. Most notable with permanent enchantments like shapeshifter -
- this is what caused the "shapeshifter" dancing weapons that Josh (indirectly)
- reported.
-
-** 451. As you read the scroll, it crumbles to dust.
-Your club glows black for a moment.
-Drop which item?
-You drop a +0 dwarven hand axe.
-You are empty-handed.
-
--- 452.
-I hit an assert failure after reading a scroll of curse armour. From the
-traceback, we see an immediate problem at the call to itemname::in_name()
-at line 3358 of item_use.cc. The object to be named is -1.
-#6 0x80b1797 in in_name (inn=-1, des=4 '\004',
- str_pass=0x825b9a0 "a +1,+0 elven long sword") at itemname.cc:69
-#7 0x80b125b in read_scroll () at item_use.cc:3358
-#8 0x8050e2d in input () at acr.cc:880
-
-Doing a quick compare between the pr16 & pr17 code, I think this line:
- ok_to_curse[i] == (you.equip[i] != -1
- && you.inv_plus[you.equip[i]] < 130);
-
-should be:
- ok_to_curse[i] = (you.equip[i] != -1
- && you.inv_plus[you.equip[i]] <= 130);
-
-** 453.
-DOS, 486sx
-4.1.16 Floating above a (dart) trap discovers it but gives no message.
-
- I'd like to see a message when Coronas wear out.
-
- >> mv: added
-
-4.1.17 Loading the game; Okawaru says: Welcome, disciple.
-
-A monster called "a human" was displayed as a darker (non-visible)
- floor tile.
-
- >> mv: fixed
-
-
-** 454 .Goblins and orcs still get infinite potions of healing??
-
-** 455. I'm playing Crawl pr17 (I double-checked this time) under Solaris, and I just
-got the "Too many items" bug with a minotaur monk. It had to do with a
-cursed runed leather armor that I was carrying. I had a bunch of stuff in
-my inventory, and read a scroll of detect curse (this is how I discovered
-that the armor was cursed). So I dropped the armor and moved to another
-spot. There I dropped some weapons that I wasn't interested in. I stepped
-back to this spot later, there's a cursed runed leather armor. There's also
-a cursed runed leather armor on the spot where I actually dropped it. I
-picked one up and dropped in on the other, looked, and "Too many items." The
-game hung when I tried to save. :^/
-
-** 456. I was playing the same minotaur monk (I was able to salvage the game) when I
-saw what I thought was a statue (an '8'). When I looked at it, I saw:
-
-You see 26 !questionable item (c100,t0,p0,p(2)0,d0:q26)s here.
-
-** 457.
-I was wandering along when I met a hobgoblin. I kill him and decide to pick
-up his weapon to see if it's good. I then get "do you want to pick up
-hobgoblin corpse (y/n/a/q)"(or something like that). I type no. "do you
-want to pick up hobgoblin corpse" No. "do you want... " no ad nauseum. I
-give up and press q the game crashes. I restart and load the autosave.
-Same thing happens. I this time press a and get
-x - a hobgoblin corpse
-x - a hobgoblin corpse
-x - a hobgoblin corpse etc
-It won't stop doing that
-
-Yours
-
-William Hull
-
-Another one:
-at another time there was this situation:
-
-###
-@g! the potion is yellow
-###
-
-###
-@!! after killing the goblin,a second yellow potion appeared
-###
-
-but walking over both just gave me the msg "m - a yellow potion" twice.
-afterwards i had just one yellow potion in my pack.
-
-(more)
-
-The item bug (duplicate items and potential lockup) seems to happen whenever
-a monster picks something up off the floor. The most recent incident is
-typical (at least in my games).
-
-
- #'####
- #!
- # ###
- #K#
- #
- <@ ###
-
-Near the door is an emulsified red potion. After I kill the kobold (who had
-previously been wandering around, i.e. he wasn't asleep), I find that he was
-carrying an emulsifed red potion. Coincidence? I think not. In this
-instance, I left the potion where it was sitting and checked out the potion
-near the door. Underneath the potion is a kobold corpse. I go up the stairs
-to the previous level, then return; the corpse and potion near the door are
-gone. From previous experience, I know that picking up both potions/corpses
-would have left me with just one potion/corpse in my inventory (assuming I
-didn't have any before), and picking up one potion/corpse and dropping it
-on top of the other potion/corpse will create the "Too many items" bug, and
-cause the game to hang when saving the level.
-
-(more)
-
-Sorry to follow up on my own post, but I was browsing through the sources and
-I noticed that in pickup() in items.cc, relink_cells() is called after the
-player successfully picks up an item off of the floor. No such function is
-called in handle_pickup() in monstuff.cc. Perhaps handle_pickup() should
-call relink_cells() (which we know works) instead of trying to update the
-igrd array itself.
-
-
--- 458. My char with some stabbing skill stabbed a mimic wich was nerly dead
-after many rounds of battle. I know there is bonus when attacking a
-fleeing moster, but mimics cannot flee.
-
->> fixed. Immobile monsters cannot flee.
-
-** 459. An artifact weapon of holy wrath does allow a demonspawn to wield it, wich
-is bug or maybe not.
-
-** 460. ..to Sif Muna, so I went back to the Temple and converted. Little did I know
-that Vehumet would hold a grudge. I survived a blue demon, an abomination,
-and several magical blasts, but Vehumet eventually blasted me when I was low
-on HP and did me in. *sigh*
-
-Anyway, here's the buglet: the high score list claims that my character was
-killed by bad targeting.
-
--- 461. There is another one in monstuff.cc in handle_scroll when checking for
-negative numbers of scrolls...
-And yes it would be cool if they removed all the warnings (or at least
-most of them). Removing unused variables would be a first step.
-
->>
-
-** 462. In the dos binary of Crawl 17, when running the game with "crawl -plain"
-option, the game screen is totally black. I still get the player statistics
-and messages, but the map display that you normally see is blacked out.
-
-This is bad because the normal crawl display (without -plain) is a bit buggy
-for me. (no cursor under the character). I also kinda prefer the #
-character for walls (got used to ADOM) :)
-
-xx 463. Beam tracers: tweak to take into account what might happen if they _miss_.
-
-** 464. Level draining can cause -1/-1 -magic when used against ogre (or maybe
-troll) character.
-
-== 465. Automatic weapon change when dissectiong gives a litle funny messages when
-berserk:
-Switching to your swap slot weapon.
-You are too berserk!
-Maybe you should try using a sharper implement.
-Switching back to a - the uncursed great mace "Res".
-
- >> mv: fixed
-
-xx 466. My deep elf summoner cast summon demon from a staff of summoning (A
-great item for a starting summoner.), and received an orange demon,
-which proceded to attack me. None of the other demons had attacked. Is
-this a bug, or is there some way to make demons hostile?
-
->> 1 in 4 chance of hostile demon.
-
--- 467. Ettins have no description. I just met an elf and I think those should only
-appear as corpses. It had description "A monster whose description has yet
-to be written.".
-
-
-== 468. Invalid polymorph targets (this has been reported several times).
- There are several generic monster types which are _not_ valid poly.
- targets: 'human' and 'elf' being two of the more common results when
- polymorphing stuff. And yet, 'human' should probably be given some
- generic statistics and then allowed as a target (it makes sense, after
- all).
-
->> mv: fixed now
diff --git a/stone_soup/crawl-ref/docs/crawl.6 b/stone_soup/crawl-ref/docs/crawl.6
deleted file mode 100644
index 70bf129651..0000000000
--- a/stone_soup/crawl-ref/docs/crawl.6
+++ /dev/null
@@ -1,1053 +0,0 @@
-.TH crawl 6 "02 April 2001"
-.IX crawl
-.SH NAME
-crawl - play the roguelike game of crawl
-.SH SYNOPSIS
-.BR crawl
-[-scores [N]]
-[-name <string>]
-[-race <letter>]
-[-class <letter>]
-[-pizza <string>]
-[-plain]
-[-dir <path>]
-[-rc <file>]
-.SH DESCRIPTION
-Crawl is a fun game in the grand tradition of games like Rogue, Hack, and
-Moria. Your objective is to travel deep into a subterranean cave complex and
-retrieve the Orb of Zot, which is guarded by many horrible and hideous
-creatures.
-.PP
-This file contains detailed instructions for playing Crawl. If you are
-completely new to this kind of game, it may be worth your while to read at
-least part (although it will probably confuse you somewhat), otherwise you
-should probably just dive into the game and use the '?' command to give a list
-of keys to use.
-.PP
-.SH OPTIONS
-.TP
-\fB-scores\fR [N]
-show highscore list [first N entries]
-.TP
-\fB-name\fR <string>
-set character name
-.TP
-\fB-race\fR <letter>
-preselect race
-.TP
-\fB-class\fR <letter>
-preselect class
-.TP
-\fB-pizza\fR <string>
-crawl pizza
-.TP
-\fB-plain\fR
-don't use IBM extended characters (needed when playing in a xterm)
-.TP
-\fB-dir\fR <path>
-crawl directory
-.TP
-\fB-rc\fR <file>
-init file name
-.PP
-.SH THE GAME
-.IP "CHARACTER SPECIES"
-.PP
-You have a number of different character races to choose from. This affects
-several characteristics including:
-Your choice of classes;
-Your initial attributes (strength etc);
-Occasional extra points added to some abilities;
-The amount of hit points and magic you get as you increase in level;
-Your initial equipment;
-Your rate of level advancement;
-Your rate of skill advancement.
-.PP
-.I Humans
-are the most versatile race. Humans advance quickly in levels and
-have equal abilities in all skills. Humans can also be of any class.
-.PP
-.I Elves
-have good intelligence and dexterity, but suffer a bit in strength.
-They have slightly less hp and slightly more magic than humans, and advance in
-experience a bit more slowly as well. They are especially good at fighting
-with short and long swords, although not so good at other weapons, and are
-adept at bows and darts. Their quickness makes them good at dodging, and they
-possess natural elven stealth as well. Their nature also gives them
-proficiency with magic, especially enchantments, but they are poor at using
-necromancy.
-.PP
-There are also a number of related types of elves:
-.PP
-.I High elves
-are a powerful elven race who advance in levels very slowly -
-requiring half again as much experience as do humans. They are similar to
-common elves in most respects, but their strengths and weaknesses tend to be
-greater.
-.PP
-.I Grey elves
-also advance slowly, but more quickly than high elves. They are
-generally poor at fighting - although they are still good at short and long
-swords and bows - but are excellent at all forms of magic except for
-necromancy.
-.PP
-.I Deep elves
-are poor at fighting but excellent at bows, crossbows, darts, and
-especially magic. They are the only elven subtype who are skilled at using
-necromancy and earth magic, and are particularly good at enchantment magic.
-They advance in levels at the same rate as grey elves. Deep elves are not
-physically robust, but have great reserves of magical energy.
-.PP
-.I Sludge elves
-are a bit like common elves, but are not quite as good at most
-things while being better at necromancy and some elemental magics. They
-advance in level slightly faster, though.
-.PP
-Elven armour is unusually light, and does not affect the dodging or stealth of
-its wearer to the extent that other armours do. Elven cloaks and boots are
-particularly useful to those who wish to be stealthy, and elven bows are
-particularly effective in conjunction with elven arrows. Elves are especially
-dangerous when using elven weapons.
-.PP
-All elves are good at using air elemental magic, and are okay at fire and ice
-magic. They are also poor at earth magic with the exceptions of deep and
-sludge elves, who can use earth magic well.
-.PP
-.I Hill dwarves
-are extremely robust but are poor at using magic. They are
-excellent at hand combat, especially favouring axes, and are good at using
-armour and shields, but are poor at missile combat or at using polearms (which
-are usually too big for them to wield comfortably). The only forms of magic
-which they can use with any aptitude are earth, fire and conjurations, but
-they are worse than humans at the conjurations skill. They advance in levels
-at a similar rate to common elves.
-.PP
-.I Mountain dwarves
-are almost as robust as hill dwarves and have similar
-aptitudes, but are slightly better at the things that hill dwarves don't do
-very well, and slightly worse at the things that hill dwarves are good at.
-They advance in levels at a rate between that of elves and humans.
-.PP
-Dwarven weapons and armours are very durable, and do not rust or corrode
-easily. Dwarves are especially effective when using dwarven weaponry.
-.PP
-.I Halflings
-are very small and, with deep elves and kobolds, are the least
-robust of any character race. Although fair to poor at most fighting skills,
-they can use short blades well and are good at all forms of missile combat.
-They are also very stealthy and good at dodging and stabbing, but are poor at
-most types of magic (except enchantments and translocations). They advance in
-levels as rapidly as humans. Halflings cannot wield large weapons.
-.PP
-.I Hill orcs
-are orcs from the upper world who, jealous of the riches which
-their cousins, the cave orcs, possess below the ground, descend in search of
-plunder and adventure. They are as robust as the hill dwarves, but have very
-low reserves of magical energy. Their forte is fighting, and they are skilled
-at using most hand weapons (with the exception of short blades, at which they
-are only fair, and missile weapons, at which they are not particularly good).
-They are poor at using most types of magic with the exception of conjurations
-and necromancy. They advance as quickly as humans.
-.PP
-Orcish bows/crossbows are particularly effective in combination with orcish
-arrows/bolts. Orcs are especially good at using orcish weapons.
-.PP
-Orcs are poor at using air elemental magic, but okay at other kinds (and good
-at earth magic).
-.PP
-.I Kobolds
-are small, ugly creatures with few redeeming features. They have
-poor abilities and have similar aptitudes to halflings, without the excellent
-agility. However, they are slightly better than halflings at using some types
-of magic, particularly summonings and necromancy. They often live as
-scavengers, surviving on carrion, but are carnivorous and can only eat meat.
-They advance in levels as quickly as humans.
-.PP
-.I Mummies
-are undead creatures who travel into the depths in search of
-revenge, redemption, or just because they want to. Being undead, they are
-immune to poisons and negative energy, have little warmth left to be affected
-by cold, and are not susceptible to reductions in their physical or mental
-abilities. However, their dessicated bodies are highly flammable. They also do
-not need to eat or drink, and in any case are unable to.
-.PP
-Mummies progress very slowly in level (as slow as High Elves) and in all
-skills except fighting, spellcasting and necromancy. As they increase in level
-they become increasingly in touch with the powers of death, but cannot use
-some types of necromancy which only affect living creatures (if they are
-unable to use a spell, they will usually be unable to memorise it). The side
-effects of necromantic magic tend to be relatively harmless to mummies.
-.PP
-.I Naga
-are a race of hybrids; humanoid from the waist up, with a large
-snake tail instead of legs. They are reasonably good at most things and
-advance in experience levels at a decent rate. They are naturally immune to
-poisons, can see invisible creatures, and have tough skin, but their tails are
-relatively slow and cannot move them around as quickly as can other creatures'
-legs (this only affects their movement rate; all other actions are at normal
-speed). Their body shape also prevents them from gaining full protection from
-most armour. Every now and then, a naga can spit poison; the range, accuracy
-and damage of this poison increases with the naga's experience level.
-.PP
-.I Gnomes
-are an underground-dwelling race of creatures, related to the dwarves
-but even more closely in touch with the earth. They are quite small, and share
-many of their characteristics with halflings (except for the great agility),
-although they advance slightly more slowly in experience levels. They are okay
-at most skills, but excellent at earth elemental magic and very poor at air
-magic. Occasionally they can use their empathy with the earth to sense their
-surroundings; this ability increases in power as they gain experience levels.
-.PP
-.I Ogres
-are huge, chunky creatures related to orcs. They have great physical
-strength, but are bad at almost everything except fighting. Because of their
-large size they can only wear loose robes, cloaks and animal skins. They learn
-quite slowly. Although ogres can eat almost anything, their size means that
-they need to.
-.PP
-.I Trolls
-are like ogres, but even nastier. They can rip creatures apart with
-their claws, and regenerate very quickly from even the most terrible wounds.
-They learn very slowly indeed - even more slowly than high elves - and need a
-great amount of food to survive.
-.PP
-.I Ogre-mages
-are a separate race of ogres who are unique among the beefier
-races in their ability to use magic, especially enchantments. Although
-slighter than their common ogre relatives they nevertheless have great
-strength and can survive a lot of punishment. They advance in level as slowly
-as high elves.
-.PP
-.I Draconians
-are a race of human-dragon hybrids; humanoid in form and
-approximately human-sized, with wings, tails and scaly skins. Draconians start
-out in an immature form with brown scales, but as they grow in power they take
-on a variety of colours. Some types of draconians have breath weapons. Because
-of their decidedly non-human shapes, draconians cannot wear most armours.
-Draconians advance very slowly in level, but are reasonably good at most
-skills (except missile weapons and armour).
-.PP
-.I Centaurs
-are another race of hybrid creatures: horses with a human
-torso. Centaurs can move very quickly on their four legs, and are excellent
-with bows and other missile weapons; they are also reasonable at the Fighting
-skill while being slow learners at specific weapon skills. They advance quite
-slowly in experience level and are rather sub-average at using magic. Due to
-their large bulk, they need a little extra food to survive.
-.PP
-.I Demigods
-are mortals (humans, orcs or elves, for example) with some divine
-ancestry, however distant; they can be created by a number of processes
-including magical experiments and the time-honoured practice of interplanar
-miscegenation. Demigods look more or less like members of their mortal part's
-race, but have excellent abilities (strength, int, dex) and are extremely
-robust; they also have great supplies of magical energy. On the downside they
-advance very slowly in experience, gain skills slightly less quickly than
-humans, and cannot worship the various Gods and Powers available to the other
-races.
-.PP
-.I Spriggans
-are small magical creatures distantly related to elves. They are
-poor fighters with anything other than a dagger or a shortsword, have little
-physical resilience, and are terrible at destructive magic - conjurations,
-summonings, necromancy and elemental spells. On the other hand, they are
-excellent at other forms of magic and are very good at moving silently and
-quickly. So great is their speed that a spriggan can keep pace with a centaur.
-.PP
-.I Minotaurs
-are yet another hybrid - a human body with a bovine head.
-Minotaurs are extremely good at all forms of physical combat, but are awful at
-using any type of magic. They can wear all armour except for headgear.
-.PP
-.I Demonspawn
-are horrible half-mortal, half-infernal creatures - the flip side
-of the Demigods. Demonspawn can be created in any number of ways - magical
-experiments, breeding, unholy pacts, etc. Although many demonspawn may be
-indistinguishable from those of pure mortal stock, they often grow horns,
-scales or other unusual features. Powerful members of this class of beings
-also develop a range of unholy abilities, which are listed as mutations (and
-can sometimes be activated with the 'a' command).
-.PP
-Demonspawn advance very slowly in experience and learn most skills at about
-the same rate as do Demigods. However, they are a little better at fighting
-and much better at conjurations, summonings, necromancy and invocations.
-.PP
-.I Ghouls
-are horrible undead creatures, slowly rotting away. Although ghouls
-can sleep in their graves for years on end, when they rise to walk among the
-living they must eat flesh to survive. Raw flesh is preferred, especially
-rotting or tainted meat, and ghouls gain strength from consuming it.
-.PP
-As undead, Ghouls are naturally immune to poison, cold and negative energy.
-They aren't very good at doing most things, although they make decent fighters
-and can use ice and earth magic without too many difficulties.
-.PP
-.I Kenku
-are an ancient and feared race of bird-people with a legendary
-propensity for violence. They are experts at all forms of fighting, including
-the magical arts of combat (conjurations, summonings and, to a lesser extent,
-necromancy). However, their light avian bodies cannot sustain a great deal of
-injury.
-.PP
-Basically humanoid with bird-like heads and clawed feet, the kenku can
-wear all types of armour except helmets and boots. Despite their lack of
-wings, powerful kenku can fly and very powerful members of this race can stay
-in the air permanently. They are good at air and fire elemental magic, but
-poor at ice and earth magic. Kenku do not appreciate any form of servitude,
-and so are poor at using invocations.
-.PP
-Some species have special abilities which can be accessed by the 'a' abilities
-menu. Some also have physical characteristics which allow them to make extra
-attacks using the Unarmed Combat skill.
-.PP
-.IP "CHARACTER CLASSES"
-.PP
-In your quest, you play as one of a number of different types of characters.
-Although each has its own strengths and weaknesses, some are definitely easier
-than others, at least to begin with. The best classes for a beginner are
-probably Gladiators, fighters and Berserkers; if you really want to play a
-magician, try a Conjurer. Each class starts out with a different set of skills
-and items, but from there you can shape them as you will.
-.PP
-.I Fighters
-start with a decent weapon, a suit of armour and a shield. They have
-a good general grounding in the arts of fighting.
-.PP
-.I Priests
-serve either Zin, the ancient and revered God of Law, or the rather
-less pleasant Death-God Yredelemnul. Although priests enter the dungeon with a
-mace (as well as a priestly robe and a few healing potions), this is purely
-the result of an archaic tradition the reason for which has been lost in the
-mists of time; Priests are not in any way restricted in their choice of weapon
-skills.
-.PP
-The
-.I Thief
-is one of the trickiest classes to play. Thieves start out with a
-large variety of useful skills, and need to use all of them to survive.
-Thieves start with a short sword, some throwing darts, and light armour.
-.PP
-The magician is the best at using magic. Magicians start with a dagger,
-a robe, and a book of spells which should see them through the first several
-levels. There are various kinds of magicians:
-.PP
-The
-.I Wizard
-is a magician who does not specialise in any area of magic.
-Wizards start with a variety of magical skills and the magic dart spell in
-memory.
-.PP
-The
-.I Conjurer
-specialises in the violent and destructive magic of conjuration
-spells. Like the Wizard, the Conjurer starts with the magic dart spell.
-.PP
-The
-.I Enchanter
-specialises in the more subtle area of enchantment magic.
-Although not as directly powerful as conjurations, high-level enchantments
-offer a wide range of very handy effects. As there are no useful enchantment
-spells of the first level, the Enchanter begins with a random attack spell and
-has a magic wand to help survive until he or she can start learning to use the
-craft properly, and is equipped with lightly enchanted weapons and armour.
-.PP
-The
-.I Summoner
-specialises in calling creatures from this and other worlds to
-give assistance. Although they can at first summon only very wimpy creatures,
-the more advanced summoning spells allow summoners to call on such powers as
-elementals and demons.
-.PP
-The
-.I Necromancer
-is a magician who specialises in the less pleasant side of
-magic. Necromantic spells are a varied bunch, but many involve some degree of
-risk or harm to the caster.
-.PP
-.I Elementalists
-are magicians who specialise in one of the four types of
-elemental magic.
-.PP
-.I Venom mages
-specialise in poison magic, which is extremely useful in the
-shallower levels of the dungeon where few creatures are immune to it. Poison
-magic is especially effective when used against insects.
-.PP
-.I Transmuters
-specialise in transmigrations, and can cause strange changes in
-themselves and others.
-.PP
-.I Warpers
-specialise in translocations, and are experts in travelling long
-distances and positioning themselves precisely.
-.PP
-The
-.I Paladin
-is a servant of the Shining One, and has many of the abilities of
-the Fighter and the Priest. He or she enters the dungeon with a sword, a
-shield, a robe, and a healing potion.
-.PP
-The
-.I Gladiator
-is well trained in the art of fighting but is not so good at
-other things. In fact, Gladiators are pretty terrible at anything except
-bashing monsters with heavy things. They start with a nasty weapon, a small
-shield, and armour.
-.PP
-The
-.I Berserker
-is a hardy warrior who fights well with many weapons.
-Berserkers worship Trog the Wrathful, from whom they get the power to go
-berserk (as well as a number of other powers should they prove worthy)
-but who forbids the use of spell magic. They enter the dungeon with an
-axe, some spears, and a set of leather armour.
-.PP
-The
-.I Ranger
-is a fighter who specialises in missile weapons. A Ranger starts
-with a bow and some arrows, as well as a hunting knife and a set of leathers.
-.PP
-An
-.I Assassin
-is a thief who is especially good at killing. Assassins are like
-thieves in most respects, but begin more skilled at hand combat.
-.PP
-The
-.I Crusader
-is a decent fighter who also has some aptitude in the magical
-arts. Crusaders start out with a book of martial spells.
-.PP
-The
-.I Death Knight
-is a fighter who aligns him or herself with the powers of
-death. There are two types of Death Knights: those who worship and draw their
-abilities from the Demon-God Yredelemnul, and those who study the fearsome
-arts of necromancy.
-.PP
-The
-.I Chaos knight
-is a fighter who chooses to serve one of the fearsome and
-unpredictable Gods of Chaos. He or she has two choices: Xom or Makhleb. Xom is
-a very unpredictable (and possibly psychotic) creature who rewards or punishes
-according to whim. Makhleb the Destroyer is a more purposeful God, who
-appreciates destruction and offers a variety of very violent powers to the
-faithful.
-.PP
-The
-.I Healer
-is a priest of Elyvilon. Healers begin with minor healing powers,
-but can gain far greater abilities in the long run.
-.PP
-The
-.I Reaver
-is a warrior who has some aptitude with the magic of destruction.
-.PP
-The
-.I stalker
-is an assassin who has some aptitude in the use of poison magic.
-.PP
-The
-.I Monk
-is a type of fighter specialising in unarmed combat. Monks start
-with very little equipment, but can survive without the weighty weapons and
-spellbooks needed by other classes.
-.PP
-.IP EXPERIENCE
-.PP
-When you kill monsters, you gain experience points (xp) (you also receive one
-half experience for monsters killed by friendly creatures). When you get
-enough xp, you gain an experience level, making your character more powerful.
-As they gain levels, characters gain more hit points, magic points, and spell
-levels.
-.PP
-.IP SKILLS
-.PP
-Your character has a number of skills which affect his or her ability to
-perform certain tasks. You can see your character's skills by pressing the 'm'
-key; the higher the skill level of a skill, the better you are at it. Every
-time your character gains experience points, those points become available to
-increase skills. You convert experience points into skill levels by practising
-the skill in question (eg fight with a certain type of weapon, cast a certain
-type of spell, or walk around wearing light armour to practise stealth). The
-amount of unassigned experience points is shown on the skills screen, and the
-number in blue next to each skill counts down from 9 to 0 as you get closer to
-increasing that skill.
-.PP
-You can elect not to practise a particular skill by selecting it in the skill
-screen (making it turn dark grey). This means that you will be less likely to
-increase that skill when you practise it (and will also not spend as many
-experience points on it).
-.PP
-The race you have chosen for your character has a significant effect on
-your rate of advancement in each skill. Some races are very good at some
-skills and poor at others. If your character's race is good at a skill, they
-will require less experience and take less time to advance in it; being bad
-at a skill has the opposite result.
-.PP
-There are a few different types of skills:
-.PP
-Fighting skills
-.PP
-.I Fighting
-is the basic skill used in hand-to-hand combat, and applies
-no matter which weapon your character is wielding (if any). It is also
-the skill which determines the number of hit points your character gets
-as they increase in level (note that this is calculated so that you don't
-get a long run advantage by starting out with a high fighting skill).
-.PP
-In addition, there are a number of weapon skills which affect your ability to
-fight with specific weapons. If you are already good at a weapon, say a long
-sword, and you practise for a while with similar weapon such as a short sword,
-your practise will be speeded up (and will require less experience) until both
-skills are equal.
-.IP "Similar types of weapons include:"
-- All sword skills
-.br
-- Maces & flails and Axes
-.br
-- Polearms and Axes
-.br
-- Staves and Polearms
-.PP
-Being good at a specific weapon improves the speed with which you can use it
-by about 10% every two skill levels. Although lighter weapons are easier to
-use initially, as they strike quickly and accurately, heavier weapons increase
-in damage potential very quickly as you improve your skill with them.
-.PP
-.I Unarmed Combat
-is a special fighting skill. It allows your character to make
-a powerful attack when unarmed and also to make special secondary attacks
-(and increases the power of those attacks for characters who get them anyway).
-You can practise Unarmed Combat by attacking empty-handed, and it is also
-exercised when you make a secondary attack (a kick, punch etc). Unarmed combat
-is particularly difficult to use in combination with heavy armour, and
-characters wearing a shield or wielding a two-handed weapon other than a staff
-lose the powerful punch attack.
-.PP
-Throwing skills
-.PP
-.I Throwing
-is the basic skill used when throwing things, and there are
-a number of individual weapon skills for missile weapons as well.
-.PP
-Magic skills
-.PP
-.I Spellcasting
-is the basic skill for magic use, and affects your
-reserves of magical energy in the same way that Fighting affects your
-hit points. Every time you increase your spellcasting skill you gain
-some magic points and spell levels. Spellcasting is a very difficult
-skill to learn, and requires a large amount of practice and experience.
-.PP
-Only those characters with at least one magic skill at level one or above can
-learn magical spells. If your character has no magic skills, he or she can
-learn the basic principles of the hermetic arts by reading and reciting the
-spells inscribed on magical scrolls (this stops being useful once you reach
-level one in Spellcasting).
-.PP
-There are also individual skills for each different type of magic; the higher
-the skill, the more powerful the spell. Multidisciplinary spells use an
-average of the two or three skills.
-.PP
-Elemental magic is a special case here. When you practise an elemental magic
-skill (fire, ice, air or earth magic) you will improve much less quickly than
-normal if you already have one or more elemental magic skills higher than the
-one you are practising. This is especially true if those skills are 'opposed'
-to the one you're practising: fire and ice are mutually opposed, as are earth
-and air. Say you have level 2 fire magic, level 4 ice magic, and level 1 air
-magic. Practising ice magic won't be a problem. Practising air magic will be a
-bit slow, as you have other elemental skills at higher levels. Practising fire
-magic will be very slow, as you have a higher level in ice magic. Right?
-.PP
-Miscellaneous
-.PP
-This includes a variety of skills:
-.PP
-.IR Armour :
-Having a high armour skill means that you are used to wearing heavy
-armour, so you gain more AC from it and lose less evasion while wearing it.
-.PP
-.IR Dodging :
-When you are wearing light armour, a high dodging skill increases
-your evasion score.
-.PP
-.IR Stealth :
-Helps you avoid being noticed. Try not to wear heavy armour (or be
-encumbered) if you want to be stealthy.
-.PP
-.IR Stabbing :
-Lets you make a very powerful first strike against a
-sleeping/resting monster who hasn't noticed you yet. This is most effective
-with a dagger, slightly less effective with a short sword, and less useful
-(although by no means of negligible effect) with any other weapon.
-.PP
-.IR Shields :
-affects the amount of protection you gain by using a shield.
-.PP
-.IR "Traps & doors" :
-affects your ability to notice hidden traps and doors and to
-disarm traps when you find them. With this skill at a high level you will
-often find hidden things without actively looking for them.
-.PP
-.IR Invocations :
-an easy-to-learn skill which affects your ability to call on
-your God for aid. Those skilled at invoking have reduced fail rates and
-produce more powerful effects. The Invocations skill affects your supply of
-magic in a similar way to the Spellcasting skill and to a greater extent, but
-the two are not cumulative - whichever gives the greater increase is used.
-Some Gods (such as Trog) do not require followers to learn this skill.
-.PP
-If your character does not have a particular skill, they can gain it by
-practising as above.
-.PP
-.IP ABILITIES
-.PP
-Your character is further defined by his or her abilities, which initially
-vary according to class and species.
-.PP
-.I Strength
-affects the amount of damage you do in combat, as well as how much
-stuff you can carry.
-.PP
-.I Intelligence
-affects how well you can cast spells as well as your ability to
-use some magical items.
-.PP
-.I Dexterity
-affects your accuracy in combat, your general effectiveness with
-missile weapons, and your ability to dodge attacks aimed at you. Although
-your dexterity does not affect your evasion score (Ev) directly, any
-calculation involving your Ev score also takes account of your dexterity.
-.PP
-.IR AC :
-This stands for Armour Class. When you something injures you, your AC
-reduces the amount of damage you suffer. The number next to your AC is a
-measure of how good your shield (if any) is at blocking attacks.
-.PP
-.IR EV :
-This is your evasion score. It helps you to avoid being hit by unpleasant
-things.
-.PP
-.IR Gold :
-This is how much money you're carrying. Money adds to your final score,
-and can be used to purchase items in shops.
-.PP
-.I Magic Resistance
-affects your ability to resist the effects of enchantments
-and similar magic directed at you. Although your magic resistance increases
-with your level to an extent determined by your character's race, the
-creatures you will meet deeper in the dungeon are better at casting spells
-and are more likely to be able to affect you. MR is an internal variable, so
-you can't see what yours is.
-.PP
-Sometimes characters will be able to use special abilities, for example the
-Naga's ability to spit poison or the magical power to turn invisible granted
-by a ring. These are accessed through the 'a' command.
-.PP
-.IP RELIGION
-.PP
-There are a number of Gods, Demons and other assorted Powers who will accept
-your character's worship, and sometimes give out favours in exchange. You can
-use the '^' command to check the requirements of whoever it is that you
-worship, and if you find religion to be an inconvenience you can always
-renounce your faith (use the 'a' command - but some Gods resent being
-scorned!).
-.PP
-The 'p' command lets you pray to your God. Anything you do while praying, you
-do in your God's name - this is how you dedicate your kills or corpse-
-sacrifices ('D' command) to your God, for example. Praying also gives you a
-sense of what your God thinks of you, and can be used to sacrifice things at
-altars.
-.PP
-To use any powers which your God deems you fit for, access the abilities menu
-with the 'a' command; God-given abilities are listed as invocations.
-.PP
-Some classes start out religious; others have to pray at an altar to dedicate
-themselves to a life of servitude. There are altars scattered all over the
-dungeon, and your character has heard rumours of a special temple somewhere
-near the surface.
-.PP
-.IP MUTATIONS
-.PP
-Although it would doubtless be a nice thing if you could remain genetically
-pure, there are too many toxic wastes and mutagenic radiations in the Dungeon
-for that to be possible. If your character is so affected by these that he or
-she undergoes physiological change, you can use the 'A' command to see how
-much of a freak they've become and the 'a' command to activate any mutations
-which can be controlled.
-.PP
-You can also become mutated by overusing certain powerful enchantments,
-particularly Haste (not the kind you get from being berserk) and Invisibility,
-as your system absorbs too much magical energy - but you would have to spend
-almost all of your time hasted or invisible to be affected. However, some
-powerful items radiate dangerous levels of magical energy. More often than
-not, the mutations caused by magical radiations express harmfully.
-.PP
-Any demonic powers your character may have are listed in red; these are
-permanent and can never be removed. If one of your powers has been augmented
-by a mutation, it is displayed in a lighter red colour.
-.PP
-.IP "EXPLORING THE DUNGEON"
-.PP
-You can make your character walk around with the numeric keypad (turn numlock
-off) or the "Rogue" keys (hjklbnyu). If this is too slow, you can make your
-character walk repeatedly by typing shift and a direction. They will walk in
-that direction until any of a number of things happen: a hostile monster is
-visible on the screen, a message is sent to the message window for any reason,
-you type a key, or you are about to step on anything other than normal floor
-or an undiscovered trap and it is not your first move of the long walk. Note
-that this is functionally equivalent to just pressing the direction key
-several times.
-.PP
-If you press shift and '5' on the numeric keypad (or just the number '5' on
-the keyboard) you rest for 100 turns or until your hit points or magic return
-to full, whichever is sooner. You can rest for just one turn by pressing '.',
-delete, 's', or '5' on the keypad. Whenever you are resting, you are assumed
-to be observing your surroundings, so you have a chance of detecting any traps
-or secret doors adjacent to you.
-.PP
-The section of the viewing window which is coloured (with the '@' representing
-you at the centre) is what you can see around you. The dark grey around it is
-the parts of the level which you have visited, but cannot currently see. The
-'x' command lets you move the cursor around to get a description of the
-various dungeon features, and typing '?' when the cursor is over a monster
-brings up a short description of that monster (these are all rather sketchy;
-I'll write better descriptions when I have time). You can get a map of the
-whole level (which shows where you've already been) by typing the 'X' key.
-This map specially colour-codes stairs and known traps, even if something is
-on top of them.
-.PP
-You can make your way between levels by using staircases, which appear as '>'
-(down) and '<' (up), by pressing the '>' or '<' keys. If you ascend an up
-staircase on level one, you will leave the dungeon forever; if you are
-carrying the magical Orb of Zot, you win the game by doing this.
-.PP
-Occasionally you will find an archway; these lead to special places like
-shops, magical labyrinths, and Hell. Depending on which type of archway it is,
-you can enter it by typing '<' or '>'.
-.PP
-Doors can be opened with the 'o' command and closed with the 'c' command.
-Pressing control plus a direction also opens doors. If there is no closed door
-in the indicated space, you will attempt to attack any monster which may be
-standing there (this is the only way to attack a friendly creature hand-to-
-hand). If there is no creature there, you will attempt to disarm any trap in
-the target square. If there is apparently nothing there you will still attack
-it, just in case there's something invisible lurking around.
-.PP
-A variety of dangerous and irritating traps are hidden around the dungeon.
-Traps look like normal floor until discovered (usually by activating them). A
-discovered trap can be disarmed with the control-direction commands, although
-not all traps can be affected in this way.
-.PP
-When you are in a shop, you are given a list of the shopkeeper's stock from
-which to choose, and a list of instructions. You can leave the shop and even
-the level and come back later if you want. Unfortunately the shopkeepers all
-have an enterprise bargaining agreement with the dungeon teamsters union which
-prevents them using non-union labour to obtain stock, so you can't sell
-anything in a shop (but what shopkeeper would trust a scummy adventurer like
-you, anyway?).
-.PP
-You goal is to locate the Orb of Zot, which is held somewhere deep beneath the
-world's surface. The Orb is an ancient and incredibly powerful artefact, and
-the legends promise great things for anyone brave enough to extract it from
-the fearsome Dungeon. Some believe it will grant immortality or even godhood
-to the one who carries it into the sunlight; many undead creatures seek it in
-the hope that it will restore them to life. Good luck!
-.PP
-.PP
-A full list of the commands available to you can be accessed by typing '?'
-(question mark). If you don't like them, they can be changed by the use of:
-.PP
-.IP "MACROS/KEYMAPS"
-.PP
-You can change the keys used to perform specific functions by editing the
-macro.txt file (or creating a new one). The K: line indicates a key, and the
-A: line assigns another key to that key's function.
-.PP
-You can also redefine keys in-game with the ` key, and save them with the ~
-key.
-.PP
-(Thanks to Juho Snellman for this patch)
-.PP
-.IP ITEMS
-.PP
-In the dungeons of Crawl there are many different kinds of normal and magical
-artefacts to be found and used. Some of them are useful, some are nasty, and
-some give you great power, but at a price. Some items are unique; these have
-interesting properties which can make your life rather bizarre for a while.
-They all fall into several classes of items, each of which is used in a
-different way. Here is a general list of what you might find in the course of
-your adventures:
-.PP
-.IP WEAPONS
-.PP
-These are rather important. You will find a variety of weapons in the dungeon,
-ranging from small and quick daggers to huge, cumbersome battleaxes and pole-
-arms. Each type of weapon does a differing amount of damage, has a different
-chance of hitting its target, and takes a different amount of time to swing.
-You should choose your weapons carefully; trying to hit a bat with a
-greatsword is about as clever as bashing a dragon with a club. For this reason
-it is wise to have a good mixture of weapon skills. Skills affect damage,
-accuracy and speed.
-.PP
-Weapons can be enchanted; when they are identified, they have values which
-tell you how much more effective they are than an unenchanted version. The
-first number is the enchantment to-hit, which affects the weapon's accuracy,
-and the second is its damage enchantment; weapons which are not enchanted are
-simply '+0'. Some weapons also have special magical effects which make them
-very effective in certain situations. Some types of hand weapon (especially
-daggers, spears and hand axes) are quite effective when thrown. You can wield
-weapons with the 'w' command, which is a very quick action. If for some reason
-you want to go bare-handed, type 'w' followed by a hyphen ('-'). Note that
-weapons are not the only class of item which you can wield.
-.PP
-The ' key is a shortcut which automatically wields item a. If item a is being
-wielded, it causes you to wield item b instead, if possible. Try assigning the
-letter a to your primary weapon, and b to your bow or something else you need
-to wield only sometimes. Note that this is just a typing shortcut and is not
-functionally different to wielding these items normally.
-.PP
-.IP AMMUNITION
-.PP
-If you would rather pick off monsters from a safe distance, you will need
-ammunition for your sling or bow. Darts are effective when simply thrown;
-other kinds of ammunition require you to wield an appropriate device to
-inflict worthwhile damage. Ammunition has only one "plus" value, which affects
-both accuracy and damage. If you have ammunition suitable for what you are
-wielding, the 'f' command will choose the first lot in your inventory, or you
-can use the 't' command to throw anything. If you are using the right kind of
-hand weapon, you will "shoot" the ammunition, otherwise you "throw" it.
-.PP
-When throwing something, you are asked for a direction. You can either enter
-one of the directions on your keypad, or type '*' and move the cursor over
-your target if they are not in a direct line with you. When the cursor is on
-them, press '.' (period) or delete to target them (you can also target an
-empty space if you want). If you press '>' instead of '.', the missile will
-stop at that space even if it misses, and if the target space is water, it may
-hit anything which might be lurking beneath the surface (which would otherwise
-be missed completely). If you type '.' (or del) instead of a direction or '*',
-or if you target yourself as described above, you throw whatever it is at
-yourself (this can be useful when zapping some wands; see later). Also, if you
-type 'p' instead of a direction or '*', you will target your previous target
-(if still possible).
-.PP
-.IP ARMOUR
-.PP
-This is also rather important. When worn, most armour improves your Armour
-Class, which decreases the amount of damage you take when something injures
-you. Unfortunately the heavier types of armour also hamper your movement,
-making it easier for monsters to hit you (ie reducing your evasion score) and
-making it harder for you to hit monsters. These effect can be mitigated by a
-high Armour skill. Wearing heavy armour also increases your chances of
-miscasting spells, an effect which is not reduced by your Armour skill.
-.PP
-A Shield normally affects neither your AC or your evasion, but it lets you
-block some of the attacks aimed at you and absorbs some of the damage you
-would otherwise receive from things like dragon breath and lightning bolts.
-Wearing a shield (especially a large shield) makes you less effective in hand
-combat.
-.PP
-Some magical armours have special powers. These powers are sometimes
-automatic, affecting you whenever you wear the armour, and sometimes must be
-activated with the 'a' command.
-.PP
-You can wear armour with the 'W' command, and take it off with the 'T'
-command.
-.PP
-.IP FOOD
-.PP
-This is extremely important. You can find many different kinds of food in the
-dungeon. If you don't eat when you get hungry, you will eventually die of
-starvation. Fighting, carrying heavy loads, casting spells, and using some
-magical items will make you hungry. When you are starving you fight less
-effectively as well. You can eat food with the 'e' command.
-.PP
-.IP "MAGICAL SCROLLS"
-.PP
-Scrolls have many different magical spells enscribed on them, some good and
-some bad. One of the most useful scrolls is the scroll of identify, which will
-tell you the function of any item you have in your inventory; save these up
-for the more powerful and inscrutable magic items, like rings. You can read
-scrolls (and by doing so invoke their magic) with the 'r' command.
-.PP
-.IP "MAGICAL POTIONS"
-.PP
-While scrolls tend to affect your equipment or your environment, most potions
-affect your character in some way. The most common type is the simple healing
-potion, which restores some hit points, but there are many other varieties of
-potions to be found. Try to avoid drinking poisonous potions! Potions can be
-quaffed (drunk) with the 'q' command.
-.PP
-.IP WANDS
-.PP
-Sometimes you will be lucky enough to find a stick which contains stored
-magical energies. Wands each have a certain amount of charges, and a wand will
-cease to function when its charges run out. You must identify a wand to find
-out how many uses it has left. Wands are aimed in the same way as missile
-weapons, and you can invoke the power of a wand by 'z'apping it.
-.PP
-.IP RINGS
-.PP
-Magical rings are among the most useful of the items you will find in the
-dungeon, but can also be some of the most hazardous. They transfer various
-magical abilities onto their wearer, but powerful rings like rings of
-regeneration or invisibility make you hunger very quickly when activated. You
-can put on rings with the 'P' command, and remove them by typing 'R'. You can
-wear up to two rings simultaneously, one on each hand; which hand you put a
-ring on is immaterial to its function. Some rings function automatically,
-while others require activation (the 'a' command).
-.PP
-Amulets are similar to rings, but have a different range of effects (which
-tend to be more subtle). Amulets are worn around the neck, and you can wear
-only one at a time.
-.PP
-.IP STAVES
-.PP
-There are a number of types of magical staves. Some enhance your general
-spellcasting ability, while some greatly increase the power of a certain class
-of spells (and possibly reduce your effectiveness with others). Some are
-spell staves, and hold spells which you can cast without having to memorise
-them first, and also without consuming food. You must wield a staff like a
-weapon in order to gain from its power, and magical staves are as effective as
-+0 quarterstaves in combat. Spell staves can be Invoked with the 'I' command
-while you are wielding them.
-.PP
-.IP BOOKS
-.PP
-Books contain magical spells which your character may be able to learn. You
-can read a book with the 'r' command, which lets you access a description of
-each spell, or memorise spells from it with the 'M' command. Some books have
-other special effects, and some powerful spellbooks have been known to punish
-the attentions of incompetent magicians.
-.PP
-.IP CARRION
-.PP
-If you manage to kill a monster delicately enough to avoid scattering bits of
-it around the room, it may leave a corpse behind for you to play with. Despite
-the fact that corpses are represented by the same '%' sign as food, you can't
-eat them without first cutting them into pieces with the 'D' command, and
-being extremely hungry helps as well. Even then, you should choose your
-homemade food with great care.
-.PP
-.IP MISCELLANEOUS
-.PP
-These are items which don't fall into any other category. You can use many of
-them by wielding and 'I'nvoking them. You can also use some other special
-items (such as some weapons) by invoking them in this way.
-.PP
-You pick items up with the ',' (comma) command and drop them with the 'd'rop
-command. When you are given a prompt like "drop which item?" or "pick up
-<x>?", if you type a number before either the letter of the item, or 'y' or
-'n' for yes or no, you will drop or get that quantity of the item.
-.PP
-Typing 'i' gives you an inventory of what you are carrying. When you
-are given a prompt like "Throw [or wield, wear, etc] which item?", you can
-type the letter of the item, or you can type '?' or '*' to get an inventory
-list. '?' lists all appropriate items, while '*' lists all items, appropriate
-or not. When the inventory screen is showing "-more-", to show you that there
-is another page of items, you can type the letter of the item you want instead
-of space or enter.
-.PP
-You can use the adjust command (the '=' key) to change the letters to which
-your possessions are assigned. This command can be used to change spell
-letters as well.
-.PP
-Some items can be stickycursed, in which case they weld themselves to your
-body when you use them. Such items usually carry some kind of disadvantage: a
-weapon or armour may be damaged or negatively enchanted, while rings can have
-all manner of unpleasant effects on you. If you are lucky, you might find
-magic which can rid you of cursed items.
-.PP
-Items like scrolls, potions and some other types each have a characteristic,
-like a label or a colour, which will let you tell them apart on the basis of
-their function. However, these characteristics change between each game, so
-while in one game every potion of healing may be yellow, in another game they
-might all be purple and bubbly. Once you have discovered the function of such
-an item, you will remember it for the rest of the current game. You can access
-your item discoveries with the '\' key.
-.PP
-A very useful command is the 'V' key, which gives you a description of what an
-item does. This is particularly useful when comparing different types of
-weapons, but don't expect too much information from examining unidentified
-items.
-.PP
-.IP SPELLCASTING
-.PP
-Magical spells are a very important part of surviving in the dungeon. Every
-character class can make use of magical spells, although those who enter the
-dungeon without magical skills must practise by reading scrolls before they
-can attempt spellcasting.
-.PP
-Spells are stored in books, which you will occasionally find in the dungeon.
-Each spell has a Level, which denotes the amount of skill required to use it
-as well as indicating how powerful it may be. You can only memorise a certain
-number of levels of spells; type 'M' to find out how many. When you gain
-experience levels, you can memorise more, and you will need to save up for
-several levels to memorise the more powerful spells. When you cast a spell,
-you temporarily expend some of your magical energy as well as becoming
-hungrier (although more powerful spellcasters hunger less quickly from using
-magic).
-.PP
-High level spells are difficult to cast, and you may miscast them every once
-in a while (resulting in a waste of magic and possibly dangerous side-
-effects). Your chance of failing to cast a spell properly depends on your your
-skills, your intelligence, the level of the spell and whether you are wearing
-heavy armour. Failing to cast a spell exercises your spell skills, but not by
-as much as casting it successfully.
-.PP
-Many of the more powerful spells carry disadvantages or risks; you should read
-the spell description (obtained by reading the spellbook in which you found
-the spell) before casting anything.
-.PP
-Some spells are directional, and require you to enter a direction in the same
-way as you would when shooting a missile or zapping a wand. Some spells
-require the proper materials to be present before they will work; for example,
-to animate a skeleton with the necromantic spell, you must stand on a space
-where a skeleton is on the top of the stack of items.
-.PP
-Be careful of magic-using enemies! Some of them can use magic just as well as
-you, if not better, and often use it intelligently.
-.PP
-.IP MONSTERS
-.PP
-In the caverns of Crawl, you will find a great variety of creatures, many of
-whom would very much like to eat you. To stop them doing this, you will need
-to fight. To attack a monster, stand next to it and move in its direction;
-this makes you attack it with your wielded weapon. Of course, some monsters
-are just too nasty to beat, and you will find that discretion is often the
-better part of valour.
-.PP
-Some monsters can be friendly; friendly monsters will follow you around and
-fight on your behalf (you gain 1/2 the normal experience points for any kills
-they make). You can command your allies using the '!' key, which lets you
-either shout to attract them or tell them who to attack.
-.PP
-.SH ENVIRONMENT VARIABLES
-.IP CRAWL_NAME
-Default name for your character.
-.IP CRAWL_PIZZA
-Your favourite pizza topping.
-.IP CRAWL_DIR
-The directory where your macros and character dumps are stored.
-.IP CRAWL_RC
-A pointer to the file containing your default settings.
-.PP
-.SH FILES
-.IP "/usr/lib/games/crawl/bone*"
-The bones files.
-.IP "/usr/lib/games/crawl/score"
-The high score list.
-.IP "$CRAWL_DIR/macro.txt"
-The macro resource file.
-.IP "$CRAWL_DIR/morgue.txt"
-A character dump of your last death.
-.IP "$CRAWL_RC, $CRAWL_DIR/init.txt, $HOME/.crawlrc"
-Default settings.
-
-.SH BUGS
-Lots.
-.PP
-Avoid the labyrinth... you may not be able to get out.
-
-.SH AUTHORS
-Copyright 1997, 1998, 1999 Linley Henzell
diff --git a/stone_soup/crawl-ref/docs/crawl.txt b/stone_soup/crawl-ref/docs/crawl.txt
deleted file mode 100644
index 355522e792..0000000000
--- a/stone_soup/crawl-ref/docs/crawl.txt
+++ /dev/null
@@ -1,1250 +0,0 @@
- Dungeon Crawl version 3.40
- (Copyright 1997, 1998, 1999 Linley Henzell)
-
-Crawl is a fun game in the grand tradition of games like Rogue, Hack and
-Moria. Your objective is to travel deep into a subterranean cave complex and
-retrieve the Orb of Zot, which is guarded by many horrible and hideous
-creatures.
-
-Detailed instructions for playing Crawl follow. If you want to get into the
-game quickly, read the quick-start guide (README.TXT) and learn as you play.
-Otherwise, it may be worth your while to read at least part of this file
-(although it will probably confuse you somewhat). Read at least the disclaimer
-at the end of this document and the LICENCE.TXT file, though.
-
-----------------------------------------------------------------------------
- CHARACTER SPECIES
-----------------------------------------------------------------------------
-
-You have a number of different species to choose from. This affects several
-characteristics:
-
- o Your choice of classes
- o Your initial attributes
- o Occasional bonus points added to some abilities
- o The amount of hit points you get each level
- o The amount of magic points you get each level
- o Your initial equipment
- o Your rate of level advancement
- o Your rate of skill advancement
- o Various special abilities and powers
-
-Note: Some species are slower than humans in most/all skills. For some
-classes these races may seem to have very few skills because they haven't
-quite earned the first level of several of their skills (Centaurs are
-notable in this regard... although non-human Wanderers can appear to
-start with no apparent skills at all). This isn't a bug or an oversight,
-these species are just particularly weaker than humans at these classes.
-
-If you practise the skills you think or know are missing early on, they
-should pick up the remaining skills very quickly (and their training will be
-more complete).
-
-
-The species:
-
-Human:
-
- Humans tend to be hardworking and industrious, and learn new things quickly.
- The human race is the most versatile of all the species available to
- players. Humans advance quickly in levels and have equal abilities in all
- skills. Humans can also be of any class.
-
-Elves:
-
- There are a number of distinct races of elf in the world. Elves are all
- physically slight but long-lived people, quicker-witted than humans but
- sometimes slower to learn new things. Elves are especially good at using
- those skills which require a degree of finesse, such as stealth, sword-
- fighting and archery, but tend to be poor at using brute force and inelegant
- forms of combat. They find heavy armour uncomfortable, and make the finest,
- lightest armours to be found anywhere. Elves are particularly good at using
- elven weapons.
-
- Due to their fey natures, all elves are good at using enchantments and air
- elemental magic and most are poor at invoking the powers of earth and death
- (necromancy).
-
- Those of the most common strain are referred to simply as elves or, when
- they're not listening, as common elves. Common elves have good intelligence
- and dexterity, but suffer a bit in strength. They have slightly fewer HP and
- slightly more magic than humans, and advance in experience a bit more
- slowly.
-
- High elves are a tall and powerful elven race who advance in levels very
- slowly, requiring half again as much experience as do humans. They share the
- same attributes as common elves in most respects, but their strengths and
- weaknesses tend to be more pronounced.
-
- Grey elves also advance slowly, but not as slowly as high elves. They excel
- at using short and long swords and bows, but are poor at other fighting
- skills. They are excellent at all forms of magic except for necromancy.
-
- The deep elves are an elven race who long ago fled the overworld to live in
- darkness underground. There they developed their mental powers, evolving a
- natural gift for all forms of magic (including necromancy and earth magic),
- and adapted physically to their new environment, becoming shorter and weaker
- than other elves and losing all colouration. They are poor at hand-to-hand
- combat but excellent at fighting from a distance.
-
- Sludge elves are a somewhat degenerate race of elves. They are mirror images
- of normal elves in some respects: they have no special proficiency with bows
- or swords (long or short), nor do they have any aptitude in the traditional
- areas of high elven magic (enchantments, conjurations and divinations). On
- the other hand, they are superlative transmuters, and are comfortable
- dabbling in necromantic, poison and elemental magic. As fighters they are
- often more dangerous unarmed than armed. They advance in level slightly
- faster than their common brethren.
-
-Dwarves:
-
- Dwarves are short, hardy people. They love to fight, and often venture forth
- from their subterranean cities to seek fame and fortune through battle.
- Their armour and weapons are very well-crafted and much more durable than
- the products of lesser artisans. Dwarves are particularly dangerous when
- using dwarven weaponry.
-
- Hill dwarves are extremely robust but are poor at using magic. They are
- excellent at hand combat, especially favouring axes or bludgeoning weapons,
- and are good at using armour and shields, but are poor at missile combat or
- at using polearms (which are usually too big for them to wield comfortably).
- The only forms of magic which they can use with even a minimal degree of
- aptitude are earth, fire and conjurations. They advance in levels at a
- similar rate to common elves.
-
- Mountain dwarves come from the larger, more civilised communities of the
- mountains. They advance slightly more quickly than hill dwarves and are
- almost as robust while having similar aptitudes, but are slightly worse at
- fighting while being slightly better at more civilised pursuits.
-
-Halflings:
-
- Halflings, who are named for being about half the size of a human, live in
- small villages. They live simple lives, and have simple interests. Some
- times a particularly restless halfling will leave his or her village in
- search of adventure.
-
- Halflings are very small and are among the least robust of any character
- species. Although only average at most fighting skills, they can use short
- blades well and are good at all forms of missile combat. They are also very
- stealthy and good at dodging and stabbing, but are poor at magic (except
- enchantments and, for some reason, translocations). They advance in levels
- as rapidly as humans. Halflings cannot wield large weapons.
-
-Gnomes:
-
- Gnomes are an underground-dwelling race of creatures, related to the
- dwarves but even more closely in touch with the earth.
-
- They are quite small, and share many of their characteristics with
- halflings (except for the great agility), although they advance slightly
- more slowly in experience levels. They are okay at most skills, but
- excellent at earth elemental magic and very poor at air magic.
-
- Occasionally they can use their empathy with the earth to sense their
- surroundings; this ability increases in power as they gain experience
- levels.
-
-Orcs:
-
- Hill orcs are orcs from the upper world who, jealous of the riches which
- their cousins the cave orcs possess below the ground, descend in search of
- plunder and adventure.
-
- Hill orcs are as robust as the hill dwarves, but have very low reserves of
- magical energy. Their forte is brute-force fighting, and they are skilled at
- using most hand weapons (with the exception of short blades, at which they
- are only fair), although they are not particularly good at using missile
- weapons. They prefer to use their own weapons. Orcs are poor at using most
- types of magic with the exception of conjurations, necromancy, and earth and
- fire elemental magic. They advance as quickly as humans.
-
-Kobolds:
-
- Kobolds are small, ugly creatures with few redeeming features. They are not
- the sort of people you would want to spend much time with, unless you happen
- to be a kobold yourself.
-
- They have poor abilities and have similar aptitudes to halflings, without
- the excellent agility. However, they are better than halflings at using
- some types of magic, particularly summonings and necromancy. They often
- live as scavengers, surviving on carrion, but are carnivorous and can
- only eat meat. They advance in levels as quickly as humans.
-
-The Undead:
-
- As creatures brought back from beyond the grave they are naturally immune to
- poisons and negative energy, have little warmth left to be affected by cold,
- and are not susceptible to reductions in their physical or mental abilities.
-
- There are two type of undead available to players: Mummies and Ghouls.
-
-Mummies:
-
- Mummies are undead creatures who travel into the depths in search of
- revenge, redemption, or just because they want to.
-
- Mummies progress very slowly in level, half again as slow as humans, and in
- all skills except fighting, spellcasting and necromancy. As they increase in
- level they become increasingly in touch with the powers of death, but cannot
- use some types of necromancy which only affect living creatures. The side
- effects of necromantic magic tend to be relatively harmless to mummies.
- However, their dessicated bodies are highly flammable. They also do not need
- to eat or drink, and in any case are incapable of doing so.
-
-Ghouls:
-
- Ghouls are horrible undead creatures, slowly rotting away. Although ghouls
- can sleep in their graves for years on end, when they rise to walk among the
- living they must eat flesh to survive. Raw flesh is preferred, especially
- rotting or tainted meat, and ghouls gain strength from consuming it.
-
- They aren't very good at doing most things, although they make decent
- fighters and, due to their contact with the grave, can use ice, earth and
- death magic without too many difficulties.
-
-Naga:
-
- The Naga are a race of hybrids: humanoid from the waist up, with a large
- snake tail instead of legs.
-
- They are reasonably good at most things and advance in experience levels at
- a decent rate. They are naturally immune to poisons, can see invisible
- creatures, and have tough skin, but their tails are relatively slow and
- cannot move them around as quickly as can other creatures' legs (this only
- affects their movement rate; all other actions are at normal speed). Their
- body shape also prevents them from gaining full protection from most armour.
-
- Every now and then, a naga can spit poison; the range, accuracy and damage
- of this poison increases with the naga's experience level.
-
-Ogres and Ogre Mages:
-
- Ogres are huge, chunky creatures related to orcs. They are terrible monsters
- who usually live to do nothing more than smash, smash, smash, and destroy.
-
- They have great physical strength, but are bad at almost everything except
- fighting and learn quite slowly. Because of their large size they can only
- wear loose robes, cloaks and animal skins. Although ogres can eat almost
- anything, their size means that they need to do so more frequently than
- smaller folk.
-
- Ogre-mages are a separate race of ogres who are unique among the beefier
- species in their ability to use magic, especially enchantments. Although
- slighter than their common ogre relatives they nevertheless have great
- strength and can survive a lot of punishment. They advance in level as
- slowly as high elves.
-
-Trolls:
-
- Trolls are like ogres, but even nastier. They have thick, knobbly skins of
- any colour from putrid green to mucky brown and their mouths are full of
- ichor-dripping fangs.
-
- They can rip creatures apart with their claws, and regenerate very quickly
- from even the most terrible wounds. They learn very slowly indeed - even
- more slowly than high elves - and need a great amount of food to survive.
-
-Draconians:
-
- Draconians are a race of human-dragon hybrids: humanoid in form and
- approximately human-sized, with wings, tails and scaly skins. Draconians
- start out in an immature form with brown scales, but as they grow in
- power they take on a variety of colours.
-
- Some types of draconians have breath weapons. Draconians advance very slowly
- in level, but are reasonably good at all skills but armour (most types of
- which they cannot wear) and missile weapons.
-
-Centaurs:
-
- The Centaurs are another race of hybrid creatures: horses with a human
- torso. They usually live in forests, surviving by hunting.
-
- Centaurs can move very quickly on their four legs, and are excellent
- with bows and other missile weapons; they are also reasonable at the
- Fighting skill while being slow learners at specific weapon skills. They
- advance quite slowly in experience level and are rather sub-average at
- using magic. Due to their large bulk, they need a little extra food to
- survive.
-
-Demigods:
-
- Demigods are mortals (humans, orcs or elves, for example) with some divine
- or angelic ancestry, however distant; they can be created by a number of
- processes including magical experiments and the time-honoured practice of
- interplanar miscegenation.
-
- Demigods look more or less like members of their mortal part's race, but
- have excellent abilities (strength, int, dex) and are extremely robust; they
- can also draw on great supplies of magical energy. On the downside they
- advance very slowly in experience, gain skills slightly less quickly than
- humans, and due to their status cannot worship the various Gods and Powers
- available to other classes of being.
-
-Spriggans:
-
- Spriggans are small magical creatures distantly related to elves. They
- love to frolic and cast mischevious spells.
-
- They are poor fighters, have little physical resilience, and are terrible at
- destructive magic - conjurations, summonings, necromancy and elemental
- spells. On the other hand, they are excellent at other forms of magic and
- are very good at moving silently and quickly. So great is their speed that a
- spriggan can keep pace with a centaur.
-
-Minotaurs:
-
- The minotaur is yet another hybrid - a human body with a bovine head. It
- delves into the Dungeon because of its instinctive love of twisting
- passageways.
-
- Minotaurs are extremely good at all forms of physical combat, but are
- awful at using any type of magic. They can wear all armour except for
- some headgear.
-
-Demonspawn:
-
- Demonspawn are horrible half-mortal, half-infernal creatures - the flip side
- of the Demigods. Demonspawn can be created in any number of ways: magical
- experiments, breeding, unholy pacts, etc. Although many demonspawn may be
- indistinguishable from those of pure mortal stock, they often grow horns,
- scales or other unusual features. Powerful members of this class of beings
- also develop a range of unholy abilities, which are listed as mutations (and
- can sometimes be activated with the 'a' command).
-
- Demonspawn advance quite slowly in experience and learn most skills at about
- the same rate as do Demigods. However, they are a little better at fighting
- and much better at conjurations, summonings, necromancy and invocations.
-
-Kenku:
-
- The Kenku are an ancient and feared race of bird-people with a legendary
- propensity for violence. Basically humanoid with bird-like heads and clawed
- feet, the kenku can wear all types of armour except helmets and boots.
- Despite their lack of wings, powerful kenku can fly and very powerful
- members of this race can stay in the air for as long as they wish to do so.
-
- They are experts at all forms of fighting, including the magical arts of
- combat (conjurations, summonings and, to a lesser extent, necromancy). They
- are good at air and fire elemental magic, but poor at ice and earth magic.
- Kenku do not appreciate any form of servitude, and so are poor at using
- invocations. Their light avian bodies cannot sustain a great deal of injury.
-
-Merfolk:
-
- The Merfolk are a hybrid race of half-human, half-fish that typically
- live in the oceans and rivers and seldom come onto the land. The merfolk
- aren't as limited on land as some myths suggest, their tails will quickly
- reform into legs once they leave the water (and, likewise, their legs
- will quickly reform into a tail should they ever enter water). Their
- agility is often misjudged, and they tend to be surprising nimble on
- land as well as in the water. Experts at swimming they need not fear
- drowning as they can quickly slip out of any encumbering armour during
- the transformation into their half-fish form.
-
- The Merfolk have developed their martial arts strongly on thrusting
- and grappling, since those are the most efficient ways to fight
- underwater. They, therefore, prefer polearms and short swords above
- all other weapons, although they can also use longer swords quite well.
-
- As spellcasters, they tend to be quite good in specific areas. Their
- mystical relationship with water makes it easier for them to use
- divination, poison, and ice magics... which use water occasionally
- as a material component. The legendary water magic of the merfolk
- was lost in ancient times, but some of that affinity still remains.
- The instability of their own morphogenic matrix has made them very
- accomplished transmuters, but most other magics seem foreign to them.
-
-Note:
-
- Some species have special abilities which can be accessed by the 'a'
- abilities menu. Some also have physical characteristics which allow them
- to make extra attacks using the Unarmed Combat skill.
-
-----------------------------------------------------------------------------
- CHARACTER CLASSES
-----------------------------------------------------------------------------
-
-In your quest, you play as one of a number of different types of characters.
-Although each has its own strengths and weaknesses, some are definitely
-easier than others, at least to begin with. The best classes for a beginner
-are probably Gladiators, fighters and Berserkers; if you really want to play
-a magician, try a Conjurer. Each class starts out with a different set of
-skills and items, but from there you can shape them as you will.
-
-Fighters:
-
- Fighters start with a decent weapon, a suit of armour and a shield. They
- have a good general grounding in the arts of fighting.
-
-Gladiators:
-
- The Gladiator is trained to fight in the ring, and so is an expert in the
- art of fighting but is not so good at anything else. In fact, Gladiators are
- pretty terrible at anything except bashing monsters with heavy things. They
- start with a nasty weapon, a small shield, and armour.
-
-Berserkers:
-
- Berserkers are hardy warriors who worship Trog the Wrathful, from whom they
- get the power to go berserk (as well as a number of other powers should they
- prove worthy) but who forbids the use of spell magic. They enter the dungeon
- with an axe and a set of leather armour.
-
-Hunters:
-
- The Hunter is a type of fighter who specialises in missile weapons. A Hunter
- starts with a bow and some arrows, as well as a hunting knife and a set of
- leathers.
-
-Monks:
-
- The Monk is a member of an ascetic order dedicated to the perfection of
- one's body and soul through the discipline of the martial arts. Monks start
- with very little equipment, but can survive without the weighty weapons and
- spellbooks needed by other classes.
-
-Thieves:
-
- The Thief is one of the trickiest classes to play. Thieves start out with a
- large variety of useful skills, and need to use all of them to survive.
- Thieves start with a short sword, some throwing darts, and light armour.
-
-Assassin:
-
- An Assassin is a thief who is especially good at killing. Assassins are like
- thieves in most respects, but are more dangerous in combat.
-
-Stalkers:
-
- The stalker is an assassin who has trained in the use of poison magic.
-
-Crusaders:
-
- The Crusader is a decent fighter who can use the magical art of enchantment
- to become more dangerous in battle. Crusaders start out lightly armed and
- armoured, but equipped with a book of martial spells.
-
-Reavers:
-
- Reavers are warriors who learn the magics of destruction in order to
- complement their deadliness in hand combat.
-
-Death Knights:
-
- The Death Knight is a fighter who aligns him or herself with the powers of
- death. There are two types of Death Knights: those who worship and draw
- their abilities from the Demon-God Yredelemnul, and those who study the
- fearsome arts of necromancy.
-
-Chaos Knights:
-
- The Chaos Knight is a fighter who chooses to serve one of the fearsome and
- unpredictable Gods of Chaos. He or she has two choices: Xom or Makhleb.
- Xom is a very unpredictable (and possibly psychotic) entity who rewards
- or punishes according to whim. Makhleb the Destroyer is a more purposeful
- God, who appreciates destruction and offers a variety of very violent
- powers to the faithful.
-
-Paladins:
-
- The Paladin is a servant of the Shining One, and has many of the abilities
- of the Fighter and the Priest. He or she enters the dungeon with a sword,
- a shield, a robe, and a healing potion.
-
-Priests:
-
- Priests serve either Zin, the ancient and revered God of Law, or the
- rather less pleasant Death-God Yredelemnul. Although priests enter the
- dungeon with a mace (as well as a priestly robe and a few healing
- potions), this is purely the result of an archaic tradition the reason
- for which has been lost in the mists of time; Priests are not in any way
- restricted in their choice of weapon skills.
-
-Healers:
-
- The Healer is a priest of Elyvilon. Healers begin with minor healing
- powers, but can gain far greater abilities in the long run.
-
-Magicians:
-
- The magician is not a class, but a type of class. A magician is the best
- at using magic. Magicians start with a dagger, a robe, and a book of
- spells which should see them through the first several levels. There are
- various kinds of magicians:
-
- A Wizard is a magician who does not specialise in any area of magic.
- Wizards start with a variety of magical skills and the magic dart spell in
- memory.
-
- The Conjurer specialises in the violent and destructive magic of
- conjuration spells. Like the Wizard, the Conjurer starts with the magic
- dart spell.
-
- The Enchanter specialises in the more subtle area of enchantment magic.
- Although not as directly powerful as conjurations, high-level enchantments
- offer a wide range of very handy effects. The Enchanter begins with
- lightly enchanted weapons and armour, but no direct damage spell (since
- enchantments does not deal with direct attacks). Instead they begin
- with the "confusing touch" spell and some enchanted darts, which should
- help them out until they can use the higher level enchantment spells.
-
- The Summoner specialises in calling creatures from this and other worlds
- to give assistance. Although they can at first summon only very wimpy
- creatures, the more advanced summoning spells allow summoners to call on
- such powers as elementals and demons.
-
- The Necromancer is a magician who specialises in the less pleasant side of
- magic. Necromantic spells are a varied bunch, but many involve some degree
- of risk or harm to the caster.
-
- Elementalists are magicians who specialise in one of the four types of
- elemental magic: air, fire, earth, or ice.
-
- Fire Magic tends towards destructive conjurations.
-
- Ice Magic offers a balance between destructive conjurations and
- protective enchantments.
-
- Air Magic provides many useful enchantments in addition to some
- unique destructive capabilities.
-
- Earth Magic is a mixed bag, with destructive, defensive and utility
- spells available.
-
- Venom mages specialise in poison magic, which is extremely useful in the
- shallower levels of the dungeon where few creatures are immune to it. Poison
- is especially effective when used against insects.
-
- Transmuters specialise in transmigrations, and can cause strange changes
- in themselves and others.
-
- Warpers specialise in translocations, and are experts in travelling long
- distances and positioning themselves precisely.
-
-Wanderers:
-
- Wanderers are people who have not learned a specific trade. Instead,
- they've travelled around becoming "Jacks-of-all-trades, master of none".
- They start the game with a large assortment of skills and maybe some
- small items they picked up along the way, but other than that they're
- pretty much on their own. Non-human wanderers might not even know which
- skills they have (since they haven't quite learned enough for one full
- level), and therefore make for an additional challenge. You shouldn't
- expect human wanderers to be easy either, as this class is typically
- harder to play than the other classes.
-
-----------------------------------------------------------------------------
- EXPERIENCE
-----------------------------------------------------------------------------
-
-When you kill monsters, you gain experience points (xp) (you also receive
-one half experience for monsters killed by friendly creatures). When you
-get enough xp, you gain an experience level, making your character more
-powerful. As they gain levels, characters gain more hit points, magic
-points, and spell levels.
-
-Additionally, the experience you gain is used for your experience pool.
-This pool of points is used up whenever you practice a skill.
-
-----------------------------------------------------------------------------
- SKILLS
-----------------------------------------------------------------------------
-
-Your character has a number of skills which affect his or her ability to
-perform certain tasks. You can see your character's skills by pressing the 'm'
-key; the higher the level of a skill, the better you are at it. Every time
-your character gains experience points, those points become available to
-increase skills. You convert experience points into skill levels by practising
-the skill in question (eg fight with a certain type of weapon, cast a certain
-type of spell, or walk around wearing light armour to practise stealth). The
-amount of unassigned experience points is shown next to your experience total
-on the main screen as well as on the skills screen, and the number in blue
-next to each skill counts down from 9 to 0 as you get closer to gaining a
-level in that skill.
-
-You can elect not to practise a particular skill by selecting it in the skill
-screen (making it turn dark grey). This means that you will be less likely to
-increase that skill when you practise it (and will also not spend as many
-experience points on it). This can be useful for skills like stealth which use
-up points whenever you move. It can also be used on a specific weapon skill if
-you want to spend more points on Fighting, and similarly with magic skills and
-Spellcasting.
-
-The species you have chosen for your character has a significant effect on
-your rate of advancement in each skill. Some races are very good at some
-skills and poor at others. If your character is naturally quick to learn a
-skill, they will require less experience and take less time to advance in it;
-being bad at a skill has the opposite result.
-
-Here is a description of the skills you may have:
-
-
-Fighting skills:
-
- Fighting is the basic skill used in hand-to-hand combat, and applies no
- matter which weapon your character is wielding (if any). It is also the
- skill which determines the number of hit points your character gets as
- they increase in level (note that this is calculated so that you don't get
- a long run advantage by starting out with a high fighting skill).
-
- Weapon skills affect your ability to fight with specific melee weapons.
- Weapon skills include:
-
- o Short Blades
- o Long Blades
- o Maces & Flails
- o Axes
- o Staves
- o Polearms
-
- If you are already good at a weapon, say a long sword, and you practise
- for a while with similar weapon such as a short sword, your practise will
- be speeded up (and will require less experience) until both skills are
- equal. Similar types of weapons include:
-
- o Short Blades and Long Blades
- o Maces & Flails and Axes
- o Polearms and Axes
- o Staves and Polearms
-
- Being good at a specific weapon improves the speed with which you can use
- it by about 10% every two skill levels. Although lighter weapons are
- easier to use initially, as they strike quickly and accurately, heavier
- weapons increase in damage potential very quickly as you improve your
- skill with them.
-
- Unarmed Combat is a special fighting skill. It allows your character to
- make a powerful attack when unarmed and also to make special secondary
- attacks (and increases the power of those attacks for characters who get
- them anyway). You can practise Unarmed Combat by attacking empty-handed,
- and it is also exercised when you make a secondary attack (a kick, punch
- etc). Unarmed combat is particularly difficult to use in combination with
- heavy armour, and characters wearing a shield or wielding a two-handed
- weapon other than a staff lose the powerful punch attack.
-
-Throwing skills:
-
- Throwing is the basic skill used when throwing things, and there are a
- number of individual weapon skills for missile weapons as well:
-
- o Darts
- o Bows
- o Crossbows
- o Slings
-
-Magic skills:
-
- Spellcasting is the basic skill for magic use, and affects your reserves of
- magical energy in the same way that Fighting affects your hit points. Every
- time you increase your spellcasting skill you gain some magic points and
- spell levels. Spellcasting is a very difficult skill to learn, and requires
- a large amount of practice and experience.
-
- Only those characters with at least one magic skill at level one or above
- can learn magical spells. If your character has no magic skills, he or she
- can learn the basic principles of the hermetic arts by reading and reciting
- the spells inscribed on magical scrolls (this stops being useful once you
- reach level one in Spellcasting).
-
- There are also individual skills for each different type of magic; the
- higher the skill, the more powerful the spell. Multidisciplinary spells use
- an average of the two or three skills.
-
- Elemental magic is a special case. When you practise an elemental magic
- skill (fire, ice, air or earth magic) you will improve much less quickly
- than normal if you already have one or more elemental magic skills higher
- than the one you are practising. This is especially true if those skills are
- 'opposed' to the one you're practising: fire and ice are mutually opposed,
- as are earth and air.
-
- Say you have level 2 fire magic, level 4 ice magic, and level 1 air magic.
- Practising ice magic won't be a problem. Practising air magic will be a bit
- slow, as you have other elemental skills at higher levels. Practising fire
- magic will be very slow, as you have a higher level in ice magic. Right?
-
-Miscellaneous skills:
-
-Armour:
-
- Having a high Armour skill means that you are used to wearing heavy armour,
- allowing you to move more freely and gain more protection.
-
-Dodging:
-
- When you are wearing light armour, a high dodging skill helps you evade
- attacks.
-
-Stealth:
-
- Helps you avoid being noticed. Try not to wear heavy armour or be encumbered
- if you want to be stealthy. Big creatures (like trolls and ogres) are bad at
- stealth.
-
-Stabbing:
-
- Lets you make a very powerful first strike against a sleeping/resting
- monster who hasn't noticed you yet. This is most effective with a dagger,
- slightly less effective with a short sword, and less useful (although by
- no means of negligible effect) with any other weapon.
-
-Shields:
-
- Affects the amount of protection you gain by using a shield, and the degree
- to which it hinders you.
-
-Traps & Doors:
-
- Affects your ability to notice hidden traps and doors and to disarm traps
- when you find them. With this skill at a high level you will often find
- hidden things without actively looking for them.
-
-Invocations:
-
- An easy-to-learn skill which affects your ability to call on your God for
- aid. Those skilled at invoking have reduced fail rates and produce more
- powerful effects. The Invocations skill affects your supply of magic in a
- similar way to the Spellcasting skill and to a greater extent, but the two
- are not cumulative - whichever gives the greater increase is used. Some
- Gods (such as Trog) do not require followers to learn this skill.
-
-If your character does not have a particular skill, s/he can gain it by
-practising as above.
-
-----------------------------------------------------------------------------
- ABILITIES
-----------------------------------------------------------------------------
-
-Your character is further defined by his or her abilities, which initially
-vary according to class and species.
-
-Strength:
-
- Affects the amount of damage you do in combat, as well as how much stuff
- you can carry.
-
-Intelligence:
-
- Affects how well you can cast spells as well as your ability to use some
- magical items.
-
-Dexterity:
-
- Affects your accuracy in combat, your general effectiveness with missile
- weapons, your ability to dodge attacks aimed at you, and your ability to use
- thiefly skills such as backstabbing and disarming traps. Although your
- dexterity does not affect your evasion score (EV) directly, any calculation
- involving your EV score also takes account of your dexterity.
-
-Armour Class:
-
- Also called AC, when something injures you, your AC reduces the amount of
- damage you suffer. The number next to your AC is a measure of how good your
- shield (if any) is at blocking attacks. In both cases, more is better.
-
-Evasion:
-
- Also called EV, this helps you to avoid being hit by unpleasant things.
-
-Gold:
-
- This is how much money you're carrying. Money adds to your final score,
- and can be used to purchase items in shops.
-
-Magic Resistance:
-
- Affects your ability to resist the effects of enchantments and similar
- magic directed at you. Although your magic resistance increases with your
- level to an extent determined by your character's species, the creatures you
- will meet deeper in the dungeon are better at casting spells and are more
- likely to be able to affect you. MR is an internal variable, so you can't
- see what yours is.
-
-Special Abilities:
-
- Sometimes characters will be able to use special abilities, for example
- the Naga's ability to spit poison or the magical power to turn invisible
- granted by a ring. These are accessed through the 'a' command.
-
-----------------------------------------------------------------------------
- ITEMS
-----------------------------------------------------------------------------
-
-
-In the dungeons of Crawl there are many different kinds of normal and magical
-artefacts to be found and used. Some of them are useful, some are nasty, and
-some give great power, but at a price. Some items are unique; these have
-interesting properties which can make your life rather bizarre for a while.
-They all fall into several classes of items, each of which is used in a
-different way. Here is a general list of what you might find in the course of
-your adventures:
-
-Weapons:
-
- These are rather important. You will find a variety of weapons in the
- dungeon, ranging from small and quick daggers to huge, cumbersome
- battleaxes and pole-arms. Each type of weapon does a differing amount of
- damage, has a different chance of hitting its target, and takes a
- different amount of time to swing. You should choose your weapons
- carefully; trying to hit a bat with a greatsword is about as clever as
- bashing a dragon with a club. For this reason it is wise to have a good
- mixture of weapon skills. Skills affect damage, accuracy and speed.
-
- Weapons can be enchanted; when they are identified, they have values which
- tell you how much more effective they are than an unenchanted version. The
- first number is the enchantment to-hit, which affects the weapon's
- accuracy, and the second is its damage enchantment; weapons which are not
- enchanted are simply '+0'. Some weapons also have special magical effects
- which make them very effective in certain situations. Some types of hand
- weapons (especially daggers, spears and hand axes) are quite effective
- when thrown.
-
- You can wield weapons with the 'w' command, which is a very quick action.
- If for some reason you want to go bare-handed, type 'w' followed by a
- hyphen ('-'). Note that weapons are not the only class of item which you
- can wield.
-
- The ' (apostrophe) key is a shortcut which automatically wields item a. If
- item a is being wielded, it causes you to wield item b instead, if possible.
- Try assigning the letter a to your primary weapon, and b to your bow or
- something else you need to wield only sometimes. Note that this is just a
- typing shortcut and is not functionally different to wielding these items
- normally.
-
-Ammunition:
-
- If you would rather pick off monsters from a safe distance, you will need
- ammunition for your sling or bow. Darts are effective when simply thrown;
- other kinds of ammunition require you to wield an appropriate device to
- inflict worthwhile damage. Ammunition has only one "plus" value, which
- affects both accuracy and damage. If you have ammunition suitable for
- what you are wielding, the 'f' command will choose the first lot in your
- inventory, or you can use the 't' command to throw anything. If you are
- using the right kind of hand weapon, you will "shoot" the ammunition,
- otherwise you "throw" it.
-
- When throwing something, you are asked for a direction. You can either
- enter one of the directions on your keypad, or type '*' and move the
- cursor over your target if they are not in a direct line with you. When
- the cursor is on them, press '.' (period) or delete to target them (you
- can also target an empty space if you want). If you press '>' instead of
- '.', the missile will stop at that space even if it misses, and if the
- target space is water, it may hit anything which might be lurking beneath
- the surface (which would otherwise be missed completely). If you type '.'
- (or del) instead of a direction or '*', or if you target yourself as
- described above, you throw whatever it is at yourself (this can be useful
- when zapping some wands; see later). Also, if you type 'p' instead of a
- direction or '*', you will target your previous target (if still
- possible).
-
-Armour:
-
- This is also rather important. When worn, most armour improves your Armour
- Class, which decreases the amount of damage you take when something
- injures you. Unfortunately the heavier types of armour also hamper your
- movement, making it easier for monsters to hit you (ie reducing your
- evasion score) and making it harder for you to hit monsters. These effect
- can be mitigated by a high Armour skill. Wearing heavy armour also
- increases your chances of miscasting spells, an effect which is not
- reduced by your Armour skill.
-
- A Shield normally affects neither your AC or your evasion, but it lets you
- block some of the attacks aimed at you and absorbs some of the damage you
- would otherwise receive from things like dragon breath and lightning
- bolts. Wearing a shield (especially a large shield) makes you less
- effective in hand combat. Shields are more effective when you're fighting a
- small number of foes than when you're surrounded.
-
- Some magical armours have special powers. These powers are sometimes
- automatic, affecting you whenever you wear the armour, and sometimes must
- be activated with the 'a' command.
-
- You can wear armour with the 'W' command, and take it off with the 'T'
- command.
-
-Food:
-
- This is extremely important. You can find many different kinds of food in
- the dungeon. If you don't eat when you get hungry, you will eventually
- die of starvation. Fighting, carrying heavy loads, casting spells, and
- using some magical items will make you hungry. When you are starving you
- fight less effectively as well. You can eat food with the 'e' command.
-
-Magical Scrolls:
-
- Scrolls have many different magical spells enscribed on them, some good
- and some bad. One of the most useful scrolls is the scroll of identify,
- which will tell you the function of any item you have in your inventory;
- save these up for the more powerful and inscrutable magic items, like
- rings. You can read scrolls (and by doing so invoke their magic) with the
- 'r' command.
-
-Magical Potions:
-
- While scrolls tend to affect your equipment or your environment, most
- potions affect your character in some way. The most common type is the
- simple healing potion, which restores some hit points, but there are many
- other varieties of potions to be found. Potions can be quaffed (drunk)
- with the 'q' command. Try to avoid drinking poisonous potions!
-
-Wands:
-
- Sometimes you will be lucky enough to find a stick which contains stored
- magical energies. Wands each have a certain amount of charges, and a wand
- will cease to function when its charges run out. You must identify a wand
- to find out how many uses it has left. Wands are aimed in the same way as
- missile weapons, and you can invoke the power of a wand by 'z'apping it.
-
-Rings:
-
- Magical rings are among the most useful of the items you will find in the
- dungeon, but can also be some of the most hazardous. They transfer various
- magical abilities onto their wearer, but powerful rings like rings of
- regeneration or invisibility make you hunger very quickly when activated.
- You can put on rings with the 'P' command, and remove them by typing 'R'.
- You can wear up to two rings simultaneously, one on each hand; which hand
- you put a ring on is immaterial to its function. Some rings function
- automatically, while others require activation (the 'a' command).
-
- Amulets are similar to rings, but have a different range of effects (which
- tend to be more subtle). Amulets are worn around the neck, and you can
- wear only one at a time.
-
-Staves:
-
- There are a number of types of magical staves. Some enhance your general
- spellcasting ability, while some greatly increase the power of a certain
- class of spells (and possibly reduce your effectiveness with others).
- Some are spell staves, and hold spells which you can cast without having
- to memorise them first, and also without consuming food. You must wield a
- staff like a weapon in order to gain from its power, and magical staves
- are as effective as +0 quarterstaves in combat. Spell staves can be
- Invoked with the 'I' command while you are wielding them.
-
-Books:
-
- Most books contain magical spells which your character may be able to learn.
- You can read a book with the 'r' command, which lets you access a
- description of each spell, or memorise spells from it with the 'M' command.
- Some books have other special effects, and powerful spellbooks have been
- known to punish the attentions of incompetent magicians.
-
-Carrion:
-
- If you manage to kill a monster delicately enough to avoid scattering bits
- of it around the room, it may leave a corpse behind for you to play with.
- Despite the fact that corpses are represented by the same '%' sign as
- food, you can't eat them without first cutting them into pieces with the
- 'D' command, and being extremely hungry helps as well. Even then, you
- should choose your homemade food with great care.
-
-Miscellaneous:
-
- These are items which don't fall into any other category. You can use many
- of them by wielding and 'I'nvoking them. You can also use some other
- special items (such as some weapons) by invoking them in this way.
-
-Racial Items:
-
- Some items have been crafted by members of a gifted race, and have special
- properties. In addition, items made by a specific race work better in the
- hands of people of that race.
-
- Dwarven weapons and armours are very durable, and do not rust or corrode
- easily.
-
- Orcish bows/crossbows are particularly effective in combination with orcish
- arrows/bolts.
-
- Elven armour is unusually light, and does not affect the dodging or stealth
- of its wearer to the extent that other armours do. Elven cloaks and boots
- are particularly useful to those who wish to be stealthy, and elven bows are
- particularly effective in conjunction with elven arrows.
-
-Getting Items:
-
- You pick items up with the ',' (comma) command and drop them with the 'd'rop
- command. When you are given a prompt like "drop which item?" or "pick up
- <x>?", if you type a number before either the letter of the item, or 'y' or
- 'n' for yes or no, you will drop or get that quantity of the item.
-
- Typing 'i' gives you an inventory of what you are carrying. When you are
- given a prompt like "Throw [or wield, wear, etc] which item?", you can type
- the letter of the item, or you can type '?' or '*' to get an inventory list.
- '?' lists all appropriate items, while '*' lists all items, appropriate or
- not. When the inventory screen is showing "-more-", to show you that there
- is another page of items, you can type the letter of the item you want
- instead of space or enter.
-
- You can use the adjust command (the '=' key) to change the letters to which
- your possessions are assigned. This command can be used to change spell
- letters as well.
-
- Some items can be stickycursed, in which case they weld themselves to your
- body when you use them. Such items usually carry some kind of disadvantage:
- a weapon or armour may be damaged or negatively enchanted, while rings can
- have all manner of unpleasant effects on you. If you are lucky, you might
- find magic which can rid you of cursed items.
-
- Items like scrolls, potions and some other types each have a characteristic,
- like a label or a colour, which will let you tell them apart on the basis of
- their function. However, these characteristics change between each game, so
- while in one game every potion of healing may be yellow, in another game
- they might all be purple and bubbly. Once you have discovered the function
- of such an item, you will remember it for the rest of the current game. You
- can access your item discoveries with the '\' key.
-
- A very useful command is the 'v' key, which gives you a description of what
- an item does. This is particularly useful when comparing different types of
- weapons, but don't expect too much information from examining unidentified
- items.
-
-----------------------------------------------------------------------------
- RELIGION
-----------------------------------------------------------------------------
-
-There are a number of Gods, Demons and other assorted Powers who will accept
-your character's worship, and sometimes give out favours in exchange. You can
-use the '^' command to check the requirements of whoever it is that you
-worship, and if you find religion to be an inconvenience you can always
-renounce your faith (use the 'a' command - but some Gods resent being
-scorned!).
-
-The 'p' command lets you pray to your God. Anything you do while praying, you
-do in your God's name - this is how you dedicate your kills or corpse-
-sacrifices ('D' command) to your God, for example. Praying also gives you a
-sense of what your God thinks of you, and can be used to sacrifice things at
-altars.
-
-To use any powers which your God deems you fit for, access the abilities menu
-with the 'a' command; God-given abilities are listed as invocations.
-
-Some classes start out religious; others have to pray at an altar to dedicate
-themselves to a life of servitude. There are altars scattered all over the
-dungeon, and your character has heard rumours of a special temple somewhere
-near the surface.
-
-----------------------------------------------------------------------------
- MUTATIONS
-----------------------------------------------------------------------------
-
-Although it would doubtless be a nice thing if you could remain genetically
-pure, there are too many toxic wastes and mutagenic radiations in the Dungeon
-for that to be possible. If your character is so affected by these that he or
-she undergoes physiological change, you can use the 'A' command to see how
-much of a freak they've become and the 'a' command to activate any mutations
-which can be controlled.
-
-You can also become mutated by overusing certain powerful enchantments,
-particularly Haste (not the kind you get from being berserk) and Invisibility,
-as your system absorbs too much magical energy - but you would have to spend
-almost all of your time hasted or invisible to be affected. However, some
-powerful items radiate dangerous levels of magical energy. More often than
-not, the mutations caused by magical radiations express harmfully.
-
-Any demonic powers your character may have are listed in red; these are
-permanent and can never be removed. If one of your powers has been augmented
-by a mutation, it is displayed in a lighter red colour.
-
-
-----------------------------------------------------------------------------
- SPELLCASTING
-----------------------------------------------------------------------------
-
-Magical spells are a very important part of surviving in the dungeon. Every
-character class can make use of magical spells, although those who enter the
-dungeon without magical skills must practise by reading scrolls before they
-can attempt spellcasting.
-
-Spells are stored in books, which you will occasionally find in the dungeon.
-Each spell has a Level, which denotes the amount of skill required to use it
-as well as indicating how powerful it may be. You can only memorise a certain
-number of levels of spells; type 'M' to find out how many. When you gain
-experience levels, you can memorise more, and you will need to save up for
-several levels to memorise the more powerful spells. When you cast a spell,
-you temporarily expend some of your magical energy as well as becoming
-hungrier (although more powerful spellcasters hunger less quickly from using
-magic).
-
-High level spells are difficult to cast, and you may miscast them every once
-in a while (resulting in a waste of magic and possibly dangerous side-
-effects). Your chance of failing to cast a spell properly depends on your
-skills, your intelligence, the level of the spell and whether you are wearing
-heavy armour. Failing to cast a spell exercises your spell skills, but not by
-as much as casting it successfully.
-
-Many of the more powerful spells carry disadvantages or risks; you should read
-the spell description (obtained by reading the spellbook in which you found
-the spell) before casting anything.
-
-Be careful of magic-using enemies! Some of them can use magic just as well as
-you, if not better, and often use it intelligently.
-
-
-----------------------------------------------------------------------------
- EXPLORING THE DUNGEON
-----------------------------------------------------------------------------
-
-You can make your character walk around with the numeric keypad (turn numlock
-off) or the "Rogue" keys (hjklbnyu). If this is too slow, you can make your
-character walk repeatedly by typing shift and a direction. They will walk in
-that direction until any of a number of things happen: a hostile monster is
-visible on the screen, a message is sent to the message window for any reason,
-you type a key, or you are about to step on anything other than normal floor
-or an undiscovered trap and it is not your first move of the long walk. Note
-that this is functionally equivalent to just pressing the direction key
-several times.
-
-If you press shift and '5' on the numeric keypad (or just the number '5' on
-the keyboard) you rest for 100 turns or until your hit points or magic return
-to full, whichever is sooner. You can rest for just one turn by pressing '.',
-delete, 's', or '5' on the keypad. Whenever you are resting, you are assumed
-to be observing your surroundings, so you have a chance of detecting any traps
-or secret doors adjacent to you.
-
-The section of the viewing window which is coloured (with the '@' representing
-you at the centre) is what you can see around you. The dark grey around it is
-the parts of the level which you have visited, but cannot currently see. The
-'x' command lets you move the cursor around to get a description of the
-various dungeon features, and typing '?' when the cursor is over a monster
-brings up a short description of that monster. You can get a map of the whole
-level (which shows where you've already been) by typing the 'X' key. This map
-specially colour-codes stairs and known traps, even if something is on top of
-them.
-
-You can make your way between levels by using staircases, which appear as '>'
-(down) and '<' (up), by pressing the '>' or '<' keys. If you ascend an up
-staircase on level one, you will leave the dungeon forever; if you are
-carrying the magical Orb of Zot, you win the game by doing this.
-
-Occasionally you will find an archway; these lead to special places like
-shops, magical labyrinths, and Hell. Depending on which type of archway it is,
-you can enter it by typing '<' or '>'.
-
-Doors can be opened with the 'o' command and closed with the 'c' command.
-Pressing control plus a direction also opens doors. If there is no closed door
-in the indicated space, you will attempt to attack any monster which may be
-standing there (this is the only way to attack a friendly creature hand-to-
-hand). If there is no creature there, you will attempt to disarm any trap in
-the target square. If there is apparently nothing there you will still attack
-it, just in case there's something invisible lurking around.
-
-A variety of dangerous and irritating traps are hidden around the dungeon.
-Traps look like normal floor until discovered. Some traps can be disarmed with
-the control-direction commands
-
-When you are in a shop, you are given a list of the shopkeeper's stock from
-which to choose, and a list of instructions. Unfortunately the shopkeepers all
-have an enterprise bargaining agreement with the dungeon teamsters union which
-prevents them using non-union labour to obtain stock, so you can't sell
-anything in a shop (but what shopkeeper would trust a scummy adventurer like
-you, anyway?).
-
-You goal is to locate the Orb of Zot, which is held somewhere deep beneath the
-world's surface. The Orb is an ancient and incredibly powerful artefact, and
-the legends promise great things for anyone brave enough to extract it from
-the fearsome Dungeon. Some say it will grant immortality or even godhood to
-the one who carries it into the sunlight; many undead creatures seek it in the
-hope that it will restore them to life. But then, some people will believe
-anything. Good luck!
-
-A full list of the commands available to you can be accessed by typing '?'
-(question mark). If you don't like them, they can be changed by the use of:
-
-----------------------------------------------------------------------------
- MACROS/KEYMAPS
-----------------------------------------------------------------------------
-
-You can change the keys used to perform specific functions by editing the
-macro.txt file (or creating a new one). The K: line indicates a key, and the
-A: line assigns another key to that key's function.
-
-You can also redefine keys in-game with the ` key, and save them with the ~
-key.
-
-(Thanks to Juho Snellman for this patch)
-
-----------------------------------------------------------------------------
- MONSTERS
-----------------------------------------------------------------------------
-
-In the caverns of Crawl, you will find a great variety of creatures, many of
-whom would very much like to eat you. To stop them doing this, you will need
-to fight. To attack a monster, stand next to it and move in its direction;
-this makes you attack it with your wielded weapon. Of course, some monsters
-are just too nasty to beat, and you will find that discretion is often the
-better part of valour.
-
-Some monsters can be friendly; friendly monsters will follow you around and
-fight on your behalf (you gain 1/2 the normal experience points for any kills
-they make). You can command your allies using the '!' key, which lets you
-either shout to attract them or tell them who to attack.
-
-----------------------------------------------------------------------------
- MISCELLANEOUS STUFF
-----------------------------------------------------------------------------
-
-The scores file does not have to be present (as of v2.02), and is not included
-in the distribution. You can unpack the zip file into your old crawl directory
-and the new version will keep using the old scores file (scores files from any
-version are usable by any later version).
-
-The initfile, INIT.TXT, lets you set various options affecting the game's user
-interface, like the conditions for Autopickup and a default name for your
-character. You can alter it with any reputable text editor.
-
-As of 2.60, a -c command line switch activates the alternative character set
-for non-IBM graphics displays. A -nc switch activates the non-IBM char set
-and, for Linux systems, disables colour.
-
-Crawl is available for a number of different systems, including Linux, DOS,
-the Mac, etc.
-
-One strange thing you may notice about Crawl is that it does not keep your
-saved games if you die. This is not a bug, it is a feature! If you could
-restore your game after dying, you would probably finish the game rather
-quickly and lose interest, because most of the fun in Crawl is in the
-discovery of its bizarre secrets while taking risks with your characters. It
-is possible to cheat by messing around with the save files, but you're only
-cheating yourself out of experiencing this game as it was supposed to be
-played. If you think Crawl is too difficult, tell me!
-
-Crawl was compiled using the djgpp compiler, and comes with the files
-CWSDPMI.EXE and CWSDPMI.DOC. You can contact the author of CWSDPMI.EXE at
-sandmann@clio.rice.edu. Read CWSDPMI.DOC for more details.
-
-Although version 3 of Crawl is a complete and finished game, it probably
-contains a few unwanted features which crept in without me noticing (all of
-the earlier versions did). So, if you find anything which you think may be a
-bug, please send details of it to me, including version number, details of
-your system, what you were doing (in the game) when it happened, and just what
-exactly did happen. Hopefully this will never be necessary, but if it is you
-can (as of 26/3/99) reach me at:
-linley.henzell@student.adelaide.edu.au
-
-You can also discuss this game on the newsgroup rec.games.roguelike.misc.
-
-The object of your quest in Crawl (the Orb of Zot) was taken from Wizard's
-Castle, a text adventure written in BASIC.
-
-A lot of people have been sending me feedback and bug reports, which is
-extremely encouraging. I really appreciate that people have been taking the
-time to play my game. Keep it up!
-
-Licence:
-Read Licence.txt for information about the Crawl licence (which is practically
-identical to the nethack GPL).
-
-Source Code:
-The source code for the current version of Crawl is, at the time of writing
-(30/12/97) available from the Crawl web site:
-http://olis.net.au/~zel/index.html
-Source for some earlier versions can be obtained from me, although
-unfortunately I've lost most of it.
-
-Disclaimer:
-
-This software is provided as is, with absolutely no warranty express or
-implied. Use of it is at the sole risk of the user. No liability is accepted
-for any damage to the user or to any of the user's possessions.
diff --git a/stone_soup/crawl-ref/docs/messlog.txt b/stone_soup/crawl-ref/docs/messlog.txt
deleted file mode 100644
index d04ae19f83..0000000000
--- a/stone_soup/crawl-ref/docs/messlog.txt
+++ /dev/null
@@ -1,562 +0,0 @@
-CHANGES TO pr31:
-
-
-
-* #defines MWATER6-10 (values 436 - 440) removed, unused in code, not needed and there is no point in reserving space for nonexistent monsters
-* #defines for MLAVA4,5,6,7,8,10 (and MLAVA10 should really have been MLAVA9, anyway), values 424-429, removed -- now unneeded, unused in code anyway.
-* #ifdef'd (USE_DEBRIS_CODE) enum DEBRIS -- really have to look at how this is implemented now!
-* ATTR_LAST_ATTR -> NUM_ATTRIBUTES
-* BEAM_CLOUD -> BEAM_ACID on strength of evidence in plant_spit() and zappy(), but now stinking_cloud() looks odd ... hmmm
-* DEBRIS_LAST -> NUM_DEBRIS
-* DNGN_TRAP_I -> DNGN_TRAP_MECHANICAL; DNGN_TRAP_II -> DNGN_TRAP_MAGICAL
-* ENCH_LAST_ENCH -> NUM_ENCHANTMENTS
-* FOOD_LAST -> NUM_FOODS
-* GOD_LAST_GOD -> NUM_GODS
-* GOOD_LAST_GOOD -> NUM_GOOD_THINGS
-* KILLED_LAST_KILLED -> NUM_KILLBY
-* MH_NORMAL -> MH_NATURAL, H_NORMAL -> H_NATURAL ... may want to add in {M}H_MAGICAL for creatures that are mortal though magical ...
-* MI_LAST_MI -> NUM_MISSILES
-* MONS_LAST_MONS -> NUM_MONSTERS
-* MONS_SMALL_SKELETON -> MONS_SKELETON_SMALL; MONS_LARGE_SKELETON -> MONS_SKELETON_LARGE; removed #defines in enum.h that josh added to achieve similar effect
-* MS_LAST_MS -> NUM_MONSTER_SPELLS
-* NAUGHTY_LAST_NAUGHTY -> NUM_NAUGHTY THINGS
-* OBJ_LAST_OBJ -> NUM_OBJECT_CLASSES
-* POT_LAST_POT -> NUM_POTIONS
-* SCR_LAST_SCR -> NUM_SCROLLS
-* SHOP_LAST_SHOP -> NUM_SHOPS
-* SK_LAST_SK -> NUM_SKILLS
-* SPELL_LAST_SPELL -> NUM_SPELLS
-* SPELL_MANNA and spells4::cast_manna() struck from the code, along with all supporting tie-ins
-* SPWPN_LAST_SPWPN -> NUM_SPECIAL_WEAPONS
-* STAFF_LAST_STAFF -> NUM_STAVES
-* SYM_SPORE -> SYM_BURST, as it is used all over the place for things other than spores
-* TOTAL_CARDS replaced with enum meber NUM_CARDS
-* TRAN_LAST_TRAN -> NUM_TRANSFORMATIONS
-* Vehumet will no longer shield one's intelligence when casting SUMMON_HORRIBLE_THINGS -- made no sense that he did in the first place
-* ZAP_LAST_ZAP -> NUM_ZAPS
-* a lot of cleanup/compaction in itemname.cc
-* a lot of general clean-up
-* a lot of mpr() clean-up
-* ability::show_abilities() made static
-* ability::species_ability() -> activate_ability()
-* abyss::generate_area() recoded for efficiency in selecting replacement tiles
-* abyss::priest_spells() -> player::priest_spells() and commented out, declaration from abyss.h moved to atop player.cc and also commented out -- part and parcel of above reasoning
-* added "you.redraw_hit_points = 1" to calc_hp() -- caught a number of instances where it was not being set
-* added #define ENDOFPACK for max size of player backpack
-* added #undef MAX to macro definition in it_use3::reaching_weapon_attack()
-* added CANNED_MESSAGES and stuff::msg_something_appears -> stuff::canned_msg() with appropriate parameter
-* added DARM_PLAIN to fill out ARMOUR_DESCRIPTIONS enum
-* added DNGN_LAST_SOLID_TILE to track this value's usage ... wish me luck
-* added DWPN_PLAIN
-* added MDSC_NOMSG_WOUNDS for monsters that do not message wound status to player
-* added MONSTER_DESCRIPTORS and monstuff:monster_descriptor() to handle usage
-* added MSG_SPELL_FIZZLES to stuff::canned_msg()
-* added NUM_TRAPS and TRAP_RANDOM
-* added OBJ_RANDOM
-* added OBJ_UNASSIGNED
-* added SHOP_UNASSIGNED and SHOP_RANDOM
-* added SPARM_RANDART_I
-* added STAT_ALL to deal with royal jelly, etc.
-* added TRAP_UNASSIGNED
-* added a number of CANNED_MESSAGES and handling by stuff::canned_msg()
-* added and implemented newgame::jobs_hpmp_init()
-* added declaration for monstuff::handle_behavior() atop file
-* added declaration of monstuff::flag_ench() atop monstuff.cc -- no idea why there wasn't one
-* added enum DIRECTION and applied members to codebase
-* added enum GENUS_PLAYER and started population of the enum for cases
-* added enum MONSTER_INVENTORY_SLOTS and applied members to codebase
-* added enum PLAYER_DESCRIPTORS
-* added enum SPECIAL_ROOMS and applied to codebase
-* added food::make_hungry(int bool) to streamline hunger decrements and messaging
-* added itemname::is_demonic() and applied to codebase -- probably should be expanded at a later date as more demonic items are introduced
-* added itemname::launched_by() which returns the appropriate missile subtype for a given weapon[launcher] subtype and implemented into code -- this will probably have to be reworked
-* added itemname::launches_things() which simply returns whether or not a WPN_foo launches other objects or not
-* added message to spells2::cast_toxic_radiance() for cases where light passes through invisible monsters
-* added misc::trap_at_xy() to handle determination of "which trap" for a given (x,y) coordinate
-* added misc::trap_category() to return grd[][] symbol for a given env.trap_type[]
-* added monstuff::message_current_target() for multiple instances of same messaging -- seemed the best place to stick it
-* added monstuff::monster_index() to return index value of a given monster pointer
-* added monstuff:heal_monster() and applied to codebase
-* added monstuff:hurt_monster() and applied to codebase
-* added monstuff:monster_habitat() to determine native habitat of creatures without resorting to range checking on MONSTERS enum -- better future flexibility
-* added mstruct::mons_itemuse() to replace global array gmon_use[1000] -- too much memory wasted there
-* added newgame::enterPlayerName()
-* added newgame::give_basic_knowledge()
-* added newgame::give_basic_spells()
-* added newgame::openingScreen()
-* added newgame::verifyPlayerName()
-* added player::dec_hp() -- probably should be inline or macro -- to unify handling decrementing of hp and catch error of not setting redraw to 1 (!!!)
-* added player::dec_mp() -- probably should be inline or macro -- to unify handling decrementing of mp and catch error of not setting redraw to 1 (!!!)
-* added player::decrease_stats() -- yes, I know that decrease_stats() and increase_stats() could be merged, but I'm too tired to do it now
-* added player::deflate_hp() to catch possible redraw bugs
-* added player::enuf_hp() to clarify ability.cc
-* added player::enuf_mp() to clarify ability.cc
-* added player::inc_hp() to catch possible redraw problems and bounds checking
-* added player::inc_mp() -- probably should be inline or macro -- to unify handling incrementing of mp and catch error of not setting redraw to 1 (!!!)
-* added player::job_title() and implemented
-* added player::player_descriptor() -- plan on future expansion
-* added player::reset_hp() to catch possible redraw problems
-* added player::set_hp() to catch possible redraw bugs
-* added player::set_mp() to catch redraw problems and to clarify coding
-* added player::species_abbrev() to stand in place of code in ouch::ouch()
-* added spellbook::spelltype_name() to permit recoding of certain portions of code as loops!!! (see: spells0.cc, spellbook.cc) - maybe should be moved elsewhere - output not in traditional order, but does it matter? -- cf. chardump::spell_type_name() -- grrrr!!!
-* added spells0::set_spellflags() to handle routine tasks
-* added spells0::spell_enhancement()
-* added spells0::spell_type2skill()
-* added static enum CARDS to decks.cc -- only used within this file -- and applied
-* added stuff::canned_msg(MSG_SOMETHING_APPEARS) to handle frequent use of set message: "Something appears at your feet."
-* added stuff::index_to_letter() and applied across codebase
-* added stuff::player_can_hear() to handle silence checking for both a distant (x,y) coordinate and the player's own coordinate
-* added stuff::random_colour() to generate a random color -- clarifies usage of particular calculation, prefer overhead of function to macro definition -- and applied to codebase
-* added view::mons_near_2() as future replacement for view::mons_near() -- takes a pointer rather than an index
-* anything relating to #ifdef CLASSES has been pulled out of the codebase -- it was never defined (or undefined for that matter), the code was out-of-date, got in the way of the actual operating code, and there is was a note dating all the way back to version 3.10 stating all this and more -- hope no one will miss it
-* applied stuff::yesno() to codebase -- a couple more complicated instances can use application
-* bang::explosion() now takes into account monster clouds as well as player clouds for "sizzle"
-* bang::explosion() now takes struct bolt * instead of struct bolt[] as second parameter
-* bang::explosion1() now takes struct bolt * instead of struct bolt[] as only parameter
-* beam::beam() now takes struct bolt * instead of struct bolt[] as only parameter
-* beam::check_mons_magres() returns bool instead of int
-* beam::check_mons_magres() takes struct monsters * instead of int as first parameter
-* beam::check_mons_resists() now takes struct bolt * instead of struct bolt[] as second parameter
-* beam::check_mons_resists() takes struct monsters * instead of int as second parameter
-* beam::mimic_alert() now takes struct monsters * instead of int as parameter
-* beam::missile() now takes struct bolt * instead of struct bolt[] as first parameter
-* beam::mons_ench_f2() no longer takes the second parameter (int foo[]) -- completely uneccesary, as it can be passed directly to the bolt struct
-* beam::mons_ench_f2() now returns bool instead of int -- not that the return value is ever used elsewhere
-* beam::mons_ench_f2() now takes struct bolt * instead of struct bolt[] as third parameter
-* beam::mons_ench_f2() takes bool as second parameter instead of char
-* beam::poison_monster() now takes struct monsters * instead of int as parameter
-* beam::poison_monster() takes bool instead of char for second parameter, renamed from "source" to "fromPlayer" and values reversed in passes (as it actually was t/f on fromMonster, but double m's looked silly)
-* beam::sticky_flame_monster() takes bool instead of char for second parameter -- no idea what it really means, as the function is called but once and the parameter ("source") is set to false
-* beam::tracer_f() now takes struct bolt * instead of struct bolt[] as second parameter
-* beam::tracer_f() now takes struct monster * instead of int as first parameter
-* bugfix (again): mummies get "closer to death" at levels 13 and 26
-* bugfix (of sorts): wizard commands 'x' and '$' no longer add to experience and call level_change() directly, but rather call gain_exp() instead -- these commands should still be bound by experience limits imposed by player::gain_exp()
-* bugfix in beam::beam() referenced menv[0] when menv[o] was meant ... cripes (!!!)
-* bugfix(?): items::handle_time() now forces one to exercise stealth -or- armour ... the original coding was a little odd (players with no or light armor had less of a chance to exercise stealth than those with heavier armour) -- but the intent seemed to be to make this tradeoff ... can't be stealthy in plate (unless elven), don't even try ... will potentially boost learning of armour skill by not wasting xp on stealth practicing. -- odds collapse on stealth practicing is 1 in 18 ... cf. to armour, which is 1 in 6 -- does that seem right, because that was the way it was and still is.
-* bugfix(minor) monstuff::monster_move() now cases monster clouds as well as player clouds for determination of safe move
-* bugfix/added itemname::hide2armour() and applied to codebase -- includes STEAM_DRAGON_HIDE, which had for some reason been overlooked in certain routines in dungeon.cc
-* bugfix/kinda: mstuff2::mons_trap() rewritten for better handling, silence checks for Zot trap, etc.
-* bugfix: (I think this was the case) warning message for followers of good gods weilding demonic weapons now outputs upon wield regardless of how special the item is
-* bugfix: I think I got the "off-by-one" for the Overmap error fixed
-* bugfix: NAMED_WEAPONS now begins at 181 and not 581 [josh admits fault here]
-* bugfix: [Daniel] SPWPN_FLAMING -> SPWPN_FLAME and SPWPN_FREEZING -> SPWPN_FROST for missile weapons in dungeon::items()
-* bugfix: abilities exercised by monsters in monstuff::handle_nearby_ability() were often dependent upon whether or not the monster was visible to the player -- which is stupid, a monster should stare at you (for example) regardless of whether you can see it
-* bugfix: ability case for ABIL_TO_PANDEMONIUM was only checking for 4 magic points when ability costs 7
-* bugfix: acr::input() -- changed "if ( you.duration[DUR_WEAPON_BRAND] > 0 )" to "if ( you.duration[DUR_WEAPON_BRAND] > 1 )" and else-if'd the ( you.duration[DUR_WEAPON_BRAND] == 1 ) -- as coded before, brands would jump from 2 to 1 to 0 in one call to input() -- just plain wrong!
-* bugfix: acr::input() -- changed instances of "if (foo > 1) foo--; if (foo == 1) foo = 0;" for durational things to "if (foo > 1) foo--; else if (foo == 1) foo = 0;" so that durational values of 2 would mean "two turns left" and not "expire now" as the code actually worked
-* bugfix: added #include <string.h> atop spell.cc {Brent}
-* bugfix: added bounds checking to dungeon::check_doors()
-* bugfix: added descriptor strings for transformation states missing from chardump::dump_char()
-* bugfix: added josh's acquirement book bugfix to dungeon::items() [Josh]
-* bugfix: applied SPTYP_RANDOM to appropriate spells::miscast_effect() calls and added appropriate code to spells::miscast_effect() -- much easier to change later, now
-* bugfix: bang::explosion1() had the potential to dump out duplicate lines from info[] due to careless placement of mpr() calls
-* bugfix: calls to "miscast_effect(10+random2(15), ...)" changed to "miscast_effect(10+random2(14), ...)" as there is no SPTYP_foo value assigned to 24!
-* bugfix: ditto for spells4::tame_beast_monsters()
-* bugfix: dungeon::build_minivaults() would attempt to build an undefined vault 1 out of 34 times ... no idea whether it would cause the game to hang, but not good to do that
-* bugfix: dungeon::give_item() was placing scrolls in the potion slot of monsters -- cripes (!!!)
-* bugfix: dungeon::hide_doors() fixed to not reference things outside bounds of grd[][]
-* bugfix: dungeon::items() for OBJ_WEAPONS was going off a value of 0 [no descrip] and not 3 [DWPN_ORCISH] in disallowing orcish weapons of orc slaying or holiness
-* bugfix: dungeon::items() was not generating the last four spellbooks (Josh's additions) -- it is now
-* bugfix: effects::forget_spell() would only check to "forget" spells in range of [0,19] and not [0,24], the full range of you.spells[] - and infinite loop check rewritten so as not to be probabilistic itself (!!!)
-* bugfix: eliminated references to feet for players who are centaurs
-* bugfix: fight::jelly_divide was locating suitable spots for the new jelly thusly:
- "if ( mgrd[parent.x + jex][parent.y + jey] == MNG && mgrd[parent.x + jex][parent.y + jey] > 10 && ( parent.x + jex != you.x_pos || parent.y + jey != you.y_pos ) )"
- the second grid check should be against grd[][] and not mgrd[][] -- the way it is coded, the second conditional is automativally satisfied by the first (MNG > 10) !!!
-* bugfix: fight::monster_polymorph() will only message the transformation if the player is near, the monster is visible or player can see invisible (before, messaging would only check for first case, and would do the strcpy/strcat regardless, only putting mpr() within a conditional)
-* bugfix: fight::you_attack() change in to hit bonus for sure blade changed from "5 + random2(10)" to "5 + random2limit(you.sure_blade, 25)" [Daniel] and changed messages in player::display_char_status()
-* bugfix: food::eating() case FOOD_PIZZA to properly display the "Mmmm..." string prior to the name of player's favorite kind of pizza
-* bugfix: for some reason Red Draconians were the only Draconians that did not get a tailslap attack in fight.cc -- now they do
-* bugfix: general change of "if (mons_near(o) && menv[o].enchantment[2] != ENCH_INVIS)" to "if (mons_near(o) && ( menv[o].enchantment[2] != ENCH_INVIS) || player_see_invis() ) )" -> simple_monster_message() where appropriate and some bugfixes with where checks were not applied against messages
-* bugfix: in abilities, moved some spells cast to positions prior to exercising so players would not get potential skill increase (and application) during act of casting
-* bugfix: in acr::input() you.delay was decrementing from 2 to 0 ... fixed by making an if-else rather than if-if situation
-* bugfix: in beam::beam() wand_id for LIGHTGREY (TELEPORTATION), WHITE (DISINTEGRATION), LIGHTRED (ENSLAVEMENT), BEAM_SLEEP only set to 1 for monsters that player can see
-* bugfix: in dungeon::plan_3() it was calling clear_area() to replace DNGN_FLOOR with DNGN_FLOOR -> should have been replacing DNGN_ROCK_WALL with DNGN_FLOOR {linley}
-* bugfix: in dungeon::plan_4() it was calling clear_area() to replace DNGN_FLOOR with DNGN_FLOOR -> should have been replacing DNGN_ROCK_WALL with DNGN_FLOOR {linley}
-* bugfix: in fight::monster_die() for case KILL_RESET cloud was only being placed if monster was near player
-* bugfix: in mstuff2::mons_cast() menv[0] was being referenced, preventing monster abjuration for spells MS_LEVEL_SUMMON, MS_SUMMON_DEMON, MS_SUMMON_UNDEAD, and MS_SUMMON_DEMON_GREATER
-* bugfix: in skills::exercise2() fixed determination of which skills impact recalculation of certain stats and/or forced redraws
-* bugfix: it_use2::unwear_armour() removed message checking for SPARM_COLD_RESISTANCE -- no real check for "lowered" resistance [how to save state w/o recalling player_res_foo()? problem with "stateless" resistances!]
-* bugfix: item_in_shop() no longer generates items of type OBJ_UNKNOWN_I or OBJ_UNKNOWN_II
-* bugfix: items::add_items() calculations for item_weight recoded to take advantage of itemname::mass() properly and permit Josh's USE_LIGHTER_MAGIC_ITEMS modification -- screwy it was
-* bugfix: message in player::display_char_status() for sure_blade now based on you.sure_blade and not you.confusing_touch [Daniel Ligon]
-* bugfix: messaging for spells2::holy_word() would only happen for invisible monsters for players unable to see invisible !!! (d'oh!)
-* bugfix: messaging screwed-up for monstuff::handle_potion() -- also, would only quaff potions of invis or haste iff not near player (latter makes little sense)
-* bugfix: misc::manage_clouds() now handles monster clouds, too.
-* bugfix: misc::in_a_cloud() for MIASMA cases was doing "double damage" by decrementing hp directly, then calling ouch (which does the same)
-* bugfix: monster flying over trap message was copied into info but never output by mpr()
-* bugfix: mstuff2::mons_throw() was checking against MSLOT_MISSILE instead of MSLOT_WEAPON in determining whether monster was in fact using a missile launcher (I think that was a bug)
-* bugfix: mstuff2::mons_throw() was checking against a value of 120 (not possible, AFAIK) and not DWPN_ELVEN in providing a to-hit bonus to the use of elven missile launchers
-* bugfix: mstuff2::monster_teleport() messaging was occurring for nearby monsters that were either visible or in the presence of a player that could not see invisible -- odd
-* bugfix: no description was output for runes of zot if id level was 0 (actually, would output debug string)
-* bugfix: no more messaging that a monster "almost triggered" a blade trap and no more revealing the trap, then -- makes no sense if it was "almost triggered" to perform either action
-* bugfix: player thrown missiles now match monster thrown missiles
-* bugfix: player::level_change() had mummies receiving "closer to powers of death" messages at levels 13 and 23 and not 13 and 27 as set in player::player_spec_death() [Daniel]
-* bugfix: related to above, gift timeout for YRED not set if he can't get a servant to you
-* bugfix: religion::lose_piety() did not have a message of losing ability to hasten self if follower of GOD_OKAWARU (piety > 120) or ability to receive minor healing (piety > 50) or ability of temporary might (piety > 30)
-* bugfix: repaired messaging for it_use3::box_of_beasts() to check to see whether a creature actually appears before saying one does (!!!)
-* bugfix: same as above for items::item_place()
-* bugfix: shopping::item_value() was going off a value of 6 [DARM_ORCISH] (and not 3 [DWPN_ORCISH]) when devaluing ocish weapons
-* bugfix: some possible messages were not being directed to player because of improper random limits being set in religion::Xom_acts()
-* bugfix: species selection screen in newgame::new_game() now starts with clrscr() call for all platforms -- was ugly under linux with just two EOLs output
-* bugfix: spells3::cast_selective_amnesia() will now return mana to player equivalent to the spell's cost ... looks like it was supposed to, but prior code did nothing at all
-* bugfix: spells3::entomb() did not destroy the traps it overwrote with walls - now, mechanical traps destroyed, magical traps retained
-* bugfix: spells4::cast_evaporate() was not messaging string constructed for "hands flaking" case
-* bugfix: spells4::make_shuggoth() could potentially have referenced menv[-1] -- fixed, but I still have to fix messaging
-* bugfix: spells4::passwall() attempts to reference areas outside the bounds of grd[][] -- still need to figure out what proper "borders" should be (see function)
-* bugfix: spells4::sleep_monsters() was using check_mons_magres() instead of !check_mons_magres() for condition where monster "saved" -- yes, I know it is a bit backward, but that is the code
-* bugfix: started applying GXM and GYM - caught instances where things were being checked/added/whatever beyond bounds of env.foo[][]
-* bugfix: the "Symbol of Immediate Regeneration" card was producing POT_HEALING effect, when it should have been generating a POT_HEAL_WOUNDS effect, according to the commented name of the card and the fact that there is already a Card of Healing
-* bugfix: dungeon::give_item() switched "(mitm.quantity[bp] == 0 || mitm.quantity[bp] == 100)" to "(mitm.quantity[bp] == 0 || mitm.base_type[bp] == 100)" as it should have been all along
-* bugfix: restore_foo() will no longer reset foo to foo_max in cases where foo >= foo_max -- don't know if it is the case, but may be at some point in the future
-* bugfixes: messaging based on create_monster() has been fixed to be dependent upon whether a monster actually appears -- probably did not get them all << checks spells2, spells3, and spells4 still >>
-* changed H_foo to MH_foo in spells4.cc (shame on you, Josh)
-* clean-up of mons_lev.cc
-* clean-up: player::player_AC() recoded as switch on species rather than bunch of if's -- too bad things weren't coded as species/subspecies to make working with draconians easier!!! (future change?)
-* cleaned up remaining "% 100" madness when it comes to cloud handling routines
-* cleaned-up cloud description coding in direct::look_around() -- last of the "foo % 100" coding, I think
-* cleaned-up dungeon::prepare_swamp() <again>
-* cleaned-up dungeon::prepare_water()
-* cleaned-up dungeon::vault_grid()
-* cleaning up my own bugs
-* codebase: it_use3 definition of "extern unsigned char show_green" removed - already in externs.h, which is included
-* codebase: moved spells4.cc and spells4.h to "unused" folder for the time being, removed spells4.o from makefile.obj list -- none of the functions in these files are called elsewhere
-* codebase: which_spellbook() definition moved from atop spells.cc to atop spellbook.cc -- it is only used there
-* commented out GOOD_ATTACKED_FRIEND in enum.h and only reference to it in fight::you_attack() -- not even accounted for in religion::done_good() so what the h*** is the point? way open to potential abuse if implemented, anyway. grumble, grumble.
-* commented out global char filenam[80] in dungeon.cc -- cannot find a single instance of usage
-* commented out global char save_file[9] in dungeon.cc -- cannot find a single instance of usage
-* commented out global char whole_line[80] in dungeon.cc -- cannot find a single instance of usage
-* commented out global char wm_1[5] in dungeon.cc -- cannot find a single instance of usage
-* commented out global char wm_2 in dungeon.cc -- cannot find a single instance of usage
-* commented out global int leng_str in dungeon.cc -- cannot find a single instance of usage
-* commented out global int old_x in dungeon.cc -- cannot find a single instance of usage
-* commented out global int old_y in dungeon.cc -- cannot find a single instance of usage
-* commented out global int rd in dungeon.cc -- only used in dungeon::specr_2() as near as I can tell
-* commented out global int x_fin and y_fin in dungeon.cc -- cannot find a single instance of usage
-* commented out global int x_max and y_max in dungeon.cc -- can only find variables local to dungeon::clear_area() that share these names
-* commented out globals int put_x and put_y in dungeon.cc -- cannot find a single instance of usage
-* commented out mstruct::def_letters() as the function is no longer being used anywhere
-* commented out stuff::output_value() - not used anywhere in the codebase
-* commented out unused gods in enum GODS and their unused altars in enum DUNGEON_FEATURES
-* completed ifdef of ABIL_GLAMOUR routines in abilities.cc -- josh didn't do it all the way through
-* created obj-weap.cc, corrected signage on parameters passed to some functions (char -> unsigned char)
-* deck_of_wonders[], deck_of_summoning[], deck_of_tricks[], and deck_of_power[] made static to decks.cc
-* decks::cards() made static to decks.cc
-* declaration for food::can_ingest() moved from food.h to atop food.cc -- internal to sourcefile
-* declaration for food::eat_from_floor() moved from food.h to atop food.cc -- internal to sourcefile
-* declaration for food::eaten() moved from food.h to atop food.cc -- internal to sourcefile
-* declaration for monstuff::simple_monster_message() moved from atop monstuff.cc to monstuff.h as it is now used in other sourcefiles
-* declaration of spells4::cast_detect_magic() moved from spells4.h to atop spells4.cc and commented out, along with actual function -- not in current usage
-* declaration of spells4::cast_eringyas_surprising_bouquet() moved from spells4.h to atop spells4.cc and commented out, along with actual function -- not in current usage
-* declaration of spells4::cast_summon_serpents() moved from spells4.h to atop spells4.cc and commented out, along with actual function -- not in current usage
-* declaration of spells4::do_monster_rot() moved from spells4.h to atop spells4.cc and commented out, along with actual function -- not in current usage
-* declaration of spells4::make_a_random_cloud() moved from spells4.h to atop spells4.cc
-* declaration of spells4::make_a_rot_cloud() moved from spells4.h to atop spells4.cc
-* definition of monstuff::handle_special_ability() added atop monstuff.cc -- no idea why it was not there already
-* definition of religion::divine_retribution() moved from religion.h to atop religion.cc
-* dungeon::item_in_shop() returns unsigned char instead of char, and takes unsigned char instead of char as sole parameter
-* dungeon::items() takes unsigned char instead of int for second and third parameters
-* dungeon::place_spec_shop() takes unsigned char instead of char for all three parameters
-* dungeon::plan_1() returns unsigned char instead of char
-* dungeon::plan_2() returns unsigned char instead of char
-* dungeon::plan_4() returns unsigned char instead of char
-* dungeon::plan_5() returns unsigned char instead of char
-* effects::direct_effect() now takes struct bolt * instead of struct bolt[] as parameter
-* effects::mons_direct_effect() now takes struct bolt * instead of struct bolt[] as first parameter
-* eliminated default parameter for spells3::cast_selective_amnesia()
-* enum: MUT_LAST_MUT reverted back to NUM_MUTATIONS ... to me, it is clearer to use NUM_foo rather than the particular enum prefix, as it denotes clearly that *this is not really a member of the enum, but rather a description of them* also for cases where LAST is not really last (see MONSTER_CATEGORIES), also removed related #define
-* enum: SPTYP_LAST -> NUM_SPELL_TYPES
-* enum: added SPTYP_RANDOM for use in spells::miscast_effect() -- I'd like to set to 255, but don't know how many things need to be switched to unsigned char to do so
-* enum: added SPWLD_PRUNE, SPWLD_HUM, SPWLD_CHIME, SPWLD_BECKON, SPWLD_SHOUT as per it_use3::special_wielded()
-* enumery and clean-up
-* enumery in describe.cc
-* enummed MH_foo where appropriate and changed inequalities to equivalence tests
-* etc. etc. on the messaging bugfixes
-* f(x): added food::hunger_warning() to break-out functionality from acr::input
-* f(x): spells::miscast_effect() returns bool instead of char
-* fight::jelly_divide() takes struct monsters * instead of int as parameter
-* fight::monster_die() takes struct monsters * instead of int as first parameter
-* fight::monster_polymorph() now returns bool -- whether the polymorphing took place or not -- needs to be more rigorous in determation of return value, though
-* fight::monster_polymorph() takes struct monsters * instead of int for first parameter
-* fight::place_monster_corpse() takes struct monsters * instead of int as parameter
-* fight::place_monster_corpse() takes struct monsters * instead of unsigned char as parameter
-* figured out proper inclusions for spells4.h throughout codebase
-* figured out proper places to #include items.h
-* files::find_spell() returns bool instead of char
-* files::load() now takes bool instead of char for 2nd, 3rd, 5th and 6th parameters
-* files::save_game() takes bool instead of char for only parameter
-* files::save_level() now takes bool instead of char for 2nd parameter
-* filpped first and second parameters to beam::check_mons_resists() -- makes more sense
-* finished putting in new spell struct, see spl-util.cc/.h and spl-data.h
-* first parameter to bang::explosion() renamed from ex_size to is5x5 to denote properly what it means -- changed to bool (as the f(x) only does 3x3 and 5x5 explosions now)
-* first two parameters to beam::mons_ench_f2() replaced by a single parameter of type struct monsters *
-* fixed a bug in dungeon::item_colour() which was not colouring namwed weapons properly
-* fully ifdef'd anything relating to elvish glamour
-* general clean-up
-* general clean-up
-* general clean-up
-* general clean-up
-* general clean-up
-* general clean-up
-* general clean-up -- trying to rid the codebase of goto statements here and there
-* general clean-up and enumery
-* general clean-up and enumery
-* general clean-up and enummery -- starting to unravel dungeon::give_item()
-* general clean-up and optimization in dungeon.cc -- starting to unravel the mysteries of dungeon.cc and all its glory!
-* general clean-up in monstuff.cc --> don't bother to strcpy()/strcat() if final mpr() dependent upon mons_near() -- *all* operations dependent on mons_near(), then !!!
-* general clean-up of religion.cc
-* general clean-up, mostly in dungeon.cc
-* general cleanup
-* general cleanup and enumery
-* general fixing of messaging for invisibility checks
-* general: indentation and enumming
-* global "int diag_door = 0" in dungeon.cc deleted -- only used and set within dungeon::make_room()
-* global "int max_doors" in dungeon.cc moved to atop dungeon::builder() -- only passed between builder() and make_room() -- which now takes an int [max_doors] and not "void" as parameter
-* global int band and band_no moved into dungeon::place_monster() -- only used within that function, near as I can tell
-* global int dir_x2 and dir_y2 moved into dungeon::make_trail() -- only used within that function near as I can tell
-* global int no_rooms moved into dungeon::builder() -- only used within that function near as I can tell
-* global int roomsize moved into dungeon::builder() -- only used within that function near as I can tell
-* global int x_start and y_start moved into dungeon::builder() -- only used within that function near as I can tell
-* global ints cx and cy in dungeon.cc moved into dungeon::specr_2(), only used there
-* global ints dx and dy in dungeon.cc moved into dungeon::specr_2(), only used there
-* global ints sx and sy in dungeon.cc moved into dungeon::specr_2(), only used there
-* got rid of the MLAVAfoo defines
-* got rid of the MWATERfoo defines
-* had to un-#ifdef the DEBRIS enum ... I want it gone, goddamn it!!!
-* heavy_armour modifier in fight::you_attack() for large species using large shields fixed at +1, and not potentially +3 -- reasoning that id ARM_SHIELD is +1 regardless for all races, ARM_LARGE_SHIELD should be equivalent modifier for large races (SHIELD :: SPECIES as LARGE_SHIELD :: LARGE_SPECIES), and besides, on average, large and regular/small species were getting the same modifier on use of large shields, which did not seem fair.
-* implemented newgame::give_last_paycheck()
-* implemented newgame::jobs_stat_init()
-* implemented wrapper f(x) religion::simple_god_message()
-* in monstuff:handle_wand() - monsters will no longer zap themselves with wand of invisibility if player can see invisible -- a cheat, I know, but every bit helps
-* invent::list_commands() now takes bool instead of int
-* it_use2:: zapping() <---> zappy() relationship worked out, parameters passed between them have changed
-* it_use2::zapping() now takes struct bolt * instead of struct bolt[] as last parameter
-* it_use2::zappy() made static
-* it_use3::ball_of_energy() made static
-* it_use3::ball_of_fixation() made static
-* it_use3::ball_of_seeing() made static
-* it_use3::box_of_beasts() made static
-* it_use3::disc_of_storms() made static
-* it_use3::efreet_flask() made static
-* it_use3::staff_spell() made static
-* item_use::eat_food() -> food::eat_food() -- just so I can keep everything together wrt food thingees
-* item_use::throw_it() made static
-* item_use::throw_it() takes struct bolt * instead of struct bolt[] as first parameter
-* itemname::is_a_vowel() now returns bool instead of char
-* items::conv_letter() -> stuff::letter_to_index() -- more descriptive of actual function, stuff more central for now
-* made global char is_a_specroom in dungeon.cc into a static variable -- not utilized outside this file
-* made global char oblique in dungeon.cc into a static variable -- not utilized outside this file
-* made global char oblique_max in dungeon.cc into a static variable -- not utilized outside this file
-* made global int bno_mons in dungeon.cc into a static variable -- not utilized outside this file
-* made global int corrlength in dungeon.cc into a static variable -- not utilized outside this file
-* made global int finish in dungeon.cc into a static variable -- not utilized outside this file
-* made global int intersect_chance in dungeon.cc into a static variable -- not utilized outside this file
-* made global int no_corr in dungeon.cc into a static variable -- not utilized outside this file
-* made global int time_run in dungeon.cc into a static variable -- not utilized outside this file
-* made global ints room_x1 and room_x2 in dungeon.cc into static variables -- not utilized outside this file
-* made global ints room_y1 and room_y2 in dungeon.cc into static variables -- not utilized outside this file
-* made global ints vsx and vsy in dungeon.cc into static variables -- not utilized outside this file
-* made global ints x_ps and y_ps in dungeon.cc into static variables -- not utilized outside this file
-* made several functions in mons_lev.cc static
-* made spells4:::yesno() accept lower-case responses, too
-* maintenance: removed curly-braces at end of lines to indented beginning of next line, as per coding standard
-* mass enumery of m_list.h and reformatting for legibility
-* minor bugfix in dungeon::items() -- demon tridents apparently forgotten in initial conditional to set special enchantments on weapons -- esp. given that they are singled out later in a nested conditional, added back in to parent conditional
-* minor bugfix in dungeon::items() -- many_many was being set from 351 to 200 when determing weapon specials, but a subsequent conditional was still relying on the value of 351, meaning fewer special weapons than the algortihm intended
-* minor bugix: reading scroll of summoning will only message if the creature actually appears
-* minor clean-up of dungeon::labyrinth_level()
-* minor tweak - fight::monster_polymorph() will no longer allow monsters to polymorph "in place" -- i.e. to the same type as they already are
-* minor tweak -- wand_id for polymorphing now dependent upon outcome of monster_polymorph()
-* minor tweak: monsters that drain hps and heal beyond current max hp will gain +1 max_hp in some circumstances {just to make things a bit more interesting}
-* misc::dart_trap() made static
-* misc::dart_trap() takes struct bolt * instead of struct bolt[] as first parameter
-* misc::itrap() takes struct bolt * instead of struct bolt[] as first parameter
-* misc::manage_clouds() now returns void instead of int -- since env.foo is externed, no need to pass back integer value to acr.cc
-* misc::manage_clouds() rewritten slightly to clarify logic of function
-* misc::trap_item() returns bool instead of int
-* mon-util::mon_init() scrapped and replaced by mon-util::mons_colour() -- let's see what the slowdown is
-* mon-util::mons_pan() -> mon-pick::mons_pan()
-* monstuff::distance() -> stuff::distance()
-* monstuff::handle_behavior() now takes struct monsters * instead of int as only parameter
-* monstuff::handle_enchantment() takes struct monsters * instead of int as parameter
-* monstuff::handle_movement() takes struct monsters * instead of int as parameter
-* monstuff::handle_nearby_ability() takes struct monsters * instead of int as parameter
-* monstuff::handle_potion() takes struct monsters * instead of int as parameter
-* monstuff::handle_reaching() takes struct monsters * instead of int as parameter
-* monstuff::handle_scroll() takes struct monsters * instead of int as parameter
-* monstuff::handle_special_ability() takes struct monsters * instead of int as parameter
-* monstuff::handle_spell() takes struct monsters * instead of int as parameter
-* monstuff::handle_throw() takes struct monsters * instead of int as parameter
-* monstuff::mons_in_cloud() now takes struct monsters * instead of int as parameter
-* monstuff::mons_pickup() made static monstuff.cc for the time being
-* monstuff::mons_pickup() returns bool instead of char -- it never returns anything other than false, is this intentional?
-* monstuff::mons_pickup() takes struct monsters * instead of int as parameter
-* monstuff::monster_blink() takes struct monsters * instead of int as parameter
-* monstuff::monster_habitat() takes struct monsters * instead of int as parameter -- had to create monplace::monster_habitat_2() as a workaround for one case for the time being
-* monstuff::monster_move() made static monstuff.cc for the time being
-* monstuff::monster_speaks() made static to monstuff.cc for the time being
-* monstuff::monster_speaks() takes struct monsters * instead of int as parameter
-* monstuff::plant_spit() now takes struct bolt * instead of struct bolt[] as only parameter
-* monstuff::plant_spit() takes struct monsters * instead of int as parameter
-* monstuff::print_wounds() now takes struct monsters * instead of int as parameter
-* monstuff::simple_monster_message() no longer requires first parameter, so it has been dropped
-* monstuff::simple_monster_message() returns bool intead of void to permit testing and outputting of alternate message <not implemented yet>
-* monstuff::swap_places() takes struct monsters * instead of int as parameter
-* monstuff:mons_in_cloud() and monstuff:plant_spit() made static to monstuff.cc for now
-* monstuff:monster() -- commented all lines having to do with variable no_mons -- it was initialized, decremented, and incremented, but never applied in the codebase
-* monstuff:monster_regenerates(foo) removed in favor of monstuff::monster_descriptor(foo, MDSC_REGENERATES)
-* more clean-up
-* more general clean-up
-* more general clean-up
-* more messaging fixes
-* more work toward completing determination of proper #includes for each file
-* moved enum DEBRIS from enum.h to atop spells4.cc -- not well-implemented yet, so buried there instead
-* moved some things from skills::exercise2() into skills::exercise() -- function could probably be folded in together, given the set value of deg ...
-* moved the #ifdef inside of spells4::silence() to clarify that it all applies to a single function
-* moved the FEATURE enum from overmap.h to atop overmap.cc -- no need to open it to use outside the file
-* mstuff2::dragon() now takes struct bolt * instead of struct bolt[] as second parameter
-* mstuff2::dragon() takes struct monsters * instead of int as parameter
-* mstuff2::mons_cast() takes struct bolt * instead of struct bolt[] as second parameter
-* mstuff2::mons_cast() takes struct monsters * instead of int as first parameter
-* mstuff2::mons_throw() takes struct bolt * instead of struct bolt[] as second parameter
-* mstuff2::mons_throw() takes struct monsters * instead of int as first parameter
-* mstuff2::mons_trap() takes struct monsters * instead of int as first parameter
-* mstuff2::monster_teleport() now takes struct monstes * instead of int as first parameter
-* mstuff2::spore_goes_pop() takes struct monsters * instead of int as parameter
-* much cleanup and compaction of religion.cc
-* newgame::new_game() now returns bool instead of char
-* optimization: some optimization of it_use3::special_wielded()
-* optimized mon-util::seekmonster() but odd things are happening (monsters on level 1 don't awaken and missiles may now appear to go through walls)
-* player::forget_map() takes unsigned char instead of char for sole parameter
-* player::how_hungered() -> food::how_hungered() added appropriate #include atop it_use2.cc
-* player::increase_stats() now can increase by more than one by adding a a third parameter for amount of increase
-* player::reset_hp() pulled in favor of more flexible player::set_hp()
-* player::species_name() takes unsigned char instead of char to match you.species
-* player::you_are_draconian() -> player::player_genus(), now uses switch (don't use comparatives!) and broadened to cover other cases
-* possible bugfix: fight::monster_polymorph() - first two parameters were of type unsigned char when they should have been of type int (MONS_foo definitely falls outside range [0,255]) -- also double-checked types of old_foo variables used within the function itself
-* propagated effects::lose_stat() throughout codebase
-* propagation of silenced() to cover instances of "You hear ..." messages << bang.cc -
-* pulled out all the code relating to MONS_TUNNELING_WORM and MONS_WORM_TAIL -- haphazard and deprecated (monster never appeared)
-* pulled out all the code relating to the QUOKKA, SWORD, GUARDIAN ROBOT, and DORGI -- all were deprecated a long time ago
-* recoded dungeon::special_room() for efficiency -- was filling monster arrays on each and every loop-through (sheesh!)
-* recoded monplace::mons_place() to do away with way too many calls to random2() in order to generate random nasty for dungeoneers heading downwards
-* recoded monplace::summon_any_demon() to make types more apparent and to remove calls to stuff::table_lookup()
-* recoded monstuff::print_wounds() for clarity of logic flow, got rid of that damn goto statement
-* religion::Xom_acts() now takes bool for first and third parameters
-* religion::god_name_long() commented out (but left intact) -- as jmf flagged, this function is not in use within the codebase
-* religion::god_name_long() struck from codebase -- relevant salvaged information now conveyed through comments
-* religion::god_speaks() no longer has a default parameter value -- confusing use of GOD_foo enum as it was
-* religion::naughty() now ordered by deity then by naughty -- makes more sense to be able to see naughty by deity rather than deity response by naughty
-* removed Isk's Cross garbage from spell::your_spells() -- no longer a spell, had been replaced by Symbol of Torment
-* removed MS_ZULZER -- only used by Dorgi ...
-* removed some useless typedefs from atop mon-util.h and randart.cc
-* removed the "guarantee knife" code in dungeon::builder() as per brent's suggestion
-* rename mons_lev -> mon-pick
-* renamed ability -> ply-abil
-* renamed levels -> lev-pand
-* renamed m_list -> mon-list
-* renamed mstruct -> mon-util
-* replaced C_foo defines with appropriate CE_foo enums
-* replaced H_foo defines with appropriate MH_foo enums
-* restructured monplace::create_monster() to get rid of the silly goto statements and clarify program flow
-* reversed the parameters passed to player::slaying_bonus() to align with PWPN_foo and applied enum function calls
-* rewrote a lot of ability.cc
-* rewrote effects::lose_stat() to be a bit more robust and now player_sust_abil() no longer fullproof protection against stat loss
-* ripped out mstruct::def_letters() -- no longer in use anywhere in the codebase
-* second parameter passed to ouch is now int instead of char -- typical of source code that it should be int and not anything else, as it refers to menv[foo]
-* set wield_change to a single type (it was used as a char, unsigned char, and int all over the place) -- I decided to make it type bool for clarity
-* shifted MH_foo and H_foo flags up one to start at 0 and include MH_HOLY at start -- should not be problematic
-* shopping::clear_line() removed entirely -- did not do anything but return upon being called
-* simple_monster_message() propagated throughout codebase
-* skills2::best_skill() now takes unsigned char instead of char for all three parameters -- it also now returns unsigned char instead of char
-* skills2::calc_ep() -> calc_mp() -- I always think of experience and not magic points when I see the f(x) - you.redraw_magic_points moved into f(x) and duplicate settings removed from codebase
-* skills2::skill_name() takes unsigned char instead of char for sole parameter
-* skills2::skill_title() no longer takes you.char_class as third parameter -- available globally and no longer utilized within the f(x) itself
-* skills2::skill_title() no longer takes you.experience_level as fourth parameter -- not utilized at all within function, meaningless pass
-* skills2::skill_title() takes unsigned char instead of char for its two remaining parameters
-* skills::exercise2() made static
-* some enumeration work
-* some enumery
-* some enumery and housekkeeping
-* some enummery and clean-up in files.cc
-* some fixing up in dungeon::item() -- knive will no longer be quite so common in the deeper parts of the dungeon (minor bugfix/tweak)
-* some general clean-up
-* some general clean-up
-* some more general cleanup
-* some restructuring of newgame.cc to clarify what is being done
-* spell::exercise_spell() second and third params now bool not int
-* spell::surge_power() made static
-* spell::your_spells() returns bool instead of char, third parameter (allow_fail) now bool not char
-* spellbook::spellbook_contents() returned unsigned char instead of char
-* spellbook_contents() declaration moved from spellbook.h to atop spellbook.cc - native only to file
-* spells0::spell_hunger() now takes only the first parameter - second parameter not used in function
-* spells0::spell_spec() no longer takes a second parameter -- it was never used !!!
-* spells1::identify() now takes a power parameter (currently unused) and a value of -1 flags it as coming from an item (in this case, a scroll)
-* spells1::spell_direction() takes struct bolt * instead of struct bolt[] as last parameter
-* spells2::manage_shock_shield() -> spells1::manage_shock_shield() and definition moved from spells2.h to spells1.h -- better fit here
-* spells2::restore_foo() [three functions] rolled into spells2::restore_stat() -- permits restoration of STAT_RANDOM now, which may be useful at some future point
-* spells2::summon_butter() -> effects::summon_butter() and definition moved from spells2.h to atop effects.cc (only used here)
-* spells3::aistrike() now returns a success value
-* spells3::cast_bone_shards() now returns a success value
-* spells3::cast_smiting() now returns a success value
-* spells3::create_noise() now returns a success value
-* spells3::create_noise2() renamed to spells3::create_noise() -- what happened to the other function?
-* spells3::death_channel() now returns a success value
-* spells3::entomb() now returns a success value
-* spells3::monster_on_level() made static
-* spells3::recall() now returns a [apparent] success value
-* spells4::cast_summon_large_mammal() -> summon_large_mammal()
-* spells4::cast_warp_brand() deleted -- does not conform to existing usage of brands in spell.cc
-* spells4::drop_everything() -> transfor::drop_everything(), declaration moved from spells4.h to atop transfor.cc -- only used here (for now), so just move it there, already
-* spells4::silenced() -> stuff::silenced()
-* spells4::yesno() -> stuff::yesno() <need to check includes again>
-* standardized somewhat the ordering of ability evaluation and effects when used in abilities.cc to make editing easier
-* started cleaning up maps.cc -- made everything static, moved old, unused vault maps to "unused" folder
-* started newgame.cc cleanup
-* started rectifying the global vars in dungeon.cc: int's rannum, randnum, & q deleted - border_type moved into builder() - lev_mons moved into place_monster() and special_room() - passout moved to place_monster() - char dung1 & dung2 deleted, set to random2(100) each in builder() but never used beyond that - skipped moved to builder()
-* starting clearing out oddball global variables in spellbook.cc: int's i, sc_read_1, sc_read_2; unsigned char keyin
-* stuff::magic_ability() folded into player::player_mag_abil() and the latter function now takes parameter as to whether or not to weight value by intelligence
-* stuff::magic_ability() no longer takes a second parameter
-* stuff::output_value() struck from the codebase -- not used anywhere
-* stuff::table_lookup() yanked -- I think I was trying to swat a fly with a sledgehammer originally
-* too much time spent cleaning-up ouch::item_corrode() but recoded nonetheless
-* tweak(minor) - jellies may now split upon eating secret / closed doors, and the types of jellies that do has been expanded
-* tweak/bugfix: airstriking your own tile causes spell to fizzle
-* tweak: all draconians now get a 20% lowering on breath failures if transformed into dragons -- should not affect much, as failure rates are already pretty low.
-* tweak: blinking in the abyss is a bit more difficult -- reordered the conditionals in spells1::blink() to place barring of teleport in abyss prior to merely interfering with it
-* tweak: in religion::pray() sustenance is now only provided by ZIN and ZIN only, as per discussion on onelist
-* tweak: it_use3::ball_of_seeing() and it_use3::ball_of_energy() now flow to confusion case from drain mana case when invoker has no mana at time of invocation
-* tweak: monstuff::handle_behavior() now picks a new target tile for BEH_WANDER that is within "normal" bounds of dungeon (10 to GfooM-11 instead of 0 to GfooM-1) -- wonder if it will keep monsters more to center
-* tweak: spells3::detect_curse() take a bool parameter and returns a bool signifying success -- scrolls of detect curse no longer ID if no curses detected
-* tweak: spells3::remove_curse() take a bool parameter and returns a bool signifying success -- scrolls of remove curse no longer ID if no curses removed
-* updated VERSION and BUILD_DATE
-* variable "char already" struck from ability:show_abilities() -- initialized to zero and never used
-* view::mons_near(int) replaced with view::mons_near(struct monsters *) and applied throughout codebase -- should not be a problem
-* which also means that skills2::add_skill() was pulled, meaning that the definition of the function in skills2.h had to be pulled (now why wasn't *that* #ifdef'd, I ask?)
-
-
-*** SOME OF THE THINGS SINCE THE TESTDEV RELEASE ***
-
-* fixed typo concerning Chaos Knights [josh]
-* added in macro definitions to replace the ENUMS for SPLFOOD SPLMANA and SPLEVEL [brent]
-* stuff::yesno() fixed to take uppercase only, also now clears message screen and reprints query [josh]
-* SPELL_POISON_CLOUD now has the correct associated types [POISON/CONJURATION/AIR] [brent]
-* SPELL_MEPHITIC_CLOUD now has the correct associated types [POISON/CONJURATION/AIR] [josh]
-* bugfixes: some fixes noted by Jesse were applied -- and then even more fixes noted by Jesse were applied
-* all tabs removed from the sources
-* bugfixes: more fixes noted by Jesse in re: array indexing
-* bugfix (potential): ghoul rotting separated out from regular rotting, preventing negative you.rotting value from arising
-* "You smell ..." messages now take into account the fact that mummies cannot smell -- except for a couple mutations and a random demon description
-* added enum SPECIAL_MISSILES to separate out weapon and missile specials
-* bugfix: players resistant to poison eating poisonous chunks will no longer get diseased, unless chunk is rotting
-* bugfix: amulet of gourmand now works as described, and will work to the benefit of both normal species and ghouls
-* added food::lessen_hunger() and food::set_hunger() and some other routines, which led to ...
-* reworked food.cc
-* bugfix: ghouls will no longer become "full"
-* bugfix: summon_small_mammals() will now summon at least one creature [Daniel]
-* minor messaging tweaks here and there
-* killed monster_habitat_2() and reverted monster_habitat() to take int instead of pointer to monster struct
-* added in Jesse's Mac-specific files
-* borrowed a couple tweaks from Gordon
-* fixed a few minor things in spells4.cc and added some small annotations
-
diff --git a/stone_soup/crawl-ref/docs/todo.txt b/stone_soup/crawl-ref/docs/todo.txt
deleted file mode 100644
index 6974ecff3b..0000000000
--- a/stone_soup/crawl-ref/docs/todo.txt
+++ /dev/null
@@ -1,456 +0,0 @@
-Enhancements:
-
-* make screen update correctly when player vision is <2.
-
-* Make dangerous things be shown on top of a stack. This includes traps,
- walls of fire, etc.
-
-* Make food acquirement give you more kinds of food.
-
-* file locking for the high score file
-
-* adjust EV for low levels.
-
-* repopulate levels on the way out
-
-* should species armour bonus work on EV instead of AC?
-
-* make rings of fire/ice (and others?) auto identify with use
-
-* miscast effects too weak? Not enough of a threat, especially when used
- by gods, Zot traps, or mummies as a form of punishment.
-
-* add toggled stealthy mode?
-
-* print out '@' status in character dumps (might be nice to have the
- chacters status in the dump... method of death might be good as well).
-
-* fix green crystal room so its not boring (pretty vault, just no real
- point to it currently)
-
-* fix the summoning abuse problem properly. Ideally, the player should
- not get piety for killing things he summoned, but should get piety
- for things that are summoned against him.
-
-* Add a wizard debugging function to output several thousand items for
- a particular depth (should make item frequency tuning easier).
-
-* Perhaps races should be physically "described" (stucture or bit
- fields) to keep track of their size and physical body parts that
- interfer with armour. This could also be used in other ways...
- small races could be harder to hit with ranged weapons
- than larger ones, but the larger races might get a bonus
- to carrying capacity... could also probably simplify the
- extra unarmed combat attacks code
-
-* Speaking of the character info, I really like that Linley now displays
- the weapon being wielded. We should think about displaying all ten
- wielded/worn objects.
-
-* Need to make sure that ghost names will be OK when long player names
- are used.
-
-* Blink prompt is bogus (probably also happens elsewhere). Can probably
- fix this by adding a prompt argument to look_around.
-
-* Some of the more important messages should be in color?
-
-* The spores contaminate the food by exploding, only the
- > explosion effect should destroy food on the ground.
-
- Right. Maybe this should be implemented (it shouldn't be too
- hard; fiery explosions already destroy scrolls laying on the
- floor).
-
- One idea I had with contaminated food was to use the it_plus2
- variable (which IIRC is currently unused for all types of
- food) to store the number of items in a stack of food which
- are contaminated. Say you have a stack of 4 meat rations, if the
- plus2 value is 1 then one is bad, 3 are good. Any operations
- carried out on the stack (eating, dropping, picking up etc)
- have a 1 in 4 chance of taking the bad ration and 3/4 of
- taking the good. A quantum thing, sort of. Poisoned food could
- be done in the same way (if there are any variables left - dam?)
-
- This means that contaminated food doesn't just disappear, it
- stays around to haunt you.
-
- This could perhaps lead into a 'food' skill, which lets you
- cook food, get the most out of corpses, separate the good
- food from the bad etc.
-
-* Heavy armor doesn't offer enough protection?
- >The big problem is the strange evasion modifier calculation that
- >results in armour completely destroying your EV with the
- >double subtraction thing.
-
- I don't think this is so strange. It only affects chars who have
- high dodging skills, and it makes sense to me that dodging
- effectively and wearing heavy armour should be mutually
- exclusive unless you're used to wearing heavy armour, in which
- case the evasion penalty is reduced according to your armour
- skill and the dodging skill (which can only be picked up when
- you're wearing light or no armour) is usually ignored.
-
- I did it this way so that the two skills (dodging and armour)
- would rarely both be useful at the same time, so players would
- have to choose between them. Otherwise they could just practice
- both and everyone would end up the same.
-
- Personally, I think the double subtraction thing should be left
- in, but with the following changes to the way armour works:
- - base AC should be upped considerably, as discussed
- - the limit on the proportion of the evasion penalty removed by
- a high armour skill could be raised or scrapped (currently only
- half of the evasion penalty of a piece of body armour can be
- negated by the armour skill)
-
- I would have fixed these problems before I stopped working on the
- code myself, except that nobody ever complained about them and I
- didn't notice them myself.
-
- -- EV penalty now recovered faster, Armour skill slightly easier to
- get -- base ACs should probably still be upped (bwross)
-
-* New spell realms (Linley doesn't like these):
- NATURE - spells connected with some nature forces, animals and plants
-e.g. summon small mammal, summon scorpions, summon elemental, passwall,
-resist <element>, create plant/fungus, charm animal/plant and so on
-
- PROTECTION - protective spells - shield, resist sth., Fire/Ice armor,
-Deflect missiles... HEALING - Cure Light/Serious/Critical Wounds, Cure
-Disease, Neutralize/Slow Poison, Heal
-
-* DRUID class - with spells allowing him to summon animals & plants,
-charm them, also some to work with natural forces - eg. elementals,
-resist fire..., also some healing spells - neutralize poison etc...
-
-* Maybe some God of Nature, which offers to his believers some of Druid
- ablities
-
-* "write scroll" skill
-
-* Dagger of Backstabbing - hit and Damage bonus when you are backstabbing
-
-* purify food spell
-
-* create water/lava pool spell, also some monsters creating this kind
- of terrain
-
-* Some work needs to be done for multi-user environments.
- -- some done, more could be useful (bwross)
-
-* Targetting isn't intuitive enough?
- -- slightly improved (bwross)
-
-* Use gdbm to save games? However gdbm won't compensate for endian
- differences...
-
-* Use gdmn to save bones?
-
-* Use zlib to compress saved games?
-
-* larger windows
- -- number of lines is now handled more dynamically, but only at
- during init or compile time (depending on NUMBER_OF_LINES) (bwross)
-
-* multiple-windows
-
-* Use XML for monster definitions
-
-* Use XML for room layout/fixed levels
-
-* Use XML for item definitions?
-
-* moves[0], beam[0] should be simplified to use pointers to structs instead.
-
-* Locking to prevent multiple game loads/save file overwrites?
-
-* Allow access to the new longer high score files... add user id field (for
- multi-user systems).
-
-* Add DEC graphics support for non-IBM machines (like nethack).
-
-* Come up with a better save file system that will accomidate versions
- easily and involve (hopefully) one smaller file... instead of the
- large number of current files.
-
-* Add Food/Survival skill
-
-> (1) Cooking Food -- by far the most potential to unbalance the game.
->
-> Cooking food should probably cost a limited resource to use (fire
-> sources? -- some like spellcasting would be very powerful). It would
-> allow anyone to eat chunks of flesh, thus removing an advantage
-> that carnivores and gourmands have... so you probably don't want
-> to add other advantages like extended shelf life. The food value
-> of chunks of flesh would probably have to be made smaller to maintain
-> the food balance.
->
-> Maybe cooking should be an ability that's either granted by a god,
-> being a member of a race or class, or becomes available with a
-> certain (high) level of the Food skill (perhaps Survival is a better
-> encompassing name... it could potentially be used for other things
-> as well then).
->
-> (2) Butchery -- not much of a game unbalance.
->
-> This doesn't effect the game balance unless its made really powerful
-> (ie. I can get 6 chunks from a bat). Right now you can get a full
-> stomach off of any number of large monsters. A few extra chunks
-> doesn't count for much unless you can improve their shelf life.
->
-> (3) Detecting Bad Food -- depends
->
-> If Giant Spores secretly contaminate rations this could be an
-> important skill. Perhaps it could give you a slightly better
-> save on eating meat chunks (limiting the advantage of the
-> carnivore's save and to a lesser extent the "AotG). It could
-> also warn you about things like mutagenic and necrophage meat
-> (give you a yes/no prompt you wouldn't normally get).
-
-
-* New inventory/equip/drop system
-
->>> // > Makes a certain sense, but I can drop any number of the healing potions
->>> // > as one action that suggests a bit more care... also I could just drop
->>> // > all of my potions and that would take an action for each stack I had,
->>> // > whereas all it probably requires is me dropping my "potion sack" or
->>> // > dumping it out.
->>> // >
->>> // How about a compromise where you can hit d% to drop all your food,
->>> // or d! to drop all your potions, but if you want to discriminate you have
->>> // to do them individually?
->>>
->>> I'm wanting something a bit more featured like the nethack system (not
->>> the old traditional, but the newer ones). Bascia concept would be that
->>> I could either select via inventory slot letter, or optionally pull down
->>> an inventory browser/selector and select the items I want. Complete
->>> with options like "select all potions", "toggle all potions", "select all",
->>> and "unselect all" (for example).
->>>
->>> If you want to add aditional time for discrimination, you can do it
->>> Ragnarok style (I like the Ragnarok armour equip system) and have a
->>> counter on the top line (with a short list of commands) that tells the
->>> player how many turns the action will take. There are a few problems
->>> with calculating this value, because there are any number of ways
->>> I can select all potions and the value should be independant of
->>> which ever I choose to use.
->>
->> Well, it would seem that the time calculation should depend on the
->>final set of selected items rather than the steps taken to select them.
->>That would remove abiguity. We could generate a time based on the variety
->>of things dropped. So, if you were dropping potions, swords, rings, and
->>scrolls, it would take you much longer than to just drop your rings. It
->>might be worth it to let weight factor into drop speed as well.
->
->You don't want to get too complicated. There's a limit to the
->granularity here, as you probably don't want to have it taking a
->couple dozen actions to drop some equipment. A simple little
->penalty for dropping only part of a stack, or only some types
->of potions is probably enough of a change.
-
-
-* Options files
- -- must keep two distinct types of options and handle them separate:
- - ones that would be loaded from a "crawlrc" file and would effect
- the players characters in a general way.
- - ones selected during the game and would be carried between
- saves, but not to other characters the player is playing.
-
-* fix non-magical traps
- -- should have some number of "charges" for those that shoot items...
- these should be more dangerous as well.
- -- monsters should "learn" the traps of a level.
-
-> Could be done with a bit array (if there is a limit of 32 traps on
-> a level, that would be bonus... but it could be extended to more
-> for not too much trouble). That would take up little space, and
-> testing would be by simple boolean operators (to test if the monster
-> knows about trap X, you check (monster.traps & (1 << X))). We could
-> have the code test the line of sight from a trap everytime it is
-> activated, and set the appropriate bit of the array in any monster
-> within line of sight.
-
-
-* Revert/change the Elementalist spellbooks?
-
-> // >This brings up another little problem around here. People around
-> // >here weren't entirely happy about the change to the Elemental
-> // >Spellbooks in 3.30. For the most part its considered that the
-> // >elementalists are becoming less individual in flavour and that
-> // >they're now just slight variations of Fire. In particular (and
-> // >pertaining to this discussion), was the loss of levitation from
-> // >the Air book, which was considered a useful "Tensor's Disk" for
-> // >lifting stuff up stairs.
-> //
-> // I removed levitation because it no longer fit, and I didn't
-> // want to stretch air out to three books. As for the other changes,
-> // these were made because I thought the non-fire elements were too
-> // weak by far. Which spells in particular are problematic? (I'll
-> // try to write an explanation for the differences between the
-> // elements when I have a little more time)
->
-> Well, we didn't think the other elements were actually "weaker".
-> They're only weaker in combat potential -- Fire was all attack, the
-> others offered more utility and defensive abilities. There was
-> enough combat in the others to get you well into the midgame, at
-> which point you adapt to whatever books you find (its typically
-> quite hard to get the advanced versions of your magic discipline...
-> I remember how happy I was when I finally had a necromancer find
-> Unlife... my Paladin had a complete set of death books early on).
->
-> The main problem is that the elements were made too similar (we
-> really liked the fact that they all played quite different, it
-> was one of the things that made crawl really popular here).
->
-> For example, they all start with a slight variation of the same spell.
-> This means that they all start playing the same way, with the same
-> tactics. Before you could play Earth for the range attack, or Air for
-> the somewhat risky-yet-powerful Shock.
->
-> There's still a little varity left, but certain bits are gone. You
-> can't depend on getting summoning when you start with Ice, for
-> example. The Levitation spell is now only in the Enchantment book,
-> it used to be a something you could depend on as an Air mage (now
-> you have to hope to get the book of Sky, and that gets you Fly, which
-> is better, but is also a level four spell).
->
-> Earth had a little issue before (too many similar throwing spells),
-> but replacing Throw Pebble with Crush just makes it the same as the
-> other elements. Stone Arrow has always been better than Iron Bolt,
-> IMO... iron bolt just isn't effective enough to justify the extra
-> cost and difficulty... it requires really high skill levels to
-> be better. I would have rather seen Iron Bolt go, in favour of
-> something a bit more interesting (Earthquake, Pass Wall, Stair
-> Creation).
-
-* Improve running code
-
-* Carrion eating mutation
- -- like vegetarian and carnivore, only gives a preference for
- rotten meat. Progesses with level until the character
- can only effectively eat rotten food.
-
-* Add rumours/fortune cookies?
-
-* Improvements to the character dump
- -- is the current dump as verbose as wanted/too verbose?
- -- add spell failures to dump?
-
-* Change character for throwing weapons to '(' and small armour to '['.
- -- Problem: '(' is used for dancing weapons.
-
-* Put some limits of teleport/teleport control? Make it rarer?
-
-* Improve artefacts to compete better with Sword of Power? Improve
- non-sword weapons so they become more of a choice?
-
-* Currently possible to gain 0hp when gaining a level... should
- be safeguards added to make sure this is at least never negative,
- if not guaranteeing 1hp / level.
-
-* should be able to see contents of books in stores?
-
-* remove possibility of teleport control with the Blink spell (require
- the player to use the Control Blink spell instead).
-
-* merge the chardump spell listing code with the other spell listing code.
-
-* throw traces to target should coincide with line-of-sight better
-
-* item inscriptions
-
-* are crossbows correct? The other launchers seem to be adding their
- skill bonuses twice
-
-* The Throwing skill isn't particularly useful. You could use it for
- throwing daggers, axes, or spears but they don't stack and are
- heavy.
-
-* add some weapons/change weapon code so that non-swords are more of
- an option
-
- // >I was thinking that this might be a good way to increase the value of
- // >non-sword weapons.
- //
- // .. which probably needs to be done anyway. One or two
- // suggestions for new weapons which could help:
- //
- // - axe (just axe, no 'hand' or 'battle' there): this would be to
- // a hand axe what a long sword is to a short sword. Skills may
- // need to be adjusted (a new 'great axes' skill, covering the
- // two-handed axes? Or just condense the sword skills).
- // - Spiked flail: like a flail, but more damage and slightly
- // slower (heavier etc).
- // - Great flail/mace: two-handed versions.
-
- These would certainly help out a bit. The other weapon classes were
- lacking good intermediates. I don't think a "great axe" skill is
- required, removing "great swords" might be correct (although it
- does add a limiting factor on the power of swords). Having weapon
- skills where only one member of the class exists doesn't seem very
- worthwhile. Maybe fighting style skills could be used instead...
-
- - 'two handed weapons' could be a skill for all two handed weapons,
- it would be used in conjunction with the appropriate weapon skill.
-
- - 'shields' would cover "weapon and shield" style, maybe allowing
- for the possibility of offensive shield bashing.
-
- - 'unarmed combat' or 'fighting' could cover the cases where one
- or both hands are empty. Characters not using one of the other
- styles should be able to use unarmed strikes more often and
- more efficiently.
-
- Potentially, you could add a bastard sword to the game. Its hand and
- a half nature could put it in any of the above categories (if you
- have a shield, it would be the second... if not it could be either
- of the other two).
-
- Of course, adding new skills has its own problems... there is already a
- shortage of space on the skills screen.
-
- -- add special attacks to weapons and allow them to be accessed by the
- player via SHIFT-<move> onto an adjacent monster.
-
-- fix monster enchantments to have proper timeouts and a better structure
-
-- score file still gets messed up from time to time... should probably
- change the format into something that can be expanded and contains more
- information that might be printed (user id on multiuser systems, time, etc)
-
--- add checking for legal background colour (or just let it ignore the
- "bold" colours like it does now?)
-
--- change file formats and functions
- -- change score file format (see nethack for additional fields... also
- maybe a field for damage done by killing attack... could be used to
- spice up the death description (use final HP?))... also a userid
- field for MULTIUSER systems would be nice (to tell likenamed
- charcters apart and identify the player).
-
--- sort out spells into separate spl-* files based on type/skill
-
--- make all this you.inv_*, mitm/itm stuff the same instead of
- having conversions everywhere.
-
--- differentiate the good gods more
-
--- break up dungeon.cc more
-
--- a check floor for lava/water function
-
--- a simple "summon hostile unfriendly/random demon" spell with fewer params?
-
--- centralize the elemental resistance code into a single entry point that
- takes damage and type and does the appropriate things... some of the
- cases are notably special, so some extra damage cateogries might have
- to be created (ie. stepping/falling into lava is an instadeath for
- characters with negative fire resistance, but being hit with a lava
- bolt is only extra damage).
-
--- functions to check for specific equipment (ie reduce checks for "!= -1")
-
--- move ghost/demon array into a proper structure.
-
diff --git a/stone_soup/crawl-ref/docs/versions.txt b/stone_soup/crawl-ref/docs/versions.txt
deleted file mode 100644
index d7387c60ca..0000000000
--- a/stone_soup/crawl-ref/docs/versions.txt
+++ /dev/null
@@ -1,782 +0,0 @@
- Crawl Versions History
-
- The name after each bug is the person who found it and told me
- first. If you find a bug and for some reason don't want to be
- credited, just tell me on the bug report.
-
-First DevTeam Release: 3.40 [23.02.2000]
-
- This is an abbreviated list of changes. For the full list, see
- changes.340.
-
- Bug Fixes:
-
- * Fixed Abyss-related crash bug;
- * Should now be able to escape the Labyrinth; and
- * Players can no longer descend below the 27th level.
-
- Gameplay and Mechanics:
-
- * Implemented initfile (see init.txt for explanation of options);
- * Added autopickup option (see init.txt for details);
- * 'Easy Crawl' -- doors open when running or walking into them;
- * 'V' and 'v' commands swapped -- now examine object and version
- check, respectively;
- * "Over-map" added;
- * max hit points ceiling displayed when the player's max is down;
- * Information about character's experience pool added to main
- screen;
- * Implemented new equipment listing commands: ')', ']', and '"'; and
- * Removed halving of cost for spellcasting skills.
-
- Game (re-)Balancing:
-
- * Three runes (at least) required to enter Realm of Zot;
- * Killing creatures created friendly no longer generates xp;
- * Skill gain modified for better balance;
- * Backstabbing with daggers now much more effective;
- * Stealth is now much more effective (try playing thieves again!);
- * Resistances to electricity and poison no longer absolute;
- * Disarming traps may now trigger them;
- * Armor and evasion skills are more effective;
- * Great and triple swords now treated as long swords for purposes of
- skill (Great Swords skill removed); and
- * Berserk mode made more interesting:
- + Berserk counter decrements more quickly when not attacking;
- + Butchery no longer penalized, resets the penalty counter;
- + Eating no longer penalized, does not reset penalty counter;
- and
- + Added exhaustion counter to track berserk fatigue
-
- Monster Modifications:
-
- * Monster AI improved in various ways;
- * More info available when examining monsters and when their
- enchantments expire;
- * A few new low-level monsters added;
- * Ghosts inflict less damage, heal more quickly, and may teleport;
- and
- * Three 'silly' monsters (dorgi, sword, guardian robot) removed.
-
- Character Changes:
-
- * Stalkers, assassins, and venom mages now being with knowledge of
- Potions of Poison;
- * Spriggan assassins and stalkers now allowed;
- * Halfling assassins and warpers now allowed;
- * Horned characters may wear caps and hats;
- * Lessened penalty for use of large shields by giant races;
- * Rangers are now called hunters;
- * Assassins now begin with unarmed combat, stat modifiers for
- thieves and assassins reversed;
- * Altered stat modifiers for wizards, making them smarter than other
- spellcasters;
- * Rebalanced the Gladiator and Fighter classes;
- * Lowered the experience penalty for demonspawn characters;
- * Kobolds now receive a stat increase every five levels; and
- * Spriggans and Halflings now consume less food than before.
-
- Item Changes:
-
- * Hand-and-a-half weapons added -- bonus if no shield wielded;
- * Added weapons of reaching, permitting attacks two squares over;
- * Cekugob no longer confers resistances to fire and cold;
- * Worn cloaks no longer prevent donning/removal of body armor;
- * Amulet of maintain speed now the amulet of resist slowness; and
- * New weapon types: knife, axe, broad axe, spiked flail, great
- flail, great mace, trident, demon trident.
-
-
-
-3.31-pre [~28.04.1999]
-
- * An attempt to merge the Mac port with the DOS/Linux code.
-
-
-
-Linley's Last: 3.30 [30.03.1999]
-
- * All known bugs (a *huge* list) fixed;
- * Several spells added, mostly to make Earth, Ice, and Air magic
- viable in comparison to Fire;
- * Numerous rebalancings;
- * "Unrandom artefacts" added -- see the source files randart.cc and
- unrand.h for details (These are very easy for non-coders to add);
- * 'V' command made available in shops;
- * Crossbows upgraded;
- * Characters lacking magic skills cannot learn spells;
- * It's now possible to get level 1 Spellcasting just by reading
- scrolls; and
- * A whole heap of other stuff.
-
-
-
-3.20 [09.02.1999]
-
- * New races: Demonspawn, Ghoul and Kenku;
- * A new God, Yredemnul, and this one is a lot better than Nemelex,
- who has also been upgraded a bit) -- another option for Priests
- and Death Knights;
- * Changes to a few spells, and I finally got around to upgrading the
- crappy armour spells;
- * Heaps of the usual rebalancing and some new features; and
- * Many bugs found by Daniel Ligon and others fixed.
-
-
-
-3.11 [31.01.1999]
-
- * Fixed minor bugs; and
- * Tweaked the balance of the early levels and monsters.
-
-
-
-3.10 [27.01.1999]
-
- * New races: Spriggan and Minotaur;
- * Added a new and rather strange God;
- * Shallow water implemented;
- * An Invocations skill was added;
- * Invocations are generally much cheaper to use, especially in
- piety;
- * Random demons in Pandemonium;
- * Many, many new monsters and several items added;
- * New mutations;
- * Plenty of rebalancing done;
- * Chaos Knights now have a choice between Xom or Makhleb;
- * Centaurs have been toned down a lot (and now require more food);
- * Heaps of new minor features; and
- * Many bug fixes.
-
-
-
-3.02 [~04.01.1999]
-
- * Certain monsters' attacks upgraded and spells balanced, too;
- * Fixes the currently known about bugs and tweaks balance; and
- * Only one known bug remaining (an empty macro.txt file can cause a
- crash).
-
-
-
-3.01 [~01.01.1999]
-
- * Bugfix release: Version 3.0 was a little bug-ridden, including a
- small problem where stats were raised by wearing almost anything.
-
-
-
-3.0 [23.12.1998]
-
- * Fixes all known bugs (but unfortunately invalidates old save);
- * Lots of new dungeon features -- new monsters, items, etc.;
- * Random artefact armours, rings and amulets;
- * Two new races: centaur and demigod;
- * Three new classes: stalker, warper and monk;
- * Unarmed Combat skill added;
- * Ghosts upgraded -- they now remember a little more from past lives;
- * Various minor miscellaneous changes have been made -- for example,
- the 'x' command now describes items as well as monsters/dungeon
- features;
- * A new dungeon branch;
- * A new God to worship; and
- * Sam Jansen has reformatted several modules (including the horrible
- dungeon.cc), making them far easier to read and work with.
-
-
-
-2.95 [15.12.1998]
-
- * Fixed the bug in 2.94, by which reloading a level with a mapped
- arch on it crashed the game, has been fixed by saving all files in
- binary, rather than text, format;
- * Gives crusaders the full range of spells in their initial
- spellbook;
- * Species-skills table in skills2.cc has been converted to an array;
- * For source-readers, the horrible dungeon.cc module has been
- revised and reformatted by Sam Jansen; and
- * A Linux message output bug fixed by Robert Glowczynski.
-
-
-
-2.94 [09.12.1998]
-
- * All known bugs fixed (including, I hope, the notorious Item Link
- Error bug);
- * Several interface improvements;
- * Several rebalancings; and
- * File I/O rewritten by Alexey Guzeev -- it's now several times
- faster.
-
-
-
-2.93 [~23.11.1998]
-
- * Alexey Guzeev's OS/2 port integrated into the code; and
- * Many bugs fixed, and a few new features (mostly user interface).
-
-
-
-2.92 [??.??.????]
-
- * I think I forgot to release this version.
-
-
-
-2.91 [17.11.1998]
-
- * Bug fix version;
- * Trolls and Ogres can now choose the Berserker class;
- * Random artefacts are now a bit more common;
- * Shops contain better items; and
- * Source code should now compile properly under Linux (thanks to
- Svante).
-
-
-
-2.90 [13.11.1998]
-
- * Juho Snellman's macro-patch was added;
- * Random "artefact" weapons added -- these are special weapons with
- a wide range of possible abilities;
- * Several new items and monsters;
- * Hell and the Realm of Zot are now much nastier.
- * Considerable balance changes;
- * New dungeon formations;
- * The 'V' command now gives more specific information for weapons
- and armor;
- * 'Target previous monster' function is now a bit easier to use;
- * You can now command your servants to attack ('!' command); and
- * Bugs fixed.
-
-
-
-2.83 [31.10.1998]
-
- * Yet another bugfix release;
- * Some new monsters and items;
- * Reaver class added; and
- * The Dungeon is again only 27 levels deep.
-
-
-
-2.82 [24.10.1998]
-
- * Another bugfix release; and
- * Adds some new user-interface features.
-
-
-
-2.81 [20.10.1998]
-
- * Bugfix release.
-
-
-
-2.80 [18.10.1998]
-
- * New species: Draconian (yes, I have been playing too much
- Zangband!);
- * New classes: Healer, Chaos Knight, Transmuter;
- * New monsters, including some which make curse skulls look
- completely harmless;
- * Religions and altars -- there are 8 or 9 gods who you can worship,
- each of whom requires different forms of devotion and offer
- different advantages;
- * Greatly expanded Transmigration magic, including
- self-transformations;
- * Several new dungeon branches;
- * Necromantic weapons (draining, vampiric, etc) are now more
- effective;
- * Significant balance changes -- deep levels should be harder now;
- * Special abilities ordered in the new 'a' abilities menu;
- * New items, spells, monsters, etc. as usual; and
- * A number of bugs found in the source by Daniel Ligon were erased.
-
-
-
-2.72 [~02.10.1998]
-
- * Another bug fix version (there seem to be a lot of these); and
- * Still a couple more bugs from 2.71 to bash and the balance may
- have been a little on the easy side.
-
-
-
-2.71 [25.09.1998]
-
- * Bug fix version.
-
-
-
-2.70 [22.09.1998]
-
- Heaps of new features (I almost called this version 3.0):
-
- * New species to choose from: Ogre, Troll, Ogre Mage;
- * New class: Venom Mage;
- * Several huge branches (extra dungeons branching off from the main
- one), each containing special new monsters and terrifying vaults;
- * New winning conditions;
- * Player ghosts;
- * Mutations;
- * Many new items, spells, monsters;
- * Several bugfixes; and
- * ... a heap of other stuff.
-
-
-
-2.61 [06.09.1998]
-
- A bug fix version:
-
- * Levitation is no longer permanent;
- * Fixes dropping-worn-armour bug;
- * Fixes item destruction bug (when picking up an item from the
- middle or bottom of an item pile);
- * Fixes poison and sticky flame bugs (neither worked properly);
- * Fixes 'program bug' bug;
- * The recall message screen no longer crashes the game;
- * Paralysis works again;
- * Drained dexterity is now displayed properly;
- * Some essential files were accidentally omitted from the source
- distribution -- they have been replaced;
- * Something I forgot to mention for 2.60: most rings no longer use
- food -- check them with 'V' when identified; and
- * There is a 'little surprise in this release which gives an
- indication of what will be in the next big release'.
-
-
-
-2.60 [01.09.1998]
-
- The Source Code Clean-up is finally finished!
-
- * Functions have been split up into about 30 different modules,
- making coding *much* easier;
- * All functions are now available from any module;
- * An alternative display set for non-IBM graphics displays included
- (activate it with a -c command-line switch);
- * Several minor balancing changes were made; and
- * If the game crashes, you can continue from the last save (unless
- it crashed during saving). Your game is autosaved every time you
- climb stairs.
-
- A great number of interface changes were made, many of which were
- suggested by Eino Keskitalo and Jim Baranovich. These include:
-
- * The clumsy '^' untrap command has been replaced by a new use for
- the control key;
- * The character selection menus have been streamlined, with a new
- random option;
- * Shop displays are easier to read;
- * The old message display has been rendered readable;
- * It is now possible to reorder items and spells; and
- * Various other things.
-
-
-
-2.51 [18.05.1998]
-
- Purely a bug fix version:
-
- * Item 1 no longer turns green on saving;
- * *Hopefully* the horrible item bug has been permanently removed (at
- least parts of it have, anyway);
- * Repeatedly casting Deflect Missiles no longer causes problems;
- * Skill selection now works properly (there were some problems in
- 2.50); and
- * A couple of bugs in monster teleportation have been fixed.
-
-
-
-2.50 [03.05.1998]
-
- Changes made:
-
- * Character classes made much more relevant;
- * Class system is back, in a slightly different form. Characters now
- gain a certain amount of skills when the gain levels (depending on
- which class they are). The old system is still in place but
- advancement is slower with it;
- * New class: Death Knights;
- * Monsters can now use more kinds of items;
- * Heaps of items, monsters, spells etc added;
- * Naga and Gnome character species added;
- * Rings of teleport control now available;
- * Levitating across water or lava works properly now;
- * Shields are now much more effective;
- * All known manifestations of the horrible item bug have been
- tracked down and fixed (except for the apparently harmless
- items-turning-green thing); and
- * Et cetera.
-
-
-
-2.41 [~22.04.1998]
-
- Bugs fixed:
-
- * The game occasionally crashed in the iron city of Dis;
- * Gates out of pandemonium were too rare;
- * There were problems with saving and restoring magic points; and
- * The source code distribution was extremely confusing.
-
-
-
-2.40 [~19.04.1998]
-
- * Two new races: Kobolds and Mummies;
- * Five new classes: Four types of elementalist and a fighter/wizard
- [Crusader] class;
- * New skills -- elemental magic and traps and doors;
- * New spells to go with the new skills and a spell failure system;
- * Heaps of spells, items, and monsters added (as usual);
- * You now get 1/2 experience for monsters killed by tame monsters;
- and
- * A large part of the monster and skills code was rewritten and
- generally cleaned up by $pellbinder (Wladimir van der Laan).
-
-
-
-(2.33) 2.34 [~22.03.1998]
-
- * A crash bug and some problems with items should be fixed with this
- release; and
- * I forget right now, but these releases probably just fixed stuff.
-
-
-
-2.32 [~15.03.1998]
-
- * Even more cool stuff fixed;
- * Level files are now deleted properly under Windows 95;
- * Removed a bug which sometimes caused the dungeon generator to
- hang; and
- * Compiling no longer generates warnings.
-
-
-
-2.31 [~13.03.1998]
-
- * Lots of cool stuff fixed;
- * Fixes the problem with magic missiles and saves; and
- * Adds amulets and several new types of armour.
-
-
-
-2.30 [~11.03.1998]
-
- * Lots of cool stuff added;
- * New in this version is a character race system with ten races to
- choose from and a trove of new monsters and items; and
- * Character dump feature implemented in the last version has been
- fixed now so you'll be able to swamp the newsgroups and annoy the
- regulars with ritualistic weekly reports of your favourite
- adventurer.
-
-
-
-2.21 [~20.02.1998]
-
- * Various bugfixes and minor changes;
- * Added the ability to produce character dumps (popular with the
- newsgroup egocentrics); and
- * Among the usual bunch of fixes, characters now get the chance to
- disarm traps (especially thieves).
-
-
-
-2.20 [~15.02.1998]
-
- * Added a comprehensive skills system;
- * Angband-style vaults and unique monsters;
- * Fixed a few very minor bugs and added a vast number of new
- features, the Abyss, Pandemonium, etc.; and
- * Dungeon architecture is also a lot more varied.
-
-
-
-2.11 [~21.01.1998]
-
- * First Linux release, ported to Linux by Svante Gerhard;
- * Updated source tree allows for easier ports onto other Unix
- systems; and
- * The port will apparently also run on a Sun Sparc running SunOS.
-
-
-
-2.10 [30.12.1997]
-
- Sorry to all of the many people who've been sending me bug reports,
- but it's become too tricky to list all bugs and credit their
- finder. I'm just getting too much email, and my mail reader has a
- strange way of eating some messages and making them very difficult
- to find. So from now on, I'll just list some of the major bugs
- fixed and major features added:
-
- * A bug with wearing armour of fire/cold resistance was fixed;
- * The properties of several items and spells were tweaked a bit;
- * Specialist wizards were made even more powerful in their
- discipline;
- * The dungeon was made deeper (36 levels now), and lots of new
- monsters were added to fill in the deeper levels;
- * Several spells (mostly necromancy) were added;
- * The dungeon architecture is a bit more varied, especially as you
- get deeper; and
- * A warning was added to labyrinths ... among other things.
-
-
-
-2.03 [22.12.1997]
-
- This version fixes a few bugs, and puts back the floating point
- emulation which was missing from previous version 2 releases
- (Daniel Josef Dekok and someone else noticed this). It also removes
- the debugging code which was accidentally included. Bugs fixed:
-
- * Butterfly corpses were coloured black, making them invisible
- (Bridget Farace);
- * Shadow lanterns were also coloured black, and kept on working even
- after you unwielded them (Bridget Farace);
- * Items purchased from shops were not identified properly (Lord Gek,
- Timo Laitila);
- * Scrolls of Acquirement weren't being identified after being read;
- * When you got hit by a monster wielding a weapon of draining,
- events could become confusing (Timo Laitila);
- * Finally, the '5' key on the keypad works as a rest key (Timo
- Laitila); and
- * Names longer than 8 letters caused problems with saving and
- restoring games, especially in Windows 95 (Lord Gek and Timo
- Laitila).
-
- The following new features were also added:
-
- * When tame creatures kill monsters, you now get 1/3 xp (Howard
- Liu);
- * Orcish spellcasters have been downgraded a bit (lots of people
- recommended this);
- * Specialist wizards are now slightly more powerful in their
- specialisation, especially with magical staves (I can't find the
- usenet post which told me about this); and
- * ... A few other minor changes.
-
-
-
-2.02 [13.12.1997]
-
- I'm afraid that 2.01 didn't fully fix the bug in the shop code, but
- hopefully this version does. Just about the only differences
- between this version and 2.01 are:
-
- * Pressing 'r', 's', or 't' while in a shop really no longer crashes
- the game (Saradon and Bridget Farace);
- * If the scores file is not present, a new one is generated. I've
- stopped including a scores file in the distribution, so that you
- can unpack the zip file into your old crawl directory and keep on
- using the old score file; and
- * Save games should be compatible with 2.01.
-
-
-
-2.01 [12.12.1997]
-
- I had wanted version 2.0 to be a stable and bug-less release, but
- this was not to be. Anyway, 2.01 fixes these bugs:
-
- * Zapping a wand of polymorph at yourself caused problems (polymorph
- self hasn't been implemented anyway) (Saradon);
- * Polymorph other didn't work properly;
- * Choosing a non-existent item in a shop crashed the game (but only
- sometimes, which was why I didn't notice it) (Saradon);
- * Spell descriptions weren't working properly (Saradon);
- * Some messages were misspelt due to an indiscriminate
- search/replace (Adam Horowitz);
- * Detect curse didn't detect curses on unrecognised rings (this bug
- had been present right from version 1.0);
- * Sometimes, a special weapon in the hands of a monster would not
- function properly (watch out for creatures wielding weapons of
- draining!);
- * The use of the control key was not mentioned in the command list
- (it opens/closes doors, like in Angband); and
- * ... a few others (if I haven't credited someone, please tell me).
-
- Also, a few new things were added, as suggested by Saradon: A shout
- command ('!') to attract your followers (and enemies!), and better
- equipment for the enchanter. Also, you are now given a difficulty
- message and prompted when memorising spells, so you will know which
- spells you won't be able to cast reliably before you memorise them.
-
- * Scrolls of Acquirement create much better items; and
- * Enchanters now get a magical dagger/robe with which to start.
-
-
-
-2.0 [09.12.1997]
-
- There have been so many additions in this version that I'm not
- going to list them all, but here is a very incomplete list of bugs
- and things rectified:
-
- * Characters could cause an excessive amount of damage empty-handed
- (Bridget Farace);
- * Darts didn't fire properly when character not wielding anything
- (Bridget Farace);
- * Hand crossbows didn't work properly;
- * Fireballs always did the same amount of damage (0-27), regardless
- of who cast them and how powerful they were;
- * Going to Hell could have unexpected results due to an
- out-of-bounds reference to levels_exist[];
- * Permanent levels, which are saved when you leave, and to which you
- can later return;
- * Shops;
- * Several new character classes, including Rangers, Assassins,
- Summoners, etc.;
- * A more interesting Hell;
- * New creatures, items, and spells;
- * Written descriptions of every single item, spell, and monster in
- the game; and
- * Several bugs squashed.
-
-
-
-1.22 [~06.11.1997]
-
- * Fixes a minor bug with weapons of slay orc and brings back the old
- spell level system.
-
-
-
-1.21 [~03.11.1997]
-
- * Fixes a bug which caused problems with high-level spellcasting.
-
-
-
-1.2 [02.11.1997]
-
- * The monster and cloud location bits have been completely
- rewritten, a process which turned out to be rather easier than I
- thought it would be. The new system is much more flexible;
- * Monsters are now a bit more intelligent, especially in the way
- they treat clouds;
- * Several monsters have been added;
- * Several items and two new classes of items (Carrion and
- Miscellaneous) have been added;
- * Several spells, most of them necromantic, have been added;
- * The Gladiator, Necromancer, and Paladin classes have been added;
- * A spell type system has been implemented, and several new staves
- to specialise in particular types of magic have been added
- (conjuration, summoning etc.);
- * New unique items have been added, and a bug (actually, a mistype)
- which prevented some from being generated has been removed;
- * A few bugs have been removed; and
- * Several other changes have been made, too numerous to mention
- here.
-
-
-
-1.10 [14.10.1997]
-
- * Several new items and monsters were added;
- * Labyrinths were added;
- * Magical weapons are now less powerful;
- * Some bugs have been fixed -- I forget what they were right now;
- and
- * The source was released, and Crawl is now under the GPL (see
- Licence.txt for details).
-
-
-
-1.05 [07.10.1997]
-
- * A minor display bug was fixed;
- * A bug with restoring clouds from saved games was fixed;
- * A major bug which caused a segment violation when restoring saved
- games if there were any magical traps on the level was finally
- discovered and fixed;
- * Those pathetic worms you see around level 6 are now nastier, and
- jackals now tend to appear in packs; and
- * This time, your item memory really does work.
-
-
-
-1.04 [06.10.1997]
-
- * A few really nasty bugs with saved games were fixed. The game
- would not save enchantments affecting monsters, and would mess up
- the items carried by the monsters (Adam Horowitz);
- * A bug with the enchanting/corroding of shields was fixed;
- * A '<=' instead of a '<' led to characters not using shields
- occasionally blocking trap missiles (Adam Horowitz);
- * You can now type '+' or '-' in the map screen to move around
- faster (Adam Horowitz);
- * The direction function now accepts '.' as well as delete (Adam
- Horowitz);
- * During your first step while long-walking, you can walk on
- anything (still prompts for water, etc., though) (Adam Horowitz);
- and
- * I think that was all.
-
-
-
-1.03 [04.10.1997]
-
- * Some unique items were added;
- * A silly bug, by which your item knowledge was not saved, was fixed
- (Darren Hebden);
- * Teleport traps now work properly; and
- * I think I fixed another bug, but I can't remember.
-
-
-
-1.02 [04.10.1997]
-
- * A few more items and traps have been added;
- * The game now uses the rogue keys (hjklyubn) properly; and
- * You used to be able to throw and zap straight when confused. No
- longer!
-
-
-
-1.01 [03.10.1997]
-
- * Shields were changed;
- * Items were made more common;
- * Monsters were made less common (this was a bug);
- * Cursed weapons were made less common (this was just bad planning);
- and
- * I changed the name to make it a bit less egotistical.
-
- Bugs removed include:
-
- * A debugging feature of the 'x' command was unintentionally left
- in;
- * The summon scorpions spell summoned a vampire (oops) (Haran
- Pilpel);
- * Sometimes +50 armour could be generated (oops again) (Haran
- Pilpel);
- * The inventory item counter was not decremented when you dropped
- something! This would lead to you being unable to pick things up
- after a while (Darren Hebden);
- * A bug with detect curse scrolls (Darren Hebden);
- * Slime creatures and jellies were a bit weak;
- * Killing normal (not spitting) plants gave you far too much xp;
- * Your rate of regeneration was not saved properly;
- * About half of the rings could never be generated;
- * The 's' command would sometimes make you repeat your last move
- (Haran Pilpel);
- * I forgot to mention the walk-in-place function in any
- documentation;
- * I set the level builder to put 100 monsters on each new level for
- debugging, and forgot to reset it -- I really should playtest
- more!;
- * If you tried to cast spell 'z', you cast the identify spell (Lucas
- Ackerman); and
- * A few more fixes which I forget right now.
-
-
-
-Linley's First: 1.00 [02.10.1997]
-
- * First (rather buggy) version.
diff --git a/stone_soup/crawl-ref/dolinks.sh b/stone_soup/crawl-ref/dolinks.sh
deleted file mode 100644
index 46815055b0..0000000000
--- a/stone_soup/crawl-ref/dolinks.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/sh
-
-mkdir -p NORMAL
-mkdir -p WIZARD
-
-pushd NORMAL ; ln -s ../source/*.h ../source/*.cc ../source/makefile* . ; popd
-pushd WIZARD ; ln -s ../source/*.h ../source/*.cc ../source/makefile* . ; popd
-
diff --git a/stone_soup/crawl-ref/domake.sh b/stone_soup/crawl-ref/domake.sh
deleted file mode 100644
index a523e0b3b6..0000000000
--- a/stone_soup/crawl-ref/domake.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/sh
-#jmf: automate making normal & wizard binaries, until they merge
-#jmf: N.B.: requires symlink directories; run ./dolinks.sh to make
-
-pushd NORMAL && make && popd && pushd WIZARD && make wizard ; popd
-
-if [ -f NORMAL/crawl ]; then
- ln -sf NORMAL/crawl ncrawl
-fi
-if [ -f WIZARD/crawl ]; then
- ln -sf WIZARD/crawl wcrawl
-fi
diff --git a/stone_soup/crawl-ref/init.txt b/stone_soup/crawl-ref/init.txt
deleted file mode 100644
index 672f51d9f2..0000000000
--- a/stone_soup/crawl-ref/init.txt
+++ /dev/null
@@ -1,676 +0,0 @@
-#
-# Crawl Init file
-#
-# Lines begining with '#' are comments. The basic syntax is:
-#
-# field = value or field.subfield = value
-#
-# Only one specification is allowed per line.
-#
-# The terms are typically case-insensitive except in the fairly obvious
-# cases (the character's name and specifying files or directories when
-# on a system that has case-sensitive filenames).
-#
-# White space is stripped from the begining and end of the line, as
-# well as imediately before and after the '='. All other whitespace
-# is left alone.
-#
-
-
-#
-# Player name
-#
-
-# name=kernel
-
-#
-# If remember_name set, the game remembers the last name you used.
-#
-
-# remember_name = true
-
-# Directory for reading macro.txt and init.txt, and dumping characters.
-# It should end with the path delimiter.
-# crawl_dir=/home/bwross/crawl/
-
-
-# Here's a list of autopickup types:
-#
-# ) Weapons
-# ( Missiles
-# [ Armour
-# / Wands
-# % Food
-# ? Scrolls
-# " or = jewellery
-# ! Potions
-# + or : Books
-# \ or | Staves
-# 0 Orbs
-# } Misc items
-# X Corpses
-# $ Gold
-
-autopickup = $?!:"/0
-
-#
-# assign_item_slot
-#
-# When picking up items, the inventory slot into which the item goes is
-# normally the first free slot from a-zA-Z. Setting assign_item_slot to
-# "backward" changes the slot assignment to work backwards. For instance, if
-# you have items on 'a' and 'c', and assign_item_slot = forward, the next item
-# will go into 'b'. If assign_item_slot = backward, the next item will go to
-# 'd' instead.
-#
-# assign_item_slot = backward
-
-#
-# dump_kill_places
-#
-# In the Vanquished Creatures list, this option controls how the locations of
-# each kill are displayed. Use 'none' to suppress place display altogether,
-# 'all' to display all known kill places, anything else to default to showing
-# the kill place only for single kills
-#
-# dump_kill_places = all
-
-#
-# dump_item_origins
-#
-# The game remembers where you find items. If you want this item origin memory
-# listed in your dumps, use this option to select which items get annotated. The
-# default behaviour is for artifacts and rods to get annotated.
-#
-# Available selectors: artifacts, ego_arm, ego_weap, jewellery, runes, rods,
-# staves, books, all.
-#
-# If you use multiple dump_item_origins lines, the last line takes effect; all
-# preceding lines are ignored.
-#
-# If you don't want any items to be annotated, set dump_item_origins to "none",
-# and set dump_item_origin_price to -1.
-#
-# dump_item_origins = artifacts, ego_weap, ego_arm, rods, staves, runes
-
-#
-# dump_item_origin_price
-#
-# Item origins are dumped if the price of the item is greater than or equal
-# to this amount. Set this to -1 to prevent selection by price.
-#
-# dump_item_origin_price = 100
-
-#
-# Base Lua file that's needed by other Lua scripts. You must source this
-# before you source any Lua script that relies on this. For safety, always
-# source this first.
-#
-# lua_file = lua\base.lua
-
-#
-# Control what messages stop shift+running and resting.
-#
-# lua_file = lua\runrest.lua
-
-#
-# If you want more detailed kill statistics, you can use a LUA script to do
-# that. See kills.lua for more ideas.
-#
-# lua_file = lua\kills.lua
-
-#
-# If you'd like to switch quickly between sets of gear, you can use this. See
-# gearset.lua for more information.
-#
-# lua_file = lua\gearset.lua
-
-#
-# This lua script prompts you to eat chunks in inventory (after prompting for
-# eating off the floor).
-#
-# lua_file = lua\eat.lua
-
-#
-# stash.lua annotates items to make for easier stash-searches. Weapons are
-# prefixed by the name of the weapon skill, so you can search for "long blades"
-# and find everything that exercises that skill. See stash.lua for more details.
-#
-# lua_file = lua\stash.lua
-
-#
-# wield.lua selects items to show in the wield menu based on the spells your
-# character knows. For instance, if you know Sublimation of Blood, chunks
-# will be added to your wield menu.
-#
-# lua_file = lua\wield.lua
-
-# The number of messages to be displayed in character dump files. Defaults to 4
-dump_message_count = 4
-
-# Set to false to disable targeting zero exp monsters in hostile targeting mode
-# target_zero_exp = false
-
-#
-# Set to true if targeting should wrap around from last to first and vice versa
-#
-# target_wrap = true
-
-#
-# When cycling through items/features with 'x' look-around, setting target_oos
-# to true allows you to jump the cursor to items and features that are outside
-# line-of-sight but in the main view. Defaults to true. See also
-# target_los_first.
-#
-target_oos = true
-
-#
-# When cycling through items/features with the 'x' look-around command, setting
-# target_los_first to true will force the cursor to squares in line-of-sight
-# before going to squares outside LOS. Defaults to true.
-#
-target_los_first = true
-
-#
-# Allows you to specify special characters as \{nn} when creating macros or
-# keymaps. For instance, you can macro a key to Enter by specifying a mapping
-# of \{13} when this is set to true. If you want to map a key to a backslash
-# with macro_meta_entry set true, escape the backslash as \\.
-#
-# Defaults to true.
-#
-macro_meta_entry = true
-
-# pickup_thrown causes autopickup to grab thrown/fired missiles
-#
-pickup_thrown = true
-
-# pickup_dropped lets autopickup affect objects you've dropped. Set to false to
-# block autopickup for dropped objects
-#
-pickup_dropped = false
-
-# assign_item_slot = backward
-
-# List of item name regexes for items which autopickup will never touch. You
-# can use multiple ban_pickup lines.
-#
-# ban_pickup = degeneration,decay,confusion
-# ban_pickup = inaccuracy
-# ban_pickup = scrolls? of paper
-
-# Option to turn off colouring the level-map with travel information
-# travel_colour = false
-
-#
-# Monsters found by detect creatures will be coloured this colour (defaults
-# to darkgrey):
-#
-detected_monster_colour = lightred
-
-
-#
-# Items found by detect items will be given this colour (defaults to darkgrey)
-#
-detected_item_colour = green
-
-#
-# Remembered monsters can be shown with their actual colours (real), or
-# assigned an arbitrary colour by name.
-#
-# remembered_monster_colour = real
-remembered_monster_colour = darkgrey
-
-
-# How long travel waits after each move (milliseconds).
-#
-travel_delay = 20
-
-# Prevent travel from routing through shallow water.
-# travel_avoid_terrain = shallow water
-
-# For merfolk and/or characters with permanent levitation, prevent travel from
-# routing through shallow _or_ deep water
-#
-# travel_avoid_terrain = shallow water, deep water
-
-# The square of the radius around travel-excluded squares where travel will
-# refuse to go. Set to zero if you want to exclude single squares.
-#
-# travel_exclude_radius2 = 68
-
-# If set to true (the default), waypoints will be numbered on the level map,
-# assuming that they're on a floor square with nothing on it.
-#
-# show_waypoints = false
-
-# Explore will stop for one of these conditions. Whatever you set this option
-# to, anything that stops travel will also stop explore.
-#
-# Multiple explore_stop lines are *not* cumulative! The last explore_stop
-# line will override all previous explore_stop lines.
-#
-explore_stop = items,stairs,shops,altars
-
-# How many squares the cursor moves on the level map when using Shift+direction.
-# Defaults to 10.
-#
-# level_map_cursor_step = 10
-
-# Playing sounds:
-# Option is set as sound = <regex>:<path to sound file>. Your regex should not
-# include commas or colons.
-# sound = LOW HITPOINT WARNING:sound\sounds2\danger3.wav
-
-# Tracking stashes. Valid options are 'all', 'dropped' and 'explicit'. Anything
-# else disables stash tracking
-stash_tracking = all
-
-# Filter corpses (14) and chunks of meat (4:21) out of the stash-tracker.
-# The filter syntax is object class:object subtype. So, to filter, say, potions
-# of degeneration, you'd use 8:14 (where 8 is for OBJ_POTIONS and 14 is
-# POT_DEGENERATION). See enum.h for all the magic numbers involved.
-stash_filter = 14, 4:21
-
-# Substrings that will stop travel if they're present in any message the game
-# displays. Substrings can be comma separated, and multiple stop_travel lines
-# are accepted.
-
-# Stop travel if Xom grants us a gift suddenly.
-stop_travel = Something appears
-
-# To limit a substring match to a message channel, prefix the substring with the
-# channel name and a colon. For instance, if you want travel to stop when you're
-# hit by divine retribution, you could use:
-# stop_travel = god:wrath finds you
-
-# If you'd like to stop travel for any message sent to a particular channel, use
-# a stop_travel line with that message channel name and a colon alone. For
-# example, if you've an amulet of the gourmand, and are hankering after rotten
-# meat, or you're playing a ghoul:
-# stop_travel = rotten_meat:
-
-# Stop travel for any god messages (including prayer)
-stop_travel = god:
-
-# verbose dump causes less important item details to appear in character dumps
-# verbose_dump = false
-
-
-# Colours out of sight map features on the playing screen
-colour_map = true
-
-
-# Cleans up out of sight monsters and clouds on the map
-clean_map = false
-
-# To be able to drop multiple items from the drop menu in one go, enable
-# multidrop (you can also switch to multidrop from the classic drop menu using
-# the @ key).
-#
-# drop_mode = multi
-
-# When selecting items using the global select key (, or -) in a multidrop
-# listing, you can choose to apply a filter - only items whose names match
-# the filter will be selected. The filter strings are regexes.
-#
-# For instance, to quickly select carrion and rotting chunks of meat, you
-# could use:
-#
-# drop_filter = skeleton, rotting, corpse
-
-# Open doors by moving on to them
-# easy_open = false
-
-
-# Auto-switch to uncursed short blade for butchery (EXPERIMENTAL!)
-easy_butcher = true
-
-
-# Allows auto removal of armour when dropping it
-# easy_armour = false
-
-
-# Make confirmation queations easier to answer:
-# none = force capitals on Y/N questions
-# safe = force only on questions that will end game
-# all = never force capitals
-
-# WARNING TO KEYPAD USERS: The number 7 is mapped to the letter 'y',
-# which can result in accidentally answering yes to questions; it is
-# suggested that you use a value of 'none' or 'safe'
-
-easy_confirm = safe
-
-
-# Setting this option to true allows the quitting of item listing with
-# space as well as escape. These lists are essentially all of those
-# that are requesting an inventory item and accept '?' and '*'.
-#
-# The identify list will never easy quit. The default is false.
-
-# easy_quit_item_lists = true
-
-# In multidrop (and pickup) menus, paging past the end will exit the menu if
-# you set the easy_exit_menu option
-#
-# easy_exit_menu = true
-
-# This option adds the text "uncursed" to items where the
-# curse status is relevent and known. Does not bother to
-# show "uncursed" on items that are fully identified (showing pluses),
-# since that wound be redundant and waste space.
-
-show_uncursed = true
-
-
-#
-# The weapon option allows defaulting on the weapon selection screen
-#
-# Valid weapons are short sword, hand axe, spear, mace, and trident...
-# although tridents are restricted to only merfolk and gladiators, so
-# you'll get queries for the illegal cases.
-#
-
-# weapon = hand axe
-
-
-#
-# These allow auto-selection of other third-screen options.
-#
-# Select "random" for random choice.
-#
-# chaos_knight => Xom or Makleb
-# death_knight => necromancy or Yredelemnul
-# priest => Zin or Yredelemnul
-#
-
-# chaos_knight = xom
-# death_knight = necromancy
-# priest = random
-
-
-#
-# The random_pick option will randomly generate a character.
-# The above options (weapons and class options) will override where
-# appropriate.
-#
-
-# random_pick = true
-
-
-# Macro colours to other colours
-#
-# Useful for terminals where some colours are hards to read (and cannot
-# be adjusted), as well as for creating a custom scheme, especially
-# when used with the background option on a terminal with a non-black
-# background.
-#
-# Format is colour.OLDCOLOUR = NEWCOLOUR, later rules take preference and
-# the NEWCOLOUR is always literal (ie. it won't re-evaluate to a different
-# colour).
-#
-# The colours are:
-#
-# black, blue, green, cyan, red, magenta, brown, lightgrey, darkgrey,
-# lightblue, lightgreen, lightcyan, lightred, lightmagenta, yellow, white
-#
-# lightgray = lightgrey, darkgray = darkgrey
-
-# colour.lightgray = black
-# colour.white = black
-# colour.lightcyan = cyan
-# colour.yellow = brown
-
-
-#
-# always_greet will give the race/class and god messages everytime the
-# game is started.
-#
-
-always_greet = true
-
-
-# Set the default background colour of your window
-# Warning: setting this to a value different than the window's background
-# colour, will probably result in some very ugly results.
-
-# background = white
-
-
-#
-# Brand friendly monsters with a curses attribute... these might not
-# do what you think, it depends on the terminal being used (and won't
-# work with non-curses compiles).
-#
-# Available options, with typical results:
-#
-# standout -- often the same as reverse, might be underline or dim
-# bold -- used by colour curses for brightening foreground colours
-# blink -- used by colour curses for brightening background colours
-# reverse -- this will probably work
-# dim -- probably no effect
-# underline -- this will probably work
-# highlight:col -- set background colour of highlighted monsters to "col"
-#
-# This is somewhat interesting (blink here is used to give friends a
-# dark grey background, and then we change dark grey so we can see bats):
-#
-# friend_brand = blink
-# colour.darkgrey = magenta
-#
-# Brand friends with a green background. If the friend is itself green, it'll
-# show up as black on green.
-#
-# friend_brand = hi:green
-
-friend_brand = reverse
-
-#
-# Stab warning.
-#
-# Some deities object to you stabbing monsters. Certain classes specialise
-# in stabbing monsters. For both these cases, it helps to identify monsters
-# that are susceptible to being stabbed without using the 'x' command. This
-# option brands sleeping monsters. All the normal 'brand' options apply.
-#
-# stab_brand = hi:blue
-
-#
-# Stabbing may be possible even if the monster is not asleep (if it's confused,
-# for instance). This option brands monsters that you *might* be able to stab,
-# provided the monster is adjacent to you. Primarily useful for worshippers of
-# The Su^WShining One. Purists may consider this unnecessarily spoily and a
-# cheat. Direct such opinions to <scintilla@gmail.com>
-#
-# may_stab_brand = hi:darkgrey
-#
-
-#
-# On DOS and Windows, if you're using a console that can do high-intensity
-# background colours, set this option to true for superior friend-branding.
-# If your console doesn't like this option, some friendly monsters will appear
-# as blinking characters (and setting this option to false may be advisable
-# to preserve your sanity in such cases).
-#
-# dos_use_background_intensity = true
-
-# Colour items on level-map
-#
-# item_colour = true
-
-# Brand heaps of items (more than one item or stack). Options apply as for
-# friend_brand.
-#
-# heap_brand = reverse
-
-
-# Message channel options:
-#
-# Format is channel.CHANNEL_NAME = (COLOUR|mute|default|on|off|plain)
-#
-# CHANNEL_NAME can currently be one of these:
-# plain = regular text (and things "uncoloured")
-# prompt = input prompts to the player
-# god = messages from the gods
-# duration = messages about character spells/effects wearing off
-# danger = serious threats to the characters existence
-# food = warnings about food
-# warning = various other warnings
-# recovery = recovery from disease/stat loss/poison conditions
-# talk = monsters talking (acting)
-# intrinsic_gain = level/stat/species power gains
-# mutation = gain/lose mutations
-# monster_spell = messages about monsters gesturing and casting spells
-# monster_enchant = messages pertaining to monster enchantments (up or down)
-# monster_damage = messages telling how damaged a monster is
-# rotten_meat = messages about chunks/corpses becoming rotten
-#
-# COLOUR can be any of the colours in the colour section above.
-#
-# Other channel options:
-#
-# mute = show no messages from channel (dangerous, be careful!)
-# default = turn channel on to it's default scheme
-# alternate = turn channel on to it's alternate "colourful" scheme
-# on = same as default
-# plain = make channel the same colour as the "plain" channel
-# (won't do anything silly like "mute" if plain == mute, though)
-# off = same as plain
-#
-# Note: The only multi-colour channels currently are monster_damage and
-# god. Setting god to a COLOUR will make all god messages that
-# colour. Setting monster_damage to a colour will make the
-# "monster dies" messages that colour, and the "injured" messages
-# will be plain coloured. More control of these and other channels
-# will be coming later.
-#
-
-# channel.plain = green
-# channel.talk = mute
-# channel.warning = plain
-# channel.diagnostic = mute
-# channel.rotten_meat = yellow
-# channel.god = alternate
-# channel.mutation = green
-
-
-#
-# hp_warning gives "* * * LOW HITPOINT WARNING * * *" on the danger channel
-# when the player takens damage and their hitpoints are less than this
-# percentage of their maximum (use 0 to turn off these messages).
-
-hp_warning = 25
-
-
-# race
-#
-# Use to preselect race. Argument can be:
-#
-# - letter used in the character creation process
-# - two letter abbreviation used on the high score board
-# - a string to match against the full name
-
-# race = human
-
-
-# class
-#
-# Used to preselect class. Same format as race option above.
-
-# class = fighter
-
-
-#
-# Wizard mode options (available only in WIZARD compiles):
-#
-# yes = start games in wizard mode (game might not be scored)
-# no = still allows player to enter wizard mode after start of game
-# never = never allow a wizard command to be used
-#
-
-wiz_mode = no
-
-
-#
-# Fire command options
-#
-# fire_items_start - sets the first inventory item to consider (default is a)
-#
-# fire_order - controls when to consider types of items
-#
-# launcher, dart, stone, dagger, spear, handaxe, club
-#
-# The list should be on one line, with commas between items.
-#
-# Launcher refers to firing the appropriate missile for the wielded
-# weapon (ie crossbow, bow, sling)... you'll probably want it first, as
-# it'll be ignored when you're not wielding a ranged weapon. The default
-# is "launcher, dart" which matches the old behaviour.
-#
-
-fire_items_start = c
-fire_order = launcher, dart, stone
-
-
-#
-# auto_list
-#
-# Setting this to true if you want to automatically list appropriate
-# inventory items for commands like quaff and read. This is like
-# immediately hitting '?', and can be confusing to beginners because
-# they won't get to see the prompts.
-#
-# This option does not apply to spell casting... Conjurers would probably
-# find that really annoying.
-#
-
-# auto_list = true
-
-
-#
-# Input buffer flushing options (flush.*)
-#
-# These are useful when using macros. Setting one of these
-# sub-options to true will cause the entire input buffer to
-# be dumped and thus effectively stop the macro.
-#
-# The sub-options currently are (and their defaults):
-#
-# failure -- when spells/abilities get miscast (true)
-# command -- whenever the game is aboutn to get the next command (false)
-# message -- whenever the game outputs a non-mute message (false)
-#
-# flush.failure = false
-# flush.command = true
-# flush.message = true
-
-#
-# lowercase_invocations
-#
-# Set this option to true if you prefer to have invocations on 'a'-'e'
-# instead of the traditional 'A'-'E' (which is the default).
-#
-
-lowercase_invocations = true
-
-
-#
-# terse_hand
-#
-# Set this to false to have the "in hand" description on the main screen
-# the same as the inventory. The default setting of true will give the
-# newer more terse description that should fit the limited space better
-# (but will be harder for newbies to understand).
-
-# terse_hand = false
-
-
-#
-# delay_message_clear - experimental (may be ugly at points)
-#
-# Setting this option to true will delay the clearing of messages until
-# the message space is full (default is false which results in clearing
-# between player actions).
-
-# delay_message_clear = true
diff --git a/stone_soup/crawl-ref/licence.txt b/stone_soup/crawl-ref/licence.txt
deleted file mode 100644
index 852d23afb2..0000000000
--- a/stone_soup/crawl-ref/licence.txt
+++ /dev/null
@@ -1,104 +0,0 @@
-
- Crawl General Public Licence
-
- Linley Henzell
- (Copyright 1997-1999 Linley Henzell)
-
- Yes, this is an almost exact copy of the Nethack Licence, but has
- obviously been adapted for Crawl (under the 'terms for other
- programs' portion of paragraph one). Crawl contains no code from
- Nethack in any shape or form.
-
- Based on the NETHACK GENERAL PUBLIC LICENCE
- (Copyright 1989 M. Stephenson)
-
- Based on the BISON GENERAL PUBLIC LICENCE
- (Copyright 1988 Richard M. Stallman)
-
- Everyone is permitted to copy and distribute verbatim copies of
- this licence, but changing it is not allowed. You can also use this
- wording to make the terms for other programs.
-
- The licence agreements of most software companies keep you at the
- mercy of those companies. By contrast, our general public licence
- is intended to give everyone the right to share Crawl. To make sure
- that you get the rights we want you to have, we need to make
- restrictions that forbid anyone to deny you these rights or to ask
- you to surrender the rights. Hence this licence agreement.
-
- Specifically, we want to make sure that you have the right to give
- away copies of Crawl, that you receive source code or else can get
- it if you want it, that you can change Crawl or use pieces of it in
- new free programs, and that you know you can do these things.
-
- To make sure that everyone has such rights, we have to forbid you
- to deprive anyone else of these rights. For example, if you
- distribute copies of Crawl, you must give the recipients all the
- rights that you have. You must make sure that they, too, receive or
- can get the source code. And you must tell them their rights.
-
- Also, for our own protection, we must make certain that everyone
- finds out that there is no warranty for Crawl. If Crawl is modified
- by someone else and passed on, we want its recipients to know that
- what they have is not what we distributed.
-
- Therefore I (Linley Henzell, the copyright holder of Crawl) make
- the following terms which say what you must do to be allowed to
- distribute or change Crawl.
-
- COPYING POLICIES
-
- 1. You may copy and distribute verbatim copies of Crawl source code
- as you receive it, in any medium, provided that you keep intact
- the notices on all files that refer to copyrights, to this Licence
- Agreement, and to the absence of any warranty; and give any other
- recipients of the Crawl program a copy of this Licence Agreement
- along with the program.
- 2. You may modify your copy or copies of Crawl or any portion of it,
- and copy and distribute such modifications under the terms of
- Paragraph 1 above (including distributing this Licence Agreement),
- provided that you also do the following:
- a. cause the modified files to carry prominent notices stating
- that you changed the files and the date of any change; and
- b. cause the whole of any work that you distribute or publish,
- that in whole or in part contains or is a derivative of Crawl
- or any part thereof, to be licensed at no charge to all third
- parties on terms identical to those contained in this Licence
- Agreement (except that you may choose to grant more extensive
- warranty protection to some or all third parties, at your
- option)
- c. You may charge a distribution fee for the physical act of
- transferring a copy, and you may at your option offer
- warranty protection in exchange for a fee.
- 3. You may copy and distribute Crawl (or a portion or derivative of
- it, under Paragraph 2) in object code or executable form under the
- terms of Paragraphs 1 and 2 above provided that you also do one of
- the following:
- a. accompany it with the complete machine-readable source code,
- which must be distributed under the terms of Paragraphs 1 and
- 2 above; or,
- b. accompany it with full information as to how to obtain the
- complete machine-readable source code from an appropriate
- archive site. (This alternative is allowed only for
- noncommercial distribution.)
- For these purposes, complete source code means either the full
- source distribution as available from my web site or updated
- copies of the files in this distribution used to create the object
- code or executable.
- 4. You may not copy, sublicence, distribute or transfer Crawl except
- as expressly provided under this Licence Agreement. Any attempt
- otherwise to copy, sublicence, distribute or transfer Crawl is
- void and your rights to use the program under this Licence
- agreement shall be automatically terminated. However, parties who
- have received computer software programs from you with this
- Licence Agreement will not have their licences terminated so long
- as such parties remain in full compliance.
-
- Stated plainly: You are prohibited by the terms of this Licence
- Agreement from using Crawl for gainful purposes. You are permitted
- to modify Crawl, or otherwise use parts of Crawl, provided that you
- comply with the conditions specified above; in particular, your
- modified Crawl or program containing parts of Crawl must remain
- freely available as provided in this Licence Agreement. In other
- words, go ahead and share Crawl, but don't try to stop anyone else
- from sharing it farther.
diff --git a/stone_soup/crawl-ref/mac/68K_Stub.r b/stone_soup/crawl-ref/mac/68K_Stub.r
deleted file mode 100644
index 391dda2ad6..0000000000
--- a/stone_soup/crawl-ref/mac/68K_Stub.r
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * File: 68K_Stub.r
- * Summary: Mac resources
- * Written by: Jesse Jones
- *
- * Change History (most recent first):
- *
- * <1> 3/30/99 JDJ Created
- */
-
-#include <Types.r>
-
-
-// ============================================================================
-// Resources
-// These resources create a tiny 68K app that pops up an
-// alert telling the user that the app will not run and
-// exits when the user dismisses the alert. This
-// file should only be added to PPC builds.
-// ============================================================================
-resource 'ALRT' (30000) {
- {84, 122, 174, 486},
- 30000,
- {
- OK, visible, silent,
- OK, visible, silent,
- OK, visible, silent,
- OK, visible, silent
- },
- alertPositionMainScreen
-};
-
-resource 'DITL' (30000) {
- {
- {60, 280, 80, 338},
- Button {
- enabled,
- "Quit"
- },
-
- {10, 60, 46, 360},
- StaticText {
- disabled,
- "This program requires a PowerPC processor and will"
- "not run on your Macintosh."
- }
- }
-};
-
-data 'CODE' (1, "Sources", locked, protected, preload) {
- $"0000 0001 9DCE 598F 2F3C 434F 4445 4267" /* ....ù'Yè/<CODEBg */
- $"A9A0 2017 6700 011E 2040 2050 2E18 2C10" /* ©Ý .g... @P..,. */
- $"A9A3 7000 204D 91C6 6002 10C0 B1CD 6DFA" /* ©£p.Më`..¿±ÕmT */
- $"41ED 0028 43F5 7800 6002 10C0 B1C9 6DFA" /* AÌ.(Czx.`..¿±SmT */
- $"598F 2F3C 4441 5441 4267 A9A0 2057 2008" /* Yè/<DATABg©Ý W . */
- $"6700 00E2 2F0D 2050 4868 0004 4EBA 00DC" /* g..'/¬PHh..N?.Ð */
- $"508F 43FA FF9C 2B49 FF12 224D 4EBA 0244" /* PèCTú+I."MN?.D */
- $"226D FF12 4EBA 023C A9A3 4EBA 02C2 422D" /* "m.N?.<©£N?.¬B- */
- $"FF17 303C A89F A746 2F08 303C A198 A346" /* .0<®üßF/.0<°ò£F */
- $"B1DF 670A 1B7C 0001 FF17 7001 A198 303C" /* ±þg..|...p.°ò0< */
- $"A9F0 A746 2B48 FF0E 303C A9F1 A746 2B48" /* ©.ßF+H.0<©ÒßF+H */
- $"FF0A 303C A9F4 A746 2B48 FF06 303C A9F0" /* .0<©ÙßF+H.0<©. */
- $"41FA 0284 A647 303C A9F1 41FA 0338 A647" /* AT.ѶG0<©ÒAT.8¶G */
- $"303C A9F4 41FA 003C A647 4EB9 0000 0492" /* 0<©ÙAT.<¶GN¼...í */
- $"4EB9 0000 04B8 487A 004E 4A2D FFFF 6702" /* N¼...½Hz.NJ-g. */
- $"4267 4267 4EB9 0000 04E4 5C8F 4A2D FFFF" /* BgBgN¼..."\èJ- */
- $"6702 548F 202D FF2C 6704 2040 4E90 4EBA" /* g.Tè -,g.@NêN? */
- $"0384 2A78 0904 303C A9F4 206D FF06 A647" /* .Ñ*x.0<©Ùm.¶G */
- $"303C A9F0 206D FF0E A647 303C A9F1 206D" /* 0<©.m.¶G0<©Ò m */
- $"FF0A A647 A9F4 0000 0000 48E7 1C30 594F" /* .¶G©Ù....HÁ.0YO */
- $"266F 001C 7800 6000 00E4 1E9B 1F5B 0001" /* &o..x.`..".õ.[.. */
- $"1F5B 0002 1F5B 0003 246F 0020 D5D7 161B" /* .[...[..$o. '×.. */
- $"4883 3003 0240 0080 670E 0243 007F 14DB" /* HÉ0..@.Äg..C...¤ */
- $"5343 4A43 6CF8 60E6 3003 0240 0040 670E" /* SCJCl¯`Ê0..@.@g. */
- $"3003 0240 003F 5240 48C0 D5C0 60D0 3003" /* 0..@.?R@H¿'¿`-0. */
- $"0240 0020 670A 0243 001F 5243 1A1B 600E" /* .@.g..C..RC..`. */
- $"3003 0240 0010 6710 0243 000F 7AFF 14C5" /* 0..@..g..C..z.? */
- $"5343 4A43 6CF8 60A6 3003 0C40 0004 6264" /* SCJCl¯`¶0..@..bd */
- $"D040 303B 0006 4EFB 0002 0060 000A 001C" /* -@0;..Ns...`.... */
- $"002C 0042 588A 14FC FFFF 14FC FFFF 14DB" /* .,.BXä.¸.¸.¤ */
- $"14DB 6000 FF7A 588A 14FC FFFF 14DB 14DB" /* .¤`.zXä.¸.¤.¤ */
- $"14DB 6000 FF6A 14FC FFA9 14FC FFF0 548A" /* .¤`.j.¸©.¸.Tä */
- $"14DB 14DB 528A 14DB 6000 FF54 14FC FFA9" /* .¤.¤Rä.¤`.T.¸© */
- $"14FC FFF0 528A 14DB 14DB 14DB 528A 14DB" /* .¸.Rä.¤.¤.¤Rä.¤ */
- $"6000 FF3C 3F3C 000F A9C9 5244 0C44 0003" /* `.<?<..©SRD.D.. */
- $"6D00 FF18 204B 584F 4CDF 0C38 4E75 2F05" /* m..KXOLþ.8Nu/. */
- $"594F 226F 000C 1E99 1F59 0001 1F59 0002" /* YO"o...ô.Y...Y.. */
- $"1F59 0003 2A17 7400 604C 1219 1001 0240" /* .Y..*.t.`L.....@ */
- $"0080 670C D201 1001 4880 48C0 D480 6028" /* .Äg."...HÄH¿'Ä`( */
- $"1E81 1F59 0001 1001 0240 0040 670C 3017" /* .Å.Y.....@.@g.0. */
- $"E548 E240 48C0 D480 600E 1F59 0002 1F59" /* ÂH'@H¿'Ä`..Y...Y */
- $"0003 2417 E58A E282 206F 0010 202F 0014" /* ..$.Âä'Ço.. /.. */
- $"D1B0 2800 5385 4A85 6EB0 2049 584F 2A1F" /* -f(.SÖJÖnfIXO*. */
- $"4E75 2F0A 2449 2F0D 2F0A 2F08 4EBA FF80" /* Nu/.$I/¬/./.N?Ä */
- $"2F2D FF12 2F0A 2F08 4EBA FF74 2F0A 2F0A" /* /-././.N?t/./. */
- $"2F08 4EBA FF6A 4FEF 0024 245F 4E75 2F0A" /* /.N?jOÔ.$$_Nu/. */
- $"2449 2F0D 4497 2F0A 2F08 4EBA FF52 2F2D" /* $I/¬Dó/./.N?R/- */
- $"FF12 4497 2F0A 2F08 4EBA FF44 2F0A 4497" /* .Dó/./.N?D/.Dó */
- $"2F0A 2F08 4EBA FF38 4FEF 0024 245F 4E75" /* /./.N?8OÔ.$$_Nu */
- $"BBFA 0028 6602 4E75 48E7 0084 2A7A 001C" /* ªT.(f.NuHÁ.Ñ*z.. */
- $"206D FF0E 4A6F 000C 6604 206D FF0A 2F48" /* m.Jo..f.m./H */
- $"000A 4CDF 2100 544F 4E75 0000 0000 41FA" /* ..Lþ!.TONu....AT */
- $"FFFA 208D 4E75 3F3C 0001 4EBA FFC4 544F" /* TçNu?<..N?YTO */
- $"48E7 E0E0 55AF 0018 246F 0018 202D FF18" /* HÁýýUØ..$o.. -. */
- $"670A 2040 3F2A 0006 4E90 548F 50F8 0A5E" /* g.@?*..NêTèP¯.^ */
- $"598F 2F3C 434F 4445 3F2A 0006 A9A0 2017" /* Yè/<CODE?*..©Ý . */
- $"6616 202D FF24 6604 700F A9C9 2040 3F2A" /* f.-$f.p.©S @?* */
- $"0006 4E90 548F 60DA 4A38 0BB2 6704 2040" /* ..NêTè`ZJ8.¾g. @ */
- $"A064 2057 A029 205F 2050 2008 A055 2040" /* Ýd WÝ) _ P.ÝU @ */
- $"2F08 2248 D1E8 0008 4EBA FEF8 205F 224D" /* /."H-Ë..N?o¯ _"M */
- $"D3E8 0004 3028 0002 2208 600C 337C 4EF9" /* "Ë..0(..".`.3|N~ */
- $"0000 D3A9 0002 5089 51C8 FFF2 4A2D FF17" /* .."©..PâQ»ÚJ-. */
- $"6704 7001 A198 202D FF1C 670A 2040 3F2A" /* g.p.°ò-.g. @?* */
- $"0006 4E90 548F 4CDF 0707 4A38 012D 6702" /* ..NêTèLþ..J8.-g. */
- $"A9FF 4E75 3F3C 0000 4EBA FF06 544F 2F0A" /* ©Nu?<..N?.TO/. */
- $"246F 0008 0C6A 4EF9 0000 6670 0C6A 0002" /* $o...jN~..fp.j.. */
- $"0006 6D68 598F 2F3C 434F 4445 3F2A 0006" /* ..mhYè/<CODE?*.. */
- $"A9A0 2017 6604 588F 6052 2040 2050 2248" /* ©Ý .f.Xè`R@ P"H */
- $"D1E8 0008 4EBA FE98 2057 2050 224D D3E8" /* -Ë..N?oò WP"M"Ë */
- $"0004 3028 0002 2208 600C 337C A9F0 0000" /* ..0(..".`.3|©... */
- $"93A9 0002 5089 51C8 FFF2 2057 A02A 205F" /* ì©..PâQ»ÚWÝ* _ */
- $"A049 4A2D FF17 6704 7001 A198 202D FF20" /* ÝIJ-.g.p.°ò - */
- $"670A 2040 3F2A 0006 4E90 548F 245F 2E9F" /* g.@?*..NêTè$_.ü */
- $"4E75 4E75 2F0A 6014 2B52 FF28 3F3C FFFF" /* NuNu/.`.+R(?< */
- $"2F2A 0008 206A 0004 4E90 5C4F 246D FF28" /* /*.. j..Nê\O$m( */
- $"200A 66E4 245F 4E75 4E75 4E56 0000 486D" /* .f"$_NuNuNV..Hm */
- $"FFFA A86E A8FE A912 A930 A9CC 42A7 A97B" /* T®n®o©.©0©ÃBß©{ */
- $"A850 4E5E 4E75 8B49 6E69 7454 6F6F 6C62" /* ®PN^NuãInitToolb */
- $"6F78 0000 4E56 0000 4EBA FFD0 554F 3F3C" /* ox..NV..N?-UO?< */
- $"7530 42A7 A986 301F 4E5E 4E75 846D 6169" /* u0Bß©Ü0.N^NuÑmai */
- $"6E00 0000" /* n... */
-};
-
-data 'CODE' (0, purgeable, protected) {
- $"0000 0030 0000 0100 0000 0008 0000 0020" /* ...0........... */
- $"0000 3F3C 0001 A9F0" /* ..?<..©. */
-};
-
-data 'DATA' (0, purgeable, protected) {
- $"0000 0020 FFFF FFFF 4000 0000 0028 0000" /* ... @....(.. */
- $"0000 2800 0000 0000 0000 0000 0000 0000" /* ..(............. */
- $"0000 0000 0000 0003 406E 838A 0000 0000" /* ........@nÉä.... */
-};
-
diff --git a/stone_soup/crawl-ref/mac/Crawl.r b/stone_soup/crawl-ref/mac/Crawl.r
deleted file mode 100644
index 86fa65c8d6..0000000000
--- a/stone_soup/crawl-ref/mac/Crawl.r
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * File: Crawl.r
- * Summary: Mac resources
- * Written by: Jesse Jones
- *
- * Change History (most recent first):
- *
- * <2> 5/25/02 JDJ Added some Carbon resources
- * <1> 3/26/99 JDJ Created
- */
-
-#include <BalloonTypes.r>
-#include <Types.r>
-
-
-// ============================================================================
-// Carbon Resources
-// ============================================================================
-data 'carb' (0) {
-};
-
-// $$$ is this only for bundled apps?
-resource 'plst' (0) {
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- "<!DOCTYPE plist SYSTEM\n\"file://localhost/System/Library/DTDs/PropertyList.dtd\">\n"
- "<plist version=\"4.0\">\n"
- "<dict>\n"
- "<key>CFBundleInfoDictionaryVersion</key>\n"
- "<string>4.0</string>\n"
- "<key>CFBundleIdentifier</key>\n"
- "<string>Crawl4</string>\n"
- "<key>CFBundleVersion</key>\n"
- "<string>4.0</string>\n"
- "<key>CFBundleDevelopmentRegion</key>\n"
- "<string>English</string>\n"
- "<key>CFBundleName</key>\n"
- "<string>Crawl</string>\n"
- "<key>CFBundlePackageType</key>\n"
- "<string>APPL</string>\n"
- "<key>CFBundleSignature</key>\n"
- "<string>????</string>\n"
- "</dict>\n"
- "</plist>"
-};
-
-
-// ============================================================================
-// Finder Icon Help Message
-// ============================================================================
-resource 'hfdr' (-5696, "Finder Help") {
- HelpMgrVersion,
- hmDefaultOptions,
- 0, 0,
-
- {
- HMStringItem {
- "Crawl is a fun game in the grand tradition of games like Rogue, Hack and Moria."
- },
- }
-};
-
-
-// ============================================================================
-// Get Info String
-// ============================================================================
-type 'Crwl' {pstring;};
-
-data 'Crwl' (0, "Owner resource") {
- "Crawl 3.3 ©1997 -1999 by Linley Henzell (Mac Port by Jesse Jones)"
-};
-
-
-// ============================================================================
-// Derezed Resources
-// ============================================================================
-
-resource 'BNDL' (128) {
- 'Crwl',
- 0,
- {
- /* [1] */
- 'FREF',
- { /* array IDArray: 2 elements */
- /* [1] */
- 0, 128,
- /* [2] */
- 1, 129
- },
- /* [2] */
- 'ICN#',
- {
- /* [1] */
- 0, 0,
- /* [2] */
- 1, 0
- }
- }
-};
-
-resource 'FREF' (128) {
- 'CrlF',
- 0,
- ""
-};
-
-resource 'FREF' (129) {
- 'APPL',
- 1,
- ""
-};
-
-resource 'DITL' (129) {
- {
- /* [1] */
- {45, 353, 65, 411},
- Button {
- enabled,
- "OK"
- },
- /* [2] */
- {19, 68, 90, 339},
- StaticText {
- disabled,
- "^0"
- },
- /* [3] */
- {38, 21, 70, 53},
- Icon {
- disabled,
- 128
- }
- }
-};
-
-resource 'DITL' (130) {
- {
- /* [1] */
- {81, 136, 101, 194},
- Button {
- enabled,
- "No"
- },
- /* [2] */
- {81, 37, 101, 95},
- Button {
- enabled,
- "Yes"
- },
- /* [3] */
- {24, 43, 56, 188},
- StaticText {
- disabled,
- "Do you really want to quit without savin"
- "g?"
- }
- }
-};
-
-resource 'DITL' (256, "About", purgeable) {
- {
- /* [1] */
- {70, 220, 90, 280},
- Button {
- enabled,
- "OK"
- },
- /* [2] */
- {10, 70, 64, 279},
- StaticText {
- disabled,
- "Crawl 3.3 \n© 1997-1999 by Linley Henzell"
- "\nMac Port by Jesse Jones"
- },
- /* [3] */
- {10, 20, 42, 52},
- Icon {
- disabled,
- 1
- }
- }
-};
-
-resource 'DITL' (131, purgeable) {
- {
- /* [1] */
- {71, 288, 91, 348},
- Button {
- enabled,
- "Save"
- },
- /* [2] */
- {71, 215, 91, 275},
- Button {
- enabled,
- "Cancel"
- },
- /* [3] */
- {71, 75, 91, 159},
- Button {
- enabled,
- "Don't Save"
- },
- /* [4] */
- {10, 75, 58, 348},
- StaticText {
- disabled,
- "Do you want to save your game before qui"
- "tting?"
- }
- }
-};
-
-data 'ALRT' (129) {
-$"0028 0028 0096 01D7 0081 5555" /*.(.(.ñ.×.ÅUU */
-};
-
-data 'ALRT' (130) {
- $"0090 009A 011B 0180 0082 5555" /* .ê.ö...Ä.ÇUU */
-};
-
-resource 'ALRT' (256, "About", purgeable) {
- {88, 85, 184, 378},
- 256,
- {
- /* [1] */
- OK, visible, silent,
- /* [2] */
- OK, visible, silent,
- /* [3] */
- OK, visible, silent,
- /* [4] */
- OK, visible, silent
- },
- alertPositionMainScreen
-};
-
-resource 'ALRT' (131, "Save Changes", purgeable) {
- {104, 130, 205, 488},
- 131,
- {
- /* [1] */
- OK, visible, silent,
- /* [2] */
- OK, visible, silent,
- /* [3] */
- OK, visible, silent,
- /* [4] */
- OK, visible, silent
- },
- alertPositionParentWindowScreen
-};
-
-resource 'clut' (256) {
- {
- // [0] // DOS colors crayon colors
- 0xFFFF, 0xFFFF, 0xFFFF, // white
-
- // [1]
- 0x0000, 0x3333, 0xCCCC, // blue
-
- // [2]
- 0x0000, 0x6666, 0x3333, // green pine
-
- // [3]
- 0x6666, 0xCCCC, 0xCCCC, // cyan fog
-
- // [4]
- 0xFFFF, 0x0000, 0x3333, // red
-
- // [5]
- 0xCCCC, 0x6666, 0xCCCC, // magenta orchid
-
- // [6]
- 0x9999, 0x6666, 0x3333, // brown dirt
-
- // [7]
- 0x9999, 0x9999, 0x9999, // light grey granite
-
- // [8]
- 0x3333, 0x3333, 0x3333, // drag grey gabbro
-
- // [9]
- 0x6666, 0x9999, 0xFFFF, // light blue sky blue
-
- // [10]
- 0x3333, 0x9999, 0x3333, // light green clover
-
- // [11]
- 0x6666, 0xCCCC, 0x9999, // light cyan ocean green
-
- // [12]
- 0xFFFF, 0x6666, 0x0000, // light red fire
-
- // [13]
- 0xFFFF, 0x9999, 0x0000, // light magenta orange
-
- // [14]
- 0xFFFF, 0xFFFF, 0x0000, // yellow lemon
-
- // [15]
- 0x0000, 0x0000, 0x0000 // black
- }
-};
diff --git a/stone_soup/crawl-ref/mac/Crawl4.mcp b/stone_soup/crawl-ref/mac/Crawl4.mcp
deleted file mode 100644
index d59edd3cd3..0000000000
--- a/stone_soup/crawl-ref/mac/Crawl4.mcp
+++ /dev/null
Binary files differ
diff --git a/stone_soup/crawl-ref/mac/Precomp (Common).h b/stone_soup/crawl-ref/mac/Precomp (Common).h
deleted file mode 100644
index f4f9450d05..0000000000
--- a/stone_soup/crawl-ref/mac/Precomp (Common).h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * File: Precomp (Common).h
- * Summary: The header included by the CodeWarrior precompiled header files.
- * Written by: Jesse Jones
- *
- * Change History (most recent first):
- *
- * <1> 5/25/02 JDJ Created
- */
-
-// In order for precompiled headers to work on MSVC this header must be included
-// before *anything* else.
-#if _MSC_VER >= 1100
- #pragma message("Compiling Precomp (Common).h (this message should only appear once per project)")
-#endif
-
-#ifndef PRECOMP_COMMON_H
-#define PRECOMP_COMMON_H
-
-
-// ===================================================================================
-// Debug Macros
-// ===================================================================================
-#ifdef _DEBUG
- #define DEBUG 1
- #define RELEASE 0
-
- #if __MWERKS__
- #define MSIPL_DEBUG_MODE
- #endif
-#else
- #define DEBUG 0
-
- #if __profile__
- #define RELEASE 0
- #else
- #define RELEASE 0
- #endif
-
- #if !defined(NDEBUG)
- #define NDEBUG // used by <assert.h>
- #endif
-#endif
-
-
-// ===================================================================================
-// Misc Macros
-// ===================================================================================
-#if MAC
- #define TARGET_API_MAC_CARBON 1
- #define __CF_USE_FRAMEWORK_INCLUDES__
-#endif
-
-#if MAC && !defined(macintosh) // macintosh isn't defined for MACH-O
- #define macintosh 1
-#endif
-
-#include <mslconfig>
-
-
-// ===================================================================================
-// C++ Includes
-// ===================================================================================
-#include <algorithm>
-#include <cstdio>
-#include <iostream>
-#include <limits>
-#include <list>
-#include <map>
-#include <set>
-#include <string>
-#include <vector>
-
-
-#endif // PRECOMP_COMMON_H \ No newline at end of file
diff --git a/stone_soup/crawl-ref/mac/Precomp (Mac-D).pch++ b/stone_soup/crawl-ref/mac/Precomp (Mac-D).pch++
deleted file mode 100644
index 32d0b7a246..0000000000
--- a/stone_soup/crawl-ref/mac/Precomp (Mac-D).pch++
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * File: Precomp (Mac-D).pch++
- * Summary: Precompiled header for Mac debug builds.
- * Written by: Jesse Jones
- *
- * Change History (most recent first):
- *
- * <1> 5/25/02 JDJ Created
- */
-
-#pragma precompile_target "Precomp (Mac-D)"
-
-#define MAC 1
-#define _DEBUG // this is how we know a build is a debug build on Windows so we'll use the same mechanism on the Mac
-
-#include "Precomp (Common).h"
diff --git a/stone_soup/crawl-ref/mac/Precomp (Mac-R).pch++ b/stone_soup/crawl-ref/mac/Precomp (Mac-R).pch++
deleted file mode 100644
index e72da8198e..0000000000
--- a/stone_soup/crawl-ref/mac/Precomp (Mac-R).pch++
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * File: Precomp (Mac-R).pch++
- * Summary: Precompiled header for Mac release builds.
- * Written by: Jesse Jones
- *
- * Change History (most recent first):
- *
- * <1> 5/25/02 JDJ Created
- */
-
-#if __profile__
- #pragma precompile_target "Precomp (Mac-P)"
-#else
- #pragma precompile_target "Precomp (Mac-R)"
-#endif
-
-#define MAC 1
-
-#include "Precomp (Common).h"
diff --git a/stone_soup/crawl-ref/mac/Precomp (Posix-D).pch++ b/stone_soup/crawl-ref/mac/Precomp (Posix-D).pch++
deleted file mode 100644
index 313f4a33bc..0000000000
--- a/stone_soup/crawl-ref/mac/Precomp (Posix-D).pch++
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * File: Precomp (Posix-D).pch++
- * Summary: Precompiled header for Posix debug builds.
- * Written by: Jesse Jones
- *
- * Change History (most recent first):
- *
- * <1> 5/25/02 JDJ Created
- */
-
-#pragma precompile_target "Precomp (Posix-D)"
-
-#define UNIX 1
-#define BSD 1
-#define _DEBUG // this is how we know a build is a debug build on Windows so we'll use the same mechanism on the Mac
-
-#include "Precomp (Common).h"
diff --git a/stone_soup/crawl-ref/mac/Precomp (Posix-R).pch++ b/stone_soup/crawl-ref/mac/Precomp (Posix-R).pch++
deleted file mode 100644
index f6d249a5f4..0000000000
--- a/stone_soup/crawl-ref/mac/Precomp (Posix-R).pch++
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * File: Precomp (Posix-R).pch++
- * Summary: Precompiled header for Posix release builds.
- * Written by: Jesse Jones
- *
- * Copyright © 2002 Jesse Jones.
- *
- * Change History (most recent first):
- *
- * <1> 5/25/02 JDJ Created
- */
-
-#pragma precompile_target "Precomp (Posix-R)"
-
-#define UNIX 1
-#define BSD 1
-
-#include "Precomp (Common).h"
diff --git a/stone_soup/crawl-ref/macro.txt b/stone_soup/crawl-ref/macro.txt
deleted file mode 100644
index e0ca8d697f..0000000000
--- a/stone_soup/crawl-ref/macro.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-K:\033[1S~\015
-A:H\1L8\4
-
-K:\033[1~\015
-A:B\1L8\4
-
-K:\033[2S~\015
-A:y\1L8\4
-
-K:\033[3S~\015
-A:J\1L8\4
-
-K:\033[4S~\015
-A:N\1L8\4
-
-K:\033[4~\015
-A:H\1L8\4
-
-K:\033[5S~\015
-A:b\1L8\4
-
-K:\033[5~\015
-A:5\1L8\4
-
-K:\033[6S~\015
-A:u\1L8\4
-
-K:\033[6~\015
-A:L\1L8\4
-
-K:\033[7S~\015
-A:n\1L8\4
-
-K:\033[8S~\015
-A:Y\1L8\4
-
-K:\033[9S~\015
-A:K\1L8\4
-
-K:\033[A\015
-A:U\1L8\4
-
-K:\033[B\015
-A:k\1L8\4
-
-K:\033[C\015
-A:j\1L8\4
-
-K:\033[D\015
-A:l\1L8\4
-
-K:\033[G\015
-A:h\1L8\4
-
-K:\0345\015
-A:.\1L8\4
-
diff --git a/stone_soup/crawl-ref/readme.txt b/stone_soup/crawl-ref/readme.txt
deleted file mode 100644
index 3174052c27..0000000000
--- a/stone_soup/crawl-ref/readme.txt
+++ /dev/null
@@ -1,151 +0,0 @@
- Crawl Quick-Start Guide
- (Copyright 1999 Linley Henzell)
-
-So, you want to start playing Crawl straight away without bothering with the
-manual? Read this, the guide to starting Crawl with a minimum of preparation.
-When you get some more time, you can read crawl.txt in the Docs directory
-for more detailed information.
-
-I suggest printing it out and following its instructions while playing your
-first few games (you can also press '?' while playing for a list of commands).
-
- INTRODUCTION TO CRAWL
-
-Crawl is a large and very random game of subterranean exploration in a fantasy
-world of magic and frequent violence. Your quest is to travel into the depths
-of the Dungeon (which is different each time you play) and retrieve the Orb of
-Zot.
-
-Crawl is an RPG of the 'rogue-like' type, one of the descendants of Rogue. Its
-graphics are simple but highly informative, designed to be understood at a
-glance, and control is exercised largely through one-keystroke commands.
-
- STARTING OUT
-
-After starting the program you will be greeted with a message asking for your
-name. Don't spend too much time over this, as your first character will *not*
-last very long (sorry, but it's true).
-
-Next you are given menus of species and character classes from which to
-choose. A dwarf, orc, ogre or troll Fighter is a good bet. Elves are quite
-fragile, humans are pretty average at everything, and the weirder species are
-mostly too tricky for beginning players. Finally, you may be given a choice of
-weapons. I suggest an axe (axes are fun).
-
-Now you are in the game. The game screen has three parts:
- - the Map takes up the upper left part of the screen. In its very centre is
-the @ sign which represents You. The coloured parts of the Map are the parts
-you can see, while places which you have visited before but cannot currently
-see are shown in grey.
- - the Message box is the large part of the screen below the map. It describes
-events as they happen and asks you questions from time to time.
- - the Stats area (to the right of the Map) contains various indicators of
-your health and abilities.
-
- EXPLORING
-
-Try walking around, using either the numeric keypad (turn numlock off) or the
-hjklyubn keys. To move in a given direction until you reach something
-interesting or see a hostile creature, press shift and the direction.
-
-If you want to know what a certain character on the screen represents, you can
-use the 'x' (examine) command to get a short description. You use the 'o'
-(open) command to open doors, and the '<' (up) and '>' (down) commands to
-climb staircases. Sometimes doors are hidden, and must be searched out by
-standing next to walls and resting (a number of commands do the same thing:
-'s', '.' (period), delete, or '5' on the numeric keypad).
-
-The Dungeon gets more dangerous (but more interesting!) as you go down. If you
-get lost you can access a map of the whole level you are on with the 'X'
-command, which uses the whole screen.
-
- ITEMS
-
- After walking around for a while, you will no doubt come across some items
-laying around (you may come across some monsters as well; for help in dealing
-with them skip to the Monsters section). You can pick up items with the 'g'
-(get) or ',' commands and drop them again with 'd' (drop), and the 'i'
-(inventory) command shows you what you're carrying.
-
-There are several different types of items:
-
- - Weapons, represented by the ) sign. Wield them with the 'w' (wield)
-command. Some weapons are cursed and cannot be un-wielded without the use of
-magic.
-
- - Armour (]). Wear it with the 'W' (Wear) command, and remove it with 'T'
-(Take off). Heavier armours give more protection, but may hamper your ability
-to fight and to dodge attacks aimed at you.
-
- - Ammunition (also the ) sign). Throw it with 't' (throw). Darts are meant to
-be thrown by hand; other missiles need an appropriate launcher to be wielded
-(eg arrows are much more effective when shot with a bow).
-
- - Wands (/), Scrolls (?) and Potions (!) can be very valuable, but have
-limited uses (scrolls and potions can only be used once each, wands contain
-only a certain number of charges). Wands are 'z'apped, scrolls are 'r'ead and
-potions are 'q'uaffed.
- Unfortunately, you won't at first know what a wand, scroll or potion does; it
-will only be described by its physical appearance. But once you have used, for
-example, a potion of healing, you will in future recognise all potions of
-healing.
-
- - Rings (=) and Amulets (") often contain powerful magic, but it can be
-difficult to work out exactly what one does. They are put on with 'P' (Put on)
-and removed with 'R' (remove), but can, like weapons, be cursed.
-
- - Food (%) is vital to your survival. Eat it with the 'e' (eat) command when
-hungry. Monsters' corpses, also %, can be eaten if chopped up (the 'D'
-(Dissect) command), but not all of them are healthful, and many species of
-player-character dislike eating raw flesh unless very hungry.
-
- - Money ($) can be used to buy stuff in shops, and increases your score if
-you escape.
-
-There are a few other types of item, but you will discover these as you play.
-
-One vital command to remember when dealing with items is 'V' (View), which
-gives you a short description of any item. Use it on everything you find. The
-magical Scroll of Identify can also help for identifying magical items of
-uncertain nature.
-
- MONSTERS
-
-You will also run into monsters (most of which are represented by letters of
-the alphabet). You can attack a monster by trying to move into the square it
-is occupying.
-
-When you are wounded you lose hit points (displayed near the top of the stats
-list); these return gradually over time through the natural process of
-healing. If you lose all of your hp you Die.
-
-To survive, you will need to develop a few basic tactics:
- - Never fight more than one monster if you can help it. Always back into a
-corridor so that they must fight you one-on-one.
- - If you are badly wounded, you can run away from monsters to buy some time.
-Try losing them in corridors, or find a place where you can run around in
-circles to heal while the monster chases you.
- - Rest between encounters. The 's', '.', delete or keypad-5 commands make you
-rest for one turn, while pressing '5' or shift-and-keypad-5 make you rest for
-a longer time (you will stop resting when fully healed).
- - Learn when to run away from things you can't handle - this is important!
-
- DEATH
-
-Before long, you'll probably end up dead.
-
-Death in Crawl is permanent; you cannot just reload a saved game and start
-again where you left off. The 'S' (Save) command exists only to let you leave
-a game part-way through and come back to it later. Quitting ('Q') is a way of
-committing suicide if you can't even be bothered to help your character escape
-from the Dungeon alive.
-
-
-
-Well, that's it for the quick-start guide. This should help you through your
-first few games, but Crawl is extremely (some would say excessively) complex
-and cannot be adequately described in so short a document. So when you feel
-ready to start playing with magic, skills, religions, the arcane intricacies
-of the initfile and a whole heap of other stuff, glance through the manual.
-Happy Crawling!
-
diff --git a/stone_soup/crawl-ref/source/AppHdr.h b/stone_soup/crawl-ref/source/AppHdr.h
deleted file mode 100644
index e9b38ff160..0000000000
--- a/stone_soup/crawl-ref/source/AppHdr.h
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- * File: AppHdr.h
- * Summary: Precompiled header used by Crawl.
- * Written by: Jesse Jones
- *
- * Abstract: CodeWarrior and MSVC both support precompiled headers which can
- * significantly speed up compiles. Unlike CodeWarrior MSVC imposes
- * some annoying restrictions on precompiled headers: the precompiled
- * header *must* be the first include in all cc files. Any includes or
- * other statements that occur before the pch include are ignored. This
- * is really stupid and can lead to bizarre errors, but it does mean
- * that we shouldn't run into any problems on systems without precompiled
- * headers.
- *
- * Copyright © 1999 Jesse Jones.
- *
- * Change History (most recent first):
- *
- * <9> 9 Aug 2001 MV Added USE_RIVERS,USE_NEW_UNRANDS
- * and MISSILE_TRAILS_OFF #define
- * <8> 10 May 2001 GDL Added FreeBSD support
- * courtesy Andrew E. Filonov
- * <7> 9 May 2000 GDL Added Windows 32 bit console support
- * <6> 24mar2000 jmf Added a whole slew of new options, which
- * ought to be mandatory :-)
- * <5> 10/12/99 BCR Added USE_NEW_RANDOM #define
- * <4> 9/25/99 CDL linuxlib -> liblinux
- * <3> 6/18/99 BCR Moved the CHARACTER_SET #define here from
- * linuxlib.cc. Also wrapped the #define
- * USE_MACROS to prevent it from being used by
- * Linux.
- * <2> 6/17/99 BCR Removed 'linux' check, replaced it with
- * 'LINUX' check. Now need to be -DLINUX
- * during compile. Also moved
- * CHARACTER_SET #define here from
- * linuxlib.cc
- * <1> 5/30/99 JDJ Created (from config.h)
- */
-
-
-#ifndef APPHDR_H
-#define APPHDR_H
-
-#if _MSC_VER >= 1100 // note that we can't just check for _MSC_VER: most compilers will wind up defining this in order to work with the SDK headers...
-#pragma message("Compiling AppHeader.h (this message should only appear once)")
-#endif
-
-#if defined(GCC)
-# define HASH_CONTAINER_NS __gnu_cxx
-# define HASH_CONTAINERS
-#endif
-
-// Enables stash-tracking: keeps track of items in the dungeon as a convenience
-// for the player.
-#define STASH_TRACKING
-
-// Uncomment to enable the Crawl Lua bindings.
-//
-// #define CLUA_BINDINGS
-
-// =========================================================================
-// System Defines
-// =========================================================================
-// Define plain_term for Unix and dos_term for DOS and EMX.
-
-#if defined(LINUX)
- #define UNIX
- #define USE_UNIX_SIGNALS
-#elif defined(SOLARIS)
- #define UNIX
- #define USE_UNIX_SIGNALS
-#elif defined(BSD)
- #define UNIX
-#elif defined(OSX)
- #define UNIX
- // Darkgrey is a particular problem in Terminal.app.
- #define USE_8_COLOUR_TERM_MAP
- #define COL_TO_REPLACE_DARKGREY BLUE
-#elif defined(HPUX)
- #define UNIX
- #define USE_UNIX_SIGNALS
- // Under HP-UX it's typically easier to use ncurses than try and
- // get the colour curses library to work. -- bwr
- #define CURSES_INCLUDE_FILE <ncurses.h>
-#endif
-
-#ifdef UNIX
- #define PLAIN_TERM
- #define MULTIUSER
-
- #define CHARACTER_SET 0
- #define USE_ASCII_CHARACTERS
- #define USE_CURSES
- #define EOL "\n"
-
- // Unix builds use curses/ncurses, which supports colour.
- //
- // This will allow using the standout attribute in curses to
- // mark friendly monsters... results depend on the type of
- // term used... under X Windows try "rxvt".
- #define USE_COLOUR_OPTS
-
- // More sophisticated character handling
- #define CURSES_USE_KEYPAD
-
- // How long (milliseconds) curses should wait for additional characters
- // after seeing an Escape (0x1b) keypress. May not be available on all
- // curses implementations.
- #define CURSES_SET_ESCDELAY 20
-
- // Use this to seed the PRNG with a bit more than just time()... turning
- // this off is perfectly okay, the game just becomes more exploitable
- // with a bit of hacking (ie only by people who know how).
- //
- // For now, we'll make it default to on for Linux (who should have
- // no problems with compiling this).
- #define USE_MORE_SECURE_SEED
-
- // Use POSIX regular expressions
- #define REGEX_POSIX
-
- // If you have libpcre, you can use that instead of POSIX regexes -
- // uncomment the line below and add -lpcre to your makefile.
- // #define REGEX_PCRE
-
- // Uncomment (and edit as appropriate) to play sounds.
- //
- // WARNING: Enabling sounds may compromise security if Crawl is installed
- // setuid or setgid. Filenames passed to this command *are not
- // validated in any way*.
- //
- // #define SOUND_PLAY_COMMAND "/usr/bin/play -v .5 %s 2>/dev/null &"
-
- // For cases when the game will be played on terms that don't support the
- // curses "bold == lighter" 16 colour mode. -- bwr
- //
- // Darkgrey is a particular problem in the 8 colour mode. Popular values
- // for replacing it around here are: WHITE, BLUE, and MAGENTA. THis
- // option has no affect in 16 colour mode. -- bwr
- //
- // #define USE_8_COLOUR_TERM_MAP
- // #define COL_TO_REPLACE_DARKGREY MAGENTA
-
- #include "libunix.h"
-
-// To compile with EMX for OS/2 define USE_EMX macro with compiler command line
-// (already defined in supplied makefile.emx)
-#elif defined(USE_EMX)
- #define DOS_TERM
- #define EOL "\n"
- #define CHARACTER_SET A_ALTCHARSET
-
- #include <string>
- #include "libemx.h"
-
-#elif _MSC_VER >= 1100
- #include <string>
- #include "WinHdr.h"
- #error MSVC is not supported yet
- #define CHARACTER_SET A_ALTCHARSET
-
-// macintosh is predefined on all the common Mac compilers
-#elif defined(macintosh)
- #define PLAIN_TERM
- #define HAS_NAMESPACES 1
- #define EOL "\r"
- #define CHARACTER_SET A_ALTCHARSET
- #include <string>
- #include "libmac.h"
-
-#elif defined(DOS)
- #define DOS_TERM
- #define SHORT_FILE_NAMES
- #define EOL "\r\n"
- #define CHARACTER_SET A_ALTCHARSET
-
- #include <string>
-
- #ifdef __DJGPP__
- #define NEED_SNPRINTF
- #endif
-
-#elif defined(WIN32CONSOLE) && (defined(__IBMCPP__) || defined(__BCPLUSPLUS__) || defined(__MINGW32__))
- #include "libw32c.h"
- #define PLAIN_TERM
- #define SHORT_FILE_NAMES
- #define EOL "\n"
- #define CHARACTER_SET A_ALTCHARSET
- #define getstr(X,Y) getConsoleString(X,Y)
-
- // Uncomment to play sounds. winmm must be linked in if this is uncommented.
- // #define WINMM_PLAY_SOUNDS
-
- // Use Perl-compatible regular expressions. libpcre must be available and
- // linked in.
- // #define REGEX_PCRE
-#else
- #error unsupported compiler
-#endif
-
-
-// =========================================================================
-// Debugging Defines
-// =========================================================================
-#ifdef FULLDEBUG
- // Bounds checking and asserts
- #define DEBUG 1
-
- // Outputs many "hidden" details, defaults to wizard on.
- #define DEBUG_DIAGNOSTICS 1
-
- // Scan for bad items before every input (may be slow)
- //
- // This function might slow things down quite a bit
- // on slow machines because it's going to go through
- // every item on the level and do string comparisons
- // against the name. Still, it is nice to know the
- // turn in which "bad" items appear.
- #define DEBUG_ITEM_SCAN 1
-#endif
-
-#ifdef _DEBUG // this is how MSVC signals a debug build
- #define DEBUG 1
-#else
-// #define DEBUG 0 // leave this undefined for those lamers who use #ifdef
-#endif
-
-#if DEBUG
- #if __MWERKS__
- #define MSIPL_DEBUG_MODE
- #endif
-#else
- #if !defined(NDEBUG)
- #define NDEBUG // used by <assert.h>
- #endif
-#endif
-
-
-// =========================================================================
-// Game Play Defines
-// =========================================================================
-// number of back messages saved during play (currently none saved into files)
-#define NUM_STORED_MESSAGES 1000
-
-// if this works out okay, eventually we can change this to USE_OLD_RANDOM
-#define USE_NEW_RANDOM
-
-// Uncomment this if you find the labyrinth to be buggy and want to
-// remove it from the game.
-// #define SHUT_LABYRINTH
-
-// Define USE_MACRO if you want to use the macro patch in macro.cc.
-#define USE_MACROS
-
-// Set this to the number of runes that will be required to enter Zot's
-// domain. You shouldn't set this really high unless you want to
-// make players spend far too much time in Pandemonium/The Abyss.
-//
-// Traditional setting of this is one rune, but three is pretty standard now.
-#define NUMBER_OF_RUNES_NEEDED 3
-
-// Number of top scores to keep.
-#define SCORE_FILE_ENTRIES 100
-
-// Option to allow scoring of wizard characters. Note that even if
-// you define this option, wizard characters are still tagged as such
-// in the score file.
-// #define SCORE_WIZARD_CHARACTERS
-
-// ================================================= --------------------------
-//jmf: New defines for a bunch of optional features.
-// ================================================= --------------------------
-
-// Use special colours for various channels of messages
-#define USE_COLOUR_MESSAGES
-
-// Wizard death option (needed to test new death messages)
-#define USE_OPTIONAL_WIZARD_DEATH
-
-// Semi-Controlled Blink
-#define USE_SEMI_CONTROLLED_BLINK
-
-// Use new system for weighting str and dex based on weapon type, -- bwr
-#define USE_NEW_COMBAT_STATS
-
-// Use this is you want the occasional spellcaster or ranger type wanderer
-// to show up... comment it if you find these types silly or too powerful,
-// or just want fighter type wanderers.
-// #define USE_SPELLCASTER_AND_RANGER_WANDERER_TEMPLATES
-
-//mv: (new 9 Aug 01) switches on new rivers & lakes code
-#define USE_RIVERS
-
-//mv: (new 9 Aug 01) switches on new unrands
-#define USE_NEW_UNRANDS
-
-// mv: (new 9 Aug 01) turns off missile trails, might be slow on some computers
-// #define MISSILE_TRAILS_OFF
-
-// bwr: allow player to destroy items in inventory (but not equiped items)
-// See comment at items.cc::cmd_destroy_item() for details/issues.
-// #define ALLOW_DESTROY_ITEM_COMMAND
-
-// bwr: set this to non-zero if you want to know the pluses, "runed" status
-// of the monster's weapons in the hiscore file.
-// #define HISCORE_WEAPON_DETAIL 1
-
-// ====================== -----------------------------------------------------
-//jmf: end of new defines
-// ====================== -----------------------------------------------------
-
-
-#ifdef MULTIUSER
- // Define SAVE_DIR to the directory where saves, bones, and score file
- // will go... end it with a '\'. Since all player files will be in the
- // same directory, the players UID will be appended when this option
- // is set.
- //
- // Setting it to nothing or not setting it will cause all game files to
- // be dumped in the current directory.
- //
- // #define SAVE_DIR_PATH "/opt/crawl/lib/"
- #define SAVE_DIR_PATH ""
-
- // will make this little thing go away. Define SAVE_PACKAGE_CMD
- // to a command to compress and bundle the save game files into a
- // single unit... the two %s will be replaced with the players
- // save file name. Define LOAD_UNPACKAGE_CMD to undo this process
- // the %s is the same as above.
- //
- // PACKAGE_SUFFIX is used when the package file name is needed
- //
- // Comment these lines out if you want to leave the save files uncompressed.
- //
- // #define SAVE_PACKAGE_CMD "/usr/bin/zip -m -q -j -1 %s.zip %s.*"
- // #define LOAD_UNPACKAGE_CMD "/usr/bin/unzip -q -o %s.zip -d" SAVE_DIR_PATH
- // #define PACKAGE_SUFFIX ".zip"
-
- // This provides some rudimentary protection against people using
- // save file cheats on multi-user systems.
- #define DO_ANTICHEAT_CHECKS
-
- // This defines the chmod permissions for score and bones files.
- #define SHARED_FILES_CHMOD_PRIVATE 0664
- #define SHARED_FILES_CHMOD_PUBLIC 0664
-
- // If we're on a multiuser system, file locking of shared files is
- // very important (else things will just keep getting corrupted)
- #define USE_FILE_LOCKING
-
- // Define this if you'd rather have the game block on locked files,
- // commenting it will poll the file lock once a second for thirty
- // seconds before giving up.
- #define USE_BLOCKING_LOCK
-
-// some files needed for file locking
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#endif
-
-// ===========================================================================
-// Misc
-// ===========================================================================
-#if HAS_NAMESPACES
- using namespace std;
-#endif
-
-// Uncomment these if you can't find these functions on your system
-// #define NEED_USLEEP
-// #define NEED_SNPRINTF
-
-// Must include libutil.h here if one of the above is defined.
-#include "libutil.h"
-
-template < class T >
-inline void UNUSED(const volatile T &)
-{
-} // Note that this generates no code with CodeWarrior or MSVC (if inlining is on).
-
-#endif
diff --git a/stone_soup/crawl-ref/source/Crawl.xcodeproj/project.pbxproj b/stone_soup/crawl-ref/source/Crawl.xcodeproj/project.pbxproj
deleted file mode 100644
index 17b504e3a0..0000000000
--- a/stone_soup/crawl-ref/source/Crawl.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,865 +0,0 @@
-// !$*UTF8*$!
-{
- archiveVersion = 1;
- classes = {
- };
- objectVersion = 42;
- objects = {
-
-/* Begin PBXBuildFile section */
- 7B237E6C0A8EC9D000580F30 /* maps.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237DE50A8EC9D000580F30 /* maps.h */; };
- 7B237E6D0A8EC9D000580F30 /* maps.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237DE60A8EC9D000580F30 /* maps.cc */; };
- 7B237E6E0A8EC9D000580F30 /* mon-pick.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237DE70A8EC9D000580F30 /* mon-pick.h */; };
- 7B237E6F0A8EC9D000580F30 /* mon-pick.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237DE80A8EC9D000580F30 /* mon-pick.cc */; };
- 7B237E700A8EC9D000580F30 /* misc.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237DE90A8EC9D000580F30 /* misc.h */; };
- 7B237E710A8EC9D000580F30 /* insult.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237DEA0A8EC9D000580F30 /* insult.h */; };
- 7B237E720A8EC9D000580F30 /* insult.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237DEB0A8EC9D000580F30 /* insult.cc */; };
- 7B237E730A8EC9D000580F30 /* initfile.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237DEC0A8EC9D000580F30 /* initfile.h */; };
- 7B237E740A8EC9D000580F30 /* overmap.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237DED0A8EC9D000580F30 /* overmap.h */; };
- 7B237E750A8EC9D000580F30 /* overmap.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237DEE0A8EC9D000580F30 /* overmap.cc */; };
- 7B237E760A8EC9D000580F30 /* output.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237DEF0A8EC9D000580F30 /* output.h */; };
- 7B237E770A8EC9D000580F30 /* item_use.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237DF00A8EC9D000580F30 /* item_use.h */; };
- 7B237E780A8EC9D000580F30 /* initfile.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237DF10A8EC9D000580F30 /* initfile.cc */; };
- 7B237E790A8EC9D000580F30 /* hiscores.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237DF20A8EC9D000580F30 /* hiscores.h */; };
- 7B237E7A0A8EC9D000580F30 /* hiscores.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237DF30A8EC9D000580F30 /* hiscores.cc */; };
- 7B237E7B0A8EC9D000580F30 /* travel.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237DF40A8EC9D000580F30 /* travel.h */; };
- 7B237E7C0A8EC9D000580F30 /* travel.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237DF50A8EC9D000580F30 /* travel.cc */; };
- 7B237E7D0A8EC9D000580F30 /* lev-pand.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237DF60A8EC9D000580F30 /* lev-pand.h */; };
- 7B237E7E0A8EC9D000580F30 /* lev-pand.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237DF70A8EC9D000580F30 /* lev-pand.cc */; };
- 7B237E7F0A8EC9D000580F30 /* items.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237DF80A8EC9D000580F30 /* items.h */; };
- 7B237E800A8EC9D000580F30 /* newgame.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237DF90A8EC9D000580F30 /* newgame.cc */; };
- 7B237E810A8EC9D000580F30 /* mutation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237DFA0A8EC9D000580F30 /* mutation.h */; };
- 7B237E820A8EC9D000580F30 /* mutation.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237DFB0A8EC9D000580F30 /* mutation.cc */; };
- 7B237E830A8EC9D000580F30 /* misc.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237DFC0A8EC9D000580F30 /* misc.cc */; };
- 7B237E840A8EC9D000580F30 /* message.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237DFD0A8EC9D000580F30 /* message.h */; };
- 7B237E850A8EC9D000580F30 /* mon-util.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237DFE0A8EC9D000580F30 /* mon-util.h */; };
- 7B237E860A8EC9D000580F30 /* mon-util.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237DFF0A8EC9D000580F30 /* mon-util.cc */; };
- 7B237E870A8EC9D000580F30 /* it_use3.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E000A8EC9D000580F30 /* it_use3.h */; };
- 7B237E880A8EC9D000580F30 /* it_use3.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E010A8EC9D000580F30 /* it_use3.cc */; };
- 7B237E890A8EC9D000580F30 /* it_use2.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E020A8EC9D000580F30 /* it_use2.h */; };
- 7B237E8A0A8EC9D000580F30 /* itemname.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E030A8EC9D000580F30 /* itemname.cc */; };
- 7B237E8B0A8EC9D000580F30 /* command.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E040A8EC9D000580F30 /* command.cc */; };
- 7B237E8C0A8EC9D000580F30 /* describe.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E050A8EC9D000580F30 /* describe.h */; };
- 7B237E8D0A8EC9D000580F30 /* spl-util.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E060A8EC9D000580F30 /* spl-util.h */; };
- 7B237E8E0A8EC9D000580F30 /* spl-util.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E070A8EC9D000580F30 /* spl-util.cc */; };
- 7B237E8F0A8EC9D000580F30 /* randart.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E080A8EC9D000580F30 /* randart.h */; };
- 7B237E900A8EC9D000580F30 /* randart.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E090A8EC9D000580F30 /* randart.cc */; };
- 7B237E910A8EC9D000580F30 /* player.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E0A0A8EC9D000580F30 /* player.h */; };
- 7B237E920A8EC9D000580F30 /* player.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E0B0A8EC9D000580F30 /* player.cc */; };
- 7B237E930A8EC9D000580F30 /* effects.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E0C0A8EC9D000580F30 /* effects.h */; };
- 7B237E940A8EC9D000580F30 /* abl-show.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E0D0A8EC9D000580F30 /* abl-show.cc */; };
- 7B237E950A8EC9D000580F30 /* files.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E0E0A8EC9D000580F30 /* files.cc */; };
- 7B237E960A8EC9D000580F30 /* direct.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E0F0A8EC9D000580F30 /* direct.cc */; };
- 7B237E970A8EC9D000580F30 /* dungeon.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E100A8EC9D000580F30 /* dungeon.h */; };
- 7B237E980A8EC9D000580F30 /* wpn-misc.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E110A8EC9D000580F30 /* wpn-misc.h */; };
- 7B237E990A8EC9D000580F30 /* wpn-misc.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E120A8EC9D000580F30 /* wpn-misc.cc */; };
- 7B237E9A0A8EC9D000580F30 /* view.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E130A8EC9D000580F30 /* view.h */; };
- 7B237E9B0A8EC9D000580F30 /* view.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E140A8EC9D000580F30 /* view.cc */; };
- 7B237E9C0A8EC9D000580F30 /* spl-book.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E150A8EC9D000580F30 /* spl-book.cc */; };
- 7B237E9D0A8EC9D000580F30 /* spells4.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E160A8EC9D000580F30 /* spells4.h */; };
- 7B237E9E0A8EC9D000580F30 /* spells4.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E170A8EC9D000580F30 /* spells4.cc */; };
- 7B237E9F0A8EC9D000580F30 /* spells3.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E180A8EC9D000580F30 /* spells3.h */; };
- 7B237EA00A8EC9D000580F30 /* macro.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E190A8EC9D000580F30 /* macro.h */; };
- 7B237EA10A8EC9D000580F30 /* debug.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E1A0A8EC9D000580F30 /* debug.h */; };
- 7B237EA20A8EC9D000580F30 /* direct.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E1B0A8EC9D000580F30 /* direct.h */; };
- 7B237EA30A8EC9D000580F30 /* decks.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E1C0A8EC9D000580F30 /* decks.h */; };
- 7B237EA40A8EC9D000580F30 /* stuff.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E1D0A8EC9D000580F30 /* stuff.h */; };
- 7B237EA50A8EC9D000580F30 /* stuff.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E1E0A8EC9D000580F30 /* stuff.cc */; };
- 7B237EA60A8EC9D000580F30 /* stash.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E1F0A8EC9D000580F30 /* stash.h */; };
- 7B237EA70A8EC9D000580F30 /* stash.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E200A8EC9D000580F30 /* stash.cc */; };
- 7B237EA80A8EC9D000580F30 /* transfor.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E210A8EC9D000580F30 /* transfor.h */; };
- 7B237EA90A8EC9D000580F30 /* transfor.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E220A8EC9D000580F30 /* transfor.cc */; };
- 7B237EAA0A8EC9D000580F30 /* tags.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E230A8EC9D000580F30 /* tags.h */; };
- 7B237EAB0A8EC9D000580F30 /* tags.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E240A8EC9D000580F30 /* tags.cc */; };
- 7B237EAC0A8EC9D000580F30 /* libutil.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E250A8EC9D000580F30 /* libutil.h */; };
- 7B237EAD0A8EC9D000580F30 /* item_use.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E260A8EC9D000580F30 /* item_use.cc */; };
- 7B237EAE0A8EC9D000580F30 /* acr.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E270A8EC9D000580F30 /* acr.cc */; };
- 7B237EAF0A8EC9D000580F30 /* abyss.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E280A8EC9D000580F30 /* abyss.cc */; };
- 7B237EB00A8EC9D000580F30 /* abl-show.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E290A8EC9D000580F30 /* abl-show.h */; };
- 7B237EB10A8EC9D000580F30 /* chardump.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E2A0A8EC9D000580F30 /* chardump.cc */; };
- 7B237EB20A8EC9D000580F30 /* chardump.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E2B0A8EC9D000580F30 /* chardump.h */; };
- 7B237EB30A8EC9D000580F30 /* beam.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E2C0A8EC9D000580F30 /* beam.cc */; };
- 7B237EB40A8EC9D000580F30 /* beam.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E2D0A8EC9D000580F30 /* beam.h */; };
- 7B237EB50A8EC9D000580F30 /* spl-cast.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E2E0A8EC9D000580F30 /* spl-cast.h */; };
- 7B237EB60A8EC9D000580F30 /* spl-cast.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E2F0A8EC9D000580F30 /* spl-cast.cc */; };
- 7B237EB70A8EC9D000580F30 /* spl-book.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E300A8EC9D000580F30 /* spl-book.h */; };
- 7B237EB80A8EC9D000580F30 /* output.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E310A8EC9D000580F30 /* output.cc */; };
- 7B237EB90A8EC9D000580F30 /* ouch.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E320A8EC9D000580F30 /* ouch.h */; };
- 7B237EBA0A8EC9D000580F30 /* ouch.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E330A8EC9D000580F30 /* ouch.cc */; };
- 7B237EBB0A8EC9D000580F30 /* newgame.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E340A8EC9D000580F30 /* newgame.h */; };
- 7B237EBC0A8EC9D000580F30 /* message.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E350A8EC9D000580F30 /* message.cc */; };
- 7B237EBD0A8EC9D000580F30 /* menu.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E360A8EC9D000580F30 /* menu.h */; };
- 7B237EBE0A8EC9D000580F30 /* menu.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E370A8EC9D000580F30 /* menu.cc */; };
- 7B237EBF0A8EC9D000580F30 /* macro.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E380A8EC9D000580F30 /* macro.cc */; };
- 7B237EC00A8EC9D000580F30 /* shopping.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E390A8EC9D000580F30 /* shopping.cc */; };
- 7B237EC10A8EC9D000580F30 /* religion.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E3A0A8EC9D000580F30 /* religion.h */; };
- 7B237EC20A8EC9D000580F30 /* religion.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E3B0A8EC9D000580F30 /* religion.cc */; };
- 7B237EC30A8EC9D000580F30 /* spells3.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E3C0A8EC9D000580F30 /* spells3.cc */; };
- 7B237EC40A8EC9D000580F30 /* spells2.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E3D0A8EC9D000580F30 /* spells2.h */; };
- 7B237EC50A8EC9D000580F30 /* spells2.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E3E0A8EC9D000580F30 /* spells2.cc */; };
- 7B237EC60A8EC9D000580F30 /* mstuff2.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E3F0A8EC9D000580F30 /* mstuff2.cc */; };
- 7B237EC70A8EC9D000580F30 /* monstuff.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E400A8EC9D000580F30 /* monstuff.h */; };
- 7B237EC80A8EC9D000580F30 /* monstuff.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E410A8EC9D000580F30 /* monstuff.cc */; };
- 7B237EC90A8EC9D000580F30 /* monspeak.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E420A8EC9D000580F30 /* monspeak.h */; };
- 7B237ECA0A8EC9D000580F30 /* delay.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E430A8EC9D000580F30 /* delay.h */; };
- 7B237ECB0A8EC9D000580F30 /* command.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E440A8EC9D000580F30 /* command.h */; };
- 7B237ECC0A8EC9D000580F30 /* spells1.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E450A8EC9D000580F30 /* spells1.h */; };
- 7B237ECD0A8EC9D000580F30 /* spells1.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E460A8EC9D000580F30 /* spells1.cc */; };
- 7B237ECE0A8EC9D000580F30 /* skills2.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E470A8EC9D000580F30 /* skills2.h */; };
- 7B237ECF0A8EC9D000580F30 /* skills2.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E480A8EC9D000580F30 /* skills2.cc */; };
- 7B237ED00A8EC9D000580F30 /* decks.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E490A8EC9D000580F30 /* decks.cc */; };
- 7B237ED10A8EC9D000580F30 /* describe.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E4A0A8EC9D000580F30 /* describe.cc */; };
- 7B237ED20A8EC9D000580F30 /* monspeak.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E4B0A8EC9D000580F30 /* monspeak.cc */; };
- 7B237ED30A8EC9D000580F30 /* monplace.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E4C0A8EC9D000580F30 /* monplace.h */; };
- 7B237ED40A8EC9D000580F30 /* monplace.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E4D0A8EC9D000580F30 /* monplace.cc */; };
- 7B237ED50A8EC9D000580F30 /* Kills.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E4E0A8EC9D000580F30 /* Kills.h */; };
- 7B237ED60A8EC9D000580F30 /* Kills.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E4F0A8EC9D000580F30 /* Kills.cc */; };
- 7B237ED70A8EC9D000580F30 /* files.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E500A8EC9D000580F30 /* files.h */; };
- 7B237ED80A8EC9D000580F30 /* fight.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E510A8EC9D000580F30 /* fight.h */; };
- 7B237ED90A8EC9D000580F30 /* effects.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E520A8EC9D000580F30 /* effects.cc */; };
- 7B237EDA0A8EC9D000580F30 /* fight.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E530A8EC9D000580F30 /* fight.cc */; };
- 7B237EDB0A8EC9D000580F30 /* food.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E540A8EC9D000580F30 /* food.cc */; };
- 7B237EDC0A8EC9D000580F30 /* food.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E550A8EC9D000580F30 /* food.h */; };
- 7B237EDD0A8EC9D000580F30 /* clua.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E560A8EC9D000580F30 /* clua.h */; };
- 7B237EDE0A8EC9D000580F30 /* clua.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E570A8EC9D000580F30 /* clua.cc */; };
- 7B237EDF0A8EC9D000580F30 /* cloud.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E580A8EC9D000580F30 /* cloud.h */; };
- 7B237EE00A8EC9D000580F30 /* cloud.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E590A8EC9D000580F30 /* cloud.cc */; };
- 7B237EE10A8EC9D000580F30 /* items.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E5A0A8EC9D000580F30 /* items.cc */; };
- 7B237EE20A8EC9D000580F30 /* itemname.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E5B0A8EC9D000580F30 /* itemname.h */; };
- 7B237EE30A8EC9D000580F30 /* skills.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E5C0A8EC9D000580F30 /* skills.h */; };
- 7B237EE40A8EC9D000580F30 /* skills.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E5D0A8EC9D000580F30 /* skills.cc */; };
- 7B237EE50A8EC9D000580F30 /* shopping.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E5E0A8EC9D000580F30 /* shopping.h */; };
- 7B237EE60A8EC9D000580F30 /* it_use2.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E5F0A8EC9D000580F30 /* it_use2.cc */; };
- 7B237EE70A8EC9D000580F30 /* invent.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E600A8EC9D000580F30 /* invent.h */; };
- 7B237EE80A8EC9D000580F30 /* invent.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E610A8EC9D000580F30 /* invent.cc */; };
- 7B237EE90A8EC9D000580F30 /* libutil.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E620A8EC9D000580F30 /* libutil.cc */; };
- 7B237EEA0A8EC9D000580F30 /* libunix.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E630A8EC9D000580F30 /* libunix.h */; };
- 7B237EEB0A8EC9D000580F30 /* libunix.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E640A8EC9D000580F30 /* libunix.cc */; };
- 7B237EEC0A8EC9D000580F30 /* abyss.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E650A8EC9D000580F30 /* abyss.h */; };
- 7B237EED0A8EC9D000580F30 /* delay.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E660A8EC9D000580F30 /* delay.cc */; };
- 7B237EEE0A8EC9D000580F30 /* dungeon.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E670A8EC9D000580F30 /* dungeon.cc */; };
- 7B237EEF0A8EC9D000580F30 /* debug.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E680A8EC9D000580F30 /* debug.cc */; };
- 7B237EF00A8EC9D000580F30 /* mt19937ar.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E690A8EC9D000580F30 /* mt19937ar.h */; };
- 7B237EF10A8EC9D000580F30 /* mt19937ar.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B237E6A0A8EC9D000580F30 /* mt19937ar.cc */; };
- 7B237EF20A8EC9D000580F30 /* mstuff2.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7B237E6B0A8EC9D000580F30 /* mstuff2.h */; };
- 7B237F150A8ECD2E00580F30 /* libncurses.5.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 7B237F140A8ECD2E00580F30 /* libncurses.5.dylib */; };
- 7BC222E70ABBB286003A7D9A /* itemprop.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BC222E50ABBB286003A7D9A /* itemprop.cc */; };
- 7BC222E80ABBB286003A7D9A /* itemprop.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7BC222E60ABBB286003A7D9A /* itemprop.h */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXCopyFilesBuildPhase section */
- 8DD76FAF0486AB0100D96B5E /* CopyFiles */ = {
- isa = PBXCopyFilesBuildPhase;
- buildActionMask = 8;
- dstPath = /usr/share/man/man1/;
- dstSubfolderSpec = 0;
- files = (
- 7B237E6C0A8EC9D000580F30 /* maps.h in CopyFiles */,
- 7B237E6E0A8EC9D000580F30 /* mon-pick.h in CopyFiles */,
- 7B237E700A8EC9D000580F30 /* misc.h in CopyFiles */,
- 7B237E710A8EC9D000580F30 /* insult.h in CopyFiles */,
- 7B237E730A8EC9D000580F30 /* initfile.h in CopyFiles */,
- 7B237E740A8EC9D000580F30 /* overmap.h in CopyFiles */,
- 7B237E760A8EC9D000580F30 /* output.h in CopyFiles */,
- 7B237E770A8EC9D000580F30 /* item_use.h in CopyFiles */,
- 7B237E790A8EC9D000580F30 /* hiscores.h in CopyFiles */,
- 7B237E7B0A8EC9D000580F30 /* travel.h in CopyFiles */,
- 7B237E7D0A8EC9D000580F30 /* lev-pand.h in CopyFiles */,
- 7B237E7F0A8EC9D000580F30 /* items.h in CopyFiles */,
- 7B237E810A8EC9D000580F30 /* mutation.h in CopyFiles */,
- 7B237E840A8EC9D000580F30 /* message.h in CopyFiles */,
- 7B237E850A8EC9D000580F30 /* mon-util.h in CopyFiles */,
- 7B237E870A8EC9D000580F30 /* it_use3.h in CopyFiles */,
- 7B237E890A8EC9D000580F30 /* it_use2.h in CopyFiles */,
- 7B237E8C0A8EC9D000580F30 /* describe.h in CopyFiles */,
- 7B237E8D0A8EC9D000580F30 /* spl-util.h in CopyFiles */,
- 7B237E8F0A8EC9D000580F30 /* randart.h in CopyFiles */,
- 7B237E910A8EC9D000580F30 /* player.h in CopyFiles */,
- 7B237E930A8EC9D000580F30 /* effects.h in CopyFiles */,
- 7B237E970A8EC9D000580F30 /* dungeon.h in CopyFiles */,
- 7B237E980A8EC9D000580F30 /* wpn-misc.h in CopyFiles */,
- 7B237E9A0A8EC9D000580F30 /* view.h in CopyFiles */,
- 7B237E9D0A8EC9D000580F30 /* spells4.h in CopyFiles */,
- 7B237E9F0A8EC9D000580F30 /* spells3.h in CopyFiles */,
- 7B237EA00A8EC9D000580F30 /* macro.h in CopyFiles */,
- 7B237EA10A8EC9D000580F30 /* debug.h in CopyFiles */,
- 7B237EA20A8EC9D000580F30 /* direct.h in CopyFiles */,
- 7B237EA30A8EC9D000580F30 /* decks.h in CopyFiles */,
- 7B237EA40A8EC9D000580F30 /* stuff.h in CopyFiles */,
- 7B237EA60A8EC9D000580F30 /* stash.h in CopyFiles */,
- 7B237EA80A8EC9D000580F30 /* transfor.h in CopyFiles */,
- 7B237EAA0A8EC9D000580F30 /* tags.h in CopyFiles */,
- 7B237EAC0A8EC9D000580F30 /* libutil.h in CopyFiles */,
- 7B237EB00A8EC9D000580F30 /* abl-show.h in CopyFiles */,
- 7B237EB20A8EC9D000580F30 /* chardump.h in CopyFiles */,
- 7B237EB40A8EC9D000580F30 /* beam.h in CopyFiles */,
- 7B237EB50A8EC9D000580F30 /* spl-cast.h in CopyFiles */,
- 7B237EB70A8EC9D000580F30 /* spl-book.h in CopyFiles */,
- 7B237EB90A8EC9D000580F30 /* ouch.h in CopyFiles */,
- 7B237EBB0A8EC9D000580F30 /* newgame.h in CopyFiles */,
- 7B237EBD0A8EC9D000580F30 /* menu.h in CopyFiles */,
- 7B237EC10A8EC9D000580F30 /* religion.h in CopyFiles */,
- 7B237EC40A8EC9D000580F30 /* spells2.h in CopyFiles */,
- 7B237EC70A8EC9D000580F30 /* monstuff.h in CopyFiles */,
- 7B237EC90A8EC9D000580F30 /* monspeak.h in CopyFiles */,
- 7B237ECA0A8EC9D000580F30 /* delay.h in CopyFiles */,
- 7B237ECB0A8EC9D000580F30 /* command.h in CopyFiles */,
- 7B237ECC0A8EC9D000580F30 /* spells1.h in CopyFiles */,
- 7B237ECE0A8EC9D000580F30 /* skills2.h in CopyFiles */,
- 7B237ED30A8EC9D000580F30 /* monplace.h in CopyFiles */,
- 7B237ED50A8EC9D000580F30 /* Kills.h in CopyFiles */,
- 7B237ED70A8EC9D000580F30 /* files.h in CopyFiles */,
- 7B237ED80A8EC9D000580F30 /* fight.h in CopyFiles */,
- 7B237EDC0A8EC9D000580F30 /* food.h in CopyFiles */,
- 7B237EDD0A8EC9D000580F30 /* clua.h in CopyFiles */,
- 7B237EDF0A8EC9D000580F30 /* cloud.h in CopyFiles */,
- 7B237EE20A8EC9D000580F30 /* itemname.h in CopyFiles */,
- 7B237EE30A8EC9D000580F30 /* skills.h in CopyFiles */,
- 7B237EE50A8EC9D000580F30 /* shopping.h in CopyFiles */,
- 7B237EE70A8EC9D000580F30 /* invent.h in CopyFiles */,
- 7B237EEA0A8EC9D000580F30 /* libunix.h in CopyFiles */,
- 7B237EEC0A8EC9D000580F30 /* abyss.h in CopyFiles */,
- 7B237EF00A8EC9D000580F30 /* mt19937ar.h in CopyFiles */,
- 7B237EF20A8EC9D000580F30 /* mstuff2.h in CopyFiles */,
- 7BC222E80ABBB286003A7D9A /* itemprop.h in CopyFiles */,
- );
- runOnlyForDeploymentPostprocessing = 1;
- };
-/* End PBXCopyFilesBuildPhase section */
-
-/* Begin PBXFileReference section */
- 7B237DE50A8EC9D000580F30 /* maps.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = maps.h; sourceTree = "<group>"; };
- 7B237DE60A8EC9D000580F30 /* maps.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = maps.cc; sourceTree = "<group>"; };
- 7B237DE70A8EC9D000580F30 /* mon-pick.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = "mon-pick.h"; sourceTree = "<group>"; };
- 7B237DE80A8EC9D000580F30 /* mon-pick.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = "mon-pick.cc"; sourceTree = "<group>"; };
- 7B237DE90A8EC9D000580F30 /* misc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = misc.h; sourceTree = "<group>"; };
- 7B237DEA0A8EC9D000580F30 /* insult.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = insult.h; sourceTree = "<group>"; };
- 7B237DEB0A8EC9D000580F30 /* insult.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = insult.cc; sourceTree = "<group>"; };
- 7B237DEC0A8EC9D000580F30 /* initfile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = initfile.h; sourceTree = "<group>"; };
- 7B237DED0A8EC9D000580F30 /* overmap.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = overmap.h; sourceTree = "<group>"; };
- 7B237DEE0A8EC9D000580F30 /* overmap.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = overmap.cc; sourceTree = "<group>"; };
- 7B237DEF0A8EC9D000580F30 /* output.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = output.h; sourceTree = "<group>"; };
- 7B237DF00A8EC9D000580F30 /* item_use.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = item_use.h; sourceTree = "<group>"; };
- 7B237DF10A8EC9D000580F30 /* initfile.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = initfile.cc; sourceTree = "<group>"; };
- 7B237DF20A8EC9D000580F30 /* hiscores.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = hiscores.h; sourceTree = "<group>"; };
- 7B237DF30A8EC9D000580F30 /* hiscores.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = hiscores.cc; sourceTree = "<group>"; };
- 7B237DF40A8EC9D000580F30 /* travel.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = travel.h; sourceTree = "<group>"; };
- 7B237DF50A8EC9D000580F30 /* travel.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = travel.cc; sourceTree = "<group>"; };
- 7B237DF60A8EC9D000580F30 /* lev-pand.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = "lev-pand.h"; sourceTree = "<group>"; };
- 7B237DF70A8EC9D000580F30 /* lev-pand.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = "lev-pand.cc"; sourceTree = "<group>"; };
- 7B237DF80A8EC9D000580F30 /* items.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = items.h; sourceTree = "<group>"; };
- 7B237DF90A8EC9D000580F30 /* newgame.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = newgame.cc; sourceTree = "<group>"; };
- 7B237DFA0A8EC9D000580F30 /* mutation.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = mutation.h; sourceTree = "<group>"; };
- 7B237DFB0A8EC9D000580F30 /* mutation.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = mutation.cc; sourceTree = "<group>"; };
- 7B237DFC0A8EC9D000580F30 /* misc.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = misc.cc; sourceTree = "<group>"; };
- 7B237DFD0A8EC9D000580F30 /* message.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = message.h; sourceTree = "<group>"; };
- 7B237DFE0A8EC9D000580F30 /* mon-util.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = "mon-util.h"; sourceTree = "<group>"; };
- 7B237DFF0A8EC9D000580F30 /* mon-util.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = "mon-util.cc"; sourceTree = "<group>"; };
- 7B237E000A8EC9D000580F30 /* it_use3.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = it_use3.h; sourceTree = "<group>"; };
- 7B237E010A8EC9D000580F30 /* it_use3.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = it_use3.cc; sourceTree = "<group>"; };
- 7B237E020A8EC9D000580F30 /* it_use2.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = it_use2.h; sourceTree = "<group>"; };
- 7B237E030A8EC9D000580F30 /* itemname.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = itemname.cc; sourceTree = "<group>"; };
- 7B237E040A8EC9D000580F30 /* command.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = command.cc; sourceTree = "<group>"; };
- 7B237E050A8EC9D000580F30 /* describe.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = describe.h; sourceTree = "<group>"; };
- 7B237E060A8EC9D000580F30 /* spl-util.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = "spl-util.h"; sourceTree = "<group>"; };
- 7B237E070A8EC9D000580F30 /* spl-util.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = "spl-util.cc"; sourceTree = "<group>"; };
- 7B237E080A8EC9D000580F30 /* randart.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = randart.h; sourceTree = "<group>"; };
- 7B237E090A8EC9D000580F30 /* randart.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = randart.cc; sourceTree = "<group>"; };
- 7B237E0A0A8EC9D000580F30 /* player.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = player.h; sourceTree = "<group>"; };
- 7B237E0B0A8EC9D000580F30 /* player.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = player.cc; sourceTree = "<group>"; };
- 7B237E0C0A8EC9D000580F30 /* effects.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = effects.h; sourceTree = "<group>"; };
- 7B237E0D0A8EC9D000580F30 /* abl-show.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = "abl-show.cc"; sourceTree = "<group>"; };
- 7B237E0E0A8EC9D000580F30 /* files.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = files.cc; sourceTree = "<group>"; };
- 7B237E0F0A8EC9D000580F30 /* direct.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = direct.cc; sourceTree = "<group>"; };
- 7B237E100A8EC9D000580F30 /* dungeon.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = dungeon.h; sourceTree = "<group>"; };
- 7B237E110A8EC9D000580F30 /* wpn-misc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = "wpn-misc.h"; sourceTree = "<group>"; };
- 7B237E120A8EC9D000580F30 /* wpn-misc.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = "wpn-misc.cc"; sourceTree = "<group>"; };
- 7B237E130A8EC9D000580F30 /* view.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = view.h; sourceTree = "<group>"; };
- 7B237E140A8EC9D000580F30 /* view.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = view.cc; sourceTree = "<group>"; };
- 7B237E150A8EC9D000580F30 /* spl-book.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = "spl-book.cc"; sourceTree = "<group>"; };
- 7B237E160A8EC9D000580F30 /* spells4.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = spells4.h; sourceTree = "<group>"; };
- 7B237E170A8EC9D000580F30 /* spells4.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = spells4.cc; sourceTree = "<group>"; };
- 7B237E180A8EC9D000580F30 /* spells3.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = spells3.h; sourceTree = "<group>"; };
- 7B237E190A8EC9D000580F30 /* macro.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = macro.h; sourceTree = "<group>"; };
- 7B237E1A0A8EC9D000580F30 /* debug.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = debug.h; sourceTree = "<group>"; };
- 7B237E1B0A8EC9D000580F30 /* direct.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = direct.h; sourceTree = "<group>"; };
- 7B237E1C0A8EC9D000580F30 /* decks.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = decks.h; sourceTree = "<group>"; };
- 7B237E1D0A8EC9D000580F30 /* stuff.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = stuff.h; sourceTree = "<group>"; };
- 7B237E1E0A8EC9D000580F30 /* stuff.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = stuff.cc; sourceTree = "<group>"; };
- 7B237E1F0A8EC9D000580F30 /* stash.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = stash.h; sourceTree = "<group>"; };
- 7B237E200A8EC9D000580F30 /* stash.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = stash.cc; sourceTree = "<group>"; };
- 7B237E210A8EC9D000580F30 /* transfor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = transfor.h; sourceTree = "<group>"; };
- 7B237E220A8EC9D000580F30 /* transfor.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = transfor.cc; sourceTree = "<group>"; };
- 7B237E230A8EC9D000580F30 /* tags.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = tags.h; sourceTree = "<group>"; };
- 7B237E240A8EC9D000580F30 /* tags.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tags.cc; sourceTree = "<group>"; };
- 7B237E250A8EC9D000580F30 /* libutil.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = libutil.h; sourceTree = "<group>"; };
- 7B237E260A8EC9D000580F30 /* item_use.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = item_use.cc; sourceTree = "<group>"; };
- 7B237E270A8EC9D000580F30 /* acr.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = acr.cc; sourceTree = "<group>"; };
- 7B237E280A8EC9D000580F30 /* abyss.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = abyss.cc; sourceTree = "<group>"; };
- 7B237E290A8EC9D000580F30 /* abl-show.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = "abl-show.h"; sourceTree = "<group>"; };
- 7B237E2A0A8EC9D000580F30 /* chardump.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = chardump.cc; sourceTree = "<group>"; };
- 7B237E2B0A8EC9D000580F30 /* chardump.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = chardump.h; sourceTree = "<group>"; };
- 7B237E2C0A8EC9D000580F30 /* beam.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = beam.cc; sourceTree = "<group>"; };
- 7B237E2D0A8EC9D000580F30 /* beam.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = beam.h; sourceTree = "<group>"; };
- 7B237E2E0A8EC9D000580F30 /* spl-cast.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = "spl-cast.h"; sourceTree = "<group>"; };
- 7B237E2F0A8EC9D000580F30 /* spl-cast.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = "spl-cast.cc"; sourceTree = "<group>"; };
- 7B237E300A8EC9D000580F30 /* spl-book.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = "spl-book.h"; sourceTree = "<group>"; };
- 7B237E310A8EC9D000580F30 /* output.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = output.cc; sourceTree = "<group>"; };
- 7B237E320A8EC9D000580F30 /* ouch.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ouch.h; sourceTree = "<group>"; };
- 7B237E330A8EC9D000580F30 /* ouch.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ouch.cc; sourceTree = "<group>"; };
- 7B237E340A8EC9D000580F30 /* newgame.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = newgame.h; sourceTree = "<group>"; };
- 7B237E350A8EC9D000580F30 /* message.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = message.cc; sourceTree = "<group>"; };
- 7B237E360A8EC9D000580F30 /* menu.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = menu.h; sourceTree = "<group>"; };
- 7B237E370A8EC9D000580F30 /* menu.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = menu.cc; sourceTree = "<group>"; };
- 7B237E380A8EC9D000580F30 /* macro.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = macro.cc; sourceTree = "<group>"; };
- 7B237E390A8EC9D000580F30 /* shopping.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = shopping.cc; sourceTree = "<group>"; };
- 7B237E3A0A8EC9D000580F30 /* religion.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = religion.h; sourceTree = "<group>"; };
- 7B237E3B0A8EC9D000580F30 /* religion.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = religion.cc; sourceTree = "<group>"; };
- 7B237E3C0A8EC9D000580F30 /* spells3.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = spells3.cc; sourceTree = "<group>"; };
- 7B237E3D0A8EC9D000580F30 /* spells2.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = spells2.h; sourceTree = "<group>"; };
- 7B237E3E0A8EC9D000580F30 /* spells2.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = spells2.cc; sourceTree = "<group>"; };
- 7B237E3F0A8EC9D000580F30 /* mstuff2.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = mstuff2.cc; sourceTree = "<group>"; };
- 7B237E400A8EC9D000580F30 /* monstuff.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = monstuff.h; sourceTree = "<group>"; };
- 7B237E410A8EC9D000580F30 /* monstuff.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = monstuff.cc; sourceTree = "<group>"; };
- 7B237E420A8EC9D000580F30 /* monspeak.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = monspeak.h; sourceTree = "<group>"; };
- 7B237E430A8EC9D000580F30 /* delay.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = delay.h; sourceTree = "<group>"; };
- 7B237E440A8EC9D000580F30 /* command.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = command.h; sourceTree = "<group>"; };
- 7B237E450A8EC9D000580F30 /* spells1.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = spells1.h; sourceTree = "<group>"; };
- 7B237E460A8EC9D000580F30 /* spells1.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = spells1.cc; sourceTree = "<group>"; };
- 7B237E470A8EC9D000580F30 /* skills2.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = skills2.h; sourceTree = "<group>"; };
- 7B237E480A8EC9D000580F30 /* skills2.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = skills2.cc; sourceTree = "<group>"; };
- 7B237E490A8EC9D000580F30 /* decks.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = decks.cc; sourceTree = "<group>"; };
- 7B237E4A0A8EC9D000580F30 /* describe.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = describe.cc; sourceTree = "<group>"; };
- 7B237E4B0A8EC9D000580F30 /* monspeak.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = monspeak.cc; sourceTree = "<group>"; };
- 7B237E4C0A8EC9D000580F30 /* monplace.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = monplace.h; sourceTree = "<group>"; };
- 7B237E4D0A8EC9D000580F30 /* monplace.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = monplace.cc; sourceTree = "<group>"; };
- 7B237E4E0A8EC9D000580F30 /* Kills.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Kills.h; sourceTree = "<group>"; };
- 7B237E4F0A8EC9D000580F30 /* Kills.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Kills.cc; sourceTree = "<group>"; };
- 7B237E500A8EC9D000580F30 /* files.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = files.h; sourceTree = "<group>"; };
- 7B237E510A8EC9D000580F30 /* fight.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = fight.h; sourceTree = "<group>"; };
- 7B237E520A8EC9D000580F30 /* effects.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = effects.cc; sourceTree = "<group>"; };
- 7B237E530A8EC9D000580F30 /* fight.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = fight.cc; sourceTree = "<group>"; };
- 7B237E540A8EC9D000580F30 /* food.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = food.cc; sourceTree = "<group>"; };
- 7B237E550A8EC9D000580F30 /* food.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = food.h; sourceTree = "<group>"; };
- 7B237E560A8EC9D000580F30 /* clua.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = clua.h; sourceTree = "<group>"; };
- 7B237E570A8EC9D000580F30 /* clua.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = clua.cc; sourceTree = "<group>"; };
- 7B237E580A8EC9D000580F30 /* cloud.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cloud.h; sourceTree = "<group>"; };
- 7B237E590A8EC9D000580F30 /* cloud.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = cloud.cc; sourceTree = "<group>"; };
- 7B237E5A0A8EC9D000580F30 /* items.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = items.cc; sourceTree = "<group>"; };
- 7B237E5B0A8EC9D000580F30 /* itemname.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = itemname.h; sourceTree = "<group>"; };
- 7B237E5C0A8EC9D000580F30 /* skills.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = skills.h; sourceTree = "<group>"; };
- 7B237E5D0A8EC9D000580F30 /* skills.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = skills.cc; sourceTree = "<group>"; };
- 7B237E5E0A8EC9D000580F30 /* shopping.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = shopping.h; sourceTree = "<group>"; };
- 7B237E5F0A8EC9D000580F30 /* it_use2.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = it_use2.cc; sourceTree = "<group>"; };
- 7B237E600A8EC9D000580F30 /* invent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = invent.h; sourceTree = "<group>"; };
- 7B237E610A8EC9D000580F30 /* invent.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = invent.cc; sourceTree = "<group>"; };
- 7B237E620A8EC9D000580F30 /* libutil.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = libutil.cc; sourceTree = "<group>"; };
- 7B237E630A8EC9D000580F30 /* libunix.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = libunix.h; sourceTree = "<group>"; };
- 7B237E640A8EC9D000580F30 /* libunix.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = libunix.cc; sourceTree = "<group>"; };
- 7B237E650A8EC9D000580F30 /* abyss.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = abyss.h; sourceTree = "<group>"; };
- 7B237E660A8EC9D000580F30 /* delay.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = delay.cc; sourceTree = "<group>"; };
- 7B237E670A8EC9D000580F30 /* dungeon.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = dungeon.cc; sourceTree = "<group>"; };
- 7B237E680A8EC9D000580F30 /* debug.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = debug.cc; sourceTree = "<group>"; };
- 7B237E690A8EC9D000580F30 /* mt19937ar.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = mt19937ar.h; sourceTree = "<group>"; };
- 7B237E6A0A8EC9D000580F30 /* mt19937ar.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = mt19937ar.cc; sourceTree = "<group>"; };
- 7B237E6B0A8EC9D000580F30 /* mstuff2.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = mstuff2.h; sourceTree = "<group>"; };
- 7B237F140A8ECD2E00580F30 /* libncurses.5.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libncurses.5.dylib; path = /usr/lib/libncurses.5.dylib; sourceTree = "<absolute>"; };
- 7BC222E50ABBB286003A7D9A /* itemprop.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = itemprop.cc; sourceTree = "<group>"; };
- 7BC222E60ABBB286003A7D9A /* itemprop.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = itemprop.h; sourceTree = "<group>"; };
- 8DD76FB20486AB0100D96B5E /* crawl */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "compiled.mach-o.executable"; path = crawl; sourceTree = BUILT_PRODUCTS_DIR; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
- 8DD76FAD0486AB0100D96B5E /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 7B237F150A8ECD2E00580F30 /* libncurses.5.dylib in Frameworks */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
- 08FB7794FE84155DC02AAC07 /* Crawl */ = {
- isa = PBXGroup;
- children = (
- 08FB7795FE84155DC02AAC07 /* Source */,
- 7B237F120A8ECCDE00580F30 /* Libraries */,
- C6A0FF2B0290797F04C91782 /* Documentation */,
- 1AB674ADFE9D54B511CA2CBB /* Products */,
- );
- name = Crawl;
- sourceTree = "<group>";
- };
- 08FB7795FE84155DC02AAC07 /* Source */ = {
- isa = PBXGroup;
- children = (
- 7B237E0D0A8EC9D000580F30 /* abl-show.cc */,
- 7B237E290A8EC9D000580F30 /* abl-show.h */,
- 7B237E280A8EC9D000580F30 /* abyss.cc */,
- 7B237E650A8EC9D000580F30 /* abyss.h */,
- 7B237E270A8EC9D000580F30 /* acr.cc */,
- 7B237E2C0A8EC9D000580F30 /* beam.cc */,
- 7B237E2D0A8EC9D000580F30 /* beam.h */,
- 7B237E2A0A8EC9D000580F30 /* chardump.cc */,
- 7B237E2B0A8EC9D000580F30 /* chardump.h */,
- 7B237E590A8EC9D000580F30 /* cloud.cc */,
- 7B237E580A8EC9D000580F30 /* cloud.h */,
- 7B237E570A8EC9D000580F30 /* clua.cc */,
- 7B237E560A8EC9D000580F30 /* clua.h */,
- 7B237E040A8EC9D000580F30 /* command.cc */,
- 7B237E440A8EC9D000580F30 /* command.h */,
- 7B237E680A8EC9D000580F30 /* debug.cc */,
- 7B237E1A0A8EC9D000580F30 /* debug.h */,
- 7B237E490A8EC9D000580F30 /* decks.cc */,
- 7B237E1C0A8EC9D000580F30 /* decks.h */,
- 7B237E660A8EC9D000580F30 /* delay.cc */,
- 7B237E430A8EC9D000580F30 /* delay.h */,
- 7B237E4A0A8EC9D000580F30 /* describe.cc */,
- 7B237E050A8EC9D000580F30 /* describe.h */,
- 7B237E0F0A8EC9D000580F30 /* direct.cc */,
- 7B237E1B0A8EC9D000580F30 /* direct.h */,
- 7B237E670A8EC9D000580F30 /* dungeon.cc */,
- 7B237E100A8EC9D000580F30 /* dungeon.h */,
- 7B237E520A8EC9D000580F30 /* effects.cc */,
- 7B237E0C0A8EC9D000580F30 /* effects.h */,
- 7B237E530A8EC9D000580F30 /* fight.cc */,
- 7B237E510A8EC9D000580F30 /* fight.h */,
- 7B237E0E0A8EC9D000580F30 /* files.cc */,
- 7B237E500A8EC9D000580F30 /* files.h */,
- 7B237E540A8EC9D000580F30 /* food.cc */,
- 7B237E550A8EC9D000580F30 /* food.h */,
- 7B237DF30A8EC9D000580F30 /* hiscores.cc */,
- 7B237DF20A8EC9D000580F30 /* hiscores.h */,
- 7B237DF10A8EC9D000580F30 /* initfile.cc */,
- 7B237DEC0A8EC9D000580F30 /* initfile.h */,
- 7B237DEB0A8EC9D000580F30 /* insult.cc */,
- 7B237DEA0A8EC9D000580F30 /* insult.h */,
- 7B237E610A8EC9D000580F30 /* invent.cc */,
- 7B237E600A8EC9D000580F30 /* invent.h */,
- 7B237E5F0A8EC9D000580F30 /* it_use2.cc */,
- 7B237E020A8EC9D000580F30 /* it_use2.h */,
- 7B237E010A8EC9D000580F30 /* it_use3.cc */,
- 7B237E000A8EC9D000580F30 /* it_use3.h */,
- 7B237E260A8EC9D000580F30 /* item_use.cc */,
- 7B237DF00A8EC9D000580F30 /* item_use.h */,
- 7B237E030A8EC9D000580F30 /* itemname.cc */,
- 7B237E5B0A8EC9D000580F30 /* itemname.h */,
- 7BC222E50ABBB286003A7D9A /* itemprop.cc */,
- 7BC222E60ABBB286003A7D9A /* itemprop.h */,
- 7B237E5A0A8EC9D000580F30 /* items.cc */,
- 7B237DF80A8EC9D000580F30 /* items.h */,
- 7B237E4F0A8EC9D000580F30 /* Kills.cc */,
- 7B237E4E0A8EC9D000580F30 /* Kills.h */,
- 7B237DF70A8EC9D000580F30 /* lev-pand.cc */,
- 7B237DF60A8EC9D000580F30 /* lev-pand.h */,
- 7B237E640A8EC9D000580F30 /* libunix.cc */,
- 7B237E630A8EC9D000580F30 /* libunix.h */,
- 7B237E620A8EC9D000580F30 /* libutil.cc */,
- 7B237E250A8EC9D000580F30 /* libutil.h */,
- 7B237E380A8EC9D000580F30 /* macro.cc */,
- 7B237E190A8EC9D000580F30 /* macro.h */,
- 7B237DE60A8EC9D000580F30 /* maps.cc */,
- 7B237DE50A8EC9D000580F30 /* maps.h */,
- 7B237E370A8EC9D000580F30 /* menu.cc */,
- 7B237E360A8EC9D000580F30 /* menu.h */,
- 7B237E350A8EC9D000580F30 /* message.cc */,
- 7B237DFD0A8EC9D000580F30 /* message.h */,
- 7B237DFC0A8EC9D000580F30 /* misc.cc */,
- 7B237DE90A8EC9D000580F30 /* misc.h */,
- 7B237DE80A8EC9D000580F30 /* mon-pick.cc */,
- 7B237DE70A8EC9D000580F30 /* mon-pick.h */,
- 7B237DFF0A8EC9D000580F30 /* mon-util.cc */,
- 7B237DFE0A8EC9D000580F30 /* mon-util.h */,
- 7B237E4D0A8EC9D000580F30 /* monplace.cc */,
- 7B237E4C0A8EC9D000580F30 /* monplace.h */,
- 7B237E4B0A8EC9D000580F30 /* monspeak.cc */,
- 7B237E420A8EC9D000580F30 /* monspeak.h */,
- 7B237E410A8EC9D000580F30 /* monstuff.cc */,
- 7B237E400A8EC9D000580F30 /* monstuff.h */,
- 7B237E3F0A8EC9D000580F30 /* mstuff2.cc */,
- 7B237E6B0A8EC9D000580F30 /* mstuff2.h */,
- 7B237E6A0A8EC9D000580F30 /* mt19937ar.cc */,
- 7B237E690A8EC9D000580F30 /* mt19937ar.h */,
- 7B237DFB0A8EC9D000580F30 /* mutation.cc */,
- 7B237DFA0A8EC9D000580F30 /* mutation.h */,
- 7B237DF90A8EC9D000580F30 /* newgame.cc */,
- 7B237E340A8EC9D000580F30 /* newgame.h */,
- 7B237E330A8EC9D000580F30 /* ouch.cc */,
- 7B237E320A8EC9D000580F30 /* ouch.h */,
- 7B237E310A8EC9D000580F30 /* output.cc */,
- 7B237DEF0A8EC9D000580F30 /* output.h */,
- 7B237DEE0A8EC9D000580F30 /* overmap.cc */,
- 7B237DED0A8EC9D000580F30 /* overmap.h */,
- 7B237E0B0A8EC9D000580F30 /* player.cc */,
- 7B237E0A0A8EC9D000580F30 /* player.h */,
- 7B237E090A8EC9D000580F30 /* randart.cc */,
- 7B237E080A8EC9D000580F30 /* randart.h */,
- 7B237E3B0A8EC9D000580F30 /* religion.cc */,
- 7B237E3A0A8EC9D000580F30 /* religion.h */,
- 7B237E390A8EC9D000580F30 /* shopping.cc */,
- 7B237E5E0A8EC9D000580F30 /* shopping.h */,
- 7B237E5D0A8EC9D000580F30 /* skills.cc */,
- 7B237E5C0A8EC9D000580F30 /* skills.h */,
- 7B237E480A8EC9D000580F30 /* skills2.cc */,
- 7B237E470A8EC9D000580F30 /* skills2.h */,
- 7B237E460A8EC9D000580F30 /* spells1.cc */,
- 7B237E450A8EC9D000580F30 /* spells1.h */,
- 7B237E3E0A8EC9D000580F30 /* spells2.cc */,
- 7B237E3D0A8EC9D000580F30 /* spells2.h */,
- 7B237E3C0A8EC9D000580F30 /* spells3.cc */,
- 7B237E180A8EC9D000580F30 /* spells3.h */,
- 7B237E170A8EC9D000580F30 /* spells4.cc */,
- 7B237E160A8EC9D000580F30 /* spells4.h */,
- 7B237E150A8EC9D000580F30 /* spl-book.cc */,
- 7B237E300A8EC9D000580F30 /* spl-book.h */,
- 7B237E2F0A8EC9D000580F30 /* spl-cast.cc */,
- 7B237E2E0A8EC9D000580F30 /* spl-cast.h */,
- 7B237E070A8EC9D000580F30 /* spl-util.cc */,
- 7B237E060A8EC9D000580F30 /* spl-util.h */,
- 7B237E200A8EC9D000580F30 /* stash.cc */,
- 7B237E1F0A8EC9D000580F30 /* stash.h */,
- 7B237E1E0A8EC9D000580F30 /* stuff.cc */,
- 7B237E1D0A8EC9D000580F30 /* stuff.h */,
- 7B237E240A8EC9D000580F30 /* tags.cc */,
- 7B237E230A8EC9D000580F30 /* tags.h */,
- 7B237E220A8EC9D000580F30 /* transfor.cc */,
- 7B237E210A8EC9D000580F30 /* transfor.h */,
- 7B237DF50A8EC9D000580F30 /* travel.cc */,
- 7B237DF40A8EC9D000580F30 /* travel.h */,
- 7B237E140A8EC9D000580F30 /* view.cc */,
- 7B237E130A8EC9D000580F30 /* view.h */,
- 7B237E120A8EC9D000580F30 /* wpn-misc.cc */,
- 7B237E110A8EC9D000580F30 /* wpn-misc.h */,
- );
- name = Source;
- sourceTree = "<group>";
- };
- 1AB674ADFE9D54B511CA2CBB /* Products */ = {
- isa = PBXGroup;
- children = (
- 8DD76FB20486AB0100D96B5E /* crawl */,
- );
- name = Products;
- sourceTree = "<group>";
- };
- 7B237F120A8ECCDE00580F30 /* Libraries */ = {
- isa = PBXGroup;
- children = (
- 7B237F140A8ECD2E00580F30 /* libncurses.5.dylib */,
- );
- name = Libraries;
- sourceTree = "<group>";
- };
- C6A0FF2B0290797F04C91782 /* Documentation */ = {
- isa = PBXGroup;
- children = (
- );
- name = Documentation;
- sourceTree = "<group>";
- };
-/* End PBXGroup section */
-
-/* Begin PBXNativeTarget section */
- 8DD76FA90486AB0100D96B5E /* Crawl */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = 1DEB928508733DD80010E9CD /* Build configuration list for PBXNativeTarget "Crawl" */;
- buildPhases = (
- 8DD76FAB0486AB0100D96B5E /* Sources */,
- 8DD76FAD0486AB0100D96B5E /* Frameworks */,
- 8DD76FAF0486AB0100D96B5E /* CopyFiles */,
- );
- buildRules = (
- );
- dependencies = (
- );
- name = Crawl;
- productInstallPath = "$(HOME)/bin";
- productName = Crawl;
- productReference = 8DD76FB20486AB0100D96B5E /* crawl */;
- productType = "com.apple.product-type.tool";
- };
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
- 08FB7793FE84155DC02AAC07 /* Project object */ = {
- isa = PBXProject;
- buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "Crawl" */;
- hasScannedForEncodings = 1;
- mainGroup = 08FB7794FE84155DC02AAC07 /* Crawl */;
- projectDirPath = "";
- targets = (
- 8DD76FA90486AB0100D96B5E /* Crawl */,
- );
- };
-/* End PBXProject section */
-
-/* Begin PBXSourcesBuildPhase section */
- 8DD76FAB0486AB0100D96B5E /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 7B237E6D0A8EC9D000580F30 /* maps.cc in Sources */,
- 7B237E6F0A8EC9D000580F30 /* mon-pick.cc in Sources */,
- 7B237E720A8EC9D000580F30 /* insult.cc in Sources */,
- 7B237E750A8EC9D000580F30 /* overmap.cc in Sources */,
- 7B237E780A8EC9D000580F30 /* initfile.cc in Sources */,
- 7B237E7A0A8EC9D000580F30 /* hiscores.cc in Sources */,
- 7B237E7C0A8EC9D000580F30 /* travel.cc in Sources */,
- 7B237E7E0A8EC9D000580F30 /* lev-pand.cc in Sources */,
- 7B237E800A8EC9D000580F30 /* newgame.cc in Sources */,
- 7B237E820A8EC9D000580F30 /* mutation.cc in Sources */,
- 7B237E830A8EC9D000580F30 /* misc.cc in Sources */,
- 7B237E860A8EC9D000580F30 /* mon-util.cc in Sources */,
- 7B237E880A8EC9D000580F30 /* it_use3.cc in Sources */,
- 7B237E8A0A8EC9D000580F30 /* itemname.cc in Sources */,
- 7B237E8B0A8EC9D000580F30 /* command.cc in Sources */,
- 7B237E8E0A8EC9D000580F30 /* spl-util.cc in Sources */,
- 7B237E900A8EC9D000580F30 /* randart.cc in Sources */,
- 7B237E920A8EC9D000580F30 /* player.cc in Sources */,
- 7B237E940A8EC9D000580F30 /* abl-show.cc in Sources */,
- 7B237E950A8EC9D000580F30 /* files.cc in Sources */,
- 7B237E960A8EC9D000580F30 /* direct.cc in Sources */,
- 7B237E990A8EC9D000580F30 /* wpn-misc.cc in Sources */,
- 7B237E9B0A8EC9D000580F30 /* view.cc in Sources */,
- 7B237E9C0A8EC9D000580F30 /* spl-book.cc in Sources */,
- 7B237E9E0A8EC9D000580F30 /* spells4.cc in Sources */,
- 7B237EA50A8EC9D000580F30 /* stuff.cc in Sources */,
- 7B237EA70A8EC9D000580F30 /* stash.cc in Sources */,
- 7B237EA90A8EC9D000580F30 /* transfor.cc in Sources */,
- 7B237EAB0A8EC9D000580F30 /* tags.cc in Sources */,
- 7B237EAD0A8EC9D000580F30 /* item_use.cc in Sources */,
- 7B237EAE0A8EC9D000580F30 /* acr.cc in Sources */,
- 7B237EAF0A8EC9D000580F30 /* abyss.cc in Sources */,
- 7B237EB10A8EC9D000580F30 /* chardump.cc in Sources */,
- 7B237EB30A8EC9D000580F30 /* beam.cc in Sources */,
- 7B237EB60A8EC9D000580F30 /* spl-cast.cc in Sources */,
- 7B237EB80A8EC9D000580F30 /* output.cc in Sources */,
- 7B237EBA0A8EC9D000580F30 /* ouch.cc in Sources */,
- 7B237EBC0A8EC9D000580F30 /* message.cc in Sources */,
- 7B237EBE0A8EC9D000580F30 /* menu.cc in Sources */,
- 7B237EBF0A8EC9D000580F30 /* macro.cc in Sources */,
- 7B237EC00A8EC9D000580F30 /* shopping.cc in Sources */,
- 7B237EC20A8EC9D000580F30 /* religion.cc in Sources */,
- 7B237EC30A8EC9D000580F30 /* spells3.cc in Sources */,
- 7B237EC50A8EC9D000580F30 /* spells2.cc in Sources */,
- 7B237EC60A8EC9D000580F30 /* mstuff2.cc in Sources */,
- 7B237EC80A8EC9D000580F30 /* monstuff.cc in Sources */,
- 7B237ECD0A8EC9D000580F30 /* spells1.cc in Sources */,
- 7B237ECF0A8EC9D000580F30 /* skills2.cc in Sources */,
- 7B237ED00A8EC9D000580F30 /* decks.cc in Sources */,
- 7B237ED10A8EC9D000580F30 /* describe.cc in Sources */,
- 7B237ED20A8EC9D000580F30 /* monspeak.cc in Sources */,
- 7B237ED40A8EC9D000580F30 /* monplace.cc in Sources */,
- 7B237ED60A8EC9D000580F30 /* Kills.cc in Sources */,
- 7B237ED90A8EC9D000580F30 /* effects.cc in Sources */,
- 7B237EDA0A8EC9D000580F30 /* fight.cc in Sources */,
- 7B237EDB0A8EC9D000580F30 /* food.cc in Sources */,
- 7B237EDE0A8EC9D000580F30 /* clua.cc in Sources */,
- 7B237EE00A8EC9D000580F30 /* cloud.cc in Sources */,
- 7B237EE10A8EC9D000580F30 /* items.cc in Sources */,
- 7B237EE40A8EC9D000580F30 /* skills.cc in Sources */,
- 7B237EE60A8EC9D000580F30 /* it_use2.cc in Sources */,
- 7B237EE80A8EC9D000580F30 /* invent.cc in Sources */,
- 7B237EE90A8EC9D000580F30 /* libutil.cc in Sources */,
- 7B237EEB0A8EC9D000580F30 /* libunix.cc in Sources */,
- 7B237EED0A8EC9D000580F30 /* delay.cc in Sources */,
- 7B237EEE0A8EC9D000580F30 /* dungeon.cc in Sources */,
- 7B237EEF0A8EC9D000580F30 /* debug.cc in Sources */,
- 7B237EF10A8EC9D000580F30 /* mt19937ar.cc in Sources */,
- 7BC222E70ABBB286003A7D9A /* itemprop.cc in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXSourcesBuildPhase section */
-
-/* Begin XCBuildConfiguration section */
- 1DEB928608733DD80010E9CD /* Development */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- COPY_PHASE_STRIP = NO;
- GCC_ENABLE_FIX_AND_CONTINUE = YES;
- GCC_OPTIMIZATION_LEVEL = 1;
- GCC_PREPROCESSOR_DEFINITIONS = OSX;
- PRODUCT_NAME = crawl;
- ZERO_LINK = YES;
- };
- name = Development;
- };
- 1DEB928A08733DD80010E9CD /* Development */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- GCC_PREPROCESSOR_DEFINITIONS = OSX;
- GCC_TREAT_WARNINGS_AS_ERRORS = YES;
- GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
- GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
- GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
- GCC_WARN_MISSING_PARENTHESES = YES;
- GCC_WARN_PEDANTIC = YES;
- GCC_WARN_SHADOW = NO;
- GCC_WARN_SIGN_COMPARE = YES;
- GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_LABEL = YES;
- GCC_WARN_UNUSED_VALUE = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- MACOSX_DEPLOYMENT_TARGET_i386 = 10.4;
- MACOSX_DEPLOYMENT_TARGET_ppc = 10.3;
- PREBINDING = NO;
- SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
- };
- name = Development;
- };
- 7B97C01F0A8ECFD700CE8936 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- COPY_PHASE_STRIP = NO;
- GCC_ENABLE_FIX_AND_CONTINUE = YES;
- GCC_OPTIMIZATION_LEVEL = 1;
- GCC_PREPROCESSOR_DEFINITIONS = (
- OSX,
- WIZARD,
- DEBUG,
- DEBUG_ITEM_SCAN,
- FULLDEBUG,
- );
- PRODUCT_NAME = crawl;
- ZERO_LINK = YES;
- };
- name = Debug;
- };
- 7B97C0200A8ECFD700CE8936 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- GCC_PREPROCESSOR_DEFINITIONS = (
- OSX,
- DEBUG,
- FULLDEBUG,
- DEBUG_ITEM_SCAN,
- WIZARD,
- );
- GCC_TREAT_WARNINGS_AS_ERRORS = YES;
- GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
- GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES;
- GCC_WARN_UNUSED_LABEL = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- MACOSX_DEPLOYMENT_TARGET_i386 = 10.4;
- MACOSX_DEPLOYMENT_TARGET_ppc = 10.3;
- PREBINDING = NO;
- SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
- };
- name = Debug;
- };
- 7B97C0240A8ED2AB00CE8936 /* Wizard */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- COPY_PHASE_STRIP = NO;
- GCC_ENABLE_FIX_AND_CONTINUE = YES;
- GCC_OPTIMIZATION_LEVEL = 1;
- GCC_PREPROCESSOR_DEFINITIONS = (
- OSX,
- WIZARD,
- DEBUG,
- DEBUG_ITEM_SCAN,
- );
- PRODUCT_NAME = crawl;
- ZERO_LINK = YES;
- };
- name = Wizard;
- };
- 7B97C0250A8ED2AB00CE8936 /* Wizard */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- GCC_PREPROCESSOR_DEFINITIONS = (
- OSX,
- WIZARD,
- DEBUG,
- DEBUG_ITEM_SCAN,
- );
- GCC_TREAT_WARNINGS_AS_ERRORS = YES;
- GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
- GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES;
- GCC_WARN_UNUSED_LABEL = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- MACOSX_DEPLOYMENT_TARGET_i386 = 10.4;
- MACOSX_DEPLOYMENT_TARGET_ppc = 10.3;
- PREBINDING = NO;
- SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
- };
- name = Wizard;
- };
- 7B97C0260A8ED34400CE8936 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ARCHS = (
- ppc,
- i386,
- );
- GCC_ENABLE_FIX_AND_CONTINUE = NO;
- GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
- GCC_OPTIMIZATION_LEVEL = 1;
- GCC_PREPROCESSOR_DEFINITIONS = OSX;
- PRODUCT_NAME = crawl;
- ZERO_LINK = NO;
- };
- name = Release;
- };
- 7B97C0270A8ED34400CE8936 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ARCHS = (
- i386,
- ppc,
- );
- GCC_PREPROCESSOR_DEFINITIONS = OSX;
- GCC_TREAT_WARNINGS_AS_ERRORS = YES;
- GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
- GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES;
- GCC_WARN_UNUSED_LABEL = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- MACOSX_DEPLOYMENT_TARGET_i386 = 10.4;
- MACOSX_DEPLOYMENT_TARGET_ppc = 10.3;
- PREBINDING = NO;
- SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
- };
- name = Release;
- };
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
- 1DEB928508733DD80010E9CD /* Build configuration list for PBXNativeTarget "Crawl" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 1DEB928608733DD80010E9CD /* Development */,
- 7B97C0260A8ED34400CE8936 /* Release */,
- 7B97C01F0A8ECFD700CE8936 /* Debug */,
- 7B97C0240A8ED2AB00CE8936 /* Wizard */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Development;
- };
- 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "Crawl" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 1DEB928A08733DD80010E9CD /* Development */,
- 7B97C0270A8ED34400CE8936 /* Release */,
- 7B97C0200A8ECFD700CE8936 /* Debug */,
- 7B97C0250A8ED2AB00CE8936 /* Wizard */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Development;
- };
-/* End XCConfigurationList section */
- };
- rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
-}
diff --git a/stone_soup/crawl-ref/source/FixAry.h b/stone_soup/crawl-ref/source/FixAry.h
deleted file mode 100644
index 99f802e2f3..0000000000
--- a/stone_soup/crawl-ref/source/FixAry.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * File: FixAry.h
- * Summary: Fixed size 2D vector class that asserts if you do something bad.
- * Written by: Jesse Jones
- *
- * Change History (most recent first):
- *
- * <1> 6/16/00 JDJ Created
- */
-
-#ifndef FIXARY_H
-#define FIXARY_H
-
-#include "FixVec.h"
-
-
-// ==========================================================================
-// class FixedArray
-// ==========================================================================
-template <class TYPE, int WIDTH, int HEIGHT> class FixedArray {
-
-//-----------------------------------
-// Types
-//
-public:
- typedef TYPE value_type;
- typedef TYPE& reference;
- typedef const TYPE& const_reference;
- typedef TYPE* pointer;
- typedef const TYPE* const_pointer;
-
- typedef unsigned long size_type;
- typedef long difference_type;
-
- typedef FixedVector<TYPE, HEIGHT> Column; // operator[] needs to return one of these to avoid breaking client code (if inlining is on there won't be a speed hit)
-
-//-----------------------------------
-// Initialization/Destruction
-//
-public:
- ~FixedArray() {}
-
- FixedArray() {}
-
-//-----------------------------------
-// API
-//
-public:
- // ----- Size -----
- bool empty() const {return WIDTH == 0 || HEIGHT == 0;}
- int size() const {return WIDTH*HEIGHT;}
-
- int width() const {return WIDTH;}
- int height() const {return HEIGHT;}
-
- // ----- Access -----
- Column& operator[](unsigned long index) {return mData[index];}
- const Column& operator[](unsigned long index) const {return mData[index];}
-
-//-----------------------------------
-// Member Data
-//
-protected:
- FixedVector<Column, WIDTH> mData;
-};
-
-
-#endif // FIXARY_H
diff --git a/stone_soup/crawl-ref/source/FixVec.h b/stone_soup/crawl-ref/source/FixVec.h
deleted file mode 100644
index b0afb34e82..0000000000
--- a/stone_soup/crawl-ref/source/FixVec.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * File: FixVec.h
- * Summary: Fixed size vector class that asserts if you do something bad.
- * Written by: Jesse Jones
- *
- * Change History (most recent first):
- *
- * <2> 7/29/00 JDJ Added a variable argument ctor.
- * <1> 6/16/00 JDJ Created
- */
-
-#ifndef FIXVEC_H
-#define FIXVEC_H
-
-#include <stdarg.h>
-
-#include "debug.h"
-
-
-// ==========================================================================
-// class FixedVector
-// ==========================================================================
-
-template <class TYPE, int SIZE> class FixedVector {
-
-//-----------------------------------
-// Types
-//
-public:
- typedef TYPE value_type;
- typedef TYPE& reference;
- typedef const TYPE& const_reference;
- typedef TYPE* pointer;
- typedef const TYPE* const_pointer;
-
- typedef unsigned long size_type;
- typedef long difference_type;
-
- typedef TYPE* iterator;
- typedef const TYPE* const_iterator;
-
-#if 0
-#if MSVC >= 1100
- typedef std::reverse_iterator<const_iterator, const TYPE> const_reverse_iterator;
- typedef std::reverse_iterator<iterator, TYPE> reverse_iterator;
-#else
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
- typedef std::reverse_iterator<iterator> reverse_iterator;
-#endif
-#endif
-
-//-----------------------------------
-// Initialization/Destruction
-//
-public:
- ~FixedVector() {}
-
- FixedVector() {}
-
- FixedVector(TYPE value0, TYPE value1, ...);
- // Allows for something resembling C array initialization, eg
- // instead of "int a[3] = {0, 1, 2}" you'd use "FixedVector<int, 3>
- // a(0, 1, 2)". Note that there must be SIZE arguments.
-
-// public:
-// FixedVector(const FixedVector& rhs);
-//
-// FixedVector& operator=(const FixedVector& rhs);
-
-//-----------------------------------
-// API
-//
-public:
- // ----- Size -----
- bool empty() const {return SIZE == 0;}
- int size() const {return SIZE;}
-
- // ----- Access -----
- TYPE& operator[](unsigned long index) {ASSERT(index < SIZE); return mData[index];}
- const TYPE& operator[](unsigned long index) const {ASSERT(index < SIZE); return mData[index];}
-
- TYPE& front() {ASSERT(SIZE > 0); return mData[0];}
- const TYPE& front() const {ASSERT(SIZE > 0); return mData[0];}
-
- TYPE& back() {ASSERT(SIZE > 0); return mData[SIZE - 1];}
- const TYPE& back() const {ASSERT(SIZE > 0); return mData[SIZE - 1];}
-
- TYPE* buffer() {return mData;}
- const TYPE* buffer() const {return mData;}
-
- // ----- Iterating -----
- iterator begin() {return mData;}
- const_iterator begin() const {return mData;}
-
- iterator end() {return this->begin() + this->size();}
- const_iterator end() const {return this->begin() + this->size();}
-
-// reverse_iterator rbegin() {return reverse_iterator(this->end());}
-// const_reverse_iterator rbegin() const {return const_reverse_iterator(this->end());}
-
-// reverse_iterator rend() {return reverse_iterator(this->begin());}
-// const_reverse_iterator rend() const {return const_reverse_iterator(this->begin());}
-
-//-----------------------------------
-// Member Data
-//
-protected:
- TYPE mData[SIZE];
-};
-
-
-// ==========================================================================
-// Outlined Methods
-// ==========================================================================
-template <class TYPE, int SIZE>
-FixedVector<TYPE, SIZE>::FixedVector(TYPE value0, TYPE value1, ...)
-{
- mData[0] = value0;
- mData[1] = value1;
-
- va_list ap;
- va_start(ap, value1); // second argument is last fixed parameter
-
- for (int index = 2; index < SIZE; index++) {
- TYPE value = va_arg(ap, TYPE);
-
- mData[index] = value;
- }
-
- va_end(ap);
-}
-
-#endif // FIXVEC_H
diff --git a/stone_soup/crawl-ref/source/Kills.cc b/stone_soup/crawl-ref/source/Kills.cc
deleted file mode 100644
index 06f465bb70..0000000000
--- a/stone_soup/crawl-ref/source/Kills.cc
+++ /dev/null
@@ -1,1098 +0,0 @@
-/*
- * File: Kills.cc
- * Summary: Player kill tracking
- * Written by: Darshan Shaligram
- */
-#include "AppHdr.h"
-#include "chardump.h"
-#include "describe.h"
-#include "mon-util.h"
-#include "files.h"
-#include "itemname.h"
-#include "travel.h"
-#include "tags.h"
-#include "Kills.h"
-#include "clua.h"
-#include <algorithm>
-
-#define KILLS_MAJOR_VERSION 4
-#define KILLS_MINOR_VERSION 1
-
-#ifdef CLUA_BINDINGS
-static void kill_lua_filltable(std::vector<kill_exp> &v);
-#endif
-
-
-unsigned short get_packed_place( unsigned char branch, int subdepth,
- char level_type )
-{
- unsigned short place = (unsigned short)
- ( (branch << 8) | subdepth );
- if (level_type == LEVEL_ABYSS || level_type == LEVEL_PANDEMONIUM
- || level_type == LEVEL_LABYRINTH)
- place = (unsigned short) ( (level_type << 8) | 0xFF );
- return place;
-}
-
-unsigned short get_packed_place()
-{
- return get_packed_place( you.where_are_you,
- subdungeon_depth(you.where_are_you, you.your_level),
- you.level_type );
-}
-
-///////////////////////////////////////////////////////////////////////////
-// KillMaster
-//
-
-const char *kill_category_names[] =
-{
- "you",
- "collateral kills",
- "others",
-};
-
-const char *KillMaster::category_name(kill_category kc) const
-{
- if (kc >= KC_YOU && kc < KC_NCATEGORIES)
- return (kill_category_names[kc]);
- return (NULL);
-}
-
-bool KillMaster::empty() const
-{
- for (int i = 0; i < KC_NCATEGORIES; ++i)
- if (!categorized_kills[i].empty())
- return (false);
- return (true);
-}
-
-void KillMaster::save(FILE *file) const
-{
- // Write the version of the kills file
- writeByte(file, KILLS_MAJOR_VERSION);
- writeByte(file, KILLS_MINOR_VERSION);
-
- for (int i = 0; i < KC_NCATEGORIES; ++i)
- categorized_kills[i].save(file);
-}
-
-void KillMaster::load(FILE *file)
-{
- unsigned char major = readByte(file),
- minor = readByte(file);
- if (major != KILLS_MAJOR_VERSION ||
- (minor != KILLS_MINOR_VERSION && minor > 0))
- return ;
-
- for (int i = 0; i < KC_NCATEGORIES; ++i)
- {
- categorized_kills[i].load(file);
- if (!minor)
- break;
- }
-}
-
-void KillMaster::record_kill(const monsters *mon, int killer, bool ispet)
-{
- kill_category kc =
- (killer == KILL_YOU || killer == KILL_YOU_MISSILE)? KC_YOU :
- (ispet)? KC_FRIENDLY :
- KC_OTHER;
- categorized_kills[kc].record_kill(mon);
-}
-
-std::string KillMaster::kill_info() const
-{
- if (empty())
- return ("");
-
- std::string killtext;
-
- bool needseparator = false;
- int categories = 0;
- long grandtotal = 0L;
-
- Kills catkills[KC_NCATEGORIES];
- for (int i = 0; i < KC_NCATEGORIES; ++i)
- {
- int targ = Options.kill_map[i];
- catkills[targ].merge( categorized_kills[i] );
- }
-
- for (int i = KC_YOU; i < KC_NCATEGORIES; ++i)
- {
- if (catkills[i].empty())
- continue;
-
- categories++;
- std::vector<kill_exp> kills;
- long count = catkills[i].get_kills(kills);
- grandtotal += count;
-
- add_kill_info( killtext,
- kills,
- count,
- i == KC_YOU? NULL :
- category_name((kill_category) i),
- needseparator );
- needseparator = true;
- }
-
- std::string grandt;
- if (categories > 1)
- {
- char buf[200];
- snprintf(buf, sizeof buf,
- "Grand Total: %ld creatures vanquished",
- grandtotal);
- grandt = buf;
- }
-
-#ifdef CLUA_BINDINGS
- // Call the kill dump Lua function with null a, to tell it we're done.
- if (!clua.callfn("c_kill_list", "ss", NULL, grandt.c_str()))
-#endif
- {
- // We can sum up ourselves, if Lua doesn't want to.
- // FIXME: I'm not happy with the looks/wording of the grand total
- // count.
- if (categories > 1)
- {
- // Give ourselves a newline first
- killtext += EOL;
- killtext += grandt + EOL;
- }
- }
-
- return killtext;
-}
-
-void KillMaster::add_kill_info(std::string &killtext,
- std::vector<kill_exp> &kills,
- long count,
- const char *category,
- bool separator) const
-{
-#ifdef CLUA_BINDINGS
- // Set a pointer to killtext as a Lua global
- lua_pushlightuserdata(clua.state(), &killtext);
- clua.setregistry("cr_skill");
-
- // Populate a Lua table with kill_exp structs, in the default order,
- // and leave the table on the top of the Lua stack.
- kill_lua_filltable(kills);
-
- if (category)
- lua_pushstring(clua, category);
- else
- lua_pushnil(clua);
-
- lua_pushboolean(clua, separator);
-
- if (!clua.callfn("c_kill_list", 3, 0))
-#endif
- {
-#ifdef CLUA_BINDINGS
- if (clua.error.length())
- {
- killtext += "Lua error:\n";
- killtext += clua.error + "\n\n";
- }
-#endif
- if (separator)
- killtext += EOL;
-
- killtext += "Vanquished Creatures";
- if (category)
- killtext += std::string(" (") + category + ")";
-
- killtext += EOL;
-
- for (int i = 0, sz = kills.size(); i < sz; ++i)
- {
- killtext += " " + kills[i].desc;
- killtext += EOL;
- }
- {
- char numbuf[100];
- snprintf(numbuf, sizeof numbuf,
- "%ld creature%s vanquished." EOL, count,
- count > 1? "s" : "");
- killtext += numbuf;
- }
- }
-}
-
-///////////////////////////////////////////////////////////////////////////
-
-bool Kills::empty() const
-{
- return kills.empty() && ghosts.empty();
-}
-
-void Kills::merge(const Kills &k)
-{
- ghosts.insert( ghosts.end(), k.ghosts.begin(), k.ghosts.end() );
-
- // Regular kills are messier to merge.
- for (kill_map::const_iterator i = k.kills.begin();
- i != k.kills.end(); ++i)
- {
- const kill_monster_desc &kmd = i->first;
- kill_def &k = kills[kmd];
- const kill_def &ko = i->second;
- bool uniq = mons_is_unique(kmd.monnum);
- k.merge(ko, uniq);
- }
-}
-
-void Kills::record_kill(const struct monsters *mon)
-{
- // Handle player ghosts separately.
- if (mon->type == MONS_PLAYER_GHOST || mon->type == MONS_PANDEMONIUM_DEMON)
- {
- record_ghost_kill(mon);
- return ;
- }
-
- // Normal monsters
- // Create a descriptor
- kill_monster_desc descriptor = mon;
-
- kill_def &k = kills[descriptor];
- if (k.kills)
- k.add_kill(mon, get_packed_place());
- else
- k = kill_def(mon);
-}
-
-long Kills::get_kills(std::vector<kill_exp> &all_kills) const
-{
- long count = 0;
- kill_map::const_iterator iter = kills.begin();
- for (; iter != kills.end(); ++iter)
- {
- const kill_monster_desc &md = iter->first;
- const kill_def &k = iter->second;
- all_kills.push_back( kill_exp(k, md) );
- count += k.kills;
- }
-
- ghost_vec::const_iterator gi = ghosts.begin();
- for (; gi != ghosts.end(); ++gi)
- {
- all_kills.push_back( kill_exp(*gi) );
- }
- count += ghosts.size();
-
- std::sort(all_kills.begin(), all_kills.end());
- return (count);
-}
-
-// Takes a packed 'place' and returns a compact stringified place name.
-// XXX: This is done in several other places; a unified function to
-// describe places would be nice.
-std::string short_place_name(unsigned short place)
-{
- unsigned char branch = (unsigned char) ((place >> 8) & 0xFF);
- int lev = place & 0xFF;
-
- const char *s;
- bool level_num = false;
- if (lev == 0xFF)
- {
- switch (branch)
- {
- case LEVEL_ABYSS:
- s = "Abyss";
- break;
- case LEVEL_PANDEMONIUM:
- s = "Pan";
- break;
- case LEVEL_LABYRINTH:
- s = "Lab";
- break;
- default:
- s = "Buggy Badlands";
- break;
- }
- }
- else
- {
- switch (branch)
- {
- case BRANCH_VESTIBULE_OF_HELL:
- s = "Hell";
- break;
- case BRANCH_HALL_OF_BLADES:
- s = "Blade";
- break;
- case BRANCH_ECUMENICAL_TEMPLE:
- s = "Temple";
- break;
- default:
- level_num = true;
- s = (branch == BRANCH_DIS) ? "Dis:" :
- (branch == BRANCH_GEHENNA) ? "Geh:" :
- (branch == BRANCH_COCYTUS) ? "Coc:" :
- (branch == BRANCH_TARTARUS) ? "Tar:" :
- (branch == BRANCH_ORCISH_MINES) ? "Orc:" :
- (branch == BRANCH_HIVE) ? "Hive:" :
- (branch == BRANCH_LAIR) ? "Lair:" :
- (branch == BRANCH_SLIME_PITS) ? "Slime:" :
- (branch == BRANCH_VAULTS) ? "Vault:" :
- (branch == BRANCH_CRYPT) ? "Crypt:" :
- (branch == BRANCH_HALL_OF_ZOT) ? "Zot:" :
- (branch == BRANCH_SNAKE_PIT) ? "Snake:" :
- (branch == BRANCH_ELVEN_HALLS) ? "Elf:" :
- (branch == BRANCH_TOMB) ? "Tomb:" :
- (branch == BRANCH_SWAMP) ? "Swamp:" : "D:";
- break;
- }
- }
-
- std::string pl = s;
- if (level_num)
- {
- char buf[20];
- snprintf(buf, sizeof buf, "%d", lev);
- pl += buf;
- }
- return pl;
-}
-
-void Kills::save(FILE *file) const
-{
- // How many kill records do we have?
- writeLong(file, kills.size());
-
- kill_map::const_iterator iter = kills.begin();
- for ( ; iter != kills.end(); ++iter)
- {
- iter->first.save(file);
- iter->second.save(file);
- }
-
- // How many ghosts do we have?
- writeShort(file, ghosts.size());
- for (ghost_vec::const_iterator iter = ghosts.begin();
- iter != ghosts.end(); ++iter)
- {
- iter->save(file);
- }
-}
-
-void Kills::load(FILE *file)
-{
- // How many kill records?
- long kill_count = readLong(file);
- kills.clear();
- for (long i = 0; i < kill_count; ++i)
- {
- kill_monster_desc md;
- md.load(file);
- kills[md].load(file);
- }
-
- short ghost_count = readShort(file);
- ghosts.clear();
- for (short i = 0; i < ghost_count; ++i)
- {
- kill_ghost kg;
- kg.load(file);
- ghosts.push_back(kg);
- }
-}
-
-void Kills::record_ghost_kill(const struct monsters *mon)
-{
- kill_ghost ghost(mon);
- ghosts.push_back(ghost);
-}
-
-kill_def::kill_def(const struct monsters *mon) : kills(0), exp(0)
-{
- exp = exper_value( (struct monsters *) mon);
- add_kill(mon, get_packed_place());
-}
-
-static bool ends_with(const std::string &s, const char *suffix)
-{
- std::string other = suffix;
- if (s.length() < other.length()) return false;
- return (s.substr(s.length() - other.length()) == other);
-}
-
-static bool ends_with(const std::string &s, const char *suffixes[])
-{
- if (!suffixes) return false;
- for ( ; *suffixes; suffixes++)
- {
- if (ends_with(s, *suffixes))
- return true;
- }
- return false;
-}
-
-// For monster names ending with these suffixes, we pluralize directly without
-// attempting to use the "of" rule. For instance:
-//
-// moth of wrath => moths of wrath but
-// moth of wrath zombie => moth of wrath zombies.
-//
-// This is not necessary right now, since there are currently no monsters that
-// require this special treatment (no monster with 'of' in its name is eligible
-// for zombies or skeletons).
-static const char *modifier_suffixes[] =
-{
- "zombie", "skeleton", "simulacrum", NULL,
-};
-
-// Pluralizes a monster name. This'll need to be updated for correctness
-// whenever new monsters are added.
-static std::string pluralize(const std::string &name,
- const char *no_of[] = NULL)
-{
- std::string::size_type pos;
-
- // Pluralize first word of names like 'eye of draining', but only if the
- // whole name is not suffixed by a modifier, such as 'zombie' or 'skeleton'
- if ( (pos = name.find(" of ")) != std::string::npos
- && !ends_with(name, no_of) )
- {
- return pluralize(name.substr(0, pos)) + name.substr(pos);
- }
- else if (ends_with(name, "us"))
- // Fungus, ufetubus, for instance.
- return name.substr(0, name.length() - 2) + "i";
- else if (ends_with(name, "larva") || ends_with(name, "amoeba"))
- // Giant amoebae sounds a little weird, to tell the truth.
- return name + "e";
- else if (ends_with(name, "ex"))
- // Vortex; vortexes is legal, but the classic plural is cooler.
- return name.substr(0, name.length() - 2) + "ices";
- else if (ends_with(name, "cyclops"))
- return name.substr(0, name.length() - 1) + "es";
- else if (ends_with(name, "y"))
- return name.substr(0, name.length() - 1) + "ies";
- else if (ends_with(name, "lf"))
- // Elf, wolf. Dwarfs can stay dwarfs, if there were dwarfs.
- return name.substr(0, name.length() - 1) + "ves";
- else if (ends_with(name, "mage"))
- // mage -> magi
- return name.substr(0, name.length() - 1) + "i";
- else if ( ends_with(name, "sheep") || ends_with(name, "manes")
- || ends_with(name, "fish") )
- // Maybe we should generalise 'manes' to ends_with("es")?
- return name;
- else if (ends_with(name, "ch") || ends_with(name, "sh")
- || ends_with(name, "x"))
- // To handle cockroaches, fish and sphinxes. Fish will be netted by
- // the previous check anyway.
- return name + "es";
- else if (ends_with(name, "um"))
- // simulacrum -> simulacra
- return name.substr(0, name.length() - 2) + "a";
- else if (ends_with(name, "efreet"))
- // efreet -> efreeti. Not sure this is correct.
- return name + "i";
-
- return name + "s";
-}
-
-// Naively prefix A/an to a monster name. At the moment, we don't have monster
-// names that demand more sophistication (maybe ynoxinul - don't know how
-// that's pronounced).
-static std::string article_a(const std::string &name)
-{
- if (!name.length()) return name;
- switch (name[0])
- {
- case 'a': case 'e': case 'i': case 'o': case 'u':
- case 'A': case 'E': case 'I': case 'O': case 'U':
- return "An " + name;
- default:
- return "A " + name;
- }
-}
-
-// For a non-unique monster, prefixes a suitable article if we have only one
-// kill, else prefixes a kill count and pluralizes the monster name.
-static std::string n_names(const std::string &name, int n)
-{
- if (n > 1)
- {
- char buf[20];
- snprintf(buf, sizeof buf, "%d ", n);
- return buf + pluralize(name, modifier_suffixes);
- }
- else
- return article_a(name);
-}
-
-// Returns a string describing the number of times a unique has been killed.
-// Currently required only for Boris.
-//
-static std::string kill_times(int kills)
-{
- char buf[50];
- switch (kills)
- {
- case 1:
- strcpy(buf, " (once)");
- break;
- case 2:
- strcpy(buf, " (twice)");
- break;
- case 3:
- strcpy(buf, " (thrice)");
- break;
- default:
- snprintf(buf, sizeof buf, " (%d times)", kills);
- break;
- }
- return std::string(buf);
-}
-
-void kill_def::merge(const kill_def &k, bool uniq)
-{
- if (!kills)
- {
- *this = k;
- }
- else
- {
- kills += k.kills;
- for (int i = 0, size = k.places.size(); i < size; ++i)
- add_place(k.places[i], uniq);
- }
-}
-
-void kill_def::add_kill(const struct monsters *mon, unsigned short place)
-{
- kills++;
- add_place(place, mons_is_unique(mon->type));
-}
-
-void kill_def::add_place(unsigned short place, bool force)
-{
- for (unsigned i = 0; i < places.size(); ++i)
- if (places[i] == place) return;
-
- if (force || places.size() < PLACE_LIMIT)
- places.push_back(place);
-}
-
-std::string kill_def::base_name(const kill_monster_desc &md) const
-{
- char monnamebuf[ITEMNAME_SIZE]; // Le sigh.
- moname(md.monnum, true, DESC_PLAIN, monnamebuf);
-
- std::string name = monnamebuf;
- switch (md.modifier)
- {
- case kill_monster_desc::M_ZOMBIE:
- name += " zombie";
- break;
- case kill_monster_desc::M_SKELETON:
- name += " skeleton";
- break;
- case kill_monster_desc::M_SIMULACRUM:
- name += " simulacrum";
- break;
- case kill_monster_desc::M_SPECTRE:
- name = "spectral " + name;
- break;
- default:
- // Silence compiler warning about not handling M_NORMAL and
- // M_SHAPESHIFTER
- break;
- }
-
- switch (md.monnum)
- {
- case MONS_ABOMINATION_LARGE:
- name = "large " + name;
- break;
- case MONS_ABOMINATION_SMALL:
- // Do nothing
- break;
- case MONS_RAKSHASA_FAKE:
- name = "illusory " + name;
- break;
- }
- return name;
-}
-
-std::string kill_def::info(const kill_monster_desc &md) const
-{
- std::string name = base_name(md);
-
- if (!mons_is_unique(md.monnum))
- {
- // Pluralize as needed
- name = n_names(name, kills);
-
- // We brand shapeshifters with the (shapeshifter) qualifier. This
- // has to be done after doing pluralize(), else we get very odd plurals
- // :)
- if (md.modifier == kill_monster_desc::M_SHAPESHIFTER &&
- md.monnum != MONS_SHAPESHIFTER &&
- md.monnum != MONS_GLOWING_SHAPESHIFTER)
- name += " (shapeshifter)";
- }
- else if (kills > 1)
- {
- // Aha! A resurrected unique
- name += kill_times(kills);
- }
-
- // What places we killed this type of monster
- return append_places(md, name);
-}
-
-std::string kill_def::append_places(const kill_monster_desc &md,
- const std::string &name) const
-{
- if (Options.dump_kill_places == KDO_NO_PLACES) return name;
-
- int nplaces = places.size();
- if ( nplaces == 1 || mons_is_unique(md.monnum)
- || Options.dump_kill_places == KDO_ALL_PLACES )
- {
- std::string augmented = name;
- augmented += " (";
- for (std::vector<unsigned short>::const_iterator iter = places.begin();
- iter != places.end(); ++iter)
- {
- if (iter != places.begin())
- augmented += " ";
- augmented += short_place_name(*iter);
- }
- augmented += ")";
- return augmented;
- }
- return name;
-}
-
-void kill_def::save(FILE *file) const
-{
- writeShort(file, kills);
- writeShort(file, exp);
-
- writeShort(file, places.size());
- for (std::vector<unsigned short>::const_iterator iter = places.begin();
- iter != places.end(); ++iter)
- {
- writeShort(file, *iter);
- }
-}
-
-void kill_def::load(FILE *file)
-{
- kills = (unsigned short) readShort(file);
- exp = readShort(file);
-
- places.clear();
- short place_count = readShort(file);
- for (short i = 0; i < place_count; ++i)
- {
- places.push_back((unsigned short) readShort(file));
- }
-}
-
-kill_ghost::kill_ghost(const struct monsters *mon)
-{
- exp = exper_value( (struct monsters *) mon);
- place = get_packed_place();
- ghost_name = ghost.name;
-
- // Check whether this is really a ghost, since we also have to handle
- // the Pandemonic demons.
- if (mon->type == MONS_PLAYER_GHOST)
- ghost_name = "The ghost of " + ghost_description(true);
-}
-
-std::string kill_ghost::info() const
-{
- return ghost_name +
- (Options.dump_kill_places != KDO_NO_PLACES?
- " (" + short_place_name(place) + ")" : std::string(""));
-}
-
-void kill_ghost::save(FILE *file) const
-{
- writeString(file, ghost_name);
- writeShort(file, (unsigned short) exp);
- writeShort(file, place);
-}
-
-void kill_ghost::load(FILE *file)
-{
- ghost_name = readString(file);
- exp = readShort(file);
- place = (unsigned short) readShort(file);
-}
-
-kill_monster_desc::kill_monster_desc(const monsters *mon)
-{
-
- // TODO: We need to understand how shapeshifters are handled.
- monnum = mon->type;
- modifier = M_NORMAL;
- switch (mon->type)
- {
- case MONS_ZOMBIE_LARGE: case MONS_ZOMBIE_SMALL:
- modifier = M_ZOMBIE;
- break;
- case MONS_SKELETON_LARGE: case MONS_SKELETON_SMALL:
- modifier = M_SKELETON;
- break;
- case MONS_SIMULACRUM_LARGE: case MONS_SIMULACRUM_SMALL:
- modifier = M_SIMULACRUM;
- break;
- case MONS_SPECTRAL_THING:
- modifier = M_SPECTRE;
- break;
- }
- if (modifier != M_NORMAL) monnum = mon->number;
-
- if (mons_has_ench((struct monsters *) mon, ENCH_SHAPESHIFTER) ||
- mons_has_ench((struct monsters *) mon, ENCH_GLOWING_SHAPESHIFTER))
- modifier = M_SHAPESHIFTER;
-
- // XXX: Ugly hack - merge all mimics into one mimic record.
- if (monnum >= MONS_GOLD_MIMIC && monnum <= MONS_POTION_MIMIC)
- monnum = MONS_WEAPON_MIMIC;
-}
-
-void kill_monster_desc::save(FILE *file) const
-{
- writeShort(file, (short) monnum);
- writeShort(file, (short) modifier);
-}
-
-void kill_monster_desc::load(FILE *file)
-{
- monnum = (int) readShort(file);
- modifier = (name_modifier) readShort(file);
-}
-
-#ifdef CLUA_BINDINGS
-///////////////////////////////////////////////////////////////////////////
-// Kill Lua interface
-//
-
-#define KILLEXP_ACCESS(name, type, field) \
- static int kill_lualc_##name(lua_State *ls) { \
- if (!lua_islightuserdata(ls, 1)) { \
- luaL_argerror(ls, 1, "Unexpected argument type"); \
- return 0; \
- } \
- \
- kill_exp *ke = static_cast<kill_exp*>( lua_touserdata(ls, 1) ); \
- if (ke) { \
- lua_push##type(ls, ke->field); \
- return 1; \
- } \
- return 0; \
- }
-
-KILLEXP_ACCESS(nkills, number, nkills)
-KILLEXP_ACCESS(exp, number, exp)
-KILLEXP_ACCESS(base_name, string, base_name.c_str())
-KILLEXP_ACCESS(desc, string, desc.c_str())
-KILLEXP_ACCESS(monnum, number, monnum)
-KILLEXP_ACCESS(isghost, boolean,
- monnum == -1 &&
- ke->desc.find("The ghost of") != std::string::npos)
-KILLEXP_ACCESS(ispandemon, boolean,
- monnum == -1 &&
- ke->desc.find("The ghost of") == std::string::npos)
-KILLEXP_ACCESS(isunique, boolean,
- monnum != -1 && mons_is_unique(ke->monnum))
-
-
-static int kill_lualc_modifier(lua_State *ls)
-{
- if (!lua_islightuserdata(ls, 1))
- {
- luaL_argerror(ls, 1, "Unexpected argument type");
- return 0;
- }
-
- kill_exp *ke = static_cast<kill_exp*>( lua_touserdata(ls, 1) );
- if (ke)
- {
- const char *modifier;
- switch (ke->modifier)
- {
- case kill_monster_desc::M_ZOMBIE:
- modifier = "zombie";
- break;
- case kill_monster_desc::M_SKELETON:
- modifier = "skeleton";
- break;
- case kill_monster_desc::M_SIMULACRUM:
- modifier = "simulacrum";
- break;
- case kill_monster_desc::M_SPECTRE:
- modifier = "spectre";
- break;
- case kill_monster_desc::M_SHAPESHIFTER:
- modifier = "shapeshifter";
- break;
- default:
- modifier = "";
- break;
- }
- lua_pushstring(ls, modifier);
- return 1;
- }
- return 0;
-}
-
-static int kill_lualc_places(lua_State *ls)
-{
- if (!lua_islightuserdata(ls, 1))
- {
- luaL_argerror(ls, 1, "Unexpected argument type");
- return 0;
- }
-
- kill_exp *ke = static_cast<kill_exp*>( lua_touserdata(ls, 1) );
- if (ke)
- {
- lua_newtable(ls);
- for (int i = 0, count = ke->places.size(); i < count; ++i)
- {
- lua_pushnumber(ls, ke->places[i]);
- lua_rawseti(ls, -2, i + 1);
- }
- return 1;
- }
- return 0;
-}
-
-static int kill_lualc_place_name(lua_State *ls)
-{
- int num = luaL_checkint(ls, 1);
- std::string plname = short_place_name(num);
- lua_pushstring(ls, plname.c_str());
- return 1;
-}
-
-static bool is_ghost(const kill_exp *ke)
-{
- return ke->monnum == -1
- && ke->desc.find("The ghost of") != std::string::npos;
-}
-
-static int kill_lualc_holiness(lua_State *ls)
-{
- if (!lua_islightuserdata(ls, 1))
- {
- luaL_argerror(ls, 1, "Unexpected argument type");
- return 0;
- }
-
- kill_exp *ke = static_cast<kill_exp*>( lua_touserdata(ls, 1) );
- if (ke)
- {
- const char *verdict = "strange";
- if (ke->monnum == -1)
- {
- verdict = is_ghost(ke)? "undead" : "demonic";
- }
- else
- {
- switch (mons_class_holiness(ke->monnum))
- {
- case MH_HOLY: verdict = "holy"; break;
- case MH_NATURAL: verdict = "natural"; break;
- case MH_UNDEAD: verdict = "undead"; break;
- case MH_DEMONIC: verdict = "demonic"; break;
- case MH_NONLIVING: verdict = "nonliving"; break;
- case MH_PLANT: verdict = "plant"; break;
- }
- if (ke->modifier != kill_monster_desc::M_NORMAL
- && ke->modifier != kill_monster_desc::M_SHAPESHIFTER)
- verdict = "undead";
- }
- lua_pushstring(ls, verdict);
- return 1;
- }
- return 0;
-}
-
-static int kill_lualc_symbol(lua_State *ls)
-{
- if (!lua_islightuserdata(ls, 1))
- {
- luaL_argerror(ls, 1, "Unexpected argument type");
- return 0;
- }
-
- kill_exp *ke = static_cast<kill_exp*>( lua_touserdata(ls, 1) );
- if (ke)
- {
- unsigned char ch = ke->monnum != -1?
- mons_char(ke->monnum) :
- is_ghost(ke)? 'p' : '&';
-
- if (ke->monnum == MONS_PROGRAM_BUG)
- ch = ' ';
-
- switch (ke->modifier)
- {
- case kill_monster_desc::M_ZOMBIE:
- case kill_monster_desc::M_SKELETON:
- case kill_monster_desc::M_SIMULACRUM:
- ch = mons_zombie_size(ke->monnum) == Z_SMALL? 'z' : 'Z';
- break;
- case kill_monster_desc::M_SPECTRE:
- ch = 'W';
- break;
- default:
- break;
- }
-
- char s[2];
- s[0] = (char) ch;
- s[1] = 0;
- lua_pushstring(ls, s);
- return 1;
- }
- return 0;
-}
-
-static int kill_lualc_rawwrite(lua_State *ls)
-{
- const char *s = luaL_checkstring(ls, 1);
- lua_pushstring(ls, "cr_skill");
- lua_gettable(ls, LUA_REGISTRYINDEX);
- if (!lua_islightuserdata(ls, -1))
- {
- lua_settop(ls, -2);
- fprintf(stderr, "Can't find kill string?\n");
- return 0;
- }
-
- std::string *skill = static_cast<std::string *>( lua_touserdata(ls, -1) );
- // Pop the userdata off the stack.
- lua_settop(ls, -2);
-
- *skill += s;
- *skill += "\n";
-
- return 0;
-}
-
-static int kill_lualc_write(lua_State *ls)
-{
- if (!lua_islightuserdata(ls, 1))
- {
- luaL_argerror(ls, 1, "Unexpected argument type");
- return 0;
- }
-
- kill_exp *ke = static_cast<kill_exp*>( lua_touserdata(ls, 1) );
- if (ke)
- {
- lua_pushstring(ls, "cr_skill");
- lua_gettable(ls, LUA_REGISTRYINDEX);
- if (!lua_islightuserdata(ls, -1))
- {
- lua_settop(ls,-2);
- fprintf(stderr, "Can't find kill string?\n");
- return 0;
- }
-
- std::string *skill = static_cast<std::string *>(
- lua_touserdata(ls, -1) );
- // Pop the userdata off the stack.
- lua_settop(ls, -2);
-
- // Write kill description and a newline.
- *skill += ke->desc + "\n";
- }
- return 0;
-}
-
-static int kill_lualc_summary(lua_State *ls)
-{
- if (!lua_istable(ls, 1))
- {
- luaL_argerror(ls, 1, "Unexpected argument type, wanted table");
- return 0;
- }
-
- unsigned long count = 0;
- for (int i = 1; ; ++i)
- {
- lua_rawgeti(ls, 1, i);
- if (lua_isnil(ls, -1))
- {
- lua_settop(ls, -2);
- break;
- }
-
- if (!lua_islightuserdata(ls, -1))
- {
- luaL_argerror(ls, 1, "Unexpected argument type");
- return 0;
- }
-
- kill_exp *ke = static_cast<kill_exp*>( lua_touserdata(ls, -1) );
- lua_settop(ls, -2);
- if (ke)
- count += ke->nkills;
- }
- char buf[120];
- *buf = 0;
- if (count)
- snprintf(buf, sizeof buf, "%lu creature%s vanquished.",
- count, count > 1? "s" : "");
- lua_pushstring(ls, buf);
- return 1;
-}
-
-static const struct luaL_reg kill_lib[] =
-{
- { "nkills", kill_lualc_nkills },
- { "exp" , kill_lualc_exp },
- { "base_name", kill_lualc_base_name },
- { "desc", kill_lualc_desc },
- { "monnum", kill_lualc_monnum },
- { "modifier", kill_lualc_modifier },
- { "places", kill_lualc_places },
- { "place_name", kill_lualc_place_name },
- { "holiness", kill_lualc_holiness },
- { "symbol", kill_lualc_symbol },
- { "isghost", kill_lualc_isghost },
- { "ispandemon", kill_lualc_ispandemon },
- { "isunique", kill_lualc_isunique },
- { "rawwrite", kill_lualc_rawwrite },
- { "write", kill_lualc_write },
- { "summary", kill_lualc_summary },
- { NULL, NULL }
-};
-
-void lua_open_kills(lua_State *ls)
-{
- luaL_openlib(ls, "kills", kill_lib, 0);
-}
-
-static void kill_lua_filltable(std::vector<kill_exp> &v)
-{
- lua_State *ls = clua.state();
- lua_newtable(ls);
- for (int i = 0, count = v.size(); i < count; ++i)
- {
- lua_pushlightuserdata(ls, &v[i]);
- lua_rawseti(ls, -2, i + 1);
- }
-}
-
-#endif
diff --git a/stone_soup/crawl-ref/source/Kills.h b/stone_soup/crawl-ref/source/Kills.h
deleted file mode 100644
index 074ea79a6d..0000000000
--- a/stone_soup/crawl-ref/source/Kills.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * File: Kills.h
- * Summary: Tracks monsters the player has killed.
- * Written by: Darshan Shaligram
- */
-#ifndef KILLS_H
-#define KILLS_H
-
-#include <vector>
-#include <string>
-#include <map>
-#include <stdio.h>
-#include "enum.h"
-
-struct monsters;
-
-// Not intended for external use!
-struct kill_monster_desc
-{
- kill_monster_desc(const struct monsters *);
- kill_monster_desc() { }
-
- void save(FILE*) const;
- void load(FILE*);
-
- enum name_modifier
- {
- M_NORMAL, M_ZOMBIE, M_SKELETON, M_SIMULACRUM, M_SPECTRE,
- M_SHAPESHIFTER // A shapeshifter pretending to be 'monnum'
- };
-
- int monnum; // Number of the beast
- name_modifier modifier; // Nature of the beast
-
- struct less_than
- {
- bool operator () ( const kill_monster_desc &m1,
- const kill_monster_desc &m2) const
- {
- return m1.monnum < m2.monnum ||
- (m1.monnum == m2.monnum && m1.modifier < m2.modifier);
- }
- };
-};
-
-#define PLACE_LIMIT 5 // How many unique kill places we're prepared to track
-class kill_def
-{
-public:
- kill_def(const struct monsters *mon);
- kill_def() : kills(0), exp(0)
- {
- // This object just says to the world that it's uninitialized
- }
-
- void save(FILE*) const;
- void load(FILE*);
-
- void add_kill(const struct monsters *mon, unsigned short place);
- void add_place(unsigned short place, bool force = false);
-
- void merge(const kill_def &k, bool unique_monster);
-
- std::string info(const kill_monster_desc &md) const;
- std::string base_name(const kill_monster_desc &md) const;
-
- unsigned short kills; // How many kills does the player have?
- int exp; // Experience gained for slaying the beast.
- // Only set *once*, even for shapeshifters.
-
- std::vector<unsigned short> places; // Places where we've killed the beast.
-private:
- std::string append_places(const kill_monster_desc &md,
- const std::string &name) const;
-};
-
-// Ghosts and random Pandemonium demons.
-class kill_ghost
-{
-public:
- kill_ghost(const struct monsters *mon);
- kill_ghost() { }
-
- void save(FILE*) const;
- void load(FILE*);
-
- std::string info() const;
-
- std::string ghost_name;
- int exp;
- unsigned short place;
-};
-
-// This is the structure that Lua sees.
-struct kill_exp
-{
- int nkills;
- int exp;
- std::string base_name;
- std::string desc;
-
- int monnum; // Number of the beast
- int modifier; // Nature of the beast
-
- std::vector<unsigned short> places;
-
- kill_exp(const kill_def &k, const kill_monster_desc &md)
- : nkills(k.kills), exp(k.exp), base_name(k.base_name(md)),
- desc(k.info(md)),
- monnum(md.monnum), modifier(md.modifier)
- {
- places = k.places;
- }
-
- kill_exp(const kill_ghost &kg)
- : nkills(1), exp(kg.exp), base_name(), desc(kg.info()),
- monnum(-1), modifier(0)
- {
- places.push_back(kg.place);
- }
-
- // operator< is implemented for a descending sort.
- bool operator < ( const kill_exp &b) const
- {
- return exp == b.exp? (base_name < b.base_name) : (exp > b.exp);
- }
-};
-
-class Kills
-{
-public:
- void record_kill(const monsters *mon);
- void merge(const Kills &k);
-
- bool empty() const;
- void save(FILE*) const;
- void load(FILE*);
-
- long get_kills(std::vector<kill_exp> &v) const;
-private:
- typedef std::map<kill_monster_desc,
- kill_def,
- kill_monster_desc::less_than> kill_map;
- typedef std::vector<kill_ghost> ghost_vec;
-
- kill_map kills;
- ghost_vec ghosts;
-
- void record_ghost_kill(const struct monsters *mon);
-};
-
-class KillMaster
-{
-public:
- void record_kill(const monsters *mon, int killer, bool ispet);
-
- bool empty() const;
- void save(FILE*) const;
- void load(FILE*);
-
- std::string kill_info() const;
-private:
- const char *category_name(kill_category kc) const;
-
- Kills categorized_kills[KC_NCATEGORIES];
-private:
- void add_kill_info(std::string &, std::vector<kill_exp> &,
- long count, const char *c, bool separator)
- const;
-};
-
-unsigned short get_packed_place();
-
-unsigned short get_packed_place( unsigned char branch, int subdepth,
- char level_type );
-
-std::string short_place_name(unsigned short place);
-
-enum KILL_DUMP_OPTIONS
-{
- KDO_NO_PLACES, // Don't dump places at all
- KDO_ONE_PLACE, // Show places only for single kills and uniques.
- KDO_ALL_PLACES // Show all available place information
-};
-
-#endif
diff --git a/stone_soup/crawl-ref/source/MacString.cc b/stone_soup/crawl-ref/source/MacString.cc
deleted file mode 100644
index 2d5c14442e..0000000000
--- a/stone_soup/crawl-ref/source/MacString.cc
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * File: MacString.cc
- * Summary: Wrapper around an immutable CFString.
- * Written by: Jesse Jones (jesjones@mindspring.com)
- *
- * Change History (most recent first):
- *
- * <1> 6/04/02 JDJ Created
- */
-
-#include "AppHdr.h"
-#include "MacString.h"
-
-#if macintosh
-
-#include <CoreFoundation/CFString.h>
-
-#include "debug.h"
-
-
-// ========================================================================
-// Internal Functions
-// ========================================================================
-
-//---------------------------------------------------------------
-//
-// ThrowIf
-//
-//---------------------------------------------------------------
-static void ThrowIf(bool predicate, const std::string& text)
-{
- if (predicate)
- throw std::runtime_error(text);
-}
-
-#if __MWERKS__
-#pragma mark -
-#endif
-
-// ============================================================================
-// class MacString
-// ============================================================================
-
-//---------------------------------------------------------------
-//
-// MacString::~MacString
-//
-//---------------------------------------------------------------
-MacString::~MacString()
-{
- CFRelease(mString);
-}
-
-
-//---------------------------------------------------------------
-//
-// MacString::MacString ()
-//
-//---------------------------------------------------------------
-MacString::MacString()
-{
- mString = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, NULL, 0);
- ThrowIf(mString == NULL, "Couldn't create the CFString");
-}
-
-
-//---------------------------------------------------------------
-//
-// MacString::MacString (unsigned char*)
-//
-//---------------------------------------------------------------
-MacString::MacString(const unsigned char* str)
-{
- ASSERT(str != NULL);
-
- CFStringEncoding encoding = CFStringGetSystemEncoding();
- mString = CFStringCreateWithPascalString(kCFAllocatorSystemDefault, str, encoding);
- ThrowIf(mString == NULL, "Couldn't create the CFString");
-}
-
-
-//---------------------------------------------------------------
-//
-// MacString::MacString (char*)
-//
-//---------------------------------------------------------------
-MacString::MacString(const char* str)
-{
- ASSERT(str != NULL);
-
- CFStringEncoding encoding = CFStringGetSystemEncoding();
- mString = CFStringCreateWithCString(kCFAllocatorSystemDefault, str, encoding);
- ThrowIf(mString == NULL, "Couldn't create the CFString");
-}
-
-
-//---------------------------------------------------------------
-//
-// MacString::MacString (CFStringRef)
-//
-//---------------------------------------------------------------
-MacString::MacString(CFStringRef str)
-{
- ASSERT(str != NULL);
-
- mString = str;
- CFRetain(mString);
-}
-
-
-//---------------------------------------------------------------
-//
-// MacString::MacString (CFMutableStringRef)
-//
-//---------------------------------------------------------------
-MacString::MacString(CFMutableStringRef str)
-{
- ASSERT(str != NULL);
-
- mString = CFStringCreateCopy(kCFAllocatorSystemDefault, str);
- ThrowIf(mString == NULL, "Couldn't create the CFString");
-}
-
-
-//---------------------------------------------------------------
-//
-// MacString::MacString (int)
-//
-//---------------------------------------------------------------
-MacString::MacString(int value)
-{
- char buffer[32];
- sprintf(buffer, "%d", value);
-
- CFStringEncoding encoding = CFStringGetSystemEncoding();
- mString = CFStringCreateWithCString(kCFAllocatorSystemDefault, buffer, encoding);
- ThrowIf(mString == NULL, "Couldn't create the CFString");
-}
-
-
-//---------------------------------------------------------------
-//
-// MacString::MacString (MacString)
-//
-//---------------------------------------------------------------
-MacString::MacString(const MacString& str)
-{
- mString = str.mString; // immutable so we can refcount
- CFRetain(mString);
-}
-
-
-//---------------------------------------------------------------
-//
-// MacString::operator= (MacString)
-//
-//---------------------------------------------------------------
-MacString& MacString::operator=(const MacString& rhs)
-{
- if (this != &rhs)
- {
- CFRelease(mString);
-
- mString = rhs.mString; // immutable so we can refcount
- CFRetain(mString);
- }
-
- return *this;
-}
-
-
-//---------------------------------------------------------------
-//
-// MacString::length
-//
-//---------------------------------------------------------------
-size_t MacString::length() const
-{
- size_t len = (size_t) CFStringGetLength(mString);
-
- return len;
-}
-
-
-//---------------------------------------------------------------
-//
-// MacString::CopyTo
-//
-//---------------------------------------------------------------
-void MacString::CopyTo(unsigned char* buffer, CFIndex bytes)
-{
- ASSERT(buffer != NULL || bytes == 0);
-
- bool converted = CFStringGetPascalString(mString, buffer, bytes, CFStringGetSystemEncoding());
- ThrowIf(!converted, "Couldn't convert the CFString into a Pascal string");
-}
-
-
-#endif // macintosh
diff --git a/stone_soup/crawl-ref/source/MacString.h b/stone_soup/crawl-ref/source/MacString.h
deleted file mode 100644
index d2cad4b1be..0000000000
--- a/stone_soup/crawl-ref/source/MacString.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * File: MacString.h
- * Summary: Wrapper around an immutable CFString.
- * Written by: Jesse Jones (jesjones@mindspring.com)
- *
- * Change History (most recent first):
- *
- * <1> 6/04/02 JDJ Created
- */
-
-#ifndef MAC_STRING_H
-#define MAC_STRING_H
-
-#if macintosh
-
-#include <CoreFoundation/CFBase.h>
-
-
-// ============================================================================
-// class MacString
-//! Wrapper around an immutable CFString.
-// ============================================================================
-class MacString {
-
-//-----------------------------------
-// Initialization/Destruction
-//
-public:
- ~MacString();
-
- MacString();
-
- MacString(const char* str);
- MacString(const unsigned char* str);
- /**< Uses default system encoding. */
-
- MacString(CFStringRef str);
- /**< Bumps the ref count. */
-
- MacString(CFMutableStringRef str);
- /**< Makes a copy. */
-
- explicit MacString(int value);
-
- MacString(const MacString& str);
- MacString& operator=(const MacString& rhs);
-
-//-----------------------------------
-// API
-//
-public:
- // ----- Size -----
- size_t length() const;
- size_t size() const {return this->length();}
- bool empty() const {return this->length() == 0;}
-
- // ----- Access -----
- void CopyTo(unsigned char* buffer, CFIndex bytes);
-
- operator CFStringRef() const {return mString;}
-
-//-----------------------------------
-// Member Data
-//
-private:
- CFStringRef mString;
-};
-
-
-#endif // macintosh
-#endif // MAC_STRING_H
diff --git a/stone_soup/crawl-ref/source/abl-show.cc b/stone_soup/crawl-ref/source/abl-show.cc
deleted file mode 100644
index ae7c89fa59..0000000000
--- a/stone_soup/crawl-ref/source/abl-show.cc
+++ /dev/null
@@ -1,2164 +0,0 @@
-/*
- * File: abl-show.cc
- * Summary: Functions related to special abilities.
- * Written by: Linley Henzell
- *
- * Modified for Crawl Reference by $Author$ on $Date$
- *
- * Change History (most recent first):
- *
- * <6> 19mar2000 jmf added elvish Glamour
- * <5> 11/06/99 cdl reduced power of minor destruction
- *
- * <4> 9/25/99 cdl linuxlib -> liblinux
- *
- * <3> 5/20/99 BWR Now use scan_randarts to
- * check for flags, rather than
- * only checking the weapon.
- *
- * <2> 5/20/99 BWR Extended screen line support
- *
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "abl-show.h"
-
-#include <string.h>
-#include <stdio.h>
-#include <ctype.h>
-
-#ifdef DOS
-#include <conio.h>
-#endif
-
-#include "externs.h"
-
-#include "beam.h"
-#include "effects.h"
-#include "food.h"
-#include "it_use2.h"
-#include "macro.h"
-#include "message.h"
-#include "misc.h"
-#include "monplace.h"
-#include "player.h"
-#include "religion.h"
-#include "skills.h"
-#include "skills2.h"
-#include "spl-cast.h"
-#include "spl-util.h"
-#include "spells1.h"
-#include "spells2.h"
-#include "spells3.h"
-#include "spells4.h"
-#include "stuff.h"
-#include "transfor.h"
-#include "view.h"
-
-
-#ifdef UNIX
-#include "libunix.h"
-#endif
-
-// this all needs to be split into data/util/show files
-// and the struct mechanism here needs to be rewritten (again)
-// along with the display routine to piece the strings
-// together dynamically ... I'm getting to it now {dlb}
-
-// it makes more sense to think of them as an array
-// of structs than two arrays that share common index
-// values -- well, doesn't it? {dlb}
-struct talent
-{
- int which;
- int fail;
- bool is_invocation;
-};
-
-static FixedVector< talent, 52 > Curr_abil;
-
-static bool insert_ability( int which_ability );
-
-// The description screen was way out of date with the actual costs.
-// This table puts all the information in one place... -- bwr
-//
-// The four numerical fields are: MP, HP, food, and piety.
-// Note: food_cost = val + random2avg( val, 2 )
-// piety_cost = val + random2( (val + 1) / 2 + 1 );
-static const struct ability_def Ability_List[] =
-{
- // NON_ABILITY should always come first
- { ABIL_NON_ABILITY, "No ability", 0, 0, 0, 0, ABFLAG_NONE },
- { ABIL_SPIT_POISON, "Spit Poison", 0, 0, 40, 0, ABFLAG_BREATH },
- { ABIL_GLAMOUR, "Glamour", 5, 0, 40, 0, ABFLAG_DELAY },
-
- { ABIL_MAPPING, "Sense Surroundings", 0, 0, 30, 0, ABFLAG_NONE },
- { ABIL_TELEPORTATION, "Teleportation", 3, 0, 200, 0, ABFLAG_NONE },
- { ABIL_BLINK, "Blink", 1, 0, 50, 0, ABFLAG_NONE },
-
- { ABIL_BREATHE_FIRE, "Breathe Fire", 0, 0, 125, 0, ABFLAG_BREATH },
- { ABIL_BREATHE_FROST, "Breathe Frost", 0, 0, 125, 0, ABFLAG_BREATH },
- { ABIL_BREATHE_POISON, "Breathe Poison Gas", 0, 0, 125, 0, ABFLAG_BREATH },
- { ABIL_BREATHE_LIGHTNING, "Breathe Lightning", 0, 0, 125, 0, ABFLAG_BREATH },
- { ABIL_BREATHE_POWER, "Breathe Power", 0, 0, 125, 0, ABFLAG_BREATH },
- { ABIL_BREATHE_STICKY_FLAME, "Breathe Sticky Flame", 0, 0, 125, 0, ABFLAG_BREATH },
- { ABIL_BREATHE_STEAM, "Breathe Steam", 0, 0, 75, 0, ABFLAG_BREATH },
-
- // Handled with breath weapons, but doesn't cause a breathing delay
- { ABIL_SPIT_ACID, "Spit Acid", 0, 0, 125, 0, ABFLAG_NONE },
-
- { ABIL_FLY, "Fly", 3, 0, 100, 0, ABFLAG_NONE },
- { ABIL_SUMMON_MINOR_DEMON, "Summon Minor Demon", 3, 3, 75, 0, ABFLAG_NONE },
- { ABIL_SUMMON_DEMONS, "Summon Demons", 5, 5, 150, 0, ABFLAG_NONE },
- { ABIL_HELLFIRE, "Hellfire", 8, 8, 200, 0, ABFLAG_NONE },
- { ABIL_TORMENT, "Torment", 9, 0, 250, 0, ABFLAG_PAIN },
- { ABIL_RAISE_DEAD, "Raise Dead", 5, 5, 150, 0, ABFLAG_NONE },
- { ABIL_CONTROL_DEMON, "Control Demon", 4, 4, 100, 0, ABFLAG_NONE },
- { ABIL_TO_PANDEMONIUM, "Gate Yourself to Pandemonium", 7, 0, 200, 0, ABFLAG_NONE },
- { ABIL_CHANNELING, "Channeling", 1, 0, 30, 0, ABFLAG_NONE },
- { ABIL_THROW_FLAME, "Throw Flame", 1, 1, 50, 0, ABFLAG_NONE },
- { ABIL_THROW_FROST, "Throw Frost", 1, 1, 50, 0, ABFLAG_NONE },
- { ABIL_BOLT_OF_DRAINING, "Bolt of Draining", 4, 4, 100, 0, ABFLAG_NONE },
-
- // FLY_II used to have ABFLAG_EXHAUSTION, but that's somewhat meaningless
- // as exhaustion's only (and designed) effect is preventing Berserk. -- bwr
- { ABIL_FLY_II, "Fly", 0, 0, 25, 0, ABFLAG_NONE },
- { ABIL_DELAYED_FIREBALL, "Release Delayed Fireball", 0, 0, 0, 0, ABFLAG_INSTANT },
- { ABIL_MUMMY_RESTORATION, "Restoration", 1, 0, 0, 0, ABFLAG_PERMANENT_MP },
-
- // EVOKE abilities use Evocations and come from items:
- // Mapping, Teleportation, and Blink can also come from mutations
- // so we have to distinguish them (see above). The off items
- // below are labeled EVOKE because they only work now if the
- // player has an item with the evocable power (not just because
- // you used a wand, potion, or miscast effect). I didn't see
- // any reason to label them as "Evoke" in the text, they don't
- // use or train Evocations (the others do). -- bwr
- { ABIL_EVOKE_MAPPING, "Evoke Sense Surroundings", 0, 0, 30, 0, ABFLAG_NONE },
- { ABIL_EVOKE_TELEPORTATION, "Evoke Teleportation", 3, 0, 200, 0, ABFLAG_NONE },
- { ABIL_EVOKE_BLINK, "Evoke Blink", 1, 0, 50, 0, ABFLAG_NONE },
-
- { ABIL_EVOKE_BERSERK, "Evoke Berserk Rage", 0, 0, 0, 0, ABFLAG_NONE },
-
- { ABIL_EVOKE_TURN_INVISIBLE, "Evoke Invisibility", 2, 0, 250, 0, ABFLAG_NONE },
- { ABIL_EVOKE_TURN_VISIBLE, "Turn Visible", 0, 0, 0, 0, ABFLAG_NONE },
- { ABIL_EVOKE_LEVITATE, "Evoke Levitation", 1, 0, 100, 0, ABFLAG_NONE },
- { ABIL_EVOKE_STOP_LEVITATING, "Stop Levitating", 0, 0, 0, 0, ABFLAG_NONE },
-
- { ABIL_END_TRANSFORMATION, "End Transformation", 0, 0, 0, 0, ABFLAG_NONE },
-
- // INVOCATIONS:
- // Zin
- { ABIL_ZIN_REPEL_UNDEAD, "Repel Undead", 1, 0, 100, 0, ABFLAG_NONE },
- { ABIL_ZIN_HEALING, "Minor Healing", 2, 0, 50, 1, ABFLAG_NONE },
- { ABIL_ZIN_PESTILENCE, "Pestilence", 3, 0, 100, 2, ABFLAG_NONE },
- { ABIL_ZIN_HOLY_WORD, "Holy Word", 6, 0, 150, 3, ABFLAG_NONE },
- { ABIL_ZIN_SUMMON_GUARDIAN, "Summon Guardian", 7, 0, 150, 4, ABFLAG_NONE },
-
- // The Shining One
- { ABIL_TSO_REPEL_UNDEAD, "Repel Undead", 1, 0, 100, 0, ABFLAG_NONE },
- { ABIL_TSO_SMITING, "Smiting", 3, 0, 50, 2, ABFLAG_NONE },
- { ABIL_TSO_ANNIHILATE_UNDEAD, "Annihilate Undead", 3, 0, 50, 2, ABFLAG_NONE },
- { ABIL_TSO_CLEANSING_FLAME, "Cleansing Flame", 5, 0, 100, 2, ABFLAG_NONE },
- { ABIL_TSO_SUMMON_DAEVA, "Summon Daeva", 8, 0, 150, 4, ABFLAG_NONE },
-
- // Kikubaaqudgha
- { ABIL_KIKU_RECALL_UNDEAD_SLAVES, "Recall Undead Slaves", 2, 0, 50, 0, ABFLAG_NONE },
- { ABIL_KIKU_ENSLAVE_UNDEAD, "Enslave Undead", 4, 0, 150, 3, ABFLAG_NONE },
- { ABIL_KIKU_INVOKE_DEATH, "Invoke Death", 4, 0, 250, 3, ABFLAG_NONE },
-
- // Yredelemnul
- { ABIL_YRED_ANIMATE_CORPSE, "Animate Corpse", 1, 0, 50, 0, ABFLAG_NONE },
- { ABIL_YRED_RECALL_UNDEAD, "Recall Undead Slaves", 2, 0, 50, 0, ABFLAG_NONE },
- { ABIL_YRED_ANIMATE_DEAD, "Animate Dead", 3, 0, 100, 1, ABFLAG_NONE },
- { ABIL_YRED_DRAIN_LIFE, "Drain Life", 6, 0, 200, 2, ABFLAG_NONE },
- { ABIL_YRED_CONTROL_UNDEAD, "Control Undead", 5, 0, 150, 2, ABFLAG_NONE },
-
- // Vehumet
- { ABIL_VEHUMET_CHANNEL_ENERGY, "Channel Energy", 0, 0, 50, 0, ABFLAG_NONE },
-
- // Okawaru
- { ABIL_OKAWARU_MIGHT, "Might", 2, 0, 50, 1, ABFLAG_NONE },
- { ABIL_OKAWARU_HEALING, "Healing", 2, 0, 75, 1, ABFLAG_NONE },
- { ABIL_OKAWARU_HASTE, "Haste", 5, 0, 100, 3, ABFLAG_NONE },
-
- // Makhleb
- { ABIL_MAKHLEB_MINOR_DESTRUCTION, "Minor Destruction", 1, 0, 20, 0, ABFLAG_NONE },
- { ABIL_MAKHLEB_LESSER_SERVANT_OF_MAKHLEB, "Lesser Servant of Makhleb", 2, 0, 50, 1, ABFLAG_NONE },
- { ABIL_MAKHLEB_MAJOR_DESTRUCTION, "Major Destruction", 4, 0, 100, 2, ABFLAG_NONE },
- { ABIL_MAKHLEB_GREATER_SERVANT_OF_MAKHLEB, "Greater Servant of Makhleb", 6, 0, 100, 3, ABFLAG_NONE },
-
- // Sif Muna
- { ABIL_SIF_MUNA_FORGET_SPELL, "Forget Spell", 5, 0, 0, 8, ABFLAG_NONE },
-
- // Trog
- { ABIL_TROG_BERSERK, "Berserk", 0, 0, 200, 0, ABFLAG_NONE },
- { ABIL_TROG_MIGHT, "Might", 0, 0, 200, 1, ABFLAG_NONE },
- { ABIL_TROG_HASTE_SELF, "Haste Self", 0, 0, 250, 3, ABFLAG_NONE },
-
- // Elyvilon
- { ABIL_ELYVILON_LESSER_HEALING, "Lesser Healing", 1, 0, 100, 0, ABFLAG_NONE },
- { ABIL_ELYVILON_PURIFICATION, "Purification", 2, 0, 150, 1, ABFLAG_NONE },
- { ABIL_ELYVILON_HEALING, "Healing", 2, 0, 250, 2, ABFLAG_NONE },
- { ABIL_ELYVILON_RESTORATION, "Restoration", 3, 0, 400, 3, ABFLAG_NONE },
- { ABIL_ELYVILON_GREATER_HEALING, "Greater Healing", 6, 0, 600, 4, ABFLAG_NONE },
-
- // These six are unused "evil" god abilities:
- { ABIL_CHARM_SNAKE, "Charm Snake", 6, 0, 200, 5, ABFLAG_NONE },
- { ABIL_TRAN_SERPENT_OF_HELL, "Turn into Demonic Serpent", 16, 0, 600, 8, ABFLAG_NONE },
- { ABIL_BREATHE_HELLFIRE, "Breathe Hellfire", 0, 8, 200, 0, ABFLAG_BREATH },
-
- { ABIL_ROTTING, "Rotting", 4, 4, 0, 2, ABFLAG_NONE },
- { ABIL_TORMENT_II, "Call Torment", 9, 0, 0, 3, ABFLAG_PAIN },
-
- { ABIL_RENOUNCE_RELIGION, "Renounce Religion", 0, 0, 0, 0, ABFLAG_NONE },
-};
-
-
-const struct ability_def & get_ability_def( int abil )
-/****************************************************/
-{
- for (unsigned int i = 0; i < sizeof( Ability_List ); i++)
- {
- if (Ability_List[i].ability == abil)
- return (Ability_List[i]);
- }
-
- return (Ability_List[0]);
-}
-
-
-const char * get_ability_name_by_index( char index )
-/**************************************************/
-{
- const struct ability_def &abil = get_ability_def( Curr_abil[index].which );
-
- return (abil.name);
-}
-
-
-const std::string make_cost_description( const struct ability_def &abil )
-/***********************************************************************/
-{
- char tmp_buff[80]; // avoiding string steams for portability
- std::string ret = "";
-
- if (abil.mp_cost)
- {
- snprintf( tmp_buff, sizeof(tmp_buff), "%d%s MP",
- abil.mp_cost,
- (abil.flags & ABFLAG_PERMANENT_MP) ? " Permanent" : "" );
-
- ret += tmp_buff;
- }
-
- if (abil.hp_cost)
- {
- if (ret.length())
- ret += ", ";
-
- snprintf( tmp_buff, sizeof(tmp_buff), "%d%s HP",
- abil.hp_cost,
- (abil.flags & ABFLAG_PERMANENT_HP) ? " Permanent" : "" );
-
- ret += tmp_buff;
- }
-
- if (abil.food_cost)
- {
- if (ret.length())
- ret += ", ";
-
- ret += "Food"; // randomized and amount hidden from player
- }
-
- if (abil.piety_cost)
- {
- if (ret.length())
- ret += ", ";
-
- ret += "Piety"; // randomized and amount hidden from player
- }
-
- if (abil.flags & ABFLAG_BREATH)
- {
- if (ret.length())
- ret += ", ";
-
- ret += "Breath";
- }
-
- if (abil.flags & ABFLAG_DELAY)
- {
- if (ret.length())
- ret += ", ";
-
- ret += "Delay";
- }
-
- if (abil.flags & ABFLAG_PAIN)
- {
- if (ret.length())
- ret += ", ";
-
- ret += "Pain";
- }
-
- if (abil.flags & ABFLAG_EXHAUSTION)
- {
- if (ret.length())
- ret += ", ";
-
- ret += "Exhaustion";
- }
-
- if (abil.flags & ABFLAG_INSTANT)
- {
- if (ret.length())
- ret += ", ";
-
- ret += "Instant"; // not really a cost, more of a bonus -bwr
- }
-
- // If we haven't output anything so far, then the effect has no cost
- if (!ret.length())
- ret += "None";
-
- return (ret);
-}
-
-std::vector<const char *> get_ability_names()
-{
- std::vector<const char *> abils;
- if (generate_abilities())
- {
- for (int i = 0; i < 52; ++i)
- {
- if (Curr_abil[i].which != ABIL_NON_ABILITY)
- abils.push_back( get_ability_name_by_index(i) );
- }
- }
- return (abils);
-}
-
-/*
- Activates a menu which gives player access to all of their non-spell
- special abilities - Eg naga's spit poison, or the Invocations you get
- from worshipping. Generated dynamically - the function checks to see which
- abilities you have every time.
- */
-bool activate_ability(void)
-/*************************/
-{
- unsigned char keyin = 0;
- unsigned char spc, spc2;
-
- int power;
- struct dist abild;
- struct bolt beam;
- struct dist spd;
-
- unsigned char abil_used;
-
- // early returns prior to generation of ability list {dlb}:
- if (you.conf)
- {
- mpr("You're too confused!");
- return (false);
- }
-
- if (you.berserker)
- {
- canned_msg(MSG_TOO_BERSERK);
- return (false);
- }
-
- // populate the array of structs {dlb}:
- if (!generate_abilities())
- {
- mpr("Sorry, you're not good enough to have a special ability.");
- return (false);
- }
-
- bool need_redraw = false;
- bool need_prompt = true;
- bool need_getch = true;
-
- for (;;)
- {
- if (need_redraw)
- {
- mesclr( true );
- redraw_screen();
- }
-
- if (need_prompt)
- mpr( "Use which ability? (? or * to list)", MSGCH_PROMPT );
-
- if (need_getch)
- keyin = get_ch();
-
- need_redraw = false;
- need_prompt = true;
- need_getch = true;
-
- if (isalpha( keyin ))
- {
- break;
- }
- else if (keyin == '?' || keyin == '*')
- {
- keyin = show_abilities();
-
- need_getch = false;
- need_redraw = true;
- need_prompt = true;
- }
- else if (keyin == ESCAPE || keyin == ' '
- || keyin == '\r' || keyin == '\n')
- {
- canned_msg( MSG_OK );
- return (false);
- }
- }
-
- spc = (int) keyin;
-
- if (!isalpha( spc ))
- {
- mpr("You can't do that.");
- return (false);
- }
-
- spc2 = letter_to_index(spc);
-
- if (Curr_abil[spc2].which == -1)
- {
- mpr("You can't do that.");
- return (false);
- }
-
- abil_used = spc2;
-
- // some abilities don't need a hunger check
- bool hungerCheck = true;
- switch (Curr_abil[abil_used].which)
- {
- case ABIL_RENOUNCE_RELIGION:
- case ABIL_EVOKE_STOP_LEVITATING:
- case ABIL_EVOKE_TURN_VISIBLE:
- case ABIL_END_TRANSFORMATION:
- case ABIL_DELAYED_FIREBALL:
- case ABIL_MUMMY_RESTORATION:
- hungerCheck = false;
- break;
- default:
- break;
- }
-
- if (hungerCheck && you.hunger_state < HS_HUNGRY)
- {
- mpr("You're too hungry.");
- return (false);
- }
-
- // no turning back now... {dlb}
- const struct ability_def abil = get_ability_def(Curr_abil[abil_used].which);
-
- // currently only delayed fireball is instantaneous -- bwr
- you.turn_is_over = ((abil.flags & ABFLAG_INSTANT) ? 0 : 1);
-
- if (random2avg(100, 3) < Curr_abil[abil_used].fail)
- {
- mpr("You fail to use your ability.");
- return (false);
- }
-
- if (!enough_mp( abil.mp_cost, false ))
- return (false);
-
- if (!enough_hp( abil.hp_cost, false ))
- return (false);
-
- // Note: the costs will not be applied until after this switch
- // statement... it's assumed that only failures have returned! -- bwr
- switch (abil.ability)
- {
- case ABIL_MUMMY_RESTORATION:
- mpr( "You infuse your body with magical energy." );
- restore_stat( STAT_ALL, false );
- unrot_hp( 100 );
- break;
-
- case ABIL_DELAYED_FIREBALL:
- // Note: power level of ball calculated at release -- bwr
- fireball( calc_spell_power( SPELL_DELAYED_FIREBALL, true ) );
-
- // only one allowed since this is instantaneous -- bwr
- you.attribute[ ATTR_DELAYED_FIREBALL ] = 0;
- break;
-
- case ABIL_GLAMOUR:
- if (you.duration[DUR_GLAMOUR])
- {
- canned_msg(MSG_CANNOT_DO_YET);
- return (false);
- }
-
- mpr("You use your Elvish wiles.");
-
- cast_glamour( 10 + random2(you.experience_level)
- + random2(you.experience_level) );
-
- you.duration[DUR_GLAMOUR] = 20 + random2avg(13, 3);
- break;
-
- case ABIL_SPIT_POISON: // Naga + spit poison mutation
- if (you.duration[DUR_BREATH_WEAPON])
- {
- canned_msg(MSG_CANNOT_DO_YET);
- return (false);
- }
- else if (spell_direction(abild, beam) == -1)
- {
- canned_msg(MSG_OK);
- return (false);
- }
- else
- {
- mpr("You spit poison.");
-
- zapping( ZAP_SPIT_POISON,
- you.experience_level
- + you.mutation[MUT_SPIT_POISON] * 5
- + (you.species == SP_NAGA) * 10,
- beam );
-
- you.duration[DUR_BREATH_WEAPON] = 3 + random2(5);
- }
- break;
-
- case ABIL_EVOKE_MAPPING: // randarts
- mpr("You sense your surroundings.");
-
- magic_mapping( 3 + roll_dice( 2, you.skills[SK_EVOCATIONS] ),
- 40 + roll_dice( 2, you.skills[SK_EVOCATIONS] ) );
-
- exercise( SK_EVOCATIONS, 1 );
- break;
-
- case ABIL_MAPPING: // Gnome + sense surrounds mut
- mpr("You sense your surroundings.");
-
- magic_mapping( 3 + roll_dice( 2, you.experience_level )
- + you.mutation[MUT_MAPPING] * 10,
- 40 + roll_dice( 2, you.experience_level ) );
- break;
-
- case ABIL_EVOKE_TELEPORTATION: // ring of teleportation
- case ABIL_TELEPORTATION: // teleport mut
- if (you.mutation[MUT_TELEPORT_AT_WILL] == 3)
- you_teleport2( true, true ); // instant and to new area of Abyss
- else
- you_teleport();
-
- if (abil.ability == ABIL_EVOKE_TELEPORTATION)
- exercise( SK_EVOCATIONS, 1 );
- break;
-
- case ABIL_BREATHE_FIRE:
- case ABIL_BREATHE_FROST:
- case ABIL_BREATHE_POISON:
- case ABIL_BREATHE_LIGHTNING:
- case ABIL_SPIT_ACID:
- case ABIL_BREATHE_POWER:
- case ABIL_BREATHE_STICKY_FLAME:
- case ABIL_BREATHE_STEAM:
- if (you.duration[DUR_BREATH_WEAPON]
- && Curr_abil[abil_used].which != ABIL_SPIT_ACID)
- {
- canned_msg(MSG_CANNOT_DO_YET);
- return (false);
- }
- else if (spell_direction( abild, beam ) == -1)
- {
- canned_msg(MSG_OK);
- return (false);
- }
-
- switch (Curr_abil[abil_used].which)
- {
- case ABIL_BREATHE_FIRE:
- power = you.experience_level;
- power += you.mutation[MUT_BREATHE_FLAMES] * 4;
-
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON)
- power += 12;
-
- // don't check for hell serpents - they get hell fire,
- // never regular fire (GDL)
-
- snprintf( info, INFO_SIZE, "You breathe fire%c", (power < 15)?'.':'!');
- mpr(info);
-
- zapping( ZAP_BREATHE_FIRE, power, beam);
- break;
-
- case ABIL_BREATHE_FROST:
- mpr("You exhale a wave of freezing cold.");
- zapping(ZAP_BREATHE_FROST, you.experience_level, beam);
- break;
-
- case ABIL_BREATHE_POISON:
- mpr("You exhale a blast of poison gas.");
- zapping(ZAP_BREATHE_POISON, you.experience_level, beam);
- break;
-
- case ABIL_BREATHE_LIGHTNING:
- mpr("You spit a bolt of lightning.");
- zapping(ZAP_LIGHTNING, (you.experience_level * 2), beam);
- break;
-
- case ABIL_SPIT_ACID:
- mpr("You spit acid.");
- zapping(ZAP_BREATHE_ACID, you.experience_level, beam);
- break;
-
- case ABIL_BREATHE_POWER:
- mpr("You spit a bolt of incandescent energy.");
- zapping(ZAP_BREATHE_POWER, you.experience_level, beam);
- break;
-
- case ABIL_BREATHE_STICKY_FLAME:
- mpr("You spit a glob of burning liquid.");
- zapping(ZAP_STICKY_FLAME, you.experience_level, beam);
- break;
-
- case ABIL_BREATHE_STEAM:
- mpr("You exhale a blast of scalding steam.");
- zapping(ZAP_BREATHE_STEAM, you.experience_level, beam);
- break;
-
- }
-
- if (Curr_abil[abil_used].which != ABIL_SPIT_ACID)
- {
- you.duration[DUR_BREATH_WEAPON] = 3 + random2(5)
- + random2(30 - you.experience_level);
- }
-
- if (Curr_abil[abil_used].which == ABIL_BREATHE_STEAM)
- {
- you.duration[DUR_BREATH_WEAPON] /= 2;
- }
- break;
-
- case ABIL_EVOKE_BLINK: // randarts
- case ABIL_BLINK: // mutation
- random_blink(true);
-
- if (abil.ability == ABIL_EVOKE_BLINK)
- exercise( SK_EVOCATIONS, 1 );
- break;
-
- case ABIL_EVOKE_BERSERK: // amulet of rage, randarts
- if (you.hunger_state < HS_SATIATED)
- {
- mpr("You're too hungry to berserk.");
- return (false);
- }
-
- go_berserk(true);
- exercise( SK_EVOCATIONS, 1 );
- break;
-
- // fly (kenku) -- eventually becomes permanent (see acr.cc)
- case ABIL_FLY:
- cast_fly( you.experience_level * 4 );
-
- if (you.experience_level > 14)
- {
- mpr("You feel very comfortable in the air.");
- you.levitation = 100;
- you.duration[DUR_CONTROLLED_FLIGHT] = 100;
- }
- break;
-
- case ABIL_FLY_II: // Fly (Draconians, or anything else with wings)
- if (you.exhausted)
- {
- mpr("You're too exhausted to fly.");
- return (false);
- }
- else if (you.burden_state != BS_UNENCUMBERED)
- {
- mpr("You're carrying too much weight to fly.");
- return (false);
- }
- else
- {
- cast_fly( you.experience_level * 2 );
- // you.attribute[ATTR_EXPENSIVE_FLIGHT] = 1; // unused
- }
- break;
-
- // DEMONIC POWERS:
- case ABIL_SUMMON_MINOR_DEMON:
- summon_ice_beast_etc( you.experience_level * 4,
- summon_any_demon(DEMON_LESSER) );
- break;
-
- case ABIL_SUMMON_DEMONS:
- summon_ice_beast_etc( you.experience_level * 4,
- summon_any_demon(DEMON_COMMON) );
- break;
-
- case ABIL_HELLFIRE:
- your_spells(SPELL_HELLFIRE, 20 + you.experience_level, false);
- break;
-
- case ABIL_TORMENT:
- if (you.is_undead)
- {
- mpr("The unliving cannot use this ability.");
- return (false);
- }
-
- torment(you.x_pos, you.y_pos);
- break;
-
- case ABIL_RAISE_DEAD:
- your_spells(SPELL_ANIMATE_DEAD, you.experience_level * 5, false);
- break;
-
- case ABIL_CONTROL_DEMON:
- if (spell_direction(abild, beam) == -1)
- {
- canned_msg(MSG_OK);
- return (false);
- }
-
- zapping(ZAP_CONTROL_DEMON, you.experience_level * 5, beam);
- break;
-
- case ABIL_TO_PANDEMONIUM:
- if (you.level_type == LEVEL_PANDEMONIUM)
- {
- mpr("You're already here.");
- return (false);
- }
-
- banished(DNGN_ENTER_PANDEMONIUM);
- break;
-
- case ABIL_CHANNELING:
- mpr("You channel some magical energy.");
- inc_mp(1 + random2(5), false);
- break;
-
- case ABIL_THROW_FLAME:
- case ABIL_THROW_FROST:
- if (spell_direction(abild, beam) == -1)
- {
- canned_msg(MSG_OK);
- return (false);
- }
-
- zapping( (Curr_abil[abil_used].which == ABIL_THROW_FLAME ? ZAP_FLAME
- : ZAP_FROST),
- you.experience_level * 3,
- beam );
- break;
-
- case ABIL_BOLT_OF_DRAINING:
- if (spell_direction(abild, beam) == -1)
- {
- canned_msg(MSG_OK);
- return (false);
- }
-
- zapping(ZAP_NEGATIVE_ENERGY, you.experience_level * 6, beam);
- break;
-
- case ABIL_EVOKE_TURN_INVISIBLE: // ring, randarts, darkness items
- if (you.hunger_state < HS_SATIATED)
- {
- mpr("You're too hungry to turn invisible.");
- return (false);
- }
-
- potion_effect( POT_INVISIBILITY, 2 * you.skills[SK_EVOCATIONS] + 5 );
- contaminate_player( 1 + random2(3) );
- exercise( SK_EVOCATIONS, 1 );
- break;
-
- case ABIL_EVOKE_TURN_VISIBLE:
- mpr("You feel less transparent.");
- you.invis = 1;
- break;
-
- case ABIL_EVOKE_LEVITATE: // ring, boots, randarts
- potion_effect( POT_LEVITATION, 2 * you.skills[SK_EVOCATIONS] + 30 );
- exercise( SK_EVOCATIONS, 1 );
- break;
-
- case ABIL_EVOKE_STOP_LEVITATING:
- mpr("You feel heavy.");
- you.levitation = 1;
- break;
-
- case ABIL_END_TRANSFORMATION:
- mpr("You feel almost normal.");
- you.duration[DUR_TRANSFORMATION] = 2;
- break;
-
- // INVOCATIONS:
- case ABIL_ZIN_REPEL_UNDEAD:
- case ABIL_TSO_REPEL_UNDEAD:
- turn_undead(you.piety);
-
- if (!you.duration[DUR_REPEL_UNDEAD])
- mpr( "You feel a holy aura protecting you." );
-
- you.duration[DUR_REPEL_UNDEAD] += 8
- + roll_dice(2, 2 * you.skills[SK_INVOCATIONS]);
-
- if (you.duration[ DUR_REPEL_UNDEAD ] > 50)
- you.duration[ DUR_REPEL_UNDEAD ] = 50;
-
- exercise(SK_INVOCATIONS, 1);
- break;
-
- case ABIL_ZIN_HEALING:
- if (!cast_healing( 3 + (you.skills[SK_INVOCATIONS] / 6) ))
- break;
-
- exercise(SK_INVOCATIONS, 1 + random2(3));
- break;
-
- case ABIL_ZIN_PESTILENCE:
- mpr( "You call forth a swarm of pestilential beasts!" );
-
- if (!summon_swarm( you.skills[SK_INVOCATIONS] * 8, false, true ))
- mpr( "Nothing seems to have answered your call." );
-
- exercise( SK_INVOCATIONS, 2 + random2(4) );
- break;
-
- case ABIL_ZIN_HOLY_WORD:
- holy_word( you.skills[SK_INVOCATIONS] * 8 );
- exercise(SK_INVOCATIONS, 3 + random2(5));
- break;
-
- case ABIL_ZIN_SUMMON_GUARDIAN:
- summon_ice_beast_etc(you.skills[SK_INVOCATIONS] * 4, MONS_ANGEL);
- exercise(SK_INVOCATIONS, 8 + random2(10));
- break;
-
- case ABIL_TSO_SMITING:
- cast_smiting( you.skills[SK_INVOCATIONS] * 6 );
- exercise( SK_INVOCATIONS, (coinflip()? 3 : 2) );
- break;
-
- case ABIL_TSO_ANNIHILATE_UNDEAD:
- if (spell_direction(spd, beam) == -1)
- {
- canned_msg(MSG_OK);
- return (false);
- }
-
- zapping(ZAP_DISPEL_UNDEAD, you.skills[SK_INVOCATIONS] * 6, beam);
- exercise(SK_INVOCATIONS, 2 + random2(4));
- break;
-
- case ABIL_TSO_CLEANSING_FLAME:
- if (spell_direction(spd, beam) == -1)
- {
- canned_msg(MSG_OK);
- return (false);
- }
-
- zapping(ZAP_CLEANSING_FLAME, 20 + you.skills[SK_INVOCATIONS] * 6, beam);
- exercise(SK_INVOCATIONS, 3 + random2(6));
- break;
-
- case ABIL_TSO_SUMMON_DAEVA:
- summon_ice_beast_etc(you.skills[SK_INVOCATIONS] * 4, MONS_DAEVA);
- exercise(SK_INVOCATIONS, 8 + random2(10));
- break;
-
- case ABIL_KIKU_RECALL_UNDEAD_SLAVES:
- recall(1);
- exercise(SK_INVOCATIONS, 1);
- break;
-
- case ABIL_KIKU_ENSLAVE_UNDEAD:
- if (spell_direction(spd, beam) == -1)
- {
- canned_msg(MSG_OK);
- return (false);
- }
-
- zapping( ZAP_ENSLAVE_UNDEAD, you.skills[SK_INVOCATIONS] * 8, beam );
- exercise(SK_INVOCATIONS, 5 + random2(5));
- break;
-
- case ABIL_KIKU_INVOKE_DEATH:
- summon_ice_beast_etc(
- 20 + you.skills[SK_INVOCATIONS] * 3, MONS_REAPER, true);
- exercise(SK_INVOCATIONS, 10 + random2(14));
- break;
-
- case ABIL_YRED_ANIMATE_CORPSE:
- mpr("You call on the dead to walk for you...");
-
- animate_a_corpse( you.x_pos, you.y_pos, BEH_FRIENDLY,
- you.pet_target, CORPSE_BODY );
-
- exercise(SK_INVOCATIONS, 2 + random2(4));
- break;
-
- case ABIL_YRED_RECALL_UNDEAD:
- recall(1);
- exercise(SK_INVOCATIONS, 2 + random2(4));
- break;
-
- case ABIL_YRED_ANIMATE_DEAD:
- mpr("You call on the dead to walk for you...");
-
- animate_dead( 1 + you.skills[SK_INVOCATIONS], BEH_FRIENDLY,
- you.pet_target, 1 );
-
- exercise(SK_INVOCATIONS, 2 + random2(4));
- break;
-
- case ABIL_YRED_DRAIN_LIFE:
- drain_life( you.skills[SK_INVOCATIONS] );
- exercise(SK_INVOCATIONS, 2 + random2(4));
- break;
-
- case ABIL_YRED_CONTROL_UNDEAD:
- mass_enchantment( ENCH_CHARM, you.skills[SK_INVOCATIONS] * 8, MHITYOU );
- exercise(SK_INVOCATIONS, 3 + random2(4));
- break;
-
- case ABIL_VEHUMET_CHANNEL_ENERGY:
- mpr("You channel some magical energy.");
-
- inc_mp(1 + random2(you.skills[SK_INVOCATIONS] / 4 + 2), false);
- exercise(SK_INVOCATIONS, 1 + random2(3));
- break;
-
- case ABIL_OKAWARU_MIGHT:
- potion_effect( POT_MIGHT, you.skills[SK_INVOCATIONS] * 8 );
- exercise(SK_INVOCATIONS, 1 + random2(3));
- break;
-
- case ABIL_OKAWARU_HEALING:
- if (!cast_healing( 3 + (you.skills[SK_INVOCATIONS] / 6) ))
- break;
-
- exercise(SK_INVOCATIONS, 2 + random2(5));
- break;
-
- case ABIL_OKAWARU_HASTE:
- potion_effect( POT_SPEED, you.skills[SK_INVOCATIONS] * 8 );
- exercise(SK_INVOCATIONS, 3 + random2(7));
- break;
-
- case ABIL_MAKHLEB_MINOR_DESTRUCTION:
- if (spell_direction(spd, beam) == -1)
- {
- canned_msg(MSG_OK);
- return (false);
- }
-
- power = you.skills[SK_INVOCATIONS]
- + random2( 1 + you.skills[SK_INVOCATIONS] )
- + random2( 1 + you.skills[SK_INVOCATIONS] );
-
- switch (random2(5))
- {
- case 0: zapping( ZAP_FLAME, power, beam ); break;
- case 1: zapping( ZAP_PAIN, power, beam ); break;
- case 2: zapping( ZAP_STONE_ARROW, power, beam ); break;
- case 3: zapping( ZAP_ELECTRICITY, power, beam ); break;
- case 4: zapping( ZAP_BREATHE_ACID, power / 2, beam ); break;
- }
-
- exercise(SK_INVOCATIONS, 1);
- break;
-
- case ABIL_MAKHLEB_LESSER_SERVANT_OF_MAKHLEB:
- summon_ice_beast_etc( 20 + you.skills[SK_INVOCATIONS] * 3,
- MONS_NEQOXEC + random2(5) );
-
- exercise(SK_INVOCATIONS, 2 + random2(3));
- break;
-
- case ABIL_MAKHLEB_MAJOR_DESTRUCTION:
- if (spell_direction(spd, beam) == -1)
- {
- canned_msg(MSG_OK);
- return (false);
- }
-
- power = you.skills[SK_INVOCATIONS] * 3
- + random2( 1 + you.skills[SK_INVOCATIONS] )
- + random2( 1 + you.skills[SK_INVOCATIONS] );
-
- switch (random2(8))
- {
- case 0: zapping( ZAP_FIRE, power, beam ); break;
- case 1: zapping( ZAP_FIREBALL, power, beam ); break;
- case 2: zapping( ZAP_LIGHTNING, power, beam ); break;
- case 3: zapping( ZAP_NEGATIVE_ENERGY, power, beam ); break;
- case 4: zapping( ZAP_STICKY_FLAME, power, beam ); break;
- case 5: zapping( ZAP_IRON_BOLT, power, beam ); break;
- case 6: zapping( ZAP_ORB_OF_ELECTRICITY, power, beam ); break;
-
- case 7:
- you.attribute[ATTR_DIVINE_LIGHTNING_PROTECTION] = 1;
- mpr("Makhleb hurls a blast of lightning!");
-
- // make a divine lightning bolt...
- beam.beam_source = NON_MONSTER;
- beam.type = SYM_BURST;
- beam.damage = dice_def( 3, 30 );
- beam.flavour = BEAM_ELECTRICITY;
- beam.target_x = you.x_pos;
- beam.target_y = you.y_pos;
- strcpy(beam.beam_name, "blast of lightning");
- beam.colour = LIGHTCYAN;
- beam.thrower = KILL_YOU;
- beam.aux_source = "Makhleb's lightning strike";
- beam.ex_size = 1 + you.skills[SK_INVOCATIONS] / 8;
- beam.is_tracer = false;
-
- // ... and fire!
- explosion(beam);
-
- // protection down
- mpr("Your divine protection wanes.");
- you.attribute[ATTR_DIVINE_LIGHTNING_PROTECTION] = 0;
- break;
- }
-
- exercise(SK_INVOCATIONS, 3 + random2(5));
- break;
-
- case ABIL_MAKHLEB_GREATER_SERVANT_OF_MAKHLEB:
- summon_ice_beast_etc( 20 + you.skills[SK_INVOCATIONS] * 3,
- MONS_EXECUTIONER + random2(5) );
-
- exercise(SK_INVOCATIONS, 6 + random2(6));
- break;
-
- case ABIL_TROG_BERSERK:
- // Trog abilities don't use or train invocations.
- if (you.hunger_state < HS_SATIATED)
- {
- mpr("You're too hungry to berserk.");
- return (false);
- }
-
- go_berserk(true);
- break;
-
- case ABIL_TROG_MIGHT:
- // Trog abilities don't use or train invocations.
- potion_effect( POT_MIGHT, 150 );
- break;
-
- case ABIL_TROG_HASTE_SELF:
- // Trog abilities don't use or train invocations.
- potion_effect( POT_SPEED, 150 );
- break;
-
- case ABIL_SIF_MUNA_FORGET_SPELL:
- cast_selective_amnesia(true);
- break;
-
- case ABIL_ELYVILON_LESSER_HEALING:
- if (!cast_healing( 3 + (you.skills[SK_INVOCATIONS] / 6) ))
- break;
-
- exercise( SK_INVOCATIONS, 1 );
- break;
-
- case ABIL_ELYVILON_PURIFICATION:
- purification();
- exercise( SK_INVOCATIONS, 2 + random2(3) );
- break;
-
- case ABIL_ELYVILON_HEALING:
- if (!cast_healing( 10 + (you.skills[SK_INVOCATIONS] / 3) ))
- break;
-
- exercise( SK_INVOCATIONS, 3 + random2(5) );
- break;
-
- case ABIL_ELYVILON_RESTORATION:
- restore_stat( STAT_ALL, false );
- unrot_hp( 100 );
-
- exercise( SK_INVOCATIONS, 4 + random2(6) );
- break;
-
- case ABIL_ELYVILON_GREATER_HEALING:
- if (!cast_healing( 20 + you.skills[SK_INVOCATIONS] * 2 ))
- break;
-
- exercise( SK_INVOCATIONS, 6 + random2(10) );
- break;
-
- //jmf: intended as invocations from evil god(s):
- case ABIL_CHARM_SNAKE:
- cast_snake_charm( you.experience_level * 2
- + you.skills[SK_INVOCATIONS] * 3 );
-
- exercise(SK_INVOCATIONS, 2 + random2(4));
- break;
-
- case ABIL_TRAN_SERPENT_OF_HELL:
- transform(10 + (you.experience_level * 2) +
- (you.skills[SK_INVOCATIONS] * 3), TRAN_SERPENT_OF_HELL);
-
- exercise(SK_INVOCATIONS, 6 + random2(9));
- break;
-
- case ABIL_BREATHE_HELLFIRE:
- if (you.duration[DUR_BREATH_WEAPON])
- {
- canned_msg(MSG_CANNOT_DO_YET);
- return (false);
- }
-
- your_spells( SPELL_HELLFIRE, 20 + you.experience_level, false );
-
- you.duration[DUR_BREATH_WEAPON] +=
- 3 + random2(5) + random2(30 - you.experience_level);
- break;
-
- case ABIL_ROTTING:
- cast_rotting(you.experience_level * 2 + you.skills[SK_INVOCATIONS] * 3);
- exercise(SK_INVOCATIONS, 2 + random2(4));
- break;
-
- case ABIL_TORMENT_II:
- if (you.is_undead)
- {
- mpr("The unliving cannot use this ability.");
- return (false);
- }
-
- torment(you.x_pos, you.y_pos);
- exercise(SK_INVOCATIONS, 2 + random2(4));
- break;
-
- case ABIL_RENOUNCE_RELIGION:
- if (yesno("Really renounce your faith, foregoing its fabulous benefits?")
- && yesno( "Are you sure you won't change your mind later?" ))
- {
- excommunication();
- }
- else
- {
- canned_msg(MSG_OK);
- }
- break;
-
- default:
- mpr("Sorry, you can't do that.");
- break;
- }
-
- // All failures should have returned by this point, so we'll
- // apply the costs -- its not too neat, but it works for now. -- bwr
- const int food_cost = abil.food_cost + random2avg(abil.food_cost, 2);
- const int piety_cost = abil.piety_cost + random2((abil.piety_cost + 1) / 2 + 1);
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "Cost: mp=%d; hp=%d; food=%d; piety=%d",
- abil.mp_cost, abil.hp_cost, food_cost, piety_cost );
-
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- if (abil.mp_cost)
- {
- dec_mp( abil.mp_cost );
- if (abil.flags & ABFLAG_PERMANENT_MP)
- rot_mp(1);
- }
-
- if (abil.hp_cost)
- {
- dec_hp( abil.hp_cost, false );
- if (abil.flags & ABFLAG_PERMANENT_HP)
- rot_hp(1);
- }
-
- if (food_cost)
- make_hungry( food_cost, false );
-
- if (piety_cost)
- lose_piety( piety_cost );
-
- return (true);
-} // end activate_ability()
-
-
-// Lists any abilities the player may possess
-char show_abilities( void )
-/*************************/
-{
- int loopy = 0;
- char lines = 0;
- unsigned char anything = 0;
- char ki;
- bool can_invoke = false;
-
- const int num_lines = get_number_of_lines();
-
- for (loopy = 0; loopy < 52; loopy++)
- {
- if (Curr_abil[loopy].is_invocation)
- {
- can_invoke = true;
- break;
- }
- }
-
-
-#ifdef DOS_TERM
- char buffer[4800];
-
- gettext(1, 1, 80, 25, buffer);
- window(1, 1, 80, 25);
-#endif
-
- clrscr();
- cprintf(" Ability Cost Success");
- lines++;
-
- for (int do_invoke = 0; do_invoke < (can_invoke ? 2 : 1); do_invoke++)
- {
- if (do_invoke)
- {
- anything++;
- textcolor(BLUE);
- cprintf(EOL " Invocations - ");
- textcolor(LIGHTGREY);
- lines++;
- }
-
- for (loopy = 0; loopy < 52; loopy++)
- {
- if (lines > num_lines - 2)
- {
- gotoxy(1, num_lines);
- cprintf("-more-");
-
- ki = getch();
-
- if (ki == ESCAPE)
- {
-#ifdef DOS_TERM
- puttext(1, 1, 80, 25, buffer);
-#endif
- return (ESCAPE);
- }
-
- if (ki >= 'A' && ki <= 'z')
- {
-#ifdef DOS_TERM
- puttext(1, 1, 80, 25, buffer);
-#endif
- return (ki);
- }
-
- if (ki == 0)
- ki = getch();
-
- lines = 0;
- clrscr();
- gotoxy(1, 1);
- anything = 0;
- }
-
- if (Curr_abil[loopy].which != ABIL_NON_ABILITY
- && (do_invoke == Curr_abil[loopy].is_invocation))
- {
- anything++;
-
- if (lines > 0)
- cprintf(EOL);
-
- lines++;
-
- const struct ability_def abil = get_ability_def( Curr_abil[loopy].which );
-
- cprintf( " %c - %s", index_to_letter(loopy), abil.name );
-
- // Output costs:
- gotoxy( 35, wherey() );
-
- std::string cost_str = make_cost_description( abil );
-
- if (cost_str.length() > 24)
- cost_str = cost_str.substr( 0, 24 );
-
- cprintf( cost_str.c_str() );
-
- gotoxy(60, wherey());
-
- int spell_f = Curr_abil[loopy].fail;
-
- cprintf( (spell_f >= 100) ? "Useless" :
- (spell_f > 90) ? "Terrible" :
- (spell_f > 80) ? "Cruddy" :
- (spell_f > 70) ? "Bad" :
- (spell_f > 60) ? "Very Poor" :
- (spell_f > 50) ? "Poor" :
- (spell_f > 40) ? "Fair" :
- (spell_f > 30) ? "Good" :
- (spell_f > 20) ? "Very Good" :
- (spell_f > 10) ? "Great" :
- (spell_f > 0) ? "Excellent" :
- "Perfect" );
-
- gotoxy(70, wherey());
- } // end if conditional
- } // end "for loopy"
- }
-
- if (anything > 0)
- {
- ki = getch();
-
- if (ki >= 'A' && ki <= 'z')
- {
-#ifdef DOS_TERM
- puttext(1, 1, 80, 25, buffer);
-#endif
- return (ki);
- }
-
- if (ki == 0)
- ki = getch();
-
-#ifdef DOS_TERM
- puttext(1, 1, 80, 25, buffer);
-#endif
-
- return (ki);
- }
-
-#ifdef DOS_TERM
- puttext(1, 1, 80, 25, buffer);
-#endif
-
- ki = getch();
-
- return (ki);
-} // end show_abilities()
-
-
-bool generate_abilities( void )
-/*****************************/
-{
- int loopy;
- int ability = -1; // used with draconian checks {dlb}
-
- // fill array of structs with "empty" values {dlb}:
- for (loopy = 0; loopy < 52; loopy++)
- {
- Curr_abil[loopy].which = ABIL_NON_ABILITY;
- Curr_abil[loopy].fail = 100;
- Curr_abil[loopy].is_invocation = false;
- }
-
- // first we do the racial abilities:
-
- // Mummies get the ability to restore HPs and stats, but it
- // costs permanent MP (and those can never be recovered). -- bwr
- if (you.species == SP_MUMMY && you.experience_level >= 13)
- {
- insert_ability( ABIL_MUMMY_RESTORATION );
- }
-
- // checking for species-related abilities and mutagenic counterparts {dlb}:
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_NONE
- && ((you.species == SP_GREY_ELF && you.experience_level >= 5)
- || (you.species == SP_HIGH_ELF && you.experience_level >= 15)))
- {
- insert_ability( ABIL_GLAMOUR );
- }
-
- if (you.species == SP_NAGA)
- {
- if (you.mutation[MUT_BREATHE_POISON])
- insert_ability( ABIL_BREATHE_POISON );
- else
- insert_ability( ABIL_SPIT_POISON );
- }
- else if (you.mutation[MUT_SPIT_POISON])
- {
- insert_ability( ABIL_SPIT_POISON );
- }
-
- if (player_genus(GENPC_DRACONIAN))
- {
- if (you.experience_level >= 7)
- {
- ability = (
- (you.species == SP_GREEN_DRACONIAN) ? ABIL_BREATHE_POISON :
- (you.species == SP_RED_DRACONIAN) ? ABIL_BREATHE_FIRE :
- (you.species == SP_WHITE_DRACONIAN) ? ABIL_BREATHE_FROST :
- (you.species == SP_GOLDEN_DRACONIAN) ? ABIL_SPIT_ACID :
- (you.species == SP_BLACK_DRACONIAN) ? ABIL_BREATHE_LIGHTNING :
- (you.species == SP_PURPLE_DRACONIAN) ? ABIL_BREATHE_POWER :
- (you.species == SP_PALE_DRACONIAN) ? ABIL_BREATHE_STEAM :
- (you.species == SP_MOTTLED_DRACONIAN)? ABIL_BREATHE_STICKY_FLAME:
- -1);
-
- if (ability != -1)
- insert_ability( ability );
- }
- }
-
- //jmf: alternately put check elsewhere
- if ((you.level_type == LEVEL_DUNGEON
- && (you.species == SP_GNOME || you.mutation[MUT_MAPPING]))
- || (you.level_type == LEVEL_PANDEMONIUM
- && you.mutation[MUT_MAPPING] == 3))
- {
- insert_ability( ABIL_MAPPING );
- }
-
- if (!you.duration[DUR_CONTROLLED_FLIGHT] && !player_is_levitating())
- {
- // kenku can fly, but only from the ground
- // (until levitation 15, when it becomes permanent until revoked)
- //jmf: "upgrade" for draconians -- expensive flight
- if (you.species == SP_KENKU && you.experience_level >= 5)
- insert_ability( ABIL_FLY );
- else if (player_genus(GENPC_DRACONIAN) && you.mutation[MUT_BIG_WINGS])
- insert_ability( ABIL_FLY_II );
- }
-
- // demonic powers {dlb}:
- if (you.mutation[MUT_SUMMON_MINOR_DEMONS])
- insert_ability( ABIL_SUMMON_MINOR_DEMON );
-
- if (you.mutation[MUT_SUMMON_DEMONS])
- insert_ability( ABIL_SUMMON_DEMONS );
-
- if (you.mutation[MUT_HURL_HELLFIRE])
- insert_ability( ABIL_HELLFIRE );
-
- if (you.mutation[MUT_CALL_TORMENT])
- insert_ability( ABIL_TORMENT );
-
- if (you.mutation[MUT_RAISE_DEAD])
- insert_ability( ABIL_RAISE_DEAD );
-
- if (you.mutation[MUT_CONTROL_DEMONS])
- insert_ability( ABIL_CONTROL_DEMON );
-
- if (you.mutation[MUT_PANDEMONIUM])
- insert_ability( ABIL_TO_PANDEMONIUM );
-
- if (you.mutation[MUT_CHANNEL_HELL])
- insert_ability( ABIL_CHANNELING );
-
- if (you.mutation[MUT_THROW_FLAMES])
- insert_ability( ABIL_THROW_FLAME );
-
- if (you.mutation[MUT_THROW_FROST])
- insert_ability( ABIL_THROW_FROST );
-
- if (you.mutation[MUT_SMITE])
- insert_ability( ABIL_BOLT_OF_DRAINING );
-
- if (you.duration[DUR_TRANSFORMATION])
- insert_ability( ABIL_END_TRANSFORMATION );
-
- if (you.mutation[MUT_BLINK])
- insert_ability( ABIL_BLINK );
-
- if (you.mutation[MUT_TELEPORT_AT_WILL])
- insert_ability( ABIL_TELEPORTATION );
-
- // gods take abilities away until penance completed -- bwr
- if (!player_under_penance() && !silenced( you.x_pos, you.y_pos ))
- {
- switch (you.religion)
- {
- case GOD_ZIN:
- if (you.piety >= 30)
- insert_ability( ABIL_ZIN_REPEL_UNDEAD );
- if (you.piety >= 50)
- insert_ability( ABIL_ZIN_HEALING );
- if (you.piety >= 75)
- insert_ability( ABIL_ZIN_PESTILENCE );
- if (you.piety >= 100)
- insert_ability( ABIL_ZIN_HOLY_WORD );
- if (you.piety >= 120)
- insert_ability( ABIL_ZIN_SUMMON_GUARDIAN );
- break;
-
- case GOD_SHINING_ONE:
- if (you.piety >= 30)
- insert_ability( ABIL_TSO_REPEL_UNDEAD );
- if (you.piety >= 50)
- insert_ability( ABIL_TSO_SMITING );
- if (you.piety >= 75)
- insert_ability( ABIL_TSO_ANNIHILATE_UNDEAD );
- if (you.piety >= 100)
- insert_ability( ABIL_TSO_CLEANSING_FLAME );
- if (you.piety >= 120)
- insert_ability( ABIL_TSO_SUMMON_DAEVA );
- break;
-
- case GOD_YREDELEMNUL:
- if (you.piety >= 30)
- insert_ability( ABIL_YRED_ANIMATE_CORPSE );
- if (you.piety >= 50)
- insert_ability( ABIL_YRED_RECALL_UNDEAD );
- if (you.piety >= 75)
- insert_ability( ABIL_YRED_ANIMATE_DEAD );
- if (you.piety >= 100)
- insert_ability( ABIL_YRED_DRAIN_LIFE );
- if (you.piety >= 120)
- insert_ability( ABIL_YRED_CONTROL_UNDEAD );
- break;
-
- case GOD_ELYVILON:
- if (you.piety >= 30)
- insert_ability( ABIL_ELYVILON_LESSER_HEALING );
- if (you.piety >= 50)
- insert_ability( ABIL_ELYVILON_PURIFICATION );
- if (you.piety >= 75)
- insert_ability( ABIL_ELYVILON_HEALING );
- if (you.piety >= 100)
- insert_ability( ABIL_ELYVILON_RESTORATION );
- if (you.piety >= 120)
- insert_ability( ABIL_ELYVILON_GREATER_HEALING );
- break;
-
- case GOD_MAKHLEB:
- if (you.piety >= 50)
- insert_ability( ABIL_MAKHLEB_MINOR_DESTRUCTION );
- if (you.piety >= 75)
- insert_ability( ABIL_MAKHLEB_LESSER_SERVANT_OF_MAKHLEB );
- if (you.piety >= 100)
- insert_ability( ABIL_MAKHLEB_MAJOR_DESTRUCTION );
- if (you.piety >= 120)
- insert_ability( ABIL_MAKHLEB_GREATER_SERVANT_OF_MAKHLEB );
- break;
-
- case GOD_KIKUBAAQUDGHA:
- if (you.piety >= 30)
- insert_ability( ABIL_KIKU_RECALL_UNDEAD_SLAVES );
- if (you.piety >= 75)
- insert_ability( ABIL_KIKU_ENSLAVE_UNDEAD );
- if (you.piety >= 120)
- insert_ability( ABIL_KIKU_INVOKE_DEATH );
- break;
-
- case GOD_OKAWARU:
- if (you.piety >= 30)
- insert_ability( ABIL_OKAWARU_MIGHT );
- if (you.piety >= 50)
- insert_ability( ABIL_OKAWARU_HEALING );
- if (you.piety >= 120)
- insert_ability( ABIL_OKAWARU_HASTE );
- break;
-
- case GOD_TROG:
- if (you.piety >= 30)
- insert_ability( ABIL_TROG_BERSERK );
- if (you.piety >= 50)
- insert_ability( ABIL_TROG_MIGHT );
- if (you.piety >= 100)
- insert_ability( ABIL_TROG_HASTE_SELF );
- break;
-
- case GOD_SIF_MUNA:
- if (you.piety >= 50)
- insert_ability( ABIL_SIF_MUNA_FORGET_SPELL );
- break;
-
- case GOD_VEHUMET:
- if (you.piety >= 100)
- insert_ability( ABIL_VEHUMET_CHANNEL_ENERGY );
- break;
-
- default:
- break;
- }
- }
-
- // and finally, the ability to opt-out of your faith {dlb}:
- if (you.religion != GOD_NO_GOD && !silenced( you.x_pos, you.y_pos ))
- insert_ability( ABIL_RENOUNCE_RELIGION );
-
- //jmf: check for breath weapons -- they're exclusive of each other I hope!
- // better make better ones first.
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_SERPENT_OF_HELL)
- {
- insert_ability( ABIL_BREATHE_HELLFIRE );
- }
- else if (you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON
- || you.mutation[MUT_BREATHE_FLAMES])
- {
- insert_ability( ABIL_BREATHE_FIRE );
- }
-
- // checking for unreleased delayed fireball
- if (you.attribute[ ATTR_DELAYED_FIREBALL ])
- {
- insert_ability( ABIL_DELAYED_FIREBALL );
- }
-
- // evocations from items:
- if (scan_randarts(RAP_BLINK))
- insert_ability( ABIL_EVOKE_BLINK );
-
- if (wearing_amulet(AMU_RAGE) || scan_randarts(RAP_BERSERK))
- insert_ability( ABIL_EVOKE_BERSERK );
-
- if (scan_randarts( RAP_MAPPING ))
- insert_ability( ABIL_EVOKE_MAPPING );
-
- if (player_equip( EQ_RINGS, RING_INVISIBILITY )
- || player_equip_ego_type( EQ_ALL_ARMOUR, SPARM_DARKNESS )
- || scan_randarts( RAP_INVISIBLE ))
- {
- // Now you can only turn invisibility off if you have an
- // activatable item. Wands and potions allow will have
- // to time out. -- bwr
- if (you.invis)
- insert_ability( ABIL_EVOKE_TURN_VISIBLE );
- else
- insert_ability( ABIL_EVOKE_TURN_INVISIBLE );
- }
-
- //jmf: "upgrade" for draconians -- expensive flight
- // note: this ability only applies to this counter
- if (player_equip( EQ_RINGS, RING_LEVITATION )
- || player_equip_ego_type( EQ_BOOTS, SPARM_LEVITATION )
- || scan_randarts( RAP_LEVITATE ))
- {
- // Now you can only turn levitation off if you have an
- // activatable item. Potions and miscast effects will
- // have to time out (this makes the miscast effect actually
- // a bit annoying). -- bwr
- if (you.levitation)
- insert_ability( ABIL_EVOKE_STOP_LEVITATING );
- else
- insert_ability( ABIL_EVOKE_LEVITATE );
- }
-
- if (player_equip( EQ_RINGS, RING_TELEPORTATION )
- || scan_randarts( RAP_CAN_TELEPORT ))
- {
- insert_ability( ABIL_EVOKE_TELEPORTATION );
- }
-
- // this is a shameless kludge for the time being {dlb}:
- // still shameless. -- bwr
- for (loopy = 0; loopy < 52; loopy++)
- {
- if (Curr_abil[loopy].which != ABIL_NON_ABILITY)
- return (true);
- }
-
- return (false);
-} // end generate_abilities()
-
-// Note: we're trying for a behaviour where the player gets
-// to keep their assigned invocation slots if they get excommunicated
-// and then rejoin (but if they spend time with another god we consider
-// the old invocation slots void and erase them). We also try to
-// protect any bindings the character might have made into the
-// traditional invocation slots (A-E and X). -- bwr
-void set_god_ability_helper( int abil, char letter )
-/**************************************************/
-{
- int i;
- const int index = letter_to_index( letter );
-
- for (i = 0; i < 52; i++)
- {
- if (you.ability_letter_table[i] == abil)
- break;
- }
-
- if (i == 52) // ability is not already assigned
- {
- // if slot is unoccupied, move in
- if (you.ability_letter_table[index] == ABIL_NON_ABILITY)
- you.ability_letter_table[index] = abil;
- }
-}
-
-void set_god_ability_slots( void )
-/********************************/
-{
- ASSERT( you.religion != GOD_NO_GOD );
-
- int i;
-
- set_god_ability_helper( ABIL_RENOUNCE_RELIGION, 'X' );
-
- int num_abil = 0;
- int abil_start = ABIL_NON_ABILITY;
-
- switch (you.religion)
- {
- case GOD_ZIN:
- abil_start = ABIL_ZIN_REPEL_UNDEAD;
- num_abil = 5;
- break;
-
- case GOD_SHINING_ONE:
- abil_start = ABIL_TSO_REPEL_UNDEAD;
- num_abil = 5;
- break;
-
- case GOD_KIKUBAAQUDGHA:
- abil_start = ABIL_KIKU_RECALL_UNDEAD_SLAVES;
- num_abil = 3;
- break;
-
- case GOD_YREDELEMNUL:
- abil_start = ABIL_YRED_ANIMATE_CORPSE;
- num_abil = 5;
- break;
-
- case GOD_VEHUMET:
- abil_start = ABIL_VEHUMET_CHANNEL_ENERGY;
- num_abil = 1;
- break;
-
- case GOD_OKAWARU:
- abil_start = ABIL_OKAWARU_MIGHT;
- num_abil = 3;
- break;
-
- case GOD_MAKHLEB:
- abil_start = ABIL_MAKHLEB_MINOR_DESTRUCTION;
- num_abil = 4;
- break;
-
- case GOD_SIF_MUNA:
- abil_start = ABIL_SIF_MUNA_FORGET_SPELL;
- num_abil = 1;
- break;
-
- case GOD_TROG:
- abil_start = ABIL_TROG_BERSERK;
- num_abil = 3;
- break;
-
- case GOD_ELYVILON:
- abil_start = ABIL_ELYVILON_LESSER_HEALING;
- num_abil = 5;
- break;
-
- case GOD_NEMELEX_XOBEH:
- case GOD_XOM:
- default:
- break;
- }
-
- // clear out other god invocations:
- for (i = 0; i < 52; i++)
- {
- const int abil = you.ability_letter_table[i];
-
- if ((abil >= ABIL_ZIN_REPEL_UNDEAD // is a god ability
- && abil <= ABIL_ELYVILON_GREATER_HEALING)
- && (num_abil == 0 // current god does have abilities
- || abil < abil_start // not one of current god's abilities
- || abil >= abil_start + num_abil))
- {
- you.ability_letter_table[i] = ABIL_NON_ABILITY;
- }
- }
-
- // finally, add in current god's invocaions in traditional slots:
- if (num_abil)
- {
- for (i = 0; i < num_abil; i++)
- {
- set_god_ability_helper( abil_start + i,
- (Options.lowercase_invocations ? 'a' : 'A') + i );
- }
- }
-}
-
-
-// returns index to Curr_abil, -1 on failure
-static int find_ability_slot( int which_ability )
-/***********************************************/
-{
- int slot;
- for (slot = 0; slot < 52; slot++)
- {
- if (you.ability_letter_table[slot] == which_ability)
- break;
- }
-
- // no requested slot, find new one and make it prefered.
- if (slot == 52)
- {
- // skip over a-e if player prefers them for invocations
- for (slot = (Options.lowercase_invocations ? 5 : 0); slot < 52; slot++)
- {
- if (you.ability_letter_table[slot] == ABIL_NON_ABILITY)
- break;
- }
-
- // if we skipped over a-e to reserve them, try them now
- if (Options.lowercase_invocations && slot == 52)
- {
- for (slot = 5; slot >= 0; slot--)
- {
- if (you.ability_letter_table[slot] == ABIL_NON_ABILITY)
- break;
- }
- }
-
- // All letters are assigned, check Curr_abil and try to steal a letter
- if (slot == 52)
- {
- // backwards, to protect the low lettered slots from replacement
- for (slot = 51; slot >= 0; slot--)
- {
- if (Curr_abil[slot].which == ABIL_NON_ABILITY)
- break;
- }
-
- // no slots at all == no hope of adding
- if (slot < 0)
- return (-1);
- }
-
- // this ability now takes over this slot
- you.ability_letter_table[slot] = which_ability;
- }
-
- return (slot);
-}
-
-static bool insert_ability( int which_ability )
-/**********************************************/
-{
- ASSERT( which_ability != ABIL_NON_ABILITY );
-
- int failure = 0;
- bool perfect = false; // is perfect
- bool invoc = false;
-
- // Look through the table to see if there's a preference, else
- // find a new empty slot for this ability. -- bwr
- const int slot = find_ability_slot( which_ability );
- if (slot == -1)
- return (false);
-
- Curr_abil[slot].which = which_ability;
-
- switch (which_ability)
- {
- // begin spell abilities
- case ABIL_DELAYED_FIREBALL:
- case ABIL_MUMMY_RESTORATION:
- perfect = true;
- failure = 0;
- break;
-
- // begin species abilities - some are mutagenic, too {dlb}
- case ABIL_GLAMOUR:
- failure = 50 - (you.experience_level * 2);
- break;
-
- case ABIL_SPIT_POISON:
- failure = ((you.species == SP_NAGA) ? 20 : 40)
- - 10 * you.mutation[MUT_SPIT_POISON]
- - you.experience_level;
- break;
-
- case ABIL_EVOKE_MAPPING:
- failure = 30 - you.skills[SK_EVOCATIONS];
- break;
-
- case ABIL_MAPPING:
- failure = ((you.species == SP_GNOME) ? 20 : 40)
- - 10 * you.mutation[MUT_MAPPING]
- - you.experience_level;
- break;
-
- case ABIL_BREATHE_FIRE:
- failure = ((you.species == SP_RED_DRACONIAN) ? 30 : 50)
- - 10 * you.mutation[MUT_BREATHE_FLAMES]
- - you.experience_level;
-
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON)
- failure -= 20;
- break;
-
- case ABIL_BREATHE_FROST:
- case ABIL_BREATHE_POISON:
- case ABIL_SPIT_ACID:
- case ABIL_BREATHE_LIGHTNING:
- case ABIL_BREATHE_POWER:
- case ABIL_BREATHE_STICKY_FLAME:
- failure = 30 - you.experience_level;
-
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON)
- failure -= 20;
- break;
-
- case ABIL_BREATHE_STEAM:
- failure = 20 - you.experience_level;
-
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON)
- failure -= 20;
- break;
-
- case ABIL_FLY: // this is for kenku {dlb}
- failure = 45 - (3 * you.experience_level);
- break;
-
- case ABIL_FLY_II: // this is for draconians {dlb}
- failure = 45 - (you.experience_level + you.strength);
- break;
- // end species abilties (some mutagenic)
-
- // begin demonic powers {dlb}
- case ABIL_THROW_FLAME:
- case ABIL_THROW_FROST:
- failure = 10 - you.experience_level;
- break;
-
- case ABIL_SUMMON_MINOR_DEMON:
- failure = 27 - you.experience_level;
- break;
-
- case ABIL_CHANNELING:
- case ABIL_BOLT_OF_DRAINING:
- failure = 30 - you.experience_level;
- break;
-
- case ABIL_CONTROL_DEMON:
- failure = 35 - you.experience_level;
- break;
-
- case ABIL_SUMMON_DEMONS:
- failure = 40 - you.experience_level;
- break;
-
- case ABIL_TO_PANDEMONIUM:
- failure = 57 - (you.experience_level * 2);
- break;
-
- case ABIL_HELLFIRE:
- case ABIL_RAISE_DEAD:
- failure = 50 - you.experience_level;
- break;
-
- case ABIL_TORMENT:
- failure = 60 - you.experience_level;
- break;
-
- case ABIL_BLINK:
- failure = 30 - (10 * you.mutation[MUT_BLINK]) - you.experience_level;
- break;
-
- case ABIL_TELEPORTATION:
- failure = ((you.mutation[MUT_TELEPORT_AT_WILL] > 1) ? 30 : 50)
- - you.experience_level;
- break;
- // end demonic powers {dlb}
-
- // begin transformation abilities {dlb}
- case ABIL_END_TRANSFORMATION:
- perfect = true;
- failure = 0;
- break;
-
- case ABIL_BREATHE_HELLFIRE:
- failure = 32 - you.experience_level;
- break;
- // end transformation abilities {dlb}
- //
- // begin item abilities - some possibly mutagenic {dlb}
- case ABIL_EVOKE_TURN_INVISIBLE:
- case ABIL_EVOKE_TELEPORTATION:
- failure = 60 - 2 * you.skills[SK_EVOCATIONS];
- break;
-
- case ABIL_EVOKE_TURN_VISIBLE:
- case ABIL_EVOKE_STOP_LEVITATING:
- perfect = true;
- failure = 0;
- break;
-
- case ABIL_EVOKE_LEVITATE:
- case ABIL_EVOKE_BLINK:
- failure = 40 - 2 * you.skills[SK_EVOCATIONS];
- break;
-
- case ABIL_EVOKE_BERSERK:
- failure = 50 - 2 * you.skills[SK_EVOCATIONS];
-
- if (you.species == SP_TROLL)
- failure -= 30;
- else if (player_genus(GENPC_DWARVEN) || you.species == SP_HILL_ORC
- || you.species == SP_OGRE)
- {
- failure -= 10;
- }
- break;
- // end item abilities - some possibly mutagenic {dlb}
-
- // begin invocations {dlb}
- case ABIL_ELYVILON_PURIFICATION:
- invoc = true;
- failure = 20 - (you.piety / 20) - (5 * you.skills[SK_INVOCATIONS]);
- break;
-
- case ABIL_ZIN_REPEL_UNDEAD:
- case ABIL_TSO_REPEL_UNDEAD:
- case ABIL_KIKU_RECALL_UNDEAD_SLAVES:
- case ABIL_OKAWARU_MIGHT:
- case ABIL_ELYVILON_LESSER_HEALING:
- invoc = true;
- failure = 30 - (you.piety / 20) - (6 * you.skills[SK_INVOCATIONS]);
- break;
-
- // These three are Trog abilities... Invocations means nothing -- bwr
- case ABIL_TROG_BERSERK: // piety >= 30
- invoc = true;
- failure = 30 - you.piety; // starts at 0%
- break;
-
- case ABIL_TROG_MIGHT: // piety >= 50
- invoc = true;
- failure = 80 - you.piety; // starts at 30%
- break;
-
- case ABIL_TROG_HASTE_SELF: // piety >= 100
- invoc = true;
- failure = 160 - you.piety; // starts at 60%
- break;
-
- case ABIL_YRED_ANIMATE_CORPSE:
- invoc = true;
- failure = 40 - (you.piety / 20) - (3 * you.skills[SK_INVOCATIONS]);
- break;
-
- case ABIL_ZIN_HEALING:
- case ABIL_TSO_SMITING:
- case ABIL_OKAWARU_HEALING:
- case ABIL_MAKHLEB_MINOR_DESTRUCTION:
- case ABIL_SIF_MUNA_FORGET_SPELL:
- case ABIL_KIKU_ENSLAVE_UNDEAD:
- case ABIL_YRED_ANIMATE_DEAD:
- case ABIL_MAKHLEB_LESSER_SERVANT_OF_MAKHLEB:
- case ABIL_ELYVILON_HEALING:
- invoc = true;
- failure = 40 - (you.piety / 20) - (5 * you.skills[SK_INVOCATIONS]);
- break;
-
- case ABIL_VEHUMET_CHANNEL_ENERGY:
- invoc = true;
- failure = 40 - you.intel - you.skills[SK_INVOCATIONS];
- break;
-
- case ABIL_YRED_RECALL_UNDEAD:
- invoc = true;
- failure = 50 - (you.piety / 20) - (you.skills[SK_INVOCATIONS] * 4);
- break;
-
- case ABIL_ZIN_PESTILENCE:
- case ABIL_TSO_ANNIHILATE_UNDEAD:
- invoc = true;
- failure = 60 - (you.piety / 20) - (5 * you.skills[SK_INVOCATIONS]);
- break;
-
- case ABIL_MAKHLEB_MAJOR_DESTRUCTION:
- case ABIL_YRED_DRAIN_LIFE:
- invoc = true;
- failure = 60 - (you.piety / 25) - (you.skills[SK_INVOCATIONS] * 4);
- break;
-
- case ABIL_ZIN_HOLY_WORD:
- case ABIL_TSO_CLEANSING_FLAME:
- case ABIL_ELYVILON_RESTORATION:
- case ABIL_YRED_CONTROL_UNDEAD:
- case ABIL_OKAWARU_HASTE:
- case ABIL_MAKHLEB_GREATER_SERVANT_OF_MAKHLEB:
- invoc = true;
- failure = 70 - (you.piety / 25) - (you.skills[SK_INVOCATIONS] * 4);
- break;
-
- case ABIL_ZIN_SUMMON_GUARDIAN:
- case ABIL_TSO_SUMMON_DAEVA:
- case ABIL_KIKU_INVOKE_DEATH:
- case ABIL_ELYVILON_GREATER_HEALING:
- invoc = true;
- failure = 80 - (you.piety / 25) - (you.skills[SK_INVOCATIONS] * 4);
- break;
-
- //jmf: following for to-be-created gods
- case ABIL_CHARM_SNAKE:
- invoc = true;
- failure = 40 - (you.piety / 20) - (3 * you.skills[SK_INVOCATIONS]);
- break;
-
- case ABIL_TRAN_SERPENT_OF_HELL:
- invoc = true;
- failure = 80 - (you.piety / 25) - (you.skills[SK_INVOCATIONS] * 4);
- break;
-
- case ABIL_ROTTING:
- invoc = true;
- failure = 60 - (you.piety / 20) - (5 * you.skills[SK_INVOCATIONS]);
- break;
-
- case ABIL_TORMENT_II:
- invoc = true;
- failure = 70 - (you.piety / 25) - (you.skills[SK_INVOCATIONS] * 4);
- break;
-
- case ABIL_RENOUNCE_RELIGION:
- invoc = true;
- perfect = true;
- failure = 0;
- break;
-
- // end invocations {dlb}
- default:
- failure = -1;
- break;
- }
-
- // Perfect abilities are things like "renounce religion", which
- // shouldn't have a failure rate ever. -- bwr
- if (failure <= 0 && !perfect)
- failure = 1;
-
- if (failure > 100)
- failure = 100;
-
- Curr_abil[slot].fail = failure;
- Curr_abil[slot].is_invocation = invoc;
-
- return (true);
-} // end insert_ability()
diff --git a/stone_soup/crawl-ref/source/abl-show.h b/stone_soup/crawl-ref/source/abl-show.h
deleted file mode 100644
index e901335fa1..0000000000
--- a/stone_soup/crawl-ref/source/abl-show.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * File: abl-show.h
- * Summary: Functions related to special abilities.
- * Written by: Linley Henzell
- *
- * Modified for Crawl Reference by $Author$ on $Date$
- *
- * Change History (most recent first):
- *
- * <1> --/--/-- LRH Created
- */
-
-
-#ifndef ABLSHOW_H
-#define ABLSHOW_H
-
-#include <string>
-#include <vector>
-
-// Structure for representing an ability:
-struct ability_def
-{
- int ability;
- const char * name;
- unsigned int mp_cost; // magic cost of ability
- unsigned int hp_cost; // hit point cost of ability
- unsigned int food_cost; // + rand2avg( food_cost, 2 )
- unsigned int piety_cost; // + random2( (piety_cost + 1) / 2 + 1 )
- unsigned int flags; // used for additonal cost notices
-};
-
-const struct ability_def & get_ability_def( int abil );
-
-const char * get_ability_name_by_index( char index );
-
-const std::string make_cost_description( const struct ability_def &abil );
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-bool activate_ability( void ); // handles all special abilities now
-char show_abilities( void );
-bool generate_abilities( void );
-
-std::vector<const char *> get_ability_names( void );
-
-void set_god_ability_slots( void );
-
-
-#endif
diff --git a/stone_soup/crawl-ref/source/abyss.cc b/stone_soup/crawl-ref/source/abyss.cc
deleted file mode 100644
index 3f48ed7b35..0000000000
--- a/stone_soup/crawl-ref/source/abyss.cc
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- * File: abyss.cc
- * Summary: Misc functions (most of which don't appear to be related to priests).
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <2> 10/11/99 BCR Added Daniel's crash patch
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "abyss.h"
-
-#include <stdlib.h>
-
-#include "externs.h"
-
-#include "cloud.h"
-#include "monplace.h"
-#include "dungeon.h"
-#include "items.h"
-#include "lev-pand.h"
-#include "randart.h"
-#include "stuff.h"
-
-// public for abyss generation
-void generate_abyss(void)
-{
- int i, j; // loop variables
- int temp_rand; // probability determination {dlb}
-
- for (i = 5; i < (GXM - 5); i++)
- {
- for (j = 5; j < (GYM - 5); j++)
- {
- temp_rand = random2(4000);
-
- grd[i][j] = ((temp_rand > 999) ? DNGN_FLOOR : // 75.0%
- (temp_rand > 400) ? DNGN_ROCK_WALL : // 15.0%
- (temp_rand > 100) ? DNGN_STONE_WALL : // 7.5%
- (temp_rand > 0) ? DNGN_METAL_WALL // 2.5%
- : DNGN_CLOSED_DOOR); // 1 in 4000
- }
- }
-
- grd[45][35] = DNGN_FLOOR;
-} // end generate_abyss()
-
-
-static void generate_area(unsigned char gx1, unsigned char gy1,
- unsigned char gx2, unsigned char gy2)
-{
- unsigned char i, j;
- unsigned char x1, x2, y1, y2;
- unsigned char items_placed = 0;
- int thickness = random2(70) + 30;
- int thing_created;
- unsigned int rooms_done = 0;
- unsigned int rooms_to_do = 0;
-
- int temp_rand; // probability determination {dlb}
-
- FixedVector < unsigned char, 5 > replaced;
-
- // nuke map
- for (i = 0; i < GXM; i++)
- {
- for (j = 0; j < GYM; j++)
- {
- env.map[i][j] = 0;
- }
- }
-
- // generate level composition vector
- for (i = 0; i < 5; i++)
- {
- temp_rand = random2(10000);
-
- replaced[i] = ((temp_rand > 4926) ? DNGN_ROCK_WALL : // 50.73%
- (temp_rand > 2918) ? DNGN_STONE_WALL : // 20.08%
- (temp_rand > 2004) ? DNGN_METAL_WALL : // 9.14%
- (temp_rand > 1282) ? DNGN_LAVA : // 7.22%
- (temp_rand > 616) ? DNGN_SHALLOW_WATER :// 6.66%
- (temp_rand > 15) ? DNGN_DEEP_WATER // 6.01%
- : DNGN_CLOSED_DOOR); // 0.16%
- }
-
- if (one_chance_in(3))
- {
- rooms_to_do = 1 + random2(10);
-
- while(true)
- {
- x1 = 10 + random2(GXM - 20);
- y1 = 10 + random2(GYM - 20);
- x2 = x1 + 1 + random2(10);
- y2 = y1 + 1 + random2(10);
-
- if (one_chance_in(100))
- goto out_of_rooms;
-
- for (i = x1; i < x2; i++) // that is, [10,(GXM-1)] {dlb}
- {
- for (j = y1; j < y2; j++) // that is, [10,(GYM-1)] {dlb}
- {
- if (grd[i][j] != DNGN_UNSEEN)
- goto continued;
- }
- }
-
- for (i = x1; i < x2; i++) // that is, [10,(GXM-1)] {dlb}
- {
- for (j = y1; j < y2; j++) // that is, [10,(GYM-1)] {dlb}
- {
- grd[i][j] = DNGN_FLOOR;
- }
- }
-
- continued:
- rooms_done++;
-
- if (rooms_done >= rooms_to_do)
- break;
- }
- }
-
- out_of_rooms:
- for (i = gx1; i < gx2 + 1; i++)
- {
- for (j = gy1; j < gy2 + 1; j++)
- {
- if (grd[i][j] == DNGN_UNSEEN && random2(100) <= thickness)
- {
- grd[i][j] = DNGN_FLOOR;
-
- if (items_placed < 150 && one_chance_in(200))
- {
- if (one_chance_in(500))
- {
- thing_created = items(1, OBJ_MISCELLANY,
- MISC_RUNE_OF_ZOT, true, 51, 51);
- }
- else
- {
- thing_created = items(1, OBJ_RANDOM, OBJ_RANDOM, true,
- 51, 250);
- }
-
- move_item_to_grid( &thing_created, i, j );
-
- if (thing_created != NON_ITEM)
- items_placed++;
- }
- }
- }
- }
-
- for (i = gx1; i < gx2 + 1; i++)
- {
- for (j = gy1; j < gy2 + 1; j++)
- {
- if (grd[i][j] == DNGN_UNSEEN)
- grd[i][j] = replaced[random2(5)];
-
- if (one_chance_in(7500))
- grd[i][j] = DNGN_EXIT_ABYSS;
-
- if (one_chance_in(10000))
- {
- do
- {
- grd[i][j] = DNGN_ALTAR_ZIN + random2(12);
- }
- while (grd[i][j] == DNGN_ALTAR_YREDELEMNUL
- || grd[i][j] == DNGN_ALTAR_VEHUMET
- || grd[i][j] == DNGN_ALTAR_NEMELEX_XOBEH);
- }
- }
- }
-}
-
-
-void area_shift(void)
-/*******************/
-{
- for (unsigned int i = 0; i < MAX_MONSTERS; i++)
- {
- if (menv[i].type == -1)
- {
- continue;
- }
-
- // remove non-nearby monsters
- if (menv[i].x < you.x_pos - 10
- || menv[i].x >= you.x_pos + 11
- || menv[i].y < you.y_pos - 10 || menv[i].y >= you.y_pos + 11)
- {
- menv[i].type = -1;
-
- mgrd[menv[i].x][menv[i].y] = NON_MONSTER;
-
- for (unsigned int j = 0; j < NUM_MONSTER_SLOTS; j++)
- {
- if (menv[i].inv[j] != NON_ITEM)
- {
- destroy_item( menv[i].inv[j] );
- menv[i].inv[j] = NON_ITEM;
- }
- }
- }
- }
-
- for (int i = 5; i < (GXM - 5); i++)
- {
- for (int j = 5; j < (GYM - 5); j++)
- {
- // don't modify terrain by player
- if (i >= you.x_pos - 10 && i < you.x_pos + 11
- && j >= you.y_pos - 10 && j < you.y_pos + 11)
- {
- continue;
- }
-
- // nuke terrain otherwise
- grd[i][j] = DNGN_UNSEEN;
-
- // nuke items
- destroy_item_stack( i, j );
- }
- }
-
- // shift all monsters & items to new area
- for (int i = you.x_pos - 10; i < you.x_pos + 11; i++)
- {
- if (i < 0 || i >= GXM)
- continue;
-
- for (int j = you.y_pos - 10; j < you.y_pos + 11; j++)
- {
- if (j < 0 || j >= GYM)
- continue;
-
- const int ipos = 45 + i - you.x_pos;
- const int jpos = 35 + j - you.y_pos;
-
- // move terrain
- grd[ipos][jpos] = grd[i][j];
-
- // move item
- move_item_stack_to_grid( i, j, ipos, jpos );
-
- // move monster
- mgrd[ipos][jpos] = mgrd[i][j];
- if (mgrd[i][j] != NON_MONSTER)
- {
- menv[mgrd[ipos][jpos]].x = ipos;
- menv[mgrd[ipos][jpos]].y = jpos;
- mgrd[i][j] = NON_MONSTER;
- }
-
- // move cloud
- if (env.cgrid[i][j] != EMPTY_CLOUD)
- move_cloud( env.cgrid[i][j], ipos, jpos );
- }
- }
-
-
- for (unsigned int i = 0; i < MAX_CLOUDS; i++)
- {
- if (env.cloud[i].type == CLOUD_NONE)
- continue;
-
- if (env.cloud[i].x < 35 || env.cloud[i].x > 55
- || env.cloud[i].y < 25 || env.cloud[i].y > 45)
- {
- delete_cloud( i );
- }
- }
-
- you.x_pos = 45;
- you.y_pos = 35;
-
- generate_area(5, 5, (GXM - 5), (GYM - 5));
-
- for (unsigned int mcount = 0; mcount < 15; mcount++)
- {
- mons_place( RANDOM_MONSTER, BEH_HOSTILE, MHITNOT, false, 1, 1,
- LEVEL_ABYSS, PROX_AWAY_FROM_PLAYER ); // PROX_ANYWHERE?
- }
-}
-
-
-void abyss_teleport( bool new_area )
-/**********************************/
-{
- int x, y, i, j, k;
-
- if (!new_area)
- {
- // try to find a good spot within the shift zone:
- for (i = 0; i < 100; i++)
- {
- x = 16 + random2( GXM - 32 );
- y = 16 + random2( GYM - 32 );
-
- if ((grd[x][y] == DNGN_FLOOR
- || grd[x][y] == DNGN_SHALLOW_WATER)
- && mgrd[x][y] == NON_MONSTER
- && env.cgrid[x][y] == EMPTY_CLOUD)
- {
- break;
- }
- }
-
- if (i < 100)
- {
- you.x_pos = x;
- you.y_pos = y;
- return;
- }
- }
-
- // teleport to a new area of the abyss:
-
- init_pandemonium(); /* changes colours */
-
- env.floor_colour = (mcolour[env.mons_alloc[9]] == BLACK)
- ? LIGHTGREY : mcolour[env.mons_alloc[9]];
-
- env.rock_colour = (mcolour[env.mons_alloc[8]] == BLACK)
- ? LIGHTGREY : mcolour[env.mons_alloc[8]];
-
- // Orbs and fixed artefacts are marked as "lost in the abyss"
- for (k = 0; k < MAX_ITEMS; k++)
- {
- if (is_valid_item( mitm[k] ))
- {
- if (mitm[k].base_type == OBJ_ORBS)
- {
- set_unique_item_status( OBJ_ORBS, mitm[k].sub_type,
- UNIQ_LOST_IN_ABYSS );
- }
- else if (is_fixed_artefact( mitm[k] ))
- {
- set_unique_item_status( OBJ_WEAPONS, mitm[k].special,
- UNIQ_LOST_IN_ABYSS );
- }
-
- destroy_item( k );
- }
- }
-
- for (i = 0; i < MAX_MONSTERS; i++)
- menv[i].type = -1;
-
- for (i = 0; i < MAX_CLOUDS; i++)
- delete_cloud( i );
-
- for (i = 10; i < (GXM - 9); i++)
- {
- for (j = 10; j < (GYM - 9); j++)
- {
- grd[i][j] = DNGN_UNSEEN; // so generate_area will pick it up
- igrd[i][j] = NON_ITEM;
- mgrd[i][j] = NON_MONSTER;
- env.cgrid[i][j] = EMPTY_CLOUD;
- }
- }
-
- ASSERT( env.cloud_no == 0 );
-
- you.x_pos = 45;
- you.y_pos = 35;
-
- generate_area( 10, 10, (GXM - 10), (GYM - 10) );
-
- grd[you.x_pos][you.y_pos] = DNGN_FLOOR;
-}
diff --git a/stone_soup/crawl-ref/source/abyss.h b/stone_soup/crawl-ref/source/abyss.h
deleted file mode 100644
index 9ecef56114..0000000000
--- a/stone_soup/crawl-ref/source/abyss.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * File: abyss.h
- * Summary: Misc functions (most of which don't appear to be related to priests).
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef ABYSS_H
-#define ABYSS_H
-
-
-// last updated 02apr2001 {gdl}
-/* ***********************************************************************
- * called from: dungeon
- * *********************************************************************** */
-void generate_abyss(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void area_shift(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: spells1 - spells3 - spells4
- * *********************************************************************** */
-void abyss_teleport( bool new_area );
-
-
-#endif
diff --git a/stone_soup/crawl-ref/source/acr.cc b/stone_soup/crawl-ref/source/acr.cc
deleted file mode 100644
index 95618e83c0..0000000000
--- a/stone_soup/crawl-ref/source/acr.cc
+++ /dev/null
@@ -1,3201 +0,0 @@
-/*
- * File: acr.cc
- * Summary: Main entry point, event loop, and some initialization functions
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <18> 7/29/00 JDJ values.h isn't included on Macs
- * <17> 19jun2000 GDL added Windows console support
- * <16> 06mar2000 bwr changes to berserk
- * <15> 09jan2000 BCR new Wiz command: blink
- * <14> 10/13/99 BCR Added auto door opening,
- * move "you have no
- * religion" to describe.cc
- * <13> 10/11/99 BCR Added Daniel's wizard patch
- * <12> 10/9/99 BCR swapped 'v' and 'V' commands,
- * added wizard help command
- * <11> 10/7/99 BCR haste and slow now take amulet of
- * resist slow into account
- * <10> 9/25/99 CDL Changes to Linux input
- * switch on command enums
- * <9> 6/12/99 BWR New init code, restructured
- * wiz commands, added equipment
- * listing commands
- * <8> 6/7/99 DML Autopickup
- * <7> 5/30/99 JDJ Added game_has_started.
- * <6> 5/25/99 BWR Changed move() to move_player()
- * <5> 5/20/99 BWR New berserk code, checking
- * scan_randarts for NO_TELEPORT
- * and NO_SPELLCASTING.
- * <4> 5/12/99 BWR Solaris support.
- * <3> 5/09/99 JDJ look_around no longer prints a prompt.
- * <2> 5/08/99 JDJ you and env are no longer arrays.
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-
-#include <string>
-
-// I don't seem to need values.h for VACPP..
-#if !defined(__IBMCPP__) && !defined(MAC)
-#include <limits.h>
-#endif
-
-#if DEBUG
- // this contains the DBL_MAX constant
- #include <float.h>
-#endif
-
-#include <time.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <stdio.h>
-
-#ifdef DOS
-#include <dos.h>
-#include <conio.h>
-#include <file.h>
-#endif
-
-#ifdef USE_UNIX_SIGNALS
-#include <signal.h>
-#endif
-
-#ifdef USE_EMX
-#include <sys/types.h>
-#endif
-
-#ifdef OS9
-#include <stat.h>
-#else
-#include <sys/stat.h>
-#endif
-
-#include "externs.h"
-
-#include "abl-show.h"
-#include "abyss.h"
-#include "chardump.h"
-#include "clua.h"
-#include "command.h"
-#include "debug.h"
-#include "delay.h"
-#include "describe.h"
-#include "direct.h"
-#include "dungeon.h"
-#include "effects.h"
-#include "fight.h"
-#include "files.h"
-#include "food.h"
-#include "hiscores.h"
-#include "initfile.h"
-#include "invent.h"
-#include "item_use.h"
-#include "it_use2.h"
-#include "it_use3.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "items.h"
-#include "lev-pand.h"
-#include "macro.h"
-#include "misc.h"
-#include "monplace.h"
-#include "monstuff.h"
-#include "mon-util.h"
-#include "mutation.h"
-#include "newgame.h"
-#include "ouch.h"
-#include "output.h"
-#include "overmap.h"
-#include "player.h"
-#include "randart.h"
-#include "religion.h"
-#include "shopping.h"
-#include "skills.h"
-#include "skills2.h"
-#include "spells1.h"
-#include "spells3.h"
-#include "spells4.h"
-#include "spl-book.h"
-#include "spl-cast.h"
-#include "spl-util.h"
-#include "stuff.h"
-#include "tags.h"
-#include "transfor.h"
-#include "travel.h"
-#include "view.h"
-#include "wpn-misc.h"
-#include "stash.h"
-
-struct crawl_environment env;
-struct player you;
-struct system_environment SysEnv;
-
-char info[ INFO_SIZE ]; // messaging queue extern'd everywhere {dlb}
-
-int stealth; // externed in view.h // no it is not {dlb}
-char use_colour = 1;
-
-FixedVector< char, NUM_STATUE_TYPES > Visible_Statue;
-
-// set to true once a new game starts or an old game loads
-bool game_has_started = false;
-
-// Clockwise, around the compass from north (same order as enum RUN_DIR)
-static const struct coord_def Compass[8] =
-{
- { 0, -1 }, { 1, -1 }, { 1, 0 }, { 1, 1 },
- { 0, 1 }, { -1, 1 }, { -1, 0 }, { -1, -1 },
-};
-
-/*
-
- Functions needed:
- New:
- int player_speed(player you);
- hit_player(damage, flavour, then last two ouch values, env);
-
-
- Old:
- wield(player you);
- show_map
- noisy()
- losight
-
-*/
-
-void (*viewwindow) (char, bool);
-
-/*
- Function pointers are used to make switching between Unix and DOS char sets
- possible as a runtime option (command-line -c)
-*/
-
-// these two are defined in view.cc. What does the player look like?
-// (changed for shapechanging)
-extern unsigned char your_sign;
-extern unsigned char your_colour;
-
-// Functions in main module
-static void close_door(char move_x, char move_y);
-static void do_berserk_no_combat_penalty(void);
-static bool initialise(void);
-static void input(void);
-static void move_player(char move_x, char move_y);
-static void open_door(char move_x, char move_y);
-
-/*
- It all starts here. Some initialisations are run first, then straight to
- new_game and then input.
-*/
-int main( int argc, char *argv[] )
-{
-#ifdef USE_ASCII_CHARACTERS
- apply_ascii_display(true);
-#else
- apply_ascii_display(false);
-#endif
-
- // Load in the system environment variables
- get_system_environment();
-
- // parse command line args -- look only for initfile & crawl_dir entries
- if (!parse_args(argc, argv, true))
- {
- // print help
- puts("Command line options:");
- puts(" -name <string> character name");
- puts(" -race <arg> preselect race (by letter, abbreviation, or name)");
- puts(" -class <arg> preselect class (by letter, abbreviation, or name)");
- puts(" -pizza <string> crawl pizza");
- puts(" -plain don't use IBM extended characters");
- puts(" -dir <path> crawl directory");
- puts(" -rc <file> init file name");
- puts("");
- puts("Command line options override init file options, which override");
- puts("environment options (CRAWL_NAME, CRAWL_PIZZA, CRAWL_DIR, CRAWL_RC).");
- puts("");
- puts("Highscore list options: (Can now be redirected to more, etc)");
- puts(" -scores [N] highscore list");
- puts(" -tscores [N] terse highscore list");
- puts(" -vscores [N] verbose highscore list");
- exit(1);
- }
-
- // Read the init file
- read_init_file();
-
- // now parse the args again, looking for everything else.
- parse_args( argc, argv, false );
-
- if (Options.sc_entries > 0)
- {
- printf( " Best Crawlers -" EOL );
- hiscores_print_list( Options.sc_entries, Options.sc_format );
- exit(0);
- }
-
-#ifdef UNIX
- unixcurses_startup();
-#endif
-
-#ifdef MAC
- init_mac();
-#endif
-
-#ifdef WIN32CONSOLE
- init_libw32c();
-#endif
-
-#ifdef USE_MACROS
- // Load macros
- macro_init();
-#endif
-
- init_overmap(); // in overmap.cc (duh?)
- clear_ids(); // in itemname.cc
-
- bool game_start = initialise();
-
- if (game_start || Options.always_greet)
- {
- snprintf( info, INFO_SIZE, "Welcome, %s the %s %s.",
- you.your_name, species_name( you.species,you.experience_level ), you.class_name );
-
- mpr( info );
-
- // Starting messages can go here as this should only happen
- // at the start of a new game -- bwr
- // This message isn't appropriate for Options.always_greet
- if (you.char_class == JOB_WANDERER && game_start)
- {
- int skill_levels = 0;
- for (int i = 0; i <= NUM_SKILLS; i++)
- skill_levels += you.skills[ i ];
-
- if (skill_levels <= 2)
- {
- // Demigods and Demonspawn wanderers stand to not be
- // able to see any of their skills at the start of
- // the game (one or two skills should be easily guessed
- // from starting equipment)... Anyways, we'll give the
- // player a message to warn them (and give a reason why). -- bwr
- mpr("You wake up in a daze, and can't recall much.");
- }
- }
-
- // These need some work -- should make sure that the god's
- // name is metioned, else the message might be confusing.
- switch (you.religion)
- {
- case GOD_ZIN:
- simple_god_message( " says: Spread the light, my child." );
- break;
- case GOD_SHINING_ONE:
- simple_god_message( " says: Smite the infidels!" );
- break;
- case GOD_KIKUBAAQUDGHA:
- case GOD_YREDELEMNUL:
- case GOD_NEMELEX_XOBEH:
- simple_god_message( " says: Welcome..." );
- break;
- case GOD_XOM:
- if (game_start)
- simple_god_message( " says: A new plaything!" );
- break;
- case GOD_VEHUMET:
- god_speaks( you.religion, "Let it end in hellfire!");
- break;
- case GOD_OKAWARU:
- simple_god_message(" says: Welcome, disciple.");
- break;
- case GOD_MAKHLEB:
- god_speaks( you.religion, "Blood and souls for Makhleb!" );
- break;
- case GOD_SIF_MUNA:
- simple_god_message( " whispers: I know many secrets...");
- break;
- case GOD_TROG:
- simple_god_message( " says: Kill them all!" );
- break;
- case GOD_ELYVILON:
- simple_god_message( " says: Go forth and aid the weak!" );
- break;
- default:
- break;
- }
-
- // warn player about their weapon, if unsuitable
- wield_warning(false);
- }
-
- while (true)
- {
- input();
- // cprintf("x");
- }
-
- // Should never reach this stage, right?
-
-#ifdef UNIX
- unixcurses_shutdown();
-#endif
-
-#ifdef MAC
- deinit_mac();
-#endif
-
-#ifdef USE_EMX
- deinit_emx();
-#endif
-
- return 0;
-} // end main()
-
-#ifdef WIZARD
-static void handle_wizard_command( void )
-{
- int wiz_command, i, j, tmp;
- char specs[256];
-
- // WIZ_NEVER gives protection for those who have wiz compiles,
- // and don't want to risk their characters.
- if (Options.wiz_mode == WIZ_NEVER)
- return;
-
- if (!you.wizard)
- {
- mpr( "WARNING: ABOUT TO ENTER WIZARD MODE!", MSGCH_WARN );
-
-#ifndef SCORE_WIZARD_MODE
- mpr( "If you continue, your game will not be scored!", MSGCH_WARN );
-#endif
-
- if (!yesno( "Do you really want to enter wizard mode?",
- false, 'n' ))
- return;
-
- you.wizard = true;
- redraw_screen();
- }
-
- mpr( "Enter Wizard Command: ", MSGCH_PROMPT );
- wiz_command = getch();
-
- switch (wiz_command)
- {
- case '?':
- list_commands(true); // tell it to list wizard commands
- redraw_screen();
- break;
-
- case CONTROL('G'):
- save_ghost(true);
- break;
-
- case 'x':
- you.experience = 1 + exp_needed( 2 + you.experience_level );
- level_change();
- break;
-
- case 's':
- you.exp_available = 20000;
- you.redraw_experience = 1;
- break;
-
- case 'S':
- debug_set_skills();
- break;
-
- case 'A':
- debug_set_all_skills();
- break;
-
- case '$':
- you.gold += 1000;
- you.redraw_gold = 1;
- break;
-
- case 'a':
- acquirement( OBJ_RANDOM, AQ_WIZMODE );
- break;
-
- case 'v':
- // this command isn't very exciting... feel free to replace
- i = prompt_invent_item( "Value of which item?", -1 );
- if (i == PROMPT_ABORT || !is_random_artefact( you.inv[i] ))
- {
- canned_msg( MSG_OK );
- break;
- }
- else
- {
- snprintf( info, INFO_SIZE, "randart val: %d", randart_value( you.inv[i] ) );
- mpr( info );
- }
- break;
-
- case '+':
- i = prompt_invent_item( "Make an artefact out of which item?", -1 );
- if (i == PROMPT_ABORT)
- {
- canned_msg( MSG_OK );
- break;
- }
-
- // set j == equipment slot of chosen item, remove old randart benefits
- for (j = 0; j < NUM_EQUIP; j++)
- {
- if (you.equip[j] == i)
- {
- if (j == EQ_WEAPON)
- you.wield_change = true;
-
- if (is_random_artefact( you.inv[i] ))
- unuse_randart( i );
-
- break;
- }
- }
-
- make_item_randart( you.inv[i] );
-
- // if equiped, apply new randart benefits
- if (j != NUM_EQUIP)
- use_randart( i );
-
- item_name( you.inv[i], DESC_INVENTORY_EQUIP, info );
- mpr( info );
- break;
-
- case '|':
- // create all unrand arts
- for (tmp = 1; tmp < NO_UNRANDARTS; tmp++)
- {
- int islot = get_item_slot();
- if (islot == NON_ITEM)
- break;
-
- make_item_unrandart( mitm[islot], tmp );
-
- mitm[ islot ].quantity = 1;
- set_ident_flags( mitm[ islot ], ISFLAG_IDENT_MASK );
-
- move_item_to_grid( &islot, you.x_pos, you.y_pos );
- }
-
- // create all fixed artefacts
- for (tmp = SPWPN_SINGING_SWORD; tmp <= SPWPN_STAFF_OF_WUCAD_MU; tmp++)
- {
- int islot = get_item_slot();
- if (islot == NON_ITEM)
- break;
-
- if (make_item_fixed_artefact( mitm[ islot ], false, tmp ))
- {
- mitm[ islot ].quantity = 1;
- item_colour( mitm[ islot ] );
- set_ident_flags( mitm[ islot ], ISFLAG_IDENT_MASK );
-
- move_item_to_grid( &islot, you.x_pos, you.y_pos );
- }
- }
- break;
-
- case 'B':
- if (you.level_type != LEVEL_ABYSS)
- banished( DNGN_ENTER_ABYSS );
- else
- {
- grd[you.x_pos][you.y_pos] = DNGN_EXIT_ABYSS;
- down_stairs(true, you.your_level, true);
- untag_followers();
- }
- break;
-
- case 'g':
- debug_add_skills();
- break;
-
- case 'G':
- // Genocide... "unsummon" all the monsters from the level.
- for (int mon = 0; mon < MAX_MONSTERS; mon++)
- {
- struct monsters *monster = &menv[mon];
-
- if (monster->type == -1)
- continue;
-
- monster_die(monster, KILL_RESET, 0);
-
- }
- break;
-
- case 'h':
- you.rotting = 0;
- you.poison = 0;
- you.disease = 0;
- set_hp( abs(you.hp_max), false );
- set_hunger( 5000 + abs(you.hunger), true );
- break;
-
- case 'H':
- you.rotting = 0;
- you.poison = 0;
- you.disease = 0;
- inc_hp( 10, true );
- set_hp( you.hp_max, false );
- set_hunger( 12000, true );
- you.redraw_hit_points = 1;
- break;
-
- case 'b':
- blink(); // wizards can always blink
- break;
-
- case '\"':
- case '~':
- level_travel(0);
- break;
-
- case 'd':
- case 'D':
- level_travel(1);
- break;
-
- case 'u':
- case 'U':
- level_travel(-1);
- break;
-
- case '%':
- case 'o':
- create_spec_object();
- break;
-
- case 't':
- tweak_object();
- break;
-
- case 'f':
- debug_fight_statistics(false);
- break;
-
- case 'F':
- debug_fight_statistics(true);
- break;
-
- case 'm':
- create_spec_monster();
- break;
-
- case 'M':
- create_spec_monster_name();
- break;
-
- case 'r':
- debug_change_species();
- break;
-
- case '>':
- grd[you.x_pos][you.y_pos] = DNGN_STONE_STAIRS_DOWN_I;
- break;
-
- case '<':
- grd[you.x_pos][you.y_pos] = DNGN_ROCK_STAIRS_UP;
- break;
-
- case 'p':
- grd[you.x_pos][you.y_pos] = DNGN_ENTER_PANDEMONIUM;
- break;
-
- case 'l':
- grd[you.x_pos][you.y_pos] = DNGN_ENTER_LABYRINTH;
- break;
-
- case 'i':
- mpr( "You feel a rush of knowledge." );
- for (i = 0; i < ENDOFPACK; i++)
- {
- if (is_valid_item( you.inv[i] ))
- {
- set_ident_type( you.inv[i].base_type, you.inv[i].sub_type,
- ID_KNOWN_TYPE );
-
- set_ident_flags( you.inv[i], ISFLAG_IDENT_MASK );
- }
- }
- you.wield_change = true;
- break;
-
- case 'I':
- mpr( "You feel a rush of antiknowledge." );
- for (i = 0; i < ENDOFPACK; i++)
- {
- if (is_valid_item( you.inv[i] ))
- {
- set_ident_type( you.inv[i].base_type, you.inv[i].sub_type,
- ID_UNKNOWN_TYPE );
-
- unset_ident_flags( you.inv[i], ISFLAG_IDENT_MASK );
- }
- }
- you.wield_change = true;
- break;
-
- case 'X':
- Xom_acts(true, 20, true);
- break;
-
- case 'z':
- cast_spec_spell();
- break; /* cast spell by number */
-
- case 'Z':
- cast_spec_spell_name();
- break; /* cast spell by name */
-
- case '(':
- mpr( "Create which feature (by number)? ", MSGCH_PROMPT );
- get_input_line( specs, sizeof( specs ) );
-
- if (specs[0] != '\0')
- grd[you.x_pos][you.y_pos] = atoi(specs);
- break;
-
- case ']':
- if (!debug_add_mutation())
- mpr( "Failure to give mutation." );
- break;
-
- case '[':
- demonspawn();
- break;
-
- case ':':
- j = 0;
- for (i = 0; i < 20; i++)
- {
- if (you.branch_stairs[i] == 0)
- continue;
-
- snprintf( info, INFO_SIZE, "Branch %2d is on level %2d",
- i, you.branch_stairs[i] + 1 );
-
- mpr(info);
- }
- break;
-
- case '{':
- magic_mapping(99, 100);
- break;
-
- case '^':
- {
- int old_piety = you.piety;
-
- gain_piety(50);
- snprintf( info, INFO_SIZE, "Congratulations, your piety went from %d to %d!",
- old_piety, you.piety);
- mpr(info);
- }
- break;
-
- case '=':
- snprintf( info, INFO_SIZE,
- "Cost level: %d Skill points: %d Next cost level: %d",
- you.skill_cost_level, you.total_skill_points,
- skill_cost_needed( you.skill_cost_level + 1 ) );
-
- mpr( info );
- break;
-
- case '_':
- debug_get_religion();
- break;
-
- case '\'':
- for (i = 0; i < MAX_ITEMS; i++)
- {
- if (mitm[i].link == NON_ITEM)
- continue;
-
- snprintf( info, INFO_SIZE, "item:%3d link:%3d cl:%3d ty:%3d pl:%3d pl2:%3d sp:%3ld q:%3d",
- i, mitm[i].link,
- mitm[i].base_type, mitm[i].sub_type,
- mitm[i].plus, mitm[i].plus2, mitm[i].special,
- mitm[i].quantity );
-
- mpr(info);
- }
-
- strcpy(info, "igrid:");
- mpr(info);
-
- for (i = 0; i < GXM; i++)
- {
- for (j = 0; j < GYM; j++)
- {
- if (igrd[i][j] != NON_ITEM)
- {
- snprintf( info, INFO_SIZE, "%3d at (%2d,%2d), cl:%3d ty:%3d pl:%3d pl2:%3d sp:%3ld q:%3d",
- igrd[i][j], i, j,
- mitm[i].base_type, mitm[i].sub_type,
- mitm[i].plus, mitm[i].plus2, mitm[i].special,
- mitm[i].quantity );
-
- mpr(info);
- }
- }
- }
- break;
-
- default:
- mpr("Not a Wizard Command.");
- break;
- }
-}
-#endif
-
-// This function creates "equivalence classes" so that undiscovered
-// traps and secret doors aren't running stopping points.
-static char base_grid_type( char grid )
-{
- // Don't stop for undiscovered traps:
- if (grid == DNGN_UNDISCOVERED_TRAP)
- return (DNGN_FLOOR);
-
- // Or secret doors (which currently always look like rock walls):
- if (grid == DNGN_SECRET_DOOR)
- return (DNGN_ROCK_WALL);
-
- return (grid);
-}
-
-// Set up the front facing array for detecting terrain based stops
-static void set_run_check( int index, int dir )
-{
- you.run_check[index].dx = Compass[dir].x;
- you.run_check[index].dy = Compass[dir].y;
-
- const int targ_x = you.x_pos + Compass[dir].x;
- const int targ_y = you.y_pos + Compass[dir].y;
-
- you.run_check[index].grid = base_grid_type( grd[ targ_x ][ targ_y ] );
-}
-
-// Set up the running variables for the current run.
-static void start_running( int dir, char mode )
-{
- if (dir == RDIR_REST)
- {
- you.run_x = 0;
- you.run_y = 0;
- you.running = mode;
- return;
- }
-
- ASSERT( dir >= 0 && dir <= 7 );
-
- you.run_x = Compass[dir].x;
- you.run_y = Compass[dir].y;
- you.running = mode;
-
- // Get the compass point to the left/right of intended travel:
- const int left = (dir - 1 < 0) ? 7 : (dir - 1);
- const int right = (dir + 1 > 7) ? 0 : (dir + 1);
-
- // Record the direction and starting tile type for later reference:
- set_run_check( 0, left );
- set_run_check( 1, dir );
- set_run_check( 2, right );
-}
-
-// Returns true if one of the front three grids has changed.
-static bool check_stop_running( void )
-{
- if (env.cgrid[you.x_pos + you.run_x][you.y_pos + you.run_y] != EMPTY_CLOUD)
- return (true);
-
- if (mgrd[you.x_pos + you.run_x][you.y_pos + you.run_y] != NON_MONSTER)
- return (true);
-
- for (int i = 0; i < 3; i++)
- {
- const int targ_x = you.x_pos + you.run_check[i].dx;
- const int targ_y = you.y_pos + you.run_check[i].dy;
- const int targ_grid = base_grid_type( grd[ targ_x ][ targ_y ] );
-
- if (you.run_check[i].grid != targ_grid)
- return (true);
- }
-
- return (false);
-}
-
-static bool recharge_rod( item_def &rod, bool wielded )
-{
- if (!item_is_rod(rod) || rod.plus >= rod.plus2 || !enough_mp(1, true))
- return (false);
-
- const int charge = rod.plus / ROD_CHARGE_MULT;
-
- int rate = ((charge + 1) * ROD_CHARGE_MULT) / 10;
-
- rate *= (10 + skill_bump( SK_EVOCATIONS ));
- rate = div_rand_round( rate, 100 );
-
- if (rate < 5)
- rate = 5;
- else if (rate > ROD_CHARGE_MULT / 2)
- rate = ROD_CHARGE_MULT / 2;
-
- // If not wielded, the rod charges far more slowly.
- if (!wielded)
- rate /= 3;
-
- if (rod.plus / ROD_CHARGE_MULT != (rod.plus + rate) / ROD_CHARGE_MULT)
- {
- dec_mp(1);
- if (wielded)
- you.wield_change = true;
- }
-
- rod.plus += rate;
- if (rod.plus > rod.plus2)
- rod.plus = rod.plus2;
-
- if (wielded && rod.plus == rod.plus2 && is_resting())
- stop_running();
-
- return (true);
-}
-
-static void recharge_rods()
-{
- const int wielded = you.equip[EQ_WEAPON];
- if (wielded != -1)
- {
- if (recharge_rod( you.inv[wielded], true ))
- return ;
- }
-
- for (int i = 0; i < ENDOFPACK; ++i)
- {
- if (i != wielded && is_valid_item(you.inv[i])
- && one_chance_in(3)
- && recharge_rod( you.inv[i], false ))
- return;
- }
-}
-
-/*
- This function handles the player's input. It's called from main(), from
- inside an endless loop.
- */
-static void input(void)
-{
-
- bool its_quiet; //jmf: for silence messages
- FixedVector < int, 2 > plox;
- char move_x = 0;
- char move_y = 0;
-
- int keyin = 0;
-
-#ifdef UNIX
- // Stuff for the Unix keypad kludge
- bool running = false;
- bool opening = false;
-#endif
-
- you.shield_blocks = 0; // no blocks this round
-
- you.time_taken = player_speed();
-
-#ifdef UNIX
- update_screen();
-#else
- window( 1, 1, 80, get_number_of_lines() );
-#endif
-
- textcolor(LIGHTGREY);
-
- set_redraw_status( REDRAW_LINE_2_MASK | REDRAW_LINE_3_MASK );
- print_stats();
-
- if (you.paralysis)
- {
- keyin = '.'; // end of if you.paralysis == 0
- }
- else
- {
-#ifdef STASH_TRACKING
- if (Options.stash_tracking)
- stashes.update_visible_stashes(
- Options.stash_tracking == STM_ALL?
- StashTracker::ST_AGGRESSIVE :
- StashTracker::ST_PASSIVE);
-#endif
- handle_delay();
-
- gotoxy(18, 9);
-
- if (you_are_delayed())
- keyin = '.';
- else if (you.activity)
- {
- keyin = 128;
- you.turn_is_over = 0;
- perform_activity();
- }
- else
- {
- if (you.running < 0) // Travel and explore
- travel(&keyin, &move_x, &move_y);
-
- if (you.running > 0)
- {
- keyin = 128;
-
- move_x = you.run_x;
- move_y = you.run_y;
-
- if (kbhit())
- {
- stop_running();
- goto gutch;
- }
-
- if (you.run_x == 0 && you.run_y == 0)
- {
- you.running--;
- keyin = '.';
- }
- }
- else if (!you.running)
- {
-
-#if DEBUG_DIAGNOSTICS
- // save hunger at start of round
- // for use with hunger "delta-meter" in output.cc
- you.old_hunger = you.hunger;
-#endif
-
-#if DEBUG_ITEM_SCAN
- debug_item_scan();
-#endif
-
- gutch:
- flush_input_buffer( FLUSH_BEFORE_COMMAND );
- keyin = getch_with_command_macros();
- }
-
- mesclr();
-
-#ifdef UNIX
- // Kludging running and opening as two character sequences
- // for Unix systems. This is an easy way out... all the
- // player has to do is find a termcap and numlock setting
- // that will get curses the numbers from the keypad. This
- // will hopefully be easy.
-
- if (keyin == '*')
- {
- opening = true;
- keyin = getch();
- }
- else if (keyin == '/')
- {
- running = true;
- keyin = getch();
- }
-
- // Translate keypad codes into command enums
- keyin = key_to_command(keyin);
-#else
- // Old DOS keypad support
- if (keyin == 0) // ALT also works - see ..\KEYTEST.CPP
- {
- keyin = getch();
- switch (keyin)
- {
- case 'O': move_x = -1; move_y = 1; break;
- case 'P': move_x = 0; move_y = 1; break;
- case 'I': move_x = 1; move_y = -1; break;
- case 'H': move_x = 0; move_y = -1; break;
- case 'G': move_x = -1; move_y = -1; break;
- case 'K': move_x = -1; move_y = 0; break;
- case 'Q': move_x = 1; move_y = 1; break;
- case 'M': move_x = 1; move_y = 0; break;
-
- case 119: open_door(-1, -1); move_x = 0; move_y = 0; break;
- case 141: open_door( 0, -1); move_x = 0; move_y = 0; break;
- case 132: open_door( 1, -1); move_x = 0; move_y = 0; break;
- case 116: open_door( 1, 0); move_x = 0; move_y = 0; break;
- case 118: open_door( 1, 1); move_x = 0; move_y = 0; break;
- case 145: open_door( 0, 1); move_x = 0; move_y = 0; break;
- case 117: open_door(-1, 1); move_x = 0; move_y = 0; break;
- case 115: open_door(-1, 0); move_x = 0; move_y = 0; break;
-
- case 76:
- case 'S':
- keyin = '.';
- goto get_keyin_again;
- }
-
- keyin = 128;
- }
-#endif
- }
- }
-
- if (keyin != 128)
- {
- move_x = 0;
- move_y = 0;
- you.turn_is_over = 0;
- }
-
-#ifndef UNIX
- get_keyin_again:
-#endif //jmf: just stops an annoying gcc warning
-
- if (is_userfunction(keyin))
- {
- run_macro(get_userfunction(keyin));
- keyin = 128;
- }
-
- switch (keyin)
- {
- case CONTROL('Y'):
- case CMD_OPEN_DOOR_UP_RIGHT:
- open_door(-1, -1); move_x = 0; move_y = 0; break;
-
- case CONTROL('K'):
- case CMD_OPEN_DOOR_UP:
- open_door( 0, -1); move_x = 0; move_y = 0; break;
-
- case CONTROL('U'):
- case CMD_OPEN_DOOR_UP_LEFT:
- open_door( 1, -1); move_x = 0; move_y = 0; break;
-
- case CONTROL('L'):
- case CMD_OPEN_DOOR_RIGHT:
- open_door( 1, 0); move_x = 0; move_y = 0; break;
-
- case CONTROL('N'):
- case CMD_OPEN_DOOR_DOWN_RIGHT:
- open_door( 1, 1); move_x = 0; move_y = 0; break;
-
- case CONTROL('J'):
- case CMD_OPEN_DOOR_DOWN:
- open_door( 0, 1); move_x = 0; move_y = 0; break;
-
- case CONTROL('B'):
- case CMD_OPEN_DOOR_DOWN_LEFT:
- open_door(-1, 1); move_x = 0; move_y = 0; break;
-
- case CONTROL('H'):
- case CMD_OPEN_DOOR_LEFT:
- open_door(-1, 0); move_x = 0; move_y = 0; break;
-
- case 'b': case CMD_MOVE_DOWN_LEFT: move_x = -1; move_y = 1; break;
- case 'j': case CMD_MOVE_DOWN: move_y = 1; move_x = 0; break;
- case 'u': case CMD_MOVE_UP_RIGHT: move_x = 1; move_y = -1; break;
- case 'k': case CMD_MOVE_UP: move_y = -1; move_x = 0; break;
- case 'y': case CMD_MOVE_UP_LEFT: move_y = -1; move_x = -1; break;
- case 'h': case CMD_MOVE_LEFT: move_x = -1; move_y = 0; break;
- case 'n': case CMD_MOVE_DOWN_RIGHT: move_y = 1; move_x = 1; break;
- case 'l': case CMD_MOVE_RIGHT: move_x = 1; move_y = 0; break;
-
- case CMD_REST:
- // Yes this is backwards, but everyone here is used to using
- // straight 5s for long rests... might need to define a roguelike
- // rest key and get people switched over. -- bwr
-
-#ifdef UNIX
- if (!running && !opening)
- start_running( RDIR_REST, 100 );
- else
- {
- search_around();
- move_x = 0;
- move_y = 0;
- you.turn_is_over = 1;
- }
-#endif
- break;
-
- case 'B': case CMD_RUN_DOWN_LEFT:
- start_running( RDIR_DOWN_LEFT, 2 ); break;
-
- case 'J': case CMD_RUN_DOWN:
- start_running( RDIR_DOWN, 2 ); break;
-
- case 'U': case CMD_RUN_UP_RIGHT:
- start_running( RDIR_UP_RIGHT, 2 ); break;
-
- case 'K': case CMD_RUN_UP:
- start_running( RDIR_UP, 2 ); break;
-
- case 'Y': case CMD_RUN_UP_LEFT:
- start_running( RDIR_UP_LEFT, 2 ); break;
-
- case 'H': case CMD_RUN_LEFT:
- start_running( RDIR_LEFT, 2 ); break;
-
- case 'N': case CMD_RUN_DOWN_RIGHT:
- start_running( RDIR_DOWN_RIGHT, 2 ); break;
-
- case 'L': case CMD_RUN_RIGHT:
- start_running( RDIR_RIGHT, 2 ); break;
-
-#ifdef UNIX
- // taken care of via key -> command mapping
-#else
- // Old DOS keypad support
- case '1': start_running( RDIR_DOWN_LEFT, 2 ); break;
- case '2': start_running( RDIR_DOWN, 2 ); break;
- case '9': start_running( RDIR_UP_RIGHT, 2 ); break;
- case '8': start_running( RDIR_UP, 2 ); break;
- case '7': start_running( RDIR_UP_LEFT, 2 ); break;
- case '4': start_running( RDIR_LEFT, 2 ); break;
- case '3': start_running( RDIR_DOWN_RIGHT, 2 ); break;
- case '6': start_running( RDIR_RIGHT, 2 ); break;
- case '5': start_running( RDIR_REST, 100 ); break;
-
-#endif
-
- case CONTROL('A'):
- case CMD_TOGGLE_AUTOPICKUP:
- autopickup_on = !autopickup_on;
- strcpy(info, "Autopickup is now ");
- strcat(info, (autopickup_on) ? "on" : "off");
- strcat(info, ".");
- mpr(info);
- break;
-
- case CONTROL('C'):
- case CMD_CLEAR_MAP:
- if (you.level_type != LEVEL_LABYRINTH && you.level_type != LEVEL_ABYSS)
- {
- mpr("Clearing level map.");
- clear_map();
- }
- break;
-
- case '<':
- case CMD_GO_UPSTAIRS:
- if (grd[you.x_pos][you.y_pos] == DNGN_ENTER_SHOP)
- {
- shop();
- break;
- }
- else if ((grd[you.x_pos][you.y_pos] < DNGN_STONE_STAIRS_UP_I
- || grd[you.x_pos][you.y_pos] > DNGN_ROCK_STAIRS_UP)
- && (grd[you.x_pos][you.y_pos] < DNGN_RETURN_FROM_ORCISH_MINES
- || grd[you.x_pos][you.y_pos] >= 150))
- {
- mpr( "You can't go up here!" );
- break;
- }
-
- tag_followers(); // only those beside us right now can follow
- start_delay( DELAY_ASCENDING_STAIRS,
- 1 + (you.burden_state > BS_UNENCUMBERED) );
- break;
-
- case '>':
- case CMD_GO_DOWNSTAIRS:
- if ((grd[you.x_pos][you.y_pos] < DNGN_ENTER_LABYRINTH
- || grd[you.x_pos][you.y_pos] > DNGN_ROCK_STAIRS_DOWN)
- && grd[you.x_pos][you.y_pos] != DNGN_ENTER_HELL
- && ((grd[you.x_pos][you.y_pos] < DNGN_ENTER_DIS
- || grd[you.x_pos][you.y_pos] > DNGN_TRANSIT_PANDEMONIUM)
- && grd[you.x_pos][you.y_pos] != DNGN_STONE_ARCH)
- && !(grd[you.x_pos][you.y_pos] >= DNGN_ENTER_ORCISH_MINES
- && grd[you.x_pos][you.y_pos] < DNGN_RETURN_FROM_ORCISH_MINES))
- {
- mpr( "You can't go down here!" );
- break;
- }
-
- tag_followers(); // only those beside us right now can follow
- start_delay( DELAY_DESCENDING_STAIRS,
- 1 + (you.burden_state > BS_UNENCUMBERED),
- you.your_level );
- break;
-
- case 'O':
- case CMD_DISPLAY_OVERMAP:
- display_overmap();
- break;
-
- case 'o':
- case CMD_OPEN_DOOR:
- open_door(0, 0);
- break;
- case 'c':
- case CMD_CLOSE_DOOR:
- close_door(0, 0);
- break;
-
- case 'd':
- case CMD_DROP:
- drop();
-#ifdef STASH_TRACKING
- if (Options.stash_tracking >= STM_DROPPED)
- stashes.add_stash();
-#endif
- break;
-
-#ifdef STASH_TRACKING
- case CONTROL('F'):
- case CMD_SEARCH_STASHES:
- stashes.search_stashes();
- break;
-
- case CONTROL('S'):
- case CMD_MARK_STASH:
- if (Options.stash_tracking >= STM_EXPLICIT)
- stashes.add_stash(-1, -1, true);
- break;
-
- case CONTROL('E'):
- case CMD_FORGET_STASH:
- if (Options.stash_tracking >= STM_EXPLICIT)
- stashes.no_stash();
- break;
-#endif
-
- case 'D':
- case CMD_BUTCHER:
- butchery();
- break;
-
- case 'i':
- case CMD_DISPLAY_INVENTORY:
- get_invent(-1);
- break;
-
- case 'I':
- case CMD_OBSOLETE_INVOKE:
- // We'll leave this message in for a while. Eventually, this
- // might be some special for of inventory command, or perhaps
- // actual god invocations will be split to here from abilities. -- bwr
- mpr( "This command is now 'E'voke wielded item.", MSGCH_WARN );
- break;
-
- case 'E':
- case CMD_EVOKE:
- if (!evoke_wielded())
- flush_input_buffer( FLUSH_ON_FAILURE );
- break;
-
- case 'g':
- case ',':
- case CMD_PICKUP:
- pickup();
- break;
-
- case ';':
- case CMD_INSPECT_FLOOR:
- item_check(';');
- break;
-
- case 'w':
- case CMD_WIELD_WEAPON:
- wield_weapon(false);
- break;
-
- case 't':
- case CMD_THROW:
- throw_anything();
- break;
-
- case 'f':
- case CMD_FIRE:
- shoot_thing();
- break;
-
- case 'W':
- case CMD_WEAR_ARMOUR:
- wear_armour();
- break;
-
- case 'T':
- case CMD_REMOVE_ARMOUR:
- {
- int index=0;
-
- if (armour_prompt("Take off which item?", &index))
- takeoff_armour(index);
- }
- break;
-
- case 'R':
- case CMD_REMOVE_JEWELLERY:
- remove_ring();
- break;
- case 'P':
- case CMD_WEAR_JEWELLERY:
- puton_ring();
- break;
-
- case '=':
- case CMD_ADJUST_INVENTORY:
- adjust();
- return;
-
- case 'M':
- case CMD_MEMORISE_SPELL:
- if (!learn_spell())
- flush_input_buffer( FLUSH_ON_FAILURE );
- break;
-
- case 'z':
- case CMD_ZAP_WAND:
- zap_wand();
- break;
-
- case 'e':
- case CMD_EAT:
- eat_food();
- break;
-
- case 'a':
- case CMD_USE_ABILITY:
- if (!activate_ability())
- flush_input_buffer( FLUSH_ON_FAILURE );
- break;
-
- case 'A':
- case CMD_DISPLAY_MUTATIONS:
- display_mutations();
- redraw_screen();
- break;
-
- case 'v':
- case CMD_EXAMINE_OBJECT:
- original_name();
- break;
-
- case 'p':
- case CMD_PRAY:
- pray();
- break;
-
- case '^':
- case CMD_DISPLAY_RELIGION:
- describe_god( you.religion, true );
- redraw_screen();
- break;
-
- case '.':
- case CMD_MOVE_NOWHERE:
- search_around();
- move_x = 0;
- move_y = 0;
- you.turn_is_over = 1;
- break;
-
- case 'q':
- case CMD_QUAFF:
- drink();
- break;
-
- case 'r':
- case CMD_READ:
- read_scroll();
- break;
-
- case 'x':
- case CMD_LOOK_AROUND:
- mpr("Move the cursor around to observe a square.", MSGCH_PROMPT);
- mpr("Press '?' for a monster description.", MSGCH_PROMPT);
-
- struct dist lmove;
- lmove.isValid = lmove.isTarget = lmove.isCancel = false;
- look_around( lmove, true );
- if (lmove.isValid && lmove.isTarget && !lmove.isCancel)
- start_travel( lmove.tx, lmove.ty );
- break;
-
- case 's':
- case CMD_SEARCH:
- search_around();
- you.turn_is_over = 1;
- break;
-
- case 'Z':
- case CMD_CAST_SPELL:
- /* randart wpns */
- if (scan_randarts(RAP_PREVENT_SPELLCASTING))
- {
- mpr("Something interferes with your magic!");
- flush_input_buffer( FLUSH_ON_FAILURE );
- break;
- }
-
- if (!cast_a_spell())
- flush_input_buffer( FLUSH_ON_FAILURE );
- break;
-
- case '\'':
- case CMD_WEAPON_SWAP:
- wield_weapon(true);
- break;
-
- // [ds] Waypoints can be added from the level-map, and we need Ctrl+F for
- // nobler things. Who uses waypoints, anyway?
- // Update: Appears people do use waypoints. Reinstating, on CONTROL('W').
- // This means Ctrl+W is no longer a wizmode trigger, but there's
- // always '&'. :-)
- case CMD_FIX_WAYPOINT:
- case CONTROL('W'):
- travel_cache.add_waypoint();
- break;
-
- case CMD_INTERLEVEL_TRAVEL:
- case CONTROL('G'):
- if (!can_travel_interlevel())
- {
- mpr("Sorry, you can't auto-travel out of here.");
- break;
- }
- start_translevel_travel();
- redraw_screen();
- break;
-
- case CONTROL('O'):
- case CMD_EXPLORE:
- if (you.level_type == LEVEL_LABYRINTH || you.level_type == LEVEL_ABYSS)
- {
- mpr("It would help if you knew where you were, first.");
- break;
- }
- // Start exploring
- start_explore();
- break;
-
- case 'X':
- case CMD_DISPLAY_MAP:
-#if (!DEBUG_DIAGNOSTICS)
- if (you.level_type == LEVEL_LABYRINTH || you.level_type == LEVEL_ABYSS)
- {
- mpr("It would help if you knew where you were, first.");
- break;
- }
-#endif
- plox[0] = 0;
- show_map(plox);
- redraw_screen();
- if (plox[0] > 0)
- start_travel(plox[0], plox[1]);
- break;
-
- case '\\':
- case CMD_DISPLAY_KNOWN_OBJECTS:
- check_item_knowledge(); //nothing = check_item_knowledge();
- redraw_screen();
- break;
-
-#ifdef ALLOW_DESTROY_ITEM_COMMAND
- case CONTROL('D'):
- case CMD_DESTROY_ITEM:
- cmd_destroy_item();
- break;
-#endif
-
- case CONTROL('P'):
- case CMD_REPLAY_MESSAGES:
- replay_messages();
- redraw_screen();
- break;
-
- case CONTROL('R'):
- case CMD_REDRAW_SCREEN:
- redraw_screen();
- break;
-
- case CONTROL('X'):
- case CMD_SAVE_GAME_NOW:
- mpr("Saving game... please wait.");
- save_game(true);
- break;
-
-#ifdef USE_UNIX_SIGNALS
- case CONTROL('Z'):
- case CMD_SUSPEND_GAME:
- // CTRL-Z suspend behaviour is implemented here,
- // because we want to have CTRL-Y available...
- // and unfortuantely they tend to be stuck together.
- clrscr();
- unixcurses_shutdown();
- kill(0, SIGTSTP);
- unixcurses_startup();
- redraw_screen();
- break;
-#endif
-
- case '?':
- case CMD_DISPLAY_COMMANDS:
- list_commands(false);
- redraw_screen();
- break;
-
- case 'C':
- case CMD_EXPERIENCE_CHECK:
- snprintf( info, INFO_SIZE, "You are a level %d %s %s.", you.experience_level,
- species_name(you.species,you.experience_level), you.class_name);
- mpr(info);
-
- if (you.experience_level < 27)
- {
- int xp_needed = (exp_needed(you.experience_level+2) - you.experience) + 1;
- snprintf( info, INFO_SIZE, "Level %d requires %ld experience (%d point%s to go!)",
- you.experience_level + 1,
- exp_needed(you.experience_level + 2) + 1,
- xp_needed,
- (xp_needed > 1) ? "s" : "");
- mpr(info);
- }
- else
- {
- mpr( "I'm sorry, level 27 is as high as you can go." );
- mpr( "With the way you've been playing, I'm surprised you got this far." );
- }
-
- if (you.real_time != -1)
- {
- const time_t curr = you.real_time + (time(NULL) - you.start_time);
- char buff[200];
-
- make_time_string( curr, buff, sizeof(buff) );
-
- snprintf( info, INFO_SIZE, "Play time: %s (%ld turns)",
- buff, you.num_turns );
-
- mpr( info );
- }
- break;
-
-
- case '!':
- case CMD_SHOUT:
- yell(); /* in effects.cc */
- break;
-
- case '@':
- case CMD_DISPLAY_CHARACTER_STATUS:
- display_char_status();
- break;
-
- case 'm':
- case CMD_DISPLAY_SKILLS:
- show_skills();
- redraw_screen();
- break;
-
- case '#':
- case CMD_CHARACTER_DUMP:
- char name_your[kNameLen+1];
-
- strncpy(name_your, you.your_name, kNameLen);
- name_your[kNameLen] = '\0';
- if (dump_char( name_your, false ))
- strcpy(info, "Char dumped successfully.");
- else
- strcat(info, "Char dump unsuccessful! Sorry about that.");
- mpr(info);
- break;
-
-#ifdef USE_MACROS
- case '`':
- case CMD_MACRO_ADD:
- macro_add_query();
- break;
- case '~':
- case CMD_MACRO_SAVE:
- mpr("Saving macros.");
- macro_save();
- break;
-#endif
-
- case ')':
- case CMD_LIST_WEAPONS:
- list_weapons();
- return;
-
- case ']':
- case CMD_LIST_ARMOUR:
- list_armour();
- return;
-
- case '"':
- case CMD_LIST_JEWELLERY:
- list_jewellery();
- return;
-
-#ifdef WIZARD
- case CMD_WIZARD:
- case '&':
- handle_wizard_command();
- break;
-#endif
-
- case 'S':
- case CMD_SAVE_GAME:
- if (yesno("Save game and exit?", false, 'n'))
- save_game(true);
- break;
-
- case 'Q':
- case CMD_QUIT:
- quit_game();
- break;
-
- case 'V':
- case CMD_GET_VERSION:
- version();
- break;
-
- case 128: // Can't use this char -- it's the special value 128
- break;
-
- default:
- case CMD_NO_CMD:
- mpr("Unknown command.");
- break;
-
- }
-
-#ifdef UNIX
- // New Unix keypad stuff
- if (running)
- {
- int dir = -1;
-
- // XXX: ugly hack to interface this with the new running code. -- bwr
- for (int i = 0; i < 8; i++)
- {
- if (Compass[i].x == move_x && Compass[i].y == move_y)
- {
- dir = i;
- break;
- }
- }
-
- if (dir != -1)
- {
- start_running( dir, 2 );
- move_x = 0;
- move_y = 0;
- }
- }
- else if (opening)
- {
- open_door(move_x, move_y);
- move_x = 0;
- move_y = 0;
- }
-#endif
-
- if (move_x != 0 || move_y != 0)
- move_player(move_x, move_y);
- else if (you.turn_is_over) // we did something other than move/attack
- do_berserk_no_combat_penalty();
-
- if (!you.turn_is_over)
- {
- viewwindow(1, false);
- return;
- }
-
- if (you.num_turns != -1)
- you.num_turns++;
-
- //if (random2(10) < you.skills [SK_TRAPS_DOORS] + 2) search_around();
-
- stealth = check_stealth();
-
-#if 0
- // too annoying for regular diagnostics
- snprintf( info, INFO_SIZE, "stealth: %d", stealth );
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- if (you.special_wield != SPWLD_NONE)
- special_wielded();
-
- if (one_chance_in(10))
- {
- // this is instantaneous
- if (player_teleport() > 0 && one_chance_in(100 / player_teleport()))
- you_teleport2( true );
- else if (you.level_type == LEVEL_ABYSS && one_chance_in(30))
- you_teleport2( false, true ); // to new area of the Abyss
- }
-
- if (env.cgrid[you.x_pos][you.y_pos] != EMPTY_CLOUD)
- in_a_cloud();
-
- if (you.duration[DUR_REPEL_UNDEAD] > 1)
- you.duration[DUR_REPEL_UNDEAD]--;
-
- if (you.duration[DUR_REPEL_UNDEAD] == 4)
- {
- mpr( "Your holy aura is starting to fade.", MSGCH_DURATION );
- you.duration[DUR_REPEL_UNDEAD] -= random2(3);
- }
-
- if (you.duration[DUR_REPEL_UNDEAD] == 1)
- {
- mpr( "Your holy aura fades away.", MSGCH_DURATION );
- you.duration[DUR_REPEL_UNDEAD] = 0;
- }
-
- // paradox: it both lasts longer & does more damage overall if you're
- // moving slower.
- // rationalisation: I guess it gets rubbed off/falls off/etc if you
- // move around more.
- if (you.duration[DUR_LIQUID_FLAMES] > 0)
- you.duration[DUR_LIQUID_FLAMES]--;
-
- if (you.duration[DUR_LIQUID_FLAMES] != 0)
- {
- const int res_fire = player_res_fire();
-
- mpr( "You are covered in liquid flames!", MSGCH_WARN );
- scrolls_burn(8, OBJ_SCROLLS);
-
- if (res_fire > 0)
- {
- ouch( (((random2avg(9, 2) + 1) * you.time_taken) /
- (1 + (res_fire * res_fire))) / 10, 0, KILLED_BY_BURNING );
- }
-
- if (res_fire <= 0)
- {
- ouch(((random2avg(9, 2) + 1) * you.time_taken) / 10, 0,
- KILLED_BY_BURNING);
- }
-
- if (res_fire < 0)
- {
- ouch(((random2avg(9, 2) + 1) * you.time_taken) / 10, 0,
- KILLED_BY_BURNING);
- }
-
- if (you.duration[DUR_CONDENSATION_SHIELD] > 0)
- {
- mpr("Your icy shield dissipates!", MSGCH_DURATION);
- you.duration[DUR_CONDENSATION_SHIELD] = 0;
- you.redraw_armour_class = 1;
- }
- }
-
- if (you.duration[DUR_ICY_ARMOUR] > 1)
- {
- you.duration[DUR_ICY_ARMOUR]--;
- //scrolls_burn(4, OBJ_POTIONS);
- }
- else if (you.duration[DUR_ICY_ARMOUR] == 1)
- {
- mpr("Your icy armour evaporates.", MSGCH_DURATION);
- you.redraw_armour_class = 1; // is this needed? 2apr2000 {dlb}
- you.duration[DUR_ICY_ARMOUR] = 0;
- }
-
- if (you.duration[DUR_REPEL_MISSILES] > 1)
- {
- you.duration[DUR_REPEL_MISSILES]--;
- if (you.duration[DUR_REPEL_MISSILES] == 6)
- {
- mpr("Your repel missiles spell is about to expire...", MSGCH_DURATION);
- if (coinflip())
- you.duration[DUR_REPEL_MISSILES]--;
- }
- }
- else if (you.duration[DUR_REPEL_MISSILES] == 1)
- {
- mpr("You feel less protected from missiles.", MSGCH_DURATION);
- you.duration[DUR_REPEL_MISSILES] = 0;
- }
-
- if (you.duration[DUR_DEFLECT_MISSILES] > 1)
- {
- you.duration[DUR_DEFLECT_MISSILES]--;
- if (you.duration[DUR_DEFLECT_MISSILES] == 6)
- {
- mpr("Your deflect missiles spell is about to expire...", MSGCH_DURATION);
- if (coinflip())
- you.duration[DUR_DEFLECT_MISSILES]--;
- }
- }
- else if (you.duration[DUR_DEFLECT_MISSILES] == 1)
- {
- mpr("You feel less protected from missiles.", MSGCH_DURATION);
- you.duration[DUR_DEFLECT_MISSILES] = 0;
- }
-
- if (you.duration[DUR_REGENERATION] > 1)
- {
- you.duration[DUR_REGENERATION]--;
-
- if (you.duration[DUR_REGENERATION] == 6)
- {
- mpr("Your skin is crawling a little less now.", MSGCH_DURATION);
- if (coinflip())
- you.duration[DUR_REGENERATION]--;
- }
- }
- else if (you.duration[DUR_REGENERATION] == 1)
- {
- mpr("Your skin stops crawling.", MSGCH_DURATION);
- you.duration[DUR_REGENERATION] = 0;
- }
-
- if (you.duration[DUR_PRAYER] > 1)
- you.duration[DUR_PRAYER]--;
- else if (you.duration[DUR_PRAYER] == 1)
- {
- god_speaks(you.religion, "Your prayer is over.");
- you.duration[DUR_PRAYER] = 0;
- }
-
-
- //jmf: more flexible weapon branding code
- if (you.duration[DUR_WEAPON_BRAND] > 1)
- you.duration[DUR_WEAPON_BRAND]--;
- else if (you.duration[DUR_WEAPON_BRAND] == 1)
- {
- const int wpn = you.equip[EQ_WEAPON];
- const int temp_effect = get_weapon_brand( you.inv[wpn] );
-
- you.duration[DUR_WEAPON_BRAND] = 0;
-
- char str_pass[ITEMNAME_SIZE];
-
- set_item_ego_type( you.inv[wpn], OBJ_WEAPONS, SPWPN_NORMAL );
- in_name(wpn, DESC_CAP_YOUR, str_pass);
- strncpy(info, str_pass, INFO_SIZE);
-
- switch (temp_effect)
- {
- case SPWPN_VORPAL:
- if (get_vorpal_type(you.inv[you.equip[EQ_WEAPON]])
- == DVORP_SLICING)
- strcat(info, " seems blunter.");
- else
- strcat(info, " feels lighter.");
- break;
-
- case SPWPN_FLAMING:
- strcat(info, " goes out.");
- break;
- case SPWPN_FREEZING:
- strcat(info, " stops glowing.");
- break;
- case SPWPN_VENOM:
- strcat(info, " stops dripping with poison.");
- break;
- case SPWPN_DRAINING:
- strcat(info, " stops crackling.");
- break;
- case SPWPN_DISTORTION:
- strcat( info, " seems straighter." );
- // [dshaligram] Makes the brand unusable
- // miscast_effect( SPTYP_TRANSLOCATION, 9, 90, 100, "a distortion effect" );
- break;
- default:
- strcat(info, " seems inexplicably less special.");
- break;
- }
-
- //you.attribute[ATTR_WEAPON_BRAND] = 0;
- mpr(info, MSGCH_DURATION);
- you.wield_change = true;
- }
-
- if (you.duration[DUR_BREATH_WEAPON] > 1)
- you.duration[DUR_BREATH_WEAPON]--;
- else if (you.duration[DUR_BREATH_WEAPON] == 1)
- {
- mpr("You have got your breath back.", MSGCH_RECOVERY);
- you.duration[DUR_BREATH_WEAPON] = 0;
- }
-
- if (you.duration[DUR_TRANSFORMATION] > 1)
- {
- you.duration[DUR_TRANSFORMATION]--;
-
- if (you.duration[DUR_TRANSFORMATION] == 10)
- {
- mpr("Your transformation is almost over.", MSGCH_DURATION);
- you.duration[DUR_TRANSFORMATION] -= random2(3);
- }
- }
- else if (you.duration[DUR_TRANSFORMATION] == 1)
- {
- untransform();
- you.duration[DUR_BREATH_WEAPON] = 0;
- }
-
- if (you.duration[DUR_SWIFTNESS] > 1)
- {
- you.duration[DUR_SWIFTNESS]--;
- if (you.duration[DUR_SWIFTNESS] == 6)
- {
- mpr("You start to feel a little slower.", MSGCH_DURATION);
- if (coinflip())
- you.duration[DUR_SWIFTNESS]--;
- }
- }
- else if (you.duration[DUR_SWIFTNESS] == 1)
- {
- mpr("You feel sluggish.", MSGCH_DURATION);
- you.duration[DUR_SWIFTNESS] = 0;
- }
-
- if (you.duration[DUR_INSULATION] > 1)
- {
- you.duration[DUR_INSULATION]--;
- if (you.duration[DUR_INSULATION] == 6)
- {
- mpr("You start to feel a little less insulated.", MSGCH_DURATION);
- if (coinflip())
- you.duration[DUR_INSULATION]--;
- }
- }
- else if (you.duration[DUR_INSULATION] == 1)
- {
- mpr("You feel conductive.", MSGCH_DURATION);
- you.duration[DUR_INSULATION] = 0;
- }
-
- if (you.duration[DUR_STONEMAIL] > 1)
- {
- you.duration[DUR_STONEMAIL]--;
- if (you.duration[DUR_STONEMAIL] == 6)
- {
- mpr("Your scaly stone armour is starting to flake away.", MSGCH_DURATION);
- you.redraw_armour_class = 1;
- if (coinflip())
- you.duration[DUR_STONEMAIL]--;
- }
- }
- else if (you.duration[DUR_STONEMAIL] == 1)
- {
- mpr("Your scaly stone armour disappears.", MSGCH_DURATION);
- you.duration[DUR_STONEMAIL] = 0;
- you.redraw_armour_class = 1;
- burden_change();
- }
-
- if (you.duration[DUR_FORESCRY] > 1) //jmf: added
- you.duration[DUR_FORESCRY]--;
- else if (you.duration[DUR_FORESCRY] == 1)
- {
- mpr("You feel firmly rooted in the present.", MSGCH_DURATION);
- you.duration[DUR_FORESCRY] = 0;
- you.redraw_evasion = 1;
- }
-
- if (you.duration[DUR_SEE_INVISIBLE] > 1) //jmf: added
- you.duration[DUR_SEE_INVISIBLE]--;
- else if (you.duration[DUR_SEE_INVISIBLE] == 1)
- {
- you.duration[DUR_SEE_INVISIBLE] = 0;
-
- if (!player_see_invis())
- mpr("Your eyesight blurs momentarily.", MSGCH_DURATION);
- }
-
- if (you.duration[DUR_SILENCE] > 0) //jmf: cute message handled elsewhere
- you.duration[DUR_SILENCE]--;
-
- if (you.duration[DUR_CONDENSATION_SHIELD] > 1)
- {
- you.duration[DUR_CONDENSATION_SHIELD]--;
-
- // [dshaligram] Makes this spell useless
- // scrolls_burn( 1, OBJ_POTIONS );
-
- if (player_res_cold() < 0)
- {
- mpr( "You feel very cold." );
- ouch( 2 + random2avg(13, 2), 0, KILLED_BY_FREEZING );
- }
- }
- else if (you.duration[DUR_CONDENSATION_SHIELD] == 1)
- {
- you.duration[DUR_CONDENSATION_SHIELD] = 0;
- mpr("Your icy shield evaporates.", MSGCH_DURATION);
- you.redraw_armour_class = 1;
- }
-
- if (you.duration[DUR_STONESKIN] > 1)
- you.duration[DUR_STONESKIN]--;
- else if (you.duration[DUR_STONESKIN] == 1)
- {
- mpr("Your skin feels tender.", MSGCH_DURATION);
- you.redraw_armour_class = 1;
- you.duration[DUR_STONESKIN] = 0;
- }
-
- if (you.duration[DUR_GLAMOUR] > 1) //jmf: actually GLAMOUR_RELOAD, like
- you.duration[DUR_GLAMOUR]--; // the breath weapon delay
- else if (you.duration[DUR_GLAMOUR] == 1)
- {
- you.duration[DUR_GLAMOUR] = 0;
- //FIXME: cute message or not?
- }
-
- if (you.duration[DUR_TELEPORT] > 1)
- you.duration[DUR_TELEPORT]--;
- else if (you.duration[DUR_TELEPORT] == 1)
- {
- // only to a new area of the abyss sometimes (for abyss teleports)
- you_teleport2( true, one_chance_in(5) );
- you.duration[DUR_TELEPORT] = 0;
- }
-
- if (you.duration[DUR_CONTROL_TELEPORT] > 1)
- {
- you.duration[DUR_CONTROL_TELEPORT]--;
-
- if (you.duration[DUR_CONTROL_TELEPORT] == 6)
- {
- mpr("You start to feel a little uncertain.", MSGCH_DURATION);
- if (coinflip())
- you.duration[DUR_CONTROL_TELEPORT]--;
- }
- }
- else if (you.duration[DUR_CONTROL_TELEPORT] == 1)
- {
- mpr("You feel uncertain.", MSGCH_DURATION);
- you.duration[DUR_CONTROL_TELEPORT] = 0;
- you.attribute[ATTR_CONTROL_TELEPORT]--;
- }
-
- if (you.duration[DUR_RESIST_POISON] > 1)
- {
- you.duration[DUR_RESIST_POISON]--;
- if (you.duration[DUR_RESIST_POISON] == 6)
- {
- mpr("Your poison resistance is about to expire.", MSGCH_DURATION);
- if (coinflip())
- you.duration[DUR_RESIST_POISON]--;
- }
- }
- else if (you.duration[DUR_RESIST_POISON] == 1)
- {
- mpr("Your poison resistance expires.", MSGCH_DURATION);
- you.duration[DUR_RESIST_POISON] = 0;
- }
-
- if (you.duration[DUR_DEATH_CHANNEL] > 1)
- {
- you.duration[DUR_DEATH_CHANNEL]--;
- if (you.duration[DUR_DEATH_CHANNEL] == 6)
- {
- mpr("Your unholy channel is weakening.", MSGCH_DURATION);
- if (coinflip())
- you.duration[DUR_DEATH_CHANNEL]--;
- }
- }
- else if (you.duration[DUR_DEATH_CHANNEL] == 1)
- {
- mpr("Your unholy channel expires.", MSGCH_DURATION); // Death channel wore off
- you.duration[DUR_DEATH_CHANNEL] = 0;
- }
-
- if (you.invis > 1)
- {
- you.invis--;
-
- if (you.invis == 6)
- {
- mpr("You flicker for a moment.", MSGCH_DURATION);
- if (coinflip())
- you.invis--;
- }
- }
- else if (you.invis == 1)
- {
- mpr("You flicker back into view.", MSGCH_DURATION);
- you.invis = 0;
- }
-
- if (you.conf > 0)
- reduce_confuse_player(1);
-
- if (you.paralysis > 1)
- you.paralysis--;
- else if (you.paralysis == 1)
- {
- mpr("You can move again.", MSGCH_DURATION);
- you.paralysis = 0;
- }
-
- if (you.exhausted > 1)
- you.exhausted--;
- else if (you.exhausted == 1)
- {
- mpr("You feel less fatigued.", MSGCH_DURATION);
- you.exhausted = 0;
- }
-
- dec_slow_player();
- dec_haste_player();
-
- if (you.might > 1)
- you.might--;
- else if (you.might == 1)
- {
- mpr("You feel a little less mighty now.", MSGCH_DURATION);
- you.might = 0;
- modify_stat(STAT_STRENGTH, -5, true);
- }
-
- if (you.berserker > 1)
- you.berserker--;
- else if (you.berserker == 1)
- {
- mpr( "You are no longer berserk.", MSGCH_DURATION );
- you.berserker = 0;
-
- //jmf: guilty for berserking /after/ berserk
- did_god_conduct( DID_STIMULANTS, 6 + random2(6) );
-
- //
- // Sometimes berserk leaves us physically drained
- //
-
- // chance of passing out:
- // - mutation gives a large plus in order to try and
- // avoid the mutation being a "death sentence" to
- // certain characters.
- // - knowing the spell gives an advantage just
- // so that people who have invested 3 spell levels
- // are better off than the casual potion drinker...
- // this should make it a bit more interesting for
- // Crusaders again.
- // - similarly for the amulet
- int chance = 10 + you.mutation[MUT_BERSERK] * 25
- + (wearing_amulet( AMU_RAGE ) ? 10 : 0)
- + (player_has_spell( SPELL_BERSERKER_RAGE ) ? 5 : 0);
-
- // Note the beauty of Trog! They get an extra save that's at
- // the very least 20% and goes up to 100%.
- if (you.berserk_penalty == NO_BERSERK_PENALTY
- || (you.religion == GOD_TROG && you.piety > random2(150))
- || !one_chance_in( chance ))
- {
- mpr("You are exhausted.");
- }
- else
- {
- mpr("You pass out from exhaustion.", MSGCH_WARN);
- you.paralysis += roll_dice( 1, 4 );
- }
-
- // this resets from an actual penalty or from NO_BERSERK_PENALTY
- you.berserk_penalty = 0;
-
- int dur = 12 + roll_dice( 2, 12 );
- you.exhausted += dur;
- slow_player( dur );
-
- make_hungry(700, true);
-
- if (you.hunger < 50)
- you.hunger = 50;
-
- calc_hp();
- }
-
- if (you.confusing_touch > 1)
- you.confusing_touch--;
- else if (you.confusing_touch == 1)
- {
- snprintf( info, INFO_SIZE, "Your %s stop glowing.", your_hand(true) );
- mpr( info, MSGCH_DURATION );
- you.confusing_touch = 0;
- }
-
- if (you.sure_blade > 1)
- you.sure_blade--;
- else if (you.sure_blade == 1)
- {
- mpr("The bond with your blade fades away.", MSGCH_DURATION);
- you.sure_blade = 0;
- }
-
- if (you.levitation > 1)
- {
- if (you.species != SP_KENKU || you.experience_level < 15)
- you.levitation--;
-
- if (player_equip_ego_type( EQ_BOOTS, SPARM_LEVITATION ))
- you.levitation = 2;
-
- if (you.levitation == 10)
- {
- mpr("You are starting to lose your buoyancy!", MSGCH_DURATION);
- you.levitation -= random2(6);
-
- if (you.duration[DUR_CONTROLLED_FLIGHT] > 0)
- you.duration[DUR_CONTROLLED_FLIGHT] = you.levitation;
- }
- }
- else if (you.levitation == 1)
- {
- mpr("You float gracefully downwards.", MSGCH_DURATION);
- you.levitation = 0;
- burden_change();
- you.duration[DUR_CONTROLLED_FLIGHT] = 0;
-
- if (grd[you.x_pos][you.y_pos] == DNGN_LAVA
- || grd[you.x_pos][you.y_pos] == DNGN_DEEP_WATER
- || grd[you.x_pos][you.y_pos] == DNGN_SHALLOW_WATER)
- {
- if (you.species == SP_MERFOLK
- && grd[you.x_pos][you.y_pos] != DNGN_LAVA)
- {
- mpr("You dive into the water and return to your normal form.");
- merfolk_start_swimming();
- }
-
- if (grd[you.x_pos][you.y_pos] != DNGN_SHALLOW_WATER)
- fall_into_a_pool(true, grd[you.x_pos][you.y_pos]);
- }
- }
-
- if (you.rotting > 0)
- {
- // XXX: Mummies have an ability (albeit an expensive one) that
- // can fix rotted HPs now... it's probably impossible for them
- // to even start rotting right now, but that could be changed. -- bwr
- if (you.species == SP_MUMMY)
- you.rotting = 0;
- else if (random2(20) <= (you.rotting - 1))
- {
- mpr("You feel your flesh rotting away.", MSGCH_WARN);
- ouch(1, 0, KILLED_BY_ROTTING);
- rot_hp(1);
- you.rotting--;
- }
- }
-
- // ghoul rotting is special, but will deduct from you.rotting
- // if it happens to be positive - because this is placed after
- // the "normal" rotting check, rotting attacks can be somewhat
- // more painful on ghouls - reversing order would make rotting
- // attacks somewhat less painful, but that seems wrong-headed {dlb}:
- if (you.species == SP_GHOUL)
- {
- if (one_chance_in(400))
- {
- mpr("You feel your flesh rotting away.", MSGCH_WARN);
- ouch(1, 0, KILLED_BY_ROTTING);
- rot_hp(1);
-
- if (you.rotting > 0)
- you.rotting--;
- }
- }
-
- dec_disease_player();
-
- if (you.poison > 0)
- {
- if (random2(5) <= (you.poison - 1))
- {
- if (you.poison > 10 && random2(you.poison) >= 8)
- {
- ouch(random2(10) + 5, 0, KILLED_BY_POISON);
- mpr("You feel extremely sick.", MSGCH_DANGER);
- }
- else if (you.poison > 5 && coinflip())
- {
- ouch((coinflip()? 3 : 2), 0, KILLED_BY_POISON);
- mpr("You feel very sick.", MSGCH_WARN);
- }
- else
- {
- // the poison running through your veins.");
- ouch(1, 0, KILLED_BY_POISON);
- mpr("You feel sick.");
- }
-
- if ((you.hp == 1 && one_chance_in(3)) || one_chance_in(8))
- reduce_poison_player(1);
- }
- }
-
- if (you.deaths_door)
- {
- if (you.hp > allowed_deaths_door_hp())
- {
- mpr("Your life is in your own hands once again.", MSGCH_DURATION);
- you.paralysis += 5 + random2(5);
- confuse_player( 10 + random2(10) );
- you.hp_max--;
- deflate_hp(you.hp_max, false);
- you.deaths_door = 0;
- }
- else
- you.deaths_door--;
-
- if (you.deaths_door == 10)
- {
- mpr("Your time is quickly running out!", MSGCH_DURATION);
- you.deaths_door -= random2(6);
- }
- if (you.deaths_door == 1)
- {
- mpr("Your life is in your own hands again!", MSGCH_DURATION);
- more();
- }
- }
-
- const int food_use = player_hunger_rate();
-
- if (food_use > 0 && you.hunger >= 40)
- make_hungry( food_use, true );
-
- // XXX: using an int tmp to fix the fact that hit_points_regeneration
- // is only an unsigned char and is thus likely to overflow. -- bwr
- int tmp = static_cast< int >( you.hit_points_regeneration );
-
- if (you.hp < you.hp_max && !you.disease && !you.deaths_door)
- tmp += player_regen();
-
- while (tmp >= 100)
- {
- if (you.hp >= you.hp_max - 1
- && you.running && you.run_x == 0 && you.run_y == 0)
- {
- stop_running();
- }
-
- inc_hp(1, false);
- tmp -= 100;
- }
-
- ASSERT( tmp >= 0 && tmp < 100 );
- you.hit_points_regeneration = static_cast< unsigned char >( tmp );
-
- // XXX: Doing the same as the above, although overflow isn't an
- // issue with magic point regeneration, yet. -- bwr
- tmp = static_cast< int >( you.magic_points_regeneration );
-
- if (you.magic_points < you.max_magic_points)
- tmp += 7 + you.max_magic_points / 2;
-
- while (tmp >= 100)
- {
- if (you.magic_points >= you.max_magic_points - 1
- && you.running && you.run_x == 0 && you.run_y == 0)
- {
- stop_running();
- }
-
- inc_mp(1, false);
- tmp -= 100;
- }
-
- ASSERT( tmp >= 0 && tmp < 100 );
- you.magic_points_regeneration = static_cast< unsigned char >( tmp );
-
- // If you're wielding a rod, it'll gradually recharge.
- recharge_rods();
-
- viewwindow(1, true);
-
- handle_monsters();
-
- ASSERT(you.time_taken >= 0);
- // make sure we don't overflow
- ASSERT(DBL_MAX - you.elapsed_time > you.time_taken);
-
- you.elapsed_time += you.time_taken;
-
- if (you.synch_time <= you.time_taken)
- {
- handle_time(200 + (you.time_taken - you.synch_time));
- you.synch_time = 200;
- }
- else
- {
- you.synch_time -= you.time_taken;
- }
-
- manage_clouds();
-
- if (you.fire_shield > 0)
- manage_fire_shield();
-
- // There used to be signs of intent to have statues as some sort
- // of more complex state machine... I'm boiling them down to bare
- // basics for now. -- bwr
- if (Visible_Statue[ STATUE_SILVER ])
- {
- interrupt_activity( AI_STATUE );
-
- if ((!you.invis && one_chance_in(3)) || one_chance_in(5))
- {
- char wc[30];
-
- weird_colours( random2(256), wc );
- snprintf(info, INFO_SIZE, "The silver statue's eyes glow %s.", wc);
- mpr( info, MSGCH_WARN );
-
- create_monster( summon_any_demon((coinflip() ? DEMON_COMMON
- : DEMON_LESSER)),
- ENCH_ABJ_V, BEH_HOSTILE,
- you.x_pos, you.y_pos,
- MHITYOU, 250 );
- }
-
- Visible_Statue[ STATUE_SILVER ] = 0;
- }
-
- if (Visible_Statue[ STATUE_ORANGE_CRYSTAL ])
- {
- interrupt_activity( AI_STATUE );
-
- if ((!you.invis && coinflip()) || one_chance_in(4))
- {
- mpr("A hostile presence attacks your mind!", MSGCH_WARN);
-
- miscast_effect( SPTYP_DIVINATION, random2(15), random2(150), 100,
- "an orange crystal statue" );
- }
-
- Visible_Statue[ STATUE_ORANGE_CRYSTAL ] = 0;
- }
-
- // food death check:
- if (you.is_undead != US_UNDEAD && you.hunger <= 500)
- {
- if (!you.paralysis && one_chance_in(40))
- {
- mpr("You lose consciousness!", MSGCH_FOOD);
- you.paralysis += 5 + random2(8);
-
- if (you.paralysis > 13)
- you.paralysis = 13;
- }
-
- if (you.hunger <= 100)
- {
- mpr( "You have starved to death.", MSGCH_FOOD );
- ouch( -9999, 0, KILLED_BY_STARVATION );
- }
- }
-
- //jmf: added silence messages
- its_quiet = silenced(you.x_pos, you.y_pos);
-
- if (you.attribute[ATTR_WAS_SILENCED] != its_quiet)
- {
- if (its_quiet)
- {
- if (random2(30))
- mpr("You are enveloped in profound silence.", MSGCH_WARN);
- else
- mpr("The dungeon seems quiet ... too quiet!", MSGCH_WARN);
- }
- else
- {
- mpr("Your hearing returns.", MSGCH_RECOVERY);
- }
-
- you.attribute[ATTR_WAS_SILENCED] = its_quiet;
- }
-
- viewwindow(1, false);
-
- if (you.paralysis > 0 && any_messages())
- more();
-
- // place normal dungeon monsters, but not in player LOS
- if (you.level_type == LEVEL_DUNGEON
- && !player_in_branch( BRANCH_ECUMENICAL_TEMPLE )
- && one_chance_in((you.char_direction == DIR_DESCENDING) ? 240 : 10))
- {
- int prox = (one_chance_in(10) ? PROX_NEAR_STAIRS
- : PROX_AWAY_FROM_PLAYER);
-
- // The rules change once the player has picked up the Orb...
- if (you.char_direction == DIR_ASCENDING)
- prox = (one_chance_in(10) ? PROX_CLOSE_TO_PLAYER : PROX_ANYWHERE);
-
- mons_place( WANDERING_MONSTER, BEH_HOSTILE, MHITNOT, false,
- 50, 50, LEVEL_DUNGEON, prox );
- }
-
- // place Abyss monsters.
- if (you.level_type == LEVEL_ABYSS && one_chance_in(5))
- {
- mons_place( WANDERING_MONSTER, BEH_HOSTILE, MHITNOT, false,
- 50, 50, LEVEL_ABYSS, PROX_ANYWHERE );
- }
-
- // place Pandemonium monsters
- if (you.level_type == LEVEL_PANDEMONIUM && one_chance_in(50))
- pandemonium_mons();
-
- // No monsters in the Labyrinth, or Ecumenical Temple
- return;
-}
-
-/*
- Opens doors and handles some aspects of untrapping. If either move_x or
- move_y are non-zero, the pair carries a specific direction for the door
- to be opened (eg if you type ctrl - dir).
- */
-static void open_door(char move_x, char move_y)
-{
- struct dist door_move;
- int dx, dy; // door x, door y
-
- door_move.dx = move_x;
- door_move.dy = move_y;
-
- if (move_x || move_y)
- {
- // convenience
- dx = you.x_pos + move_x;
- dy = you.y_pos + move_y;
-
- const int mon = mgrd[dx][dy];
-
- if (mon != NON_MONSTER && !mons_has_ench( &menv[mon], ENCH_SUBMERGED ))
- {
- you_attack(mgrd[dx][dy], true);
- you.turn_is_over = 1;
-
- if (you.berserk_penalty != NO_BERSERK_PENALTY)
- you.berserk_penalty = 0;
-
- return;
- }
-
- if (grd[dx][dy] >= DNGN_TRAP_MECHANICAL && grd[dx][dy] <= DNGN_TRAP_III)
- {
- if (env.cgrid[dx][dy] != EMPTY_CLOUD)
- {
- mpr("You can't get to that trap right now.");
- return;
- }
-
- disarm_trap(door_move);
- return;
- }
-
- }
- else
- {
- mpr("Which direction?", MSGCH_PROMPT);
- direction( door_move, DIR_DIR );
- if (!door_move.isValid)
- return;
-
- // convenience
- dx = you.x_pos + door_move.dx;
- dy = you.y_pos + door_move.dy;
- }
-
- if (grd[dx][dy] == DNGN_CLOSED_DOOR)
- {
- int skill = you.dex + (you.skills[SK_TRAPS_DOORS] + you.skills[SK_STEALTH]) / 2;
-
- if (one_chance_in(skill) && !silenced(you.x_pos, you.y_pos))
- {
- mpr( "As you open the door, it creaks loudly!" );
- noisy( 10, you.x_pos, you.y_pos );
- }
- else
- {
- mpr( player_is_levitating() ? "You reach down and open the door."
- : "You open the door." );
- }
-
- grd[dx][dy] = DNGN_OPEN_DOOR;
- you.turn_is_over = 1;
- }
- else
- {
- mpr("You swing at nothing.");
- make_hungry(3, true);
- you.turn_is_over = 1;
- }
-} // end open_door()
-
-/*
- Similar to open_door. Can you spot the difference?
- */
-static void close_door(char door_x, char door_y)
-{
- struct dist door_move;
- int dx, dy; // door x, door y
-
- door_move.dx = door_x;
- door_move.dy = door_y;
-
- if (!(door_x || door_y))
- {
- mpr("Which direction?", MSGCH_PROMPT);
- direction( door_move, DIR_DIR );
- if (!door_move.isValid)
- return;
- }
-
- if (door_move.dx == 0 && door_move.dy == 0)
- {
- mpr("You can't close doors on yourself!");
- return;
- }
-
- // convenience
- dx = you.x_pos + door_move.dx;
- dy = you.y_pos + door_move.dy;
-
- if (grd[dx][dy] == DNGN_OPEN_DOOR)
- {
- if (mgrd[dx][dy] != NON_MONSTER)
- {
- // Need to make sure that turn_is_over = 1 if creature is invisible
- mpr("There's a creature in the doorway!");
- door_move.dx = 0;
- door_move.dy = 0;
- return;
- }
-
- if (igrd[dx][dy] != NON_ITEM)
- {
- mpr("There's something blocking the doorway.");
- door_move.dx = 0;
- door_move.dy = 0;
- return;
- }
-
- int skill = you.dex + (you.skills[SK_TRAPS_DOORS] + you.skills[SK_STEALTH]) / 2;
-
- if (one_chance_in(skill) && !silenced(you.x_pos, you.y_pos))
- {
- mpr("As you close the door, it creaks loudly!");
- noisy( 10, you.x_pos, you.y_pos );
- }
- else
- {
- mpr( player_is_levitating() ? "You reach down and close the door."
- : "You close the door." );
- }
-
- grd[dx][dy] = DNGN_CLOSED_DOOR;
- you.turn_is_over = 1;
- }
- else
- {
- mpr("There isn't anything that you can close there!");
- }
-} // end open_door()
-
-
-// initialise whole lot of stuff...
-// returns true if a new character
-static bool initialise(void)
-{
- bool ret;
-
- int i = 0, j = 0; // counter variables {dlb}
-
- your_sign = '@';
- your_colour = LIGHTGREY;
-
- // system initialisation stuff:
- textbackground(0);
-
-#ifdef DOS
- directvideo = 1;
-#endif
-
-#ifdef USE_EMX
- init_emx();
-#endif
-
- seed_rng();
-
- init_properties();
- init_monsters(mcolour); // this needs to be way up top {dlb}
- init_playerspells(); // this needs to be way up top {dlb}
-
- clrscr();
-
- // init item array:
- for (i = 1; i < MAX_ITEMS; i++)
- init_item( i );
-
- // empty messaging string
- strcpy(info, "");
-
- for (i = 0; i < MAX_MONSTERS; i++)
- {
- menv[i].type = -1;
- menv[i].speed_increment = 10;
- menv[i].flags = 0;
- menv[i].behaviour = BEH_SLEEP;
-
- menv[i].foe = NON_MONSTER;
- menv[i].attitude = ATT_HOSTILE;
-
- for (j = 0; j < NUM_MON_ENCHANTS; j++)
- menv[i].enchantment[j] = ENCH_NONE;
-
- for (j = 0; j < NUM_MONSTER_SLOTS; j++)
- menv[i].inv[j] = NON_ITEM;
-
- menv[i].number = 0;
- }
-
- for (i = 0; i < GXM; i++)
- {
- for (j = 0; j < GYM; j++)
- {
- igrd[i][j] = NON_ITEM;
- mgrd[i][j] = NON_MONSTER;
- env.map[i][j] = 0;
- }
- }
-
- for (i = 0; i < 50; i++)
- {
- you.unique_creatures[i] = 0;
- you.unique_items[i] = UNIQ_NOT_EXISTS;
- }
-
- for (i = 0; i < NUM_STATUE_TYPES; i++)
- Visible_Statue[i] = 0;
-
- // initialize tag system before we try loading anything!
- tag_init();
-
- // sets up a new game:
- bool newc = new_game();
- ret = newc; // newc will be mangled later so we'll take a copy --bwr
-
- if (!newc)
- restore_game();
-
- game_has_started = true;
-
- calc_hp();
- calc_mp();
-
- load( 82, (newc ? LOAD_START_GAME : LOAD_RESTART_GAME), false, 0,
- you.where_are_you );
-
-#if DEBUG_DIAGNOSTICS
- // Debug compiles display a lot of "hidden" information, so we auto-wiz
- you.wizard = true;
-#endif
-
- init_properties();
- burden_change();
- make_hungry(0,true);
-
- you.redraw_strength = 1;
- you.redraw_intelligence = 1;
- you.redraw_dexterity = 1;
- you.redraw_armour_class = 1;
- you.redraw_evasion = 1;
- you.redraw_experience = 1;
- you.redraw_gold = 1;
- you.wield_change = true;
-
- you.start_time = time( NULL ); // start timer on session
-
- draw_border();
- new_level();
-
- travel_init_new_level();
- // Mark items in inventory as of unknown origin.
- origin_set_inventory(origin_set_unknown);
-
- // set vision radius to player's current vision
- setLOSRadius( you.current_vision );
-
- if (newc)
- {
- // For a new game, wipe out monsters in LOS.
- zap_los_monsters();
- }
-
- viewwindow(1, false); // This just puts the view up for the first turn.
- item();
-
-#ifdef CLUA_BINDINGS
- clua.runhook("chk_startgame", "%b", ret);
- std::string yname = you.your_name;
- read_init_file(true);
- strncpy(you.your_name, yname.c_str(), kNameLen);
- you.your_name[kNameLen - 1] = 0;
-#endif
-
- return (ret);
-}
-
-// An attempt to tone down berserk a little bit. -- bwross
-//
-// This function does the accounting for not attacking while berserk
-// This gives a triangluar number function for the additional penalty
-// Turn: 1 2 3 4 5 6 7 8
-// Penalty: 1 3 6 10 15 21 28 36
-//
-// Total penalty (including the standard one during upkeep is:
-// 2 5 9 14 20 27 35 44
-//
-static void do_berserk_no_combat_penalty(void)
-{
- // Butchering/eating a corpse will maintain a blood rage.
- const int delay = current_delay_action();
- if (delay == DELAY_BUTCHER || delay == DELAY_EAT)
- return;
-
- if (you.berserk_penalty == NO_BERSERK_PENALTY)
- return;
-
- if (you.berserker)
- {
- you.berserk_penalty++;
-
- switch (you.berserk_penalty)
- {
- case 2:
- mpr("You feel a strong urge to attack something.", MSGCH_DURATION);
- break;
- case 4:
- mpr("You feel your anger subside.", MSGCH_DURATION);
- break;
- case 6:
- mpr("Your blood rage is quickly leaving you.", MSGCH_DURATION);
- break;
- }
-
- // I do these three separately, because the might and
- // haste counters can be different.
- you.berserker -= you.berserk_penalty;
- if (you.berserker < 1)
- you.berserker = 1;
-
- you.might -= you.berserk_penalty;
- if (you.might < 1)
- you.might = 1;
-
- you.haste -= you.berserk_penalty;
- if (you.haste < 1)
- you.haste = 1;
- }
- return;
-} // end do_berserk_no_combat_penalty()
-
-
-// Called when the player moves by walking/running. Also calls
-// attack function and trap function etc when necessary.
-static void move_player(char move_x, char move_y)
-{
- bool attacking = false;
- bool moving = true; // used to prevent eventual movement (swap)
-
- int i;
- bool trap_known;
-
- if (you.conf)
- {
- if (!one_chance_in(3))
- {
- move_x = random2(3) - 1;
- move_y = random2(3) - 1;
- }
-
- const int new_targ_x = you.x_pos + move_x;
- const int new_targ_y = you.y_pos + move_y;
- const unsigned char new_targ_grid = grd[ new_targ_x ][ new_targ_y ];
-
- if (new_targ_grid < MINMOVE)
- {
- you.turn_is_over = 1;
- mpr("Ouch!");
- return;
- }
-
- if (new_targ_grid == DNGN_LAVA
- && you.duration[DUR_CONDENSATION_SHIELD] > 0)
- {
- mpr("Your icy shield dissipates!", MSGCH_DURATION);
- you.duration[DUR_CONDENSATION_SHIELD] = 0;
- you.redraw_armour_class = 1;
- }
-
- if ((new_targ_grid == DNGN_LAVA
- || new_targ_grid == DNGN_DEEP_WATER
- || new_targ_grid == DNGN_SHALLOW_WATER)
- && !player_is_levitating())
- {
- if (you.species == SP_MERFOLK && new_targ_grid != DNGN_LAVA)
- {
- mpr("You stumble into the water and return to your normal form.");
- merfolk_start_swimming();
- }
-
- if (new_targ_grid != DNGN_SHALLOW_WATER)
- fall_into_a_pool( false, new_targ_grid );
-
- you.turn_is_over = 1;
- do_berserk_no_combat_penalty();
- return;
- }
- } // end of if you.conf
-
- if (you.running > 0 && you.running != 2 && check_stop_running())
- {
- stop_running();
- move_x = 0;
- move_y = 0;
- you.turn_is_over = 0;
- return;
- }
-
- const int targ_x = you.x_pos + move_x;
- const int targ_y = you.y_pos + move_y;
- const unsigned char old_grid = grd[ you.x_pos ][ you.y_pos ];
- const unsigned char targ_grid = grd[ targ_x ][ targ_y ];
- const unsigned char targ_monst = mgrd[ targ_x ][ targ_y ];
-
- if (targ_monst != NON_MONSTER)
- {
- struct monsters *mon = &menv[targ_monst];
-
- if (mons_has_ench( mon, ENCH_SUBMERGED ))
- goto break_out;
-
- // you can swap places with a friendly monster if you
- // can see it and you're not confused
- if (mons_friendly( mon ) && player_monster_visible( mon ) && !you.conf)
- {
- if (!swap_places( mon ))
- moving = false;
-
- goto break_out;
- }
-
- you_attack( targ_monst, true );
- you.turn_is_over = 1;
-
- // we don't want to create a penalty if there isn't
- // supposed to be one
- if (you.berserk_penalty != NO_BERSERK_PENALTY)
- you.berserk_penalty = 0;
-
- attacking = true;
- }
-
- break_out:
- if (targ_grid == DNGN_LAVA && you.duration[DUR_CONDENSATION_SHIELD] > 0)
- {
- mpr("Your icy shield dissipates!", MSGCH_DURATION);
- you.duration[DUR_CONDENSATION_SHIELD] = 0;
- you.redraw_armour_class = 1;
- }
-
- // Handle dangerous tiles
- if ((targ_grid == DNGN_LAVA
- || targ_grid == DNGN_DEEP_WATER
- || targ_grid == DNGN_SHALLOW_WATER)
- && !attacking && !player_is_levitating() && moving)
- {
- // Merfold automatically enter deep water... every other case
- // we ask for confirmation.
- if (you.species == SP_MERFOLK && targ_grid != DNGN_LAVA)
- {
- // Only mention diving if we just entering the water.
- if (!player_in_water())
- {
- mpr("You dive into the water and return to your normal form.");
- merfolk_start_swimming();
- }
- }
- else if (targ_grid != DNGN_SHALLOW_WATER)
- {
- bool enter = yesno("Do you really want to step there?", false, 'n');
-
- if (enter)
- {
- fall_into_a_pool( false, targ_grid );
- you.turn_is_over = 1;
- do_berserk_no_combat_penalty();
- return;
- }
- else
- {
- canned_msg(MSG_OK);
- return;
- }
- }
- }
-
- if (!attacking && targ_grid >= MINMOVE && moving)
- {
- if (targ_grid == DNGN_UNDISCOVERED_TRAP
- && random2(you.skills[SK_TRAPS_DOORS] + 1) > 3)
- {
- strcpy(info, "Wait a moment, ");
- strcat(info, you.your_name);
- strcat(info, "! Do you really want to step there?");
- mpr(info, MSGCH_WARN);
- more();
- you.turn_is_over = 0;
-
- i = trap_at_xy( targ_x, targ_y );
- if (i != -1)
- grd[ targ_x ][ targ_y ] = trap_category(env.trap[i].type);
- return;
- }
-
- you.x_pos += move_x;
- you.y_pos += move_y;
-
- if (targ_grid == DNGN_SHALLOW_WATER && !player_is_levitating())
- {
- if (you.species != SP_MERFOLK)
- {
- if (one_chance_in(3) && !silenced(you.x_pos, you.y_pos))
- {
- mpr("Splash!");
- noisy( 10, you.x_pos, you.y_pos );
- }
-
- you.time_taken *= 13 + random2(8);
- you.time_taken /= 10;
-
- if (old_grid != DNGN_SHALLOW_WATER)
- {
- mpr( "You enter the shallow water. "
- "Moving in this stuff is going to be slow." );
-
- if (you.invis)
- mpr( "And don't expect to remain undetected." );
- }
- }
- else if (old_grid != DNGN_SHALLOW_WATER
- && old_grid != DNGN_DEEP_WATER)
- {
- mpr("You return to your normal form as you enter the water.");
- merfolk_start_swimming();
- }
- }
-
- move_x = 0;
- move_y = 0;
-
- you.time_taken *= player_movement_speed();
- you.time_taken /= 10;
-
- you.turn_is_over = 1;
- item_check(0);
-
- if (targ_grid >= DNGN_TRAP_MECHANICAL
- && targ_grid <= DNGN_UNDISCOVERED_TRAP)
- {
- if (targ_grid == DNGN_UNDISCOVERED_TRAP)
- {
- i = trap_at_xy(you.x_pos, you.y_pos);
- if (i != -1)
- grd[ you.x_pos ][ you.y_pos ] = trap_category(env.trap[i].type);
- trap_known = false;
- }
- else
- {
- trap_known = true;
- }
-
- i = trap_at_xy( you.x_pos, you.y_pos );
- if (i != -1)
- {
- if (player_is_levitating()
- && trap_category(env.trap[i].type) == DNGN_TRAP_MECHANICAL)
- {
- goto out_of_traps; // can fly over mechanical traps
- }
-
- handle_traps(env.trap[i].type, i, trap_known);
- }
- } // end of if another grd == trap
- }
-
- out_of_traps:
- // BCR - Easy doors single move
- if (targ_grid == DNGN_CLOSED_DOOR && (Options.easy_open || you.running < 0))
- open_door(move_x, move_y);
- else if (targ_grid <= MINMOVE)
- {
- stop_running();
- move_x = 0;
- move_y = 0;
- you.turn_is_over = 0;
- }
-
- if (you.running == 2)
- you.running = 1;
-
- if (you.level_type == LEVEL_ABYSS
- && (you.x_pos <= 15 || you.x_pos >= (GXM - 16)
- || you.y_pos <= 15 || you.y_pos >= (GYM - 16)))
- {
- area_shift();
- you.pet_target = MHITNOT;
-
-#if DEBUG_DIAGNOSTICS
- mpr( "Shifting.", MSGCH_DIAGNOSTICS );
- int igly = 0;
- int ig2 = 0;
-
- for (igly = 0; igly < MAX_ITEMS; igly++)
- {
- if (is_valid_item( mitm[igly] ))
- ig2++;
- }
-
- snprintf( info, INFO_SIZE, "Number of items present: %d", ig2 );
- mpr( info, MSGCH_DIAGNOSTICS );
-
- ig2 = 0;
- for (igly = 0; igly < MAX_MONSTERS; igly++)
- {
- if (menv[igly].type != -1)
- ig2++;
- }
-
- snprintf( info, INFO_SIZE, "Number of monsters present: %d", ig2 );
- mpr( info, MSGCH_DIAGNOSTICS );
-
- snprintf( info, INFO_SIZE, "Number of clouds present: %d", env.cloud_no );
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
- }
-
- if (!attacking)
- {
- do_berserk_no_combat_penalty();
- }
-} // end move_player()
diff --git a/stone_soup/crawl-ref/source/acrawl.gdt b/stone_soup/crawl-ref/source/acrawl.gdt
deleted file mode 100644
index 3406830926..0000000000
--- a/stone_soup/crawl-ref/source/acrawl.gdt
+++ /dev/null
Binary files differ
diff --git a/stone_soup/crawl-ref/source/acrawl.gpr b/stone_soup/crawl-ref/source/acrawl.gpr
deleted file mode 100644
index 321e91e8e3..0000000000
--- a/stone_soup/crawl-ref/source/acrawl.gpr
+++ /dev/null
Binary files differ
diff --git a/stone_soup/crawl-ref/source/beam.cc b/stone_soup/crawl-ref/source/beam.cc
deleted file mode 100644
index 44d1fbc0d9..0000000000
--- a/stone_soup/crawl-ref/source/beam.cc
+++ /dev/null
@@ -1,4520 +0,0 @@
-/*
- * File: beam.cc
- * Summary: Functions related to ranged attacks.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <7> 21mar2001 GDL Replaced all FP arithmetic with integer*100 math
- * <6> 07jan2001 GDL complete rewrite.
- * <5> 22July2000 GDL allowed 'dummy' missiles from monsters
- * <4> 11/14/99 cdl evade beams with random40(ev) vice random2(ev)
- * all armour now protects against shrapnel
- * <3> 6/ 2/99 DML Added enums
- * <2> 5/20/99 BWR Added refreshs for curses
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "beam.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#ifdef DOS
-#include <dos.h>
-#include <conio.h>
-#endif
-#if DEBUG_DIAGNOSTICS
-#include <stdio.h>
-#endif
-
-#include "externs.h"
-
-#include "cloud.h"
-#include "effects.h"
-#include "enum.h"
-#include "it_use2.h"
-#include "itemname.h"
-#include "items.h"
-#include "itemprop.h"
-#include "misc.h"
-#include "monplace.h"
-#include "monstuff.h"
-#include "mon-util.h"
-#include "mstuff2.h"
-#include "ouch.h"
-#include "player.h"
-#include "religion.h"
-#include "skills.h"
-#include "spells1.h"
-#include "spells3.h"
-#include "spells4.h"
-#include "stuff.h"
-#include "view.h"
-
-#define BEAM_STOP 1000 // all beams stopped by subtracting this
- // from remaining range
-#define MON_RESIST 0 // monster resisted
-#define MON_UNAFFECTED 1 // monster unaffected
-#define MON_AFFECTED 2 // monster was unaffected
-
-extern FixedVector< char, NUM_STATUE_TYPES > Visible_Statue; // in acr.cc
-
-static int spreadx[] = { 0, 0, 1, -1 };
-static int spready[] = { -1, 1, 0, 0 };
-static int opdir[] = { 2, 1, 4, 3 };
-static FixedArray < bool, 19, 19 > explode_map;
-
-// helper functions (some of these, esp. affect(), should probably
-// be public):
-static void sticky_flame_monster( int mn, bool source, int hurt_final );
-static bool affectsWalls(struct bolt &beam);
-static bool isBouncy(struct bolt &beam);
-static void beam_drop_object( struct bolt &beam, item_def *item, int x, int y );
-static bool beam_term_on_target(struct bolt &beam);
-static void beam_explodes(struct bolt &beam, int x, int y);
-static int bounce(int &step1, int &step2, int w1, int w2, int &n1, int &n2,
- int l1, int l2, int &t1, int &t2, bool topBlocked, bool sideBlocked);
-static bool fuzzyLine(int nx, int ny, int &tx, int &ty, int lx, int ly,
- int stepx, int stepy, bool roundX, bool roundY);
-static int affect_wall(struct bolt &beam, int x, int y);
-static int affect_place_clouds(struct bolt &beam, int x, int y);
-static void affect_place_explosion_clouds(struct bolt &beam, int x, int y);
-static int affect_player(struct bolt &beam);
-static void affect_items(struct bolt &beam, int x, int y);
-static int affect_monster(struct bolt &beam, struct monsters *mon);
-static int affect_monster_enchantment(struct bolt &beam, struct monsters *mon);
-static int range_used_on_hit(struct bolt &beam);
-static void explosion1(struct bolt &pbolt);
-static void explosion_map(struct bolt &beam, int x, int y,
- int count, int dir, int r);
-static void explosion_cell(struct bolt &beam, int x, int y, bool drawOnly);
-
-static void ench_animation( int flavour, const monsters *mon = NULL, bool force = false);
-static void zappy(char z_type, int power, struct bolt &pbolt);
-
-static bool beam_is_blockable( struct bolt &pbolt )
-{
- // BEAM_ELECTRICITY is added here because chain lighting is not
- // a true beam (stops at the first target it gets to and redirects
- // from there)... but we don't want it shield blockable.
- return (!pbolt.is_beam && !pbolt.is_explosion
- && pbolt.flavour != BEAM_ELECTRICITY);
-}
-
-// simple animated flash from Rupert Smith (and expanded to be more generic):
-void zap_animation( int colour, const monsters *mon, bool force )
-{
- int x = you.x_pos, y = you.y_pos;
-
- // default to whatever colour magic is today
- if (colour == -1)
- colour = element_colour( EC_MAGIC );
-
- if (mon)
- {
- if (!force && !player_monster_visible( mon ))
- return;
-
- x = mon->x;
- y = mon->y;
- }
-
- if (!see_grid( x, y ))
- return;
-
- const int drawx = x - you.x_pos + 18;
- const int drawy = y - you.y_pos + 9;
-
- if (drawx > 8 && drawx < 26 && drawy > 0 && drawy < 18)
- {
- textcolor( colour );
- gotoxy( drawx, drawy );
- putch( SYM_ZAP );
-
-#ifdef LINUX
- update_screen();
-#endif
-
- delay(50);
- }
-}
-
-// special front function for zap_animation to interpret enchantment flavours
-static void ench_animation( int flavour, const monsters *mon, bool force )
-{
- const int elem = (flavour == BEAM_HEALING) ? EC_HEAL :
- (flavour == BEAM_PAIN) ? EC_UNHOLY :
- (flavour == BEAM_DISPEL_UNDEAD) ? EC_HOLY :
- (flavour == BEAM_POLYMORPH) ? EC_MUTAGENIC :
- (flavour == BEAM_TELEPORT
- || flavour == BEAM_BANISH
- || flavour == BEAM_BLINK) ? EC_WARP
- : EC_ENCHANT;
- zap_animation( element_colour( elem ), mon, force );
-}
-
-void zapping(char ztype, int power, struct bolt &pbolt)
-{
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "zapping: power=%d", power );
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- // GDL: note that rangeMax is set to 0, which means that max range is
- // equal to range. This is OK, since rangeMax really only matters for
- // stuff monsters throw/zap.
-
- // all of the following might be changed by zappy():
- pbolt.range = 8 + random2(5); // default for "0" beams (I think)
- pbolt.rangeMax = 0;
- pbolt.hit = 0; // default for "0" beams (I think)
- pbolt.damage = dice_def( 1, 0 ); // default for "0" beams (I think)
- pbolt.type = 0; // default for "0" beams
- pbolt.flavour = BEAM_MAGIC; // default for "0" beams
- pbolt.ench_power = power;
- pbolt.obvious_effect = false;
- pbolt.is_beam = false; // default for all beams.
- pbolt.is_tracer = false; // default for all player beams
- pbolt.thrower = KILL_YOU_MISSILE; // missile from player
- pbolt.aux_source = NULL; // additional source info, unused
-
- // fill in the bolt structure
- zappy( ztype, power, pbolt );
-
- if (ztype == ZAP_LIGHTNING && !silenced(you.x_pos, you.y_pos))
- // needs to check silenced at other location, too {dlb}
- {
- mpr("You hear a mighty clap of thunder!");
- noisy( 25, you.x_pos, you.y_pos );
- }
-
- fire_beam(pbolt);
-
- return;
-} // end zapping()
-
-dice_def calc_dice( int num_dice, int max_damage )
-{
- dice_def ret( num_dice, 0 );
-
- if (num_dice <= 1)
- {
- ret.num = 1;
- ret.size = max_damage;
- }
- else if (max_damage <= num_dice)
- {
- ret.num = max_damage;
- ret.size = 1;
- }
- else
- {
- // Divied the damage among the dice, and add one
- // occasionally to make up for the fractions. -- bwr
- ret.size = max_damage / num_dice;
- ret.size += (random2( num_dice ) < max_damage % num_dice);
- }
-
- return (ret);
-}
-
-// *do not* call this function directly (duh - it's static), need to
-// see zapping() for default values not set within this function {dlb}
-static void zappy( char z_type, int power, struct bolt &pbolt )
-{
- int temp_rand = 0; // probability determination {dlb}
-
- // Note: The incoming power is not linear in the case of spellcasting.
- // The power curve currently allows for the character to reasonably
- // get up to a power level of about a 100, but more than that will
- // be very hard (and the maximum is 200). The low level power caps
- // provide the useful feature in that they allow for low level spells
- // to have quick advancement, but don't cause them to obsolete the
- // higher level spells. -- bwr
- //
- // I've added some example characters below to show how little
- // people should be concerned about the power caps.
- //
- // The example characters are simplified to three stats:
- //
- // - Intelligence: This magifies power, its very useful.
- //
- // - Skills: This represents the character having Spellcasting
- // and the average of the component skills at this level.
- // Although, Spellcasting probably isn't quite as high as
- // other spell skills for a lot of characters, note that it
- // contributes much less to the total power (about 20%).
- //
- // - Enhancers: These are equipment that the player can use to
- // apply additional magnifiers (x1.5) to power. There are
- // also inhibitors that reduce power (/2.0), but we're not
- // concerned about those here. Anyways, the character can
- // currently have up to 3 levels (for x1.5, x2.25, x3.375).
- // The lists below should help to point out the difficulty
- // and cost of getting more than one level of enhancement.
- //
- // Here's a list of current magnifiers:
- //
- // - rings of fire/cold
- // - staff of fire/cold/air/earth/poison/death/conjure/enchant/summon
- // - staff of Olgreb (poison)
- // - robe of the Archmagi (necro, conjure, enchant, summon)
- // - Mummy intrinsic (+1 necromancy at level 13, +2 at level 26)
- // - Necromutation (+1 to necromancy -- note: undead can't use this)
- // - Ring of Fire (+1 to fire)
- //
- // The maximum enhancement, by school (but capped at 3):
- //
- // - Necromancy: 4 (Mummies), 3 (others)
- // - Fire: 4
- // - Cold: 3
- // - Conjuration: 2
- // - Enchantment: 2
- // - Summoning: 2
- // - Air: 1
- // - Earth: 1
- // - Poison: 1
- // - Translocations, Transmigrations, Divinations intentionally 0
-
- switch (z_type)
- {
- // level 1
- //
- // This cap is to keep these easy and very cheap spells from
- // becoming too powerful.
- //
- // Example characters with about 25 power:
- //
- // - int 5, skills 20, 0 enhancers
- // - int 5, skills 14, 1 enhancer
- // - int 10, skills 10, 0 enhancers
- // - int 10, skills 7, 1 enhancers
- // - int 15, skills 7, 0 enhancers
- // - int 20, skills 6, 0 enhancers
- case ZAP_STRIKING:
- case ZAP_MAGIC_DARTS:
- case ZAP_STING:
- case ZAP_ELECTRICITY:
- case ZAP_FLAME_TONGUE:
- case ZAP_SMALL_SANDBLAST:
- case ZAP_DISRUPTION: // ench_power boosted below
- case ZAP_PAIN: // ench_power boosted below
- if (power > 25)
- power = 25;
- break;
-
- // level 2/3
- //
- // The following examples should make it clear that in the
- // early game this cap is only limiting to serious spellcasters
- // (they could easily reach the 20-10-0 example).
- //
- // Example characters with about 50 power:
- //
- // - int 10, skills 20, 0 enhancers
- // - int 10, skills 14, 1 enhancer
- // - int 15, skills 14, 0 enhancers
- // - int 15, skills 10, 1 enhancer
- // - int 20, skills 10, 0 enhancers
- // - int 20, skills 7, 1 enhancer
- // - int 25, skills 8, 0 enhancers
- case ZAP_SANDBLAST:
- case ZAP_FLAME: // also ability (pow = lev * 2)
- case ZAP_FROST: // also ability (pow = lev * 2)
- case ZAP_STONE_ARROW:
- if (power > 50)
- power = 50;
- break;
-
- // Here are some examples that show that its fairly safe to assume
- // that a high level character can easily have 75 power.
- //
- // Example characters with about 75 power:
- //
- // - int 10, skills 27, 1 enhancer
- // - int 15, skills 27, 0 enhancers
- // - int 15, skills 16, 1 enhancer
- // - int 20, skills 20, 0 enhancers
- // - int 20, skills 14, 1 enhancer
- // - int 25, skills 16, 0 enhancers
-
- // level 4
- //
- // The following examples should make it clear that this is the
- // effective maximum power. Its not easy to get to 100 power,
- // but 20-20-1 or 25-16-1 is certainly attainable by a high level
- // spellcaster. As you can see from the examples at 150 and 200,
- // getting much power beyond this is very difficult.
- //
- // Level 3 and 4 spells cannot be overpowered.
- //
- // Example characters with about 100 power:
- //
- // - int 10, skills 27, 2 enhancers
- // - int 15, skills 27, 1 enhancer
- // - int 20, skills 20, 1 enhancer
- // - int 25, skills 24, 0 enhancers
- // - int 25, skills 16, 1 enhancer
- case ZAP_MYSTIC_BLAST:
- case ZAP_STICKY_FLAME:
- case ZAP_ICE_BOLT:
- case ZAP_DISPEL_UNDEAD: // ench_power raised below
- if (power > 100)
- power = 100;
- break;
-
- // levels 5-7
- //
- // These spells used to be capped, but its very hard to raise
- // power over 100, and these examples should show that.
- // Only the twinkiest of characters are expected to get to 150.
- //
- // Example characters with about 150 power:
- //
- // - int 15, skills 27, 3 enhancers (actually, only 146)
- // - int 20, skills 27, 2 enhancers (actually, only 137)
- // - int 20, skills 21, 3 enhancers
- // - int 25, skills 26, 2 enhancers
- // - int 30, skills 21, 2 enhancers
- // - int 40, skills 24, 1 enhancer
- // - int 70, skills 20, 0 enhancers
- case ZAP_FIRE:
- case ZAP_COLD:
- case ZAP_VENOM_BOLT:
- case ZAP_MAGMA:
- case ZAP_AGONY:
- case ZAP_LIGHTNING: // also invoc * 6 or lev * 2 (abils)
- case ZAP_NEGATIVE_ENERGY: // also ability (pow = lev * 6)
- case ZAP_IRON_BOLT:
- case ZAP_DISINTEGRATION:
- case ZAP_FIREBALL:
- case ZAP_ORB_OF_ELECTRICITY:
- case ZAP_ORB_OF_FRAGMENTATION:
- case ZAP_POISON_ARROW:
- // if (power > 150)
- // power = 150;
- break;
-
- // levels 8-9
- //
- // These spells are capped at 200 (which is the cap in calc_spell_power).
- // As an example of how little of a cap that is, consider the fact
- // that a 70-27-3 character has an uncapped power of 251. Characters
- // are never expected to get to this cap.
- //
- // Example characters with about 200 power:
- //
- // - int 30, skills 27, 3 enhancers (actually, only 190)
- // - int 40, skills 27, 2 enhancers (actually, only 181)
- // - int 40, skills 23, 3 enhancers
- // - int 70, skills 27, 0 enhancers (actually, only 164)
- // - int 70, skills 27, 1 enhancers (actually, only 194)
- // - int 70, skills 20, 2 enhancers
- // - int 70, skills 13, 3 enhancers
- case ZAP_CRYSTAL_SPEAR:
- case ZAP_HELLFIRE:
- case ZAP_ICE_STORM:
- case ZAP_CLEANSING_FLAME:
- // if (power > 200)
- // power = 200;
- break;
-
- // unlimited power (needs a good reason)
- case ZAP_BONE_SHARDS: // incoming power is modified for mass
- case ZAP_BEAM_OF_ENERGY: // inaccuracy (only on staff, hardly hits)
- break;
-
- // natural/mutant breath/spit powers (power ~= characer level)
- case ZAP_SPIT_POISON: // lev + mut * 5
- case ZAP_BREATHE_FIRE: // lev + mut * 4 + 12 (if dragonform)
- case ZAP_BREATHE_FROST: // lev
- case ZAP_BREATHE_ACID: // lev (or invoc * 3 from minor destr)
- case ZAP_BREATHE_POISON: // lev
- case ZAP_BREATHE_POWER: // lev
- case ZAP_BREATHE_STEAM: // lev
- if (power > 50)
- power = 50;
- break;
-
- // enchantments and other resistable effects
- case ZAP_SLOWING:
- case ZAP_HASTING:
- case ZAP_PARALYSIS:
- case ZAP_BACKLIGHT:
- case ZAP_SLEEP:
- case ZAP_CONFUSION:
- case ZAP_INVISIBILITY:
- case ZAP_ENSLAVEMENT:
- case ZAP_TELEPORTATION:
- case ZAP_DIGGING:
- case ZAP_POLYMORPH_OTHER:
- case ZAP_DEGENERATION:
- case ZAP_BANISHMENT:
- // This is the only power that matters. We magnify it apparently
- // to get values that work better with magic resistance checks...
- // those checks will scale down this value and max it out at 120.
- pbolt.ench_power *= 3;
- pbolt.ench_power /= 2;
- break;
-
- // anything else we cap to 100
- default:
- if (power > 100)
- power = 100;
- break;
- }
-
- // Note: I'm only displaying the top damage and such here, that's
- // because it's really not been known before (since the above caps
- // didn't exist), so they were all pretty much unlimited before.
- // Also note, that the high end damage occurs at the cap, only
- // players that are that powerful can get that damage... and
- // although these numbers might seem small, you should remember
- // that Dragons in this game are 60-90 hp monsters, and very
- // few monsters have more than 100 hp (and that 1d5 damage is
- // still capable of taking a good sized chunk (and possibly killing)
- // any monster you're likely to meet in the first three levels). -- bwr
-
- // Note: damage > 100 signals that "random2(damage - 100)" will be
- // applied three times, which not only ups the damage but gives
- // a more normal distribution.
- switch (z_type)
- {
- case ZAP_STRIKING: // cap 25
- strcpy(pbolt.beam_name, "force bolt");
- pbolt.colour = BLACK;
- pbolt.range = 8 + random2(5);
- pbolt.damage = dice_def( 1, 5 ); // dam: 5
- pbolt.hit = 8 + power / 10; // 25: 10
- pbolt.type = SYM_SPACE;
- pbolt.flavour = BEAM_MMISSILE; // unresistable
- pbolt.obvious_effect = true;
- break;
-
- case ZAP_MAGIC_DARTS: // cap 25
- strcpy(pbolt.beam_name, "magic dart");
- pbolt.colour = LIGHTMAGENTA;
- pbolt.range = random2(5) + 8;
- pbolt.damage = dice_def( 1, 3 + power / 5 ); // 25: 1d8
- pbolt.hit = 1500; // hits always
- pbolt.type = SYM_ZAP;
- pbolt.flavour = BEAM_MMISSILE; // unresistable
- pbolt.obvious_effect = true;
- break;
-
- case ZAP_STING: // cap 25
- strcpy(pbolt.beam_name, "sting");
- pbolt.colour = GREEN;
- pbolt.range = 8 + random2(5);
- pbolt.damage = dice_def( 1, 3 + power / 5 ); // 25: 1d8
- pbolt.hit = 8 + power / 5; // 25: 13
- pbolt.type = SYM_ZAP;
- pbolt.flavour = BEAM_POISON; // extra damage
-
- pbolt.obvious_effect = true;
- break;
-
- case ZAP_ELECTRICITY: // cap 20
- strcpy(pbolt.beam_name, "zap");
- pbolt.colour = LIGHTCYAN;
- pbolt.range = 6 + random2(8); // extended in beam
- pbolt.damage = dice_def( 1, 3 + random2(power) / 2 ); // 25: 1d11
- pbolt.hit = 8 + power / 7; // 25: 11
- pbolt.type = SYM_ZAP;
- pbolt.flavour = BEAM_ELECTRICITY; // beams & reflects
-
- pbolt.obvious_effect = true;
- pbolt.is_beam = true;
- break;
-
- case ZAP_DISRUPTION: // cap 25
- strcpy(pbolt.beam_name, "0");
- pbolt.flavour = BEAM_DISINTEGRATION;
- pbolt.range = 7 + random2(8);
- pbolt.damage = dice_def( 1, 4 + power / 5 ); // 25: 1d9
- pbolt.ench_power *= 3;
- break;
-
- case ZAP_PAIN: // cap 25
- strcpy(pbolt.beam_name, "0");
- pbolt.flavour = BEAM_PAIN;
- pbolt.range = 7 + random2(8);
- pbolt.damage = dice_def( 1, 4 + power / 5 ); // 25: 1d9
- pbolt.ench_power *= 7;
- pbolt.ench_power /= 2;
- break;
-
- case ZAP_FLAME_TONGUE: // cap 25
- strcpy(pbolt.beam_name, "flame");
- pbolt.colour = RED;
-
- pbolt.range = 1 + random2(2) + random2(power) / 10;
- if (pbolt.range > 4)
- pbolt.range = 4;
-
- pbolt.damage = dice_def( 1, 8 + power / 4 ); // 25: 1d14
- pbolt.hit = 7 + power / 6; // 25: 11
- pbolt.type = SYM_BOLT;
- pbolt.flavour = BEAM_FIRE;
-
- pbolt.obvious_effect = true;
- break;
-
- case ZAP_SMALL_SANDBLAST: // cap 25
- strcpy(pbolt.beam_name, "blast of ");
-
- temp_rand = random2(4);
-
- strcat(pbolt.beam_name, (temp_rand == 0) ? "dust" :
- (temp_rand == 1) ? "dirt" :
- (temp_rand == 2) ? "grit" : "sand");
-
- pbolt.colour = BROWN;
- pbolt.range = (random2(power) > random2(30)) ? 2 : 1;
- pbolt.damage = dice_def( 1, 8 + power / 4 ); // 25: 1d14
- pbolt.hit = 8 + power / 5; // 25: 13
- pbolt.type = SYM_BOLT;
- pbolt.flavour = BEAM_FRAG; // extra AC resist
-
- pbolt.obvious_effect = true;
- break;
-
- case ZAP_SANDBLAST: // cap 50
- strcpy(pbolt.beam_name, coinflip() ? "blast of rock" : "rocky blast");
- pbolt.colour = BROWN;
-
- pbolt.range = 2 + random2(power) / 20;
- if (pbolt.range > 4)
- pbolt.range = 4;
-
- pbolt.damage = dice_def( 2, 4 + power / 3 ); // 25: 2d12
- pbolt.hit = 13 + power / 10; // 25: 15
- pbolt.type = SYM_BOLT;
- pbolt.flavour = BEAM_FRAG; // extra AC resist
-
- pbolt.obvious_effect = true;
- break;
-
- case ZAP_BONE_SHARDS:
- strcpy(pbolt.beam_name, "spray of bone shards");
- pbolt.colour = LIGHTGREY;
- pbolt.range = 7 + random2(10);
-
- // Incoming power is highly dependant on mass (see spells3.cc).
- // Basic function is power * 15 + mass... with the largest
- // available mass (3000) we get a power of 4500 at a power
- // level of 100 (for 3d20).
- pbolt.damage = dice_def( 3, 2 + (power / 250) );
- pbolt.hit = 8 + (power / 100); // max hit: 53
- pbolt.type = SYM_ZAP;
- pbolt.flavour = BEAM_MAGIC; // unresisted
-
- pbolt.obvious_effect = true;
- pbolt.is_beam = true;
- break;
-
- case ZAP_FLAME: // cap 50
- strcpy(pbolt.beam_name, "puff of flame");
- pbolt.colour = RED;
- pbolt.range = 8 + random2(5);
- pbolt.damage = dice_def( 2, 4 + power / 10 ); // 25: 2d6 50: 2d9
- pbolt.hit = 8 + power / 10; // 25: 10 50: 13
- pbolt.type = SYM_ZAP;
- pbolt.flavour = BEAM_FIRE;
-
- pbolt.obvious_effect = true;
- break;
-
- case ZAP_FROST: // cap 50
- strcpy(pbolt.beam_name, "puff of frost");
- pbolt.colour = WHITE;
- pbolt.range = 8 + random2(5);
- pbolt.damage = dice_def( 2, 4 + power / 10 ); // 25: 2d6 50: 2d9
- pbolt.hit = 8 + power / 10; // 50: 10 50: 13
- pbolt.type = SYM_ZAP;
- pbolt.flavour = BEAM_COLD;
-
- pbolt.obvious_effect = true;
- break;
-
- case ZAP_STONE_ARROW: // cap 100
- strcpy(pbolt.beam_name, "stone arrow");
- pbolt.colour = LIGHTGREY;
- pbolt.range = 8 + random2(5);
- pbolt.damage = dice_def( 2, 4 + power / 8 ); // 25: 2d7 50: 2d10
- pbolt.hit = 5 + power / 10; // 25: 6 50: 7
- pbolt.type = SYM_MISSILE;
- pbolt.flavour = BEAM_MMISSILE; // unresistable
-
- pbolt.obvious_effect = true;
- break;
-
- case ZAP_STICKY_FLAME: // cap 100
- strcpy(pbolt.beam_name, "sticky flame"); // extra damage
- pbolt.colour = RED;
- pbolt.range = 8 + random2(5);
- pbolt.damage = dice_def( 2, 3 + power / 12 ); // 50: 2d7 100: 2d11
- pbolt.hit = 11 + power / 10; // 50: 16 100: 21
- pbolt.type = SYM_ZAP;
- pbolt.flavour = BEAM_FIRE;
-
- pbolt.obvious_effect = true;
- break;
-
- case ZAP_MYSTIC_BLAST: // cap 100
- strcpy(pbolt.beam_name, "orb of energy");
- pbolt.colour = LIGHTMAGENTA;
- pbolt.range = 8 + random2(5);
- pbolt.damage = calc_dice( 2, 15 + (power * 2) / 5 );
- pbolt.hit = 10 + power / 7; // 50: 17 100: 24
- pbolt.type = SYM_ZAP;
- pbolt.flavour = BEAM_MMISSILE; // unresistable
-
- pbolt.obvious_effect = true;
- break;
-
- case ZAP_ICE_BOLT: // cap 100
- strcpy(pbolt.beam_name, "bolt of ice");
- pbolt.colour = WHITE;
- pbolt.range = 8 + random2(5);
- pbolt.damage = calc_dice( 3, 10 + power / 2 );
- pbolt.hit = 9 + power / 12; // 50: 13 100: 17
- pbolt.type = SYM_ZAP;
- pbolt.flavour = BEAM_ICE; // half resistable
- break;
-
- case ZAP_DISPEL_UNDEAD: // cap 100
- strcpy(pbolt.beam_name, "0");
- pbolt.flavour = BEAM_DISPEL_UNDEAD;
- pbolt.range = 7 + random2(8);
- pbolt.damage = calc_dice( 3, 20 + (power * 3) / 4 );
- pbolt.ench_power *= 3;
- pbolt.ench_power /= 2;
- break;
-
- case ZAP_MAGMA: // cap 150
- strcpy(pbolt.beam_name, "bolt of magma");
- pbolt.colour = RED;
- pbolt.range = 5 + random2(4);
- pbolt.damage = calc_dice( 4, 10 + (power * 3) / 5 );
- pbolt.hit = 8 + power / 25; // 50: 10 100: 14
- pbolt.type = SYM_ZAP;
- pbolt.flavour = BEAM_LAVA;
-
- pbolt.obvious_effect = true;
- pbolt.is_beam = true;
- break;
-
- case ZAP_FIRE: // cap 150
- strcpy(pbolt.beam_name, "bolt of fire");
- pbolt.colour = RED;
- pbolt.range = 7 + random2(10);
- pbolt.damage = calc_dice( 6, 20 + (power * 3) / 4 );
- pbolt.hit = 10 + power / 25; // 50: 12 100: 14
- pbolt.type = SYM_ZAP;
- pbolt.flavour = BEAM_FIRE;
-
- pbolt.obvious_effect = true;
- pbolt.is_beam = true;
- break;
-
- case ZAP_COLD: // cap 150
- strcpy(pbolt.beam_name, "bolt of cold");
- pbolt.colour = WHITE;
- pbolt.range = 7 + random2(10);
- pbolt.damage = calc_dice( 6, 20 + (power * 3) / 4 );
- pbolt.hit = 10 + power / 25; // 50: 12 100: 14
- pbolt.type = SYM_ZAP;
- pbolt.flavour = BEAM_COLD;
-
- pbolt.obvious_effect = true;
- pbolt.is_beam = true;
- break;
-
- case ZAP_VENOM_BOLT: // cap 150
- strcpy(pbolt.beam_name, "bolt of poison");
- pbolt.colour = LIGHTGREEN;
- pbolt.range = 8 + random2(10);
- pbolt.damage = calc_dice( 4, 15 + power / 2 );
- pbolt.hit = 8 + power / 20; // 50: 10 100: 13
- pbolt.type = SYM_ZAP;
- pbolt.flavour = BEAM_POISON; // extra damage
-
- pbolt.obvious_effect = true;
- pbolt.is_beam = true;
- break;
-
- case ZAP_NEGATIVE_ENERGY: // cap 150
- strcpy(pbolt.beam_name, "bolt of negative energy");
- pbolt.colour = DARKGREY;
- pbolt.range = 7 + random2(10);
- pbolt.damage = calc_dice( 4, 15 + (power * 3) / 5 );
- pbolt.hit = 8 + power / 20; // 50: 10 100: 13
- pbolt.type = SYM_ZAP;
- pbolt.flavour = BEAM_NEG; // drains levels
-
- pbolt.obvious_effect = true;
- pbolt.is_beam = true;
- break;
-
- case ZAP_IRON_BOLT: // cap 150
- strcpy(pbolt.beam_name, "iron bolt");
- pbolt.colour = LIGHTCYAN;
- pbolt.range = 5 + random2(5);
- pbolt.damage = calc_dice( 9, 15 + (power * 3) / 4 );
- pbolt.hit = 7 + power / 15; // 50: 10 100: 13
- pbolt.type = SYM_MISSILE;
- pbolt.flavour = BEAM_MMISSILE; // unresistable
- pbolt.obvious_effect = true;
- break;
-
- case ZAP_POISON_ARROW: // cap 150
- strcpy(pbolt.beam_name, "poison arrow");
- pbolt.colour = LIGHTGREEN;
- pbolt.range = 8 + random2(5);
- pbolt.damage = calc_dice( 4, 15 + power );
- pbolt.hit = 5 + power / 10; // 50: 10 100: 15
- pbolt.type = SYM_MISSILE;
- pbolt.flavour = BEAM_POISON_ARROW; // extra damage
- pbolt.obvious_effect = true;
- break;
-
-
- case ZAP_DISINTEGRATION: // cap 150
- strcpy(pbolt.beam_name, "0");
- pbolt.flavour = BEAM_DISINTEGRATION;
- pbolt.range = 7 + random2(8);
- pbolt.damage = calc_dice( 3, 15 + (power * 3) / 4 );
- pbolt.ench_power *= 5;
- pbolt.ench_power /= 2;
- pbolt.is_beam = true;
- break;
-
- case ZAP_LIGHTNING: // cap 150
- // also for breath (at pow = lev * 2; max dam: 33)
- strcpy(pbolt.beam_name, "bolt of lightning");
- pbolt.colour = LIGHTCYAN;
- pbolt.range = 8 + random2(10); // extended in beam
- pbolt.damage = calc_dice( 1, 10 + (power * 3) / 5 );
- pbolt.hit = 7 + random2(power) / 20; // 50: 7-9 100: 7-12
- pbolt.type = SYM_ZAP;
- pbolt.flavour = BEAM_ELECTRICITY; // beams & reflects
-
- pbolt.obvious_effect = true;
- pbolt.is_beam = true;
- break;
-
- case ZAP_FIREBALL: // cap 150
- strcpy(pbolt.beam_name, "fireball");
- pbolt.colour = RED;
- pbolt.range = 8 + random2(5);
- pbolt.damage = calc_dice( 3, 10 + power / 2 );
- pbolt.hit = 40; // hit: 40
- pbolt.type = SYM_ZAP;
- pbolt.flavour = BEAM_FIRE; // fire
- pbolt.is_explosion = true;
- break;
-
- case ZAP_ORB_OF_ELECTRICITY: // cap 150
- strcpy(pbolt.beam_name, "orb of electricity");
- pbolt.colour = LIGHTBLUE;
- pbolt.range = 9 + random2(12);
- pbolt.damage = calc_dice( 1, 15 + (power * 4) / 5 );
- pbolt.damage.num = 0; // only does explosion damage
- pbolt.hit = 40; // hit: 40
- pbolt.type = SYM_ZAP;
- pbolt.flavour = BEAM_ELECTRICITY;
- pbolt.is_explosion = true;
- break;
-
- case ZAP_ORB_OF_FRAGMENTATION: // cap 150
- strcpy(pbolt.beam_name, "metal orb");
- pbolt.colour = CYAN;
- pbolt.range = 9 + random2(7);
- pbolt.damage = calc_dice( 3, 30 + (power * 3) / 4 );
- pbolt.hit = 20; // hit: 20
- pbolt.type = SYM_ZAP;
- pbolt.flavour = BEAM_FRAG; // extra AC resist
- pbolt.is_explosion = true;
- break;
-
- case ZAP_CLEANSING_FLAME:
- strcpy(pbolt.beam_name, "golden flame");
- pbolt.colour = YELLOW;
- pbolt.range = 7;
- pbolt.damage = calc_dice( 3, 30 + (power * 3) / 4 );
- pbolt.hit = 150;
- pbolt.type = SYM_ZAP;
- pbolt.flavour = BEAM_HOLY;
-
- pbolt.obvious_effect = true;
- pbolt.is_explosion = true;
- break;
-
- case ZAP_CRYSTAL_SPEAR: // cap 200
- strcpy(pbolt.beam_name, "crystal spear");
- pbolt.colour = WHITE;
- pbolt.range = 7 + random2(10);
- pbolt.damage = calc_dice( 12, 30 + (power * 4) / 3 );
- pbolt.hit = 10 + power / 15; // 50: 13 100: 16
- pbolt.type = SYM_MISSILE;
- pbolt.flavour = BEAM_MMISSILE; // unresistable
-
- pbolt.obvious_effect = true;
- break;
-
- case ZAP_HELLFIRE: // cap 200
- strcpy(pbolt.beam_name, "hellfire");
- pbolt.colour = RED;
- pbolt.range = 7 + random2(10);
- pbolt.damage = calc_dice( 3, 10 + (power * 3) / 4 );
- pbolt.hit = 20 + power / 10; // 50: 25 100: 30
- pbolt.type = SYM_ZAP;
- pbolt.flavour = BEAM_HELLFIRE;
-
- pbolt.obvious_effect = true;
- pbolt.is_explosion = true;
- break;
-
- case ZAP_ICE_STORM: // cap 200
- strcpy(pbolt.beam_name, "great blast of cold");
- pbolt.colour = BLUE;
- pbolt.range = 9 + random2(5);
- pbolt.damage = calc_dice( 6, 15 + power );
- pbolt.damage.num = 0; // only does explosion damage
- pbolt.hit = 20 + power / 10; // 50: 25 100: 30
- pbolt.ench_power = power; // used for radius
- pbolt.type = SYM_ZAP;
- pbolt.flavour = BEAM_ICE; // half resisted
- pbolt.is_explosion = true;
- break;
-
- case ZAP_BEAM_OF_ENERGY: // bolt of innacuracy
- strcpy(pbolt.beam_name, "narrow beam of energy");
- pbolt.colour = YELLOW;
- pbolt.range = 7 + random2(10);
- pbolt.damage = calc_dice( 12, 40 + (power * 3) / 2 );
- pbolt.hit = 2; // hit: 2 (very hard)
- pbolt.type = SYM_ZAP;
- pbolt.flavour = BEAM_ENERGY; // unresisted
-
- pbolt.obvious_effect = true;
- pbolt.is_beam = true;
- break;
-
- case ZAP_SPIT_POISON: // cap 50
- // max pow = lev + mut * 5 = 42
- strcpy(pbolt.beam_name, "splash of poison");
- pbolt.colour = GREEN;
-
- pbolt.range = 3 + random2( 1 + power / 2 );
- if (pbolt.range > 9)
- pbolt.range = 9;
-
- pbolt.damage = dice_def( 1, 4 + power / 2 ); // max dam: 25
- pbolt.hit = 5 + random2( 1 + power / 3 ); // max hit: 19
- pbolt.type = SYM_ZAP;
- pbolt.flavour = BEAM_POISON;
- pbolt.obvious_effect = true;
- break;
-
- case ZAP_BREATHE_FIRE: // cap 50
- // max pow = lev + mut * 4 + 12 = 51 (capped to 50)
- strcpy(pbolt.beam_name, "fiery breath");
- pbolt.colour = RED;
-
- pbolt.range = 3 + random2( 1 + power / 2 );
- if (pbolt.range > 9)
- pbolt.range = 9;
-
- pbolt.damage = dice_def( 3, 4 + power / 3 ); // max dam: 60
- pbolt.hit = 8 + random2( 1 + power / 3 ); // max hit: 25
- pbolt.type = SYM_ZAP;
- pbolt.flavour = BEAM_FIRE;
-
- pbolt.obvious_effect = true;
- pbolt.is_beam = true;
- break;
-
- case ZAP_BREATHE_FROST: // cap 50
- // max power = lev = 27
- strcpy(pbolt.beam_name, "freezing breath");
- pbolt.colour = WHITE;
-
- pbolt.range = 3 + random2( 1 + power / 2 );
- if (pbolt.range > 9)
- pbolt.range = 9;
-
- pbolt.damage = dice_def( 3, 4 + power / 3 ); // max dam: 39
- pbolt.hit = 8 + random2( 1 + power / 3 );
- pbolt.type = SYM_ZAP;
- pbolt.flavour = BEAM_COLD;
-
- pbolt.obvious_effect = true;
- pbolt.is_beam = true;
- break;
-
- case ZAP_BREATHE_ACID: // cap 50
- // max power = lev for ability, 50 for minor destruction (max dam: 57)
- strcpy(pbolt.beam_name, "acid");
- pbolt.colour = YELLOW;
-
- pbolt.range = 3 + random2( 1 + power / 2 );
- if (pbolt.range > 9)
- pbolt.range = 9;
-
- pbolt.damage = dice_def( 3, 3 + power / 3 ); // max dam: 36
- pbolt.hit = 5 + random2( 1 + power / 3 );
- pbolt.type = SYM_ZAP;
- pbolt.flavour = BEAM_ACID;
-
- pbolt.obvious_effect = true;
- pbolt.is_beam = true;
- break;
-
- case ZAP_BREATHE_POISON: // leaves clouds of gas // cap 50
- // max power = lev = 27
- strcpy(pbolt.beam_name, "poison gas");
- pbolt.colour = GREEN;
-
- pbolt.range = 3 + random2( 1 + power / 2 );
- if (pbolt.range > 9)
- pbolt.range = 9;
-
- pbolt.damage = dice_def( 3, 2 + power / 6 ); // max dam: 18
- pbolt.hit = 6 + random2( 1 + power / 3 );
- pbolt.type = SYM_ZAP;
- pbolt.flavour = BEAM_POISON;
-
- pbolt.obvious_effect = true;
- pbolt.is_beam = true;
- break;
-
- case ZAP_BREATHE_POWER: // cap 50
- strcpy(pbolt.beam_name, "bolt of energy");
- // max power = lev = 27
-
- pbolt.colour = BLUE;
- if (random2(power) >= 8)
- pbolt.colour = LIGHTBLUE;
- if (random2(power) >= 12)
- pbolt.colour = MAGENTA;
- if (random2(power) >= 17)
- pbolt.colour = LIGHTMAGENTA;
-
- pbolt.range = 6 + random2( 1 + power / 2 );
- if (pbolt.range > 9)
- pbolt.range = 9;
-
- pbolt.damage = dice_def( 3, 3 + power / 3 ); // max dam: 36
- pbolt.hit = 5 + random2( 1 + power / 3 );
- pbolt.type = SYM_ZAP;
- pbolt.flavour = BEAM_MMISSILE; // unresistable
-
- pbolt.obvious_effect = true;
- pbolt.is_beam = true;
- break;
-
- case ZAP_BREATHE_STEAM: // cap 50
- // max power = lev = 27
- strcpy(pbolt.beam_name, "ball of steam");
- pbolt.colour = LIGHTGREY;
-
- pbolt.range = 6 + random2(5);
- if (pbolt.range > 9)
- pbolt.range = 9;
-
- pbolt.damage = dice_def( 3, 4 + power / 5 ); // max dam: 27
- pbolt.hit = 10 + random2( 1 + power / 5 );
- pbolt.type = SYM_ZAP;
- pbolt.flavour = BEAM_FIRE;
-
- pbolt.obvious_effect = true;
- pbolt.is_beam = true;
- break;
-
- case ZAP_SLOWING:
- strcpy(pbolt.beam_name, "0");
- pbolt.flavour = BEAM_SLOW;
- // pbolt.is_beam = true;
- break;
-
- case ZAP_HASTING:
- strcpy(pbolt.beam_name, "0");
- pbolt.flavour = BEAM_HASTE;
- // pbolt.is_beam = true;
- break;
-
- case ZAP_PARALYSIS:
- strcpy(pbolt.beam_name, "0");
- pbolt.flavour = BEAM_PARALYSIS;
- // pbolt.is_beam = true;
- break;
-
- case ZAP_CONFUSION:
- strcpy(pbolt.beam_name, "0");
- pbolt.flavour = BEAM_CONFUSION;
- // pbolt.is_beam = true;
- break;
-
- case ZAP_INVISIBILITY:
- strcpy(pbolt.beam_name, "0");
- pbolt.flavour = BEAM_INVISIBILITY;
- // pbolt.is_beam = true;
- break;
-
- case ZAP_HEALING:
- strcpy(pbolt.beam_name, "0");
- pbolt.flavour = BEAM_HEALING;
- pbolt.damage = dice_def( 1, 7 + power / 3 );
- // pbolt.is_beam = true;
- break;
-
- case ZAP_DIGGING:
- strcpy(pbolt.beam_name, "0");
- pbolt.flavour = BEAM_DIGGING;
- // not ordinary "0" beam range {dlb}
- pbolt.range = 3 + random2( power / 5 ) + random2(5);
- pbolt.is_beam = true;
- break;
-
- case ZAP_TELEPORTATION:
- strcpy(pbolt.beam_name, "0");
- pbolt.flavour = BEAM_TELEPORT;
- pbolt.range = 9 + random2(5);
- // pbolt.is_beam = true;
- break;
-
- case ZAP_POLYMORPH_OTHER:
- strcpy(pbolt.beam_name, "0");
- pbolt.flavour = BEAM_POLYMORPH;
- pbolt.range = 9 + random2(5);
- // pbolt.is_beam = true;
- break;
-
- case ZAP_ENSLAVEMENT:
- strcpy(pbolt.beam_name, "0");
- pbolt.flavour = BEAM_CHARM;
- pbolt.range = 7 + random2(5);
- // pbolt.is_beam = true;
- break;
-
- case ZAP_BANISHMENT:
- strcpy(pbolt.beam_name, "0");
- pbolt.flavour = BEAM_BANISH;
- pbolt.range = 7 + random2(5);
- // pbolt.is_beam = true;
- break;
-
- case ZAP_DEGENERATION:
- strcpy(pbolt.beam_name, "0");
- pbolt.flavour = BEAM_DEGENERATE;
- pbolt.range = 7 + random2(5);
- // pbolt.is_beam = true;
- break;
-
- case ZAP_ENSLAVE_UNDEAD:
- strcpy(pbolt.beam_name, "0");
- pbolt.flavour = BEAM_ENSLAVE_UNDEAD;
- pbolt.range = 7 + random2(5);
- // pbolt.is_beam = true;
- break;
-
- case ZAP_AGONY:
- strcpy(pbolt.beam_name, "0agony");
- pbolt.flavour = BEAM_PAIN;
- pbolt.range = 7 + random2(8);
- pbolt.ench_power *= 5;
- // pbolt.is_beam = true;
- break;
-
- case ZAP_CONTROL_DEMON:
- strcpy(pbolt.beam_name, "0");
- pbolt.flavour = BEAM_ENSLAVE_DEMON;
- pbolt.range = 7 + random2(5);
- pbolt.ench_power *= 3;
- pbolt.ench_power /= 2;
- // pbolt.is_beam = true;
- break;
-
- case ZAP_SLEEP: //jmf: added
- strcpy(pbolt.beam_name, "0");
- pbolt.flavour = BEAM_SLEEP;
- pbolt.range = 7 + random2(5);
- // pbolt.is_beam = true;
- break;
-
- case ZAP_BACKLIGHT: //jmf: added
- strcpy(pbolt.beam_name, "0");
- pbolt.flavour = BEAM_BACKLIGHT;
- pbolt.colour = BLUE;
- pbolt.range = 7 + random2(5);
- // pbolt.is_beam = true;
- break;
-
- case ZAP_DEBUGGING_RAY:
- strcpy( pbolt.beam_name, "debugging ray" );
- pbolt.colour = random_colour();
- pbolt.range = 7 + random2(10);
- pbolt.damage = dice_def( 1500, 1 ); // dam: 1500
- pbolt.hit = 1500; // hit: 1500
- pbolt.type = SYM_DEBUG;
- pbolt.flavour = BEAM_MMISSILE; // unresistable
-
- pbolt.obvious_effect = true;
- break;
-
- default:
- strcpy(pbolt.beam_name, "buggy beam");
- pbolt.colour = random_colour();
- pbolt.range = 7 + random2(10);
- pbolt.damage = dice_def( 1, 0 );
- pbolt.hit = 60;
- pbolt.type = SYM_DEBUG;
- pbolt.flavour = BEAM_MMISSILE; // unresistable
-
- pbolt.obvious_effect = true;
- break;
- } // end of switch
-} // end zappy()
-
-/* NEW (GDL):
- * Now handles all beamed/thrown items and spells, tracers, and their effects.
- * item is used for items actually thrown/launched
- *
- * if item is NULL, there is no physical object being thrown that could
- * land on the ground.
- */
-
-
-/*
- * Beam pseudo code:
- *
- * 1. Calculate stepx and stepy - algorithms depend on finding a step axis
- * which results in a line of rise 1 or less (ie 45 degrees or less)
- * 2. Calculate range. Tracers always have max range, otherwise the beam
- * will have somewhere between range and rangeMax
- * 3. Loop tracing out the line:
- * 3a. Check for walls and wall affecting beams
- * 3b. If no valid move is found, try a fuzzy move
- * 3c. If no valid move is yet found, try bouncing
- * 3d. If no valid move or bounce is found, break
- * 4. Check for beam termination on target
- * 5. Affect the cell which the beam just moved into -> affect()
- * 6. Decrease remaining range appropriately
- * 7. Check for early out due to aimed_at_feet
- * 8. Draw the beam
- * 9. Drop an object where the beam 'landed'
- *10. Beams explode where the beam 'landed'
- *11. If no message generated yet, send "nothing happens" (enchantments only)
- *
- */
-
-
-void fire_beam( struct bolt &pbolt, item_def *item )
-{
- int dx, dy; // total delta between source & target
- int lx, ly; // last affected x,y
- int stepx, stepy; // x,y increment - FP
- int wx, wy; // 'working' x,y - FP
- bool beamTerminate; // has beam been 'stopped' by something?
- int nx, ny; // test(new) x,y - FP
- int tx, ty; // test(new) x,y - integer
- bool roundX, roundY; // which to round?
- int rangeRemaining;
- bool fuzzyOK; // fuzzification resulted in OK move
- bool sideBlocked, topBlocked, random_beam;
-
-#if DEBUG_DIAGNOSTICS
- if (pbolt.flavour != BEAM_LINE_OF_SIGHT)
- {
- mprf( MSGCH_DIAGNOSTICS,
- "%s%s%s (%d,%d) to (%d,%d): ty=%d col=%d flav=%d hit=%d dam=%dd%d",
- (pbolt.is_beam) ? "beam" : "missile",
- (pbolt.is_explosion) ? "*" :
- (pbolt.is_big_cloud) ? "+" : "",
- (pbolt.is_tracer) ? " tracer" : "",
- pbolt.source_x, pbolt.source_y,
- pbolt.target_x, pbolt.target_y,
- pbolt.type, pbolt.colour, pbolt.flavour,
- pbolt.hit, pbolt.damage.num, pbolt.damage.size );
- }
-#endif
-
- // init
- pbolt.aimed_at_feet = false;
- pbolt.msg_generated = false;
- roundY = false;
- roundX = false;
-
- // first, calculate beam step
- dx = pbolt.target_x - pbolt.source_x;
- dy = pbolt.target_y - pbolt.source_y;
-
- // check for aim at feet
- if (dx == 0 && dy == 0)
- {
- pbolt.aimed_at_feet = true;
- stepx = 0;
- stepy = 0;
- tx = pbolt.source_x;
- ty = pbolt.source_y;
- }
- else
- {
- if (abs(dx) >= abs(dy))
- {
- stepx = (dx > 0) ? 100 : -100;
- stepy = 100 * dy / (abs(dx));
- roundY = true;
- }
- else
- {
- stepy = (dy > 0) ? 100 : -100;
- stepx = 100 * dx / (abs(dy));
- roundX = true;
- }
- }
-
- // give chance for beam to affect one cell even if aimed_at_feet.
- beamTerminate = false;
- // setup working coords
- lx = pbolt.source_x;
- wx = 100 * lx;
- ly = pbolt.source_y;
- wy = 100 * ly;
- // setup range
- rangeRemaining = pbolt.range;
- if (pbolt.rangeMax > pbolt.range)
- {
- if (pbolt.is_tracer)
- rangeRemaining = pbolt.rangeMax;
- else
- rangeRemaining += random2((pbolt.rangeMax - pbolt.range) + 1);
- }
-
- // before we start drawing the beam, turn buffering off
-#ifdef WIN32CONSOLE
- bool oldValue = true;
- if (!pbolt.is_tracer)
- oldValue = setBuffering(false);
-#endif
-
- // cannot use source_x, source_y, target_x, target_y during
- // step algorithm due to bouncing.
-
- // now, one step at a time, try to move towards target.
- while(!beamTerminate)
- {
- nx = wx + stepx;
- ny = wy + stepy;
-
- if (roundY)
- {
- tx = nx / 100;
- ty = (ny + 50) / 100;
- }
- if (roundX)
- {
- ty = ny / 100;
- tx = (nx + 50) / 100;
- }
-
- // check that tx, ty are valid. If not, set to last
- // x,y and break.
- if (tx < 0 || tx >= GXM || ty < 0 || ty >= GYM)
- {
- tx = lx;
- ty = ly;
- break;
- }
-
- // see if tx, ty is blocked by something
- if (grd[tx][ty] < MINMOVE)
- {
- // first, check to see if this beam affects walls.
- if (affectsWalls(pbolt))
- {
- // should we ever get a tracer with a wall-affecting
- // beam (possible I suppose), we'll quit tracing now.
- if (!pbolt.is_tracer)
- rangeRemaining -= affect(pbolt, tx, ty);
-
- // if it's still a wall, quit.
- if (grd[tx][ty] < MINMOVE)
- {
- break; // breaks from line tracing
- }
- }
- else
- {
- // BEGIN fuzzy line algorithm
- fuzzyOK = fuzzyLine(nx,ny,tx,ty,lx,ly,stepx,stepy,roundX,roundY);
- if (!fuzzyOK)
- {
- // BEGIN bounce case
- if (!isBouncy(pbolt))
- {
- tx = lx;
- ty = ly;
- break; // breaks from line tracing
- }
-
- sideBlocked = false;
- topBlocked = false;
- // BOUNCE -- guaranteed to return reasonable tx, ty.
- // if it doesn't, we'll quit in the next if stmt anyway.
- if (roundY)
- {
- if ( grd[lx + stepx / 100][ly] < MINMOVE)
- sideBlocked = true;
-
- if (dy != 0)
- {
- if ( grd[lx][ly + (stepy>0?1:-1)] < MINMOVE)
- topBlocked = true;
- }
-
- rangeRemaining -= bounce(stepx, stepy, wx, wy, nx, ny,
- lx, ly, tx, ty, topBlocked, sideBlocked);
- }
- else
- {
- if ( grd[lx][ly + stepy / 100] < MINMOVE)
- sideBlocked = true;
-
- if (dx != 0)
- {
- if ( grd[lx + (stepx>0?1:-1)][ly] < MINMOVE)
- topBlocked = true;
- }
-
- rangeRemaining -= bounce(stepy, stepx, wy, wx, ny, nx,
- ly, lx, ty, tx, topBlocked, sideBlocked);
- }
- // END bounce case - range check
- if (rangeRemaining < 1)
- {
- tx = lx;
- ty = ly;
- break;
- }
- }
- } // end else - beam doesn't affect walls
- } // endif - is tx, ty wall?
-
- // at this point, if grd[tx][ty] is still a wall, we
- // couldn't find any path: bouncy, fuzzy, or not - so break.
- if (grd[tx][ty] < MINMOVE)
- {
- tx = lx;
- ty = ly;
- break;
- }
-
- // check for "target termination"
- // occurs when beam can be targetted at empty
- // cell (e.g. a mage wants an explosion to happen
- // between two monsters)
-
- // in this case, don't affect the cell - players
- // /monsters have no chance to dodge or block such
- // a beam, and we want to avoid silly messages.
- if (tx == pbolt.target_x && ty == pbolt.target_y)
- beamTerminate = beam_term_on_target(pbolt);
-
- // affect the cell, except in the special case noted
- // above -- affect() will early out if something gets
- // hit and the beam is type 'term on target'.
- if (!beamTerminate || !pbolt.is_explosion)
- {
- // random beams: randomize before affect
- random_beam = false;
- if (pbolt.flavour == BEAM_RANDOM)
- {
- random_beam = true;
- pbolt.flavour = BEAM_FIRE + random2(7);
- }
-
- rangeRemaining -= affect(pbolt, tx, ty);
-
- if (random_beam)
- pbolt.flavour = BEAM_RANDOM;
- }
-
- // always decrease range by 1
- rangeRemaining -= 1;
-
- // check for range termination
- if (rangeRemaining <= 0)
- beamTerminate = true;
-
- // special case - beam was aimed at feet
- if (pbolt.aimed_at_feet)
- beamTerminate = true;
-
- // actually draw the beam/missile/whatever,
- // if the player can see the cell.
- if (!pbolt.is_tracer && pbolt.beam_name[0] != '0' && see_grid(tx,ty))
- {
- // we don't clean up the old position.
- // first, most people like seeing the full path,
- // and second, it is hard to do it right with
- // respect to killed monsters, cloud trails, etc.
-
- // draw new position
- int drawx = tx - you.x_pos + 18;
- int drawy = ty - you.y_pos + 9;
- // bounds check
- if (drawx > 8 && drawx < 26 && drawy > 0 && drawy < 18)
- {
- if (pbolt.colour == BLACK)
- textcolor(random_colour());
- else
- textcolor(pbolt.colour);
-
- gotoxy(drawx, drawy);
- putch(pbolt.type);
-
-#ifdef UNIX
- // get curses to update the screen so we can see the beam
- update_screen();
-#endif
-
- delay(15);
-
-#ifdef MISSILE_TRAILS_OFF
- if (!pbolt.is_beam || pbolt.beam_name[0] == '0')
- viewwindow(1,false); // mv: added. It's not optimal but
- // is usually enough
-#endif
- }
-
- }
-
- // set some stuff up for the next iteration
- lx = tx;
- ly = ty;
-
- wx = nx;
- wy = ny;
-
- } // end- while !beamTerminate
-
- // the beam has finished, and terminated at tx, ty
-
- // leave an object, if applicable
- if (item)
- beam_drop_object( pbolt, item, tx, ty );
-
- // check for explosion. NOTE that for tracers, we have to make a copy
- // of target co'ords and then reset after calling this -- tracers should
- // never change any non-tracers fields in the beam structure. -- GDL
- int ox = pbolt.target_x;
- int oy = pbolt.target_y;
-
- beam_explodes(pbolt, tx, ty);
-
- if (pbolt.is_tracer)
- {
- pbolt.target_x = ox;
- pbolt.target_y = oy;
- }
-
- // canned msg for enchantments that affected no-one
- if (pbolt.beam_name[0] == '0' && pbolt.flavour != BEAM_DIGGING)
- {
- if (!pbolt.is_tracer && !pbolt.msg_generated && !pbolt.obvious_effect)
- canned_msg(MSG_NOTHING_HAPPENS);
- }
-
- // that's it!
-#ifdef WIN32CONSOLE
- if (!pbolt.is_tracer)
- setBuffering(oldValue);
-#endif
-} // end fire_beam();
-
-
-// returns damage taken by a monster from a "flavoured" (fire, ice, etc.)
-// attack -- damage from clouds and branded weapons handled elsewhere.
-int mons_adjust_flavoured( struct monsters *monster, struct bolt &pbolt,
- int hurted, bool doFlavouredEffects )
-{
- // if we're not doing flavored effects, must be preliminary
- // damage check only; do not print messages or apply any side
- // effects!
- int resist;
-
- switch (pbolt.flavour)
- {
- case BEAM_FIRE:
- resist = mons_res_fire(monster);
- if (resist > 1)
- {
- if (doFlavouredEffects)
- simple_monster_message(monster, " appears unharmed.");
-
- hurted = 0;
- }
- else if (resist == 1)
- {
- if (doFlavouredEffects)
- simple_monster_message(monster, " resists.");
-
- hurted /= 3;
- }
- else if (resist < 0)
- {
- if (monster->type == MONS_ICE_BEAST
- || monster->type == MONS_SIMULACRUM_SMALL
- || monster->type == MONS_SIMULACRUM_LARGE)
- {
- if (doFlavouredEffects)
- simple_monster_message(monster, " melts!");
- }
- else
- {
- if (doFlavouredEffects)
- simple_monster_message(monster, " is burned terribly!");
- }
-
- hurted *= 15;
- hurted /= 10;
- }
- break;
-
-
- case BEAM_COLD:
- resist = mons_res_cold(monster);
- if (resist > 1)
- {
- if (doFlavouredEffects)
- simple_monster_message(monster, " appears unharmed.");
-
- hurted = 0;
- }
- else if (resist == 1)
- {
- if (doFlavouredEffects)
- simple_monster_message(monster, " resists.");
-
- hurted /= 3;
- }
- else if (resist < 0)
- {
- if (doFlavouredEffects)
- simple_monster_message(monster, " is frozen!");
-
- hurted *= 15;
- hurted /= 10;
- }
- break;
-
- case BEAM_ELECTRICITY:
- if (mons_res_elec(monster) > 0)
- {
- if (doFlavouredEffects)
- simple_monster_message(monster, " appears unharmed.");
-
- hurted = 0;
- }
- break;
-
-
- case BEAM_POISON:
- if (mons_res_poison(monster) > 0)
- {
- if (doFlavouredEffects)
- simple_monster_message( monster, " appears unharmed." );
-
- hurted = 0;
- }
- else if (doFlavouredEffects && !one_chance_in(3))
- {
- poison_monster( monster, YOU_KILL(pbolt.thrower) );
- }
- break;
-
- case BEAM_POISON_ARROW:
- if (mons_res_poison(monster) > 0)
- {
- if (doFlavouredEffects)
- {
- simple_monster_message( monster, " partially resists." );
-
- // Poison arrow can poison any living thing regardless of
- // poison resistance. -- bwr
- if (mons_has_lifeforce(monster))
- poison_monster( monster, YOU_KILL(pbolt.thrower), 2, true );
- }
-
- hurted /= 2;
- }
- else if (doFlavouredEffects)
- {
- poison_monster( monster, YOU_KILL(pbolt.thrower), 4 );
- }
- break;
-
- case BEAM_NEG:
- if (mons_res_negative_energy(monster) > 0)
- {
- if (doFlavouredEffects)
- simple_monster_message(monster, " appears unharmed.");
-
- hurted = 0;
- }
- else
- {
- // early out for tracer/no side effects
- if (!doFlavouredEffects)
- return (hurted);
-
- simple_monster_message(monster, " is drained.");
-
- if (one_chance_in(5))
- monster->hit_dice--;
-
- monster->max_hit_points -= 2 + random2(3);
- monster->hit_points -= 2 + random2(3);
-
- if (monster->hit_points >= monster->max_hit_points)
- monster->hit_points = monster->max_hit_points;
-
- if (monster->hit_dice < 1)
- monster->hit_points = 0;
- } // end else
- break;
-
- case BEAM_MIASMA:
- if (mons_res_negative_energy( monster ) >= 3)
- {
- if (doFlavouredEffects)
- simple_monster_message(monster, " appears unharmed.");
-
- hurted = 0;
- }
- else
- {
- // early out for tracer/no side effects
- if (!doFlavouredEffects)
- return (hurted);
-
- if (mons_res_poison( monster ) <= 0)
- poison_monster( monster, YOU_KILL(pbolt.thrower) );
-
- if (one_chance_in( 3 + 2 * mons_res_negative_energy(monster) ))
- {
- struct bolt beam;
- beam.flavour = BEAM_SLOW;
- mons_ench_f2( monster, beam );
- }
- }
- break;
-
- case BEAM_HOLY: // flame of cleansing
- if (mons_is_unholy( monster ))
- {
- if (doFlavouredEffects)
- simple_monster_message( monster, " writhes in agony!" );
-
- hurted = (hurted * 3) / 2;
- }
- else if (!mons_is_evil( monster ))
- {
- if (doFlavouredEffects)
- simple_monster_message( monster, " appears unharmed." );
-
- hurted = 0;
- }
- break;
-
- case BEAM_ICE:
- /* ice - about 50% of damage is cold, other 50% is impact and
- can't be resisted (except by AC, of course) */
- resist = mons_res_cold(monster);
- if (resist > 0)
- {
- if (doFlavouredEffects)
- simple_monster_message(monster, " partially resists.");
-
- hurted /= 2;
- }
- else if (resist < 0)
- {
- if (doFlavouredEffects)
- simple_monster_message(monster, " is frozen!");
-
- hurted *= 13;
- hurted /= 10;
- }
- break;
- } /* end of switch */
-
- if (pbolt.flavour == BEAM_LAVA) //jmf: lava != hellfire
- {
- resist = mons_res_fire(monster);
- if (resist > 0)
- {
- if (doFlavouredEffects)
- simple_monster_message(monster, " partially resists.");
-
- hurted /= 2;
- }
- else if (resist < 0)
- {
- if (monster->type == MONS_ICE_BEAST
- || monster->type == MONS_SIMULACRUM_SMALL
- || monster->type == MONS_SIMULACRUM_LARGE)
- {
- if (doFlavouredEffects)
- simple_monster_message(monster, " melts!");
- }
- else
- {
- if (doFlavouredEffects)
- simple_monster_message(monster, " is burned terribly!");
- }
-
- hurted *= 12;
- hurted /= 10;
- }
- }
- else if (stricmp(pbolt.beam_name, "hellfire") == 0)
- {
- resist = mons_res_fire(monster);
- if (resist > 2)
- {
- if (doFlavouredEffects)
- simple_monster_message(monster, " appears unharmed.");
-
- hurted = 0;
- }
- else if (resist > 0)
- {
- if (doFlavouredEffects)
- simple_monster_message(monster, " partially resists.");
-
- hurted /= 2;
- }
- else if (resist < 0)
- {
- if (monster->type == MONS_ICE_BEAST
- || monster->type == MONS_SIMULACRUM_SMALL
- || monster->type == MONS_SIMULACRUM_LARGE)
- {
- if (doFlavouredEffects)
- simple_monster_message(monster, " melts!");
- }
- else
- {
- if (doFlavouredEffects)
- simple_monster_message(monster, " is burned terribly!");
- }
-
- hurted *= 12; /* hellfire */
- hurted /= 10;
- }
- }
-
- return (hurted);
-} // end mons_adjust_flavoured()
-
-
-// Enchants all monsters in player's sight.
-bool mass_enchantment( int wh_enchant, int pow, int origin )
-{
- int i; // loop variable {dlb}
- bool msg_generated = false;
- struct monsters *monster;
-
- viewwindow(0, false);
-
- if (pow > 200)
- pow = 200;
-
- for (i = 0; i < MAX_MONSTERS; i++)
- {
- monster = &menv[i];
-
- if (monster->type == -1 || !mons_near(monster))
- continue;
-
- // assuming that the only mass charm is control undead:
- if (wh_enchant == ENCH_CHARM)
- {
- if (mons_friendly(monster))
- continue;
-
- if (mons_class_holiness(monster->type) != MH_UNDEAD)
- continue;
-
- if (check_mons_resist_magic( monster, pow ))
- {
- simple_monster_message(monster, " resists.");
- continue;
- }
- }
- else if (mons_holiness(monster) == MH_NATURAL)
- {
- if (check_mons_resist_magic( monster, pow ))
- {
- simple_monster_message(monster, " resists.");
- continue;
- }
- }
- else // trying to enchant an unnatural creature doesn't work
- {
- simple_monster_message(monster, " is unaffected.");
- continue;
- }
-
- if (mons_has_ench(monster, wh_enchant))
- continue;
-
- if (mons_add_ench(monster, wh_enchant))
- {
- if (player_monster_visible( monster ))
- {
- // turn message on
- msg_generated = true;
- switch (wh_enchant)
- {
- case ENCH_FEAR:
- simple_monster_message(monster,
- " looks frightened!");
- break;
- case ENCH_CONFUSION:
- simple_monster_message(monster,
- " looks rather confused.");
- break;
- case ENCH_CHARM:
- simple_monster_message(monster,
- " submits to your will.");
- break;
- default:
- // oops, I guess not!
- msg_generated = false;
- }
- }
-
- // extra check for fear (monster needs to reevaluate behaviour)
- if (wh_enchant == ENCH_FEAR)
- behaviour_event( monster, ME_SCARE, origin );
- }
- } // end "for i"
-
- if (!msg_generated)
- canned_msg(MSG_NOTHING_HAPPENS);
-
- return (msg_generated);
-} // end mass_enchantmenet()
-
-/*
- Monster has probably failed save, now it gets enchanted somehow.
-
- returns MON_RESIST if monster is unaffected due to magic resist.
- returns MON_UNAFFECTED if monster is immune to enchantment
- returns MON_AFFECTED in all other cases (already enchanted, etc)
- */
-int mons_ench_f2(struct monsters *monster, struct bolt &pbolt)
-{
- bool is_near = mons_near(monster); // single caluclation permissible {dlb}
- char buff[ ITEMNAME_SIZE ];
-
- switch (pbolt.flavour) /* put in magic resistance */
- {
- case BEAM_SLOW: /* 0 = slow monster */
- // try to remove haste, if monster is hasted
- if (mons_del_ench(monster, ENCH_HASTE))
- {
- if (simple_monster_message(monster, " is no longer moving quickly."))
- pbolt.obvious_effect = true;
-
- return (MON_AFFECTED);
- }
-
- // not hasted, slow it
- if (mons_add_ench(monster, ENCH_SLOW))
- {
- // put in an exception for fungi, plants and other things you won't
- // notice slow down.
- if (simple_monster_message(monster, " seems to slow down."))
- pbolt.obvious_effect = true;
- }
- return (MON_AFFECTED);
-
- case BEAM_HASTE: // 1 = haste
- if (mons_del_ench(monster, ENCH_SLOW))
- {
- if (simple_monster_message(monster, " is no longer moving slowly."))
- pbolt.obvious_effect = true;
-
- return (MON_AFFECTED);
- }
-
- // not slowed, haste it
- if (mons_add_ench(monster, ENCH_HASTE))
- {
- // put in an exception for fungi, plants and other things you won't
- // notice speed up.
- if (simple_monster_message(monster, " seems to speed up."))
- pbolt.obvious_effect = true;
- }
- return (MON_AFFECTED);
-
- case BEAM_HEALING: /* 2 = healing */
- if (heal_monster( monster, 5 + roll_dice( pbolt.damage ), false ))
- {
- if (monster->hit_points == monster->max_hit_points)
- {
- if (simple_monster_message(monster,
- "'s wounds heal themselves!"))
- pbolt.obvious_effect = true;
- }
- else
- {
- if (simple_monster_message(monster, " is healed somewhat."))
- pbolt.obvious_effect = true;
- }
- }
- return (MON_AFFECTED);
-
- case BEAM_PARALYSIS: /* 3 = paralysis */
- monster->speed_increment = 0;
-
- if (simple_monster_message(monster, " suddenly stops moving!"))
- pbolt.obvious_effect = true;
-
- if (grd[monster->x][monster->y] == DNGN_LAVA
- || grid_is_water(grd[monster->x][monster->y]))
- {
- if (mons_flies(monster) == 1)
- {
- // don't worry about invisibility - you should be able to
- // see if something has fallen into the lava
- if (is_near)
- {
- strcpy(info, ptr_monam(monster, DESC_CAP_THE));
- strcat(info, " falls into the ");
- strcat(info, (grd[monster->x][monster->y] == DNGN_LAVA)
- ? "lava" : "water");
- strcat(info, "!");
- mpr(info);
- }
-
- switch (pbolt.thrower)
- {
- case KILL_YOU:
- case KILL_YOU_MISSILE:
- monster_die(monster, KILL_YOU, pbolt.beam_source);
- break; /* " " */
-
- case KILL_MON:
- case KILL_MON_MISSILE:
- monster_die(monster, KILL_MON_MISSILE, pbolt.beam_source);
- break; /* dragon breath &c */
- }
- }
- }
- return (MON_AFFECTED);
-
- case BEAM_CONFUSION: /* 4 = confusion */
- if (mons_add_ench(monster, ENCH_CONFUSION))
- {
- // put in an exception for fungi, plants and other things you won't
- // notice becoming confused.
- if (simple_monster_message(monster, " appears confused."))
- pbolt.obvious_effect = true;
- }
- return (MON_AFFECTED);
-
- case BEAM_INVISIBILITY: /* 5 = invisibility */
- // Store the monster name before it becomes an "it" -- bwr
- strncpy( buff, ptr_monam( monster, DESC_CAP_THE ), sizeof(buff) );
-
- if (mons_add_ench(monster, ENCH_INVIS))
- {
- // Can't use simple_monster_message here, since it checks
- // for visibility of the monster (and its now invisible) -- bwr
- if (mons_near( monster ))
- {
- snprintf( info, INFO_SIZE, "%s flickers %s",
- buff, player_see_invis() ? "for a moment."
- : "and vanishes!" );
- mpr( info );
- }
-
- pbolt.obvious_effect = true;
- }
- return (MON_AFFECTED);
-
- case BEAM_CHARM: /* 9 = charm */
- if (mons_add_ench(monster, ENCH_CHARM))
- {
- // put in an exception for fungi, plants and other things you won't
- // notice becoming charmed.
- if (simple_monster_message(monster, " is charmed."))
- pbolt.obvious_effect = true;
- }
- return (MON_AFFECTED);
-
- default:
- break;
- } /* end of switch (beam_colour) */
-
- return (MON_AFFECTED);
-} // end mons_ench_f2()
-
-// degree is ignored.
-static void slow_monster(monsters *mon, int degree)
-{
- bolt beam;
- beam.flavour = BEAM_SLOW;
- mons_ench_f2(mon, beam);
-}
-
-// Returns true if the curare killed the monster.
-bool curare_hits_monster( const bolt &beam,
- monsters *monster,
- bool fromPlayer,
- int levels )
-{
- const bool res_poison = mons_res_poison(monster);
- bool mondied = false;
-
- poison_monster(monster, fromPlayer, levels, false);
-
- if (!mons_res_asphyx(monster))
- {
- int hurted = roll_dice(2, 6);
-
- // Note that the hurtage is halved by poison resistance.
- if (res_poison)
- hurted /= 2;
-
- if (hurted)
- {
- simple_monster_message(monster, " appears to choke.");
- if ((monster->hit_points -= hurted) < 1)
- {
- const int thrower = YOU_KILL(beam.thrower) ?
- KILL_YOU_MISSILE : KILL_MON_MISSILE;
- monster_die(monster, thrower, beam.beam_source);
- mondied = true;
- }
- }
-
- if (!mondied)
- slow_monster(monster, levels);
- }
-
- // Deities take notice.
- if (fromPlayer)
- did_god_conduct( DID_POISON, 5 + random2(3) );
-
- return (mondied);
-}
-
-// actually poisons a monster (w/ message)
-void poison_monster( struct monsters *monster, bool fromPlayer, int levels,
- bool force )
-{
- bool yourPoison = false;
- int ench = ENCH_NONE;
- int old_strength = 0;
-
- if (monster->type == -1)
- return;
-
- if (!force && mons_res_poison(monster) > 0)
- return;
-
- // who gets the credit if monster dies of poison?
- ench = mons_has_ench( monster, ENCH_POISON_I, ENCH_POISON_IV );
- if (ench != ENCH_NONE)
- {
- old_strength = ench - ENCH_POISON_I;
- }
- else
- {
- ench = mons_has_ench(monster, ENCH_YOUR_POISON_I, ENCH_YOUR_POISON_IV);
- if (ench != ENCH_NONE)
- {
- old_strength = ench - ENCH_YOUR_POISON_I;
- yourPoison = true;
- }
- }
-
- // delete old poison
- mons_del_ench( monster, ENCH_POISON_I, ENCH_POISON_IV, true );
- mons_del_ench( monster, ENCH_YOUR_POISON_I, ENCH_YOUR_POISON_IV, true );
-
- // Calculate new strength:
- int new_strength = old_strength + levels;
- if (new_strength > 3)
- new_strength = 3;
-
- // now, if player poisons the monster at ANY TIME, they should
- // get credit for the kill if the monster dies from poison. This
- // really isn't that abusable -- GDL.
- if (fromPlayer || yourPoison)
- ench = ENCH_YOUR_POISON_I + new_strength;
- else
- ench = ENCH_POISON_I + new_strength;
-
- // actually do the poisoning
- // note: order important here
- if (mons_add_ench( monster, ench ) && new_strength > old_strength)
- {
- simple_monster_message( monster,
- (old_strength == 0) ? " looks ill."
- : " looks even sicker." );
- }
-
- // finally, take care of deity preferences
- if (fromPlayer)
- did_god_conduct( DID_POISON, 5 + random2(3) );
-} // end poison_monster()
-
-// actually napalms a monster (w/ message)
-void sticky_flame_monster( int mn, bool fromPlayer, int levels )
-{
- bool yourFlame = fromPlayer;
- int currentFlame;
- int currentStrength = 0;
-
- struct monsters *monster = &menv[mn];
-
- if (monster->type == -1)
- return;
-
- if (mons_res_fire(monster) > 0)
- return;
-
- // who gets the credit if monster dies of napalm?
- currentFlame = mons_has_ench( monster, ENCH_STICKY_FLAME_I,
- ENCH_STICKY_FLAME_IV );
-
- if (currentFlame != ENCH_NONE)
- {
- currentStrength = currentFlame - ENCH_STICKY_FLAME_I;
- yourFlame = false;
- }
- else
- {
- currentFlame = mons_has_ench( monster, ENCH_YOUR_STICKY_FLAME_I,
- ENCH_YOUR_STICKY_FLAME_IV );
-
- if (currentFlame != ENCH_NONE)
- {
- currentStrength = currentFlame - ENCH_YOUR_STICKY_FLAME_I;
- yourFlame = true;
- }
- else
- currentStrength = -1; // no flame yet!
- }
-
- // delete old flame
- mons_del_ench( monster, ENCH_STICKY_FLAME_I, ENCH_STICKY_FLAME_IV, true );
- mons_del_ench( monster, ENCH_YOUR_STICKY_FLAME_I, ENCH_YOUR_STICKY_FLAME_IV,
- true );
-
- // increase sticky flame strength, cap at 3 (level is 0..3)
- currentStrength += levels;
-
- if (currentStrength > 3)
- currentStrength = 3;
-
- // now, if player flames the monster at ANY TIME, they should
- // get credit for the kill if the monster dies from napalm. This
- // really isn't that abusable -- GDL.
- if (fromPlayer || yourFlame)
- currentStrength += ENCH_YOUR_STICKY_FLAME_I;
- else
- currentStrength += ENCH_STICKY_FLAME_I;
-
- // actually do flame
- if (mons_add_ench( monster, currentStrength ))
- simple_monster_message(monster, " is covered in liquid fire!");
-
-} // end sticky_flame_monster
-
-/*
- * Used by monsters in "planning" which spell to cast. Fires off a "tracer"
- * which tells the monster what it'll hit if it breathes/casts etc.
- *
- * The output from this tracer function is four variables in the beam struct:
- * fr_count, foe_count: a count of how many friends and foes will (probably)
- * be hit by this beam
- * fr_power, foe_power: a measure of how many 'friendly' hit dice it will
- * affect, and how many 'unfriendly' hit dice.
- *
- * note that beam properties must be set, as the tracer will take them
- * into account, as well as the monster's intelligence.
- *
- */
-void fire_tracer(struct monsters *monster, struct bolt &pbolt)
-{
- // don't fiddle with any input parameters other than tracer stuff!
- pbolt.is_tracer = true;
- pbolt.source_x = monster->x; // always safe to do.
- pbolt.source_y = monster->y;
- pbolt.beam_source = monster_index(monster);
- pbolt.can_see_invis = (mons_see_invis(monster) != 0);
- pbolt.smart_monster = (mons_intel(monster->type) == I_HIGH ||
- mons_intel(monster->type) == I_NORMAL);
- pbolt.is_friendly = mons_friendly(monster);
-
- // init tracer variables
- pbolt.foe_count = pbolt.fr_count = 0;
- pbolt.foe_power = pbolt.fr_power = 0;
- pbolt.foe_ratio = 80; // default - see mons_should_fire()
-
- // foe ratio for summon gtr. demons & undead -- they may be
- // summoned, but they're hostile and would love nothing better
- // than to nuke the player and his minions
- if (monster->attitude != ATT_FRIENDLY)
- pbolt.foe_ratio = 25;
-
- // fire!
- fire_beam(pbolt);
-
- // unset tracer flag (convenience)
- pbolt.is_tracer = false;
-} // end tracer_f()
-
-bool check_line_of_sight( int sx, int sy, int tx, int ty )
-{
- struct bolt pbolt;
-
- const int dist = grid_distance( sx, sy, tx, ty );
-
- // can always see one square away
- if (dist <= 1)
- return (true);
-
- // currently we limit the range to 8
- if (dist > MONSTER_LOS_RANGE)
- return (false);
-
- // Redirect player centered LoS to the old method (using display table)...
- // note that this assumes that viewwindow() has been called if needed
- // before we get here (ie this won't work very well if this function gets
- // called between moving the player and updating the display).
- if (sx == you.x_pos && sy == you.y_pos)
- return (see_grid( tx, ty ));
- else if (tx == you.x_pos && ty == you.y_pos)
- return (see_grid( sx, sy ));
-
- // Okay, no easy way... set up a LoS beam between the points
- pbolt.flavour = BEAM_LINE_OF_SIGHT;
- pbolt.is_tracer = true;
- pbolt.source_x = sx;
- pbolt.source_y = sy;
- pbolt.target_x = tx;
- pbolt.target_y = ty;
- pbolt.range = MONSTER_LOS_RANGE;
- pbolt.rangeMax = MONSTER_LOS_RANGE;
-
- // setting these just to be safe:
- pbolt.hit = 0;
- pbolt.type = 0;
- pbolt.damage = dice_def( 0, 1 );
- pbolt.colour = BLACK;
- pbolt.is_beam = true;
-
- // init tracer variables (used to tell if we "hit" the target)
- pbolt.foe_count = pbolt.fr_count = 0;
- pbolt.foe_power = pbolt.fr_power = 0;
-
- // fire!
- fire_beam( pbolt );
-
- // got to target?
- return (pbolt.foe_count == 1);
-}
-
-/*
- When a mimic is hit by a ranged attack, it teleports away (the slow way)
- and changes its appearance - the appearance change is in monster_teleport
- in mstuff2.
- */
-void mimic_alert(struct monsters *mimic)
-{
- if (mons_has_ench( mimic, ENCH_TP_I, ENCH_TP_IV ))
- return;
-
- monster_teleport( mimic, !one_chance_in(3) );
-} // end mimic_alert()
-
-static bool isBouncy(struct bolt &beam)
-{
- // at present, only non-enchantment eletrcical beams bounce.
- if (beam.beam_name[0] != '0' && beam.flavour == BEAM_ELECTRICITY)
- return (true);
-
- return (false);
-}
-
-static void beam_explodes(struct bolt &beam, int x, int y)
-{
- int cloud_type;
-
- // this will be the last thing this beam does.. set target_x
- // and target_y to hold explosion co'ords.
-
- beam.target_x = x;
- beam.target_y = y;
-
- // generic explosion
- if (beam.is_explosion) // beam.flavour == BEAM_EXPLOSION || beam.flavour == BEAM_HOLY)
- {
- explosion1(beam);
- return;
- }
-
- if (beam.flavour >= BEAM_POTION_STINKING_CLOUD
- && beam.flavour <= BEAM_POTION_RANDOM)
- {
- switch (beam.flavour)
- {
- case BEAM_POTION_STINKING_CLOUD:
- beam.colour = GREEN;
- break;
-
- case BEAM_POTION_POISON:
- beam.colour = (coinflip() ? GREEN : LIGHTGREEN);
- break;
-
- case BEAM_POTION_MIASMA:
- case BEAM_POTION_BLACK_SMOKE:
- beam.colour = DARKGREY;
- break;
-
- case BEAM_POTION_STEAM:
- beam.colour = LIGHTGREY;
- break;
-
- case BEAM_POTION_FIRE:
- beam.colour = (coinflip() ? RED : LIGHTRED);
- break;
-
- case BEAM_POTION_COLD:
- beam.colour = (coinflip() ? BLUE : LIGHTBLUE);
- break;
-
- case BEAM_POTION_BLUE_SMOKE:
- beam.colour = LIGHTBLUE;
- break;
-
- case BEAM_POTION_PURP_SMOKE:
- beam.colour = MAGENTA;
- break;
-
- case BEAM_POTION_RANDOM:
- default:
- // Leave it the colour of the potion, the clouds will colour
- // themselves on the next refresh. -- bwr
- break;
- }
-
- explosion1(beam);
- return;
- }
-
-
- // cloud producer -- POISON BLAST
- if (strcmp(beam.beam_name, "blast of poison") == 0)
- {
- cloud_type = YOU_KILL(beam.thrower) ? CLOUD_POISON : CLOUD_POISON_MON;
- big_cloud( cloud_type, x, y, 0, 7 + random2(5) );
- return;
- }
-
- // cloud producer -- FOUL VAPOR (SWAMP DRAKE?)
- if (strcmp(beam.beam_name, "foul vapour") == 0)
- {
- cloud_type = YOU_KILL(beam.thrower) ? CLOUD_STINK : CLOUD_STINK_MON;
- if (beam.flavour == BEAM_MIASMA)
- cloud_type = YOU_KILL(beam.thrower) ?
- CLOUD_MIASMA : CLOUD_MIASMA_MON;
- big_cloud( cloud_type, x, y, 0, 9 );
- return;
- }
-
- // special cases - orbs & blasts of cold
- if (strcmp(beam.beam_name, "orb of electricity") == 0
- || strcmp(beam.beam_name, "metal orb") == 0
- || strcmp(beam.beam_name, "great blast of cold") == 0)
- {
- explosion1( beam );
- return;
- }
-
- // cloud producer only -- stinking cloud
- if (strcmp(beam.beam_name, "ball of vapour") == 0)
- {
- explosion1( beam );
- return;
- }
-}
-
-static bool beam_term_on_target(struct bolt &beam)
-{
- if (beam.flavour == BEAM_LINE_OF_SIGHT)
- {
- beam.foe_count++;
- return (true);
- }
-
- // generic - all explosion-type beams can be targetted at empty space,
- // and will explode there. This semantic also means that a creature
- // in the target cell will have no chance to dodge or block, so we
- // DON'T affect() the cell if this function returns true!
-
- if (beam.is_explosion || beam.is_big_cloud)
- return (true);
-
- // POISON BLAST
- if (strcmp(beam.beam_name, "blast of poison") == 0)
- return (true);
-
- // FOUL VAPOR (SWAMP DRAKE)
- if (strcmp(beam.beam_name, "foul vapour") == 0)
- return (true);
-
- // STINKING CLOUD
- if (strcmp(beam.beam_name, "ball of vapour") == 0)
- return (true);
-
- return (false);
-}
-
-static void beam_drop_object( struct bolt &beam, item_def *item, int x, int y )
-{
- ASSERT( item != NULL );
-
- // conditions: beam is missile and not tracer.
- if (beam.is_tracer || beam.flavour != BEAM_MISSILE)
- return;
-
- if (YOU_KILL(beam.thrower) // ie if you threw it.
- && (grd[x][y] != DNGN_LAVA && grd[x][y] != DNGN_DEEP_WATER))
- {
- int chance;
-
- // [dshaligram] Removed influence of Throwing on ammo preservation.
- // The effect is nigh impossible to perceive.
- switch (item->sub_type)
- {
- case MI_NEEDLE: chance = 7; break;
- case MI_STONE: chance = 6; break;
- case MI_DART: chance = 4; break;
- case MI_ARROW: chance = 4; break;
- case MI_BOLT: chance = 5; break;
-
- case MI_LARGE_ROCK:
- default:
- chance = 20;
- break;
- }
-
- if (item->base_type != OBJ_MISSILES || !one_chance_in(chance))
- copy_item_to_grid( *item, x, y, 1 );
- }
- else if (MON_KILL(beam.thrower) // monster threw it.
- && (grd[x][y] != DNGN_LAVA && grd[x][y] != DNGN_DEEP_WATER)
- && coinflip())
- {
- copy_item_to_grid( *item, x, y, 1 );
- } // if (thing_throw == 2) ...
-}
-
-// somewhat complicated BOUNCE function
-// returns # of times beam bounces during routine (usually 1)
-//
-// step 1 is always the step value from the stepping direction.
-#define B_HORZ 1
-#define B_VERT 2
-#define B_BOTH 3
-
-static int bounce(int &step1, int &step2, int w1, int w2, int &n1, int &n2,
- int l1, int l2, int &t1, int &t2, bool topBlocked, bool sideBlocked)
-{
- int bounceType = 0;
- int bounceCount = 1;
-
- if (topBlocked) bounceType = B_HORZ;
- if (sideBlocked) bounceType = B_VERT;
- if (topBlocked && sideBlocked)
- {
- // check for veritcal bounce only
- if ((w2 + step2 - 50)/100 == (w2 - 50)/100)
- bounceType = B_VERT;
- else
- bounceType = B_BOTH;
- }
-
- switch (bounceType)
- {
- case B_VERT: // easiest
- n1 = w1;
- n2 = w2 + step2;
- step1 = -step1;
- t1 = n1 / 100;
- t2 = (n2 + 50)/100;
- // check top
- if (t2 != n2/100 && topBlocked)
- t2 = n2/100;
- break;
- case B_HORZ: // a little tricky
- if (step2 > 0)
- n2 = (100 + 200*(w2/100)) - (w2 + step2);
- else
- n2 = (100 + 200*((w2 - 50)/100)) - (w2 + step2);
- n1 = w1 + step1;
- t1 = n1 /100;
- t2 = (n2 + 50) / 100;
- step2 = -step2;
- break;
- case B_BOTH:
- // vertical:
- n1 = w1;
- t1 = l1;
- t2 = l2;
- // horizontal:
- if (step2 > 0)
- n2 = (100 + 200*(w2/100)) - (w2 + step2);
- else
- n2 = (100 + 200*((w2 - 50)/100)) - (w2 + step2);
- // reverse both directions
- step1 =- step1;
- step2 =- step2;
- bounceCount = 2;
- break;
- default:
- bounceCount = 0;
- break;
- }
-
- return (bounceCount);
-}
-
-static bool fuzzyLine(int nx, int ny, int &tx, int &ty, int lx, int ly,
- int stepx, int stepy, bool roundX, bool roundY)
-{
- bool fuzzyOK = false;
- int fx, fy; // fuzzy x,y
-
- // BEGIN fuzzy line algorithm
- fx = tx;
- fy = ty;
- if (roundY)
- {
- // try up
- fy = (ny + 100) / 100;
- // check for monotonic
- if (fy != ty && ((stepy>0 && fy >= ly)
- || (stepy<0 && fy <= ly)))
- fuzzyOK = true;
- // see if up try is blocked
- if (fuzzyOK && grd[tx][fy] < MINMOVE)
- fuzzyOK = false;
-
- // try down
- if (!fuzzyOK)
- fy = ny / 100;
- // check for monotonic
- if (fy != ty && ((stepy>0 && fy >= ly)
- || (stepy<0 && fy <= ly)))
- fuzzyOK = true;
- if (fuzzyOK && grd[tx][fy] < MINMOVE)
- fuzzyOK = false;
- }
- if (roundX)
- {
- // try up
- fx = (nx + 100) / 100;
- // check for monotonic
- if (fx != tx && ((stepx>0 && fx >= lx)
- || (stepx<0 && fx <= lx)))
- fuzzyOK = true;
- // see if up try is blocked
- if (fuzzyOK && grd[fx][ty] < MINMOVE)
- fuzzyOK = false;
-
- // try down
- if (!fuzzyOK)
- fx = nx / 100;
- // check for monotonic
- if (fx != tx && ((stepx>0 && fx >= lx)
- || (stepx<0 && fx <= lx)))
- fuzzyOK = true;
- if (fuzzyOK && grd[fx][ty] < MINMOVE)
- fuzzyOK = false;
- }
- // END fuzzy line algorithm
-
- if (fuzzyOK)
- {
- tx = fx;
- ty = fy;
- }
-
- return (fuzzyOK);
-}
-
-// affects a single cell.
-// returns the amount of extra range 'used up' by this beam
-// during the affectation.
-//
-// pseudo-code:
-//
-// 1. If wall, and wall affecting non-tracer, affect the wall.
-// 1b. If for some reason the wall-affect didn't make it into
-// a non-wall, return affect_wall()
-// 2. for non-tracers, produce cloud effects affect_place_clouds()
-// 3. if cell holds player, affect player affect_player()
-// 4. if cell holds monster, affect monster affect_monster()
-// 5. return range used affectation.
-
-int affect(struct bolt &beam, int x, int y)
-{
- // extra range used by hitting something
- int rangeUsed = 0;
-
- // line of sight never affects anything
- if (beam.flavour == BEAM_LINE_OF_SIGHT)
- return (0);
-
- if (grd[x][y] < MINMOVE)
- {
- if (beam.is_tracer) // tracers always stop on walls.
- return (BEAM_STOP);
-
- if (affectsWalls(beam))
- {
- rangeUsed += affect_wall(beam, x, y);
- }
- // if it's still a wall, quit - we can't do anything else to
- // a wall. Otherwise effects (like clouds, etc) are still possible.
- if (grd[x][y] < MINMOVE)
- return (rangeUsed);
- }
-
- // grd[x][y] will NOT be a wall for the remainder of this function.
-
- // if not a tracer, place clouds
- if (!beam.is_tracer)
- rangeUsed += affect_place_clouds(beam, x, y);
-
- // if player is at this location, try to affect unless term_on_target
- if (x == you.x_pos && y == you.y_pos)
- {
- // Done this way so that poison blasts affect the target once (via
- // place_cloud) and explosion spells only affect the target once
- // (during the explosion phase, not an initial hit during the
- // beam phase).
- if (!beam.is_big_cloud
- && (!beam.is_explosion || beam.in_explosion_phase))
- {
- rangeUsed += affect_player( beam );
- }
-
- if (beam_term_on_target(beam))
- return (BEAM_STOP);
- }
-
- // if there is a monster at this location, affect it
- // submerged monsters aren't really there -- bwr
- int mid = mgrd[x][y];
- if (mid != NON_MONSTER && !mons_has_ench( &menv[mid], ENCH_SUBMERGED ))
- {
- if (!beam.is_big_cloud
- && (!beam.is_explosion || beam.in_explosion_phase))
- {
- rangeUsed += affect_monster( beam, &menv[mid] );
- }
-
- if (beam_term_on_target(beam))
- return (BEAM_STOP);
- }
-
- return (rangeUsed);
-}
-
-static bool affectsWalls(struct bolt &beam)
-{
- // don't know of any explosion that affects walls. But change it here
- // if there is.
- if (beam.is_explosion)
- return (false);
-
- // digging
- if (beam.flavour == BEAM_DIGGING)
- return (true);
-
- // Isn't this much nicer than the hack to remove ice bolts, disrupt,
- // and needles (just because they were also coloured "white") -- bwr
- if (beam.flavour == BEAM_DISINTEGRATION && beam.damage.num >= 3)
- return (true);
-
- // eye of devestation?
- if (beam.flavour == BEAM_NUKE)
- return (true);
-
- return (false);
-}
-
-// return amount of extra range used up by affectation of this wall.
-static int affect_wall(struct bolt &beam, int x, int y)
-{
- int rangeUsed = 0;
-
- // DIGGING
- if (beam.flavour == BEAM_DIGGING)
- {
- if (grd[x][y] == DNGN_STONE_WALL
- || grd[x][y] == DNGN_METAL_WALL
- || grd[x][y] == DNGN_PERMAROCK_WALL
- || x <= 5 || x >= (GXM - 5)
- || y <= 5 || y >= (GYM - 5))
- {
- return (0);
- }
-
- if (grd[x][y] == DNGN_ROCK_WALL)
- {
- grd[x][y] = DNGN_FLOOR;
-
- if (!beam.msg_generated)
- {
- if (!silenced(you.x_pos, you.y_pos))
- {
- mpr("You hear a grinding noise.", MSGCH_SOUND);
- beam.obvious_effect = true;
- }
-
- beam.msg_generated = true;
- }
- }
-
- return (rangeUsed);
- }
- // END DIGGING EFFECT
-
- // NUKE / DISRUPT
- if (beam.flavour == BEAM_DISINTEGRATION || beam.flavour == BEAM_NUKE)
- {
- int targ_grid = grd[x][y];
-
- if ((targ_grid == DNGN_ROCK_WALL || targ_grid == DNGN_WAX_WALL)
- && !(x <= 6 || y <= 6 || x >= (GXM - 6) || y >= (GYM - 6)))
- {
- grd[ x ][ y ] = DNGN_FLOOR;
- if (!silenced(you.x_pos, you.y_pos))
- {
- mpr("You hear a grinding noise.", MSGCH_SOUND);
- beam.obvious_effect = true;
- }
- }
-
- if (targ_grid == DNGN_ORCISH_IDOL
- || targ_grid == DNGN_SILVER_STATUE
- || targ_grid == DNGN_GRANITE_STATUE
- || targ_grid == DNGN_ORANGE_CRYSTAL_STATUE)
- {
- grd[x][y] = DNGN_FLOOR;
-
- if (!silenced(you.x_pos, you.y_pos))
- {
- if (!see_grid( x, y ))
- mpr("You hear a hideous screaming!", MSGCH_SOUND);
- else
- mpr("The statue screams as its substance crumbles away!",
- MSGCH_SOUND);
- }
- else
- {
- if (see_grid(x,y))
- mpr("The statue twists and shakes as its substance crumbles away!");
- }
-
- if (targ_grid == DNGN_SILVER_STATUE)
- Visible_Statue[ STATUE_SILVER ] = 0;
- else if (targ_grid == DNGN_ORANGE_CRYSTAL_STATUE)
- Visible_Statue[ STATUE_ORANGE_CRYSTAL ] = 0;
-
- beam.obvious_effect = 1;
- }
-
- return (BEAM_STOP);
- }
-
- return (rangeUsed);
-}
-
-static int affect_place_clouds(struct bolt &beam, int x, int y)
-{
- int cloud_type;
-
- if (beam.in_explosion_phase)
- {
- affect_place_explosion_clouds( beam, x, y );
- return (0); // return value irrelevant for explosions
- }
-
- // check for CLOUD HITS
- if (env.cgrid[x][y] != EMPTY_CLOUD) // hit a cloud
- {
- // polymorph randomly changes clouds in its path
- if (beam.flavour == BEAM_POLYMORPH)
- env.cloud[ env.cgrid[x][y] ].type = 1 + random2(8);
-
- // now exit (all enchantments)
- if (beam.beam_name[0] == '0')
- return (0);
-
- int clouty = env.cgrid[x][y];
-
- // fire cancelling cold & vice versa
- if (((env.cloud[clouty].type == CLOUD_COLD
- || env.cloud[clouty].type == CLOUD_COLD_MON)
- && (beam.flavour == BEAM_FIRE
- || beam.flavour == BEAM_LAVA))
- || ((env.cloud[clouty].type == CLOUD_FIRE
- || env.cloud[clouty].type == CLOUD_FIRE_MON)
- && beam.flavour == BEAM_COLD))
- {
- if (!silenced(x, y)
- && !silenced(you.x_pos, you.y_pos))
- {
- mpr("You hear a sizzling sound!", MSGCH_SOUND);
- }
-
- delete_cloud( clouty );
- return (5);
- }
- }
-
- // POISON BLAST
- if (strcmp(beam.beam_name, "blast of poison") == 0)
- {
- cloud_type = YOU_KILL(beam.thrower) ? CLOUD_POISON : CLOUD_POISON_MON;
-
- place_cloud( cloud_type, x, y, random2(4) + 2 );
- }
-
- // FIRE/COLD over water/lava
- if ( (grd[x][y] == DNGN_LAVA && beam.flavour == BEAM_COLD)
- || ((grd[x][y] == DNGN_DEEP_WATER || grd[x][y] == DNGN_SHALLOW_WATER)
- && beam.flavour == BEAM_FIRE) )
- {
- cloud_type = YOU_KILL(beam.thrower) ? CLOUD_STEAM : CLOUD_STEAM_MON;
- place_cloud( cloud_type, x, y, 2 + random2(5) );
- }
-
- // ORB OF ENERGY
- if (strcmp(beam.beam_name, "orb of energy") == 0)
- place_cloud( CLOUD_PURP_SMOKE, x, y, random2(5) + 1 );
-
- // GREAT BLAST OF COLD
- if (strcmp(beam.beam_name, "great blast of cold") == 0)
- place_cloud( CLOUD_COLD, x, y, random2(5) + 3 );
-
-
- // BALL OF STEAM
- if (strcmp(beam.beam_name, "ball of steam") == 0)
- {
- cloud_type = YOU_KILL(beam.thrower) ? CLOUD_STEAM : CLOUD_STEAM_MON;
- place_cloud( cloud_type, x, y, random2(5) + 2 );
- }
-
- if (beam.flavour == BEAM_MIASMA)
- {
- cloud_type = YOU_KILL( beam.thrower ) ? CLOUD_MIASMA : CLOUD_MIASMA_MON;
- place_cloud( cloud_type, x, y, random2(5) + 2 );
- }
-
- // STICKY FLAME
- if (strcmp(beam.beam_name, "sticky flame") == 0)
- {
- place_cloud( CLOUD_BLACK_SMOKE, x, y, random2(4) + 2 );
- }
-
- // POISON GAS
- if (strcmp(beam.beam_name, "poison gas") == 0)
- {
- cloud_type = YOU_KILL(beam.thrower) ? CLOUD_POISON : CLOUD_POISON_MON;
- place_cloud( cloud_type, x, y, random2(4) + 3 );
- }
-
- return (0);
-}
-
-// following two functions used with explosions:
-static void affect_place_explosion_clouds(struct bolt &beam, int x, int y)
-{
- int cloud_type;
- int duration;
-
- // first check: FIRE/COLD over water/lava
- if ( (grd[x][y] == DNGN_LAVA && beam.flavour == BEAM_COLD)
- || ((grd[x][y] == DNGN_DEEP_WATER || grd[x][y] == DNGN_SHALLOW_WATER)
- && beam.flavour == BEAM_FIRE) )
- {
- cloud_type = YOU_KILL(beam.thrower) ? CLOUD_STEAM : CLOUD_STEAM_MON;
- place_cloud( cloud_type, x, y, 2 + random2(5) );
- return;
- }
-
- if (beam.flavour >= BEAM_POTION_STINKING_CLOUD
- && beam.flavour <= BEAM_POTION_RANDOM)
- {
- duration = roll_dice( 2, 3 + beam.ench_power / 20 );
-
- switch (beam.flavour)
- {
- case BEAM_POTION_STINKING_CLOUD:
- cloud_type = CLOUD_STINK;
- break;
-
- case BEAM_POTION_POISON:
- cloud_type = CLOUD_POISON;
- break;
-
- case BEAM_POTION_MIASMA:
- cloud_type = CLOUD_MIASMA;
- break;
-
- case BEAM_POTION_BLACK_SMOKE:
- cloud_type = CLOUD_BLACK_SMOKE;
- break;
-
- case BEAM_POTION_FIRE:
- cloud_type = CLOUD_FIRE;
- break;
-
- case BEAM_POTION_COLD:
- cloud_type = CLOUD_COLD;
- break;
-
- case BEAM_POTION_BLUE_SMOKE:
- cloud_type = CLOUD_BLUE_SMOKE;
- break;
-
- case BEAM_POTION_PURP_SMOKE:
- cloud_type = CLOUD_PURP_SMOKE;
- break;
-
- case BEAM_POTION_RANDOM:
- switch (random2(10))
- {
- case 0: cloud_type = CLOUD_FIRE; break;
- case 1: cloud_type = CLOUD_STINK; break;
- case 2: cloud_type = CLOUD_COLD; break;
- case 3: cloud_type = CLOUD_POISON; break;
- case 4: cloud_type = CLOUD_BLACK_SMOKE; break;
- case 5: cloud_type = CLOUD_BLUE_SMOKE; break;
- case 6: cloud_type = CLOUD_PURP_SMOKE; break;
- default: cloud_type = CLOUD_STEAM; break;
- }
- break;
-
- case BEAM_POTION_STEAM:
- default:
- cloud_type = CLOUD_STEAM;
- break;
- }
-
- place_cloud( cloud_type, x, y, duration );
- }
-
- // then check for more specific explosion cloud types.
- if (stricmp(beam.beam_name, "ice storm") == 0)
- {
- place_cloud( CLOUD_COLD, x, y, 2 + random2avg(5, 2) );
- }
-
- if (stricmp(beam.beam_name, "stinking cloud") == 0)
- {
- duration = 1 + random2(4) + random2( (beam.ench_power / 50) + 1 );
- place_cloud( CLOUD_STINK, x, y, duration );
- }
-
- if (strcmp(beam.beam_name, "great blast of fire") == 0)
- {
- duration = 1 + random2(5) + roll_dice( 2, beam.ench_power / 5 );
-
- if (duration > 20)
- duration = 20 + random2(4);
-
- place_cloud( CLOUD_FIRE, x, y, duration );
-
- if (grd[x][y] == DNGN_FLOOR && mgrd[x][y] == NON_MONSTER
- && one_chance_in(4))
- {
- mons_place( MONS_FIRE_VORTEX, BEH_HOSTILE, MHITNOT, true, x, y );
- }
- }
-}
-
-static void affect_items(struct bolt &beam, int x, int y)
-{
- char objs_vulnerable = -1;
-
- switch (beam.flavour)
- {
- case BEAM_FIRE:
- case BEAM_LAVA:
- objs_vulnerable = OBJ_SCROLLS;
- break;
- case BEAM_COLD:
- objs_vulnerable = OBJ_POTIONS;
- break;
- case BEAM_SPORE:
- objs_vulnerable = OBJ_FOOD;
- break;
- }
-
- if (stricmp(beam.beam_name, "hellfire") == 0)
- objs_vulnerable = OBJ_SCROLLS;
-
- if (igrd[x][y] != NON_ITEM)
- {
- if (objs_vulnerable != -1 &&
- mitm[igrd[x][y]].base_type == objs_vulnerable)
- {
- destroy_item( igrd[ x ][ y ] );
-
- if (objs_vulnerable == OBJ_SCROLLS && see_grid(x,y))
- {
- mpr("You see a puff of smoke.");
- }
-
- if (objs_vulnerable == OBJ_POTIONS && !silenced(x,y)
- && !silenced(you.x_pos, you.y_pos))
- {
- mpr("You hear glass shatter.");
- }
- }
- }
-}
-
-static int beam_ouch_agent(const bolt &beam)
-{
- return YOU_KILL(beam.thrower)? 0 : beam.beam_source;
-}
-
-// A little helper function to handle the calling of ouch()...
-static void beam_ouch( int dam, struct bolt &beam )
-{
- // The order of this is important.
- if (YOU_KILL( beam.thrower ) && !beam.aux_source)
- {
- ouch( dam, 0, KILLED_BY_TARGETTING );
- }
- else if (MON_KILL( beam.thrower ))
- {
- if (beam.flavour == BEAM_SPORE)
- ouch( dam, beam.beam_source, KILLED_BY_SPORE );
- else
- ouch( dam, beam.beam_source, KILLED_BY_BEAM, beam.aux_source );
- }
- else // KILL_MISC || (YOU_KILL && aux_source)
- {
- ouch( dam, beam.beam_source, KILLED_BY_WILD_MAGIC, beam.aux_source );
- }
-}
-
-// return amount of extra range used up by affectation of the player
-static int affect_player( struct bolt &beam )
-{
- int beamHit;
-
- // digging -- don't care.
- if (beam.flavour == BEAM_DIGGING)
- return (0);
-
- // check for tracer
- if (beam.is_tracer)
- {
- // check can see player
- // XXX: note the cheat to allow for ME_ALERT to target the player...
- // replace this with a time since alert system, rather than just
- // peeking to see if the character is still there. -- bwr
- if (beam.can_see_invis || !you.invis
- || (you.x_pos == beam.target_x && you.y_pos == beam.target_y))
- {
- if (beam.is_friendly)
- {
- beam.fr_count += 1;
- beam.fr_power += you.experience_level;
- }
- else
- {
- beam.foe_count += 1;
- beam.foe_power += you.experience_level;
- }
- }
- return (range_used_on_hit(beam));
- }
-
- // BEGIN real beam code
- beam.msg_generated = true;
-
- // use beamHit, NOT beam.hit, for modification of tohit.. geez!
- beamHit = beam.hit;
-
- if (beam.beam_name[0] != '0')
- {
- if (!beam.is_explosion && !beam.aimed_at_feet)
- {
- // BEGIN BEAM/MISSILE
- int dodge = random2limit( player_evasion(), 40 )
- + random2( you.dex ) / 3 - 2;
-
- if (beam.is_beam)
- {
- // beams can be dodged
- if (player_light_armour()
- && !beam.aimed_at_feet && coinflip())
- {
- exercise(SK_DODGING, 1);
- }
-
- if (you.duration[DUR_REPEL_MISSILES]
- || you.mutation[MUT_REPULSION_FIELD] == 3)
- {
- beamHit -= random2(beamHit / 2);
- }
-
- if (you.duration[DUR_DEFLECT_MISSILES])
- beamHit = random2(beamHit / 3);
-
- if (beamHit < dodge)
- {
- strcpy(info, "The ");
- strcat(info, beam.beam_name);
- strcat(info, " misses you.");
- mpr(info);
- return (0); // no extra used by miss!
- }
- }
- else if (beam_is_blockable(beam))
- {
- // non-beams can be blocked or dodged
- if (you.equip[EQ_SHIELD] != -1
- && !beam.aimed_at_feet
- && player_shield_class() > 0)
- {
- int exer = one_chance_in(3) ? 1 : 0;
- // [dshaligram] beam.hit multiplier lowered to 3 - was 5.
- // In favour of blocking, dex multiplier changed to .25
- // (was .2), added shield skill into the equation with a
- // skill bump.
- const int hit = random2( beam.hit * 3
- + 5 * you.shield_blocks * you.shield_blocks );
-
- const int block = random2(player_shield_class())
- + (random2(you.dex) / 4)
- + (random2(skill_bump(SK_SHIELDS)) / 4)
- - 1;
-
- if (hit < block)
- {
- you.shield_blocks++;
- snprintf( info, INFO_SIZE, "You block the %s.",
- beam.beam_name );
- mpr( info );
-
- exercise( SK_SHIELDS, exer + 1 );
- return (BEAM_STOP);
- }
-
- // some training just for the "attempt"
- exercise( SK_SHIELDS, exer );
- }
-
- if (player_light_armour() && !beam.aimed_at_feet
- && coinflip())
- exercise(SK_DODGING, 1);
-
- if (you.duration[DUR_REPEL_MISSILES]
- || you.mutation[MUT_REPULSION_FIELD] == 3)
- {
- beamHit = random2(beamHit);
- }
-
-
- // miss message
- if (beamHit < dodge || you.duration[DUR_DEFLECT_MISSILES])
- {
- strcpy(info, "The ");
- strcat(info, beam.beam_name);
- strcat(info, " misses you.");
- return (0);
- }
- }
- }
- }
- else
- {
- // BEGIN enchantment beam
- if (beam.flavour != BEAM_HASTE
- && beam.flavour != BEAM_INVISIBILITY
- && beam.flavour != BEAM_HEALING
- && ((beam.flavour != BEAM_TELEPORT && beam.flavour != BEAM_BANISH)
- || !beam.aimed_at_feet)
- && you_resist_magic( beam.ench_power ))
- {
- canned_msg(MSG_YOU_RESIST);
- return (range_used_on_hit(beam));
- }
-
- ench_animation( beam.flavour );
-
- // these colors are misapplied - see mons_ench_f2() {dlb}
- switch (beam.flavour)
- {
- case BEAM_SLOW:
- potion_effect( POT_SLOWING, beam.ench_power );
- beam.obvious_effect = true;
- break; // slow
-
- case BEAM_HASTE:
- potion_effect( POT_SPEED, beam.ench_power );
- contaminate_player( 1 );
- beam.obvious_effect = true;
- break; // haste
-
- case BEAM_HEALING:
- potion_effect( POT_HEAL_WOUNDS, beam.ench_power );
- beam.obvious_effect = true;
- break; // heal (heal wounds potion eff)
-
- case BEAM_PARALYSIS:
- potion_effect( POT_PARALYSIS, beam.ench_power );
- beam.obvious_effect = true;
- break; // paralysis
-
- case BEAM_CONFUSION:
- potion_effect( POT_CONFUSION, beam.ench_power );
- beam.obvious_effect = true;
- break; // confusion
-
- case BEAM_INVISIBILITY:
- potion_effect( POT_INVISIBILITY, beam.ench_power );
- contaminate_player( 1 + random2(2) );
- beam.obvious_effect = true;
- break; // invisibility
-
- // 6 is used by digging
-
- case BEAM_TELEPORT:
- you_teleport();
- beam.obvious_effect = true;
- break;
-
- case BEAM_BLINK:
- random_blink(0);
- beam.obvious_effect = true;
- break;
-
- case BEAM_POLYMORPH:
- mpr("This is polymorph other only!");
- beam.obvious_effect = true;
- break;
-
- case BEAM_CHARM:
- potion_effect( POT_CONFUSION, beam.ench_power );
- beam.obvious_effect = true;
- break; // enslavement - confusion?
-
- case BEAM_BANISH:
- if (you.level_type == LEVEL_ABYSS)
- {
- mpr("You feel trapped.");
- break;
- }
- mpr("You are cast into the Abyss!");
- more();
- banished(DNGN_ENTER_ABYSS);
- beam.obvious_effect = true;
- break; // banishment to the abyss
-
- case BEAM_PAIN: // pain
- if (you.is_undead || you.mutation[MUT_TORMENT_RESISTANCE])
- {
- mpr("You are unaffected.");
- break;
- }
-
- mpr("Pain shoots through your body!");
-
- if (!beam.aux_source)
- beam.aux_source = "by nerve-wracking pain";
-
- beam_ouch( roll_dice( beam.damage ), beam );
- beam.obvious_effect = true;
- break;
-
- case BEAM_DISPEL_UNDEAD:
- if (!you.is_undead)
- {
- mpr("You are unaffected.");
- break;
- }
-
- mpr( "You convulse!" );
-
- if (!beam.aux_source)
- beam.aux_source = "by dispel undead";
-
- beam_ouch( roll_dice( beam.damage ), beam );
- beam.obvious_effect = true;
- break;
-
- case BEAM_DISINTEGRATION:
- mpr("You are blasted!");
-
- if (!beam.aux_source)
- beam.aux_source = "disintegration bolt";
-
- beam_ouch( roll_dice( beam.damage ), beam );
- beam.obvious_effect = true;
- break;
-
- default:
- // _all_ enchantments should be enumerated here!
- mpr("Software bugs nibble your toes!");
- break;
- } // end of switch (beam.colour)
-
- // regardless of affect, we need to know if this is a stopper
- // or not - it seems all of the above are.
- return (range_used_on_hit(beam));
-
- // END enchantment beam
- }
-
- // THE BEAM IS NOW GUARANTEED TO BE A NON-ENCHANTMENT WHICH HIT
-
- const bool engulfs = (beam.is_explosion || beam.is_big_cloud);
- mprf( "The %s %s you!", beam.beam_name, (engulfs) ? "engulfs" : "hits" );
-
- int hurted = 0;
- int burn_power = (beam.is_explosion) ? 5 : ((beam.is_beam) ? 3 : 2);
-
- // Roll the damage
- hurted += roll_dice( beam.damage );
-
-#if DEBUG_DIAGNOSTICS
- int roll = hurted;
-#endif
-
- hurted -= random2( 1 + player_AC() );
-
-
- // shrapnel
- if (beam.flavour == BEAM_FRAG && !player_light_armour())
- {
- hurted -= random2( 1 + player_AC() );
- hurted -= random2( 1 + player_AC() );
- }
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "Player damage: rolled=%d; after AC=%d",
- roll, hurted );
-
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- if (you.equip[EQ_BODY_ARMOUR] != -1)
- {
- if (!player_light_armour() && one_chance_in(4)
- && random2(1000) <= item_mass( you.inv[you.equip[EQ_BODY_ARMOUR]] ))
- {
- exercise( SK_ARMOUR, 1 );
- }
- }
-
- if (hurted < 0)
- hurted = 0;
-
- hurted = check_your_resists( hurted, beam.flavour );
-
- if (beam.flavour == BEAM_MIASMA && hurted > 0)
- {
- if (player_res_poison() <= 0)
- poison_player(1);
-
- if (one_chance_in( 3 + 2 * player_prot_life() ))
- potion_effect( POT_SLOWING, 5 );
- }
-
- // poisoning
- if (strstr(beam.beam_name, "poison") != NULL
- && beam.flavour != BEAM_POISON
- && beam.flavour != BEAM_POISON_ARROW
- && !player_res_poison())
- {
- if (hurted || (strstr( beam.beam_name, "needle" ) != NULL
- && random2(100) < 90 - (3 * player_AC())))
- {
- poison_player( 1 + random2(3) );
- }
- }
-
- if (strstr(beam.beam_name, "curare"))
- {
- if (random2(100) < 90 - (3 * player_AC()))
- {
- curare_hits_player( beam_ouch_agent(beam), 1 + random2(3) );
- }
- }
-
- // sticky flame
- if (strcmp(beam.beam_name, "sticky flame") == 0
- && (you.species != SP_MOTTLED_DRACONIAN
- || you.experience_level < 6))
- {
- if (!player_equip( EQ_BODY_ARMOUR, ARM_MOTTLED_DRAGON_ARMOUR ))
- you.duration[DUR_LIQUID_FLAMES] += random2avg(7, 3) + 1;
- }
-
- // simple cases for scroll burns
- if (beam.flavour == BEAM_LAVA || stricmp(beam.beam_name, "hellfire") == 0)
- scrolls_burn( burn_power, OBJ_SCROLLS );
-
- // more complex (geez..)
- if (beam.flavour == BEAM_FIRE && strcmp(beam.beam_name, "ball of steam") != 0)
- scrolls_burn( burn_power, OBJ_SCROLLS );
-
- // potions exploding
- if (beam.flavour == BEAM_COLD)
- scrolls_burn( burn_power, OBJ_POTIONS );
-
- if (beam.flavour == BEAM_ACID)
- splash_with_acid(5);
-
- // spore pops
- if (beam.in_explosion_phase && beam.flavour == BEAM_SPORE)
- scrolls_burn( 2, OBJ_FOOD );
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "Damage: %d", hurted );
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- beam_ouch( hurted, beam );
-
- return (range_used_on_hit( beam ));
-}
-
-static int beam_source(const bolt &beam)
-{
- return MON_KILL(beam.thrower) ? beam.beam_source :
- beam.thrower == KILL_MISC ? MHITNOT :
- MHITYOU;
-}
-
-// return amount of range used up by affectation of this monster
-static int affect_monster(struct bolt &beam, struct monsters *mon)
-{
- int tid = mgrd[mon->x][mon->y];
- int hurt;
- int hurt_final;
-
- // digging -- don't care.
- if (beam.flavour == BEAM_DIGGING)
- return (0);
-
- // fire storm creates these, so we'll avoid affecting them
- if (strcmp(beam.beam_name, "great blast of fire") == 0
- && mon->type == MONS_FIRE_VORTEX)
- {
- return (0);
- }
-
- // check for tracer
- if (beam.is_tracer)
- {
- // check can see other monster
- if (!beam.can_see_invis && mons_has_ench(&menv[tid], ENCH_INVIS))
- {
- // can't see this monster, ignore it
- return 0;
- }
- }
-
- if (beam.beam_name[0] == '0')
- {
- if (beam.is_tracer)
- {
- // enchant case -- enchantments always hit, so update target immed.
- if (beam.is_friendly ^ mons_friendly(mon))
- {
- beam.foe_count += 1;
- beam.foe_power += mons_power(tid);
- }
- else
- {
- beam.fr_count += 1;
- beam.fr_power += mons_power(tid);
- }
-
- return (range_used_on_hit(beam));
- }
-
- // BEGIN non-tracer enchantment
-
- // nasty enchantments will annoy the monster, and are considered
- // naughty (even if a monster might resist)
- if (nasty_beam(mon, beam))
- {
- if (YOU_KILL( beam.thrower ))
- {
- if (mons_friendly( mon ))
- did_god_conduct( DID_ATTACK_FRIEND, 5 );
-
- if (mons_holiness( mon ) == MH_HOLY)
- did_god_conduct( DID_ATTACK_HOLY, mon->hit_dice );
- }
-
- behaviour_event( mon, ME_ANNOY, beam_source(beam) );
- }
- else
- {
- behaviour_event( mon, ME_ALERT, beam_source(beam) );
- }
-
- // !@#*( affect_monster_enchantment() has side-effects on
- // the beam structure which screw up range_used_on_hit(),
- // so call it now and store.
- int rangeUsed = range_used_on_hit(beam);
-
- // Doing this here so that the player gets to see monsters
- // "flicker and vanish" when turning invisible....
- ench_animation( beam.flavour, mon );
-
- // now do enchantment affect
- int ench_result = affect_monster_enchantment(beam, mon);
- switch(ench_result)
- {
- case MON_RESIST:
- if (simple_monster_message(mon, " resists."))
- beam.msg_generated = true;
- break;
- case MON_UNAFFECTED:
- if (simple_monster_message(mon, " is unaffected."))
- beam.msg_generated = true;
- break;
- default:
- break;
- }
- return (rangeUsed);
-
- // END non-tracer enchantment
- }
-
-
- // BEGIN non-enchantment (could still be tracer)
- if (mons_has_ench( mon, ENCH_SUBMERGED ) && !beam.aimed_at_feet)
- return (0); // missed me!
-
- // we need to know how much the monster _would_ be hurt by this, before
- // we decide if it actually hits.
-
- // Roll the damage:
- hurt = roll_dice( beam.damage );
-
- hurt_final = hurt;
-
- if (beam.is_tracer)
- hurt_final -= mon->armour_class / 2;
- else
- hurt_final -= random2(1 + mon->armour_class);
-
- if (beam.flavour == BEAM_FRAG)
- {
- hurt_final -= random2(1 + mon->armour_class);
- hurt_final -= random2(1 + mon->armour_class);
- }
-
- if (hurt_final < 1)
- {
- hurt_final = 0;
- }
-
-#if DEBUG_DIAGNOSTICS
- const int old_hurt = hurt_final;
-#endif
-
- // check monster resists, _without_ side effects (since the
- // beam/missile might yet miss!)
- hurt_final = mons_adjust_flavoured( mon, beam, hurt_final, false );
-
-#if DEBUG_DIAGNOSTICS
- if (!beam.is_tracer)
- {
- snprintf( info, INFO_SIZE,
- "Monster: %s; Damage: pre-AC: %d; post-AC: %d; post-resist: %d",
- ptr_monam( mon, DESC_PLAIN ), hurt, old_hurt, hurt_final );
-
- mpr( info, MSGCH_DIAGNOSTICS );
- }
-#endif
-
- // now, we know how much this monster would (probably) be
- // hurt by this beam.
- if (beam.is_tracer)
- {
- if (hurt_final != 0)
- {
- // monster could be hurt somewhat, but only apply the
- // monster's power based on how badly it is affected.
- // For example, if a fire giant (power 16) threw a
- // fireball at another fire giant, and it only took
- // 1/3 damage, then power of 5 would be applied to
- // foe_power or fr_power.
- if (beam.is_friendly ^ mons_friendly(mon))
- {
- beam.foe_count += 1;
- beam.foe_power += hurt_final * mons_power(tid) / hurt;
- }
- else
- {
- beam.fr_count += 1;
- beam.fr_power += hurt_final * mons_power(tid) / hurt;
- }
- }
- // either way, we could hit this monster, so return range used
- return (range_used_on_hit(beam));
- }
- // END non-enchantment (could still be tracer)
-
- // BEGIN real non-enchantment beam
-
- // player beams which hit friendly MIGHT annoy them and be considered
- // naughty if they do much damage (this is so as not to penalize
- // players that fling fireballs into a melee with fire elementals
- // on their side - the elementals won't give a sh*t, after all)
-
- if (nasty_beam(mon, beam))
- {
- if (YOU_KILL(beam.thrower))
- {
- if (mons_friendly(mon))
- did_god_conduct( DID_ATTACK_FRIEND, 5 );
-
- if (mons_holiness( mon ) == MH_HOLY)
- did_god_conduct( DID_ATTACK_HOLY, mon->hit_dice );
- }
-
- behaviour_event(mon, ME_ANNOY, beam_source(beam) );
- }
-
- // explosions always 'hit'
- const bool engulfs = (beam.is_explosion || beam.is_big_cloud);
-
- if (!engulfs && beam.hit < random2(mon->evasion))
- {
- // if the PLAYER cannot see the monster, don't tell them anything!
- if (player_monster_visible( &menv[tid] ) && mons_near(mon))
- {
- strcpy(info, "The ");
- strcat(info, beam.beam_name);
- strcat(info, " misses ");
- strcat(info, ptr_monam(mon, DESC_NOCAP_THE));
- strcat(info, ".");
- mpr(info);
- }
- return (0);
- }
-
- // the beam hit.
- if (mons_near(mon))
- {
- strcpy(info, "The ");
- strcat(info, beam.beam_name);
- strcat(info, engulfs? " engulfs ":" hits ");
-
- if (player_monster_visible( &menv[tid] ))
- strcat(info, ptr_monam(mon, DESC_NOCAP_THE));
- else
- strcat(info, "something");
-
- strcat(info, ".");
- mpr(info);
- }
- else
- {
- // the player might hear something,
- // if _they_ fired a missile (not beam)
- if (!silenced(you.x_pos, you.y_pos) && beam.flavour == BEAM_MISSILE
- && YOU_KILL(beam.thrower))
- {
- strcpy(info, "The ");
- strcat(info, beam.beam_name);
- strcat(info, " hits something.");
- mpr(info, MSGCH_SOUND);
- }
- }
-
- // note that hurt_final was calculated above, so we don't need it again.
- // just need to apply flavoured specials (since we called with
- // doFlavouredEffects = false above)
- hurt_final = mons_adjust_flavoured(mon, beam, hurt_final);
-
- // now hurt monster
- hurt_monster( mon, hurt_final );
-
- int thrower = YOU_KILL(beam.thrower) ? KILL_YOU_MISSILE : KILL_MON_MISSILE;
-
- if (mon->hit_points < 1)
- {
- monster_die(mon, thrower, beam.beam_source);
- }
- else
- {
- if (thrower == KILL_YOU_MISSILE && mons_near(mon))
- print_wounds(mon);
-
- // sticky flame
- if (strcmp(beam.beam_name, "sticky flame") == 0)
- {
- int levels = 1 + random2( hurt_final ) / 2;
- if (levels > 4)
- levels = 4;
-
- sticky_flame_monster( tid, YOU_KILL(beam.thrower), levels );
- }
-
-
- /* looks for missiles which aren't poison but
- are poison*ed* */
- if (strstr(beam.beam_name, "poison") != NULL
- && beam.flavour != BEAM_POISON
- && beam.flavour != BEAM_POISON_ARROW)
- {
- if (strstr(beam.beam_name, "needle") != NULL
- && random2(100) < 90 - (3 * mon->armour_class))
- {
- poison_monster( mon, YOU_KILL(beam.thrower), 2 );
- }
- else if (random2(hurt_final) - random2(mon->armour_class) > 0)
- {
- poison_monster( mon, YOU_KILL(beam.thrower) );
- }
- }
-
- bool wake_mimic = true;
- if (strstr(beam.beam_name, "curare"))
- {
- if (curare_hits_monster( beam, mon, YOU_KILL(beam.thrower), 2 ))
- wake_mimic = false;
- }
-
- if (wake_mimic && mons_is_mimic( mon->type ))
- mimic_alert(mon);
- }
-
- return (range_used_on_hit(beam));
-}
-
-static int affect_monster_enchantment(struct bolt &beam, struct monsters *mon)
-{
- if (beam.flavour == BEAM_TELEPORT) // teleportation
- {
- if (check_mons_resist_magic( mon, beam.ench_power )
- && !beam.aimed_at_feet)
- {
- return (MON_RESIST);
- }
-
- if (simple_monster_message(mon, " looks slightly unstable."))
- beam.obvious_effect = true;
-
- monster_teleport(mon, false);
-
- return (MON_AFFECTED);
- }
-
- if (beam.flavour == BEAM_BLINK)
- {
- if (!beam.aimed_at_feet
- && check_mons_resist_magic( mon, beam.ench_power ))
- {
- return (MON_RESIST);
- }
-
- if (mons_near( mon ) && player_monster_visible( mon ))
- beam.obvious_effect = true;
-
- monster_blink( mon );
- return (MON_AFFECTED);
- }
-
- if (beam.flavour == BEAM_POLYMORPH)
- {
- if (mons_holiness( mon ) != MH_NATURAL)
- return (MON_UNAFFECTED);
-
- if (check_mons_resist_magic( mon, beam.ench_power ))
- return (MON_RESIST);
-
- if (monster_polymorph(mon, RANDOM_MONSTER, 100))
- beam.obvious_effect = true;
-
- return (MON_AFFECTED);
- }
-
- if (beam.flavour == BEAM_BANISH)
- {
- if (check_mons_resist_magic( mon, beam.ench_power ))
- return (MON_RESIST);
-
- if (you.level_type == LEVEL_ABYSS)
- {
- simple_monster_message(mon, " wobbles for a moment.");
- }
- else
- monster_die(mon, KILL_RESET, beam.beam_source);
-
- beam.obvious_effect = true;
- return (MON_AFFECTED);
- }
-
- if (beam.flavour == BEAM_DEGENERATE)
- {
- if (mons_holiness(mon) != MH_NATURAL
- || mon->type == MONS_PULSATING_LUMP)
- {
- return (MON_UNAFFECTED);
- }
-
- if (check_mons_resist_magic( mon, beam.ench_power ))
- return (MON_RESIST);
-
- if (monster_polymorph(mon, MONS_PULSATING_LUMP, 100))
- beam.obvious_effect = true;
-
- return (MON_AFFECTED);
- }
-
- if (beam.flavour == BEAM_DISPEL_UNDEAD)
- {
- if (mons_holiness(mon) != MH_UNDEAD)
- return (MON_UNAFFECTED);
-
- if (simple_monster_message(mon, " convulses!"))
- beam.obvious_effect = true;
-
- hurt_monster( mon, roll_dice( beam.damage ) );
-
- goto deathCheck;
- }
-
- if (beam.flavour == BEAM_ENSLAVE_UNDEAD
- && mons_holiness(mon) == MH_UNDEAD)
- {
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "HD: %d; pow: %d",
- mon->hit_dice, beam.ench_power );
-
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- if (check_mons_resist_magic( mon, beam.ench_power ))
- return (MON_RESIST);
-
- simple_monster_message(mon, " is enslaved.");
- beam.obvious_effect = true;
-
- // wow, permanent enslaving
- mon->attitude = ATT_FRIENDLY;
- return (MON_AFFECTED);
- }
-
- if (beam.flavour == BEAM_ENSLAVE_DEMON
- && mons_holiness(mon) == MH_DEMONIC)
- {
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "HD: %d; pow: %d",
- mon->hit_dice, beam.ench_power );
-
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- if (mon->hit_dice * 4 >= random2(beam.ench_power))
- return (MON_RESIST);
-
- simple_monster_message(mon, " is enslaved.");
- beam.obvious_effect = true;
-
- // wow, permanent enslaving
- mon->attitude = ATT_FRIENDLY;
- return (MON_AFFECTED);
- }
-
- //
- // Everything past this point must pass this magic resistance test.
- //
- // Using check_mons_resist_magic here since things like disintegrate
- // are beyond this point. -- bwr
- if (check_mons_resist_magic( mon, beam.ench_power )
- && beam.flavour != BEAM_HASTE
- && beam.flavour != BEAM_HEALING
- && beam.flavour != BEAM_INVISIBILITY)
- {
- return (MON_RESIST);
- }
-
- if (beam.flavour == BEAM_PAIN) /* pain/agony */
- {
- if (mons_res_negative_energy( mon ))
- return (MON_UNAFFECTED);
-
- if (simple_monster_message(mon, " convulses in agony!"))
- beam.obvious_effect = true;
-
- if (strstr( beam.beam_name, "agony" ) != NULL)
- {
- // AGONY
- mon->hit_points = mon->hit_points / 2;
-
- if (mon->hit_points < 1)
- mon->hit_points = 1;
- }
- else
- {
- // PAIN
- hurt_monster( mon, roll_dice( beam.damage ) );
- }
-
- goto deathCheck;
- }
-
- if (beam.flavour == BEAM_DISINTEGRATION) /* disrupt/disintegrate */
- {
- if (simple_monster_message(mon, " is blasted."))
- beam.obvious_effect = true;
-
- hurt_monster( mon, roll_dice( beam.damage ) );
-
- goto deathCheck;
- }
-
-
- if (beam.flavour == BEAM_SLEEP)
- {
- if (mons_has_ench( mon, ENCH_SLEEP_WARY )) // slept recently
- return (MON_RESIST);
-
- if (mons_holiness(mon) != MH_NATURAL) // no unnatural
- return (MON_UNAFFECTED);
-
- if (simple_monster_message(mon, " looks drowsy..."))
- beam.obvious_effect = true;
-
- mon->behaviour = BEH_SLEEP;
- mons_add_ench( mon, ENCH_SLEEP_WARY );
-
- return (MON_AFFECTED);
- }
-
- if (beam.flavour == BEAM_BACKLIGHT)
- {
- if (backlight_monsters(mon->x, mon->y, beam.hit, 0))
- {
- beam.obvious_effect = true;
- return (MON_AFFECTED);
- }
- return (MON_UNAFFECTED);
- }
-
- // everything else?
- return (mons_ench_f2(mon, beam));
-
-deathCheck:
-
- int thrower = KILL_YOU_MISSILE;
- if (MON_KILL(beam.thrower))
- thrower = KILL_MON_MISSILE;
-
- if (mon->hit_points < 1)
- monster_die(mon, thrower, beam.beam_source);
- else
- {
- print_wounds(mon);
-
- if (mons_is_mimic( mon->type ))
- mimic_alert(mon);
- }
-
- return (MON_AFFECTED);
-}
-
-
-// extra range used on hit
-static int range_used_on_hit(struct bolt &beam)
-{
- // non-beams can only affect one thing (player/monster)
- if (!beam.is_beam)
- return (BEAM_STOP);
-
- // CHECK ENCHANTMENTS
- if (beam.beam_name[0] == '0')
- {
- switch(beam.flavour)
- {
- case BEAM_SLOW:
- case BEAM_HASTE:
- case BEAM_HEALING:
- case BEAM_PARALYSIS:
- case BEAM_CONFUSION:
- case BEAM_INVISIBILITY:
- case BEAM_TELEPORT:
- case BEAM_POLYMORPH:
- case BEAM_CHARM:
- case BEAM_BANISH:
- case BEAM_PAIN:
- case BEAM_DISINTEGRATION:
- case BEAM_DEGENERATE:
- case BEAM_DISPEL_UNDEAD:
- case BEAM_ENSLAVE_UNDEAD:
- case BEAM_ENSLAVE_DEMON:
- case BEAM_SLEEP:
- case BEAM_BACKLIGHT:
- return (BEAM_STOP);
- default:
- break;
- }
-
- return (0);
- }
-
- // hellfire stops for nobody!
- if (strcmp( beam.beam_name, "hellfire" ) == 0)
- return (0);
-
- // generic explosion
- if (beam.is_explosion || beam.is_big_cloud)
- return (BEAM_STOP);
-
- // plant spit
- if (beam.flavour == BEAM_ACID)
- return (BEAM_STOP);
-
- // lava doesn't go far, but it goes through most stuff
- if (beam.flavour == BEAM_LAVA)
- return (1);
-
- // If it isn't lightning, reduce range by a lot
- if (beam.flavour != BEAM_ELECTRICITY)
- return (random2(4) + 2);
-
- return (0);
-}
-
-/*
- Takes a bolt struct and refines it for use in the explosion function. Called
- from missile() and beam() in beam.cc. Explosions which do not follow from
- beams (eg scrolls of immolation) bypass this function.
- */
-static void explosion1(struct bolt &pbolt)
-{
- int ex_size = 1;
- // convenience
- int x = pbolt.target_x;
- int y = pbolt.target_y;
- const char *seeMsg = NULL;
- const char *hearMsg = NULL;
-
- // assume that the player can see/hear the explosion, or
- // gets burned by it anyway. :)
- pbolt.msg_generated = true;
-
- if (stricmp(pbolt.beam_name, "hellfire") == 0)
- {
- seeMsg = "The hellfire explodes!";
- hearMsg = "You hear a strangely unpleasant explosion.";
-
- pbolt.type = SYM_BURST;
- pbolt.flavour = BEAM_HELLFIRE;
- }
-
- if (stricmp(pbolt.beam_name, "golden flame") == 0)
- {
- seeMsg = "The flame explodes!";
- hearMsg = "You hear a strange explosion.";
-
- pbolt.type = SYM_BURST;
- pbolt.flavour = BEAM_HOLY; // same as golden flame? [dlb]
- }
-
- if (stricmp( pbolt.beam_name, "golden flame" ) == 0)
- {
- seeMsg = "The flame explodes!";
- hearMsg = "You feel a deep, resonant explosion.";
-
- pbolt.type = SYM_BURST;
- pbolt.flavour = BEAM_HOLY;
- ex_size = 2;
- }
-
-
- if (stricmp(pbolt.beam_name, "fireball") == 0)
- {
- seeMsg = "The fireball explodes!";
- hearMsg = "You hear an explosion.";
-
- pbolt.type = SYM_BURST;
- pbolt.flavour = BEAM_FIRE;
- ex_size = 1;
- }
-
- if (stricmp(pbolt.beam_name, "orb of electricity") == 0)
- {
- seeMsg = "The orb of electricity explodes!";
- hearMsg = "You hear a clap of thunder!";
-
- pbolt.type = SYM_BURST;
- pbolt.flavour = BEAM_ELECTRICITY;
- pbolt.colour = LIGHTCYAN;
- pbolt.damage.num = 1;
- ex_size = 2;
- }
-
- if (stricmp(pbolt.beam_name, "orb of energy") == 0)
- {
- seeMsg = "The orb of energy explodes.";
- hearMsg = "You hear an explosion.";
- }
-
- if (stricmp(pbolt.beam_name, "metal orb") == 0)
- {
- seeMsg = "The orb explodes into a blast of deadly shrapnel!";
- hearMsg = "You hear an explosion!";
-
- strcpy(pbolt.beam_name, "blast of shrapnel");
- pbolt.type = SYM_ZAP;
- pbolt.flavour = BEAM_FRAG; // sets it from pure damage to shrapnel (which is absorbed extra by armour)
- }
-
- if (stricmp(pbolt.beam_name, "great blast of cold") == 0)
- {
- seeMsg = "The blast explodes into a great storm of ice!";
- hearMsg = "You hear a raging storm!";
-
- strcpy(pbolt.beam_name, "ice storm");
- pbolt.damage.num = 6;
- pbolt.type = SYM_ZAP;
- pbolt.colour = WHITE;
- ex_size = 2 + (random2( pbolt.ench_power ) > 75);
- }
-
- if (stricmp(pbolt.beam_name, "ball of vapour") == 0)
- {
- seeMsg = "The ball expands into a vile cloud!";
- hearMsg = "You hear a gentle \'poof\'.";
- strcpy(pbolt.beam_name, "stinking cloud");
- }
-
- if (stricmp(pbolt.beam_name, "potion") == 0)
- {
- seeMsg = "The potion explodes!";
- hearMsg = "You hear an explosion!";
- strcpy(pbolt.beam_name, "cloud");
- }
-
- if (seeMsg == NULL)
- {
- seeMsg = "The beam explodes into a cloud of software bugs!";
- hearMsg = "You hear the sound of one hand clapping!";
- }
-
-
- if (!pbolt.is_tracer)
- {
- // check for see/hear/no msg
- if (see_grid(x,y) || (x == you.x_pos && y == you.y_pos))
- mpr(seeMsg);
- else
- {
- if (!(silenced(x,y) || silenced(you.x_pos, you.y_pos)))
- mpr(hearMsg, MSGCH_SOUND);
- else
- pbolt.msg_generated = false;
- }
- }
-
- pbolt.ex_size = ex_size;
- explosion( pbolt );
-} // end explosion1()
-
-
-#define MAX_EXPLOSION_RADIUS 9
-
-// explosion is considered to emanate from beam->target_x, target_y
-// and has a radius equal to ex_size. The explosion will respect
-// boundaries like walls, but go through/around statues/idols/etc.
-
-// for each cell affected by the explosion, affect() is called.
-
-void explosion( struct bolt &beam, bool hole_in_the_middle )
-{
- int r = beam.ex_size;
-
- // beam is now an explosion; set in_explosion_phase
- beam.in_explosion_phase = true;
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE,
- "explosion at (%d, %d) : t=%d c=%d f=%d hit=%d dam=%dd%d",
- beam.target_x, beam.target_y,
- beam.type, beam.colour, beam.flavour,
- beam.hit, beam.damage.num, beam.damage.size );
-
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- // for now, we don't support explosions greater than 9 radius
- if (r > MAX_EXPLOSION_RADIUS)
- r = MAX_EXPLOSION_RADIUS;
-
- // make a noise
- noisy( 10 + 5*r, beam.target_x, beam.target_y );
-
- // set map to false
- for (int i=0; i<19; i++)
- {
- for (int j=0; j<19; j++)
- explode_map[i][j] = false;
- }
-
- // discover affected cells - recursion is your friend!
- // this is done to model an explosion's behaviour around
- // corners where a simple 'line of sight' isn't quite
- // enough. This might be slow for really big explosions,
- // as the recursion runs approximately as R^2
- explosion_map(beam, 0, 0, 0, 0, r);
-
- // go through affected cells, drawing effect and
- // calling affect() and affect_items() for each.
- // now, we get a bit fancy, drawing all radius 0
- // effects, then radius 1, radius 2, etc. It looks
- // a bit better that way.
-
- // turn buffering off
-#ifdef WIN32CONSOLE
- bool oldValue = true;
- if (!beam.is_tracer)
- oldValue = setBuffering(false);
-#endif
-
- // --------------------- begin boom ---------------
-
- bool drawing = true;
- for (int i = 0; i < 2; i++)
- {
- // do center -- but only if its affected
- if (!hole_in_the_middle)
- explosion_cell(beam, 0, 0, drawing);
-
- // do the rest of it
- for(int rad = 1; rad <= r; rad ++)
- {
- // do sides
- for (int ay = 1 - rad; ay <= rad - 1; ay += 1)
- {
- if (explode_map[-rad+9][ay+9])
- explosion_cell(beam, -rad, ay, drawing);
-
- if (explode_map[rad+9][ay+9])
- explosion_cell(beam, rad, ay, drawing);
- }
-
- // do top & bottom
- for (int ax = -rad; ax <= rad; ax += 1)
- {
- if (explode_map[ax+9][-rad+9])
- explosion_cell(beam, ax, -rad, drawing);
-
- if (explode_map[ax+9][rad+9])
- explosion_cell(beam, ax, rad, drawing);
- }
-
- // new-- delay after every 'ring' {gdl}
-#ifdef UNIX
- // If we don't refresh curses we won't
- // guarantee that the explosion is visible
- if (drawing)
- update_screen();
-#endif
- // only delay on real explosion
- if (!beam.is_tracer && drawing)
- delay(50);
- }
-
- drawing = false;
- }
-
- // ---------------- end boom --------------------------
-
-#ifdef WIN32CONSOLE
- if (!beam.is_tracer)
- setBuffering(oldValue);
-#endif
-
- // duplicate old behaviour - pause after entire explosion
- // has been drawn.
- if (!beam.is_tracer)
- more();
-}
-
-static void explosion_cell(struct bolt &beam, int x, int y, bool drawOnly)
-{
- bool random_beam = false;
- int realx = beam.target_x + x;
- int realy = beam.target_y + y;
-
- if (!drawOnly)
- {
- // random beams: randomize before affect
- if (beam.flavour == BEAM_RANDOM)
- {
- random_beam = true;
- beam.flavour = BEAM_FIRE + random2(7);
- }
-
- affect(beam, realx, realy);
-
- if (random_beam)
- beam.flavour = BEAM_RANDOM;
- }
-
- // early out for tracer
- if (beam.is_tracer)
- return;
-
- // now affect items
- if (!drawOnly)
- affect_items(beam, realx, realy);
-
- if (drawOnly)
- {
- int drawx = realx - you.x_pos + 18;
- int drawy = realy - you.y_pos + 9;
-
- if (see_grid(realx, realy) || (realx == you.x_pos && realy == you.y_pos))
- {
- // bounds check
- if (drawx > 8 && drawx < 26 && drawy > 0 && drawy < 18)
- {
- if (beam.colour == BLACK)
- textcolor(random_colour());
- else
- textcolor(beam.colour);
-
- gotoxy(drawx, drawy);
- putch('#');
- }
- }
- }
-}
-
-static void explosion_map( struct bolt &beam, int x, int y,
- int count, int dir, int r )
-{
- // 1. check to see out of range
- if (x * x + y * y > r * r + r)
- return;
-
- // 2. check count
- if (count > 10*r)
- return;
-
- // 3. check to see if we're blocked by something
- // specifically, we're blocked by WALLS. Not
- // statues, idols, etc.
- int dngn_feat = grd[beam.target_x + x][beam.target_y + y];
-
- // special case: explosion originates from rock/statue
- // (e.g. Lee's rapid deconstruction) - in this case, ignore
- // solid cells at the center of the explosion.
- if (dngn_feat < DNGN_GREEN_CRYSTAL_WALL || dngn_feat == DNGN_WAX_WALL)
- {
- if (!(x==0 && y==0))
- return;
- }
-
- // hmm, I think we're ok
- explode_map[x+9][y+9] = true;
-
- // now recurse in every direction except the one we
- // came from
- for(int i=0; i<4; i++)
- {
- if (i+1 != dir)
- {
- int cadd = 5;
- if (x * spreadx[i] < 0 || y * spready[i] < 0)
- cadd = 17;
-
- explosion_map( beam, x + spreadx[i], y + spready[i],
- count + cadd, opdir[i], r );
- }
- }
-}
-
-// returns true if the beam is harmful (ignoring monster
-// resists) -- mon is given for 'special' cases where,
-// for example, "Heal" might actually hurt undead, or
-// "Holy Word" being ignored by holy monsters, etc.
-//
-// only enchantments should need the actual monster type
-// to determine this; non-enchantments are pretty
-// straightforward.
-bool nasty_beam(struct monsters *mon, struct bolt &beam)
-{
- // take care of non-enchantments
- if (beam.beam_name[0] != '0')
- return (true);
-
- // now for some non-hurtful enchantments
-
- // degeneration / sleep
- if (beam.flavour == BEAM_DEGENERATE || beam.flavour == BEAM_SLEEP)
- return (mons_holiness(mon) == MH_NATURAL);
-
- // dispel undead / control undead
- if (beam.flavour == BEAM_DISPEL_UNDEAD || beam.flavour == BEAM_ENSLAVE_UNDEAD)
- return (mons_holiness(mon) == MH_UNDEAD);
-
- // pain/agony
- if (beam.flavour == BEAM_PAIN)
- return (!mons_res_negative_energy( mon ));
-
- // control demon
- if (beam.flavour == BEAM_ENSLAVE_DEMON)
- return (mons_holiness(mon) == MH_DEMONIC);
-
- // haste
- if (beam.flavour == BEAM_HASTE)
- return (false);
-
- // healing
- if (beam.flavour == BEAM_HEALING || beam.flavour == BEAM_INVISIBILITY)
- return (false);
-
- // everything else is considered nasty by everyone
- return (true);
-}
diff --git a/stone_soup/crawl-ref/source/beam.h b/stone_soup/crawl-ref/source/beam.h
deleted file mode 100644
index d081332bb6..0000000000
--- a/stone_soup/crawl-ref/source/beam.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * File: beam.cc
- * Summary: Functions related to ranged attacks.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef BEAM_H
-#define BEAM_H
-
-
-#include "externs.h"
-
-dice_def calc_dice( int num_dice, int max_damage );
-
-
-/* ***********************************************************************
- * called from: bang - it_use2 - monstuff - mstuff2
- * *********************************************************************** */
-void fire_beam( struct bolt &pbolt, item_def *item = NULL );
-
-// last updated 19apr2001 {gdl}
-/* ***********************************************************************
- * called from: beam
- * *********************************************************************** */
-bool nasty_beam( struct monsters *mon, struct bolt &beam );
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: ability - it_use3 - item_use - mstuff2 - religion -
- * spells - spells4
- * *********************************************************************** */
-void explosion( struct bolt &pbolt, bool hole_in_the_middle = false );
-
-
-// last updated 22jan2001 {gdl}
-/* ***********************************************************************
- * called from: effects - spells2 - spells4
- * *********************************************************************** */
-int mons_adjust_flavoured( struct monsters *monster, struct bolt &pbolt,
- int hurted, bool doFlavouredEffects = true );
-
-
-/* ***********************************************************************
- * called from: ability - item_use - spell
- * returns true if messages were generated during the enchantment
- * *********************************************************************** */
-bool mass_enchantment( int wh_enchant, int pow, int who );
-
-
-/* ***********************************************************************
- * called from: fight - monstuff - mstuff2
- * *********************************************************************** */
-int mons_ench_f2( struct monsters *monster, struct bolt &pbolt );
-
-
-/* ***********************************************************************
- * called from: fight - monstuff - spells2
- * *********************************************************************** */
-void poison_monster( struct monsters *monster, bool fromPlayer, int levels = 1,
- bool force = false );
-
-
-/* ***********************************************************************
- * called from: fight - monstuff - spells - spells1 - spells2
- * *********************************************************************** */
-#if 0
-void delete_cloud( int cloud );
-void new_cloud( int cloud, int type, int x, int y, int decay );
-
-void place_cloud(unsigned char cl_type, unsigned char ctarget_x, unsigned char ctarget_y, unsigned char cl_range);
-#endif
-
-
-/* ***********************************************************************
- * called from: monstuff
- * *********************************************************************** */
-void fire_tracer( struct monsters *monster, struct bolt &pbolt );
-
-bool check_line_of_sight( int sx, int sy, int tx, int ty );
-
-/* ***********************************************************************
- * called from: monstuff
- * *********************************************************************** */
-void mimic_alert( struct monsters *mimic );
-
-
-void zapping( char ztype, int power, struct bolt &pbolt );
-
-int affect(struct bolt &beam, int x, int y);
-
-#endif
diff --git a/stone_soup/crawl-ref/source/chardump.cc b/stone_soup/crawl-ref/source/chardump.cc
deleted file mode 100644
index 5beb0e7ab7..0000000000
--- a/stone_soup/crawl-ref/source/chardump.cc
+++ /dev/null
@@ -1,1181 +0,0 @@
-/*
- * File: chardump.cc
- * Summary: Dumps character info out to the morgue file.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- *
- * <4> 19 June 2000 GDL Changed handles to FILE *
- * <3> 6/13/99 BWR Improved spell listing
- * <2> 5/30/99 JDJ dump_spells dumps failure rates (from Brent).
- * <1> 4/20/99 JDJ Reformatted, uses string objects, split out 7
- * functions from dump_char, dumps artifact info.
- */
-
-#include "AppHdr.h"
-#include "chardump.h"
-
-#include <string>
-#include <stdio.h>
-#include <string.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#if !(defined(__IBMCPP__) || defined(__BCPLUSPLUS__))
-#include <unistd.h>
-#endif
-#include <ctype.h>
-
-#ifdef USE_EMX
-#include <sys/types.h>
-#endif
-
-#ifdef OS9
-#include <stat.h>
-#else
-#include <sys/stat.h>
-#endif
-
-#ifdef DOS
-#include <conio.h>
-#endif
-
-#include "externs.h"
-
-#include "debug.h"
-#include "describe.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "items.h"
-#include "macro.h"
-#include "mutation.h"
-#include "output.h"
-#include "player.h"
-#include "randart.h"
-#include "religion.h"
-#include "shopping.h"
-#include "skills2.h"
-#include "spl-book.h"
-#include "spl-cast.h"
-#include "spl-util.h"
-#include "stash.h"
-#include "stuff.h"
-#include "version.h"
-#include "view.h"
-
-// Defined in view.cc
-extern unsigned char (*mapch2) (unsigned char);
-
- // ========================================================================
- // Internal Functions
- // ========================================================================
-
- // fillstring() is a hack to get around a missing constructor in
- // Borland C++ implementation of the STD basic_string. Argh!!!
-static std::string fillstring(size_t strlen, char filler)
-{
- std::string s;
-
- for (size_t i=0; i<strlen; i++)
- s += filler;
-
- return s;
-}
-
- //---------------------------------------------------------------
- //
- // munge_description
- //
- // Convert dollar signs to EOL and word wrap to 80 characters.
- // (for some obscure reason get_item_description uses dollar
- // signs instead of EOL).
- // - It uses $ signs because they're easier to manipulate than the EOL
- // macro, which is of uncertain length (well, that and I didn't know how
- // to do it any better at the time) (LH)
- //---------------------------------------------------------------
-std::string munge_description(const std::string & inStr)
-{
- std::string outStr;
-
- outStr.reserve(inStr.length() + 32);
-
- const long kIndent = 3;
- long lineLen = kIndent;
-
- long i = 0;
-
- outStr += fillstring(kIndent, ' ');
-
- while (i < (long) inStr.length())
- {
- char ch = inStr[i];
-
- if (ch == '$')
- {
- outStr += EOL;
-
- outStr += fillstring(kIndent, ' ');
- lineLen = kIndent;
-
- while (inStr[++i] == '$')
- ;
- }
- else if (isspace(ch))
- {
- if (lineLen >= 79)
- {
- outStr += EOL;
- outStr += fillstring(kIndent, ' ');
- lineLen = kIndent;
-
- }
- else if (lineLen > 0)
- {
- outStr += ch;
- ++lineLen;
- }
- ++i;
- }
- else
- {
- std::string word;
-
- while (i < (long) inStr.length()
- && lineLen + (long) word.length() < 79
- && !isspace(inStr[i]) && inStr[i] != '$')
- {
- word += inStr[i++];
- }
-
- if (lineLen + word.length() >= 79)
- {
- outStr += EOL;
- outStr += fillstring(kIndent, ' ');
- lineLen = kIndent;
- }
-
- outStr += word;
- lineLen += word.length();
- }
- }
-
- outStr += EOL;
-
- return (outStr);
-} // end munge_description()
-
- //---------------------------------------------------------------
- //
- // dump_screenshot
- //
- // Grabs a screenshot and appends the text into the given std::string,
- // using several ugly hacks in the process.
- //---------------------------------------------------------------
-static void dump_screenshot( std::string &text )
-{
- // A little message history:
- if (Options.dump_message_count > 0)
- {
- text += " Last Messages" EOL EOL;
- text += get_last_messages(Options.dump_message_count);
- }
-
- FixedVector < char, 1500 > buffy; //[800]; //392];
- int bufcount = 0;
- unsigned short ch, color;
- int count_x, count_y;
-
- // Urg, ugly screen capture. CVS Crawl may have a better way of doing this,
- // but until the next release...
- for (count_y = (you.y_pos - 8); (count_y < you.y_pos + 9); count_y++)
- {
- bufcount += 8;
- for (count_x = (you.x_pos - 8); (count_x < you.x_pos + 9); count_x++)
- {
- if (count_x == you.x_pos && count_y == you.y_pos)
- {
- extern unsigned char your_sign;
- ch = your_sign;
- }
- else
- {
- unsigned int object = env.show[count_x - you.x_pos + 9]
- [count_y - you.y_pos + 9];
- get_non_ibm_symbol(object, &ch, &color);
- }
-
- buffy[bufcount++] = (char) ch;
- }
- bufcount += 8;
- }
-
- int maxbuf = bufcount;
- bufcount = 0;
-
- for (count_y = 0; count_y < 17; count_y++)
- {
- for (count_x = 0; count_x < 33; count_x++)
- {
- if (count_x + you.x_pos - 17 < 3
- || count_y + you.y_pos - 9 < 3
- || count_x + you.x_pos - 14 > (GXM - 3)
- || count_y + you.y_pos - 9 > (GYM - 3))
- {
- buffy[bufcount++] = ' ';
- continue;
- }
-
- if (count_x >= 8 && count_x <= 24 && count_y >= 0
- && count_y <= 16 && buffy[bufcount] != 0)
- {
- bufcount++;
- continue;
- }
-
- unsigned char envc = (unsigned char)
- env.map[count_x + you.x_pos - 17]
- [count_y + you.y_pos - 9];
- if (envc)
- {
- // If it's printable, use it directly.
- if (envc < 127 && envc >= 32)
- ch = envc;
- else
- {
- // Otherwise get what's on the grid and get an ASCII
- // character for that.
- unsigned int object = grd[count_x + you.x_pos - 16]
- [count_y + you.y_pos - 8];
-
- // Special case secret doors so that monsters that open
- // doors out of hero's LOS don't reveal the secret door in
- // the dump
- if (envc == mapch2(DNGN_SECRET_DOOR))
- object = DNGN_SECRET_DOOR;
-
- get_non_ibm_symbol(object, &ch, &color);
- }
-
- buffy[bufcount++] = (char) ch;
- }
- else
- {
- buffy[bufcount++] = ' ';
- }
- }
- }
-
- if (bufcount > maxbuf) maxbuf = bufcount;
-
- while (maxbuf > 0 && (!buffy[maxbuf - 1] || buffy[maxbuf - 1] == ' '))
- --maxbuf;
-
- // 33 columns and a null terminator. More hardcoding. :-(
- char buf[34];
- char *s = buf;
- bool leadblanks = true;
- for (int i = 0; i < maxbuf; )
- {
- *s++ = buffy[i]? buffy[i] : ' ';
-
- ++i;
- if (!(i % 33) || i >= maxbuf)
- {
- *s = 0;
- while (s > buf && *--s == ' ')
- *s = 0;
-
- if (s == buf && !*s && leadblanks)
- continue;
-
- leadblanks = false;
- text += buf;
- text += EOL;
- s = buf;
- }
- }
-}
-
- //---------------------------------------------------------------
- //
- // dump_stats
- //
- //---------------------------------------------------------------
-static void dump_stats( std::string & text )
-{
- char st_prn[20];
-
- text += you.your_name;
- text += " the ";
-
- text += player_title();
- text += " (";
- text += species_name(you.species, you.experience_level);
- text += ")";
- text += EOL;
-
- text += "(Level ";
- itoa(you.experience_level, st_prn, 10);
- text += st_prn;
- text += " ";
- text += you.class_name;
- text += ")";
- text += EOL EOL;
-
- if (you.real_time != -1)
- {
- const time_t curr = you.real_time + (time(NULL) - you.start_time);
- char buff[200];
-
- make_time_string( curr, buff, sizeof(buff) );
-
- text += "Play time: ";
- text += buff;
-
- text += " Number of turns: ";
- itoa( you.num_turns, st_prn, 10 );
- text += st_prn;
- text += EOL EOL;
- }
-
- text += "Experience : ";
- itoa(you.experience_level, st_prn, 10);
- text += st_prn;
- text += "/";
- itoa(you.experience, st_prn, 10);
- text += st_prn;
- text += EOL;
-
- text += "Strength ";
- itoa(you.strength, st_prn, 10);
- text += st_prn;
- if (you.strength < you.max_strength)
- {
- text += "/";
- itoa(you.max_strength, st_prn, 10);
- text += st_prn;
- }
-
- text += " Dexterity ";
- itoa(you.dex, st_prn, 10);
- text += st_prn;
- if (you.dex < you.max_dex)
- {
- text += "/";
- itoa(you.max_dex, st_prn, 10);
- text += st_prn;
- }
-
- text += " Intelligence ";
- itoa(you.intel, st_prn, 10);
- text += st_prn;
- if (you.intel < you.max_intel)
- {
- text += "/";
- itoa(you.max_intel, st_prn, 10);
- text += st_prn;
- }
- text += EOL;
-
- text += "Hit Points : ";
- itoa(you.hp, st_prn, 10);
- text += st_prn;
-
- int max_max_hp = you.hp_max + player_rotted();
-
- if (you.hp < you.hp_max || max_max_hp != you.hp_max)
- {
- text += "/";
- itoa(you.hp_max, st_prn, 10);
- text += st_prn;
-
- if (max_max_hp != you.hp_max)
- {
- text += " (";
- itoa(max_max_hp, st_prn, 10);
- text += st_prn;
- text += ")";
- }
-
- if (you.hp < 1)
- {
- text += " ";
- text += ((!you.deaths_door) ? "(dead)" : "(almost dead)");
- }
- }
-
- text += " Magic Points : ";
- itoa(you.magic_points, st_prn, 10);
- text += st_prn;
- if (you.magic_points < you.max_magic_points)
- {
- text += "/";
- itoa(you.max_magic_points, st_prn, 10);
- text += st_prn;
- }
- text += EOL;
-
- text += "AC : ";
- itoa(player_AC(), st_prn, 10);
- text += st_prn;
-
- text += " Evasion : ";
- itoa(player_evasion(), st_prn, 10);
- text += st_prn;
-
- text += " Shield : ";
- itoa(player_shield_class(), st_prn, 10);
- text += st_prn;
- text += EOL;
-
- text += "GP : ";
- itoa( you.gold, st_prn, 10 );
- text += st_prn;
- text += EOL;
- text += EOL;
-} // end dump_stats()
-
- //---------------------------------------------------------------
- //
- // dump_stats2
- //
- //---------------------------------------------------------------
-static void dump_stats2( std::string & text, bool calc_unid)
-{
- char buffer[25*3][45];
- char str_pass[80];
- char* ptr_n;
-
- get_full_detail(&buffer[0][0], calc_unid);
-
- for (int i = 0; i < 25; i++)
- {
- ptr_n = &buffer[i][0];
- if (buffer[i+25][0] == '\0' && buffer[i+50][0] == '\0')
- snprintf(&str_pass[0], 45, "%s", ptr_n);
- else
- snprintf(&str_pass[0], 45, "%-32s", ptr_n);
- text += str_pass;
-
- ptr_n = &buffer[i+25][0];
- if (buffer[i+50][0] == '\0')
- snprintf(&str_pass[0], 45, "%s", ptr_n);
- else
- snprintf(&str_pass[0], 45, "%-20s", ptr_n);
- text += str_pass;
-
- ptr_n = &buffer[i+50][0];
- if (buffer[i+50][0] != '\0')
- {
- snprintf(&str_pass[0], 45, "%s", ptr_n);
- text += str_pass;
- }
- text += EOL;
- }
-
- text += EOL EOL;
-}
-
- //---------------------------------------------------------------
- //
- // dump_location
- //
- //---------------------------------------------------------------
-static void dump_location( std::string & text )
-{
- if (you.level_type != LEVEL_DUNGEON || you.your_level != -1)
- text += "You are ";
-
- if (you.level_type == LEVEL_PANDEMONIUM)
- text += "in Pandemonium";
- else if (you.level_type == LEVEL_ABYSS)
- text += "in the Abyss";
- else if (you.level_type == LEVEL_LABYRINTH)
- text += "in a labyrinth";
- else if (you.where_are_you == BRANCH_DIS)
- text += "in Dis";
- else if (you.where_are_you == BRANCH_GEHENNA)
- text += "in Gehenna";
- else if (you.where_are_you == BRANCH_VESTIBULE_OF_HELL)
- text += "in the Vestibule of Hell";
- else if (you.where_are_you == BRANCH_COCYTUS)
- text += "in Cocytus";
- else if (you.where_are_you == BRANCH_TARTARUS)
- text += "in Tartarus";
- else if (you.where_are_you == BRANCH_INFERNO)
- text += "in the Inferno";
- else if (you.where_are_you == BRANCH_THE_PIT)
- text += "in the Pit";
- else if (you.where_are_you == BRANCH_ORCISH_MINES)
- text += "in the Mines";
- else if (you.where_are_you == BRANCH_HIVE)
- text += "in the Hive";
- else if (you.where_are_you == BRANCH_LAIR)
- text += "in the Lair";
- else if (you.where_are_you == BRANCH_SLIME_PITS)
- text += "in the Slime Pits";
- else if (you.where_are_you == BRANCH_VAULTS)
- text += "in the Vaults";
- else if (you.where_are_you == BRANCH_CRYPT)
- text += "in the Crypt";
- else if (you.where_are_you == BRANCH_HALL_OF_BLADES)
- text += "in the Hall of Blades";
- else if (you.where_are_you == BRANCH_HALL_OF_ZOT)
- text += "in the Hall of Zot";
- else if (you.where_are_you == BRANCH_ECUMENICAL_TEMPLE)
- text += "in the Ecumenical Temple";
- else if (you.where_are_you == BRANCH_SNAKE_PIT)
- text += "in the Snake Pit";
- else if (you.where_are_you == BRANCH_ELVEN_HALLS)
- text += "in the Elven Halls";
- else if (you.where_are_you == BRANCH_TOMB)
- text += "in the Tomb";
- else if (you.where_are_you == BRANCH_SWAMP)
- text += "in the Swamp";
- else
- {
- if (you.your_level == -1)
- text += "You escaped";
- else
- {
- text += "on level ";
-
- char st_prn[20];
- itoa(you.your_level + 1, st_prn, 10);
- text += st_prn;
- }
- }
-
- text += ".";
- text += EOL;
-} // end dump_location()
-
- //---------------------------------------------------------------
- //
- // dump_religion
- //
- //---------------------------------------------------------------
-static void dump_religion( std::string & text )
-{
- if (you.religion != GOD_NO_GOD)
- {
- text += "You worship ";
- text += god_name(you.religion);
- text += ".";
- text += EOL;
-
- if (!player_under_penance())
- {
- if (you.religion != GOD_XOM)
- { // Xom doesn't care
- text += god_name(you.religion);
- text += " is ";
- text += ((you.piety <= 5) ? "displeased" :
- (you.piety <= 20) ? "noncommittal" :
- (you.piety <= 40) ? "pleased with you" :
- (you.piety <= 70) ? "most pleased with you" :
- (you.piety <= 100) ? "greatly pleased with you" :
- (you.piety <= 130) ? "extremely pleased with you"
- : "exalted by your worship");
- text += ".";
- text += EOL;
- }
- }
- else
- {
- text += god_name(you.religion);
- text += " is demanding penance.";
- text += EOL;
- }
- }
-} // end dump_religion()
-
-extern char id[4][50]; // itemname.cc
-static bool dump_item_origin(const item_def &item, int value)
-{
-#define fs(x) (flags & (x))
- const int flags = Options.dump_item_origins;
- if (flags == IODS_EVERYTHING)
- return (true);
-
- if (fs(IODS_ARTIFACTS)
- && (is_random_artefact(item) || is_fixed_artefact(item))
- && item_ident(item, ISFLAG_KNOW_PROPERTIES))
- return (true);
-
- if (fs(IODS_EGO_ARMOUR) && item.base_type == OBJ_ARMOUR
- && item_ident( item, ISFLAG_KNOW_TYPE ))
- {
- const int spec_ench = get_armour_ego_type( item );
- return (spec_ench != SPARM_NORMAL);
- }
-
- if (fs(IODS_EGO_WEAPON) && item.base_type == OBJ_WEAPONS
- && item_ident( item, ISFLAG_KNOW_TYPE ))
- return (get_weapon_brand(item) != SPWPN_NORMAL);
-
- if (fs(IODS_JEWELLERY) && item.base_type == OBJ_JEWELLERY)
- return (true);
-
- if (fs(IODS_RUNES) && item.base_type == OBJ_MISCELLANY
- && item.sub_type == MISC_RUNE_OF_ZOT)
- return (true);
-
- if (fs(IODS_RODS) && item.base_type == OBJ_STAVES
- && item_is_rod(item))
- return (true);
-
- if (fs(IODS_STAVES) && item.base_type == OBJ_STAVES
- && !item_is_rod(item))
- return (true);
-
- if (fs(IODS_BOOKS) && item.base_type == OBJ_BOOKS)
- return (true);
-
- const int refpr = Options.dump_item_origin_price;
- if (refpr == -1)
- return (false);
- if (value == -1)
- value = item_value( item, id, false );
- return (value >= refpr);
-#undef fs
-}
-
- //---------------------------------------------------------------
- //
- // dump_inventory
- //
- //---------------------------------------------------------------
-static void dump_inventory( std::string & text, bool show_prices )
-{
- int i, j;
- char temp_id[4][50];
-
- std::string text2;
-
- for (i = 0; i < 4; i++)
- {
- for (j = 0; j < 50; j++)
- {
- temp_id[i][j] = 1;
- }
- }
-
- char st_pass[ ITEMNAME_SIZE ] = "";
- int inv_class2[OBJ_GOLD];
- int inv_count = 0;
- char tmp_quant[20];
-
- for (i = 0; i < OBJ_GOLD; i++)
- {
- inv_class2[i] = 0;
- }
-
- for (i = 0; i < ENDOFPACK; i++)
- {
- if (is_valid_item( you.inv[i] ))
- {
- // adds up number of each class in invent.
- inv_class2[you.inv[i].base_type]++;
- inv_count++;
- }
- }
-
- if (!inv_count)
- {
- text += "You aren't carrying anything.";
- text += EOL;
- }
- else
- {
- text += " Inventory:";
- text += EOL;
-
- for (i = 0; i < OBJ_GOLD; i++)
- {
- if (inv_class2[i] != 0)
- {
- switch (i)
- {
- case OBJ_WEAPONS: text += "Hand weapons"; break;
- case OBJ_MISSILES: text += "Missiles"; break;
- case OBJ_ARMOUR: text += "Armour"; break;
- case OBJ_WANDS: text += "Magical devices"; break;
- case OBJ_FOOD: text += "Comestibles"; break;
- case OBJ_SCROLLS: text += "Scrolls"; break;
- case OBJ_JEWELLERY: text += "Jewellery"; break;
- case OBJ_POTIONS: text += "Potions"; break;
- case OBJ_BOOKS: text += "Books"; break;
- case OBJ_STAVES: text += "Magical staves"; break;
- case OBJ_ORBS: text += "Orbs of Power"; break;
- case OBJ_MISCELLANY: text += "Miscellaneous"; break;
- case OBJ_CORPSES: text += "Carrion"; break;
-
- default:
- DEBUGSTR("Bad item class");
- }
- text += EOL;
-
- for (j = 0; j < ENDOFPACK; j++)
- {
- if (is_valid_item(you.inv[j]) && you.inv[j].base_type == i)
- {
- text += " ";
-
- in_name( j, DESC_INVENTORY_EQUIP, st_pass );
- text += st_pass;
-
- inv_count--;
-
- int ival = -1;
- if (show_prices)
- {
- text += " (";
-
- itoa( ival =
- item_value( you.inv[j], temp_id, true ),
- tmp_quant, 10 );
-
- text += tmp_quant;
- text += " gold)";
- }
-
- if (origin_describable(you.inv[j])
- && dump_item_origin(you.inv[j], ival))
- {
- text += EOL " (" + origin_desc(you.inv[j]) + ")";
- }
-
- if (is_dumpable_artifact( you.inv[j],
- Options.verbose_dump ))
- {
- text2 = get_item_description( you.inv[j],
- Options.verbose_dump,
- true );
-
- text += munge_description(text2);
- }
- else
- {
- text += EOL;
- }
- }
- }
- }
- }
- }
-} // end dump_inventory()
-
-//---------------------------------------------------------------
-//
-// dump_skills
-//
-//---------------------------------------------------------------
-static void dump_skills( std::string & text )
-{
- char tmp_quant[20];
-
- text += EOL;
- text += EOL;
- text += " Skills:";
- text += EOL;
-
- for (unsigned char i = 0; i < 50; i++)
- {
- if (you.skills[i] > 0)
- {
- text += ( (you.skills[i] == 27) ? " * " :
- (you.practise_skill[i]) ? " + "
- : " - " );
-
- text += "Level ";
- itoa( you.skills[i], tmp_quant, 10 );
- text += tmp_quant;
- text += " ";
- text += skill_name(i);
- text += EOL;
- }
- }
-
- text += EOL;
- text += EOL;
-} // end dump_skills()
-
-//---------------------------------------------------------------
-//
-// Return string of the i-th spell type, with slash if required
-//
-//---------------------------------------------------------------
-static std::string spell_type_name(int spell_class, bool slash)
-{
- std::string ret;
-
- if (slash)
- ret = "/";
-
- ret += spelltype_name(spell_class);
-
- return (ret);
-} // end spell_type_name()
-
-//---------------------------------------------------------------
-//
-// dump_spells
-//
-//---------------------------------------------------------------
-static void dump_spells( std::string & text )
-{
- char tmp_quant[20];
-
-// This array helps output the spell types in the traditional order.
-// this can be tossed as soon as I reorder the enum to the traditional order {dlb}
- const int spell_type_index[] =
- {
- SPTYP_HOLY,
- SPTYP_POISON,
- SPTYP_FIRE,
- SPTYP_ICE,
- SPTYP_EARTH,
- SPTYP_AIR,
- SPTYP_CONJURATION,
- SPTYP_ENCHANTMENT,
- SPTYP_DIVINATION,
- SPTYP_TRANSLOCATION,
- SPTYP_SUMMONING,
- SPTYP_TRANSMIGRATION,
- SPTYP_NECROMANCY,
- 0
- };
-
- int spell_levels = player_spell_levels();
-
- if (spell_levels == 1)
- text += "You have one spell level left.";
- else if (spell_levels == 0)
- text += "You cannot memorise any spells.";
- else
- {
- text += "You have ";
- itoa( spell_levels, tmp_quant, 10 );
- text += tmp_quant;
- text += " spell levels left.";
- }
-
- text += EOL;
-
- if (!you.spell_no)
- {
- text += "You don't know any spells.";
- text += EOL;
-
- }
- else
- {
- text += "You know the following spells:" EOL;
- text += EOL;
-
- text += " Your Spells Type Success Level" EOL;
-
- for (int j = 0; j < 52; j++)
- {
- const char letter = index_to_letter( j );
- const int spell = get_spell_by_letter( letter );
-
- if (spell != SPELL_NO_SPELL)
- {
- std::string spell_line = " ";
-
- char strng[2];
- strng[0] = letter;
- strng[1] = '\0';
-
- spell_line += strng;
- spell_line += " - ";
- spell_line += spell_title( spell );
-
- for (int i = spell_line.length(); i < 34; i++)
- {
- spell_line += ' ';
- }
-
- bool already = false;
-
- for (int i = 0; spell_type_index[i] != 0; i++)
- {
- if (spell_typematch( spell, spell_type_index[i] ))
- {
- spell_line +=
- spell_type_name(spell_type_index[i], already);
- already = true;
- }
- }
-
- if (spell_line.length() > 57)
- spell_line = spell_line.substr(0, 57);
- for (int i = spell_line.length(); i < 58; i++)
- {
- spell_line += ' ';
- }
-
- int fail_rate = spell_fail( spell );
-
- spell_line += (fail_rate == 100) ? "Useless" :
- (fail_rate > 90) ? "Terrible" :
- (fail_rate > 80) ? "Cruddy" :
- (fail_rate > 70) ? "Bad" :
- (fail_rate > 60) ? "Very Poor" :
- (fail_rate > 50) ? "Poor" :
- (fail_rate > 40) ? "Fair" :
- (fail_rate > 30) ? "Good" :
- (fail_rate > 20) ? "Very Good" :
- (fail_rate > 10) ? "Great" :
- (fail_rate > 0) ? "Excellent"
- : "Perfect";
-
- for (int i = spell_line.length(); i < 70; i++)
- spell_line += ' ';
-
- itoa((int) spell_difficulty( spell ), tmp_quant, 10 );
- spell_line += tmp_quant;
- spell_line += EOL;
-
- text += spell_line;
- }
- }
- }
-} // end dump_spells()
-
-
-//---------------------------------------------------------------
-//
-// dump_kills
-//
-//---------------------------------------------------------------
-static void dump_kills( std::string & text )
-{
- text += you.kills.kill_info();
-}
-
-//---------------------------------------------------------------
-//
-// dump_mutations
-//
-//---------------------------------------------------------------
-static void dump_mutations( std::string & text )
-{
- // Can't use how_mutated() here, as it doesn't count demonic powers
- int xz = 0;
-
- for (int xy = 0; xy < 100; xy++)
- {
- if (you.mutation[xy] > 0)
- xz++;
- }
-
- if (xz > 0)
- {
- text += "";
- text += EOL;
- text += " Mutations & Other Weirdness";
- text += EOL;
-
- for (int j = 0; j < 100; j++)
- {
- if (you.mutation[j])
- {
- if (you.demon_pow[j] > 0)
- text += "* ";
-
- text += mutation_name(j);
- text += EOL;
- }
- }
- }
-} // end dump_mutations()
-
-#if MAC
-#pragma mark -
-#endif
-
-// ========================================================================
-// Public Functions
-// ========================================================================
-
-const char *hunger_level(void)
-{
- return ((you.hunger <= 1000) ? "starving" :
- (you.hunger <= 2600) ? "hungry" :
- (you.hunger < 7000) ? "not hungry" :
- (you.hunger < 11000) ? "full" : "completely stuffed");
-}
-
-//---------------------------------------------------------------
-//
-// dump_char
-//
-// Creates a disk record of a character. Returns true if the
-// character was successfully saved.
-//
-//---------------------------------------------------------------
-bool dump_char( const char fname[30], bool show_prices ) // $$$ a try block?
-{
- bool succeeded = false;
-
- std::string text;
-
- // start with enough room for 100 80 character lines
- text.reserve(100 * 80);
-
- text += " Dungeon Crawl Stone Soup version " VERSION " character file.";
- text += EOL;
- text += EOL;
-
- if (Options.detailed_stat_dump)
- dump_stats2(text, show_prices);
- else
- dump_stats(text);
-
- dump_location(text);
- dump_religion(text);
-
- switch (you.burden_state)
- {
- case BS_OVERLOADED:
- text += "You are overloaded with stuff.";
- text += EOL;
- break;
- case BS_ENCUMBERED:
- text += "You are encumbered.";
- text += EOL;
- break;
- }
-
- text += "You are ";
-
- text += hunger_level();
-
- text += ".";
- text += EOL;
- text += EOL;
-
- if (you.attribute[ATTR_TRANSFORMATION])
- {
- switch (you.attribute[ATTR_TRANSFORMATION])
- {
- case TRAN_SPIDER:
- text += "You are in spider-form.";
- break;
- case TRAN_BLADE_HANDS:
- text += "Your hands are blades.";
- break;
- case TRAN_STATUE:
- text += "You are a stone statue.";
- break;
- case TRAN_ICE_BEAST:
- text += "You are a creature of crystalline ice.";
- break;
- case TRAN_DRAGON:
- text += "You are a fearsome dragon!";
- break;
- case TRAN_LICH:
- text += "You are in lich-form.";
- break;
- case TRAN_SERPENT_OF_HELL:
- text += "You are a huge, demonic serpent!";
- break;
- case TRAN_AIR:
- text += "You are a cloud of diffuse gas.";
- break;
- }
-
- text += EOL;
- text += EOL;
- }
-
- dump_inventory(text, show_prices);
-
- char tmp_quant[20];
-
- text += EOL;
- text += EOL;
- text += " You have ";
- itoa( you.exp_available, tmp_quant, 10 );
- text += tmp_quant;
- text += " experience left.";
-
- dump_skills(text);
- dump_spells(text);
- dump_mutations(text);
-
- text += EOL;
- text += EOL;
-
- dump_screenshot(text);
- text += EOL EOL;
-
- dump_kills(text);
-
- char file_name[kPathLen] = "\0";
-
- if (SysEnv.crawl_dir)
- strncpy(file_name, SysEnv.crawl_dir, kPathLen);
-
- strncat(file_name, fname, kPathLen);
-
-#ifdef STASH_TRACKING
- char stash_file_name[kPathLen] = "";
- strncpy(stash_file_name, file_name, kPathLen);
-#endif
- if (strcmp(fname, "morgue.txt") != 0)
- {
- strncat(file_name, ".txt", kPathLen);
-#ifdef STASH_TRACKING
- strncat(stash_file_name, ".lst", kPathLen);
- stashes.dump(stash_file_name);
-#endif
- }
-#ifdef STASH_TRACKING
- else
- {
- // Grr. Filename is morgue.txt, it needs to be morgue.lst
- int len = strlen(stash_file_name);
- stash_file_name[len - 3] = 'l';
- stash_file_name[len - 2] = 's';
- // Fully identified stash dump.
- stashes.dump(stash_file_name, true);
- }
-#endif
-
- FILE *handle = fopen(file_name, "wb");
-
-#if DEBUG_DIAGNOSTICS
- strcpy( info, "File name: " );
- strcat( info, file_name );
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- if (handle != NULL)
- {
- size_t begin = 0;
- size_t end = text.find(EOL);
-
- while (end != std::string::npos)
- {
- end += strlen(EOL);
-
- size_t len = end - begin;
-
- fwrite(text.c_str() + begin, len, 1, handle);
-
- begin = end;
- end = text.find(EOL, end);
- }
-
- fclose(handle);
- succeeded = true;
- }
- else
- mpr("Error opening file.");
-
- return (succeeded);
-} // end dump_char()
diff --git a/stone_soup/crawl-ref/source/chardump.h b/stone_soup/crawl-ref/source/chardump.h
deleted file mode 100644
index 22b03ac8d3..0000000000
--- a/stone_soup/crawl-ref/source/chardump.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * File: chardump.cc
- * Summary: Dumps character info out to the morgue file.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> 4/20/99 JDJ Reformatted, uses string objects, split out
- * 7 functions from dump_char, dumps artifact info.
- */
-
-
-#ifndef CHARDUMP_H
-#define CHARDUMP_H
-
-#include <string>
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - ouch
- * *********************************************************************** */
-bool dump_char( const char fname[30], bool show_prices );
-
-std::string munge_description(const std::string &inStr);
-
-const char *hunger_level(void);
-
-#endif
diff --git a/stone_soup/crawl-ref/source/cloud.cc b/stone_soup/crawl-ref/source/cloud.cc
deleted file mode 100644
index 808c4cce02..0000000000
--- a/stone_soup/crawl-ref/source/cloud.cc
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * File: cloud.cc
- * Summary: Functions related to clouds.
- * Written by: Brent Ross
- *
- * Creating a cloud module so all the cloud stuff can be isolated.
- *
- * Change History (most recent first):
- *
- * <1> Oct 1/2001 BWR Created
- */
-
-#include "AppHdr.h"
-#include "externs.h"
-
-#include "cloud.h"
-#include "stuff.h"
-
-void delete_cloud( int cloud )
-{
- if (env.cloud[ cloud ].type != CLOUD_NONE)
- {
- const int cloud_x = env.cloud[ cloud ].x;
- const int cloud_y = env.cloud[ cloud ].y;
-
- env.cloud[ cloud ].type = CLOUD_NONE;
- env.cloud[ cloud ].decay = 0;
- env.cloud[ cloud ].x = 0;
- env.cloud[ cloud ].y = 0;
- env.cgrid[ cloud_x ][ cloud_y ] = EMPTY_CLOUD;
- env.cloud_no--;
- }
-}
-
-static void new_cloud( int cloud, int type, int x, int y, int decay )
-{
- ASSERT( env.cloud[ cloud ].type == CLOUD_NONE );
-
- env.cloud[ cloud ].type = type;
- env.cloud[ cloud ].decay = decay;
- env.cloud[ cloud ].x = x;
- env.cloud[ cloud ].y = y;
- env.cgrid[ x ][ y ] = cloud;
- env.cloud_no++;
-}
-
-// The current use of this function is for shifting in the abyss, so
-// that clouds get moved along with the rest of the map.
-void move_cloud( int cloud, int new_x, int new_y )
-{
- if (cloud != EMPTY_CLOUD)
- {
- const int old_x = env.cloud[ cloud ].x;
- const int old_y = env.cloud[ cloud ].y;
-
- env.cgrid[ new_x ][ new_y ] = cloud;
- env.cloud[ cloud ].x = new_x;
- env.cloud[ cloud ].y = new_y;
- env.cgrid[ old_x ][ old_y ] = EMPTY_CLOUD;
- }
-}
-
-// Places a cloud with the given stats. May delete old clouds to make way
-// if there are too many (MAX_CLOUDS == 30) on level. Will overwrite an old
-// cloud under some circumstances.
-void place_cloud(unsigned char cl_type, unsigned char ctarget_x,
- unsigned char ctarget_y, unsigned char cl_range)
-{
- int cl_new = -1;
-
- // more compact {dlb}
- const unsigned char target_cgrid = env.cgrid[ctarget_x][ctarget_y];
-
- // that is, another cloud already there {dlb}
- if (target_cgrid != EMPTY_CLOUD)
- {
- if ((env.cloud[ target_cgrid ].type >= CLOUD_GREY_SMOKE
- && env.cloud[ target_cgrid ].type <= CLOUD_STEAM)
- || env.cloud[ target_cgrid ].type == CLOUD_STINK
- || env.cloud[ target_cgrid ].type == CLOUD_BLACK_SMOKE
- || env.cloud[ target_cgrid ].decay <= 20) //soon gone
- {
- cl_new = env.cgrid[ ctarget_x ][ ctarget_y ];
- delete_cloud( env.cgrid[ ctarget_x ][ ctarget_y ] );
- }
- else
- {
- return;
- }
- }
-
- // too many clouds
- if (env.cloud_no >= MAX_CLOUDS)
- {
- // default to random in case there's no low quality clouds
- int cl_del = random2( MAX_CLOUDS );
-
- for (int ci = 0; ci < MAX_CLOUDS; ci++)
- {
- if ((env.cloud[ ci ].type >= CLOUD_GREY_SMOKE
- && env.cloud[ ci ].type <= CLOUD_STEAM)
- || env.cloud[ ci ].type == CLOUD_STINK
- || env.cloud[ ci ].type == CLOUD_BLACK_SMOKE
- || env.cloud[ ci ].decay <= 20) //soon gone
- {
- cl_del = ci;
- break;
- }
- }
-
- delete_cloud( cl_del );
- cl_new = cl_del;
- }
-
- // create new cloud
- if (cl_new != -1)
- new_cloud( cl_new, cl_type, ctarget_x, ctarget_y, cl_range * 10 );
- else
- {
- // find slot for cloud
- for (int ci = 0; ci < MAX_CLOUDS; ci++)
- {
- if (env.cloud[ci].type == CLOUD_NONE) // ie is empty
- {
- new_cloud( ci, cl_type, ctarget_x, ctarget_y, cl_range * 10 );
- break;
- }
- }
- }
-} // end place_cloud();
diff --git a/stone_soup/crawl-ref/source/cloud.h b/stone_soup/crawl-ref/source/cloud.h
deleted file mode 100644
index e11535ca8c..0000000000
--- a/stone_soup/crawl-ref/source/cloud.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * File: cloud.h
- * Summary: Functions related to clouds.
- * Written by: Brent Ross
- *
- * Change History (most recent first):
- *
- * <1> Oct 1/2001 BWR Created
- */
-
-
-#ifndef CLOUD_H
-#define CLOUD_H
-
-#include "externs.h"
-
-void delete_cloud( int cloud );
-void move_cloud( int cloud, int new_x, int new_y );
-
-void place_cloud(unsigned char cl_type, unsigned char ctarget_x, unsigned char ctarget_y, unsigned char cl_range);
-
-#endif
diff --git a/stone_soup/crawl-ref/source/clua.cc b/stone_soup/crawl-ref/source/clua.cc
deleted file mode 100644
index 41e703c2b0..0000000000
--- a/stone_soup/crawl-ref/source/clua.cc
+++ /dev/null
@@ -1,2301 +0,0 @@
-#include "AppHdr.h"
-
-#ifdef CLUA_BINDINGS
-
-#include "clua.h"
-
-#include "abl-show.h"
-#include "command.h"
-#include "chardump.h"
-#include "food.h"
-#include "invent.h"
-#include "initfile.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "items.h"
-#include "item_use.h"
-#include "libutil.h"
-#include "macro.h"
-#include "message.h"
-#include "mon-util.h"
-#include "output.h"
-#include "player.h"
-#include "randart.h"
-#include "skills2.h"
-#include "spl-util.h"
-#include "stuff.h"
-#include "wpn-misc.h"
-
-#include <cstring>
-
-#ifdef HASH_CONTAINERS
-# include <hash_map>
-# define CHMAP HASH_CONTAINER_NS::hash_map
-#else
-# include <map>
-# define CHMAP std::map
-#endif
-
-#include <cctype>
-
-#define CL_RESETSTACK_RETURN(ls, oldtop, retval) \
- if (true) {\
- if (oldtop != lua_gettop(ls)) { \
- lua_settop(ls, oldtop); \
- } \
- return (retval); \
- } \
- else
-
-CLua clua;
-
-CLua::CLua() : _state(NULL), sourced_files(), uniqindex(0L)
-{
-}
-
-CLua::~CLua()
-{
- if (_state)
- lua_close(_state);
-}
-
-// This has the disadvantage of repeatedly trying init_lua if it fails.
-lua_State *CLua::state()
-{
- if (!_state)
- init_lua();
- return _state;
-}
-
-void CLua::setglobal(const char *name)
-{
- lua_setglobal(state(), name);
-}
-
-void CLua::getglobal(const char *name)
-{
- lua_getglobal(state(), name);
-}
-
-std::string CLua::setuniqregistry()
-{
- char name[100];
- snprintf(name, sizeof name, "__cru%lu", uniqindex++);
- lua_pushstring(state(), name);
- lua_insert(state(), -2);
- lua_settable(state(), LUA_REGISTRYINDEX);
-
- return (name);
-}
-
-void CLua::setregistry(const char *name)
-{
- lua_pushstring(state(), name);
- // Slide name round before the value
- lua_insert(state(), -2);
- lua_settable(state(), LUA_REGISTRYINDEX);
-}
-
-void CLua::getregistry(const char *name)
-{
- lua_pushstring(state(), name);
- lua_gettable(state(), LUA_REGISTRYINDEX);
-}
-
-void CLua::save(const char *file)
-{
- if (!_state)
- return;
-
- CLuaSave clsave = { file, NULL };
- callfn("c_save", "u", &clsave);
- if (clsave.handle)
- fclose(clsave.handle);
-}
-
-int CLua::file_write(lua_State *ls)
-{
- if (!lua_islightuserdata(ls, 1))
- {
- luaL_argerror(ls, 1, "Expected filehandle at arg 1");
- return (0);
- }
- CLuaSave *sf = static_cast<CLuaSave *>( lua_touserdata(ls, 1) );
- if (!sf)
- return (0);
-
- FILE *f = sf->get_file();
- if (!f)
- return (0);
-
- const char *text = luaL_checkstring(ls, 2);
- if (text)
- fprintf(f, "%s", text);
- return (0);
-}
-
-FILE *CLua::CLuaSave::get_file()
-{
- if (!handle)
- handle = fopen(filename, "w");
-
- return (handle);
-}
-
-void CLua::set_error(int err, lua_State *ls)
-{
- if (!err)
- {
- error.clear();
- return;
- }
- if (!ls && !(ls = _state))
- {
- error = "<LUA not initialized>";
- return;
- }
- const char *serr = lua_tostring(ls, -1);
- lua_pop(ls, 1);
- error = serr? serr : "<Unknown error>";
-}
-
-int CLua::execstring(const char *s, const char *context)
-{
- lua_State *ls = state();
- int err = luaL_loadbuffer(ls, s, strlen(s), context);
- if (err)
- {
- set_error(err, ls);
- return err;
- }
- err = lua_pcall(ls, 0, 0, 0);
- set_error(err, ls);
- return err;
-}
-
-int CLua::execfile(const char *filename)
-{
- if (sourced_files.find(filename) != sourced_files.end())
- return 0;
-
- sourced_files.insert(filename);
-
- FILE *f = fopen(filename, "r");
- if (f)
- fclose(f);
- else
- {
- error = std::string("Can't read ") + filename;
- return -1;
- }
-
- lua_State *ls = state();
- if (!ls)
- return -1;
-
- int err = luaL_loadfile(ls, filename);
- if (!err)
- err = lua_pcall(ls, 0, 0, 0);
- set_error(err);
- return (err);
-}
-
-bool CLua::runhook(const char *hook, const char *params, ...)
-{
- error.clear();
-
- lua_State *ls = state();
- if (!ls)
- return (false);
-
- // Remember top of stack, for debugging porpoises
- int stack_top = lua_gettop(ls);
- lua_getglobal(ls, hook);
- if (!lua_istable(ls, -1))
- {
- lua_pop(ls, 1);
- CL_RESETSTACK_RETURN( ls, stack_top, false );
- }
- for (int i = 1; ; ++i)
- {
- int currtop = lua_gettop(ls);
- lua_rawgeti(ls, -1, i);
- if (!lua_isfunction(ls, -1))
- {
- lua_pop(ls, 1);
- break;
- }
-
- // So what's on top *is* a function. Call it with the args we have.
- va_list args;
- va_start(args, params);
- calltopfn(ls, params, args);
- va_end(args);
-
- lua_settop(ls, currtop);
- }
- CL_RESETSTACK_RETURN( ls, stack_top, true );
-}
-
-void CLua::fnreturns(const char *format, ...)
-{
- lua_State *ls = _state;
-
- if (!format || !ls)
- return;
-
- va_list args;
- va_start(args, format);
-
- vfnreturns(format, args);
-
- va_end(args);
-}
-
-void CLua::vfnreturns(const char *format, va_list args)
-{
- lua_State *ls = _state;
- int nrets = return_count(ls, format);
- int sp = -nrets - 1;
-
- const char *gs = strchr(format, '>');
- if (gs)
- format = gs + 1;
- else if ((gs = strchr(format, ':')))
- format = gs + 1;
-
- for (const char *run = format; *run; ++run)
- {
- char argtype = *run;
- ++sp;
- switch (argtype)
- {
- case 'u':
- if (lua_islightuserdata(ls, sp))
- *(va_arg(args, void**)) = lua_touserdata(ls, sp);
- break;
- case 'd':
- if (lua_isnumber(ls, sp))
- *(va_arg(args, int*)) = luaL_checkint(ls, sp);
- break;
- case 'b':
- *(va_arg(args, bool *)) = lua_toboolean(ls, sp);
- break;
- case 's':
- {
- const char *s = lua_tostring(ls, sp);
- if (s)
- *(va_arg(args, std::string *)) = s;
- break;
- }
- default:
- break;
- }
-
- }
- // Pop args off the stack
- lua_pop(ls, nrets);
-}
-
-static void push_monster(lua_State *ls, monsters *mons);
-static int push_activity_interrupt(lua_State *ls, activity_interrupt_data *t);
-int CLua::push_args(lua_State *ls, const char *format, va_list args,
- va_list *targ)
-{
- if (!format)
- {
- if (targ)
- va_copy(*targ, args);
- return (0);
- }
-
- const char *cs = strchr(format, ':');
- if (cs)
- format = cs + 1;
-
- int argc = 0;
- for (const char *run = format; *run; run++) {
- if (*run == '>')
- break;
-
- char argtype = *run;
- ++argc;
- switch (argtype) {
- case 'u': // Light userdata
- lua_pushlightuserdata(ls, va_arg(args, void*));
- break;
- case 's': // String
- {
- const char *s = va_arg(args, const char *);
- if (s)
- lua_pushstring(ls, s);
- else
- lua_pushnil(ls);
- break;
- }
- case 'd': // Integer
- lua_pushnumber(ls, va_arg(args, int));
- break;
- case 'L':
- lua_pushnumber(ls, va_arg(args, long));
- break;
- case 'b':
- lua_pushboolean(ls, va_arg(args, int));
- break;
- case 'M':
- push_monster(ls, va_arg(args, monsters *));
- break;
- case 'A':
- argc += push_activity_interrupt(
- ls, va_arg(args, activity_interrupt_data *));
- break;
- default:
- --argc;
- break;
- }
- }
- if (targ)
- va_copy(*targ, args);
- return (argc);
-}
-
-int CLua::return_count(lua_State *ls, const char *format)
-{
- if (!format)
- return (0);
-
- const char *gs = strchr(format, '>');
- if (gs)
- return (strlen(gs + 1));
-
- const char *cs = strchr(format, ':');
- if (cs && isdigit(*format))
- {
- char *es = NULL;
- int ci = strtol(format, &es, 10);
- // We're capping return at 10 here, which is arbitrary, but avoids
- // blowing the stack.
- if (ci < 0)
- ci = 0;
- else if (ci > 5)
- ci = 10;
- return (ci);
- }
- return (0);
-}
-
-bool CLua::calltopfn(lua_State *ls, const char *params, va_list args,
- int retc, va_list *copyto)
-{
- // We guarantee to remove the function from the stack
- int argc = push_args(ls, params, args, copyto);
- if (retc == -1)
- retc = return_count(ls, params);
- int err = lua_pcall(ls, argc, retc, 0);
- set_error(err, ls);
- return (!err);
-}
-
-bool CLua::callbooleanfn(bool def, const char *fn, const char *params, ...)
-{
- error.clear();
- lua_State *ls = state();
- if (!ls)
- return (def);
-
- int stacktop = lua_gettop(ls);
-
- lua_getglobal(ls, fn);
- if (!lua_isfunction(ls, -1))
- {
- lua_pop(ls, 1);
- CL_RESETSTACK_RETURN(ls, stacktop, def);
- }
-
- va_list args;
- va_start(args, params);
- bool ret = calltopfn(ls, params, args, 1);
- if (!ret)
- CL_RESETSTACK_RETURN(ls, stacktop, def);
-
- def = lua_toboolean(ls, -1);
- CL_RESETSTACK_RETURN(ls, stacktop, def);
-}
-
-bool CLua::proc_returns(const char *par) const
-{
- return (strchr(par, '>') != NULL);
-}
-
-bool CLua::callfn(const char *fn, const char *params, ...)
-{
- error.clear();
- lua_State *ls = state();
- if (!ls)
- return (false);
-
- lua_getglobal(ls, fn);
- if (!lua_isfunction(ls, -1))
- {
- lua_pop(ls, 1);
- return (false);
- }
-
- va_list args;
- va_list fnret;
- va_start(args, params);
- bool ret = calltopfn(ls, params, args, -1, &fnret);
- if (ret)
- {
- // If we have a > in format, gather return params now.
- if (proc_returns(params))
- vfnreturns(params, fnret);
- }
- va_end(args);
- va_end(fnret);
- return (ret);
-}
-
-bool CLua::callfn(const char *fn, int nargs, int nret)
-{
- error.clear();
- lua_State *ls = state();
- if (!ls)
- return (false);
-
- lua_getglobal(ls, fn);
- if (!lua_isfunction(ls, -1))
- {
- lua_settop(ls, -nargs - 2);
- return (false);
- }
-
- // Slide the function in front of its args and call it.
- if (nargs)
- lua_insert(ls, -nargs - 1);
- int err = lua_pcall(ls, nargs, nret, 0);
- set_error(err, ls);
- return !err;
-}
-
-// Defined in Kills.cc because the kill bindings refer to Kills.cc local
-// structs
-extern void lua_open_kills(lua_State *ls);
-
-void lua_open_you(lua_State *ls);
-void lua_open_item(lua_State *ls);
-void lua_open_food(lua_State *ls);
-void lua_open_crawl(lua_State *ls);
-void lua_open_file(lua_State *ls);
-void lua_open_options(lua_State *ls);
-void lua_open_monsters(lua_State *ls);
-void lua_open_globals(lua_State *ls);
-
-
-void CLua::init_lua()
-{
- if (_state)
- return;
-
- _state = lua_open();
- if (!_state)
- return;
- luaopen_base(_state);
- luaopen_string(_state);
- luaopen_table(_state);
-
- // Open Crawl bindings
- lua_open_kills(_state);
- lua_open_you(_state);
- lua_open_item(_state);
- lua_open_food(_state);
- lua_open_crawl(_state);
- lua_open_file(_state);
- lua_open_options(_state);
- lua_open_monsters(_state);
-
- lua_open_globals(_state);
-
- load_cmacro();
- load_chooks();
-}
-
-void CLua::load_chooks()
-{
- // All hook names must be chk_????
- static const char *c_hooks =
- "chk_startgame = { }"
- ;
- execstring(c_hooks, "base");
-}
-
-void CLua::load_cmacro()
-{
- static const char *c_macro =
- "function c_macro(fn)"
- " if fn == nil then"
- " if c_macro_coroutine ~= nil then"
- " local coret, mret"
- " coret, mret = coroutine.resume(c_macro_coroutine)"
- " if not coret or not mret then"
- " c_macro_coroutine = nil"
- " c_macro_name = nil"
- " end"
- " if not coret and mret then"
- " error(mret)"
- " end"
- " return (coret and mret)"
- " end"
- " return false"
- " end"
- " if _G[fn] == nil or type(_G[fn]) ~= 'function' then"
- " return false"
- " end"
- " c_macro_name = fn"
- " c_macro_coroutine = coroutine.create(_G[fn]) "
- " return c_macro() "
- "end";
- execstring(c_macro, "base");
-}
-
-/////////////////////////////////////////////////////////////////////
-
-#define LUAWRAP(name, wrapexpr) \
- static int name(lua_State *ls) \
- { \
- wrapexpr; \
- return (0); \
- }
-
-#define LUARET1(name, type, val) \
- static int name(lua_State *ls) \
- { \
- lua_push##type(ls, val); \
- return (1); \
- }
-
-#define LUARET2(name, type, val1, val2) \
- static int name(lua_State *ls) \
- { \
- lua_push##type(ls, val1); \
- lua_push##type(ls, val2); \
- return (2); \
- }
-
-template <class T> T *util_get_userdata(lua_State *ls, int ndx)
-{
- return (lua_islightuserdata(ls, ndx))?
- static_cast<T *>( lua_touserdata(ls, ndx) )
- : NULL;
-}
-
-template <class T> T *clua_get_userdata(lua_State *ls, const char *mt)
-{
- return static_cast<T*>( luaL_checkudata( ls, 1, mt ) );
-}
-
-static void clua_register_metatable(lua_State *ls, const char *tn,
- const luaL_reg *lr,
- int (*gcfn)(lua_State *ls) = NULL)
-{
- int top = lua_gettop(ls);
-
- luaL_newmetatable(ls, tn);
- lua_pushstring(ls, "__index");
- lua_pushvalue(ls, -2);
- lua_settable(ls, -3);
-
- if (gcfn)
- {
- lua_pushstring(ls, "__gc");
- lua_pushcfunction(ls, gcfn);
- lua_settable(ls, -3);
- }
-
- luaL_openlib(ls, NULL, lr, 0);
-
- lua_settop(ls, top);
-}
-
-template <class T> T *clua_new_userdata(
- lua_State *ls, const char *mt)
-{
- void *udata = lua_newuserdata( ls, sizeof(T) );
- luaL_getmetatable(ls, mt);
- lua_setmetatable(ls, -2);
- return static_cast<T*>( udata );
-}
-
-/////////////////////////////////////////////////////////////////////
-// Bindings to get information on the player
-//
-
-static const char *transform_name()
-{
- switch (you.attribute[ATTR_TRANSFORMATION])
- {
- case TRAN_SPIDER:
- return "spider";
- case TRAN_BLADE_HANDS:
- return "blade";
- case TRAN_STATUE:
- return "statue";
- case TRAN_ICE_BEAST:
- return "ice";
- case TRAN_DRAGON:
- return "dragon";
- case TRAN_LICH:
- return "lich";
- case TRAN_SERPENT_OF_HELL:
- return "serpent";
- case TRAN_AIR:
- return "air";
- default:
- return "";
- }
-}
-
-LUARET1(you_turn_is_over, boolean, you.turn_is_over)
-LUARET1(you_name, string, you.your_name)
-LUARET1(you_race, string, species_name(you.species, you.experience_level))
-LUARET1(you_class, string, get_class_name(you.char_class))
-LUARET2(you_hp, number, you.hp, you.hp_max)
-LUARET2(you_mp, number, you.magic_points, you.max_magic_points)
-LUARET1(you_hunger, string, hunger_level())
-LUARET2(you_strength, number, you.strength, you.max_strength)
-LUARET2(you_intelligence, number, you.intel, you.max_intel)
-LUARET2(you_dexterity, number, you.dex, you.max_dex)
-LUARET1(you_exp, number, you.experience_level)
-LUARET1(you_exp_points, number, you.experience)
-LUARET1(you_res_poison, number, player_res_poison(false))
-LUARET1(you_res_fire, number, player_res_fire(false))
-LUARET1(you_res_cold, number, player_res_cold(false))
-LUARET1(you_res_draining, number, player_prot_life(false))
-LUARET1(you_res_shock, number, player_res_electricity(false))
-LUARET1(you_res_statdrain, number, player_sust_abil(false))
-LUARET1(you_res_mutation, number, wearing_amulet(AMU_RESIST_MUTATION, false))
-LUARET1(you_res_slowing, number, wearing_amulet(AMU_RESIST_SLOW, false))
-LUARET1(you_gourmand, boolean, wearing_amulet(AMU_THE_GOURMAND, false))
-LUARET1(you_levitating, boolean,
- player_is_levitating() && !wearing_amulet(AMU_CONTROLLED_FLIGHT))
-LUARET1(you_flying, boolean,
- player_is_levitating() && wearing_amulet(AMU_CONTROLLED_FLIGHT))
-LUARET1(you_transform, string, transform_name())
-LUAWRAP(you_stop_activity, interrupt_activity(AI_FORCE_INTERRUPT))
-
-void lua_push_floor_items(lua_State *ls);
-static int you_floor_items(lua_State *ls)
-{
- lua_push_floor_items(ls);
- return (1);
-}
-
-static int l_you_spells(lua_State *ls)
-{
- lua_newtable(ls);
- int index = 0;
- for (int i = 0; i < 52; ++i)
- {
- const int spell = get_spell_by_letter( index_to_letter(i) );
- if (spell == SPELL_NO_SPELL)
- continue;
-
- lua_pushstring(ls, spell_title(spell));
- lua_rawseti(ls, -2, ++index);
- }
- return (1);
-}
-
-static int l_you_abils(lua_State *ls)
-{
- lua_newtable(ls);
-
- std::vector<const char *>abils = get_ability_names();
- for (int i = 0, size = abils.size(); i < size; ++i)
- {
- lua_pushstring(ls, abils[i]);
- lua_rawseti(ls, -2, i + 1);
- }
- return (1);
-}
-
-static const struct luaL_reg you_lib[] =
-{
- { "turn_is_over", you_turn_is_over },
- { "spells" , l_you_spells },
- { "abilities" , l_you_abils },
- { "name" , you_name },
- { "race" , you_race },
- { "class" , you_class },
- { "hp" , you_hp },
- { "mp" , you_mp },
- { "hunger" , you_hunger },
- { "strength" , you_strength },
- { "intelligence", you_intelligence },
- { "dexterity" , you_dexterity },
- { "exp" , you_exp },
- { "exp_points" , you_exp_points },
-
- { "res_poison" , you_res_poison },
- { "res_fire" , you_res_fire },
- { "res_cold" , you_res_cold },
- { "res_draining", you_res_draining },
- { "res_shock" , you_res_shock },
- { "res_statdrain", you_res_statdrain },
- { "res_mutation", you_res_mutation },
- { "res_slowing", you_res_slowing },
- { "gourmand", you_gourmand },
- { "levitating", you_levitating },
- { "flying", you_flying },
- { "transform", you_transform },
-
- { "stop_activity", you_stop_activity },
-
- { "floor_items", you_floor_items },
- { NULL, NULL },
-};
-
-void lua_open_you(lua_State *ls)
-{
- luaL_openlib(ls, "you", you_lib, 0);
-}
-
-/////////////////////////////////////////////////////////////////////
-// Bindings to get information on items. We must be extremely careful
-// to only hand out information the player already has.
-//
-
-static const item_def *excl_item = NULL;
-
-#define LUA_ITEM(name, n) \
- if (!lua_islightuserdata(ls, n)) \
- { \
- luaL_argerror(ls, n, "Unexpected arg type"); \
- return (0); \
- } \
- \
- item_def *name = static_cast<item_def *>( lua_touserdata(ls, n ) ); \
- if (excl_item && name != excl_item) \
- { \
- luaL_argerror(ls, n, "Unexpected item"); \
- return (0); \
- }
-
-void lua_push_inv_items(lua_State *ls);
-
-void lua_set_exclusive_item(const item_def *item)
-{
- excl_item = item;
-}
-
-static int l_item_inventory(lua_State *ls)
-{
- lua_push_inv_items(ls);
- return (1);
-}
-
-static int l_item_index_to_letter(lua_State *ls)
-{
- int index = luaL_checkint(ls, 1);
- char sletter[2] = "?";
- if (index >= 0 && index <= ENDOFPACK)
- *sletter = index_to_letter(index);
- lua_pushstring(ls, sletter);
- return (1);
-}
-
-static int l_item_letter_to_index(lua_State *ls)
-{
- const char *s = luaL_checkstring(ls, 1);
- if (!s || !*s || s[1])
- return (0);
- lua_pushnumber(ls, letter_to_index(*s));
- return (1);
-}
-
-static int l_item_swap_slots(lua_State *ls)
-{
- int slot1 = luaL_checkint(ls, 1),
- slot2 = luaL_checkint(ls, 2);
- bool verbose = lua_toboolean(ls, 3);
- if (slot1 < 0 || slot1 >= ENDOFPACK ||
- slot2 < 0 || slot2 >= ENDOFPACK ||
- slot1 == slot2 || !is_valid_item(you.inv[slot1]))
- return (0);
-
- swap_inv_slots(slot1, slot2, verbose);
-
- return (0);
-}
-
-static int l_item_wield(lua_State *ls)
-{
- if (you.turn_is_over)
- return (0);
-
- LUA_ITEM(item, 1);
- int slot = -1;
- if (item && is_valid_item(*item) && in_inventory(*item))
- slot = item->link;
- bool res = wield_weapon(true, slot);
- lua_pushboolean(ls, res);
- return (1);
-}
-
-static int l_item_wear(lua_State *ls)
-{
- if (you.turn_is_over)
- return (0);
-
- LUA_ITEM(item, 1);
- if (!item || !in_inventory(*item))
- return (0);
-
- bool success = do_wear_armour(item->link, false);
- lua_pushboolean(ls, success);
- return (1);
-}
-
-static int l_item_puton(lua_State *ls)
-{
- if (you.turn_is_over)
- return (0);
-
- LUA_ITEM(item, 1);
- if (!item || !in_inventory(*item))
- return (0);
-
- lua_pushboolean(ls, puton_ring(item->link, false));
- return (1);
-}
-
-static int l_item_remove(lua_State *ls)
-{
- if (you.turn_is_over)
- {
- mpr("Turn is over");
- return (0);
- }
-
- LUA_ITEM(item, 1);
- if (!item || !in_inventory(*item))
- {
- mpr("Bad item");
- return (0);
- }
-
- int eq = get_equip_slot(item);
- if (eq < 0 || eq >= NUM_EQUIP)
- {
- mpr("Item is not equipped");
- return (0);
- }
-
- bool result = false;
- if (eq == EQ_WEAPON)
- result = wield_weapon(true, -1);
- else if (eq == EQ_LEFT_RING || eq == EQ_RIGHT_RING || eq == EQ_AMULET)
- result = remove_ring(item->link);
- else
- result = takeoff_armour(item->link);
- lua_pushboolean(ls, result);
- return (1);
-}
-
-static int l_item_drop(lua_State *ls)
-{
- if (you.turn_is_over)
- return (0);
-
- LUA_ITEM(item, 1);
- if (!item || !in_inventory(*item))
- return (0);
-
- int eq = get_equip_slot(item);
- if (eq >= 0 && eq < NUM_EQUIP)
- {
- lua_pushboolean(ls, false);
- lua_pushstring(ls, "Can't drop worn items");
- return (2);
- }
-
- int qty = item->quantity;
- if (lua_isnumber(ls, 2))
- {
- int q = luaL_checkint(ls, 2);
- if (q >= 1 && q <= item->quantity)
- qty = q;
- }
- lua_pushboolean(ls, drop_item(item->link, qty));
- return (1);
-}
-
-static int item_on_floor(const item_def &item, int x, int y);
-
-static item_def *dmx_get_item(lua_State *ls, int ndx, int subndx)
-{
- if (lua_istable(ls, ndx))
- {
- lua_rawgeti(ls, ndx, subndx);
- item_def *item = util_get_userdata<item_def>(ls, -1);
- lua_pop(ls, 1);
-
- return (item);
- }
- return util_get_userdata<item_def>(ls, ndx);
-}
-
-static int dmx_get_qty(lua_State *ls, int ndx, int subndx)
-{
- int qty = -1;
- if (lua_istable(ls, ndx))
- {
- lua_rawgeti(ls, ndx, subndx);
- if (lua_isnumber(ls, -1))
- qty = luaL_checkint(ls, -1);
- lua_pop(ls, 1);
- }
- else if (lua_isnumber(ls, ndx))
- {
- qty = luaL_checkint(ls, ndx);
- }
- return (qty);
-}
-
-static bool l_item_pickup2(item_def *item, int qty)
-{
- if (!item || in_inventory(*item))
- return (false);
-
- int floor_link = item_on_floor(*item, you.x_pos, you.y_pos);
- if (floor_link == NON_ITEM)
- return (false);
-
- return pickup_single_item(floor_link, qty);
-}
-
-static int l_item_pickup(lua_State *ls)
-{
- if (you.turn_is_over)
- return (0);
-
- if (lua_islightuserdata(ls, 1))
- {
- LUA_ITEM(item, 1);
- int qty = item->quantity;
- if (lua_isnumber(ls, 2))
- qty = luaL_checkint(ls, 2);
-
- if (l_item_pickup2(item, qty))
- lua_pushnumber(ls, 1);
- else
- lua_pushnil(ls);
- return (1);
- }
- else if (lua_istable(ls, 1))
- {
- int dropped = 0;
- for (int i = 1; ; ++i)
- {
- lua_rawgeti(ls, 1, i);
- item_def *item = dmx_get_item(ls, -1, 1);
- int qty = dmx_get_qty(ls, -1, 2);
- lua_pop(ls, 1);
-
- if (l_item_pickup2(item, qty))
- dropped++;
- else
- {
- // Yes, we bail out on first failure.
- break;
- }
- }
- if (dropped)
- lua_pushnumber(ls, dropped);
- else
- lua_pushnil(ls);
- return (1);
- }
- return (0);
-}
-
-static int l_item_equipped(lua_State *ls)
-{
- int eq = -1;
- if (lua_isnumber(ls, 1))
- eq = luaL_checkint(ls, 1);
- else if (lua_isstring(ls, 1))
- {
- const char *eqname = lua_tostring(ls, 1);
- if (!eqname)
- return (0);
- eq = equip_name_to_slot(eqname);
- }
-
- if (eq < 0 || eq >= NUM_EQUIP)
- return (0);
-
- if (you.equip[eq] != -1)
- lua_pushlightuserdata(ls, &you.inv[you.equip[eq]]);
- else
- lua_pushnil(ls);
-
- return (1);
-}
-
-static int l_item_class(lua_State *ls)
-{
- LUA_ITEM(item, 1);
- if (item)
- {
- bool terse = false;
- if (lua_isboolean(ls, 2))
- terse = lua_toboolean(ls, 2);
-
- std::string s = item_class_name(item->base_type, terse);
- lua_pushstring(ls, s.c_str());
- }
- else
- lua_pushnil(ls);
- return (1);
-}
-
-// FIXME: Fold this back into itemname.cc.
-static const char *ring_types[] = {
- "regeneration",
- "protection",
- "protection from fire",
- "poison resistance",
- "protection from cold",
- "strength",
- "slaying",
- "see invisible",
- "invisibility",
- "hunger",
- "teleportation",
- "evasion",
- "sustain abilities",
- "sustenance",
- "dexterity",
- "intelligence",
- "wizardry",
- "magical power",
- "levitation",
- "life protection",
- "protection from magic",
- "fire",
- "ice",
- "teleport control",
-};
-
-static const char *amulet_types[] = {
- "rage", "resist slowing", "clarity", "warding", "resist corrosion",
- "gourmand", "conservation", "controlled flight", "inaccuracy",
- "resist mutation"
-};
-
-static int l_item_subtype(lua_State *ls)
-{
- LUA_ITEM(item, 1);
- if (item)
- {
- if (item_type_known(*item))
- {
- const char *s = NULL;
- if (item->base_type == OBJ_JEWELLERY)
- {
- if (item->sub_type < AMU_RAGE)
- s = ring_types[item->sub_type];
- else
- s = amulet_types[ item->sub_type - AMU_RAGE ];
- }
-
- if (s)
- lua_pushstring(ls, s);
- else
- lua_pushnil(ls);
-
- lua_pushnumber(ls, item->sub_type);
- return (2);
- }
- }
-
- lua_pushnil(ls);
- lua_pushnil(ls);
- return (2);
-}
-
-static int l_item_cursed(lua_State *ls)
-{
- LUA_ITEM(item, 1);
- bool cursed = item && item_ident(*item, ISFLAG_KNOW_CURSE)
- && item_cursed(*item);
- lua_pushboolean(ls, cursed);
- return (1);
-}
-
-
-static int l_item_worn(lua_State *ls)
-{
- LUA_ITEM(item, 1);
- int worn = get_equip_slot(item);
- if (worn != -1)
- lua_pushnumber(ls, worn);
- else
- lua_pushnil(ls);
- if (worn != -1)
- lua_pushstring(ls, equip_slot_to_name(worn));
- else
- lua_pushnil(ls);
- return (2);
-}
-
-static int desc_code(const char *desc)
-{
- if (!desc)
- return DESC_PLAIN;
-
- if (!strcmp("The", desc))
- return DESC_CAP_THE;
- else if (!strcmp("the", desc))
- return DESC_NOCAP_THE;
- else if (!strcmp("A", desc))
- return DESC_CAP_A;
- else if (!strcmp("a", desc))
- return DESC_NOCAP_A;
- else if (!strcmp("Your", desc))
- return DESC_CAP_YOUR;
- else if (!strcmp("your", desc))
- return DESC_NOCAP_YOUR;
- else if (!strcmp("its", desc))
- return DESC_NOCAP_ITS;
- else if (!strcmp("worn", desc))
- return DESC_INVENTORY_EQUIP;
- else if (!strcmp("inv", desc))
- return DESC_INVENTORY;
-
- return DESC_PLAIN;
-}
-
-static int l_item_name(lua_State *ls)
-{
- LUA_ITEM(item, 1);
- if (item)
- {
- int ndesc = DESC_PLAIN;
- if (lua_isstring(ls, 2))
- ndesc = desc_code(lua_tostring(ls, 2));
- bool terse = lua_toboolean(ls, 3);
- char bufitemname[ITEMNAME_SIZE];
- item_name(*item, ndesc, bufitemname, terse);
-
- lua_pushstring(ls, bufitemname);
- }
- else
- lua_pushnil(ls);
- return (1);
-}
-
-static int l_item_quantity(lua_State *ls)
-{
- LUA_ITEM(item, 1);
- lua_pushnumber(ls, item? item->quantity : 0);
- return (1);
-}
-
-static int l_item_inslot(lua_State *ls)
-{
- int index = luaL_checkint(ls, 1);
- if (index >= 0 && index < 52 && is_valid_item(you.inv[index]))
- lua_pushlightuserdata(ls, &you.inv[index]);
- else
- lua_pushnil(ls);
- return (1);
-}
-
-static int l_item_slot(lua_State *ls)
-{
- LUA_ITEM(item, 1);
- if (item)
- {
- int slot = in_inventory(*item)? item->link :
- letter_to_index(item->slot);
- lua_pushnumber(ls, slot);
- }
- else
- lua_pushnil(ls);
- return (1);
-}
-
-static int l_item_ininventory(lua_State *ls)
-{
- LUA_ITEM(item, 1);
- lua_pushboolean(ls, item && in_inventory(*item));
- return (1);
-}
-
-static int l_item_equip_type(lua_State *ls)
-{
- LUA_ITEM(item, 1);
- if (!item || !is_valid_item(*item))
- return (0);
-
- equipment_type eq = EQ_NONE;
-
- if (item->base_type == OBJ_WEAPONS || item->base_type == OBJ_STAVES)
- eq = EQ_WEAPON;
- else if (item->base_type == OBJ_ARMOUR)
- eq = get_armour_slot(*item);
- else if (item->base_type == OBJ_JEWELLERY)
- eq = item->sub_type >= AMU_RAGE? EQ_AMULET : EQ_RINGS;
-
- if (eq != EQ_NONE)
- {
- lua_pushnumber(ls, eq);
- lua_pushstring(ls, equip_slot_to_name(eq));
- }
- else
- {
- lua_pushnil(ls);
- lua_pushnil(ls);
- }
- return (2);
-}
-
-static int l_item_weap_skill(lua_State *ls)
-{
- LUA_ITEM(item, 1);
- if (!item || !is_valid_item(*item))
- return (0);
-
- int skill = range_skill(*item);
- if (skill == SK_RANGED_COMBAT)
- skill = weapon_skill(*item);
- if (skill == SK_FIGHTING)
- return (0);
-
- lua_pushstring(ls, skill_name(skill));
- lua_pushnumber(ls, skill);
- return (2);
-}
-
-static int l_item_artifact(lua_State *ls)
-{
- LUA_ITEM(item, 1);
- if (!item || !is_valid_item(*item))
- return (0);
-
- lua_pushboolean(ls, item_ident(*item, ISFLAG_KNOW_PROPERTIES)
- && (is_random_artefact(*item) || is_fixed_artefact(*item)));
- return (1);
-}
-
-static int l_item_branded(lua_State *ls)
-{
- LUA_ITEM(item, 1);
- if (!item || !is_valid_item(*item) || !item_ident(*item, ISFLAG_KNOW_TYPE))
- return (0);
-
- bool branded = false;
- switch (item->base_type)
- {
- case OBJ_WEAPONS:
- branded = get_weapon_brand(*item) != SPWPN_NORMAL;
- break;
- case OBJ_ARMOUR:
- branded = get_armour_ego_type(*item) != SPARM_NORMAL;
- break;
- case OBJ_MISSILES:
- branded = get_ammo_brand(*item) != SPMSL_NORMAL;
- break;
- }
- lua_pushboolean(ls, branded);
- return (1);
-}
-
-static const struct luaL_reg item_lib[] =
-{
- { "artifact", l_item_artifact },
- { "branded", l_item_branded },
- { "class", l_item_class },
- { "subtype", l_item_subtype },
- { "cursed", l_item_cursed },
- { "worn", l_item_worn },
- { "name", l_item_name },
- { "quantity", l_item_quantity },
- { "inslot", l_item_inslot },
- { "slot", l_item_slot },
- { "ininventory", l_item_ininventory },
- { "inventory", l_item_inventory },
- { "letter_to_index", l_item_letter_to_index },
- { "index_to_letter", l_item_index_to_letter },
- { "swap_slots", l_item_swap_slots },
- { "wield", l_item_wield },
- { "wear", l_item_wear },
- { "puton", l_item_puton },
- { "remove", l_item_remove },
- { "drop", l_item_drop },
- { "pickup", l_item_pickup },
- { "equipped_at", l_item_equipped },
- { "equip_type", l_item_equip_type },
- { "weap_skill", l_item_weap_skill },
-
- { NULL, NULL },
-};
-
-void lua_open_item(lua_State *ls)
-{
- luaL_openlib(ls, "item", item_lib, 0);
-}
-
-/////////////////////////////////////////////////////////////////////
-// Food information. Some of this information is spoily (such as whether
-// a given chunk is poisonous), but that can't be helped.
-//
-
-static int food_do_eat(lua_State *ls)
-{
- bool eaten = false;
- if (!you.turn_is_over)
- eaten = eat_food(false);
- lua_pushboolean(ls, eaten);
- return (1);
-}
-
-static int food_prompt_floor(lua_State *ls)
-{
- bool eaten = false;
- if (!you.turn_is_over && (eaten = eat_from_floor()))
- burden_change();
- lua_pushboolean(ls, eaten);
- return (1);
-}
-
-static int food_prompt_inventory(lua_State *ls)
-{
- bool eaten = false;
- if (!you.turn_is_over)
- eaten = prompt_eat_from_inventory();
- lua_pushboolean(ls, eaten);
- return (1);
-}
-
-static int food_can_eat(lua_State *ls)
-{
- LUA_ITEM(item, 1);
- bool hungercheck = true;
-
- if (lua_isboolean(ls, 2))
- hungercheck = lua_toboolean(ls, 2);
-
- bool edible = item && can_ingest(item->base_type,
- item->sub_type,
- true,
- true,
- hungercheck);
- lua_pushboolean(ls, edible);
- return (1);
-}
-
-static int item_on_floor(const item_def &item, int x, int y)
-{
- // Check if the item is on the floor and reachable
- for (int link = igrd[x][y]; link != NON_ITEM; link = mitm[link].link)
- {
- if (&mitm[link] == &item)
- return (link);
- }
- return (NON_ITEM);
-}
-
-static bool eat_item(const item_def &item)
-{
- if (in_inventory(item))
- {
- eat_from_inventory(item.link);
- burden_change();
- you.turn_is_over = 1;
-
- return (true);
- }
- else
- {
- int ilink = item_on_floor(item, you.x_pos, you.y_pos);
-
- if (ilink != NON_ITEM)
- {
- eat_floor_item(ilink);
- return (true);
- }
- return (false);
- }
-}
-
-static int food_eat(lua_State *ls)
-{
- LUA_ITEM(item, 1);
-
- bool eaten = false;
- if (!you.turn_is_over)
- {
- // When we get down to eating, we don't care if the eating is courtesy
- // an un-ided amulet of the gourmand.
- bool edible = item && can_ingest(item->base_type,
- item->sub_type,
- false,
- false);
- if (edible)
- eaten = eat_item(*item);
- }
- lua_pushboolean(ls, eaten);
- return (1);
-}
-
-static int food_rotting(lua_State *ls)
-{
- LUA_ITEM(item, 1);
- bool rotting = false;
- if (item && item->base_type == OBJ_FOOD && item->sub_type == FOOD_CHUNK)
- {
- rotting = item->special < 100;
- }
- lua_pushboolean(ls, rotting);
- return (1);
-}
-
-static int food_ischunk(lua_State *ls)
-{
- LUA_ITEM(item, 1);
- lua_pushboolean(ls,
- item && item->base_type == OBJ_FOOD
- && item->sub_type == FOOD_CHUNK);
- return (1);
-}
-
-static const struct luaL_reg food_lib[] =
-{
- { "do_eat", food_do_eat },
- { "prompt_floor", food_prompt_floor },
- { "prompt_inventory", food_prompt_inventory },
- { "can_eat", food_can_eat },
- { "eat", food_eat },
- { "rotting", food_rotting },
- { "ischunk", food_ischunk },
- { NULL, NULL },
-};
-
-void lua_open_food(lua_State *ls)
-{
- luaL_openlib(ls, "food", food_lib, 0);
-}
-
-/////////////////////////////////////////////////////////////////////
-// General game bindings.
-//
-
-static int crawl_mpr(lua_State *ls)
-{
- const char *message = luaL_checkstring(ls, 1);
- if (!message)
- return (0);
-
- int ch = MSGCH_PLAIN;
- const char *channel = lua_tostring(ls, 2);
- if (channel)
- ch = str_to_channel(channel);
- if (ch == -1)
- ch = MSGCH_PLAIN;
-
- mpr(message, ch);
-
- return (0);
-}
-
-LUAWRAP(crawl_mesclr, mesclr())
-LUAWRAP(crawl_redraw_screen, redraw_screen())
-
-static int crawl_input_line(lua_State *ls)
-{
- // This is arbitrary, but anybody entering so many characters is psychotic.
- char linebuf[500];
-
- get_input_line(linebuf, sizeof linebuf);
- lua_pushstring(ls, linebuf);
- return (1);
-}
-
-static int crawl_c_input_line(lua_State *ls)
-{
- char linebuf[500];
-
- bool valid = cancelable_get_line(linebuf, sizeof linebuf);
- if (valid)
- lua_pushstring(ls, linebuf);
- else
- lua_pushnil(ls);
- return (1);
-}
-
-LUARET1(crawl_getch, number, getch())
-LUARET1(crawl_kbhit, number, kbhit())
-LUAWRAP(crawl_flush_input, flush_input_buffer(FLUSH_LUA))
-
-static void crawl_sendkeys_proc(lua_State *ls, int argi)
-{
- if (lua_isstring(ls, argi))
- {
- const char *keys = luaL_checkstring(ls, argi);
- if (!keys)
- return;
-
- for ( ; *keys; ++keys)
- macro_buf_add(*keys);
- }
- else if (lua_istable(ls, argi))
- {
- for (int i = 1; ; ++i)
- {
- lua_rawgeti(ls, argi, i);
- if (lua_isnil(ls, -1))
- {
- lua_pop(ls, 1);
- return;
- }
-
- crawl_sendkeys_proc(ls, lua_gettop(ls));
- lua_pop(ls, 1);
- }
- }
- else if (lua_isnumber(ls, argi))
- {
- int key = luaL_checkint(ls, argi);
- macro_buf_add(key);
- }
-}
-
-static int crawl_sendkeys(lua_State *ls)
-{
- int top = lua_gettop(ls);
- for (int i = 1; i <= top; ++i)
- crawl_sendkeys_proc(ls, i);
- return (0);
-}
-
-static int crawl_playsound(lua_State *ls)
-{
- const char *sf = luaL_checkstring(ls, 1);
- if (!sf)
- return (0);
- play_sound(sf);
- return (0);
-}
-
-static int crawl_runmacro(lua_State *ls)
-{
- const char *macroname = luaL_checkstring(ls, 1);
- if (!macroname)
- return (0);
- run_macro(macroname);
- return (0);
-}
-
-static int crawl_setopt(lua_State *ls)
-{
- if (!lua_isstring(ls, 1))
- return (0);
-
- const char *s = lua_tostring(ls, 1);
- if (s)
- {
- // Note that the conditional script can contain nested Lua[ ]Lua code.
- read_options(s, true);
- }
-
- return (0);
-}
-
-static int crawl_bindkey(lua_State *ls)
-{
- const char *s = NULL;
- if (lua_isstring(ls, 1))
- {
- s = lua_tostring(ls, 1);
- }
-
- if (!s || !lua_isfunction(ls, 2) || !lua_gettop(ls) == 2)
- return (0);
-
- lua_pushvalue(ls, 2);
- std::string name = clua.setuniqregistry();
- if (lua_gettop(ls) != 2)
- {
- fprintf(stderr, "Stack top has changed!\n");
- lua_settop(ls, 2);
- }
- macro_userfn(s, name.c_str());
- return (0);
-}
-
-static int crawl_msgch_num(lua_State *ls)
-{
- const char *s = luaL_checkstring(ls, 1);
- if (!s)
- return (0);
- int ch = str_to_channel(s);
- if (ch == -1)
- return (0);
-
- lua_pushnumber(ls, ch);
- return (1);
-}
-
-static int crawl_msgch_name(lua_State *ls)
-{
- int num = luaL_checkint(ls, 1);
- std::string name = channel_to_str(num);
- lua_pushstring(ls, name.c_str());
- return (1);
-}
-
-#define REGEX_METATABLE "crawl.regex"
-#define MESSF_METATABLE "crawl.messf"
-
-static int crawl_regex(lua_State *ls)
-{
- const char *s = luaL_checkstring(ls, 1);
- if (!s)
- return (0);
-
-
- text_pattern **tpudata =
- clua_new_userdata< text_pattern* >(ls, REGEX_METATABLE);
- if (tpudata)
- {
- *tpudata = new text_pattern(s);
- return (1);
- }
- return (0);
-}
-
-static int crawl_regex_find(lua_State *ls)
-{
- text_pattern **pattern =
- clua_get_userdata< text_pattern* >(ls, REGEX_METATABLE);
- if (!pattern)
- return (0);
-
- const char *text = luaL_checkstring(ls, -1);
- if (!text)
- return (0);
-
- lua_pushboolean(ls, (*pattern)->matches(text));
- return (1);
-}
-
-static int crawl_regex_gc(lua_State *ls)
-{
- text_pattern **pattern =
- clua_get_userdata< text_pattern* >(ls, REGEX_METATABLE);
- if (pattern)
- delete *pattern;
- return (0);
-}
-
-static const luaL_reg crawl_regex_ops[] =
-{
- { "matches", crawl_regex_find },
- { NULL, NULL }
-};
-
-static int crawl_message_filter(lua_State *ls)
-{
- const char *pattern = luaL_checkstring(ls, 1);
- if (!pattern)
- return (0);
-
- int num = lua_isnumber(ls, 2)? luaL_checkint(ls, 2) : -1;
- message_filter **mf =
- clua_new_userdata< message_filter* >( ls, MESSF_METATABLE );
- if (mf)
- {
- *mf = new message_filter( num, pattern );
- return (1);
- }
- return (0);
-}
-
-static int crawl_messf_matches(lua_State *ls)
-{
- message_filter **mf =
- clua_get_userdata< message_filter* >(ls, MESSF_METATABLE);
- if (!mf)
- return (0);
-
- const char *pattern = luaL_checkstring(ls, 2);
- int ch = luaL_checkint(ls, 3);
- if (pattern)
- {
- bool filt = (*mf)->is_filtered(ch, pattern);
- lua_pushboolean(ls, filt);
- return (1);
- }
- return (0);
-}
-
-static int crawl_messf_gc(lua_State *ls)
-{
- message_filter **pattern =
- clua_get_userdata< message_filter* >(ls, REGEX_METATABLE);
- if (pattern)
- delete *pattern;
- return (0);
-}
-
-static const luaL_reg crawl_messf_ops[] =
-{
- { "matches", crawl_messf_matches },
- { NULL, NULL }
-};
-
-static int crawl_trim(lua_State *ls)
-{
- const char *s = luaL_checkstring(ls, 1);
- if (!s)
- return (0);
- std::string text = s;
- trim_string(text);
- lua_pushstring(ls, text.c_str());
- return (1);
-}
-
-static int crawl_split(lua_State *ls)
-{
- const char *s = luaL_checkstring(ls, 1),
- *token = luaL_checkstring(ls, 2);
- if (!s || !token)
- return (0);
-
- std::vector<std::string> segs = split_string(token, s);
- lua_newtable(ls);
- for (int i = 0, count = segs.size(); i < count; ++i)
- {
- lua_pushstring(ls, segs[i].c_str());
- lua_rawseti(ls, -2, i + 1);
- }
- return (1);
-}
-
-static const struct luaL_reg crawl_lib[] =
-{
- { "mpr", crawl_mpr },
- { "mesclr", crawl_mesclr },
- { "redraw_screen", crawl_redraw_screen },
- { "input_line", crawl_input_line },
- { "c_input_line", crawl_c_input_line},
- { "getch", crawl_getch },
- { "kbhit", crawl_kbhit },
- { "flush_input", crawl_flush_input },
- { "sendkeys", crawl_sendkeys },
- { "playsound", crawl_playsound },
- { "runmacro", crawl_runmacro },
- { "bindkey", crawl_bindkey },
- { "setopt", crawl_setopt },
- { "msgch_num", crawl_msgch_num },
- { "msgch_name", crawl_msgch_name },
-
- { "regex", crawl_regex },
- { "message_filter", crawl_message_filter },
- { "trim", crawl_trim },
- { "split", crawl_split },
- { NULL, NULL },
-};
-
-void lua_open_crawl(lua_State *ls)
-{
- clua_register_metatable(ls, REGEX_METATABLE, crawl_regex_ops,
- crawl_regex_gc);
- clua_register_metatable(ls, MESSF_METATABLE, crawl_messf_ops,
- crawl_messf_gc);
-
- luaL_openlib(ls, "crawl", crawl_lib, 0);
-}
-
-///////////////////////////////////////////////////////////
-// File operations
-
-
-static const struct luaL_reg file_lib[] =
-{
- { "write", CLua::file_write },
- { NULL, NULL },
-};
-
-void lua_open_file(lua_State *ls)
-{
- luaL_openlib(ls, "file", file_lib, 0);
-}
-
-
-////////////////////////////////////////////////////////////////
-// Option handling
-
-typedef int (*ohandler)(lua_State *ls, const char *name, void *data, bool get);
-struct option_handler
-{
- const char *option;
- void *data;
- ohandler handler;
-};
-
-static int option_hboolean(lua_State *ls, const char *name, void *data,
- bool get)
-{
- if (get)
- {
- lua_pushboolean(ls, *static_cast<bool*>( data ));
- return (1);
- }
- else
- {
- if (lua_isboolean(ls, 3))
- *static_cast<bool*>( data ) = lua_toboolean(ls, 3);
- return (0);
- }
-}
-
-static option_handler handlers[] =
-{
- // Boolean options come first
- { "easy_open", &Options.easy_open, option_hboolean },
- { "verbose_dump", &Options.verbose_dump, option_hboolean },
- { "detailed_stat_dump", &Options.detailed_stat_dump, option_hboolean },
- { "colour_map", &Options.colour_map, option_hboolean },
- { "clean_map", &Options.clean_map, option_hboolean },
- { "show_uncursed", &Options.show_uncursed, option_hboolean },
- { "always_greet", &Options.always_greet, option_hboolean },
- { "easy_open", &Options.easy_open, option_hboolean },
- { "easy_armour", &Options.easy_armour, option_hboolean },
- { "easy_butcher", &Options.easy_butcher, option_hboolean },
- { "terse_hand", &Options.terse_hand, option_hboolean },
- { "delay_message_clear", &Options.delay_message_clear, option_hboolean },
- { "no_dark_brand", &Options.no_dark_brand, option_hboolean },
- { "auto_list", &Options.auto_list, option_hboolean },
- { "lowercase_invocations", &Options.lowercase_invocations,
- option_hboolean },
- { "pickup_thrown", &Options.pickup_thrown, option_hboolean },
- { "pickup_dropped", &Options.pickup_dropped, option_hboolean },
- { "show_waypoints", &Options.show_waypoints, option_hboolean },
- { "item_colour", &Options.item_colour, option_hboolean },
- { "target_zero_exp", &Options.target_zero_exp, option_hboolean },
- { "target_wrap", &Options.target_wrap, option_hboolean },
- { "easy_exit_menu", &Options.easy_exit_menu, option_hboolean },
- { "dos_use_background_intensity", &Options.dos_use_background_intensity,
- option_hboolean },
-};
-
-static const option_handler *get_handler(const char *optname)
-{
- if (optname)
- {
- for (int i = 0, count = sizeof(handlers) / sizeof(*handlers);
- i < count; ++i)
- {
- if (!strcmp(handlers[i].option, optname))
- return &handlers[i];
- }
- }
- return (NULL);
-}
-
-static int option_get(lua_State *ls)
-{
- const char *opt = luaL_checkstring(ls, 2);
- if (!opt)
- return (0);
-
- // Is this a Lua named option?
- game_options::opt_map::iterator i = Options.named_options.find(opt);
- if (i != Options.named_options.end())
- {
- const std::string &ov = i->second;
- lua_pushstring(ls, ov.c_str());
- return (1);
- }
-
- const option_handler *oh = get_handler(opt);
- if (oh)
- return (oh->handler(ls, opt, oh->data, true));
-
- return (0);
-}
-
-static int option_set(lua_State *ls)
-{
- const char *opt = luaL_checkstring(ls, 2);
- if (!opt)
- return (0);
-
- const option_handler *oh = get_handler(opt);
- if (oh)
- oh->handler(ls, opt, oh->data, false);
-
- return (0);
-}
-
-#define OPT_METATABLE "options.optaccess"
-void lua_open_options(lua_State *ls)
-{
- int top = lua_gettop(ls);
-
- luaL_newmetatable(ls, OPT_METATABLE);
- lua_pushstring(ls, "__index");
- lua_pushcfunction(ls, option_get);
- lua_settable(ls, -3);
-
- luaL_getmetatable(ls, OPT_METATABLE);
- lua_pushstring(ls, "__newindex");
- lua_pushcfunction(ls, option_set);
- lua_settable(ls, -3);
-
- lua_settop(ls, top);
-
- // Create dummy userdata to front for our metatable
- int *dummy = static_cast<int *>( lua_newuserdata(ls, sizeof(int)) );
- // Mystic number
- *dummy = 42;
-
- luaL_getmetatable(ls, OPT_METATABLE);
- lua_setmetatable(ls, -2);
-
- clua.setglobal("options");
-}
-
-/////////////////////////////////////////////////////////////////////
-// Monster handling
-
-#define MONS_METATABLE "monster.monsaccess"
-struct MonsterWrap
-{
- monsters *mons;
- long turn;
-};
-
-static int l_mons_name(lua_State *ls, monsters *mons, const char *attr)
-{
- char monnamebuf[ITEMNAME_SIZE]; // Le sigh.
- moname(mons->type, true, DESC_PLAIN, monnamebuf);
- lua_pushstring(ls, monnamebuf);
- return (1);
-}
-
-static int l_mons_x(lua_State *ls, monsters *mons, const char *attr)
-{
- lua_pushnumber(ls, int(mons->x) - int(you.x_pos));
- return (1);
-}
-
-static int l_mons_y(lua_State *ls, monsters *mons, const char *attr)
-{
- lua_pushnumber(ls, int(mons->y) - int(you.y_pos));
- return (1);
-}
-
-struct MonsAccessor {
- const char *attribute;
- int (*accessor)(lua_State *ls, monsters *mons, const char *attr);
-};
-
-static MonsAccessor mons_attrs[] =
-{
- { "name", l_mons_name },
- { "x" , l_mons_x },
- { "y" , l_mons_y },
-};
-
-static int monster_get(lua_State *ls)
-{
- MonsterWrap *mw = clua_get_userdata< MonsterWrap >(ls, MONS_METATABLE);
- if (!mw || mw->turn != you.num_turns || !mw->mons)
- return (0);
-
- const char *attr = luaL_checkstring(ls, 2);
- if (!attr)
- return (0);
-
- for (unsigned i = 0; i < sizeof(mons_attrs) / sizeof(mons_attrs[0]); ++i)
- {
- if (!strcmp(attr, mons_attrs[i].attribute))
- return (mons_attrs[i].accessor(ls, mw->mons, attr));
- }
-
- return (0);
-}
-
-// We currently permit no set operations on monsters
-static int monster_set(lua_State *ls)
-{
- return (0);
-}
-
-static int push_activity_interrupt(lua_State *ls, activity_interrupt_data *t)
-{
- if (!t->data)
- {
- lua_pushnil(ls);
- return 0;
- }
-
- switch (t->apt)
- {
- case AIP_HP_LOSS:
- {
- const ait_hp_loss *ahl = (const ait_hp_loss *) t->data;
- lua_pushnumber(ls, ahl->hp);
- lua_pushnumber(ls, ahl->hurt_type);
- return 1;
- }
- case AIP_INT:
- lua_pushnumber(ls, *(const int *) t->data);
- break;
- case AIP_STRING:
- lua_pushstring(ls, (const char *) t->data);
- break;
- case AIP_MONSTER:
- // FIXME: We're casting away the const...
- push_monster(ls, (monsters *) t->data);
- break;
- default:
- lua_pushnil(ls);
- break;
- }
- return 0;
-}
-
-static void push_monster(lua_State *ls, monsters *mons)
-{
- MonsterWrap *mw = clua_new_userdata< MonsterWrap >(ls, MONS_METATABLE);
- mw->turn = you.num_turns;
- mw->mons = mons;
-}
-
-void lua_open_monsters(lua_State *ls)
-{
- luaL_newmetatable(ls, MONS_METATABLE);
- lua_pushstring(ls, "__index");
- lua_pushcfunction(ls, monster_get);
- lua_settable(ls, -3);
-
- lua_pushstring(ls, "__newindex");
- lua_pushcfunction(ls, monster_set);
- lua_settable(ls, -3);
-
- // Pop the metatable off the stack.
- lua_pop(ls, 1);
-}
-
-//////////////////////////////////////////////////////////////////////
-// Miscellaneous globals
-
-#define PATTERN_FLUSH_CEILING 100
-
-typedef CHMAP<std::string, text_pattern> pattern_map;
-static pattern_map pattern_cache;
-
-static text_pattern &get_text_pattern(const std::string &s, bool checkcase)
-{
- pattern_map::iterator i = pattern_cache.find(s);
- if (i != pattern_cache.end())
- return i->second;
-
- if (pattern_cache.size() > PATTERN_FLUSH_CEILING)
- pattern_cache.clear();
-
- pattern_cache[s] = text_pattern(s, !checkcase);
- return pattern_cache[s];
-}
-
-static int lua_pmatch(lua_State *ls)
-{
- const char *pattern = luaL_checkstring(ls, 1);
- if (!pattern)
- return (0);
-
- const char *text = luaL_checkstring(ls, 2);
- if (!text)
- return (0);
-
- bool checkcase = true;
- if (lua_isboolean(ls, 3))
- checkcase = lua_toboolean(ls, 3);
-
- text_pattern &tp = get_text_pattern(pattern, checkcase);
- lua_pushboolean( ls, tp.matches(text) );
- return (1);
-}
-
-void lua_open_globals(lua_State *ls)
-{
- lua_pushcfunction(ls, lua_pmatch);
- lua_setglobal(ls, "pmatch");
-}
-
-
-////////////////////////////////////////////////////////////////////////
-// lua_text_pattern
-
-// We could simplify this a great deal by just using lex and yacc, but I
-// don't know if we want to introduce them.
-
-struct lua_pat_op {
- const char *token;
- const char *luatok;
-
- bool pretext; // Does this follow a pattern?
- bool posttext; // Is this followed by a pattern?
-};
-
-static lua_pat_op pat_ops[] = {
- { "<<", " ( ", false, true },
- { ">>", " ) ", true, false },
- { "!!", " not ", false, true },
- { "==", " == ", true, true },
- { "^^", " ~= ", true, true },
- { "&&", " and ", true, true },
- { "||", " or ", true, true },
-};
-
-unsigned long lua_text_pattern::lfndx = 0L;
-
-bool lua_text_pattern::is_lua_pattern(const std::string &s)
-{
- for (int i = 0, size = sizeof(pat_ops) / sizeof(*pat_ops);
- i < size; ++i)
- {
- if (s.find(pat_ops[i].token) != std::string::npos)
- return (true);
- }
- return (false);
-}
-
-lua_text_pattern::lua_text_pattern(const std::string &_pattern)
- : translated(false), isvalid(true), pattern(_pattern), lua_fn_name()
-{
- lua_fn_name = new_fn_name();
-}
-
-lua_text_pattern::~lua_text_pattern()
-{
- if (translated && !lua_fn_name.empty())
- {
- lua_State *ls = clua;
- if (ls)
- {
- lua_pushnil(ls);
- clua.setglobal(lua_fn_name.c_str());
- }
- }
-}
-
-bool lua_text_pattern::valid() const
-{
- return translated? isvalid : translate();
-}
-
-bool lua_text_pattern::matches( const std::string &s ) const
-{
- if (isvalid && !translated)
- translate();
-
- if (!isvalid)
- return (false);
-
- return clua.callbooleanfn(false, lua_fn_name.c_str(), "s", s.c_str());
-}
-
-void lua_text_pattern::pre_pattern(std::string &pat, std::string &fn) const
-{
- // Trim trailing spaces
- pat.erase( pat.find_last_not_of(" \t\n\r") + 1 );
-
- fn += " pmatch([[";
- fn += pat;
- fn += "]], text, false) ";
-
- pat.clear();
-}
-
-void lua_text_pattern::post_pattern(std::string &pat, std::string &fn) const
-{
- pat.erase( 0, pat.find_first_not_of(" \t\n\r") );
-
- fn += " pmatch([[";
- fn += pat;
- fn += "]], text, false) ";
-
- pat.clear();
-}
-
-std::string lua_text_pattern::new_fn_name()
-{
- char buf[100];
- snprintf(buf, sizeof buf, "__ch_stash_search_%lu", lfndx++);
- return (buf);
-}
-
-bool lua_text_pattern::translate() const
-{
- if (translated || !isvalid)
- return false;
-
- std::string textp;
- std::string luafn;
- const lua_pat_op *currop = NULL;
- for (std::string::size_type i = 0; i < pattern.length(); ++i)
- {
- bool match = false;
- for (unsigned p = 0; p < sizeof pat_ops / sizeof *pat_ops; ++p)
- {
- const lua_pat_op &lop = pat_ops[p];
- if (pattern.find(lop.token, i) == i)
- {
- match = true;
- if (lop.pretext && (!currop || currop->posttext))
- {
- if (currop)
- textp.erase(0, textp.find_first_not_of(" \r\n\t"));
- pre_pattern(textp, luafn);
- }
-
- currop = &lop;
- luafn += lop.luatok;
-
- i += strlen( lop.token ) - 1;
-
- break;
- }
- }
-
- if (match)
- continue;
-
- textp += pattern[i];
- }
-
- if (currop && currop->posttext)
- post_pattern(textp, luafn);
-
- luafn = "function " + lua_fn_name + "(text) return " + luafn + " end";
-
- const_cast<lua_text_pattern *>(this)->translated = true;
-
- int err = clua.execstring( luafn.c_str(), "stash-search" );
- if (err)
- {
- lua_text_pattern *self = const_cast<lua_text_pattern *>(this);
- self->isvalid = self->translated = false;
- }
-
- return translated;
-}
-
-#endif // CLUA_BINDINGS
diff --git a/stone_soup/crawl-ref/source/clua.h b/stone_soup/crawl-ref/source/clua.h
deleted file mode 100644
index 88f0f45cc0..0000000000
--- a/stone_soup/crawl-ref/source/clua.h
+++ /dev/null
@@ -1,122 +0,0 @@
-#ifndef __CLUA_H__
-#define __CLUA_H__
-
-#include "AppHdr.h"
-
-#ifdef CLUA_BINDINGS
-
-extern "C" {
-#include <lua.h>
-#include <lauxlib.h>
-#include <lualib.h>
-}
-
-#include <cstdio>
-#include <cstdarg>
-#include <string>
-#include <set>
-
-#include "libutil.h"
-#include "externs.h"
-
-class CLua
-{
-public:
- CLua();
- ~CLua();
-
- lua_State *state();
-
- operator lua_State * ()
- {
- return state();
- }
-
- void save(const char *filename);
-
- void setglobal(const char *name);
- void getglobal(const char *name);
-
- // Assigns the value on top of the stack to a unique name in the registry
- // and returns the name.
- std::string setuniqregistry();
-
- void setregistry(const char *name);
- void getregistry(const char *name);
-
- int execstring(const char *str, const char *context = "init.txt");
- int execfile(const char *filename);
-
- bool callbooleanfn(bool defval, const char *fn, const char *params, ...);
- bool callfn(const char *fn, int nargs, int nret = 1);
- bool callfn(const char *fn, const char *params, ...);
- void fnreturns(const char *params, ...);
- bool runhook(const char *hook, const char *params, ...);
-
- static int file_write(lua_State *ls);
-
- std::string error;
-private:
- lua_State *_state;
- typedef std::set<std::string> sfset;
- sfset sourced_files;
- unsigned long uniqindex;
-
- void init_lua();
- void set_error(int err, lua_State *ls = NULL);
- void load_cmacro();
- void load_chooks();
-
- void vfnreturns(const char *par, va_list va);
-
- bool proc_returns(const char *par) const;
-
- bool calltopfn(lua_State *ls, const char *format, va_list args,
- int retc = -1, va_list *fnr = NULL);
-
- int push_args(lua_State *ls, const char *format, va_list args,
- va_list *cpto = NULL);
- int return_count(lua_State *ls, const char *format);
-
- struct CLuaSave
- {
- const char *filename;
- FILE *handle;
-
- FILE *get_file();
- };
-};
-
-class lua_text_pattern : public base_pattern
-{
-public:
- lua_text_pattern(const std::string &pattern);
- ~lua_text_pattern();
-
- bool valid() const;
- bool matches(const std::string &s) const;
-
- static bool is_lua_pattern(const std::string &s);
-
-private:
- bool translated;
- bool isvalid;
- std::string pattern;
- std::string lua_fn_name;
-
- static unsigned long lfndx;
-
- bool translate() const;
- void pre_pattern(std::string &pat, std::string &fn) const;
- void post_pattern(std::string &pat, std::string &fn) const;
-
- static std::string new_fn_name();
-};
-
-extern CLua clua;
-
-void lua_set_exclusive_item(const item_def *item = NULL);
-
-#endif // CLUA_BINDINGS
-
-#endif
diff --git a/stone_soup/crawl-ref/source/command.cc b/stone_soup/crawl-ref/source/command.cc
deleted file mode 100644
index eb2bc068d2..0000000000
--- a/stone_soup/crawl-ref/source/command.cc
+++ /dev/null
@@ -1,553 +0,0 @@
-/*
- * File: command.cc
- * Summary: Misc commands.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <4> 10/12/99 BCR BUILD_DATE is now used in version()
- * <3> 6/13/99 BWR New equipment listing commands
- * <2> 5/20/99 BWR Swapping inventory letters.
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "command.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "externs.h"
-
-#include "abl-show.h"
-#include "invent.h"
-#include "itemname.h"
-#include "item_use.h"
-#include "items.h"
-#include "menu.h"
-#include "ouch.h"
-#include "spl-cast.h"
-#include "spl-util.h"
-#include "stuff.h"
-#include "version.h"
-#include "wpn-misc.h"
-
-static void adjust_item(void);
-static void adjust_spells(void);
-static void adjust_ability(void);
-
-void quit_game(void)
-{
- if (yesno("Really quit?", false, 'n'))
- ouch(-9999, 0, KILLED_BY_QUITTING);
-} // end quit_game()
-
-static const char *features[] = {
- "",
-#ifdef STASH_TRACKING
- "Stash-tracking",
-#endif
-
-#ifdef CLUA_BINDINGS
- "Lua",
-#endif
-
-#if defined(REGEX_POSIX)
- "POSIX regexps",
-#elif defined(REGEX_PCRE)
- "PCRE regexps",
-#else
- "Glob patterns",
-#endif
-};
-
-void version(void)
-{
- mpr( "This is Dungeon Crawl Stone Soup " VERSION " (" BUILD_DATE ")." );
-
- std::string feats = "Features: ";
- for (int i = 1, size = sizeof features / sizeof *features; i < size; ++i)
- {
- if (i > 1)
- feats += ", ";
- feats += features[i];
- }
- mpr(feats.c_str());
-} // end version()
-
-void adjust(void)
-{
- mpr( "Adjust (i)tems, (s)pells, or (a)bilities?", MSGCH_PROMPT );
-
- unsigned char keyin = tolower( get_ch() );
-
- if (keyin == 'i')
- adjust_item();
- else if (keyin == 's')
- adjust_spells();
- else if (keyin == 'a')
- adjust_ability();
- else if (keyin == ESCAPE)
- canned_msg( MSG_OK );
- else
- canned_msg( MSG_HUH );
-} // end adjust()
-
-void swap_inv_slots(int from_slot, int to_slot, bool verbose)
-{
- // swap items
- item_def tmp = you.inv[to_slot];
- you.inv[to_slot] = you.inv[from_slot];
- you.inv[from_slot] = tmp;
-
- you.inv[from_slot].link = from_slot;
- you.inv[to_slot].link = to_slot;
-
- for (int i = 0; i < NUM_EQUIP; i++)
- {
- if (you.equip[i] == from_slot)
- you.equip[i] = to_slot;
- else if (you.equip[i] == to_slot)
- you.equip[i] = from_slot;
- }
-
- if (verbose)
- {
- char str_pass[ ITEMNAME_SIZE ];
- in_name( to_slot, DESC_INVENTORY_EQUIP, str_pass );
- mpr( str_pass );
-
- if (is_valid_item( you.inv[from_slot] ))
- {
- in_name( from_slot, DESC_INVENTORY_EQUIP, str_pass );
- mpr( str_pass );
- }
- }
-
- if (to_slot == you.equip[EQ_WEAPON] || from_slot == you.equip[EQ_WEAPON])
- you.wield_change = true;
-}
-
-static void adjust_item(void)
-{
- int from_slot, to_slot;
- char str_pass[ ITEMNAME_SIZE ];
-
- if (inv_count() < 1)
- {
- canned_msg(MSG_NOTHING_CARRIED);
- return;
- }
-
- from_slot = prompt_invent_item( "Adjust which item?", -1 );
- if (from_slot == PROMPT_ABORT)
- {
- canned_msg( MSG_OK );
- return;
- }
-
- in_name( from_slot, DESC_INVENTORY_EQUIP, str_pass );
- mpr( str_pass );
-
- to_slot = prompt_invent_item( "Adjust to which letter?", -1, false, false );
- if (to_slot == PROMPT_ABORT)
- {
- canned_msg( MSG_OK );
- return;
- }
-
- swap_inv_slots(from_slot, to_slot, true);
-} // end adjust_item()
-
-static void adjust_spells_cleanup(bool needs_redraw)
-{
- if (needs_redraw)
- redraw_screen();
-}
-
-static void adjust_spells(void)
-{
- unsigned char index_1, index_2;
- unsigned char nthing = 0;
-
- bool needs_redraw = false;
-
- if (!you.spell_no)
- {
- mpr("You don't know any spells.");
- return;
- }
-
- query:
- mpr("Adjust which spell?", MSGCH_PROMPT);
-
- unsigned char keyin = get_ch();
-
- if (keyin == '?' || keyin == '*')
- {
- if (keyin == '*' || keyin == '?')
- {
- nthing = list_spells();
- needs_redraw = true;
- }
-
- if (isalpha( nthing ) || nthing == ESCAPE)
- keyin = nthing;
- else
- {
- mesclr( true );
- goto query;
- }
- }
-
- if (keyin == ESCAPE)
- {
- adjust_spells_cleanup(needs_redraw);
- canned_msg( MSG_OK );
- return;
- }
-
- int input_1 = (int) keyin;
-
- if (!isalpha( input_1 ))
- {
- adjust_spells_cleanup(needs_redraw);
- mpr("You don't know that spell.");
- return;
- }
-
- index_1 = letter_to_index( input_1 );
- int spell = get_spell_by_letter( input_1 );
-
- if (spell == SPELL_NO_SPELL)
- {
- adjust_spells_cleanup(needs_redraw);
- mpr("You don't know that spell.");
- return;
- }
-
- // print out targeted spell:
- snprintf( info, INFO_SIZE, "%c - %s", input_1, spell_title( spell ) );
- mpr(info);
-
- mpr( "Adjust to which letter?", MSGCH_PROMPT );
-
- keyin = get_ch();
-
- if (keyin == '?' || keyin == '*')
- {
- if (keyin == '*' || keyin == '?')
- {
- nthing = list_spells();
- needs_redraw = true;
- }
-
- if (isalpha( nthing ) || nthing == ESCAPE)
- keyin = nthing;
- else
- {
- mesclr( true );
- goto query;
- }
- }
-
- if (keyin == ESCAPE)
- {
- adjust_spells_cleanup(needs_redraw);
- canned_msg( MSG_OK );
- return;
- }
-
- int input_2 = (int) keyin;
-
- if (!isalpha( input_2 ))
- {
- adjust_spells_cleanup(needs_redraw);
- mpr("What?");
- return;
- }
-
- adjust_spells_cleanup(needs_redraw);
-
- index_2 = letter_to_index( input_2 );
-
- // swap references in the letter table:
- int tmp = you.spell_letter_table[index_2];
- you.spell_letter_table[index_2] = you.spell_letter_table[index_1];
- you.spell_letter_table[index_1] = tmp;
-
- // print out spell in new slot (now at input_2)
- snprintf( info, INFO_SIZE, "%c - %s", input_2,
- spell_title( get_spell_by_letter(input_2) ) );
-
- mpr(info);
-
- // print out other spell if one was involved (now at input_1)
- spell = get_spell_by_letter( input_1 );
- if (spell != SPELL_NO_SPELL)
- {
- snprintf( info, INFO_SIZE, "%c - %s", input_1, spell_title(spell) );
- mpr(info);
- }
-} // end adjust_spells()
-
-static void adjust_ability(void)
-{
- unsigned char index_1, index_2;
- unsigned char nthing = 0;
-
- bool needs_redraw = false;
-
- if (!generate_abilities())
- {
- mpr( "You don't currently have any abilities." );
- return;
- }
-
- query:
- mpr( "Adjust which ability?", MSGCH_PROMPT );
-
- unsigned char keyin = get_ch();
-
- if (keyin == '?' || keyin == '*')
- {
- if (keyin == '*' || keyin == '?')
- {
- nthing = show_abilities();
- needs_redraw = true;
- }
-
- if (isalpha( nthing ) || nthing == ESCAPE)
- keyin = nthing;
- else
- {
- mesclr( true );
- goto query;
- }
- }
-
- if (keyin == ESCAPE)
- {
- adjust_spells_cleanup(needs_redraw);
- canned_msg( MSG_OK );
- return;
- }
-
- int input_1 = (int) keyin;
-
- if (!isalpha( input_1 ))
- {
- adjust_spells_cleanup(needs_redraw);
- mpr("You don't have that ability.");
- return;
- }
-
- index_1 = letter_to_index( input_1 );
-
- if (you.ability_letter_table[index_1] == ABIL_NON_ABILITY)
- {
- adjust_spells_cleanup(needs_redraw);
- mpr("You don't have that ability.");
- return;
- }
-
- // print out targeted spell:
- snprintf( info, INFO_SIZE, "%c - %s", input_1,
- get_ability_name_by_index( index_1 ) );
-
- mpr(info);
-
- mpr( "Adjust to which letter?", MSGCH_PROMPT );
-
- keyin = get_ch();
-
- if (keyin == '?' || keyin == '*')
- {
- if (keyin == '*' || keyin == '?')
- {
- nthing = show_abilities();
- needs_redraw = true;
- }
-
- if (isalpha( nthing ) || nthing == ESCAPE)
- keyin = nthing;
- else
- {
- mesclr( true );
- goto query;
- }
- }
-
- if (keyin == ESCAPE)
- {
- adjust_spells_cleanup(needs_redraw);
- canned_msg( MSG_OK );
- return;
- }
-
- int input_2 = (int) keyin;
-
- if (!isalpha( input_2 ))
- {
- adjust_spells_cleanup(needs_redraw);
- mpr("What?");
- return;
- }
-
- adjust_spells_cleanup(needs_redraw);
-
- index_2 = letter_to_index( input_2 );
-
- // swap references in the letter table:
- int tmp = you.ability_letter_table[index_2];
- you.ability_letter_table[index_2] = you.ability_letter_table[index_1];
- you.ability_letter_table[index_1] = tmp;
-
- // Note: the input_2/index_1 and input_1/index_2 here is intentional.
- // This is because nothing actually moves until generate_abilities is
- // called again... fortunately that has to be done everytime because
- // that's the silly way this system currently works. -- bwr
- snprintf( info, INFO_SIZE, "%c - %s", input_2,
- get_ability_name_by_index( index_1 ) );
-
- mpr(info);
-
- if (you.ability_letter_table[index_1] != ABIL_NON_ABILITY)
- {
- snprintf( info, INFO_SIZE, "%c - %s", input_1,
- get_ability_name_by_index( index_2 ) );
- mpr(info);
- }
-} // end adjust_ability()
-
-void list_armour(void)
-{
- for (int i = EQ_CLOAK; i <= EQ_BODY_ARMOUR; i++)
- {
- int armour_id = you.equip[i];
-
- strcpy( info,
- (i == EQ_CLOAK) ? "Cloak " :
- (i == EQ_HELMET) ? "Helmet " :
- (i == EQ_GLOVES) ? "Gloves " :
- (i == EQ_SHIELD) ? "Shield " :
- (i == EQ_BODY_ARMOUR) ? "Armour " :
-
- (i == EQ_BOOTS
- && !(you.species == SP_CENTAUR || you.species == SP_NAGA))
- ? "Boots " :
- (i == EQ_BOOTS
- && (you.species == SP_CENTAUR || you.species == SP_NAGA))
- ? "Barding"
- : "unknown" );
-
- strcat(info, " : ");
-
- if (armour_id != -1)
- {
- char str_pass[ ITEMNAME_SIZE ];
- in_name(armour_id, DESC_INVENTORY, str_pass);
- strcat(info, str_pass);
- }
- else
- {
- strcat(info, " none");
- }
-
- mpr( info, MSGCH_EQUIPMENT, menu_colour(info) );
- }
-} // end list_armour()
-
-void list_jewellery(void)
-{
- for (int i = EQ_LEFT_RING; i <= EQ_AMULET; i++)
- {
- int jewellery_id = you.equip[i];
-
- strcpy( info, (i == EQ_LEFT_RING) ? "Left ring " :
- (i == EQ_RIGHT_RING) ? "Right ring" :
- (i == EQ_AMULET) ? "Amulet "
- : "unknown " );
-
- strcat(info, " : ");
-
- if (jewellery_id != -1)
- {
- char str_pass[ ITEMNAME_SIZE ];
- in_name(jewellery_id, DESC_INVENTORY, str_pass);
- strcat(info, str_pass);
- }
- else
- {
- strcat(info, " none");
- }
-
- mpr( info, MSGCH_EQUIPMENT, menu_colour(info) );
- }
-} // end list_jewellery()
-
-void list_weapons(void)
-{
- const int weapon_id = you.equip[EQ_WEAPON];
-
- // Output the current weapon
- //
- // Yes, this is already on the screen... I'm outputing it
- // for completeness and to avoid confusion.
- strcpy(info, "Current : ");
-
- if (weapon_id != -1)
- {
- char str_pass[ ITEMNAME_SIZE ];
- in_name( weapon_id, DESC_INVENTORY_EQUIP, str_pass );
- strcat(info, str_pass);
- }
- else
- {
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_BLADE_HANDS)
- strcat(info, " blade hands");
- else
- strcat(info, " empty hands");
- }
-
- mpr(info, MSGCH_EQUIPMENT, menu_colour(info));
-
- // Print out the swap slots
- for (int i = 0; i <= 1; i++)
- {
- // We'll avoid repeating the current weapon for these slots,
- // in order to keep things clean.
- if (weapon_id == i)
- continue;
-
- strcpy(info, (i == 0) ? "Primary : " : "Secondary : ");
-
- if (is_valid_item( you.inv[i] ))
- {
- char str_pass[ ITEMNAME_SIZE ];
- in_name(i, DESC_INVENTORY_EQUIP, str_pass);
- strcat(info, str_pass);
- }
- else
- strcat(info, " none");
-
- mpr(info, MSGCH_EQUIPMENT, menu_colour(info)); // Output slot
- }
-
- // Now we print out the current default fire weapon
- strcpy(info, "Firing : ");
-
- const int item = get_fire_item_index();
-
- if (item == ENDOFPACK)
- strcat(info, " nothing");
- else
- {
- char str_pass[ ITEMNAME_SIZE ];
- in_name( item, DESC_INVENTORY_EQUIP, str_pass );
- strcat( info, str_pass );
- }
-
- mpr( info, MSGCH_EQUIPMENT, menu_colour(info) );
-} // end list_weapons()
diff --git a/stone_soup/crawl-ref/source/command.h b/stone_soup/crawl-ref/source/command.h
deleted file mode 100644
index 7bdd3a9e85..0000000000
--- a/stone_soup/crawl-ref/source/command.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * File: command.cc
- * Summary: Misc commands.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef COMMAND_H
-#define COMMAND_H
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void quit_game(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void version(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void adjust(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void list_weapons(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void list_armour(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void list_jewellery(void);
-
-
-void swap_inv_slots(int slot1, int slot2, bool verbose);
-
-#endif
diff --git a/stone_soup/crawl-ref/source/crawl.gdt b/stone_soup/crawl-ref/source/crawl.gdt
deleted file mode 100644
index 11ea870110..0000000000
--- a/stone_soup/crawl-ref/source/crawl.gdt
+++ /dev/null
Binary files differ
diff --git a/stone_soup/crawl-ref/source/crawl.gpr b/stone_soup/crawl-ref/source/crawl.gpr
deleted file mode 100644
index 9ff1dd051f..0000000000
--- a/stone_soup/crawl-ref/source/crawl.gpr
+++ /dev/null
Binary files differ
diff --git a/stone_soup/crawl-ref/source/debug.cc b/stone_soup/crawl-ref/source/debug.cc
deleted file mode 100644
index eb29e8c9d9..0000000000
--- a/stone_soup/crawl-ref/source/debug.cc
+++ /dev/null
@@ -1,2136 +0,0 @@
-/*
- * File: debug.cc
- * Summary: Debug and wizard related functions.
- * Written by: Linley Henzell and Jesse Jones
- *
- * Change History (most recent first):
- *
- * <4> 14/12/99 LRH Added cast_spec_spell_name()
- * <3> 5/06/99 JDJ Added TRACE.
- * <2> -/--/-- JDJ Added a bunch od debugging macros.
- * Old code is now #if WIZARD.
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "debug.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <time.h>
-#include <ctype.h>
-
-#ifdef DOS
-#include <conio.h>
-#endif
-
-#include "externs.h"
-
-#include "direct.h"
-#include "dungeon.h"
-#include "fight.h"
-#include "invent.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "item_use.h"
-#include "items.h"
-#include "misc.h"
-#include "monplace.h"
-#include "monstuff.h"
-#include "mon-util.h"
-#include "mutation.h"
-#include "player.h"
-#include "randart.h"
-#include "religion.h"
-#include "skills.h"
-#include "skills2.h"
-#include "spl-cast.h"
-#include "spl-util.h"
-#include "stuff.h"
-#include "version.h"
-
-#ifndef WIZARD
-#define WIZARD
-#endif
-
-#if DEBUG && WIN
-#define MyDebugBreak() _asm {int 3}
-#endif
-
-//-----------------------------------
-// Internal Variables
-//
-#if WIN
-static HANDLE sConsole = NULL;
-#endif
-
-// ========================================================================
-// Internal Functions
-// ========================================================================
-
-//---------------------------------------------------------------
-//
-// BreakStrToDebugger
-//
-//---------------------------------------------------------------
-#if DEBUG
-static void BreakStrToDebugger(const char *mesg)
-{
-
-#if OSX
- fprintf(stderr, mesg);
-// raise(SIGINT); // this is what DebugStr() does on OS X according to Tech Note 2030
- int* p = NULL; // but this gives us a stack crawl...
- *p = 0;
-#elif MAC
- unsigned char s[50];
-
- int len = strlen(mesg);
-
- if (len > 255)
- len = 255;
-
- s[0] = (Byte) len;
- BlockMoveData(mesg, s + 1, len);
-
- DebugStr(s);
-
-#elif WIN
- MSG msg; // remove pending quit messages so the message box displays
-
- bool quitting = (bool)::PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT, PM_REMOVE);
-
- char text[2500];
-
- int flags = MB_YESNO + // want abort and ignore buttons
- // (too bad we can't ditch the retry button...)
- MB_ICONERROR + // display the icon for errors
- MB_TASKMODAL + // don't let the user do anything else in the app
- MB_SETFOREGROUND; // bring the app to the front
-
- strcpy(text, mesg);
- strcat(text, "\nDo you want to drop into the debugger?");
-
- int result = MessageBoxA(NULL, text, "Debug Break", flags);
-
- if (result == IDYES)
- MyDebugBreak();
-
- if (quitting)
- PostQuitMessage(msg.wParam);
-
-#else
- fprintf(stderr, "%s\n", mesg);
- abort();
-#endif
-}
-#endif
-
-
-//---------------------------------------------------------------
-//
-// IsDebuggerPresent95
-//
-// From March 1999 Windows Developer's Journal. This should only
-// be called if we're running on Win 95 (normally I'd add an
-// ASSERT, but that's a bit dicy since this is called by ASSERT...)
-//
-//---------------------------------------------------------------
-#if WIN
-static bool IsDebuggerPresent95()
-{
- bool present = false;
-
- const DWORD kDebuggerPresentFlag = 0x000000001;
- const DWORD kProcessDatabaseBytes = 190;
- const DWORD kOffsetFlags = 8;
-
- DWORD threadID = GetCurrentThreadId();
- DWORD processID = GetCurrentProcessId();
- DWORD obfuscator = 0;
-
-#if __MWERKS__
- asm
- {
- mov ax, fs
- mov es, ax
- mov eax, 0x18
- mov eax, es:[eax]
- sub eax, 0x10 xor eax,[threadID] mov[obfuscator], eax
- }
-
-#else
- _asm
- {
- mov ax, fs
- mov es, ax
- mov eax, 18 h
- mov eax, es:[eax]
- sub eax, 10 h xor eax,[threadID] mov[obfuscator], eax
- }
-#endif
-
- const DWORD *processDatabase =
- reinterpret_cast< const DWORD * >(processID ^ obfuscator);
-
- if (!IsBadReadPtr(processDatabase, kProcessDatabaseBytes))
- {
- DWORD flags = processDatabase[kOffsetFlags];
-
- present = (flags & kDebuggerPresentFlag) != 0;
- }
-
- return present;
-}
-#endif
-
-
-//---------------------------------------------------------------
-//
-// IsDebuggerPresent
-//
-//---------------------------------------------------------------
-#if WIN
-bool IsDebuggerPresent()
-{
- bool present = false;
-
- typedef BOOL(WINAPI * IsDebuggerPresentProc) ();
-
- HINSTANCE kernelH = LoadLibrary("KERNEL32.DLL");
-
- if (kernelH != NULL)
- { // should never fail
-
- IsDebuggerPresentProc proc =
- (IsDebuggerPresentProc)::GetProcAddress( kernelH,
- "IsDebuggerPresent" );
-
- if (proc != NULL) // only present in NT and Win 98
- present = proc() != 0;
- else
- present = IsDebuggerPresent95();
- }
-
- return present;
-}
-#endif
-
-
-//---------------------------------------------------------------
-//
-// CreateConsoleWindow
-//
-//---------------------------------------------------------------
-#if WIN
-static void CreateConsoleWindow()
-{
- ASSERT(sConsole == NULL);
-
- // Create the console window
- if (::AllocConsole())
- {
- // Get the console window's handle
- sConsole =::GetStdHandle(STD_ERROR_HANDLE);
- if (sConsole == INVALID_HANDLE_VALUE)
- sConsole = NULL;
-
- // Set some options
- if (sConsole != NULL)
- {
- VERIFY(::SetConsoleTextAttribute(sConsole, FOREGROUND_GREEN));
- // green text on a black background (there doesn't appear to
- // be a way to get black text)
-
- VERIFY(::SetConsoleTitle("Debug Log"));
-
- COORD size = { 80, 120 };
-
- VERIFY(::SetConsoleScreenBufferSize(sConsole, size));
- }
- else
- DEBUGSTR(L "Couldn't get the console window's handle!");
- }
- else
- DEBUGSTR(L "Couldn't allocate the console window!");
-}
-#endif
-
-
-#if DEBUG
-//---------------------------------------------------------------
-//
-// TraceString
-//
-//---------------------------------------------------------------
-static void TraceString(const char *mesg)
-{
- // Write the string to the debug window
-#if WIN
- if (IsDebuggerPresent())
- {
- OutputDebugStringA(mesg); // if you're using CodeWarrior you'll need to enable the "Log System Messages" checkbox to get this working
- }
- else
- {
- if (sConsole == NULL) // otherwise we'll use a console window
- CreateConsoleWindow();
-
- if (sConsole != NULL)
- {
- unsigned long written;
-
- VERIFY(WriteConsoleA(sConsole, mesg, strlen(mesg), &written, NULL));
- }
- }
-#else
- fprintf(stderr, "%s", mesg);
-#endif
-
- // Write the string to the debug log
- static bool inited = false;
- static FILE *file = NULL;
-
- if (!inited)
- {
- ASSERT(file == NULL);
-
- const char *fileName = "DebugLog.txt";
-
- file = fopen(fileName, "w");
- ASSERT(file != NULL);
-
- inited = true;
- }
-
- if (file != NULL)
- {
- fputs(mesg, file);
- fflush(file); // make sure all the output makes it to the file
-
- }
-}
-#endif
-
-#if MAC
-#pragma mark -
-#endif
-
-// ========================================================================
-// Global Functions
-// ========================================================================
-
-//---------------------------------------------------------------
-//
-// AssertFailed
-//
-//---------------------------------------------------------------
-#if DEBUG
-void AssertFailed(const char *expr, const char *file, int line)
-{
- char mesg[512];
-
-#if MAC
- sprintf(mesg, "ASSERT(%s) in %s at line %d failed.", expr, file, line);
-
-#else
- const char *fileName = file + strlen(file); // strip off path
-
- while (fileName > file && fileName[-1] != '\\')
- --fileName;
-
- sprintf(mesg, "ASSERT(%s) in '%s' at line %d failed.", expr, fileName,
- line);
-#endif
-
- BreakStrToDebugger(mesg);
-}
-#endif
-
-
-//---------------------------------------------------------------
-//
-// DEBUGSTR
-//
-//---------------------------------------------------------------
-#if DEBUG
-void DEBUGSTR(const char *format, ...)
-{
- char mesg[2048];
-
- va_list args;
-
- va_start(args, format);
- vsprintf(mesg, format, args);
- va_end(args);
-
- BreakStrToDebugger(mesg);
-}
-#endif
-
-
-//---------------------------------------------------------------
-//
-// TRACE
-//
-//---------------------------------------------------------------
-#if DEBUG
-void TRACE(const char *format, ...)
-{
- char mesg[2048];
-
- va_list args;
-
- va_start(args, format);
- vsprintf(mesg, format, args);
- va_end(args);
-
- TraceString(mesg);
-}
-#endif // DEBUG
-
-//---------------------------------------------------------------
-//
-// debug_prompt_for_monster
-//
-//---------------------------------------------------------------
-#ifdef WIZARD
-
-static int get_monnum(const char *name)
-{
- char search[ITEMNAME_SIZE],
- mname[ITEMNAME_SIZE];
- strncpy(search, name, sizeof search);
- search[ITEMNAME_SIZE - 1] = 0;
- strlwr(search);
-
- int mon = -1;
- for (int i = 0; i < NUM_MONSTERS; i++)
- {
- moname( i, true, DESC_PLAIN, mname );
-
- const char *ptr = strstr( strlwr(mname), search );
- if (ptr != NULL)
- {
- if (ptr == mname)
- {
- // we prefer prefixes over partial matches
- mon = i;
- break;
- }
- else
- mon = i;
- }
- }
- return (mon);
-}
-
-static int debug_prompt_for_monster( void )
-{
- char specs[80];
-
- mpr( "(Hint: 'generated' names, eg 'orc zombie', won't work)", MSGCH_PROMPT );
- mpr( "Which monster by name? ", MSGCH_PROMPT );
- get_input_line( specs, sizeof( specs ) );
-
- if (specs[0] == '\0')
- return (-1);
-
- return (get_monnum(specs));
-}
-#endif
-
-//---------------------------------------------------------------
-//
-// debug_prompt_for_skill
-//
-//---------------------------------------------------------------
-#ifdef WIZARD
-static int debug_prompt_for_skill( const char *prompt )
-{
- char specs[80];
-
- mpr( prompt, MSGCH_PROMPT );
- get_input_line( specs, sizeof( specs ) );
-
- if (specs[0] == '\0')
- return (-1);
-
- int skill = -1;
-
- for (int i = 0; i < NUM_SKILLS; i++)
- {
- // avoid the bad values:
- if (i == SK_UNUSED_1 || (i > SK_UNARMED_COMBAT && i < SK_SPELLCASTING))
- continue;
-
- char sk_name[80];
- strncpy( sk_name, skill_name(i), sizeof( sk_name ) );
-
- char *ptr = strstr( strlwr(sk_name), strlwr(specs) );
- if (ptr != NULL)
- {
- if (ptr == sk_name && strlen(specs) > 0)
- {
- // we prefer prefixes over partial matches
- skill = i;
- break;
- }
- else
- skill = i;
- }
- }
-
- return (skill);
-}
-#endif
-
-//---------------------------------------------------------------
-//
-// debug_change_species
-//
-//---------------------------------------------------------------
-#ifdef WIZARD
-void debug_change_species( void )
-{
- char specs[80];
- int i;
-
- mpr( "What species would you like to be now? " , MSGCH_PROMPT );
- get_input_line( specs, sizeof( specs ) );
-
- if (specs[0] == '\0')
- return;
-
- int sp = -1;
-
- for (int i = SP_HUMAN; i < NUM_SPECIES; i++)
- {
- char sp_name[80];
- strncpy( sp_name, species_name(i, you.experience_level), sizeof( sp_name ) );
-
- char *ptr = strstr( strlwr(sp_name), strlwr(specs) );
- if (ptr != NULL)
- {
- if (ptr == sp_name && strlen(specs) > 0)
- {
- // we prefer prefixes over partial matches
- sp = i;
- break;
- }
- else
- sp = i;
- }
- }
-
- if (sp == -1)
- mpr( "That species isn't available." );
- else
- {
- for (i = 0; i < NUM_SKILLS; i++)
- {
- you.skill_points[i] *= species_skills( i, sp );
- you.skill_points[i] /= species_skills( i, you.species );
- }
-
- you.species = sp;
-
- redraw_screen();
- }
-}
-#endif
-//---------------------------------------------------------------
-//
-// debug_prompt_for_int
-//
-// If nonneg, then it returns a non-negative number or -1 on fail
-// If !nonneg, then it returns an integer, and 0 on fail
-//
-//---------------------------------------------------------------
-#ifdef WIZARD
-static int debug_prompt_for_int( const char *prompt, bool nonneg )
-{
- char specs[80];
-
- mpr( prompt, MSGCH_PROMPT );
- get_input_line( specs, sizeof( specs ) );
-
- if (specs[0] == '\0')
- return (nonneg ? -1 : 0);
-
- char *end;
- int ret = strtol( specs, &end, 10 );
-
- if ((ret < 0 && nonneg) || (ret == 0 && end == specs))
- ret = (nonneg ? -1 : 0);
-
- return (ret);
-}
-#endif
-
-/*
- Some debugging functions, accessable through keys like %, $, &, ) etc when
- a section of code in input() in acr.cc is uncommented.
- */
-
-//---------------------------------------------------------------
-//
-// cast_spec_spell
-//
-//---------------------------------------------------------------
-#ifdef WIZARD
-void cast_spec_spell(void)
-{
- int spell = debug_prompt_for_int( "Cast which spell by number? ", true );
-
- if (spell == -1)
- canned_msg( MSG_OK );
- else
- your_spells( spell, 0, false );
-}
-#endif
-
-
-//---------------------------------------------------------------
-//
-// cast_spec_spell_name
-//
-//---------------------------------------------------------------
-#ifdef WIZARD
-void cast_spec_spell_name(void)
-{
- int i = 0;
- char specs[80];
- char spname[80];
-
- mpr( "Cast which spell by name? ", MSGCH_PROMPT );
- get_input_line( specs, sizeof( specs ) );
-
- for (i = 0; i < NUM_SPELLS; i++)
- {
- strncpy( spname, spell_title(i), sizeof( spname ) );
-
- if (strstr( strlwr(spname), strlwr(specs) ) != NULL)
- {
- your_spells(i, 0, false);
- return;
- }
- }
-
- mpr((one_chance_in(20)) ? "Maybe you should go back to WIZARD school."
- : "I couldn't find that spell.");
-}
-#endif
-
-
-//---------------------------------------------------------------
-//
-// create_spec_monster
-//
-//---------------------------------------------------------------
-#ifdef WIZARD
-void create_spec_monster(void)
-{
- int mon = debug_prompt_for_int( "Create which monster by number? ", true );
-
- if (mon == -1)
- canned_msg( MSG_OK );
- else
- create_monster( mon, 0, BEH_SLEEP, you.x_pos, you.y_pos, MHITNOT, 250 );
-} // end create_spec_monster()
-#endif
-
-
-//---------------------------------------------------------------
-//
-// create_spec_monster_name
-//
-//---------------------------------------------------------------
-#ifdef WIZARD
-void create_spec_monster_name(void)
-{
- int mon = debug_prompt_for_monster();
-
- if (mon == -1)
- {
- mpr("I couldn't find that monster.");
-
- if (one_chance_in(20))
- mpr("Maybe it's hiding.");
- }
- else
- {
- create_monster(mon, 0, BEH_SLEEP, you.x_pos, you.y_pos, MHITNOT, 250);
- }
-} // end create_spec_monster_name()
-#endif
-
-
-//---------------------------------------------------------------
-//
-// level_travel
-//
-//---------------------------------------------------------------
-#ifdef WIZARD
-void level_travel( int delta )
-{
- int old_level = you.your_level;
- int new_level = you.your_level + delta;
-
- if (delta == 0)
- {
- new_level = debug_prompt_for_int( "Travel to which level? ", true ) - 1;
- }
-
- if (new_level < 0 || new_level >= 50)
- {
- mpr( "That level is out of bounds." );
- return;
- }
-
- you.your_level = new_level - 1;
- grd[you.x_pos][you.y_pos] = DNGN_STONE_STAIRS_DOWN_I;
- down_stairs(true, old_level);
- untag_followers();
-} // end level_travel()
-#endif
-
-
-//---------------------------------------------------------------
-//
-// create_spec_object
-//
-//---------------------------------------------------------------
-#ifdef WIZARD
-void create_spec_object(void)
-{
- static int max_subtype[] =
- {
- NUM_WEAPONS,
- NUM_MISSILES,
- NUM_ARMOURS,
- NUM_WANDS,
- NUM_FOODS,
- 0, // unknown I
- NUM_SCROLLS,
- NUM_JEWELLERY,
- NUM_POTIONS,
- 0, // unknown II
- NUM_BOOKS,
- NUM_STAVES,
- 0, // Orbs -- only one, handled specially
- NUM_MISCELLANY,
- 0, // corpses -- handled specially
- 0, // gold -- handled specially
- 0, // "gemstones" -- no items of type
- };
-
- char specs[80];
- char obj_name[ ITEMNAME_SIZE ];
- char keyin;
-
- char * ptr;
- int best_index;
- int mon;
- int i;
-
- int class_wanted = OBJ_UNASSIGNED;
- int type_wanted = -1;
- int special_wanted = 0;
-
- int thing_created;
-
- for (;;)
- {
- mpr(") - weapons ( - missiles [ - armour / - wands ? - scrolls",
- MSGCH_PROMPT);
- mpr("= - jewellery ! - potions : - books | - staves 0 - The Orb",
- MSGCH_PROMPT);
- mpr("} - miscellany X - corpses %% - food $ - gold ESC - exit",
- MSGCH_PROMPT);
-
- mpr("What class of item? ", MSGCH_PROMPT);
-
- keyin = toupper( get_ch() );
-
- if (keyin == ')')
- class_wanted = OBJ_WEAPONS;
- else if (keyin == '(')
- class_wanted = OBJ_MISSILES;
- else if (keyin == '[' || keyin == ']')
- class_wanted = OBJ_ARMOUR;
- else if (keyin == '/' || keyin == '\\')
- class_wanted = OBJ_WANDS;
- else if (keyin == '?')
- class_wanted = OBJ_SCROLLS;
- else if (keyin == '=' || keyin == '"')
- class_wanted = OBJ_JEWELLERY;
- else if (keyin == '!')
- class_wanted = OBJ_POTIONS;
- else if (keyin == ':')
- class_wanted = OBJ_BOOKS;
- else if (keyin == '|')
- class_wanted = OBJ_STAVES;
- else if (keyin == '0' || keyin == 'O')
- class_wanted = OBJ_ORBS;
- else if (keyin == '}' || keyin == '{')
- class_wanted = OBJ_MISCELLANY;
- else if (keyin == 'X')
- class_wanted = OBJ_CORPSES;
- else if (keyin == '%')
- class_wanted = OBJ_FOOD;
- else if (keyin == '$')
- class_wanted = OBJ_GOLD;
- else if (keyin == ESCAPE || keyin == ' '
- || keyin == '\r' || keyin == '\n')
- {
- canned_msg( MSG_OK );
- return;
- }
-
- if (class_wanted != OBJ_UNASSIGNED)
- break;
- }
-
- // allocate an item to play with:
- thing_created = get_item_slot();
- if (thing_created == NON_ITEM)
- {
- mpr( "Could not allocate item." );
- return;
- }
-
- // turn item into appropriate kind:
- if (class_wanted == OBJ_ORBS)
- {
- mitm[thing_created].base_type = OBJ_ORBS;
- mitm[thing_created].sub_type = ORB_ZOT;
- mitm[thing_created].quantity = 1;
- }
- else if (class_wanted == OBJ_GOLD)
- {
- int amount = debug_prompt_for_int( "How much gold? ", true );
- if (amount <= 0)
- {
- canned_msg( MSG_OK );
- return;
- }
-
- mitm[thing_created].base_type = OBJ_GOLD;
- mitm[thing_created].sub_type = 0;
- mitm[thing_created].quantity = amount;
- }
- else if (class_wanted == OBJ_CORPSES)
- {
- mon = debug_prompt_for_monster();
-
- if (mon == -1)
- {
- mpr( "No such monster." );
- return;
- }
-
- mitm[thing_created].base_type = OBJ_CORPSES;
- mitm[thing_created].sub_type = CORPSE_BODY;
- mitm[thing_created].plus = mon;
- mitm[thing_created].plus2 = 0;
- mitm[thing_created].special = 210;
- mitm[thing_created].colour = mons_colour(mon);;
- mitm[thing_created].quantity = 1;
- mitm[thing_created].flags = 0;
- }
- else
- {
- mpr( "What type of item? ", MSGCH_PROMPT );
- get_input_line( specs, sizeof( specs ) );
-
- if (specs[0] == '\0')
- {
- canned_msg( MSG_OK );
- return;
- }
-
- // In order to get the sub-type, we'll fill out the base type...
- // then we're going to iterate over all possible subtype values
- // and see if we get a winner. -- bwr
- mitm[thing_created].base_type = class_wanted;
- mitm[thing_created].sub_type = 0;
- mitm[thing_created].plus = 0;
- mitm[thing_created].plus2 = 0;
- mitm[thing_created].special = 0;
- mitm[thing_created].flags = 0;
- mitm[thing_created].quantity = 1;
- set_ident_flags( mitm[thing_created], ISFLAG_IDENT_MASK );
-
- if (class_wanted == OBJ_ARMOUR)
- {
- if (strstr( "naga barding", specs ))
- {
- mitm[thing_created].sub_type = ARM_NAGA_BARDING;
- }
- else if (strstr( "centaur barding", specs ))
- {
- mitm[thing_created].sub_type = ARM_CENTAUR_BARDING;
- }
- else if (strstr( "wizard's hat", specs ))
- {
- mitm[thing_created].sub_type = ARM_HELMET;
- mitm[thing_created].plus2 = THELM_WIZARD_HAT;
- }
- else if (strstr( "cap", specs ))
- {
- mitm[thing_created].sub_type = ARM_HELMET;
- mitm[thing_created].plus2 = THELM_CAP;
- }
- else if (strstr( "helm", specs ))
- {
- mitm[thing_created].sub_type = ARM_HELMET;
- mitm[thing_created].plus2 = THELM_HELM;
- }
- }
-
- if (!mitm[thing_created].sub_type)
- {
- type_wanted = -1;
- best_index = 10000;
-
- for (i = 0; i < max_subtype[ mitm[thing_created].base_type ]; i++)
- {
- mitm[thing_created].sub_type = i;
- item_name( mitm[thing_created], DESC_PLAIN, obj_name );
-
- ptr = strstr( strlwr(obj_name), strlwr(specs) );
- if (ptr != NULL)
- {
- // earliest match is the winner
- if (ptr - obj_name < best_index)
- {
- mpr( obj_name );
- type_wanted = i;
- best_index = ptr - obj_name;
- }
- }
- }
-
- if (type_wanted == -1)
- {
- // ds -- if specs is a valid int, try using that.
- // Since zero is atoi's copout, the wizard
- // must enter (subtype + 1).
- if (!(type_wanted = atoi(specs)))
- {
- mpr( "No such item." );
- return;
- }
- type_wanted--;
- }
-
- mitm[thing_created].sub_type = type_wanted;
- }
-
- switch (mitm[thing_created].base_type)
- {
- case OBJ_MISSILES:
- mitm[thing_created].quantity = 30;
- // intentional fall-through
- case OBJ_WEAPONS:
- case OBJ_ARMOUR:
- mpr( "What ego type? ", MSGCH_PROMPT );
- get_input_line( specs, sizeof( specs ) );
-
- if (specs[0] != '\0')
- {
- special_wanted = 0;
- best_index = 10000;
-
- for (i = 1; i < 25; i++)
- {
- mitm[thing_created].special = i;
- item_name( mitm[thing_created], DESC_PLAIN, obj_name );
-
- ptr = strstr( strlwr(obj_name), strlwr(specs) );
- if (ptr != NULL)
- {
- // earliest match is the winner
- if (ptr - obj_name < best_index)
- {
- mpr( obj_name );
- special_wanted = i;
- best_index = ptr - obj_name;
- }
- }
- }
-
- mitm[thing_created].special = special_wanted;
- }
- break;
-
- case OBJ_BOOKS:
- if (mitm[thing_created].sub_type == BOOK_MANUAL)
- {
- special_wanted = debug_prompt_for_skill( "A manual for which skill? " );
- if (special_wanted != -1)
- mitm[thing_created].plus = special_wanted;
- else
- mpr( "Sorry, no books on that skill today." );
- }
- break;
-
- case OBJ_WANDS:
- mitm[thing_created].plus = 24;
- break;
-
- case OBJ_STAVES:
- if (item_is_rod( mitm[thing_created] ))
- {
- mitm[thing_created].plus = MAX_ROD_CHARGE * ROD_CHARGE_MULT;
- mitm[thing_created].plus2 = MAX_ROD_CHARGE * ROD_CHARGE_MULT;
- }
- break;
-
- case OBJ_MISCELLANY:
- // Runes to "demonic", decks have 50 cards, ignored elsewhere?
- mitm[thing_created].plus = 50;
- break;
-
- case OBJ_FOOD:
- case OBJ_SCROLLS:
- case OBJ_POTIONS:
- mitm[thing_created].quantity = 12;
- break;
-
- default:
- break;
- }
- }
-
- item_colour( mitm[thing_created] );
-
- move_item_to_grid( &thing_created, you.x_pos, you.y_pos );
-
- if (thing_created != NON_ITEM)
- {
- origin_acquired( mitm[thing_created], AQ_WIZMODE );
- canned_msg( MSG_SOMETHING_APPEARS );
- }
-}
-#endif
-
-
-//---------------------------------------------------------------
-//
-// create_spec_object
-//
-//---------------------------------------------------------------
-#ifdef WIZARD
-void tweak_object(void)
-{
- char specs[50];
- char keyin;
-
- int item = prompt_invent_item( "Tweak which item? ", -1 );
- if (item == PROMPT_ABORT)
- {
- canned_msg( MSG_OK );
- return;
- }
-
- if (item == you.equip[EQ_WEAPON])
- you.wield_change = true;
-
- for (;;)
- {
- void *field_ptr = NULL;
-
- for (;;)
- {
- item_name( you.inv[item], DESC_INVENTORY_EQUIP, info );
- mpr( info );
-
- mpr( "a - plus b - plus2 c - special d - quantity ESC - exit",
- MSGCH_PROMPT );
- mpr( "Which field? ", MSGCH_PROMPT );
-
- keyin = tolower( get_ch() );
-
- if (keyin == 'a')
- field_ptr = &(you.inv[item].plus);
- else if (keyin == 'b')
- field_ptr = &(you.inv[item].plus2);
- else if (keyin == 'c')
- field_ptr = &(you.inv[item].special);
- else if (keyin == 'd')
- field_ptr = &(you.inv[item].quantity);
- else if (keyin == ESCAPE || keyin == ' '
- || keyin == '\r' || keyin == '\n')
- {
- canned_msg( MSG_OK );
- return;
- }
-
- if (keyin >= 'a' && keyin <= 'd')
- break;
- }
-
- if (keyin != 'c')
- {
- const short *const ptr = static_cast< short * >( field_ptr );
- snprintf( info, INFO_SIZE, "Old value: %d (0x%04x)", *ptr, *ptr );
- }
- else
- {
- const long *const ptr = static_cast< long * >( field_ptr );
- snprintf( info, INFO_SIZE, "Old value: %ld (0x%08lx)", *ptr, *ptr );
- }
-
- mpr( info );
-
- mpr( "New value? ", MSGCH_PROMPT );
- get_input_line( specs, sizeof( specs ) );
-
- if (specs[0] == '\0')
- return;
-
- char *end;
- int new_value = strtol( specs, &end, 10 );
-
- if (new_value == 0 && end == specs)
- return;
-
- if (keyin != 'c')
- {
- short *ptr = static_cast< short * >( field_ptr );
- *ptr = new_value;
- }
- else
- {
- long *ptr = static_cast< long * >( field_ptr );
- *ptr = new_value;
- }
- }
-}
-#endif
-
-
-//---------------------------------------------------------------
-//
-// stethoscope
-//
-//---------------------------------------------------------------
-#if DEBUG_DIAGNOSTICS
-
-static const char *enchant_names[] =
-{
- "None",
- "Slow", "Haste", "*BUG-3*", "Fear", "Conf", "Invis",
- "YPois-1", "YPois-2", "YPois-3", "YPois-4",
- "YShug-1", "YShug-2", "YShug-3", "YShug-4",
- "YRot-1", "YRot-2", "YRot-3", "YRot-4",
- "Summon", "Abj-1", "Abj-2", "Abj-3", "Abj-4", "Abj-5", "Abj-6",
- "Corona-1", "Corona-2", "Corona-3", "Corona-4",
- "Charm", "YSticky-1", "YSticky-2", "YSticky-3", "YSticky-4",
- "*BUG-35*", "*BUG-36*", "*BUG-37*",
- "GlowShapeshifter", "Shapeshifter",
- "Tele-1", "Tele-2", "Tele-3", "Tele-4",
- "*BUG-44*", "*BUG-45*", "*BUG-46*", "*BUG-47*", "*BUG-48*", "*BUG-49*",
- "*BUG-50*", "*BUG-51*", "*BUG-52*", "*BUG-53*", "*BUG-54*", "*BUG-55*",
- "*BUG-56*",
- "Pois-1", "Pois-2", "Pois-3", "Pois-4",
- "Sticky-1", "Sticky-2", "Sticky-3", "Sticky-4",
- "OldAbj-1", "OldAbj-2", "OldAbj-3", "OldAbj-4", "OldAbj-5", "OldAbj-6",
- "OldCreatedFriendly", "SleepWary", "Submerged", "Short Lived",
- "*BUG-too big*"
-};
-
-void stethoscope(int mwh)
-{
- struct dist stth;
- int steth_x, steth_y;
- int i, j;
-
- if (mwh != RANDOM_MONSTER)
- i = mwh;
- else
- {
- mpr( "Which monster?", MSGCH_PROMPT );
-
- direction( stth );
-
- if (!stth.isValid)
- return;
-
- if (stth.isTarget)
- {
- steth_x = stth.tx;
- steth_y = stth.ty;
- }
- else
- {
- steth_x = you.x_pos + stth.dx;
- steth_y = you.x_pos + stth.dy;
- }
-
- if (env.cgrid[steth_x][steth_y] != EMPTY_CLOUD)
- {
- snprintf( info, INFO_SIZE, "cloud type: %d delay: %d",
- env.cloud[ env.cgrid[steth_x][steth_y] ].type,
- env.cloud[ env.cgrid[steth_x][steth_y] ].decay );
-
- mpr( info, MSGCH_DIAGNOSTICS );
- }
-
- if (mgrd[steth_x][steth_y] == NON_MONSTER)
- {
- snprintf( info, INFO_SIZE, "item grid = %d", igrd[steth_x][steth_y] );
- mpr( info, MSGCH_DIAGNOSTICS );
- return;
- }
-
- i = mgrd[steth_x][steth_y];
- }
-
- // print type of monster
- snprintf( info, INFO_SIZE, "%s (id #%d; type=%d loc=(%d,%d) align=%s)",
- monam( menv[i].number, menv[i].type, true, DESC_CAP_THE ),
- i, menv[i].type,
- menv[i].x, menv[i].y,
- ((menv[i].attitude == ATT_FRIENDLY) ? "friendly" :
- (menv[i].attitude == ATT_HOSTILE) ? "hostile" :
- (menv[i].attitude == ATT_NEUTRAL) ? "neutral"
- : "unknown alignment") );
-
- mpr( info, MSGCH_DIAGNOSTICS );
-
- // print stats and other info
- snprintf( info, INFO_SIZE,"HD=%d HP=%d/%d AC=%d EV=%d MR=%d SP=%d energy=%d num=%d flags=%02x",
- menv[i].hit_dice,
- menv[i].hit_points, menv[i].max_hit_points,
- menv[i].armour_class, menv[i].evasion,
- mons_resist_magic( &menv[i] ),
- menv[i].speed, menv[i].speed_increment,
- menv[i].number, menv[i].flags );
-
- mpr( info, MSGCH_DIAGNOSTICS );
-
- // print behaviour information
-
- const int hab = monster_habitat( menv[i].type );
-
- snprintf( info, INFO_SIZE, "hab=%s beh=%s(%d) foe=%s(%d) mem=%d target=(%d,%d)",
- ((hab == DNGN_DEEP_WATER) ? "water" :
- (hab == DNGN_LAVA) ? "lava"
- : "floor"),
-
- ((menv[i].behaviour == BEH_SLEEP) ? "sleep" :
- (menv[i].behaviour == BEH_WANDER) ? "wander" :
- (menv[i].behaviour == BEH_SEEK) ? "seek" :
- (menv[i].behaviour == BEH_FLEE) ? "flee" :
- (menv[i].behaviour == BEH_CORNERED) ? "cornered"
- : "unknown"),
- menv[i].behaviour,
-
- ((menv[i].foe == MHITYOU) ? "you" :
- (menv[i].foe == MHITNOT) ? "none" :
- (menv[menv[i].foe].type == -1) ? "unassigned monster"
- : monam( menv[menv[i].foe].number, menv[menv[i].foe].type,
- true, DESC_PLAIN )),
- menv[i].foe,
- menv[i].foe_memory,
-
- menv[i].target_x, menv[i].target_y );
-
- mpr( info, MSGCH_DIAGNOSTICS );
-
- // print resistances
- snprintf( info, INFO_SIZE, "resist: fire=%d cold=%d elec=%d pois=%d neg=%d",
- mons_res_fire( &menv[i] ),
- mons_res_cold( &menv[i] ),
- mons_res_elec( &menv[i] ),
- mons_res_poison( &menv[i] ),
- mons_res_negative_energy( &menv[i] ) );
-
- mpr( info, MSGCH_DIAGNOSTICS );
-
-
- // print enchantments
- strncpy( info, "ench: ", INFO_SIZE );
- for (j = 0; j < 6; j++)
- {
- if (menv[i].enchantment[j] >= NUM_ENCHANTMENTS)
- strncat( info, enchant_names[ NUM_ENCHANTMENTS ], INFO_SIZE );
- else
- strncat( info, enchant_names[ menv[i].enchantment[j] ], INFO_SIZE );
-
- if (strlen( info ) <= 70)
- strncat( info, " ", INFO_SIZE );
- else if (j < 5)
- {
- mpr( info, MSGCH_DIAGNOSTICS );
- strncpy( info, "ench: ", INFO_SIZE );
- }
- }
-
- mpr( info, MSGCH_DIAGNOSTICS );
-
- if (menv[i].type == MONS_PLAYER_GHOST
- || menv[i].type == MONS_PANDEMONIUM_DEMON)
- {
- snprintf( info, INFO_SIZE, "Ghost damage: %d; brand: %d",
- ghost.values[ GVAL_DAMAGE ], ghost.values[ GVAL_BRAND ] );
- mpr( info, MSGCH_DIAGNOSTICS );
- }
-} // end stethoscope()
-#endif
-
-#if DEBUG_ITEM_SCAN
-//---------------------------------------------------------------
-//
-// dump_item
-//
-//---------------------------------------------------------------
-static void dump_item( const char *name, int num, const item_def &item )
-{
- mpr( name, MSGCH_WARN );
-
- snprintf( info, INFO_SIZE, " item #%d: base: %d; sub: %d; plus: %d; plus2: %d; special: %ld",
- num, item.base_type, item.sub_type,
- item.plus, item.plus2, item.special );
-
- mpr( info );
-
- snprintf( info, INFO_SIZE, " quant: %d; colour: %d; ident: 0x%08lx; ident_type: %d",
- item.quantity, item.colour, item.flags,
- get_ident_type( item.base_type, item.sub_type ) );
-
- mpr( info );
-
- snprintf( info, INFO_SIZE, " x: %d; y: %d; link: %d",
- item.x, item.y, item.link );
-
- mpr( info );
-}
-
-//---------------------------------------------------------------
-//
-// debug_item_scan
-//
-//---------------------------------------------------------------
-void debug_item_scan( void )
-{
- int i;
- char name[256];
-
- // unset marks
- for (i = 0; i < MAX_ITEMS; i++)
- mitm[i].flags &= (~ISFLAG_DEBUG_MARK);
-
- // First we're going to check all the stacks on the level:
- for (int x = 0; x < GXM; x++)
- {
- for (int y = 0; y < GYM; y++)
- {
- // These are unlinked monster inventory items -- skip them:
- if (x == 0 && y == 0)
- continue;
-
- // Looking for infinite stacks (ie more links than tems allowed)
- // and for items which have bad coordinates (can't find their stack)
- for (int obj = igrd[x][y]; obj != NON_ITEM; obj = mitm[obj].link)
- {
- // Check for invalid (zero quantity) items that are linked in
- if (!is_valid_item( mitm[obj] ))
- {
- snprintf( info, INFO_SIZE, "Linked invalid item at (%d,%d)!", x, y);
- mpr( info, MSGCH_WARN );
- item_name( mitm[obj], DESC_PLAIN, name );
- dump_item( name, obj, mitm[obj] );
- }
-
- // Check that item knows what stack it's in
- if (mitm[obj].x != x || mitm[obj].y != y)
- {
- snprintf( info, INFO_SIZE, "Item position incorrect at (%d,%d)!", x, y);
- mpr( info, MSGCH_WARN );
- item_name( mitm[obj], DESC_PLAIN, name );
- dump_item( name, obj, mitm[obj] );
- }
-
- // If we run into a premarked item we're in real trouble,
- // this will also keep this from being an infinite loop.
- if (mitm[obj].flags & ISFLAG_DEBUG_MARK)
- {
- snprintf( info, INFO_SIZE, "Potential INFINITE STACK at (%d, %d)", x, y);
- mpr( info, MSGCH_WARN );
- break;
- }
-
- mitm[obj].flags |= ISFLAG_DEBUG_MARK;
- }
- }
- }
-
- // Now scan all the items on the level:
- for (i = 0; i < MAX_ITEMS; i++)
- {
- if (!is_valid_item( mitm[i] ))
- continue;
-
- item_name( mitm[i], DESC_PLAIN, name );
-
- // Don't check (-1,-1) player items or (0,0) monster items
- if ((mitm[i].x > 0 || mitm[i].y > 0)
- && !(mitm[i].flags & ISFLAG_DEBUG_MARK))
- {
- mpr( "Unlinked item:", MSGCH_WARN );
- dump_item( name, i, mitm[i] );
-
- snprintf( info, INFO_SIZE, "igrd(%d,%d) = %d", mitm[i].x, mitm[i].y,
- igrd[ mitm[i].x ][ mitm[i].y ] );
- mpr( info );
-
- // Let's check to see if it's an errant monster object:
- for (int j = 0; j < MAX_MONSTERS; j++)
- {
- for (int k = 0; k < NUM_MONSTER_SLOTS; k++)
- {
- if (menv[j].inv[k] == i)
- {
- snprintf( info, INFO_SIZE, "Held by monster #%d: %s at (%d,%d)",
- j, ptr_monam( &menv[j], DESC_CAP_A ),
- menv[j].x, menv[j].y );
-
- mpr( info );
- }
- }
- }
- }
-
- // Current bad items of interest:
- // -- armour and weapons with large enchantments/illegal special vals
- //
- // -- items described as questionable (the class 100 bug)
- //
- // -- eggplant is an illegal throwing weapon
- //
- // -- bola is an illegal fixed artefact
- //
- // -- items described as buggy (typically adjectives out of range)
- // (note: covers buggy, bugginess, buggily, whatever else)
- //
- if (strstr( name, "questionable" ) != NULL
- || strstr( name, "eggplant" ) != NULL
- || strstr( name, "bola" ) != NULL
- || strstr( name, "bugg" ) != NULL)
- {
- mpr( "Bad item:", MSGCH_WARN );
- dump_item( name, i, mitm[i] );
- }
- else if ((mitm[i].base_type == OBJ_WEAPONS
- && (abs(mitm[i].plus) > 30
- || abs(mitm[i].plus2) > 30
- || (!is_random_artefact( mitm[i] )
- && (mitm[i].special >= 30
- && mitm[i].special < 181))))
-
- || (mitm[i].base_type == OBJ_MISSILES
- && (abs(mitm[i].plus) > 25
- || (!is_random_artefact( mitm[i] )
- && mitm[i].special >= 30)))
-
- || (mitm[i].base_type == OBJ_ARMOUR
- && (abs(mitm[i].plus) > 25
- || (!is_random_artefact( mitm[i] )
- && mitm[i].sub_type != ARM_HELMET
- && mitm[i].special >= 30))))
- {
- mpr( "Bad plus or special value:", MSGCH_WARN );
- dump_item( name, i, mitm[i] );
- }
- }
-
- // Don't want debugging marks interfering with anything else.
- for (i = 0; i < MAX_ITEMS; i++)
- mitm[i].flags &= (~ISFLAG_DEBUG_MARK);
-
- // Quickly scan monsters for "program bug"s.
- for (i = 0; i < MAX_MONSTERS; i++)
- {
- const struct monsters *const monster = &menv[i];
-
- if (monster->type == -1)
- continue;
-
- moname( monster->type, true, DESC_PLAIN, name );
-
- if (strcmp( name, "program bug" ) == 0)
- {
- mpr( "Program bug detected!", MSGCH_WARN );
-
- snprintf( info, INFO_SIZE,
- "Buggy monster detected: monster #%d; position (%d,%d)",
- i, monster->x, monster->y );
-
- mpr( info, MSGCH_WARN );
- }
- }
-}
-#endif
-
-//---------------------------------------------------------------
-//
-// debug_add_skills
-//
-//---------------------------------------------------------------
-#ifdef WIZARD
-void debug_add_skills(void)
-{
- int skill = debug_prompt_for_skill( "Which skill (by name)? " );
-
- if (skill == -1)
- mpr("That skill doesn't seem to exist.");
- else
- {
- mpr("Exercising...");
- exercise(skill, 100);
- }
-} // end debug_add_skills()
-#endif
-
-//---------------------------------------------------------------
-//
-// debug_set_skills
-//
-//---------------------------------------------------------------
-#ifdef WIZARD
-void debug_set_skills(void)
-{
- int skill = debug_prompt_for_skill( "Which skill (by name)? " );
-
- if (skill == -1)
- mpr("That skill doesn't seem to exist.");
- else
- {
- mpr( skill_name(skill) );
- int amount = debug_prompt_for_int( "To what level? ", true );
-
- if (amount == -1)
- canned_msg( MSG_OK );
- else
- {
- const int points = (skill_exp_needed( amount + 1 )
- * species_skills( skill, you.species )) / 100;
-
- you.skill_points[skill] = points + 1;
- you.skills[skill] = amount;
-
- calc_total_skill_points();
-
- redraw_skill( you.your_name, player_title() );
-
- switch (skill)
- {
- case SK_FIGHTING:
- calc_hp();
- break;
-
- case SK_SPELLCASTING:
- case SK_INVOCATIONS:
- case SK_EVOCATIONS:
- calc_mp();
- break;
-
- case SK_DODGING:
- you.redraw_evasion = 1;
- break;
-
- case SK_ARMOUR:
- you.redraw_armour_class = 1;
- you.redraw_evasion = 1;
- break;
-
- default:
- break;
- }
- }
- }
-} // end debug_add_skills()
-#endif
-
-
-//---------------------------------------------------------------
-//
-// debug_set_all_skills
-//
-//---------------------------------------------------------------
-#ifdef WIZARD
-void debug_set_all_skills(void)
-{
- int i;
- int amount = debug_prompt_for_int( "Set all skills to what level? ", true );
-
- if (amount < 0) // cancel returns -1 -- bwr
- canned_msg( MSG_OK );
- else
- {
- if (amount > 27)
- amount = 27;
-
- for (i = SK_FIGHTING; i < NUM_SKILLS; i++)
- {
- if (i == SK_UNUSED_1
- || (i > SK_UNARMED_COMBAT && i < SK_SPELLCASTING))
- {
- continue;
- }
-
- const int points = (skill_exp_needed( amount + 1 )
- * species_skills( i, you.species )) / 100;
-
- you.skill_points[i] = points + 1;
- you.skills[i] = amount;
- }
-
- redraw_skill( you.your_name, player_title() );
-
- calc_total_skill_points();
-
- calc_hp();
- calc_mp();
-
- you.redraw_armour_class = 1;
- you.redraw_evasion = 1;
- }
-} // end debug_add_skills()
-#endif
-
-
-//---------------------------------------------------------------
-//
-// debug_add_mutation
-//
-//---------------------------------------------------------------
-#ifdef WIZARD
-bool debug_add_mutation(void)
-{
- bool success = false;
- char specs[80];
-
- // Yeah, the gaining message isn't too good for this... but
- // there isn't an array of simple mutation names. -- bwr
- mpr( "Which mutation (by message when getting mutation)? ", MSGCH_PROMPT );
- get_input_line( specs, sizeof( specs ) );
-
- if (specs[0] == '\0')
- return (false);
-
- int mutation = -1;
-
- for (int i = 0; i < NUM_MUTATIONS; i++)
- {
- char mut_name[80];
- strncpy( mut_name, mutation_name( i, 1 ), sizeof( mut_name ) );
-
- char *ptr = strstr( strlwr(mut_name), strlwr(specs) );
- if (ptr != NULL)
- {
- // we take the first mutation that matches
- mutation = i;
- break;
- }
- }
-
- if (mutation == -1)
- mpr("I can't warp you that way!");
- else
- {
- snprintf( info, INFO_SIZE, "Found: %s", mutation_name( mutation, 1 ) );
- mpr( info );
-
- int levels = debug_prompt_for_int( "How many levels? ", false );
-
- if (levels == 0)
- {
- canned_msg( MSG_OK );
- success = false;
- }
- else if (levels > 0)
- {
- for (int i = 0; i < levels; i++)
- {
- if (mutate( mutation ))
- success = true;
- }
- }
- else
- {
- for (int i = 0; i < -levels; i++)
- {
- if (delete_mutation( mutation ))
- success = true;
- }
- }
- }
-
- return (success);
-} // end debug_add_mutation()
-#endif
-
-
-//---------------------------------------------------------------
-//
-// debug_get_religion
-//
-//---------------------------------------------------------------
-#ifdef WIZARD
-void debug_get_religion(void)
-{
- char specs[80];
-
- mpr( "Which god (by name)? ", MSGCH_PROMPT );
- get_input_line( specs, sizeof( specs ) );
-
- if (specs[0] == '\0')
- return;
-
- int god = -1;
-
- for (int i = 1; i < NUM_GODS; i++)
- {
- char name[80];
- strncpy( name, god_name(i), sizeof( name ) );
-
- char *ptr = strstr( strlwr(name), strlwr(specs) );
- if (ptr != NULL)
- {
- god = i;
- break;
- }
- }
-
- if (god == -1)
- mpr( "That god doesn't seem to be taking followers today." );
- else
- {
- grd[you.x_pos][you.y_pos] = 179 + god;
- god_pitch(god);
- }
-} // end debug_add_skills()
-#endif
-
-
-void error_message_to_player(void)
-{
- mpr("Oh dear. There appears to be a bug in the program.");
- mpr("I suggest you leave this level then save as soon as possible.");
-
-} // end error_message_to_player()
-
-#ifdef WIZARD
-
-static int create_fsim_monster(int mtype, int hp)
-{
- const int mi =
- create_monster( mtype, 0, BEH_HOSTILE, you.x_pos, you.y_pos,
- MHITNOT, 250 );
-
- if (mi == -1)
- return (mi);
-
- monsters *mon = &menv[mi];
- mon->hit_points = mon->max_hit_points = hp;
- return (mi);
-}
-
-static skill_type fsim_melee_skill(const item_def *item)
-{
- skill_type sk = SK_UNARMED_COMBAT;
- if (item)
- sk = weapon_skill(*item);
- return (sk);
-}
-
-static void fsim_set_melee_skill(int skill, const item_def *item)
-{
- you.skills[fsim_melee_skill(item)] = skill;
- you.skills[SK_FIGHTING] = skill * 15 / 27;
-}
-
-static void fsim_set_ranged_skill(int skill, const item_def *item)
-{
- you.skills[range_skill(*item)] = skill;
- you.skills[SK_RANGED_COMBAT] = skill * 15 / 27;
-}
-
-static void fsim_item(FILE *out,
- bool melee,
- const item_def *weap,
- int wskill, unsigned long damage,
- long iterations, long hits,
- int maxdam, unsigned long time)
-{
- double hitdam = hits? double(damage) / hits : 0.0;
- int avspeed = (int) (time / iterations);
- fprintf(out, " %2d | %3ld%% | %5.2f | %5.2f | %5.2f | %3d | %2ld\n",
- wskill,
- 100 * hits / iterations,
- double(damage) / iterations,
- hitdam,
- double(damage) * player_speed() / avspeed / iterations,
- maxdam,
- time / iterations);
-}
-
-static bool fsim_ranged_combat(FILE *out, int wskill, int mi,
- const item_def *item, int missile_slot)
-{
- monsters &mon = menv[mi];
- unsigned long cumulative_damage = 0L;
- unsigned long time_taken = 0L;
- long hits = 0L;
- int maxdam = 0;
-
- const int thrown = missile_slot == -1? get_fire_item_index() : missile_slot;
- if (thrown == ENDOFPACK || thrown == -1)
- {
- mprf("No suitable missiles for combat simulation.");
- return (false);
- }
-
- fsim_set_ranged_skill(wskill, item);
-
- no_messages mx;
- const long iter_limit = Options.fsim_rounds;
- const int hunger = you.hunger;
- for (long i = 0; i < iter_limit; ++i)
- {
- mon.hit_points = mon.max_hit_points;
- bolt beam;
- you.time_taken = player_speed();
- if (throw_it(beam, thrown, &mon))
- hits++;
- you.hunger = hunger;
- time_taken += you.time_taken;
-
- int damage = (mon.max_hit_points - mon.hit_points);
- cumulative_damage += damage;
- if (damage > maxdam)
- maxdam = damage;
- }
- fsim_item(out, false, item, wskill, cumulative_damage,
- iter_limit, hits, maxdam, time_taken);
-
- return (true);
-}
-
-static bool fsim_melee_combat(FILE *out, int wskill, int mi,
- const item_def *item)
-{
- monsters &mon = menv[mi];
- unsigned long cumulative_damage = 0L;
- unsigned long time_taken = 0L;
- long hits = 0L;
- int maxdam = 0;
-
- fsim_set_melee_skill(wskill, item);
-
- no_messages mx;
- const long iter_limit = Options.fsim_rounds;
- const int hunger = you.hunger;
- for (long i = 0; i < iter_limit; ++i)
- {
- mon.hit_points = mon.max_hit_points;
- you.time_taken = player_speed();
- if (you_attack(mi, true))
- hits++;
-
- you.hunger = hunger;
- time_taken += you.time_taken;
-
- int damage = (mon.max_hit_points - mon.hit_points);
- cumulative_damage += damage;
- if (damage > maxdam)
- maxdam = damage;
- }
- fsim_item(out, true, item, wskill, cumulative_damage, iter_limit, hits,
- maxdam, time_taken);
-
- return (true);
-}
-
-static bool debug_fight_simulate(FILE *out, int wskill, int mi, int miss_slot)
-{
- int weapon = you.equip[EQ_WEAPON];
- const item_def *iweap = weapon != -1? &you.inv[weapon] : NULL;
-
- if (iweap && iweap->base_type == OBJ_WEAPONS
- && is_range_weapon(*iweap))
- return fsim_ranged_combat(out, wskill, mi, iweap, miss_slot);
- else
- return fsim_melee_combat(out, wskill, mi, iweap);
-}
-
-static const item_def *fsim_weap_item()
-{
- const int weap = you.equip[EQ_WEAPON];
- if (weap == -1)
- return NULL;
-
- return &you.inv[weap];
-}
-
-static std::string fsim_wskill()
-{
- const item_def *iweap = fsim_weap_item();
- return iweap && iweap->base_type == OBJ_WEAPONS
- && is_range_weapon(*iweap)?
- skill_name( range_skill(*iweap) ) :
- iweap? skill_name( fsim_melee_skill(iweap) ) :
- skill_name( SK_UNARMED_COMBAT );
-}
-
-static std::string fsim_weapon(int missile_slot)
-{
- char item_buf[ITEMNAME_SIZE];
- if (you.equip[EQ_WEAPON] != -1)
- {
- const item_def &weapon = you.inv[ you.equip[EQ_WEAPON] ];
- item_name(weapon, DESC_PLAIN, item_buf, true);
-
- if (is_range_weapon(weapon))
- {
- const int missile =
- missile_slot == -1? get_fire_item_index() :
- missile_slot;
- if (missile < ENDOFPACK)
- {
- std::string base = item_buf;
- base += " with ";
- in_name(missile, DESC_PLAIN, item_buf, true);
- return (base + item_buf);
- }
- }
- }
- else
- {
- strncpy(item_buf, "unarmed", sizeof item_buf);
- }
- return (item_buf);
-}
-
-static std::string fsim_time_string()
-{
- time_t curr_time = time(NULL);
- struct tm *ltime = localtime(&curr_time);
- if (ltime)
- {
- char buf[100];
- snprintf(buf, sizeof buf, "%4d%02d%02d/%2d:%02d:%02d",
- ltime->tm_year + 1900,
- ltime->tm_mon + 1,
- ltime->tm_mday,
- ltime->tm_hour,
- ltime->tm_min,
- ltime->tm_sec);
- return (buf);
- }
- return ("");
-}
-
-static void fsim_mon_stats(FILE *o, const monsters &mon)
-{
- char buf[ITEMNAME_SIZE];
- fprintf(o, "Monster : %s\n",
- moname(mon.type, true, DESC_PLAIN, buf));
- fprintf(o, "HD : %d\n", mon.hit_dice);
- fprintf(o, "AC : %d\n", mon.armour_class);
- fprintf(o, "EV : %d\n", mon.evasion);
-}
-
-static void fsim_title(FILE *o, int mon, int ms)
-{
- char buf[ITEMNAME_SIZE];
- fprintf(o, "Dungeon Crawl Stone Soup version " VERSION "\n\n");
- fprintf(o, "Combat simulation: %s %s vs. %s (%ld rounds) (%s)\n",
- species_name(you.species, you.experience_level),
- you.class_name,
- moname(menv[mon].type, true, DESC_PLAIN, buf),
- Options.fsim_rounds,
- fsim_time_string().c_str());
- fprintf(o, "Experience: %d\n", you.experience_level);
- fprintf(o, "Strength : %d\n", you.strength);
- fprintf(o, "Intel. : %d\n", you.intel);
- fprintf(o, "Dexterity : %d\n", you.dex);
- fprintf(o, "Base speed: %d\n", player_speed());
- fprintf(o, "\n");
- fsim_mon_stats(o, menv[mon]);
- fprintf(o, "\n");
- fprintf(o, "Weapon : %s\n", fsim_weapon(ms).c_str());
- fprintf(o, "Skill : %s\n", fsim_wskill().c_str());
- fprintf(o, "\n");
- fprintf(o, "Skill | Accuracy | Av.Dam | Av.HitDam | Eff.Dam | Max.Dam | Av.Time\n");
-}
-
-static int fsim_stat(int stat)
-{
- return (stat < 1 ? 1 :
- stat > 60 ? 60 :
- stat);
-}
-
-static bool debug_fight_sim(int mindex, int missile_slot)
-{
- FILE *ostat = fopen("fight.stat", "a");
- if (!ostat)
- {
- mprf("Can't write fight.stat: %s", strerror(errno));
- return (false);
- }
-
- bool success = true;
- FixedVector<unsigned char, 50> skill_backup = you.skills;
- int ystr = you.strength,
- yint = you.intel,
- ydex = you.dex;
- int yxp = you.experience_level;
-
- for (int i = SK_FIGHTING; i < NUM_SKILLS; ++i)
- you.skills[i] = 0;
-
- you.experience_level = Options.fsim_xl;
- if (you.experience_level < 1)
- you.experience_level = 1;
- if (you.experience_level > 27)
- you.experience_level = 27;
-
- you.strength = fsim_stat(Options.fsim_str);
- you.intel = fsim_stat(Options.fsim_int);
- you.dex = fsim_stat(Options.fsim_dex);
-
- fsim_title(ostat, mindex, missile_slot);
- for (int wskill = 0; wskill <= 27; ++wskill)
- {
- mesclr();
- mprf("Calculating average damage for %s at skill %d",
- fsim_weapon(missile_slot).c_str(), wskill);
- if (!debug_fight_simulate(ostat, wskill, mindex, missile_slot))
- goto done_combat_sim;
-
- fflush(ostat);
- // Not checking in the combat loop itself; that would be more responsive
- // for the user, but slow down the sim with all the calls to kbhit().
- if (kbhit() && getch() == 27)
- {
- success = false;
- mprf("Canceling simulation\n");
- goto done_combat_sim;
- }
- }
- you.skills = skill_backup;
- you.strength = ystr;
- you.intel = yint;
- you.dex = ydex;
- you.experience_level = yxp;
-
- mprf("Done fight simulation with %s", fsim_weapon(missile_slot).c_str());
-
-done_combat_sim:
- fprintf(ostat, "-----------------------------------\n\n");
- fclose(ostat);
-
- return (success);
-}
-
-int fsim_kit_equip(const std::string &kit)
-{
- int missile_slot = -1;
- char item_buf[ITEMNAME_SIZE];
-
- std::string::size_type ammo_div = kit.find("/");
- std::string weapon = kit;
- std::string missile;
- if (ammo_div != std::string::npos)
- {
- weapon = kit.substr(0, ammo_div);
- missile = kit.substr(ammo_div + 1);
- trim_string(weapon);
- trim_string(missile);
- }
-
- for (int i = 0; i < ENDOFPACK; ++i)
- {
- if (!is_valid_item(you.inv[i]))
- continue;
-
- in_name(i, DESC_PLAIN, item_buf, true);
- if (std::string(item_buf).find(weapon) != std::string::npos)
- {
- if (i != you.equip[EQ_WEAPON])
- {
- wield_weapon(true, i, false);
- if (i != you.equip[EQ_WEAPON])
- return -100;
- }
- break;
- }
- }
-
- if (!missile.empty())
- {
- for (int i = 0; i < ENDOFPACK; ++i)
- {
- if (!is_valid_item(you.inv[i]))
- continue;
-
- in_name(i, DESC_PLAIN, item_buf, true);
- if (std::string(item_buf).find(missile) != std::string::npos)
- {
- missile_slot = i;
- break;
- }
- }
- }
-
- return (missile_slot);
-}
-
-// Writes statistics about a fight to fight.stat in the current directory.
-// For fight purposes, a punching bag is summoned and given lots of hp, and the
-// average damage the player does to the p. bag over 10000 hits is noted,
-// advancing the weapon skill from 0 to 27, and keeping fighting skill to 2/5
-// of current weapon skill.
-void debug_fight_statistics(bool use_defaults)
-{
- int punching_bag = get_monnum(Options.fsim_mons.c_str());
- if (punching_bag == -1)
- punching_bag = MONS_WORM;
-
- int mindex = create_fsim_monster(punching_bag, 500);
- if (mindex == -1)
- {
- mprf("Failed to create punching bag");
- return;
- }
-
- if (!use_defaults)
- {
- debug_fight_sim(mindex, -1);
- goto fsim_mcleanup;
- }
-
- for (int i = 0, size = Options.fsim_kit.size(); i < size; ++i)
- {
- int missile = fsim_kit_equip(Options.fsim_kit[i]);
- if (missile == -100)
- {
- mprf("Aborting sim on %s", Options.fsim_kit[i].c_str());
- goto fsim_mcleanup;
- }
- if (!debug_fight_sim(mindex, missile))
- break;
- }
-fsim_mcleanup:
- monster_die(&menv[mindex], KILL_DISMISSED, 0);
-}
-#endif
diff --git a/stone_soup/crawl-ref/source/debug.h b/stone_soup/crawl-ref/source/debug.h
deleted file mode 100644
index 3df332441d..0000000000
--- a/stone_soup/crawl-ref/source/debug.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * File: debug.h
- * Summary: Debug and wizard related functions.
- * Written by: Linley Henzell and Jesse Jones
- *
- * Change History (most recent first):
- *
- * <4> 5/30/99 JDJ Added synch checks.
- * <3> 5/06/99 JDJ Added TRACE.
- * <2> -/--/-- JDJ Added a bunch of debugging macros. Old code is now #if WIZARD.
- * <1> -/--/-- LRH Created
- */
-#ifndef DEBUG_H
-#define DEBUG_H
-
-// Synch with ANSI definitions.
-#if DEBUG && defined(NDEBUG)
-#error DEBUG and NDEBUG are out of sync!
-#endif
-
-#if !DEBUG && !defined(NDEBUG)
-#error DEBUG and NDEBUG are out of sync!
-#endif
-
-// Synch with MSL definitions.
-#if __MSL__ && DEBUG != defined(MSIPL_DEBUG_MODE)
-#error DEBUG and MSIPL_DEBUG_MODE are out of sync!
-#endif
-
-// Synch with MSVC.
-#if _MSC_VER >= 1100 && DEBUG != defined(_DEBUG)
-#error DEBUG and _DEBUG are out of sync!
-#endif
-
-
-#ifndef _lint
-#define COMPILE_CHECK(p) {struct _CC {char a[(p) ? 1 : -1];};} 0
-#else
-#define COMPILE_CHECK(p)
-#endif
-
-#if DEBUG
-
-void AssertFailed(const char *expr, const char *file, int line);
-
-#define ASSERT(p) do {if (!(p)) AssertFailed(#p, __FILE__, __LINE__);} while (false)
-#define VERIFY(p) ASSERT(p)
-
-void DEBUGSTR(const char *format,...);
-void TRACE(const char *format,...);
-
-#else
-
-#define ASSERT(p) ((void) 0)
-#define VERIFY(p) do {if (p) ;} while (false)
-
-inline void __DUMMY_TRACE__(...)
-{
-}
-
-#define DEBUGSTR 1 ? ((void) 0) : __DUMMY_TRACE__
-#define TRACE 1 ? ((void) 0) : __DUMMY_TRACE__
-
-#endif
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void cast_spec_spell(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void cast_spec_spell_name(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void create_spec_monster(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void create_spec_monster_name(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: ( this does not seem to be used at all ... {dlb} )
- * *********************************************************************** */
-void create_spec_object(void);
-void tweak_object(void);
-
-// last updated 12say2001 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void debug_add_skills(void);
-void debug_set_skills(void);
-void debug_set_all_skills(void);
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void debug_add_skills(void);
-
-// last updated 17sep2001 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-bool debug_add_mutation(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: direct - food - items
- * *********************************************************************** */
-void error_message_to_player(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void level_travel( int delta );
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - direct
- * *********************************************************************** */
-void stethoscope(int mwh);
-
-void debug_item_scan( void );
-void debug_get_religion( void );
-void debug_change_species( void );
-void debug_fight_statistics( bool use_init_defaults );
-
-#endif
diff --git a/stone_soup/crawl-ref/source/decks.cc b/stone_soup/crawl-ref/source/decks.cc
deleted file mode 100644
index 47a74106be..0000000000
--- a/stone_soup/crawl-ref/source/decks.cc
+++ /dev/null
@@ -1,906 +0,0 @@
-/*
- * File: decks.cc
- * Summary: Functions with decks of cards.
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "decks.h"
-
-#include <string.h>
-
-#include "externs.h"
-
-#include "effects.h"
-#include "food.h"
-#include "it_use2.h"
-#include "items.h"
-#include "misc.h"
-#include "monplace.h"
-#include "mutation.h"
-#include "ouch.h"
-#include "player.h"
-#include "religion.h"
-#include "spells1.h"
-#include "spells3.h"
-#include "spl-cast.h"
-#include "stuff.h"
-
-// array sizes -- see notes below {dlb}
-#define DECK_WONDERS_SIZE 27
-#define DECK_SUMMONING_SIZE 11
-#define DECK_TRICKS_SIZE 11
-#define DECK_POWER_SIZE 17
-#define DECK_PUNISHMENT_SIZE 23
-
-enum CARDS // (unsigned char) deck_of_foo[]
-{
- CARD_BLANK = 0, // 0
- CARD_BUTTERFLY,
- CARD_WRAITH,
- CARD_EXPERIENCE,
- CARD_WEALTH,
- CARD_INTELLIGENCE, // 5
- CARD_STRENGTH,
- CARD_QUICKSILVER,
- CARD_STUPIDITY,
- CARD_WEAKNESS,
- CARD_SLOTH, // 10
- CARD_SHUFFLE,
- CARD_FREAK,
- CARD_DEATH,
- CARD_NORMALITY,
- CARD_SHADOW, // 15
- CARD_GATE,
- CARD_STATUE,
- CARD_ACQUISITION,
- CARD_HASTEN,
- CARD_DEMON_LESSER, // 20
- CARD_DEMON_COMMON,
- CARD_DEMON_GREATER,
- CARD_DEMON_SWARM,
- CARD_YAK,
- CARD_FIEND, // 25
- CARD_DRAGON,
- CARD_GOLEM,
- CARD_THING_FUGLY,
- CARD_LICH,
- CARD_HORROR_UNSEEN, // 30
- CARD_BLINK,
- CARD_TELEPORT,
- CARD_TELEPORT_NOW,
- CARD_RAGE,
- CARD_LEVITY, // 35
- CARD_VENOM,
- CARD_XOM,
- CARD_SLOW,
- CARD_DECAY,
- CARD_HEALING, // 40
- CARD_HEAL_WOUNDS,
- CARD_TORMENT,
- CARD_FOUNTAIN,
- CARD_ALTAR,
- CARD_FAMINE, // 45
- CARD_FEAST,
- CARD_WILD_MAGIC,
- CARD_VIOLENCE,
- CARD_PROTECTION,
- CARD_KNOWLEDGE, // 50
- CARD_MAZE,
- CARD_PANDEMONIUM,
- CARD_IMPRISONMENT,
- CARD_RULES_FOR_BRIDGE, // 54
- NUM_CARDS, // must remain last regular member {dlb}
- CARD_RANDOM = 255 // must remain final member {dlb}
-};
-
-static unsigned char deck_of_wonders[] =
-{
- CARD_BLANK,
- CARD_BUTTERFLY,
- CARD_WRAITH,
- CARD_EXPERIENCE,
- CARD_WEALTH,
- CARD_INTELLIGENCE,
- CARD_STRENGTH,
- CARD_QUICKSILVER,
- CARD_STUPIDITY,
- CARD_WEAKNESS,
- CARD_SLOTH,
- CARD_SHUFFLE,
- CARD_FREAK,
- CARD_DEATH,
- CARD_NORMALITY,
- CARD_SHADOW,
- CARD_GATE,
- CARD_STATUE,
- CARD_ACQUISITION,
- CARD_HASTEN,
- CARD_LICH,
- CARD_XOM,
- CARD_DECAY,
- CARD_ALTAR,
- CARD_FOUNTAIN,
- CARD_MAZE,
- CARD_PANDEMONIUM
-};
-
-static unsigned char deck_of_summoning[] =
-{
- CARD_STATUE,
- CARD_DEMON_LESSER,
- CARD_DEMON_COMMON,
- CARD_DEMON_GREATER,
- CARD_DEMON_SWARM,
- CARD_YAK,
- CARD_FIEND,
- CARD_DRAGON,
- CARD_GOLEM,
- CARD_THING_FUGLY,
- CARD_HORROR_UNSEEN
-};
-
-static unsigned char deck_of_tricks[] =
-{
- CARD_BLANK,
- CARD_BUTTERFLY,
- CARD_BLINK,
- CARD_TELEPORT,
- CARD_TELEPORT_NOW,
- CARD_RAGE,
- CARD_LEVITY,
- CARD_HEALING,
- CARD_WILD_MAGIC,
- CARD_DEMON_LESSER,
- CARD_HASTEN
-};
-
-static unsigned char deck_of_power[] =
-{
- CARD_BLANK,
- CARD_DEMON_COMMON,
- CARD_DEMON_GREATER,
- CARD_TELEPORT_NOW,
- CARD_VENOM,
- CARD_XOM,
- CARD_HEAL_WOUNDS,
- CARD_FAMINE,
- CARD_FEAST,
- CARD_WILD_MAGIC,
- CARD_VIOLENCE,
- CARD_PROTECTION,
- CARD_KNOWLEDGE,
- CARD_HASTEN,
- CARD_TORMENT,
- CARD_DEMON_SWARM,
- CARD_SLOW
-};
-
-// Supposed to be bad, small chance of OK... Nemelex wouldn't like a game
-// that didn't have some chance of "losing".
-static unsigned char deck_of_punishment[] =
-{
- CARD_BLANK,
- CARD_BUTTERFLY,
- CARD_WRAITH,
- CARD_WEALTH,
- CARD_STUPIDITY,
- CARD_WEAKNESS,
- CARD_SLOTH,
- CARD_SHUFFLE,
- CARD_FREAK,
- CARD_DEATH,
- CARD_NORMALITY,
- CARD_SHADOW,
- CARD_GATE,
- CARD_DEMON_SWARM,
- CARD_RAGE,
- CARD_VENOM,
- CARD_SLOW,
- CARD_DECAY,
- CARD_TORMENT,
- CARD_FAMINE,
- CARD_WILD_MAGIC,
- CARD_MAZE,
- CARD_PANDEMONIUM
-};
-
-static void cards(unsigned char which_card);
-
-void deck_of_cards(unsigned char which_deck)
-{
-
- // I really am not fond of how all of this works, the
- // decks ought to be stored (possibly) in an array of
- // pointers to int or as discrete arrays of int using
- // the sizeof operator to determine upper bounds, and
- // not defines, which is a bit clumsy given that you
- // have to update two things presently (the array and
- // the corresponding define) in order to add things to
- // decks ... someone fix this, or I will {dlb}
- unsigned char *card = deck_of_wonders;
- unsigned char max_card = 0;
- int i = 0;
- int brownie_points = 0; // for passing to did_god_conduct() {dlb}
-
- mpr("You draw a card...");
-
- switch (which_deck)
- {
- case DECK_OF_WONDERS:
- card = deck_of_wonders;
- max_card = DECK_WONDERS_SIZE;
- break;
- case DECK_OF_SUMMONING:
- card = deck_of_summoning;
- max_card = DECK_SUMMONING_SIZE;
- break;
- case DECK_OF_TRICKS:
- card = deck_of_tricks;
- max_card = DECK_TRICKS_SIZE;
- break;
- case DECK_OF_POWER:
- card = deck_of_power;
- max_card = DECK_POWER_SIZE;
- break;
- case DECK_OF_PUNISHMENT:
- card = deck_of_punishment;
- max_card = DECK_PUNISHMENT_SIZE;
- break;
- }
-
- i = (int) card[random2(max_card)];
-
- if (one_chance_in(250))
- {
- mpr("This card doesn't seem to belong here.");
- i = random2(NUM_CARDS);
- }
-
- if (i == CARD_BLANK && you.skills[SK_EVOCATIONS] > random2(30))
- i = (int) card[random2(max_card)];
-
- cards(i);
-
- // Decks of punishment aren't objects in the game,
- // its just Nemelex's form of punishment -- bwr
- if (which_deck != DECK_OF_PUNISHMENT)
- {
- you.inv[you.equip[EQ_WEAPON]].plus--;
-
- if (you.inv[you.equip[EQ_WEAPON]].plus == 0)
- {
- mpr("The deck of cards disappears in a puff of smoke.");
-
- unwield_item(you.equip[EQ_WEAPON]);
-
- dec_inv_item_quantity( you.equip[EQ_WEAPON], 1 );
-
- // these bonuses happen only when the deck expires {dlb}:
- brownie_points = (coinflip()? 2 : 1);
-
- if (which_deck == DECK_OF_WONDERS)
- brownie_points += 2;
- else if (which_deck == DECK_OF_POWER)
- brownie_points++;
- }
-
- // this bonus happens with every use {dlb}:
- if (which_deck == DECK_OF_WONDERS || one_chance_in(3))
- brownie_points++;
-
- did_god_conduct(DID_CARDS, brownie_points);
- }
-
- return;
-} // end deck_of_cards()
-
-static void cards(unsigned char which_card)
-{
- FixedVector < int, 5 > dvar;
- FixedVector < int, 5 > mvar;
- int dvar1 = 0;
- int loopy = 0; // general purpose loop variable {dlb}
- bool success = false; // for summoning messages {dlb}
- bool failMsg = true;
- int summ_dur, summ_beh, summ_num;
-
- if (which_card == CARD_BLANK && one_chance_in(10))
- which_card = CARD_RULES_FOR_BRIDGE;
-
- switch (which_card)
- {
- default:
- case CARD_BLANK:
- mpr("It is blank.");
- break;
-
- case CARD_BUTTERFLY:
- mpr("You have drawn the Butterfly.");
-
- summ_dur = ENCH_ABJ_I + random2(3) + you.skills[SK_EVOCATIONS] / 2;
- if (summ_dur > ENCH_ABJ_VI)
- summ_dur = ENCH_ABJ_VI;
-
- if (create_monster( MONS_BUTTERFLY, summ_dur, BEH_FRIENDLY,
- you.x_pos, you.y_pos, MHITYOU, 250 ) != -1)
- {
- mpr("A brightly coloured insect flies from the card!");
- }
- break;
-
- case CARD_WRAITH:
- mpr("You have drawn the Wraith.");
-
- lose_level();
- drain_exp();
- break;
-
- case CARD_EXPERIENCE:
- mpr( "You have drawn Experience." );
- potion_effect( POT_EXPERIENCE, 0 );
- break;
-
- case CARD_WEALTH:
- mpr("You have drawn Wealth.");
-
- you.gold += roll_dice( 2, 20 * you.skills[SK_EVOCATIONS] );
- you.redraw_gold = 1;
- break;
-
- case CARD_INTELLIGENCE:
- mpr("You have drawn the Brain!");
-
- you.intel += 1 + random2( you.skills[SK_EVOCATIONS] ) / 7;
-
- if (you.max_intel < you.intel)
- you.max_intel = you.intel;
-
- you.redraw_intelligence = 1;
- break;
-
- case CARD_STRENGTH:
- mpr("You have drawn Strength!");
-
- you.strength += 1 + random2( you.skills[SK_EVOCATIONS] ) / 7;
-
- if (you.max_strength < you.strength)
- you.max_strength = you.strength;
-
- you.redraw_strength = 1;
- break;
-
- case CARD_QUICKSILVER:
- mpr("You have drawn the Quicksilver card.");
-
- you.dex += 1 + random2( you.skills[SK_EVOCATIONS] ) / 7;
-
- if (you.max_dex < you.dex)
- you.max_dex = you.dex;
-
- you.redraw_dexterity = 1;
- break;
-
- case CARD_STUPIDITY:
- mpr("You have drawn Stupidity!");
-
- you.intel -= (2 + random2avg(3, 2));
- if (you.intel < 4)
- you.intel = 0;
-
- if (you.skills[SK_EVOCATIONS] < random2(30))
- you.max_intel--;
-
- you.redraw_intelligence = 1;
- break;
-
- case CARD_WEAKNESS:
- mpr("You have drawn Weakness.");
-
- you.strength -= (2 + random2avg(3, 2));
- if (you.strength < 4)
- you.strength = 0;
-
- if (you.skills[SK_EVOCATIONS] < random2(30))
- you.max_strength--;
-
- you.redraw_strength = 1;
- break;
-
- case CARD_SLOTH:
- mpr("You have drawn the Slug.");
-
- you.dex -= (2 + random2avg(3, 2));
- if (you.dex < 4)
- you.dex = 0;
-
- if (you.skills[SK_EVOCATIONS] < random2(30))
- you.max_dex--;
-
- you.redraw_dexterity = 1;
- break;
-
- case CARD_SHUFFLE: // shuffle stats
- mpr("You have drawn the Shuffle card!");
-
- dvar[STAT_STRENGTH] = you.strength;
- dvar[STAT_DEXTERITY] = you.dex;
- dvar[STAT_INTELLIGENCE] = you.intel;
-
- mvar[STAT_STRENGTH] = you.max_strength;
- mvar[STAT_DEXTERITY] = you.max_dex;
- mvar[STAT_INTELLIGENCE] = you.max_intel;
-
- you.strength = 101;
- you.intel = 101;
- you.dex = 101;
-
- do
- {
- dvar1 = random2(NUM_STATS);
-
- if (dvar[dvar1] == 101)
- continue;
-
- if (you.strength == 101)
- {
- you.strength = dvar[dvar1];
- you.max_strength = mvar[dvar1];
- }
- else if (you.intel == 101)
- {
- you.intel = dvar[dvar1];
- you.max_intel = mvar[dvar1];
- }
- else if (you.dex == 101)
- {
- you.dex = dvar[dvar1];
- you.max_dex = mvar[dvar1];
- }
-
- dvar[dvar1] = 101;
- }
- while (dvar[STAT_STRENGTH] != 101 || dvar[STAT_DEXTERITY] != 101
- || dvar[STAT_INTELLIGENCE] != 101);
-
- you.redraw_strength = 1;
- you.redraw_intelligence = 1;
- you.redraw_dexterity = 1;
- burden_change();
- break;
-
- case CARD_FREAK:
- mpr("You have drawn the Freak!");
- for (loopy = 0; loopy < 6; loopy++)
- {
- if (!mutate(100, failMsg))
- failMsg = false;
- }
- break;
-
- case CARD_DEATH:
- mpr("Oh no! You have drawn the Death card!");
-
- if (you.duration[DUR_TELEPORT])
- you_teleport();
-
- for (loopy = 0; loopy < 5; loopy++)
- {
- create_monster( MONS_REAPER, 0, BEH_HOSTILE, you.x_pos, you.y_pos,
- MHITYOU, 250 );
- }
- break;
-
- case CARD_NORMALITY:
- mpr("You have drawn Normalisation.");
- for (loopy = 0; loopy < 6; loopy++)
- {
- delete_mutation(100);
- }
- break;
-
- case CARD_SHADOW:
- mpr("You have drawn the Shadow.");
- create_monster( MONS_SOUL_EATER, 0, BEH_HOSTILE, you.x_pos, you.y_pos,
- MHITYOU, 250 );
- break;
-
- case CARD_GATE:
- mpr("You have drawn the Gate!");
- more();
-
- if (you.level_type == LEVEL_ABYSS)
- banished(DNGN_EXIT_ABYSS);
- else if (you.level_type == LEVEL_LABYRINTH)
- canned_msg(MSG_NOTHING_HAPPENS);
- else
- banished(DNGN_ENTER_ABYSS);
- break;
-
- case CARD_STATUE:
- mpr("You have drawn the Crystal Statue.");
- create_monster( MONS_CRYSTAL_GOLEM, 0, BEH_FRIENDLY,
- you.x_pos, you.y_pos, you.pet_target, 250 );
- break;
-
- case CARD_ACQUISITION:
- mpr( "You have drawn Acquisition!" );
- mpr( "The card unfolds to form a scroll of paper." );
- acquirement( OBJ_RANDOM, AQ_CARD_ACQUISITION );
- break;
-
- case CARD_HASTEN:
- mpr("You have drawn Haste.");
- potion_effect( POT_SPEED, 5 * you.skills[SK_EVOCATIONS] );
- break;
-
- case CARD_DEMON_LESSER:
- mpr("On the card is a picture of a little demon.");
-
- summ_dur = ENCH_ABJ_I + random2(3) + you.skills[SK_EVOCATIONS] / 3;
- if (summ_dur > ENCH_ABJ_VI)
- summ_dur = ENCH_ABJ_VI;
-
- if (create_monster( summon_any_demon( DEMON_LESSER ), summ_dur,
- BEH_FRIENDLY, you.x_pos, you.y_pos, you.pet_target,
- 250 ) != -1)
- {
- mpr("The picture comes to life!");
- }
- break;
-
- case CARD_DEMON_COMMON:
- mpr("On the card is a picture of a demon.");
-
- summ_dur = ENCH_ABJ_I + random2(3) + you.skills[SK_EVOCATIONS] / 4;
- if (summ_dur > ENCH_ABJ_VI)
- summ_dur = ENCH_ABJ_VI;
-
- if (create_monster( summon_any_demon( DEMON_COMMON ), summ_dur,
- BEH_FRIENDLY, you.x_pos, you.y_pos, you.pet_target,
- 250 ) != -1)
- {
- mpr("The picture comes to life!");
- }
- break;
-
- case CARD_DEMON_GREATER:
- mpr("On the card is a picture of a huge demon.");
-
- summ_beh = (you.skills[SK_EVOCATIONS] > random2(30)) ? BEH_FRIENDLY
- : BEH_CHARMED;
-
- if (summ_beh == BEH_CHARMED)
- mpr( "You don't feel so good about this..." );
-
- if (create_monster( summon_any_demon( DEMON_GREATER ), ENCH_ABJ_V,
- summ_beh, you.x_pos, you.y_pos,
- you.pet_target, 250 ) != -1)
- {
- mpr("The picture comes to life!");
- }
- break;
-
- case CARD_DEMON_SWARM:
- mpr("On the card is a picture of a swarm of little demons.");
-
- success = false;
-
- summ_num = 7 + random2(6);
-
- for (loopy = 0; loopy < summ_num; loopy++)
- {
- if (create_monster( summon_any_demon( DEMON_LESSER ), ENCH_ABJ_VI,
- BEH_HOSTILE, you.x_pos, you.y_pos,
- MHITYOU, 250 ) != -1)
- {
- success = true;
- }
- }
-
- if (success)
- mpr("The picture comes to life!");
- break;
-
- case CARD_YAK:
- mpr("On the card is a picture of a huge shaggy yak.");
-
- summ_dur = ENCH_ABJ_II + you.skills[SK_EVOCATIONS] / 2;
- if (summ_dur > ENCH_ABJ_VI)
- summ_dur = ENCH_ABJ_VI;
-
- if (create_monster( MONS_DEATH_YAK, summ_dur, BEH_FRIENDLY,
- you.x_pos, you.y_pos, you.pet_target, 250 ) != -1)
- {
- mpr("The picture comes to life!");
- }
- break;
-
- case CARD_FIEND:
- mpr("On the card is a picture of a huge scaly devil.");
-
- summ_dur = ENCH_ABJ_II + you.skills[SK_EVOCATIONS] / 6;
- if (summ_dur > ENCH_ABJ_VI)
- summ_dur = ENCH_ABJ_VI;
-
- if (create_monster( MONS_FIEND, summ_dur, BEH_FRIENDLY,
- you.x_pos, you.y_pos, you.pet_target, 250 ) != -1)
- {
- mpr("The picture comes to life!");
- }
- break;
-
- case CARD_DRAGON:
- mpr("On the card is a picture of a huge scaly dragon.");
-
- summ_dur = ENCH_ABJ_III + you.skills[SK_EVOCATIONS] / 6;
- if (summ_dur > ENCH_ABJ_VI)
- summ_dur = ENCH_ABJ_VI;
-
- if (create_monster( (coinflip() ? MONS_DRAGON : MONS_ICE_DRAGON),
- summ_dur, BEH_FRIENDLY, you.x_pos, you.y_pos,
- you.pet_target, 250 ) != -1)
- {
- mpr("The picture comes to life!");
- }
- break;
-
- case CARD_GOLEM:
- mpr("On the card is a picture of a statue.");
-
- summ_dur = ENCH_ABJ_II + you.skills[SK_EVOCATIONS] / 4;
- if (summ_dur > ENCH_ABJ_VI)
- summ_dur = ENCH_ABJ_VI;
-
- if (create_monster( MONS_CLAY_GOLEM + random2(6), summ_dur,
- BEH_FRIENDLY, you.x_pos, you.y_pos,
- you.pet_target, 250 ) != -1)
- {
- mpr("The picture comes to life!");
- }
- break;
-
- case CARD_THING_FUGLY:
- mpr("On the card is a picture of a very ugly thing.");
-
- summ_dur = ENCH_ABJ_II + you.skills[SK_EVOCATIONS] / 4;
- if (summ_dur > ENCH_ABJ_VI)
- summ_dur = ENCH_ABJ_VI;
-
- if (create_monster( MONS_VERY_UGLY_THING, summ_dur, BEH_FRIENDLY,
- you.x_pos, you.y_pos, you.pet_target, 250 ) != -1)
- {
- mpr("The picture comes to life!");
- }
- break;
-
- case CARD_LICH:
- mpr( "On the card is a picture of a very irritated-looking "
- "skeletal thing." );
-
- if (create_monster( MONS_LICH, 0, BEH_HOSTILE, you.x_pos, you.y_pos,
- MHITYOU, 250) != -1)
- {
- mpr("The picture comes to life!");
- }
- break;
-
- case CARD_HORROR_UNSEEN:
- if (!player_see_invis())
- mpr("It is blank!");
- else
- mpr("On the card is a picture of a hideous abomination.");
-
- summ_dur = ENCH_ABJ_II + you.skills[SK_EVOCATIONS] / 4;
- if (summ_dur > ENCH_ABJ_VI)
- summ_dur = ENCH_ABJ_VI;
-
- if (create_monster( MONS_UNSEEN_HORROR, summ_dur, BEH_FRIENDLY,
- you.x_pos, you.y_pos, you.pet_target, 250 ) != -1)
- {
- if (player_see_invis())
- {
- mpr("The picture comes to life!");
- }
- }
- break;
-
- case CARD_BLINK:
- mpr("You have drawn Blink.");
- blink();
- // random_blink(true);
- break;
-
- case CARD_TELEPORT:
- mpr("You have drawn the Portal of Delayed Transposition.");
- you_teleport();
- break;
-
- case CARD_TELEPORT_NOW:
- mpr( "You have drawn the Portal of Instantaneous Transposition." );
- you_teleport2( true, true ); // in abyss, always to new area
- break;
-
- case CARD_RAGE:
- mpr("You have drawn Rage.");
-
- if (!go_berserk(false))
- canned_msg(MSG_NOTHING_HAPPENS);
- else
- you.berserk_penalty = NO_BERSERK_PENALTY;
- break;
-
- case CARD_LEVITY:
- mpr("You have drawn Levity.");
- potion_effect( POT_LEVITATION, 5 * you.skills[SK_EVOCATIONS] );
- break;
-
- case CARD_VENOM:
- mpr("You have drawn Venom.");
- poison_player( 2 + random2( 7 - you.skills[SK_EVOCATIONS] / 5 ) );
- break;
-
- case CARD_XOM:
- mpr("You have drawn the card of Xom!");
- Xom_acts( true, 5 + random2( you.skills[SK_EVOCATIONS] ), true );
- break;
-
- case CARD_SLOW:
- mpr("You have drawn Slowness.");
- potion_effect( POT_SLOWING, 100 - 2 * you.skills[SK_EVOCATIONS] );
- break;
-
- case CARD_DECAY:
- mpr("You have drawn Decay.");
-
- if (you.is_undead)
- mpr("You feel terrible.");
- else
- rot_player( 2 + random2( 7 - you.skills[SK_EVOCATIONS] / 4 ) );
- break;
-
- case CARD_HEALING:
- mpr("You have drawn the Elixir of Health.");
- potion_effect( POT_HEALING, 5 * you.skills[SK_EVOCATIONS] );
- break;
-
- case CARD_HEAL_WOUNDS:
- mpr("You have drawn the Symbol of Immediate Regeneration.");
- potion_effect( POT_HEAL_WOUNDS, 5 * you.skills[SK_EVOCATIONS] );
- break;
-
- case CARD_TORMENT:
- mpr("You have drawn the Symbol of Torment.");
- torment( you.x_pos, you.y_pos );
- break;
-
-// what about checking whether there are items there, too? {dlb}
- case CARD_FOUNTAIN:
- mpr("You have drawn the Fountain.");
-
- if (grd[you.x_pos][you.y_pos] == DNGN_FLOOR)
- {
- strcpy( info, "A beautiful fountain of clear blue water grows "
- "from the floor " );
-
- strcat( info, (you.species == SP_NAGA || you.species == SP_CENTAUR)
- ? "before you!" : "at your feet!" );
- mpr(info);
- grd[you.x_pos][you.y_pos] = DNGN_BLUE_FOUNTAIN;
- }
- else
- {
- canned_msg(MSG_NOTHING_HAPPENS);
- }
- break;
-
- case CARD_ALTAR:
- mpr("You have drawn the Altar.");
-
- if (you.religion == GOD_NO_GOD)
- {
- canned_msg(MSG_NOTHING_HAPPENS);
- }
- else
- {
- dvar1 = 179 + you.religion;
-
- if (grd[you.x_pos][you.y_pos] == DNGN_FLOOR)
- {
- strcpy(info, "An altar grows from the floor ");
- strcat(info,
- (you.species == SP_NAGA || you.species == SP_CENTAUR)
- ? "before you!" : "at your feet!");
- mpr(info);
- grd[you.x_pos][you.y_pos] = dvar1;
- }
- else
- {
- do
- {
- dvar[0] = 10 + random2(GXM - 20);
- dvar[1] = 10 + random2(GYM - 20);
- }
- while (grd[dvar[0]][dvar[1]] != DNGN_FLOOR);
-
- grd[dvar[0]][dvar[1]] = dvar1;
-
- mpr( "You sense divine power!" );
- }
- }
- break;
-
- case CARD_FAMINE:
- mpr("You have drawn Famine.");
-
- if (you.is_undead == US_UNDEAD)
- mpr("You feel rather smug.");
- else
- set_hunger(500, true);
- break;
-
- case CARD_FEAST:
- mpr("You have drawn the Feast.");
-
- if (you.is_undead == US_UNDEAD)
- mpr("You feel a horrible emptiness.");
- else
- set_hunger(12000, true);
- break;
-
- case CARD_WILD_MAGIC:
- mpr( "You have drawn Wild Magic." );
- miscast_effect( SPTYP_RANDOM, random2(15) + 5, random2(250), 0 );
- break;
-
- case CARD_VIOLENCE:
- mpr("You have drawn Violence.");
- acquirement( OBJ_WEAPONS, AQ_CARD_VIOLENCE );
- break;
-
- case CARD_PROTECTION:
- mpr("You have drawn Protection.");
- acquirement( OBJ_ARMOUR, AQ_CARD_PROTECTION );
- break;
-
- case CARD_KNOWLEDGE:
- mpr("You have drawn Knowledge.");
- acquirement( OBJ_BOOKS, AQ_CARD_KNOWLEDGE );
- break;
-
- case CARD_MAZE:
- mpr("You have drawn the Maze!");
- more();
-
- if (you.level_type == LEVEL_DUNGEON)
- banished( DNGN_ENTER_LABYRINTH );
- break;
-
- case CARD_PANDEMONIUM:
- mpr("You have drawn the Pandemonium card!");
- more();
-
- if (you.level_type == LEVEL_PANDEMONIUM)
- banished(DNGN_EXIT_PANDEMONIUM);
- else if (you.level_type == LEVEL_LABYRINTH)
- canned_msg(MSG_NOTHING_HAPPENS);
- else
- banished(DNGN_ENTER_PANDEMONIUM);
- break;
-
- case CARD_RULES_FOR_BRIDGE:
- mpr("You have drawn the rules for contract bridge.");
- mpr("How intriguing!");
- break;
-
- case CARD_IMPRISONMENT:
- mpr("You have drawn the Prison!");
- entomb();
- break;
- }
-
- return;
-} // end cards()
diff --git a/stone_soup/crawl-ref/source/decks.h b/stone_soup/crawl-ref/source/decks.h
deleted file mode 100644
index 1227ee19f1..0000000000
--- a/stone_soup/crawl-ref/source/decks.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * File: decks.cc
- * Summary: Functions with decks of cards.
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef DECKS_H
-#define DECKS_H
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: it_use_3 - religion
- * *********************************************************************** */
-void deck_of_cards(unsigned char which_deck);
-
-
-#endif
diff --git a/stone_soup/crawl-ref/source/defines.h b/stone_soup/crawl-ref/source/defines.h
deleted file mode 100644
index f1156eec76..0000000000
--- a/stone_soup/crawl-ref/source/defines.h
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * File: defines.h
- * Summary: Various definess used by Crawl.
- * Written by: Linley Henzel
- *
- * Abstract: A variety of miscellaneous constant values are found here.
- * I think we should move the colors into an enum or something
- * because there are in numerical order. But I'm too lazy to
- * do it myself.
- *
- * Copyright © 1999 Brian Robinson. // Me? How come?
- *
- * Change History (most recent first):
- *
- * <4> 7/29/00 JDJ Renamed MNG NON_MONSTER, MNST MAX_MONSTERS, ITEMS MAX_ITEMS,
- * ING NON_ITEM, CLOUDS MAX_CLOUDS, CNG EMPTY_CLOUD, NTRAPS MAX_TRAPS.
- * <3> 9/25/99 CDL linuxlib -> liblinux
- * <2> 6/17/99 BCR indented and added header
- * <1> --/--/-- LRH Created
- */
-
-#ifndef DEFINES_H
-#define DEFINES_H
-
-#define ESCAPE '\x1b' // most ansi-friendly way I can think of defining this.
-
-// there's got to be a better way...
-#ifdef _LIBUNIX_IMPLEMENTATION
-#elif macintosh
-#else
- #ifndef TRUE
- #define TRUE 1
- #endif
-
- #ifndef FALSE
- #define FALSE 0
- #endif
-#endif
-
-
-// max size of inventory array {dlb}:
-#define ENDOFPACK 52
-
-// minimum value for strength required on armour and weapons
-#define STR_REQ_THRESHOLD 10
-
-// max size of monter array {dlb}:
-#define MAX_MONSTERS 200
-// number of monster enchantments
-#define NUM_MON_ENCHANTS 6
-// non-monster for mgrd[][] -- (MNST + 1) {dlb}:
-#define NON_MONSTER 201
-
-#define MAX_SUBTYPES 50
-
-// max size of item list {dlb}:
-#define MAX_ITEMS 500
-// non-item -- (ITEMS + 1) {dlb}
-#define NON_ITEM 501
-
-// max size of cloud array {dlb}:
-#define MAX_CLOUDS 100
-
-// empty cloud -- (CLOUDS + 1) {dlb}:
-#define EMPTY_CLOUD 101
-
-// max x-bound for level generation {dlb}
-#define GXM 80
-// max y-bound for level generation {dlb}
-#define GYM 70
-
-#define LOS_SX 8
-#define LOS_EX 25
-#define LOS_SY 1
-#define LOS_EY 17
-
-#define VIEW_SX 1
-#define VIEW_EX 33
-#define VIEW_SY 1
-#define VIEW_EY 17
-
-#define VIEW_Y_DIFF (((VIEW_EX - VIEW_SX + 1) - (VIEW_EY - VIEW_SY + 1)) / 2)
-
-// View centre must be the same as LOS centre.
-// VIEW_CX == 17
-#define VIEW_CX ((VIEW_SX + VIEW_EX) / 2)
-// VIEW_CY == 9
-#define VIEW_CY ((VIEW_SY + VIEW_EY) / 2)
-
-// max traps per level
-#define MAX_TRAPS 30
-
-// max shops per level
-#define MAX_SHOPS 5
-
-// lowest grid value which can be passed by walking etc.
-#define MINMOVE 31
-
-// lowest grid value which can be seen through
-#define MINSEE 11
-
-// This value is used to make test_hit checks always succeed
-#define AUTOMATIC_HIT 1500
-
-// grids that monsters can see
-#define MONSTER_LOS_RANGE 8
-
-// Maximum charge level for rods
-#define MAX_ROD_CHARGE 17
-#define ROD_CHARGE_MULT 100
-
-// Maximum enchantment on weapons/armour/secondary armours
-// Note: use armour_max_enchant(item) to get the correct limit for item
-#define MAX_WPN_ENCHANT 5
-#define MAX_ARM_ENCHANT 5
-#define MAX_SEC_ENCHANT 2
-
-#define NUM_STAVE_ADJ 9
-
-// some shortcuts:
-#define menv env.mons
-#define mitm env.item
-#define grd env.grid
-#define mgrd env.mgrid
-#define igrd env.igrid
-
-#define ENVF_FLAGS 0xFF00U
-#define ENVF_DETECT_MONS 0x0100U
-#define ENVF_DETECT_ITEM 0x0200U
-
-// This square is known because of detect-creatures/detect-items
-#define ENVF_DETECTED 0x0800U
-
-#define ENVF_COLOR(x) (((x) >> 12) & 0xF)
-
-// (MNG) -- for a reason! see usage {dlb}:
-#define MHITNOT 201
-// (MNG + 1) -- for a reason! see usage {dlb}:
-#define MHITYOU 202
-
-// colors, such pretty colors ...
-#ifndef DOS
- #define BLACK 0
- #define BLUE 1
- #define GREEN 2
- #define CYAN 3
- #define RED 4
- #define MAGENTA 5
- #define BROWN 6
- #define LIGHTGREY 7
- #define DARKGREY 8
- #define LIGHTBLUE 9
- #define LIGHTGREEN 10
- #define LIGHTCYAN 11
- #define LIGHTRED 12
- #define LIGHTMAGENTA 13
- #define YELLOW 14
- #define WHITE 15
-
- #define LIGHTGRAY LIGHTGREY
- #define DARKGRAY DARKGREY
-#else
- #include <conio.h>
- #define LIGHTGREY LIGHTGRAY
- #define DARKGREY DARKGRAY
-#endif
-
-// Colour options... these are used as bit flags along with the colour
-// value in the low byte.
-
-// This is used to signal curses (which has seven base colours) to
-// try to get a brighter version using recommisioned attribute flags.
-#define COLFLAG_CURSES_BRIGHTEN 0x0080
-
-//#ifdef USE_COLOUR_OPTS
-
- #define COLFLAG_FRIENDLY_MONSTER 0x0100
- #define COLFLAG_ITEM_HEAP 0x0200
- #define COLFLAG_WILLSTAB 0x0400
- #define COLFLAG_MAYSTAB 0x0800
-
- enum CHAR_ATTRIBUTES
- {
- CHATTR_NORMAL, /* 0 */
- CHATTR_STANDOUT,
- CHATTR_BOLD,
- CHATTR_BLINK,
- CHATTR_UNDERLINE,
- CHATTR_REVERSE, /* 5 */
- CHATTR_DIM,
- CHATTR_HILITE,
-
- CHATTR_ATTRMASK = 0xF, /* 15 (well, obviously) */
-
- CHATTR_COLMASK = 0xF00 // Mask with this to get extra colour info.
- };
-
-//#endif
-
-#define MINIMUM( xxx, yyy ) (((xxx) < (yyy)) ? (xxx) : (yyy))
-#define MAXIMUM( xxx, yyy ) (((xxx) > (yyy)) ? (xxx) : (yyy))
-
-// Convert capital letters into mystic numbers representing
-// CTRL sequences. This is a macro because a lot of the type
-// it wants to be used in case labels.
-#define CONTROL( xxx ) (xxx - 'A' + 1)
-
-#endif
diff --git a/stone_soup/crawl-ref/source/delay.cc b/stone_soup/crawl-ref/source/delay.cc
deleted file mode 100644
index b288d1bb85..0000000000
--- a/stone_soup/crawl-ref/source/delay.cc
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * File: delay.cc
- * Summary: Functions for handling multi-turn actions.
- *
- * Change History (most recent first):
- *
- * <1> Sept 09, 2001 BWR Created
- */
-
-#include "AppHdr.h"
-#include "externs.h"
-
-#include <stdio.h>
-#include <string.h>
-
-#include "delay.h"
-#include "enum.h"
-#include "food.h"
-#include "items.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "item_use.h"
-#include "it_use2.h"
-#include "message.h"
-#include "misc.h"
-#include "monstuff.h"
-#include "ouch.h"
-#include "output.h"
-#include "player.h"
-#include "randart.h"
-#include "spl-util.h"
-#include "stuff.h"
-
-void start_delay( int type, int turns, int parm1, int parm2 )
-/***********************************************************/
-{
- delay_queue_item delay;
-
- delay.type = type;
- delay.duration = turns;
- delay.parm1 = parm1;
- delay.parm2 = parm2;
-
- you.delay_queue.push( delay );
-}
-
-void stop_delay( void )
-/*********************/
-{
- delay_queue_item delay = you.delay_queue.front();
-
- // At the very least we can remove any queued delays, right
- // now there is no problem with doing this... note that
- // any queuing here can only happen from a single command,
- // as the effect of a delay doesn't normally allow interaction
- // until it is done... it merely chains up individual actions
- // into a single action. -- bwr
- if (you.delay_queue.size() > 1)
- {
- while (you.delay_queue.size())
- you.delay_queue.pop();
-
- you.delay_queue.push( delay );
- }
-
- switch (delay.type)
- {
- case DELAY_BUTCHER:
- // Corpse keeps track of work in plus2 field, see handle_delay() -- bwr
- mpr( "You stop butchering the corpse." );
- you.delay_queue.pop();
- break;
-
- case DELAY_MEMORISE:
- // Losing work here is okay... having to start from
- // scratch is a reasonable behaviour. -- bwr
- mpr( "Your memorization is interrupted." );
- you.delay_queue.pop();
- break;
-
- case DELAY_PASSWALL:
- // The lost work here is okay since this spell requires
- // the player to "attune to the rock". If changed, the
- // the delay should be increased to reduce the power of
- // this spell. -- bwr
- mpr( "Your meditation is interrupted." );
- you.delay_queue.pop();
- break;
-
- case DELAY_INTERUPTABLE:
- // always stopable by definition...
- // try using a more specific type anyways. -- bwr
- you.delay_queue.pop();
- break;
-
- case DELAY_EAT:
- // XXX: Large problems with object destruction here... food can
- // be from in the inventory or on the ground and these are
- // still handled quite differently. Eventually we would like
- // this to be stoppable, with partial food items implimented. -- bwr
- break;
-
- case DELAY_ARMOUR_ON:
- case DELAY_ARMOUR_OFF:
- // These two have the default action of not being interuptable,
- // although they will often be chained (remove cloak, remove
- // armour, wear new armour, replace cloak), all of which can
- // be stopped when complete. This is a fairly reasonable
- // behaviour, although perhaps the character should have
- // option of reversing the current action if it would take
- // less time to get out of the plate mail that's half on
- // than it would take to continue. Probably too much trouble,
- // and would have to have a prompt... this works just fine. -- bwr
- break;
-
- case DELAY_AUTOPICKUP: // one turn... too much trouble
- case DELAY_WEAPON_SWAP: // one turn... too much trouble
- case DELAY_DROP_ITEM: // one turn... only used for easy armour drops
- case DELAY_ASCENDING_STAIRS: // short... and probably what people want
- case DELAY_DESCENDING_STAIRS: // short... and probably what people want
- case DELAY_UNINTERUPTABLE: // never stopable
- default:
- break;
- }
-}
-
-bool you_are_delayed( void )
-/**************************/
-{
- return (!you.delay_queue.empty());
-}
-
-int current_delay_action( void )
-/******************************/
-{
- return (you_are_delayed() ? you.delay_queue.front().type
- : DELAY_NOT_DELAYED);
-}
-
-void handle_delay( void )
-/***********************/
-{
- int ego;
- char str_pass[ ITEMNAME_SIZE ];
-
- if (you_are_delayed())
- {
- delay_queue_item &delay = you.delay_queue.front();
-
- // First check cases where delay may no longer be valid:
- // XXX: need to handle passwall when monster digs -- bwr
- if (delay.type == DELAY_BUTCHER)
- {
- // A monster may have raised the corpse you're chopping up! -- bwr
- // Note that a monster could have raised the corpse and another
- // monster could die and create a corpse with the same ID number...
- // However, it would not be at the player's square like the
- // original and that's why we do it this way. Note that
- // we ignore the conversion to skeleton possiblity just to
- // be nice. -- bwr
- if (is_valid_item( mitm[ delay.parm1 ] )
- && mitm[ delay.parm1 ].base_type == OBJ_CORPSES
- && mitm[ delay.parm1 ].x == you.x_pos
- && mitm[ delay.parm1 ].y == you.y_pos)
- {
- // mark work done on the corpse in case we stop -- bwr
- mitm[ delay.parm1 ].plus2++;
- }
- else
- {
- // corpse is no longer valid!
- stop_delay();
- return;
- }
- }
-
- // Handle delay:
- if (delay.duration > 0)
- {
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "Delay type: %d duration: %d",
- delay.type, delay.duration );
-
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
- delay.duration--;
- }
- else
- {
- switch (delay.type)
- {
- case DELAY_AUTOPICKUP:
- break;
-
- case DELAY_WEAPON_SWAP:
- weapon_switch( delay.parm1 );
- break;
-
- case DELAY_ARMOUR_ON:
- {
- set_ident_flags( you.inv[ delay.parm1 ],
- ISFLAG_EQ_ARMOUR_MASK );
-
- in_name( delay.parm1, DESC_NOCAP_YOUR, str_pass );
- snprintf( info, INFO_SIZE,
- "You finish putting on %s.", str_pass );
- mpr(info);
-
- const equipment_type slot =
- get_armour_slot( you.inv[delay.parm1] );
-
- if (slot == EQ_BODY_ARMOUR)
- {
- you.equip[EQ_BODY_ARMOUR] = delay.parm1;
-
- if (you.duration[DUR_ICY_ARMOUR] != 0)
- {
- mpr( "Your icy armour melts away.", MSGCH_DURATION );
- you.redraw_armour_class = 1;
- you.duration[DUR_ICY_ARMOUR] = 0;
- }
- }
- else
- {
- switch (slot)
- {
- case EQ_SHIELD:
- if (you.duration[DUR_CONDENSATION_SHIELD])
- {
- mpr( "Your icy shield evaporates.", MSGCH_DURATION );
- you.duration[DUR_CONDENSATION_SHIELD] = 0;
- }
- you.equip[EQ_SHIELD] = delay.parm1;
- break;
- case EQ_CLOAK:
- you.equip[EQ_CLOAK] = delay.parm1;
- break;
- case EQ_HELMET:
- you.equip[EQ_HELMET] = delay.parm1;
- break;
- case EQ_GLOVES:
- you.equip[EQ_GLOVES] = delay.parm1;
- break;
- case EQ_BOOTS:
- you.equip[EQ_BOOTS] = delay.parm1;
- break;
- default:
- break;
- }
- }
-
- ego = get_armour_ego_type( you.inv[ delay.parm1 ] );
- if (ego != SPARM_NORMAL)
- {
- switch (ego)
- {
- case SPARM_RUNNING:
- strcpy(info, "You feel quick");
- strcat(info, (you.species == SP_NAGA
- || you.species == SP_CENTAUR) ? "." : " on your feet.");
- mpr(info);
- break;
-
- case SPARM_FIRE_RESISTANCE:
- mpr("You feel resistant to fire.");
- break;
-
- case SPARM_COLD_RESISTANCE:
- mpr("You feel resistant to cold.");
- break;
-
- case SPARM_POISON_RESISTANCE:
- mpr("You feel healthy.");
- break;
-
- case SPARM_SEE_INVISIBLE:
- mpr("You feel perceptive.");
- break;
-
- case SPARM_DARKNESS:
- if (!you.invis)
- mpr("You become transparent for a moment.");
- break;
-
- case SPARM_STRENGTH:
- modify_stat(STAT_STRENGTH, 3, false);
- break;
-
- case SPARM_DEXTERITY:
- modify_stat(STAT_DEXTERITY, 3, false);
- break;
-
- case SPARM_INTELLIGENCE:
- modify_stat(STAT_INTELLIGENCE, 3, false);
- break;
-
- case SPARM_PONDEROUSNESS:
- mpr("You feel rather ponderous.");
- // you.speed += 2;
- you.redraw_evasion = 1;
- break;
-
- case SPARM_LEVITATION:
- mpr("You feel rather light.");
- break;
-
- case SPARM_MAGIC_RESISTANCE:
- mpr("You feel resistant to magic.");
- break;
-
- case SPARM_PROTECTION:
- mpr("You feel protected.");
- break;
-
- case SPARM_STEALTH:
- mpr("You feel stealthy.");
- break;
-
- case SPARM_RESISTANCE:
- mpr("You feel resistant to extremes of temperature.");
- break;
-
- case SPARM_POSITIVE_ENERGY:
- mpr("Your life-force is being protected.");
- break;
-
- case SPARM_ARCHMAGI:
- if (!you.skills[SK_SPELLCASTING])
- mpr("You feel strangely numb.");
- else
- mpr("You feel extremely powerful.");
- break;
- }
- }
-
- if (is_random_artefact( you.inv[ delay.parm1 ] ))
- use_randart( delay.parm1 );
-
- if (item_cursed( you.inv[ delay.parm1 ] ))
- mpr( "Oops, that feels deathly cold." );
-
- you.redraw_armour_class = 1;
- you.redraw_evasion = 1;
- break;
- }
- case DELAY_ARMOUR_OFF:
- {
- in_name( delay.parm1, DESC_NOCAP_YOUR, str_pass );
- snprintf( info, INFO_SIZE, "You finish taking off %s.", str_pass );
- mpr(info);
-
- const equipment_type slot =
- get_armour_slot( you.inv[delay.parm1] );
-
- if (slot == EQ_BODY_ARMOUR)
- {
- you.equip[EQ_BODY_ARMOUR] = -1;
- }
- else
- {
- switch (slot)
- {
- case EQ_SHIELD:
- if (delay.parm1 == you.equip[EQ_SHIELD])
- you.equip[EQ_SHIELD] = -1;
- break;
-
- case EQ_CLOAK:
- if (delay.parm1 == you.equip[EQ_CLOAK])
- you.equip[EQ_CLOAK] = -1;
- break;
-
- case EQ_HELMET:
- if (delay.parm1 == you.equip[EQ_HELMET])
- you.equip[EQ_HELMET] = -1;
- break;
-
-
- case EQ_GLOVES:
- if (delay.parm1 == you.equip[EQ_GLOVES])
- you.equip[EQ_GLOVES] = -1;
- break;
-
- case EQ_BOOTS:
- if (delay.parm1 == you.equip[EQ_BOOTS])
- you.equip[EQ_BOOTS] = -1;
- break;
-
- default:
- break;
- }
- }
-
- unwear_armour( delay.parm1 );
-
- you.redraw_armour_class = 1;
- you.redraw_evasion = 1;
- break;
- }
- case DELAY_EAT:
- mpr( "You finish eating." );
- break;
-
- case DELAY_MEMORISE:
- mpr( "You finish memorising." );
- add_spell_to_memory( delay.parm1 );
- break;
-
- case DELAY_PASSWALL:
- {
- mpr( "You finish merging with the rock." );
- more(); // or the above message won't be seen
-
- const int pass_x = delay.parm1;
- const int pass_y = delay.parm2;
-
- if (pass_x != 0 && pass_y != 0)
- {
-
- switch (grd[ pass_x ][ pass_y ])
- {
- case DNGN_ROCK_WALL:
- case DNGN_STONE_WALL:
- case DNGN_METAL_WALL:
- case DNGN_GREEN_CRYSTAL_WALL:
- case DNGN_WAX_WALL:
- case DNGN_SILVER_STATUE:
- case DNGN_ORANGE_CRYSTAL_STATUE:
- ouch(1 + you.hp, 0, KILLED_BY_PETRIFICATION);
- break;
-
- case DNGN_SECRET_DOOR: // oughtn't happen
- case DNGN_CLOSED_DOOR: // open the door
- grd[ pass_x ][ pass_y ] = DNGN_OPEN_DOOR;
- break;
-
- default:
- break;
- }
-
- //jmf: hmm, what to do. kill the monster? (seems too powerful)
- // displace the monster? randomly teleport the monster?
- // This seems fair: try to move the monster, but if not
- // able to, then kill it.
- int mon = mgrd[ pass_x ][ pass_y ];
- if (mon != NON_MONSTER)
- {
- monster_blink( &menv[ mon ] );
-
- // recheck square for monster
- mon = mgrd[ pass_x ][ pass_y ];
- if (mon != NON_MONSTER)
- monster_die( &menv[ mon ], KILL_YOU, 0 );
- }
-
- you.x_pos = pass_x;
- you.y_pos = pass_y;
- redraw_screen();
-
- const unsigned char grid = grd[ you.x_pos ][ you.y_pos ];
- if ((grid == DNGN_LAVA || grid == DNGN_DEEP_WATER)
- && !player_is_levitating())
- {
- if (you.species == SP_MERFOLK && grid == DNGN_DEEP_WATER)
- {
- mpr("You fall into the water and return "
- "to your normal form.");
- merfolk_start_swimming();
- }
- else
- {
- fall_into_a_pool( true, grid );
- redraw_screen();
- }
- }
- }
- }
- break;
-
- case DELAY_BUTCHER:
- strcpy( info, "You finish " );
- strcat( info, (you.species == SP_TROLL
- || you.species == SP_GHOUL) ? "ripping"
- : "chopping" );
-
- strcat( info, " the corpse into pieces." );
- mpr( info );
-
- turn_corpse_into_chunks( mitm[ delay.parm1 ] );
-
- if (you.berserker && you.berserk_penalty != NO_BERSERK_PENALTY)
- {
- mpr("You enjoyed that.");
- you.berserk_penalty = 0;
- }
- break;
-
- case DELAY_DROP_ITEM:
- // Note: checking if item is dropable is assumed to
- // be done before setting up this delay... this includes
- // quantity (delay.parm2). -- bwr
-
- // Make sure item still exists.
- if (!is_valid_item( you.inv[ delay.parm1 ] ))
- break;
-
- // Must handle unwield_item before we attempt to copy
- // so that temporary brands and such are cleared. -- bwr
- if (delay.parm1 == you.equip[EQ_WEAPON])
- {
- unwield_item( delay.parm1 );
- you.equip[EQ_WEAPON] = -1;
- canned_msg( MSG_EMPTY_HANDED );
- }
-
- if (!copy_item_to_grid( you.inv[ delay.parm1 ],
- you.x_pos, you.y_pos, delay.parm2 ))
- {
- mpr("Too many items on this level, not dropping the item.");
- }
- else
- {
- quant_name( you.inv[ delay.parm1 ], delay.parm2,
- DESC_NOCAP_A, str_pass );
-
- snprintf( info, INFO_SIZE, "You drop %s.", str_pass );
- mpr(info);
-
- dec_inv_item_quantity( delay.parm1, delay.parm2 );
- }
- break;
-
- case DELAY_ASCENDING_STAIRS:
- up_stairs();
- untag_followers();
- break;
-
- case DELAY_DESCENDING_STAIRS:
- down_stairs( false, delay.parm1 );
- untag_followers();
- break;
-
- case DELAY_INTERUPTABLE:
- case DELAY_UNINTERUPTABLE:
- // these are simple delays that have no effect when complete
- break;
-
- default:
- mpr( "You finish doing something." );
- break;
- }
-
- you.wield_change = true;
- print_stats(); // force redraw of the stats
- you.turn_is_over = 1;
- you.delay_queue.pop();
- }
- }
-}
diff --git a/stone_soup/crawl-ref/source/delay.h b/stone_soup/crawl-ref/source/delay.h
deleted file mode 100644
index e171e355c8..0000000000
--- a/stone_soup/crawl-ref/source/delay.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * File: delay.h
- * Summary: Functions for handling multi-turn actions.
- *
- * Change History (most recent first):
- *
- * <1> 09/09/01 BWR Created
- */
-
-#ifndef DELAY_H
-#define DELAY_H
-
-void start_delay( int type, int turns, int parm1 = 0, int parm2 = 0 );
-void stop_delay( void );
-bool you_are_delayed( void );
-int current_delay_action( void );
-void handle_delay( void );
-
-#endif
diff --git a/stone_soup/crawl-ref/source/describe.cc b/stone_soup/crawl-ref/source/describe.cc
deleted file mode 100644
index 8179802ae9..0000000000
--- a/stone_soup/crawl-ref/source/describe.cc
+++ /dev/null
@@ -1,6799 +0,0 @@
-/*
- * File: describe.cc
- * Summary: Functions used to print information about various game objects.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <4> 10/14/99 BCR enummed describe_god()
- * <3> 10/13/99 BCR Added GOD_NO_GOD case in describe_god()
- * <2> 5/20/99 BWR Replaced is_artifact with
- * is_dumpable_artifact
- * <1> 4/20/99 JDJ Reformatted, uses string objects,
- * split out 10 new functions from
- * describe_item(), added
- * get_item_description and
- * is_artifact.
- */
-
-#include "AppHdr.h"
-#include "describe.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string>
-
-#ifdef DOS
-#include <conio.h>
-#endif
-
-#include "externs.h"
-
-#include "abl-show.h"
-#include "debug.h"
-#include "fight.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "macro.h"
-#include "mon-util.h"
-#include "player.h"
-#include "randart.h"
-#include "religion.h"
-#include "skills2.h"
-#include "spl-book.h"
-#include "stuff.h"
-#include "wpn-misc.h"
-#include "spl-util.h"
-
-
-// ========================================================================
-// Internal Functions
-// ========================================================================
-
-//---------------------------------------------------------------
-//
-// append_value
-//
-// Appends a value to the string. If plussed == 1, will add a + to
-// positive values (itoa always adds - to -ve ones).
-//
-//---------------------------------------------------------------
-static void append_value( std::string & description, int valu, bool plussed )
-{
- if (valu >= 0 && plussed == 1)
- description += "+";
-
- char value_str[80];
-
- itoa( valu, value_str, 10 );
-
- description += value_str;
-} // end append_value()
-
-//---------------------------------------------------------------
-//
-// print_description
-//
-// Takes a descpr string filled up with stuff from other functions,
-// and displays it with minor formatting to avoid cut-offs in mid
-// word and such. The character $ is interpreted as a CR.
-//
-//---------------------------------------------------------------
-static void print_description( const std::string &d )
-{
- unsigned int nextLine = std::string::npos;
- unsigned int currentPos = 0;
-
-#ifdef DOS
- const unsigned int lineWidth = 52;
-#else
- const unsigned int lineWidth = 70;
-#endif
-
- bool nlSearch = true; // efficiency
-
- textcolor(LIGHTGREY);
-
- while(currentPos < d.length())
- {
- if (currentPos != 0)
- {
-#ifdef PLAIN_TERM
- gotoxy(1, wherey() + 1);
-#endif
-#ifdef DOS_TERM
- cprintf(EOL);
-#endif
- }
-
- // see if $ sign is within one lineWidth
- if (nlSearch)
- {
- nextLine = d.find('$', currentPos);
-
- if (nextLine >= currentPos && nextLine < currentPos + lineWidth)
- {
- cprintf((d.substr(currentPos, nextLine - currentPos)).c_str());
- currentPos = nextLine + 1;
- continue;
- }
-
- if (nextLine == std::string::npos)
- nlSearch = false; // there are no newlines, don't search again.
- }
-
- // no newline -- see if rest of string will fit.
- if (currentPos + lineWidth >= d.length())
- {
- cprintf((d.substr(currentPos)).c_str());
- return;
- }
-
-
- // ok.. try to truncate at space.
- nextLine = d.rfind(' ', currentPos + lineWidth);
-
- if (nextLine > 0)
- {
- cprintf((d.substr(currentPos, nextLine - currentPos)).c_str());
- currentPos = nextLine + 1;
- continue;
- }
-
- // oops. just truncate.
- nextLine = currentPos + lineWidth;
-
- if (nextLine > d.length())
- nextLine = d.length();
-
- cprintf((d.substr(currentPos, nextLine - currentPos)).c_str());
- currentPos = nextLine;
- }
-}
-
-//---------------------------------------------------------------
-//
-// randart_descpr
-//
-// Appends the various powers of a random artefact to the description
-// string.
-//
-//---------------------------------------------------------------
-static void randart_descpr( std::string &description, const item_def &item )
-{
- unsigned int old_length = description.length();
-
- FixedVector< char, RA_PROPERTIES > proprt;
- randart_wpn_properties( item, proprt );
-
- if (proprt[ RAP_AC ])
- {
- description += "$It affects your AC (";
- append_value(description, proprt[ RAP_AC ], true);
- description += ").";
- }
-
- if (proprt[ RAP_EVASION ])
- {
- description += "$It affects your evasion (";
- append_value(description, proprt[ RAP_EVASION ], true);
- description += ").";
- }
-
- if (proprt[ RAP_STRENGTH ])
- {
- description += "$It affects your strength (";
- append_value(description, proprt[ RAP_STRENGTH ], true);
- description += ").";
- }
-
- if (proprt[ RAP_INTELLIGENCE ])
- {
- description += "$It affects your intelligence (";
- append_value(description, proprt[ RAP_INTELLIGENCE ], true);
- description += ").";
- }
-
- if (proprt[ RAP_DEXTERITY ])
- {
- description += "$It affects your dexterity (";
- append_value(description, proprt[ RAP_DEXTERITY ], true);
- description += ").";
- }
-
- if (proprt[ RAP_ACCURACY ])
- {
- description += "$It affects your accuracy (";
- append_value(description, proprt[ RAP_ACCURACY ], true);
- description += ").";
- }
-
- if (proprt[ RAP_DAMAGE ])
- {
- description += "$It affects your damage-dealing abilities (";
- append_value(description, proprt[ RAP_DAMAGE ], true);
- description += ").";
- }
-
- if (proprt[ RAP_FIRE ] < -2)
- description += "$It makes you highly vulnerable to fire. ";
- else if (proprt[ RAP_FIRE ] == -2)
- description += "$It makes you greatly susceptible to fire. ";
- else if (proprt[ RAP_FIRE ] == -1)
- description += "$It makes you susceptible to fire. ";
- else if (proprt[ RAP_FIRE ] == 1)
- description += "$It protects you from fire. ";
- else if (proprt[ RAP_FIRE ] == 2)
- description += "$It greatly protects you from fire. ";
- else if (proprt[ RAP_FIRE ] > 2)
- description += "$It renders you almost immune to fire. ";
-
- if (proprt[ RAP_COLD ] < -2)
- description += "$It makes you highly susceptible to cold. ";
- else if (proprt[ RAP_COLD ] == -2)
- description += "$It makes you greatly susceptible to cold. ";
- else if (proprt[ RAP_COLD ] == -1)
- description += "$It makes you susceptible to cold. ";
- else if (proprt[ RAP_COLD ] == 1)
- description += "$It protects you from cold. ";
- else if (proprt[ RAP_COLD ] == 2)
- description += "$It greatly protects you from cold. ";
- else if (proprt[ RAP_COLD ] > 2)
- description += "$It renders you almost immune to cold. ";
-
- if (proprt[ RAP_ELECTRICITY ])
- description += "$It insulates you from electricity. ";
-
- if (proprt[ RAP_POISON ])
- description += "$It protects you from poison. ";
-
- if (proprt[ RAP_NEGATIVE_ENERGY ] == 1)
- description += "$It partially protects you from negative energy. ";
- else if (proprt[ RAP_NEGATIVE_ENERGY ] == 2)
- description += "$It protects you from negative energy. ";
- else if (proprt[ RAP_NEGATIVE_ENERGY ] > 2)
- description += "$It renders you almost immune negative energy. ";
-
- if (proprt[ RAP_MAGIC ])
- description += "$It protects you from magic. ";
-
- if (proprt[ RAP_STEALTH ] < 0)
- {
- if (proprt[ RAP_STEALTH ] < -20)
- description += "$It makes you much less stealthy. ";
- else
- description += "$It makes you less stealthy. ";
- }
- else if (proprt[ RAP_STEALTH ] > 0)
- {
- if (proprt[ RAP_STEALTH ] > 20)
- description += "$It makes you much more stealthy. ";
- else
- description += "$It makes you more stealthy. ";
- }
-
- if (proprt[ RAP_EYESIGHT ])
- description += "$It enhances your eyesight. ";
-
- if (proprt[ RAP_INVISIBLE ])
- description += "$It lets you turn invisible. ";
-
- if (proprt[ RAP_LEVITATE ])
- description += "$It lets you levitate. ";
-
- if (proprt[ RAP_BLINK ])
- description += "$It lets you blink. ";
-
- if (proprt[ RAP_CAN_TELEPORT ])
- description += "$It lets you teleport. ";
-
- if (proprt[ RAP_BERSERK ])
- description += "$It lets you go berserk. ";
-
- if (proprt[ RAP_MAPPING ])
- description += "$It lets you sense your surroundings. ";
-
- if (proprt[ RAP_NOISES ])
- description += "$It makes noises. ";
-
- if (proprt[ RAP_PREVENT_SPELLCASTING ])
- description += "$It prevents spellcasting. ";
-
- if (proprt[ RAP_CAUSE_TELEPORTATION ])
- description += "$It causes teleportation. ";
-
- if (proprt[ RAP_PREVENT_TELEPORTATION ])
- description += "$It prevents most forms of teleportation. ";
-
- if (proprt[ RAP_ANGRY ])
- description += "$It makes you angry. ";
-
- if (proprt[ RAP_METABOLISM ] >= 3)
- description += "$It greatly speeds your metabolism. ";
- else if (proprt[ RAP_METABOLISM ])
- description += "$It speeds your metabolism. ";
-
- if (proprt[ RAP_MUTAGENIC ] > 3)
- description += "$It glows with mutagenic radiation.";
- else if (proprt[ RAP_MUTAGENIC ])
- description += "$It emits mutagenic radiations.";
-
- if (old_length != description.length())
- description += "$";
-
- if (is_unrandom_artefact( item ))
- {
- const char *desc = unrandart_descrip( 0, item );
- if (strlen( desc ) > 0)
- {
- description += desc;
- description += "$";
- }
- }
-}
-
-
-//---------------------------------------------------------------
-//
-// describe_demon
-//
-// Describes the random demons you find in Pandemonium.
-//
-//---------------------------------------------------------------
-static std::string describe_demon(void)
-{
- long globby = 0;
-
- for (unsigned int i = 0; i < strlen( ghost.name ); i++)
- globby += ghost.name[i];
-
- globby *= strlen( ghost.name );
-
- push_rng_state();
- seed_rng( globby );
-
- std::string description = "A powerful demon, ";
-
- description += ghost.name;
- description += " has a";
-
- switch (random2(31))
- {
- case 0:
- description += " huge, barrel-shaped ";
- break;
- case 1:
- description += " wispy, insubstantial ";
- break;
- case 2:
- description += " spindly ";
- break;
- case 3:
- description += " skeletal ";
- break;
- case 4:
- description += " horribly deformed ";
- break;
- case 5:
- description += " spiny ";
- break;
- case 6:
- description += " waif-like ";
- break;
- case 7:
- description += " scaly ";
- break;
- case 8:
- description += " sickeningly deformed ";
- break;
- case 9:
- description += " bruised and bleeding ";
- break;
- case 10:
- description += " sickly ";
- break;
- case 11:
- description += " mass of writhing tentacles for a ";
- break;
- case 12:
- description += " mass of ropey tendrils for a ";
- break;
- case 13:
- description += " tree trunk-like ";
- break;
- case 14:
- description += " hairy ";
- break;
- case 15:
- description += " furry ";
- break;
- case 16:
- description += " fuzzy ";
- break;
- case 17:
- description += "n obese ";
- break;
- case 18:
- description += " fat ";
- break;
- case 19:
- description += " slimy ";
- break;
- case 20:
- description += " wrinkled ";
- break;
- case 21:
- description += " metallic ";
- break;
- case 22:
- description += " glassy ";
- break;
- case 23:
- description += " crystalline ";
- break;
- case 24:
- description += " muscular ";
- break;
- case 25:
- description += "n icky ";
- break;
- case 26:
- description += " swollen ";
- break;
- case 27:
- description += " lumpy ";
- break;
- case 28:
- description += " armoured ";
- break;
- case 29:
- description += " carapaced ";
- break;
- case 30:
- description += " slender ";
- break;
- }
-
- description += "body";
-
-
- switch (ghost.values[GVAL_DEMONLORD_FLY])
- {
- case 1: // proper flight
- switch (random2(10))
- {
- case 0:
- description += " with small insectoid wings";
- break;
- case 1:
- description += " with large insectoid wings";
- break;
- case 2:
- description += " with moth-like wings";
- break;
- case 3:
- description += " with butterfly wings";
- break;
- case 4:
- description += " with huge, bat-like wings";
- break;
- case 5:
- description += " with fleshy wings";
- break;
- case 6:
- description += " with small, bat-like wings";
- break;
- case 7:
- description += " with hairy wings";
- break;
- case 8:
- description += " with great feathered wings";
- break;
- case 9:
- description += " with shiny metal wings";
- break;
- default:
- break;
- }
- break;
-
- case 2: // levitation
- if (coinflip())
- description += " which hovers in mid-air";
- else
- description += " with sacs of gas hanging from its back";
- break;
-
- default: // does not fly
- switch (random2(40))
- {
- default:
- break;
- case 12:
- description += " covered in tiny crawling spiders";
- break;
- case 13:
- description += " covered in tiny crawling insects";
- break;
- case 14:
- description += " and the head of a crocodile";
- break;
- case 15:
- description += " and the head of a hippopotamus";
- break;
- case 16:
- description += " and a cruel curved beak for a mouth";
- break;
- case 17:
- description += " and a straight sharp beak for a mouth";
- break;
- case 18:
- description += " and no head at all";
- break;
- case 19:
- description += " and a hideous tangle of tentacles for a mouth";
- break;
- case 20:
- description += " and an elephantine trunk";
- break;
- case 21:
- description += " and an evil-looking proboscis";
- break;
- case 22:
- description += " and dozens of eyes";
- break;
- case 23:
- description += " and two ugly heads";
- break;
- case 24:
- description += " and a long serpentine tail";
- break;
- case 25:
- description += " and a pair of huge tusks growing from its jaw";
- break;
- case 26:
- description +=
- " and a single huge eye, in the centre of its forehead";
- break;
- case 27:
- description += " and spikes of black metal for teeth";
- break;
- case 28:
- description += " and a disc-shaped sucker for a head";
- break;
- case 29:
- description += " and huge, flapping ears";
- break;
- case 30:
- description += " and a huge, toothy maw in the centre of its chest";
- break;
- case 31:
- description += " and a giant snail shell on its back";
- break;
- case 32:
- description += " and a dozen heads";
- break;
- case 33:
- description += " and the head of a jackal";
- break;
- case 34:
- description += " and the head of a baboon";
- break;
- case 35:
- description += " and a huge, slobbery tongue";
- break;
- case 36:
- description += " which is covered in oozing lacerations";
- break;
- case 37:
- description += " and the head of a frog";
- break;
- case 38:
- description += " and the head of a yak";
- break;
- case 39:
- description += " and eyes out on stalks";
- break;
- }
- break;
- }
-
- description += ".";
-
- switch (random2(40) + (you.species == SP_MUMMY ? 3 : 0))
- {
- case 0:
- description += " It stinks of brimstone.";
- break;
- case 1:
- description += " It smells like rotting flesh";
- if (you.species == SP_GHOUL)
- description += " - yum!";
- else
- description += ".";
- break;
- case 2:
- description += " It is surrounded by a sickening stench.";
- break;
- case 3:
- description += " It seethes with hatred of the living.";
- break;
- case 4:
- description += " Tiny orange flames dance around it.";
- break;
- case 5:
- description += " Tiny purple flames dance around it.";
- break;
- case 6:
- description += " It is surrounded by a weird haze.";
- break;
- case 7:
- description += " It glows with a malevolent light.";
- break;
- case 8:
- description += " It looks incredibly angry.";
- break;
- case 9:
- description += " It oozes with slime.";
- break;
- case 10:
- description += " It dribbles constantly.";
- break;
- case 11:
- description += " Mould grows all over it.";
- break;
- case 12:
- description += " It looks diseased.";
- break;
- case 13:
- description += " It looks as frightened of you as you are of it.";
- break;
- case 14:
- description += " It moves in a series of hideous convulsions.";
- break;
- case 15:
- description += " It moves with an unearthly grace.";
- break;
- case 16:
- description += " It hungers for your soul!";
- break;
- case 17:
- description += " It leaves a glistening oily trail.";
- break;
- case 18:
- description += " It shimmers before your eyes.";
- break;
- case 19:
- description += " It is surrounded by a brilliant glow.";
- break;
- case 20:
- description += " It radiates an aura of extreme power.";
- break;
- default:
- break;
- }
-
- pop_rng_state();
- return description;
-} // end describe_demon()
-
-
-//---------------------------------------------------------------
-//
-// describe_weapon
-//
-//---------------------------------------------------------------
-static std::string describe_weapon( const item_def &item, char verbose)
-{
- std::string description;
-
- description.reserve(200);
-
- description = "";
-
- if (is_fixed_artefact( item ))
- {
- if (item_ident( item, ISFLAG_KNOW_PROPERTIES ))
- {
- description += "$";
-
- switch (item.special)
- {
- case SPWPN_SINGING_SWORD:
- description += "This blessed weapon loves nothing more "
- "than to sing to its owner, "
- "whether they want it to or not. ";
- break;
- case SPWPN_WRATH_OF_TROG:
- description += "This was the favourite weapon of "
- "the old god Trog, before he lost it one day. "
- "It induces a bloodthirsty berserker rage in "
- "anyone who uses it to strike another. ";
- break;
- case SPWPN_SCYTHE_OF_CURSES:
- description += "This weapon carries a "
- "terrible and highly irritating curse. ";
- break;
- case SPWPN_MACE_OF_VARIABILITY:
- description += "It is rather unreliable. ";
- break;
- case SPWPN_GLAIVE_OF_PRUNE:
- description += "It is the creation of a mad god, and "
- "carries a curse which transforms anyone "
- "possessing it into a prune. Fortunately, "
- "the curse works very slowly, and one can "
- "use it briefly with no consequences "
- "worse than slightly purple skin and a few wrinkles. ";
- break;
- case SPWPN_SCEPTRE_OF_TORMENT:
- description += "This truly accursed weapon is "
- "an instrument of Hell. ";
- break;
- case SPWPN_SWORD_OF_ZONGULDROK:
- description += "This dreadful weapon is used "
- "at the user's peril. ";
- break;
- case SPWPN_SWORD_OF_CEREBOV:
- description += "Eerie flames cover its twisted blade. ";
- break;
- case SPWPN_STAFF_OF_DISPATER:
- description += "This legendary item can unleash "
- "the fury of Hell. ";
- break;
- case SPWPN_SCEPTRE_OF_ASMODEUS:
- description += "It carries some of the powers of "
- "the arch-fiend Asmodeus. ";
- break;
- case SPWPN_SWORD_OF_POWER:
- description += "It rewards the powerful with power "
- "and the meek with weakness. ";
- break;
- case SPWPN_KNIFE_OF_ACCURACY:
- description += "It is almost unerringly accurate. ";
- break;
- case SPWPN_STAFF_OF_OLGREB:
- description += "It was the magical weapon wielded by the "
- "mighty wizard Olgreb before he met his "
- "fate somewhere within these dungeons. It "
- "grants its wielder resistance to the "
- "effects of poison and increases their "
- "ability to use venomous magic, and "
- "carries magical powers which can be evoked. ";
- break;
- case SPWPN_VAMPIRES_TOOTH:
- description += "It is lethally vampiric. ";
- break;
- case SPWPN_STAFF_OF_WUCAD_MU:
- description += "Its power varies in proportion to "
- "its wielder's intelligence. "
- "Using it can be a bit risky. ";
- break;
- }
-
- description += "$";
- }
- else if (item_ident( item, ISFLAG_KNOW_TYPE ))
- {
- // We know it's an artefact type weapon, but not what it does.
- description += "$This weapon may have some hidden properties.$";
- }
- }
- else if (is_unrandom_artefact( item )
- && strlen(unrandart_descrip(1, item)) != 0)
- {
- description += unrandart_descrip(1, item);
- description += "$";
- }
- else
- {
- if (verbose == 1)
- {
- switch (item.sub_type)
- {
- case WPN_CLUB:
- description += "A heavy piece of wood. ";
- break;
-
- case WPN_MACE:
- description += "A long handle "
- "with a heavy lump on one end. ";
- break;
-
- case WPN_FLAIL:
- description += "Like a mace, but with a length of chain "
- "between the handle and the lump of metal. ";
- break;
-
- case WPN_DAGGER:
- description += "A long knife or a very short sword, "
- "which can be held or thrown. ";
- break;
-
- case WPN_KNIFE:
- description += "A simple survival knife. "
- "Designed more for utility than combat, "
- "it looks quite capable of butchering a corpse. ";
- break;
-
- case WPN_MORNINGSTAR:
- description += "A mace covered in spikes. ";
- break;
-
- case WPN_SHORT_SWORD:
- description += "A sword with a short, slashing blade. ";
- break;
-
- case WPN_LONG_SWORD:
- description += "A sword with a long, slashing blade. ";
- break;
-
- case WPN_GREAT_SWORD:
- description += "A sword with a very long, heavy blade "
- "and a long handle. ";
- break;
-
- case WPN_SCIMITAR:
- description += "A long sword with a curved blade. ";
- break;
-
- case WPN_HAND_AXE:
- description += "An small axe designed for either hand combat "
- "or throwing. ";
- // "It might also make a good tool.";
- break;
-
- case WPN_BATTLEAXE:
- description += "A large axe with a double-headed blade. ";
- break;
-
- case WPN_SPEAR:
- description += "A long stick with a pointy blade on one end, "
- "to be held or thrown. ";
- break;
-
- case WPN_TRIDENT:
- description +=
- "A hafted weapon with three points at one end. ";
- break;
-
- case WPN_HALBERD:
- description +=
- "A long pole with a spiked axe head on one end. ";
- break;
-
- case WPN_SLING:
- description +=
- "A piece of cloth and leather for launching stones, "
- "which do a small amount of damage on impact. ";
- break;
-
- case WPN_BOW:
- description += "A curved piece of wood and string, "
- "for shooting arrows. It does good damage in combat, "
- "and a skilled user can use it to great effect. ";
- break;
-
- case WPN_LONGBOW:
- description += "A long, strong bow made of yew. "
- "It does excellent damage in combat "
- "and a skilled archer can use it to great effect. ";
- break;
-
- case WPN_BLOWGUN:
- description += "A long, light tube, open at both ends. Doing "
- "very little damage, its main use is to fire poisoned "
- "needles from afar. It makes very little noise. ";
- break;
-
- case WPN_CROSSBOW:
- description += "A piece of machinery used for firing bolts, "
- "which takes some time to load and fire. "
- "It does very good damage in combat. ";
- break;
-
- case WPN_HAND_CROSSBOW:
- description += "A small crossbow, for firing darts. ";
- break;
-
- case WPN_GLAIVE:
- description +=
- "A pole with a large, heavy blade on one end. ";
- break;
-
- case WPN_QUARTERSTAFF:
- description += "A sturdy wooden pole. ";
- break;
-
- case WPN_SCYTHE:
- description +=
- "A farm implement, usually unsuited to combat. ";
- break;
-
- case WPN_GIANT_CLUB:
- description += "A giant lump of wood, "
- "shaped for an ogre's hands. ";
- break;
-
- case WPN_GIANT_SPIKED_CLUB:
- description +=
- "A giant lump of wood with sharp spikes at one end. ";
- break;
-
- case WPN_EVENINGSTAR:
- description += "The opposite of a morningstar. ";
- break;
-
- case WPN_QUICK_BLADE:
- description += "A small and magically quick sword. ";
- break;
-
- case WPN_KATANA:
- description += "A very rare and extremely effective "
- "imported weapon, featuring a long "
- "single-edged blade. ";
- break;
-
- case WPN_LAJATANG:
- description += "A very rare and extremely effective "
- "imported weapon, featuring a pole with half-moon blades "
- "at both ends. ";
- break;
-
- case WPN_LOCHABER_AXE:
- description += "An enormous combination of a pike "
- "and a battle axe.";
- break;
-
- case WPN_EXECUTIONERS_AXE:
- description += "A huge axe. ";
- break;
-
- case WPN_DOUBLE_SWORD:
- description +=
- "A magical weapon with two razor-sharp blades. ";
- break;
-
- case WPN_TRIPLE_SWORD:
- description += "A magical weapon with three "
- "great razor-sharp blades. ";
- break;
-
- case WPN_HAMMER:
- description += "The kind of thing you hit nails with, "
- "adapted for battle. ";
- break;
-
- case WPN_ANCUS:
- description += "A large and vicious toothed club. ";
- break;
-
- case WPN_WHIP:
- description += "A whip. ";
- break;
-
- case WPN_SABRE:
- description += "A sword with a medium length slashing blade. ";
- break;
-
- case WPN_DEMON_BLADE:
- description +=
- "A terrible weapon, forged in the fires of Hell. ";
- break;
-
- case WPN_BLESSED_BLADE:
- description += "A blade blessed by the Shining One. ";
- break;
-
- case WPN_DEMON_WHIP:
- description += "A terrible weapon, woven "
- "in the depths of the inferno. ";
- break;
-
- case WPN_DEMON_TRIDENT:
- description +=
- "A terrible weapon, molded by fire and brimstone. ";
- break;
-
- case WPN_BROAD_AXE:
- description += "An axe with a large blade. ";
- break;
-
- case WPN_WAR_AXE:
- description += "An axe intended for hand to hand combat. ";
- break;
-
- case WPN_SPIKED_FLAIL:
- description +=
- "A flail with large spikes on the metal lump. ";
- break;
-
- case WPN_GREAT_MACE:
- description += "A large and heavy mace. ";
- break;
-
- case WPN_DIRE_FLAIL:
- description += "A flail with spiked lumps on both ends.";
- break;
-
- case WPN_FALCHION:
- description += "A sword with a broad slashing blade. ";
- break;
-
- default:
- DEBUGSTR("Unknown weapon");
- }
-
- description += "$";
- }
- }
-
- if (verbose == 1 && !launches_things( item.sub_type ))
- {
- description += "$Damage rating: ";
- append_value(description, property( item, PWPN_DAMAGE ), false);
-
- description += "$Accuracy rating: ";
- append_value(description, property( item, PWPN_HIT ), true);
-
- description += "$Base attack delay: ";
- append_value(description, property( item, PWPN_SPEED ) * 10, false);
- description += "%%";
- }
- description += "$";
-
- if (!is_fixed_artefact( item ))
- {
- int spec_ench = get_weapon_brand( item );
-
- if (!is_random_artefact( item ) && verbose == 0)
- spec_ench = SPWPN_NORMAL;
-
- // special weapon descrip
- if (spec_ench != SPWPN_NORMAL && item_ident( item, ISFLAG_KNOW_TYPE ))
- {
- description += "$";
-
- switch (spec_ench)
- {
- case SPWPN_FLAMING:
- description += "It emits flame when wielded, "
- "causing extra injury to most foes "
- "and up to double damage against "
- "particularly susceptible opponents. ";
- break;
- case SPWPN_FREEZING:
- description += "It has been specially enchanted to "
- "freeze those struck by it, causing "
- "extra injury to most foes and "
- "up to double damage against "
- "particularly susceptible opponents. ";
- break;
- case SPWPN_HOLY_WRATH:
- description += "It has been blessed by the Shining One "
- "to harm undead and cause great damage to "
- "the unholy creatures of Hell or Pandemonium. ";
- break;
- case SPWPN_ELECTROCUTION:
- description += "Occasionally upon striking a foe "
- "it will discharge some electrical energy "
- "and cause terrible harm. ";
- break;
- case SPWPN_ORC_SLAYING:
- description += "It is especially effective against "
- "all of orcish descent. ";
- break;
- case SPWPN_VENOM:
- if (launches_things( item.sub_type ))
- description += "It poisons the unbranded ammo it fires. ";
- else
- description += "It poisons the flesh of those it strikes. ";
- break;
- case SPWPN_PROTECTION:
- description += "It protects the one who wields it against "
- "injury (+5 to AC). ";
- break;
- case SPWPN_DRAINING:
- description += "A truly terrible weapon, "
- "it drains the life of those it strikes. ";
- break;
- case SPWPN_SPEED:
- if (launches_things( item.sub_type ))
- {
- description += "It allows its wielder to fire twice when "
- "they would otherwise have fired only once. ";
- }
- else
- {
- description += "It allows its wielder to attack twice when "
- "they would otherwise have struck only once. ";
- }
- break;
- case SPWPN_VORPAL:
- if (launches_things(item.sub_type))
- {
- description += "Any ";
- description += ammo_name( item );
- description += " fired from it inflicts extra damage.";
- }
- else
- {
- description += "It inflicts extra damage upon your enemies. ";
- }
- break;
- case SPWPN_FLAME:
- description += "It turns projectiles fired from it into "
- "bolts of fire. ";
- break;
- case SPWPN_FROST:
- description += "It turns projectiles fired from it into "
- "bolts of frost. ";
- break;
- case SPWPN_VAMPIRICISM:
- description += "It inflicts no extra harm, "
- "but heals its wielder somewhat when "
- "he or she strikes a living foe. ";
- break;
- case SPWPN_DISRUPTION:
- description += "It is a weapon blessed by Zin, "
- "and can inflict up to fourfold damage "
- "when used against the undead. ";
- break;
- case SPWPN_PAIN:
- description += "In the hands of one skilled in "
- "necromantic magic it inflicts "
- "extra damage on living creatures. ";
- break;
- case SPWPN_DISTORTION:
- description += "It warps and distorts space around it. ";
- break;
- case SPWPN_REACHING:
- description += "It can be evoked to extend its reach. ";
- break;
- }
- }
-
- if (is_random_artefact( item ))
- {
- if (item_ident( item, ISFLAG_KNOW_PROPERTIES ))
- {
- unsigned int old_length = description.length();
- randart_descpr( description, item );
-
- if (description.length() == old_length)
- description += "$";
- }
- else if (item_ident( item, ISFLAG_KNOW_TYPE ))
- {
- description += "$This weapon may have some hidden properties.$";
- }
- }
- else if (spec_ench != SPWPN_NORMAL && item_ident( item, ISFLAG_KNOW_TYPE ))
- {
- description += "$";
- }
- }
-
- if (item_known_cursed( item ))
- {
- description += "$It has a curse placed upon it.";
- }
-
- if (verbose == 1 && !launches_things( item.sub_type ))
- {
-#ifdef USE_NEW_COMBAT_STATS
- const int str_weight = weapon_str_weight( item.base_type, item.sub_type );
-
- if (str_weight >= 8)
- description += "$This weapon is best used by the strong.";
- else if (str_weight > 5)
- description += "$This weapon is better for the strong.";
- else if (str_weight <= 2)
- description += "$This weapon is best used by the dexterous.";
- else if (str_weight < 5)
- description += "$This weapon is better for the dexterous.";
-#endif
-
- switch (hands_reqd_for_weapon(item.base_type, item.sub_type))
- {
- case HANDS_ONE:
- description += "$It is a one handed weapon.";
- break;
- case HANDS_HALF:
- description += "$It can be used with one hand, or more "
- "effectively with two (i.e. when not using a shield).";
- break;
- case HANDS_TWO:
- description += "$It is a two handed weapon.";
- break;
- }
- }
-
- if (!is_random_artefact( item ))
- {
- switch (get_equip_race( item ))
- {
- case ISFLAG_DWARVEN:
- description += "$It is well-crafted and very durable.";
- break;
- }
-
- if (launches_things( item.sub_type ))
- {
- switch (get_equip_race( item ))
- {
- case ISFLAG_DWARVEN:
- description += "$It is most deadly when used with "
- "dwarven ammunition.";
- break;
- case ISFLAG_ELVEN:
- description += "$It is most deadly when used with "
- "elven ammunition.";
- break;
- case ISFLAG_ORCISH:
- description += "$It is most deadly when used with "
- "orcish ammunition.";
- break;
- }
- }
- }
-
- if (verbose == 1)
- {
- description += "$It falls into the";
-
- switch (item.sub_type)
- {
- case WPN_SLING:
- description += " 'slings' category. ";
- break;
- case WPN_BOW:
- case WPN_LONGBOW:
- description += " 'bows' category. ";
- break;
- case WPN_HAND_CROSSBOW:
- case WPN_CROSSBOW:
- description += " 'crossbows' category. ";
- break;
- case WPN_BLOWGUN:
- description += " 'darts' category. ";
- break;
- default:
- // Melee weapons
- switch (weapon_skill(item.base_type, item.sub_type))
- {
- case SK_SHORT_BLADES:
- description += " 'short blades' category. ";
- break;
- case SK_LONG_SWORDS:
- description += " 'long swords' category. ";
- break;
- case SK_AXES:
- description += " 'axes' category. ";
- break;
- case SK_MACES_FLAILS:
- description += " 'maces and flails' category. ";
- break;
- case SK_POLEARMS:
- description += " 'pole-arms' category. ";
- break;
- case SK_STAVES:
- description += " 'staves' category. ";
- break;
- default:
- description += " 'bug' category. ";
- DEBUGSTR("Unknown weapon type");
- break;
- }
- }
- }
-
- return (description);
-}
-
-
-//---------------------------------------------------------------
-//
-// describe_ammo
-//
-//---------------------------------------------------------------
-static std::string describe_ammo( const item_def &item )
-{
- std::string description;
-
- description.reserve(64);
-
- switch (item.sub_type)
- {
- case MI_STONE:
- description += "A stone. ";
- break;
- case MI_ARROW:
- description += "An arrow. ";
- break;
- case MI_NEEDLE:
- description += "A needle. ";
- break;
- case MI_BOLT:
- description += "A crossbow bolt. ";
- break;
- case MI_DART:
- description += "A small throwing weapon. ";
- break;
- case MI_LARGE_ROCK:
- description += "A rock, used by giants as a missile. ";
- break;
- case MI_NONE: // was eggplant
- description += "A purple vegetable. "
- "The presence of this object in the game "
- "indicates a bug (or some kind of cheating on your part). ";
- break;
- default:
- DEBUGSTR("Unknown ammo type");
- break;
- }
-
- if (item.special != 0 && item_ident( item, ISFLAG_KNOW_TYPE ))
- {
- switch (item.special)
- {
- case 1:
- description += "$When fired from an appropriate launcher, "
- "it turns into a bolt of flame. ";
- break;
- case 2:
- description += "$When fired from an appropriate launcher, "
- "it turns into a bolt of ice. ";
- break;
- case 3:
- case 4:
- description += "$It is coated with poison. ";
- break;
- }
- }
-
- description += "$";
-
- return (description);
-}
-
-
-//---------------------------------------------------------------
-//
-// describe_armour
-//
-//---------------------------------------------------------------
-static std::string describe_armour( const item_def &item, char verbose )
-{
- std::string description;
-
- description.reserve(200);
-
- if (is_unrandom_artefact( item )
- && strlen(unrandart_descrip(1, item)) != 0)
- {
- description += "$";
- description += unrandart_descrip(1, item);
- description += "$$";
- }
- else
- {
- if (verbose == 1)
- {
- switch (item.sub_type)
- {
- case ARM_ROBE:
- description += "A cloth robe. ";
- break;
- case ARM_LEATHER_ARMOUR:
- description += "A suit made of hardened leather. ";
- break;
- case ARM_RING_MAIL:
- description += "A leather suit covered in little rings. ";
- break;
- case ARM_SCALE_MAIL:
- description +=
- "A leather suit covered in little metal plates. ";
- break;
- case ARM_CHAIN_MAIL:
- description += "A suit made of interlocking metal rings. ";
- break;
- case ARM_SPLINT_MAIL:
- description += "A suit made of splints of metal. ";
- break;
- case ARM_BANDED_MAIL:
- description += "A suit made of bands of metal. ";
- break;
- case ARM_PLATE_MAIL:
- description += "A suit of mail and large plates of metal. ";
- break;
- case ARM_SHIELD:
- description +=
- "A piece of metal, to be strapped on one's arm. "
- "It is cumbersome to wear, and slightly slows "
- "the rate at which you may attack. ";
- break;
- case ARM_CLOAK:
- description += "A cloth cloak. ";
- break;
-
- case ARM_HELMET:
- switch (get_helmet_type( item ))
- {
- case THELM_HELMET:
- case THELM_HELM:
- description += "A piece of metal headgear. ";
- break;
- case THELM_CAP:
- description += "A cloth or leather cap. ";
- break;
- case THELM_WIZARD_HAT:
- description += "A conical cloth hat. ";
- break;
- }
- break;
-
- case ARM_GLOVES:
- description += "A pair of gloves. ";
- break;
-
- case ARM_CENTAUR_BARDING:
- description += "An armour made for centaurs, "
- "to wear over their equine half.";
- break;
-
- case ARM_NAGA_BARDING:
- description += "A special armour made for nagas, "
- "to wear over their tails.";
- break;
-
- case ARM_BOOTS:
- description += "A pair of boots.";
- break;
-
- case ARM_BUCKLER:
- description += "A small shield. ";
- break;
- case ARM_LARGE_SHIELD:
- description += "Like a normal shield, only larger. ";
- if (you.species == SP_TROLL || you.species == SP_OGRE
- || you.species == SP_OGRE_MAGE
- || player_genus(GENPC_DRACONIAN))
- {
- description += "It looks like it would fit you well. ";
- }
- else
- {
- description += "It is very cumbersome to wear, and "
- "slows the rate at which you may attack. ";
- }
- break;
- case ARM_DRAGON_HIDE:
- description += "The scaly skin of a dragon. I suppose "
- "you could wear it if you really wanted to. ";
- break;
- case ARM_TROLL_HIDE:
- description += "The stiff and knobbly hide of a troll. "
- "I suppose you could wear it "
- "if you really wanted to. ";
- break;
- case ARM_CRYSTAL_PLATE_MAIL:
- description += "An incredibly heavy but extremely effective "
- "suit of crystalline armour. "
- "It is somewhat resistant to corrosion. ";
- break;
- case ARM_DRAGON_ARMOUR:
- description += "A magical armour, made from the scales of "
- "a fire-breathing dragon. It provides "
- "great protection from the effects of fire, "
- "but renders its wearer more susceptible to "
- "the effects of cold. ";
- break;
- case ARM_TROLL_LEATHER_ARMOUR:
- description += "A magical armour, made from the stiff and "
- "knobbly skin of a common troll. It magically regenerates "
- "its wearer's flesh at a fairly slow rate "
- "(unless already a troll). ";
- break;
- case ARM_ICE_DRAGON_HIDE:
- description += "The scaly skin of a dragon. I suppose "
- "you could wear it if you really wanted to. ";
- break;
- case ARM_ICE_DRAGON_ARMOUR:
- description += "A magical armour, made from the scales of "
- "a cold-breathing dragon. It provides "
- "great protection from the effects of cold, "
- "but renders its wearer more susceptible to "
- "the effects of fire and heat. ";
- break;
- case ARM_STEAM_DRAGON_HIDE:
- description += "The soft and supple scaley skin of "
- "a steam dragon. I suppose you could "
- "wear it if you really wanted to. ";
- break;
- case ARM_STEAM_DRAGON_ARMOUR:
- description += "A magical armour, made from the scales of "
- "a steam-breathing dragon. Although unlike "
- "the armour made from the scales of some "
- "larger dragons it does not provide its wearer "
- "with much in the way of special magical "
- "protection, it is extremely light and "
- "as supple as cloth. ";
- break; /* Protects from steam */
- case ARM_MOTTLED_DRAGON_HIDE:
- description += "The weirdly-patterned scaley skin of "
- "a mottled dragon. I suppose you could "
- "wear it if you really wanted to. ";
- break;
- case ARM_MOTTLED_DRAGON_ARMOUR:
- description += "A magical armour made from the scales of a "
- "mottled dragon. Although unlike the armour "
- "made from the scales of some larger dragons "
- "it does not provide its wearer with much in "
- "the way of special magical protection, it is "
- "as light and relatively uncumbersome as "
- "leather armour. ";
- break; /* Protects from napalm */
- case ARM_STORM_DRAGON_HIDE:
- description += "The hide of a storm dragon, covered in "
- "extremely hard blue scales. I suppose "
- "you could wear it if you really wanted to. ";
- break;
- case ARM_STORM_DRAGON_ARMOUR:
- description += "A magical armour made from the scales of "
- "a lightning-breathing dragon. It is heavier "
- "than most dragon scale armours, but gives "
- "its wearer great resistance to "
- "electrical discharges. ";
- break;
- case ARM_GOLD_DRAGON_HIDE:
- description += "The extremely tough and heavy skin of a "
- "golden dragon, covered in shimmering golden "
- "scales. I suppose you could wear it if "
- "you really wanted to. ";
- break;
- case ARM_GOLD_DRAGON_ARMOUR:
- description += "A magical armour made from the golden scales "
- "of a golden dragon. It is extremely heavy and "
- "cumbersome, but confers resistances to fire, "
- "cold, and poison on its wearer. ";
- break;
- case ARM_ANIMAL_SKIN:
- description += "The skins of several animals. ";
- break;
- case ARM_SWAMP_DRAGON_HIDE:
- description += "The slimy";
- if (you.species != SP_MUMMY)
- description += ", smelly";
- description += " skin of a swamp-dwelling dragon. I suppose "
- "you could wear it if you really wanted to. ";
- break;
- case ARM_SWAMP_DRAGON_ARMOUR:
- description += "A magical armour made from the scales of "
- "a swamp dragon. It confers resistance to "
- "poison on its wearer. ";
- break;
- default:
- DEBUGSTR("Unknown armour");
- }
-
- description += "$";
- }
- }
-
- if (verbose == 1
- && item.sub_type != ARM_SHIELD
- && item.sub_type != ARM_BUCKLER
- && item.sub_type != ARM_LARGE_SHIELD)
- {
- description += "$Armour rating: ";
-
- if (item.sub_type == ARM_HELMET
- && (get_helmet_type( item ) == THELM_CAP
- || get_helmet_type( item ) == THELM_WIZARD_HAT))
- {
- // caps and wizard hats don't have a base AC
- append_value(description, 0, false);
- }
- else if (item.sub_type == ARM_NAGA_BARDING
- || item.sub_type == ARM_CENTAUR_BARDING)
- {
- // Barding has AC value 4.
- append_value(description, 4, false);
- }
- else
- {
- append_value(description, property( item, PARM_AC ), false);
- }
-
- description += "$Evasion modifier: ";
- append_value(description, property( item, PARM_EVASION ), true);
- description += "$";
- }
-
- int ego = get_armour_ego_type( item );
- if (ego != SPARM_NORMAL
- && item_ident( item, ISFLAG_KNOW_TYPE )
- && verbose == 1)
- {
- description += "$";
-
- switch (ego)
- {
- case SPARM_RUNNING:
- description += "It allows its wearer to run at a great speed. ";
- break;
- case SPARM_FIRE_RESISTANCE:
- description += "It protects its wearer from heat and fire. ";
- break;
- case SPARM_COLD_RESISTANCE:
- description += "It protects its wearer from cold. ";
- break;
- case SPARM_POISON_RESISTANCE:
- description += "It protects its wearer from poison. ";
- break;
- case SPARM_SEE_INVISIBLE:
- description += "It allows its wearer to see invisible things. ";
- break;
- case SPARM_DARKNESS:
- description += "When activated it hides its wearer from "
- "the sight of others, but also increases "
- "their metabolic rate by a large amount. ";
- break;
- case SPARM_STRENGTH:
- description += "It increases the physical power of its wearer (+3 to strength). ";
- break;
- case SPARM_DEXTERITY:
- description += "It increases the dexterity of its wearer (+3 to dexterity). ";
- break;
- case SPARM_INTELLIGENCE:
- description += "It makes you more clever (+3 to intelligence). ";
- break;
- case SPARM_PONDEROUSNESS:
- description += "It is very cumbersome (-2 to EV, slows movement). ";
- break;
- case SPARM_LEVITATION:
- description += "It can be activated to allow its wearer to "
- "float above the ground and remain so indefinitely. ";
- break;
- case SPARM_MAGIC_RESISTANCE:
- description += "It increases its wearer's resistance "
- "to enchantments. ";
- break;
- case SPARM_PROTECTION:
- description += "It protects its wearer from harm (+3 to AC). ";
- break;
- case SPARM_STEALTH:
- description += "It enhances the stealth of its wearer. ";
- break;
- case SPARM_RESISTANCE:
- description += "It protects its wearer from the effects "
- "of both cold and heat. ";
- break;
-
- // these two are robes only:
- case SPARM_POSITIVE_ENERGY:
- description += "It partially protects its wearer from "
- "the effects of negative energy. ";
- break;
- case SPARM_ARCHMAGI:
- description += "It greatly increases the power of its "
- "wearer's magical spells, but is only "
- "intended for those who have " "very little left to learn. ";
- break;
-
- case SPARM_PRESERVATION:
- description += "It protects its wearer's possessions "
- "from damage and destruction. ";
- break;
- }
-
- description += "$";
- }
-
- if (is_random_artefact( item ))
- {
- if (item_ident( item, ISFLAG_KNOW_PROPERTIES ))
- randart_descpr( description, item );
- else if (item_ident( item, ISFLAG_KNOW_TYPE ))
- description += "$This armour may have some hidden properties.$";
- }
- else
- {
- switch (get_equip_race( item ))
- {
- case ISFLAG_ELVEN:
- //jmf: not light
- description += "$It is well-crafted and unobstructive";
-
- if (item.sub_type == ARM_CLOAK || item.sub_type == ARM_BOOTS)
- description += ", and helps its wearer avoid being noticed";
-
- description += ".";
- break;
-
- case ISFLAG_DWARVEN:
- description += "$It is well-crafted and very durable.";
- break;
-
- case ISFLAG_ORCISH:
- default:
- break;
- }
- }
-
- if (item_known_cursed( item ))
- {
- description += "$It has a curse placed upon it.";
- }
-
- return description;
-}
-
-//---------------------------------------------------------------
-//
-// describe_stick
-//
-//---------------------------------------------------------------
-static std::string describe_stick( const item_def &item )
-{
- std::string description;
-
- description.reserve(64);
-
- if (get_ident_type( OBJ_WANDS, item.sub_type ) != ID_KNOWN_TYPE)
- description += "A stick. Maybe it's magical. ";
- else
- {
- description += "A magical device which ";
- switch (item.sub_type)
- {
- case WAND_FLAME:
- description += "throws little bits of flame. ";
- break;
-
- case WAND_FROST:
- description += "throws little bits of frost. ";
- break;
-
- case WAND_SLOWING:
- description += "casts enchantments to slow down the actions of "
- "a creature at which it is directed. ";
- break;
-
- case WAND_HASTING:
- description += "casts enchantments to speed up the actions of "
- "a creature at which it is directed. ";
- break;
-
- case WAND_MAGIC_DARTS:
- description += "throws small bolts of destructive energy. ";
- break;
-
- case WAND_HEALING:
- description += "can heal a creature's wounds. ";
- break;
-
- case WAND_PARALYSIS:
- description += "can render a creature immobile. ";
- break;
-
- case WAND_FIRE:
- description += "throws great bolts of fire. ";
- break;
-
- case WAND_COLD:
- description += "throws great bolts of cold. ";
- break;
-
- case WAND_CONFUSION:
- description += "induces confusion and bewilderment in "
- "a target creature. ";
- break;
-
- case WAND_INVISIBILITY:
- description += "hides a creature from the view of others. ";
- break;
-
- case WAND_DIGGING:
- description += "drills tunnels through unworked rock. ";
- break;
-
- case WAND_FIREBALL:
- description += "throws exploding blasts of flame. ";
- break;
-
- case WAND_TELEPORTATION:
- description += "causes a creature to be randomly translocated. ";
- break;
-
- case WAND_LIGHTNING:
- description += "throws great bolts of lightning. ";
- break;
-
- case WAND_POLYMORPH_OTHER:
- description += "causes a creature to be transmogrified into "
- "another form. "
- "It doesn't work on you, so don't even try. ";
- break;
-
- case WAND_ENSLAVEMENT:
- description += "causes slavish obedience in a creature. ";
- break;
-
- case WAND_DRAINING:
- description += "throws a bolt of negative energy which "
- "drains the life essences of living creatures, "
- "but is useless against the undead. ";
- break;
-
- case WAND_RANDOM_EFFECTS:
- description += "can produce a variety of effects. ";
- break;
-
- case WAND_DISINTEGRATION:
- description += "disrupts the physical structure of "
- "an object, especially a creature's body. ";
- break;
-
- default:
- DEBUGSTR("Unknown stick");
- }
-
- if (item_ident( item, ISFLAG_KNOW_PLUSES ) && item.plus == 0)
- description += "Unfortunately, it has no charges left. ";
- }
-
- return description;
-}
-
-
-//---------------------------------------------------------------
-//
-// describe_food
-//
-//---------------------------------------------------------------
-static std::string describe_food( const item_def &item )
-{
- std::string description;
-
- description.reserve(100);
-
- switch (item.sub_type)
- {
- // rations
- case FOOD_MEAT_RATION:
- case FOOD_BREAD_RATION:
- description += "A filling ration of ";
- switch (item.sub_type)
- {
- case FOOD_MEAT_RATION:
- description += "dried and preserved meats";
- break;
- case FOOD_BREAD_RATION:
- description += "breads";
- break;
- }
- description += ". ";
- break;
-
- // fruits
- case FOOD_PEAR:
- case FOOD_APPLE:
- case FOOD_APRICOT:
- case FOOD_ORANGE:
- case FOOD_BANANA:
- case FOOD_STRAWBERRY:
- case FOOD_RAMBUTAN:
- case FOOD_LEMON:
- case FOOD_GRAPE:
- case FOOD_LYCHEE:
- case FOOD_SULTANA:
- description += "A";
- switch (item.sub_type)
- {
- case FOOD_PEAR:
- description += " delicious juicy";
- break;
- case FOOD_APPLE:
- description += " delicious red or green";
- break;
- case FOOD_APRICOT:
- description += " delicious orange";
- break;
- case FOOD_ORANGE:
- description += " delicious juicy orange";
- break;
- case FOOD_BANANA:
- description += " delicious yellow";
- break;
- case FOOD_STRAWBERRY:
- description += " small but delicious red";
- break;
- case FOOD_RAMBUTAN:
- description += " small but delicious tropical";
- break;
- case FOOD_LEMON:
- description += " yellow";
- break;
- case FOOD_GRAPE:
- description += " small";
- break;
- case FOOD_LYCHEE:
- description += " tropical";
- break;
- case FOOD_SULTANA:
- description += " dried";
- break;
- }
-
- description += " fruit";
-
- switch (item.sub_type)
- {
- case FOOD_BANANA:
- description += ", probably grown and imported by "
- "some amoral multinational as the "
- "result of a corrupt trade deal";
- break;
- case FOOD_RAMBUTAN:
- description += ". How it got into this dungeon "
- "is anyone's guess";
- break;
- case FOOD_SULTANA:
- description += " of some sort, possibly a grape";
- break;
- }
- description += ". ";
- break;
-
- // vegetables
- case FOOD_CHOKO:
- case FOOD_SNOZZCUMBER:
- description += "A";
- switch (item.sub_type)
- {
- case FOOD_CHOKO:
- description += "n almost tasteless green";
- break;
- case FOOD_SNOZZCUMBER:
- description += " repulsive cucumber-shaped";
- break;
- }
- description += " vegetable";
- switch (item.sub_type)
- {
- case FOOD_CHOKO:
- description += ", which grows on a vine";
- break;
- }
- description += ". ";
- break;
-
- // lumps, slices, chunks, and strips
- case FOOD_HONEYCOMB:
- case FOOD_ROYAL_JELLY:
- case FOOD_PIZZA:
- case FOOD_CHEESE:
- case FOOD_BEEF_JERKY:
- case FOOD_SAUSAGE:
- case FOOD_CHUNK:
- description += "A";
- switch (item.sub_type)
- {
- case FOOD_SAUSAGE:
- description += "n elongated";
- break;
- }
- switch (item.sub_type)
- {
- case FOOD_HONEYCOMB:
- case FOOD_ROYAL_JELLY:
- case FOOD_CHEESE:
- case FOOD_SAUSAGE:
- description += " lump";
- break;
- case FOOD_PIZZA:
- description += " slice";
- break;
- case FOOD_BEEF_JERKY:
- description += " strip";
- break;
- case FOOD_CHUNK:
- description += " piece";
- }
- description += " of ";
- switch (item.sub_type)
- {
- case FOOD_SAUSAGE:
- description += "low-grade gristle, entrails and "
- "cereal products encased in an intestine";
- break;
- case FOOD_HONEYCOMB:
- description += "the delicious honeycomb made by giant bees";
- break;
- case FOOD_ROYAL_JELLY:
- description += "the magical substance produced by giant bees "
- "to be fed to their queens";
- break;
- case FOOD_PIZZA:
- description += "pizza";
- break;
- case FOOD_CHEESE:
- description += "cheese";
- break;
- case FOOD_BEEF_JERKY:
- description += "preserved dead cow or bull";
- break;
- case FOOD_CHUNK:
- description += "dungeon meat";
- break;
- }
- description += ". ";
- switch (item.sub_type)
- {
- case FOOD_SAUSAGE:
- description += "Yum! ";
- break;
- case FOOD_PIZZA:
- description += "Don't tell me you don't know what that is! ";
- break;
- case FOOD_CHUNK:
- if (you.species != SP_GHOUL)
- description += "It looks rather unpleasant. ";
-
- if (item.special < 100)
- {
- if (you.species == SP_GHOUL)
- description += "It looks nice and ripe. ";
- else if (you.species != SP_MUMMY)
- {
- description += "In fact, it is "
- "rotting away before your eyes. "
- "Eating it would probably be unwise. ";
- }
- }
- break;
- }
- break;
-
- default:
- DEBUGSTR("Unknown food");
- }
-
- description += "$";
-
- return (description);
-}
-
-//---------------------------------------------------------------
-//
-// describe_potion
-//
-//---------------------------------------------------------------
-static std::string describe_potion( const item_def &item )
-{
- std::string description;
-
- description.reserve(64);
-
- if (get_ident_type( OBJ_POTIONS, item.sub_type ) != ID_KNOWN_TYPE)
- description += "A small bottle of liquid.";
- else
- {
- description += "A";
-
- switch (item.sub_type)
- {
- case POT_HEALING:
- description += " blessed";
- break;
- case POT_HEAL_WOUNDS:
- description += " magical healing";
- break;
- case POT_SPEED:
- description += "n enchanted";
- break;
- case POT_MIGHT:
- description += " magic";
- break;
- case POT_POISON:
- description += " nasty poisonous";
- break;
- case POT_PORRIDGE:
- description += " filling";
- break;
- case POT_DEGENERATION:
- description += " noxious";
- break;
- case POT_DECAY:
- description += " vile and putrid cursed";
- break;
- case POT_WATER:
- description += " unique";
- break;
- case POT_EXPERIENCE:
- description += " truly wonderful and very rare";
- break;
- case POT_MAGIC:
- description += " valuable";
- break;
- case POT_STRONG_POISON:
- description += " terribly venomous";
- break;
- }
-
- description += " ";
-
- switch (item.sub_type)
- {
- case POT_MIGHT:
- case POT_GAIN_STRENGTH:
- case POT_GAIN_DEXTERITY:
- case POT_GAIN_INTELLIGENCE:
- case POT_LEVITATION:
- case POT_SLOWING:
- case POT_PARALYSIS:
- case POT_CONFUSION:
- case POT_INVISIBILITY:
- case POT_PORRIDGE:
- case POT_MAGIC:
- case POT_RESTORE_ABILITIES:
- case POT_STRONG_POISON:
- case POT_BERSERK_RAGE:
- case POT_CURE_MUTATION:
- case POT_MUTATION:
- description += "potion";
- break;
- case POT_HEALING:
- description += "fluid";
- break;
- case POT_HEAL_WOUNDS:
- description += "elixir";
- break;
- case POT_SPEED:
- description += "beverage";
- break;
- case POT_POISON:
- case POT_DECAY:
- description += "liquid";
- break;
- case POT_DEGENERATION:
- description += "concoction";
- break;
- case POT_WATER:
- description += "substance";
- break;
- case POT_EXPERIENCE:
- description += "drink";
- break;
- }
-
- switch (item.sub_type)
- {
- case POT_HEALING:
- case POT_HEAL_WOUNDS:
- case POT_SPEED:
- case POT_MIGHT:
- case POT_LEVITATION:
- case POT_SLOWING:
- case POT_PARALYSIS:
- case POT_CONFUSION:
- case POT_INVISIBILITY:
- case POT_DEGENERATION:
- case POT_DECAY:
- case POT_MAGIC:
- case POT_RESTORE_ABILITIES:
- case POT_BERSERK_RAGE:
- case POT_CURE_MUTATION:
- case POT_MUTATION:
- description += " which ";
- break;
- case POT_GAIN_STRENGTH:
- case POT_GAIN_DEXTERITY:
- case POT_GAIN_INTELLIGENCE:
- case POT_PORRIDGE:
- description += " of ";
- break;
- }
-
- switch (item.sub_type)
- {
- case POT_HEALING:
- description += "heals some wounds, clears the mind, "
- "and cures diseases";
- break;
- case POT_HEAL_WOUNDS:
- description += "causes wounds to close and heal "
- "almost instantly";
- break;
- case POT_SPEED:
- description += "speeds the actions of anyone who drinks it";
- break;
- case POT_MIGHT:
- description += "greatly increases the strength and "
- "physical power of one who drinks it";
- break;
- case POT_GAIN_STRENGTH:
- case POT_GAIN_DEXTERITY:
- case POT_GAIN_INTELLIGENCE:
- description += "beneficial mutation";
- break;
- case POT_LEVITATION:
- description += "confers great buoyancy on one who consumes it";
- break;
- case POT_SLOWING:
- description += "slows your actions";
- break;
- case POT_PARALYSIS:
- description += "eliminates your control over your own body";
- break;
- case POT_CONFUSION:
- description += "confuses your perceptions and reduces "
- "your control over your own actions";
- break;
- case POT_INVISIBILITY:
- description += "hides you from the sight of others";
- break;
- case POT_PORRIDGE:
- description += "sludge, high in cereal fibre";
- break;
- case POT_DEGENERATION:
- description += "can do terrible things to your "
- "body, brain and reflexes";
- break;
- case POT_DECAY:
- description += "causes your flesh to decay "
- "before your very eyes";
- break;
- case POT_WATER:
- description += ", vital for the existence of most life";
- break;
- case POT_MAGIC:
- description += "grants a person with an "
- "infusion of magical energy";
- break;
- case POT_RESTORE_ABILITIES:
- description += "restores the abilities of one who drinks it";
- break;
- case POT_BERSERK_RAGE:
- description += "can send one into an incoherent rage";
- break;
- case POT_CURE_MUTATION:
- description += "removes some or all of any mutations "
- "which may be afflicting you";
- break;
- case POT_MUTATION:
- description += "does very strange things to you";
- break;
- }
-
- description += ". ";
-
- switch (item.sub_type)
- {
- case POT_HEALING:
- case POT_HEAL_WOUNDS:
- description += "If one uses it when they are "
- "at or near full health, it can also ";
-
- if (item.sub_type == POT_HEALING)
- description += "slightly ";
- description += "repair permanent injuries. ";
- break;
- }
-
- //default:
- // DEBUGSTR("Unknown potion"); // I had no idea where to put this back 16jan2000 {dlb}
- }
-
- description += "$";
-
- return (description);
-}
-
-
-//---------------------------------------------------------------
-//
-// describe_scroll
-//
-//---------------------------------------------------------------
-static std::string describe_scroll( const item_def &item )
-{
- std::string description;
-
- description.reserve(64);
-
- if (get_ident_type( OBJ_SCROLLS, item.sub_type ) != ID_KNOWN_TYPE)
- description += "A scroll of paper covered in magical writing.";
- else
- {
- switch (item.sub_type)
- {
- case SCR_IDENTIFY:
- description += "This useful magic scroll allows you to "
- "determine the properties of any object. ";
- break;
-
- case SCR_TELEPORTATION:
- description += "Reading the words on this scroll "
- "translocates you to a random position. ";
- break;
-
- case SCR_FEAR:
- description += "This scroll causes great fear in those "
- "who see the one who reads it. ";
- break;
-
- case SCR_NOISE:
- description += "This prank scroll, often slipped into a wizard's "
- "backpack by a devious apprentice, causes a loud noise. "
- "It is not otherwise noted for its usefulness. ";
- break;
-
- case SCR_REMOVE_CURSE:
- description += "Reading this scroll removes curses from "
- "the items you are using. ";
- break;
-
- case SCR_DETECT_CURSE:
- description += "This scroll allows you to detect the presence "
- "of cursed items among your possessions. ";
- break;
-
- case SCR_SUMMONING:
- description += "This scroll opens a conduit to the Abyss "
- "and draws a terrible beast to this world "
- "for a limited time. ";
- break;
-
- case SCR_ENCHANT_WEAPON_I:
- description += "This scroll places an enchantment on a weapon, "
- "making it more accurate in combat. It may fail "
- "to affect weapons already heavily enchanted. ";
- break;
-
- case SCR_ENCHANT_ARMOUR:
- description += "This scroll places an enchantment "
- "on a piece of armour. ";
- break;
-
- case SCR_TORMENT:
- description += "This scroll calls on the powers of Hell to "
- "inflict great pain on any nearby creature - "
- "including you! ";
- break;
-
- case SCR_RANDOM_USELESSNESS:
- description += "It is easy to be blinded to the essential "
- "uselessness of this scroll by the sense of achievement "
- "you get from getting it to work at all.";
- // -- The Hitchhiker's Guide to the Galaxy (paraphrase)
- break;
-
- case SCR_CURSE_WEAPON:
- description += "This scroll places a curse on a weapon. ";
- break;
-
- case SCR_CURSE_ARMOUR:
- description += "This scroll places a curse "
- "on a piece of armour. ";
- break;
-
- case SCR_IMMOLATION:
- description += "Small writing on the back of the scroll reads: "
- "\"Warning: contents under pressure. Do not use near"
- " flammable objects.\"";
- break;
-
- case SCR_BLINKING:
- description += "This scroll allows its reader to teleport "
- "a short distance, with precise control. Be wary that "
- "controlled teleports will cause the subject to "
- "become contaminated with magical energy. ";
- break;
-
- case SCR_PAPER:
- description += "Apart from a label, this scroll is blank. ";
- break;
-
- case SCR_MAGIC_MAPPING:
- description += "This scroll reveals the nearby surroundings "
- "of one who reads it. ";
- break;
-
- case SCR_FORGETFULNESS:
- description += "This scroll induces "
- "an irritating disorientation. ";
- break;
-
- case SCR_ACQUIREMENT:
- description += "This wonderful scroll causes the "
- "creation of a valuable item to "
- "appear before the reader. "
- "It is especially treasured by specialist "
- "magicians, as they can use it to obtain "
- "the powerful spells of their specialty. ";
- break;
-
- case SCR_ENCHANT_WEAPON_II:
- description += "This scroll places an enchantment on a weapon, "
- "making it inflict greater damage in combat. "
- "It may fail to affect weapons already "
- "heavily enchanted. ";
- break;
-
- case SCR_VORPALISE_WEAPON:
- description += "This scroll enchants a weapon so as to make "
- "it far more effective at inflicting harm on "
- "its wielder's enemies. Using it on a weapon "
- "already affected by some kind of special "
- "enchantment (other than that produced by a "
- "normal scroll of enchant weapon) is not advised. ";
- break;
-
- case SCR_RECHARGING:
- description += "This scroll restores the charges of "
- "any magical wand wielded by its reader. ";
- break;
-
- case SCR_ENCHANT_WEAPON_III:
- description += "This scroll enchants a weapon to be "
- "far more effective in combat. Although "
- "it can be used in the creation of especially "
- "enchanted weapons, it may fail to affect those "
- "already heavily enchanted. ";
- break;
-
- default:
- DEBUGSTR("Unknown scroll");
- }
- }
-
- description += "$";
-
- return (description);
-}
-
-
-//---------------------------------------------------------------
-//
-// describe_jewellery
-//
-//---------------------------------------------------------------
-static std::string describe_jewellery( const item_def &item, char verbose)
-{
- std::string description;
-
- description.reserve(200);
-
- if (is_unrandom_artefact( item ) && strlen(unrandart_descrip(1, item)) != 0)
- {
- description += "$";
- description += unrandart_descrip(1, item);
- description += "$$";
- }
- else if ((!is_random_artefact( item )
- && get_ident_type( OBJ_JEWELLERY, item.sub_type ) != ID_KNOWN_TYPE)
- || (is_random_artefact( item )
- && !item_ident( item, ISFLAG_KNOW_TYPE )))
- {
- description += "A piece of jewellery.";
- }
- else if (verbose == 1 || is_random_artefact( item ))
- {
- switch (item.sub_type)
- {
- case RING_REGENERATION:
- description += "This wonderful ring greatly increases the "
- "recuperative powers of its wearer, but also "
- "considerably speeds his or her metabolism. ";
- break;
-
- case RING_PROTECTION:
- description +=
- "This ring either protects its wearer from harm or makes "
- "them more vulnerable to injury, to a degree dependent "
- "on its power. ";
- break;
-
- case RING_PROTECTION_FROM_FIRE:
- description +=
- "This ring provides protection from heat and fire. ";
- break;
-
- case RING_POISON_RESISTANCE:
- description +=
- "This ring provides protection from the effects of poisons and venom. ";
- break;
-
- case RING_PROTECTION_FROM_COLD:
- description += "This ring provides protection from cold. ";
- break;
-
- case RING_STRENGTH:
- description +=
- "This ring increases or decreases the physical strength "
- "of its wearer, to a degree dependent on its power. ";
- break;
-
- case RING_SLAYING:
- description +=
- "This ring increases the hand-to-hand and missile combat "
- "skills of its wearer.";
- break;
-
- case RING_SEE_INVISIBLE:
- description +=
- "This ring allows its wearer to see those things hidden "
- "from view by magic. ";
- break;
-
- case RING_INVISIBILITY:
- description +=
- "This powerful ring can be activated to hide its wearer "
- "from the view of others, but increases the speed of his "
- "or her metabolism greatly while doing so. ";
- break;
-
- case RING_HUNGER:
- description +=
- "This accursed ring causes its wearer to hunger "
- "considerably more quickly. ";
- break;
-
- case RING_TELEPORTATION:
- description +=
- "This ring occasionally exerts its power to randomly "
- "translocate its wearer to another place, and can be "
- "deliberately activated for the same effect. ";
- break;
-
- case RING_EVASION:
- description +=
- "This ring makes its wearer either more or less capable "
- "of avoiding attacks, depending on its degree "
- "of enchantment. ";
- break;
-
- case RING_SUSTAIN_ABILITIES:
- description +=
- "This ring protects its wearer from the loss of their "
- "strength, dexterity and intelligence. ";
- break;
-
- case RING_SUSTENANCE:
- description +=
- "This ring provides energy to its wearer, so that they "
- "need eat less often. ";
- break;
-
- case RING_DEXTERITY:
- description +=
- "This ring increases or decreases the dexterity of its "
- "wearer, depending on the degree to which it has been "
- "enchanted. ";
- break;
-
- case RING_INTELLIGENCE:
- description +=
- "This ring increases or decreases the mental ability of "
- "its wearer, depending on the degree to which it has "
- "been enchanted. ";
- break;
-
- case RING_WIZARDRY:
- description +=
- "This ring increases the ability of its wearer to use "
- "magical spells. ";
- break;
-
- case RING_MAGICAL_POWER:
- description +=
- "This ring increases its wearer's reserves of magical "
- "power. ";
- break;
-
- case RING_LEVITATION:
- description +=
- "This ring allows its wearer to hover above the floor. ";
- break;
-
- case RING_LIFE_PROTECTION:
- description +=
- "This blessed ring protects the life-force of its wearer "
- "from negative energy, making them partially immune to "
- "the draining effects of undead and necromantic magic. ";
- break;
-
- case RING_PROTECTION_FROM_MAGIC:
- description +=
- "This ring increases its wearer's resistance to "
- "hostile enchantments. ";
- break;
-
- case RING_FIRE:
- description +=
- "This ring brings its wearer more in contact with "
- "the powers of fire. He or she gains resistance to "
- "heat and can use fire magic more effectively, but "
- "becomes more vulnerable to the effects of cold. ";
- break;
-
- case RING_ICE:
- description +=
- "This ring brings its wearer more in contact with "
- "the powers of cold and ice. He or she gains resistance "
- "to cold and can use ice magic more effectively, but "
- "becomes more vulnerable to the effects of fire. ";
- break;
-
- case RING_TELEPORT_CONTROL:
- description += "This ring allows its wearer to control the "
- "destination of any teleportation, although without "
- "perfect accuracy. Trying to teleport into a solid "
- "object will result in a random teleportation, at "
- "least in the case of a normal teleportation. Also "
- "be wary that controlled teleports will contaminate "
- "the subject with residual magical energy.";
- break;
-
- case AMU_RAGE:
- description +=
- "This amulet enables its wearer to attempt to enter "
- "a state of berserk rage, and increases their chance "
- "of successfully doing so. It also partially protects "
- "the user from passing out when coming out of that rage. ";
- break;
-
- case AMU_RESIST_SLOW:
- description +=
- "This amulet protects its wearer from some magically "
- "induced forms of slowness, and increases the duration "
- "of enchantments which speed his or her actions. ";
- break;
-
- case AMU_CLARITY:
- description +=
- "This amulet protects its wearer from some forms of "
- "mental confusion. ";
- break;
-
- case AMU_WARDING:
- description +=
- "This amulet repels some of the attacks of creatures "
- "which have been magically summoned. ";
- break;
-
- case AMU_RESIST_CORROSION:
- description +=
- "This amulet protects the armour and weaponry of its "
- "wearer from corrosion caused by acids, although not "
- "infallibly so. ";
- break;
-
- case AMU_THE_GOURMAND:
- description +=
- "This amulet allows its wearer to consume meat in "
- "various states of decay without suffering unduly as "
- "a result. Poisonous or cursed flesh is still not "
- "recommended. ";
- break;
-
- case AMU_CONSERVATION:
- description +=
- "This amulet protects some of the possessions of "
- "its wearer from outright destruction, but not "
- "infallibly so. ";
- break;
-
- case AMU_CONTROLLED_FLIGHT:
- description +=
- "Should the wearer of this amulet be levitated "
- "by magical means, he or she will be able to exercise "
- "some control over the resulting motion. This allows "
- "the descent of staircases and the retrieval of items "
- "lying on the ground, for example, but does not "
- "deprive the wearer of the benefits of levitation. ";
- break;
-
- case AMU_INACCURACY:
- description +=
- "This amulet makes its wearer less accurate in hand combat. ";
- break;
-
- case AMU_RESIST_MUTATION:
- description +=
- "This amulet protects its wearer from mutations, "
- "although not infallibly so. ";
- break;
-
- default:
- DEBUGSTR("Unknown jewellery");
- }
-
- description += "$";
- }
-
- if ((verbose == 1 || is_random_artefact( item ))
- && item_ident( item, ISFLAG_KNOW_PLUSES ))
- {
- // Explicit description of ring power (useful for randarts)
- // Note that for randarts we'll print out the pluses even
- // in the case that its zero, just to avoid confusion. -- bwr
- if (item.plus != 0
- || (item.sub_type == RING_SLAYING && item.plus2 != 0)
- || is_random_artefact( item ))
- {
- switch (item.sub_type)
- {
- case RING_PROTECTION:
- description += "$It affects your AC (";
- append_value( description, item.plus, true );
- description += ").";
- break;
-
- case RING_EVASION:
- description += "$It affects your evasion (";
- append_value( description, item.plus, true );
- description += ").";
- break;
-
- case RING_STRENGTH:
- description += "$It affects your strength (";
- append_value( description, item.plus, true );
- description += ").";
- break;
-
- case RING_INTELLIGENCE:
- description += "$It affects your intelligence (";
- append_value( description, item.plus, true );
- description += ").";
- break;
-
- case RING_DEXTERITY:
- description += "$It affects your dexterity (";
- append_value( description, item.plus, true );
- description += ").";
- break;
-
- case RING_SLAYING:
- if (item.plus != 0 || is_random_artefact( item ))
- {
- description += "$It affects your accuracy (";
- append_value( description, item.plus, true );
- description += ").";
- }
-
- if (item.plus2 != 0 || is_random_artefact( item ))
- {
- description += "$It affects your damage-dealing abilities (";
- append_value( description, item.plus2, true );
- description += ").";
- }
- break;
-
- default:
- break;
- }
- }
- }
-
- // randart properties
- if (is_random_artefact( item ))
- {
- if (item_ident( item, ISFLAG_KNOW_PROPERTIES ))
- randart_descpr( description, item );
- else if (item_ident( item, ISFLAG_KNOW_TYPE ))
- {
- if (item.sub_type >= AMU_RAGE)
- description += "$This amulet may have hidden properties.$";
- else
- description += "$This ring may have hidden properties.$";
- }
- }
-
- if (item_known_cursed( item ))
- {
- description += "$It has a curse placed upon it.";
- }
-
- return (description);
-} // end describe_jewellery()
-
-//---------------------------------------------------------------
-//
-// describe_staff
-//
-//---------------------------------------------------------------
-static std::string describe_staff( const item_def &item )
-{
- std::string description;
-
- description.reserve(200);
-
- if (item_ident( item, ISFLAG_KNOW_TYPE ))
- {
- // NB: the leading space is here {dlb}
- description += "This " + std::string( item_is_staff( item ) ? "staff "
- : "rod " );
-
- switch (item.sub_type)
- {
- case STAFF_WIZARDRY:
- description +=
- "increases the magical proficiency of its wielder by "
- "a considerable degree, increasing the power of their spells. ";
- break;
-
- case STAFF_POWER:
- description +=
- "provides a reservoir of magical power to its wielder. ";
- break;
-
- case STAFF_FIRE:
- description +=
- "increases the power of fire spells cast by its wielder, "
- "and protects him or her from the effects of heat and fire. "
- "It can burn those struck by it. ";
- break;
-
- case STAFF_COLD:
- description +=
- "increases the power of ice spells cast by its wielder, "
- "and protects him or her from the effects of cold. It can "
- "freeze those struck by it. ";
- break;
-
- case STAFF_POISON:
- description +=
- "increases the power of poisoning spells cast by its "
- "wielder, and protects him or her from the effects of "
- "poison. It can poison those struck by it. ";
- break;
-
- case STAFF_ENERGY:
- description +=
- "allows its wielder to cast magical spells without "
- "hungering as a result. ";
- break;
-
- case STAFF_DEATH:
- description +=
- "increases the power of necromantic spells cast by its "
- "wielder. It can cause great pain in those living souls "
- "its wielder strikes. ";
- break;
-
- case STAFF_CONJURATION:
- description +=
- "increases the power of conjurations cast by its wielder. ";
- break;
-
- case STAFF_ENCHANTMENT:
- description +=
- "increases the power of enchantments cast by its wielder. ";
- break;
-
- case STAFF_SUMMONING:
- description +=
- "increases the power of summonings cast by its wielder. ";
- break;
-
- case STAFF_SMITING:
- description +=
- "allows its wielder to smite foes from afar. The wielder "
- "must be at least level four to safely use this ability, "
- "which drains four charges. ";
- break;
-
- case STAFF_STRIKING:
- description += "allows its wielder to strike foes from afar "
- "with force bolts. ";
- break;
-
- case STAFF_SPELL_SUMMONING:
- description += "contains spells of summoning. ";
- break;
-
- case STAFF_WARDING:
- description +=
- "contains spells designed to repel one's enemies. ";
- break;
-
- case STAFF_DISCOVERY:
- description +=
- "contains spells which reveal various aspects of "
- "an explorer's surroundings to them. ";
- break;
-
- case STAFF_AIR:
- description +=
- "increases the power of air spells cast by its wielder. "
- "It can shock those struck by it. ";
- break;
-
- case STAFF_EARTH:
- description +=
- "increases the power of earth spells cast by its wielder. "
- "It can crush those struck by it. ";
- break;
-
- case STAFF_CHANNELING:
- description +=
- "allows its caster to channel ambient magical energy for "
- "his or her own purposes. ";
- break;
-
- default:
- description +=
- "contains spells of mayhem and destruction. ";
- break;
- }
-
- if (item_is_rod( item ))
- {
- if (item.sub_type != STAFF_STRIKING)
- description +=
- "$$It uses its own mana reservoir for casting spells, and "
- "recharges automatically by channeling mana from its "
- "wielder.";
- }
- else
- {
- description +=
- "$$Damage rating: 7 $Accuracy rating: +6 $Attack delay: 120%%";
-
- description += "$$It falls into the 'staves' category. ";
- }
- }
- else
- {
- description += "A stick imbued with magical properties.$";
- }
-
- return (description);
-}
-
-
-//---------------------------------------------------------------
-//
-// describe_misc_item
-//
-//---------------------------------------------------------------
-static std::string describe_misc_item( const item_def &item )
-{
- std::string description;
-
- description.reserve(100);
-
- if (item_ident( item, ISFLAG_KNOW_TYPE ))
- {
- switch (item.sub_type)
- {
- case MISC_BOTTLED_EFREET:
- description +=
- "A mighty efreet, captured by some wizard and bound into "
- "a bronze flask. Breaking the flask's seal will release it "
- "to wreak havoc - possibly on you. ";
- break;
- case MISC_CRYSTAL_BALL_OF_SEEING:
- description +=
- "A magical device which allows one to see the layout of "
- "their surroundings. It requires a degree of magical "
- "ability to be used reliably, otherwise it can produce "
- "unpredictable and possibly harmful results. ";
- break;
- case MISC_AIR_ELEMENTAL_FAN:
- description += "A magical device for summoning air "
- "elementals. It is rather unreliable, and usually requires "
- "several attempts to function correctly. Using it carries "
- "an element of risk, which is reduced if one is skilled in "
- "the appropriate elemental magic. ";
- break;
- case MISC_LAMP_OF_FIRE:
- description += "A magical device for summoning fire "
- "elementals. It is rather unreliable, and usually "
- "requires several attempts to function correctly. Using "
- "it carries an element of risk, which is reduced if one "
- "is skilled in the appropriate elemental magic.";
- break;
- case MISC_STONE_OF_EARTH_ELEMENTALS:
- description += "A magical device for summoning earth "
- "elementals. It is rather unreliable, and usually "
- "requires several attempts to function correctly. "
- "Using it carries an element of risk, which is reduced "
- "if one is skilled in the appropriate elemental magic.";
- break;
- case MISC_LANTERN_OF_SHADOWS:
- description +=
- "An unholy device which calls on the powers of darkness "
- "to assist its user, with a small cost attached. ";
- break;
- case MISC_HORN_OF_GERYON:
- description +=
- "The horn belonging to Geryon, guardian of the Vestibule "
- "of Hell. Legends say that a mortal who desires access "
- "into one of the Hells must use it in order to gain entry. ";
- break;
- case MISC_BOX_OF_BEASTS:
- description +=
- "A magical box containing many wild beasts. One may "
- "allow them to escape by opening the box's lid. ";
- break;
- case MISC_DECK_OF_WONDERS:
- description +=
- "A deck of highly mysterious and magical cards. One may "
- "draw a random card from it, but should be prepared to "
- "suffer the possible consequences! ";
- break;
- case MISC_DECK_OF_SUMMONINGS:
- description +=
- "A deck of magical cards, depicting a range of weird and "
- "wondrous creatures. ";
- break;
- case MISC_CRYSTAL_BALL_OF_ENERGY:
- description +=
- "A magical device which can be used to restore one's "
- "reserves of magical energy, but the use of which carries "
- "the risk of draining all of those energies completely. "
- "This risk varies inversely with the proportion of their "
- "maximum energy which the user possesses; a user near his "
- "or her full potential will find this item most beneficial. ";
- break;
- case MISC_EMPTY_EBONY_CASKET:
- description += "A magical box after its power is spent. ";
- break;
- case MISC_CRYSTAL_BALL_OF_FIXATION:
- description +=
- "A dangerous item which hypnotises anyone so unwise as "
- "to gaze into it, leaving them helpless for a significant "
- "length of time. ";
- break;
- case MISC_DISC_OF_STORMS:
- description +=
- "This extremely powerful item can unleash a destructive "
- "storm of electricity. It is especially effective in the "
- "hands of one skilled in air elemental magic, but cannot "
- "be used by one who is not a conductor. ";
- break;
- case MISC_RUNE_OF_ZOT:
- description +=
- "A talisman which allows entry into Zot's domain. ";
- break;
- case MISC_DECK_OF_TRICKS:
- description +=
- "A deck of magical cards, full of amusing tricks. ";
- break;
- case MISC_DECK_OF_POWER:
- description += "A deck of powerful magical cards. ";
- break;
- case MISC_PORTABLE_ALTAR_OF_NEMELEX:
- description +=
- "An altar to Nemelex Xobeh, built for easy assembly and "
- "disassembly. Evoke it to place it on a clear patch of floor, "
- "then pick it up again when you've finished. ";
- break;
- default:
- DEBUGSTR("Unknown misc item (2)");
- }
- }
- else
- {
- switch (item.sub_type)
- {
- case MISC_BOTTLED_EFREET:
- description += "A heavy bronze flask, warm to the touch. ";
- break;
- case MISC_CRYSTAL_BALL_OF_ENERGY:
- case MISC_CRYSTAL_BALL_OF_FIXATION:
- case MISC_CRYSTAL_BALL_OF_SEEING:
- description += "A sphere of clear crystal. ";
- break;
- case MISC_AIR_ELEMENTAL_FAN:
- description += "A fan. ";
- break;
- case MISC_LAMP_OF_FIRE:
- description += "A lamp. ";
- break;
- case MISC_STONE_OF_EARTH_ELEMENTALS:
- description += "A lump of rock. ";
- break;
- case MISC_LANTERN_OF_SHADOWS:
- description += "A strange lantern made out of ancient bones. ";
- break;
- case MISC_HORN_OF_GERYON:
- description += "A great silver horn, radiating unholy energies. ";
- break;
- case MISC_BOX_OF_BEASTS:
- case MISC_EMPTY_EBONY_CASKET:
- description += "A small black box. I wonder what's inside? ";
- break;
- case MISC_DECK_OF_WONDERS:
- case MISC_DECK_OF_TRICKS:
- case MISC_DECK_OF_POWER:
- case MISC_DECK_OF_SUMMONINGS:
- description += "A deck of cards. ";
- break;
- case MISC_RUNE_OF_ZOT:
- description += "A talisman of some sort. ";
- break;
- case MISC_DISC_OF_STORMS:
- description += "A grey disc. ";
- break;
- case MISC_PORTABLE_ALTAR_OF_NEMELEX:
- description +=
- "An altar to Nemelex Xobeh, built for easy assembly and "
- "disassembly. Evoke it to place on a clear patch of floor, "
- "then pick it up again when you've finished. ";
- break;
- default:
- DEBUGSTR("Unknown misc item");
- }
- }
-
- description += "$";
-
- return (description);
-}
-
-#if MAC
-#pragma mark -
-#endif
-
-// ========================================================================
-// Public Functions
-// ========================================================================
-
-bool is_dumpable_artifact( const item_def &item, char verbose)
-{
- bool ret = false;
-
- if (is_random_artefact( item ) || is_fixed_artefact( item ))
- {
- ret = item_ident( item, ISFLAG_KNOW_PROPERTIES );
- }
- else if (item.base_type == OBJ_ARMOUR
- && (verbose == 1 && item_ident( item, ISFLAG_KNOW_TYPE )))
- {
- const int spec_ench = get_armour_ego_type( item );
- ret = (spec_ench >= SPARM_RUNNING && spec_ench <= SPARM_PRESERVATION);
- }
- else if (item.base_type == OBJ_JEWELLERY
- && (verbose == 1
- && get_ident_type(OBJ_JEWELLERY, item.sub_type) == ID_KNOWN_TYPE))
- {
- ret = true;
- }
-
- return (ret);
-} // end is_dumpable_artifact()
-
-
-//---------------------------------------------------------------
-//
-// get_item_description
-//
-// Note that the string will include dollar signs which should
-// be interpreted as carriage returns.
-//
-//---------------------------------------------------------------
-std::string get_item_description( const item_def &item, char verbose, bool dump )
-{
- std::string description;
- description.reserve(500);
-
- if (!dump)
- {
- char str_pass[ ITEMNAME_SIZE ];
- item_name( item, DESC_INVENTORY_EQUIP, str_pass );
- description += std::string(str_pass);
- }
-
- description += "$$";
-
-#if DEBUG_DIAGNOSTICS
- if (!dump)
- {
- snprintf( info, INFO_SIZE,
- "base: %d; sub: %d; plus: %d; plus2: %d; special: %ld$"
- "quant: %d; colour: %d; flags: 0x%08lx$"
- "x: %d; y: %d; link: %d$ident_type: %d$$",
- item.base_type, item.sub_type, item.plus, item.plus2,
- item.special, item.quantity, item.colour, item.flags,
- item.x, item.y, item.link,
- get_ident_type( item.base_type, item.sub_type ) );
-
- description += info;
- }
-#endif
-
- switch (item.base_type)
- {
- case OBJ_WEAPONS:
- description += describe_weapon( item, verbose );
- break;
- case OBJ_MISSILES:
- description += describe_ammo( item );
- break;
- case OBJ_ARMOUR:
- description += describe_armour( item, verbose );
- break;
- case OBJ_WANDS:
- description += describe_stick( item );
- break;
- case OBJ_FOOD:
- description += describe_food( item );
- break;
- case OBJ_SCROLLS:
- description += describe_scroll( item );
- break;
- case OBJ_JEWELLERY:
- description += describe_jewellery( item, verbose );
- break;
- case OBJ_POTIONS:
- description += describe_potion( item );
- break;
- case OBJ_STAVES:
- description += describe_staff( item );
- break;
-
- case OBJ_BOOKS:
- switch (item.sub_type)
- {
- case BOOK_DESTRUCTION:
- description += "An extremely powerful but unpredictable book "
- "of magic. ";
- break;
-
- case BOOK_MANUAL:
- description += "A valuable book of magic which allows one to "
- "practise a certain skill greatly. As it is used, it gradually "
- "disintegrates and will eventually fall apart. ";
- break;
-
- default:
- description += "A book of magic spells. Beware, for some of the "
- "more powerful grimoires are not to be toyed with. ";
- break;
- }
- break;
-
- case OBJ_ORBS:
- description += "Once you have escaped to the surface with "
- "this invaluable artefact, your quest is complete. ";
- break;
-
- case OBJ_MISCELLANY:
- description += describe_misc_item( item );
- break;
-
- case OBJ_CORPSES:
- description +=
- ((item.sub_type == CORPSE_BODY) ? "A corpse. "
- : "A decaying skeleton. ");
- break;
-
- default:
- DEBUGSTR("Bad item class");
- description += "This item should not exist. Mayday! Mayday! ";
- }
-
- if (verbose == 1)
- {
- description += "$It weighs around ";
-
- const int mass = item_mass( item );
-
- char item_mass[16];
- itoa( mass / 10, item_mass, 10 );
-
- for (int i = 0; i < 14; i++)
- {
- if (item_mass[i] == '\0')
- {
- item_mass[i] = '.';
- item_mass[i+1] = (mass % 10) + '0';
- item_mass[i+2] = '\0';
- break;
- }
- }
-
- description += item_mass;
- description += " aum. "; // arbitrary unit of mass
- }
-
- return (description);
-} // end get_item_description()
-
-
-//---------------------------------------------------------------
-//
-// describe_item
-//
-// Describes all items in the game.
-//
-//---------------------------------------------------------------
-void describe_item( const item_def &item )
-{
-#ifdef DOS_TERM
- char buffer[3400];
-
- gettext(25, 1, 80, 25, buffer);
-
- window(25, 1, 80, 25);
-#endif
-
- clrscr();
-
- std::string description = get_item_description( item, 1 );
- print_description(description);
-
- if ( (item.base_type == OBJ_BOOKS && item_type_known(item)
- && item.sub_type != BOOK_DESTRUCTION
- && item.sub_type != BOOK_MANUAL)
- ||
- count_staff_spells(item, true) > 1 )
- {
- formatted_string fs;
- item_def dup = item;
- spellbook_contents( dup,
- item.base_type == OBJ_BOOKS?
- RBOOK_READ_SPELL
- : RBOOK_USE_STAFF,
- &fs );
- fs.display(2, -2);
- }
-
- if (getch() == 0)
- getch();
-
-#ifdef DOS_TERM
- puttext(25, 1, 80, 25, buffer);
- window(1, 1, 80, 25);
-#endif
-} // end describe_item()
-
-
-//---------------------------------------------------------------
-//
-// describe_spell
-//
-// Describes (most) every spell in the game.
-//
-//---------------------------------------------------------------
-void describe_spell(int spelled)
-{
- std::string description;
-
- description.reserve(500);
-
-#ifdef DOS_TERM
- char buffer[3400];
-
- gettext(25, 1, 80, 25, buffer);
- window(25, 1, 80, 25);
-#endif
-
- clrscr();
- description += spell_title( spelled );
- description += "$$This spell "; // NB: the leading space is here {dlb}
-
- switch (spelled)
- {
- case SPELL_IDENTIFY:
- description += "allows the caster to determine the properties of "
- "an otherwise inscrutable magic item. ";
- break;
-
- case SPELL_TELEPORT_SELF:
- description += "teleports the caster to a random location. ";
- break;
-
- case SPELL_CAUSE_FEAR:
- description += "causes fear in those near to the caster. ";
- break;
-
- case SPELL_CREATE_NOISE:
- description += "causes a loud noise to be heard. ";
- break;
-
- case SPELL_REMOVE_CURSE:
- description += "removes curses from any items which are "
- "being used by the caster. ";
- break;
-
- case SPELL_MAGIC_DART:
- description += "hurls a small bolt of magical energy. ";
- break;
-
- case SPELL_FIREBALL:
- description += "hurls an exploding bolt of fire. This spell "
- "does not cost additional spell levels if the learner already "
- "knows Delayed Fireball. ";
- break;
-
- case SPELL_DELAYED_FIREBALL:
- description = "$$Successfully casting this spell gives the caster "
- "the ability to instantaneously release a fireball at a later "
- "time. Knowing this spell allows the learner to memorise "
- "Fireball for no additional spell levels. ";
- break;
-
- case SPELL_BOLT_OF_MAGMA:
- description += "hurls a sizzling bolt of molten rock. ";
- break;
-
-// spells 7 through 12 ??? {dlb}
-
- case SPELL_CONJURE_FLAME:
- description += "creates a column of roaring flame. ";
- break;
-
- case SPELL_DIG:
- description += "digs a tunnel through unworked rock. ";
- break;
-
- case SPELL_BOLT_OF_FIRE:
- description += "hurls a great bolt of flames. ";
- break;
-
- case SPELL_BOLT_OF_COLD:
- description += "hurls a great bolt of ice and frost. ";
- break;
-
- case SPELL_LIGHTNING_BOLT:
- description += "hurls a mighty bolt of lightning. "
- "Although this spell inflicts less damage than "
- "similar fire and ice spells, it can at once "
- "rip through whole rows of creatures. ";
- break;
-
-// spells 18 and 19 ??? {dlb}
-
- case SPELL_POLYMORPH_OTHER:
- description += "randomly alters the form of another creature. ";
- break;
-
- case SPELL_SLOW:
- description += "slows the actions of a creature. ";
- break;
-
- case SPELL_HASTE:
- description += "speeds the actions of a creature. ";
- break;
-
- case SPELL_PARALYZE:
- description += "prevents a creature from moving. ";
- break;
-
- case SPELL_CONFUSING_TOUCH:
- description += "enchants the casters hands with magical energy. "
- "This energy is released when the caster touches "
- "a monster with their bare hands, and may induce "
- "a state of confusing in the monster. ";
- break;
-
- case SPELL_CONFUSE:
- description += "induces a state of bewilderment and confusion "
- "in a creature's mind. ";
- break;
-
- case SPELL_SURE_BLADE:
- description += "forms a mystical bond between the caster and "
- "a wielded short blade, making the blade much " "easier to use. ";
- break;
-
- case SPELL_INVISIBILITY:
- description += "hides a creature from the sight of others. ";
- break;
-
- case SPELL_THROW_FLAME:
- description += "throws a small bolt of flame. ";
- break;
-
- case SPELL_THROW_FROST:
- description += "throws a small bolt of frost. ";
- break;
-
- case SPELL_CONTROLLED_BLINK:
- description +=
- "allows short-range translocation, with precise control. "
- "Be wary that controlled teleports will cause the subject to "
- "become contaminated with magical energy. ";
- break;
-
- case SPELL_FREEZING_CLOUD:
- description += "conjures up a large cloud of lethally cold vapour. ";
- break;
-
- case SPELL_MEPHITIC_CLOUD:
- description +=
- "conjures up a large but short-lived cloud of vile fumes. ";
- break;
-
- case SPELL_RING_OF_FLAMES:
- description += "surrounds the caster with a mobile ring of searing "
- "flame, and keeps other fire clouds away from the caster. "
- "This spell attunes the caster to the forces of fire, "
- "increasing their fire magic and giving protection from fire. "
- "However, it also makes them much more susceptible to the forces "
- "of ice. "; // well, if it survives the fire wall it's a risk -- bwr
- break;
-
- case SPELL_RESTORE_STRENGTH:
- description += "restores the physical strength of the caster. ";
- break;
-
- case SPELL_RESTORE_INTELLIGENCE:
- description += "restores the intelligence of the caster. ";
- break;
-
- case SPELL_RESTORE_DEXTERITY:
- description += "restores the dexterity of the caster. ";
- break;
-
- case SPELL_VENOM_BOLT:
- description += "throws a bolt of poison. ";
- break;
-
- case SPELL_POISON_ARROW:
- description +=
- "hurls a magical arrow of the most vile and noxious toxin. "
- "No living thing is completely immune to it's effects. ";
- break;
-
- case SPELL_OLGREBS_TOXIC_RADIANCE:
- description +=
- "bathes the caster's surroundings in poisonous green light. ";
- break;
-
- case SPELL_TELEPORT_OTHER:
- description += "randomly translocates another creature. ";
- break;
-
- case SPELL_LESSER_HEALING:
- description +=
- "heals a small amount of damage to the caster's body. ";
- break;
-
- case SPELL_GREATER_HEALING:
- description +=
- "heals a large amount of damage to the caster's body. ";
- break;
-
- case SPELL_CURE_POISON_I:
- description += "removes poison from the caster's system. ";
- break;
-
- case SPELL_PURIFICATION:
- description += "purifies the caster's body, removing "
- "poison, disease, and certain malign enchantments. ";
- break;
-
- case SPELL_DEATHS_DOOR:
- description += "is extremely powerful, but carries a degree of risk. "
- "It renders living casters nigh invulnerable to harm "
- "for a brief period, but can bring them dangerously "
- "close to death (how close depends on one's necromantic "
- "abilities). The spell can be cancelled at any time by "
- "any healing effect, and the caster will receive one "
- "warning shortly before the spell expires. "
- "Undead cannot use this spell. ";
- break;
-
- case SPELL_SELECTIVE_AMNESIA:
- description += "allows the caster to selectively erase one spell "
- "from memory to recapture the magical energy bound "
- "up with it. Casters will be able to memorise this "
- "spell should even their minds be otherwise full of "
- "magic (i.e., already possessing the maximum number "
- "of spells). ";
- break;
-
- case SPELL_MASS_CONFUSION:
- description += "causes confusion in all who gaze upon the caster. ";
- break;
-
- case SPELL_STRIKING:
- description += "hurls a small bolt of force. ";
- break;
-
- case SPELL_SMITING:
- description += "smites one creature of the caster's choice. ";
- break;
-
- case SPELL_REPEL_UNDEAD:
- description += "calls on a divine power to repel the unholy. ";
- break;
-
- case SPELL_HOLY_WORD:
- description += "involves the intonation of a word of power "
- "which repels and can destroy unholy creatures. ";
- break;
-
- case SPELL_DETECT_CURSE:
- description += "alerts the caster to the presence of curses "
- "on his or her possessions. ";
- break;
-
- case SPELL_SUMMON_SMALL_MAMMAL:
- description += "summons one or more "
- "small creatures to the caster's aid. ";
- break;
-
- case SPELL_ABJURATION_I:
- description += "attempts to send hostile summoned creatures to "
- "the place from whence they came, or at least "
- "shorten their stay in the caster's locality. ";
- break;
-
- case SPELL_SUMMON_SCORPIONS:
- description += "summons one or more "
- "giant scorpions to the caster's assistance. ";
- break;
-
- case SPELL_LEVITATION:
- description += "allows the caster to float in the air. ";
- break;
-
- case SPELL_BOLT_OF_DRAINING:
- description += "hurls a deadly bolt of negative energy, "
- "which drains the life from any living creature " "it strikes. ";
- break;
-
- case SPELL_LEHUDIBS_CRYSTAL_SPEAR:
- description += "hurls a lethally sharp bolt of crystal. ";
- break;
-
- case SPELL_BOLT_OF_INACCURACY:
- description += "inflicts enormous damage upon any creature struck "
- "by the bolt of incandescent energy conjured into "
- "existence. Unfortunately, it is very difficult to "
- "aim and very rarely hits anything. Pity, that. ";
- break;
-
- case SPELL_POISONOUS_CLOUD:
- description += "conjures forth a great cloud of lethal gasses. ";
- break;
-
- case SPELL_FIRE_STORM:
- description += "creates a mighty storm of roaring flame. ";
- break;
-
- case SPELL_DETECT_TRAPS:
- description += "reveals traps in the caster's vicinity. ";
- break;
-
- case SPELL_BLINK:
- description += "randomly translocates the caster a short distance. ";
- break;
-
- case SPELL_ISKENDERUNS_MYSTIC_BLAST:
- description += "throws a crackling sphere of destructive energy. ";
- break;
-
- case SPELL_SWARM:
- description += "summons forth a pestilential swarm. ";
- break;
-
- case SPELL_SUMMON_HORRIBLE_THINGS:
- description += "opens a gate to the Abyss and calls through "
- "one or more hideous abominations from that dreadful place."
- " The powers who answer this invocation require of casters "
- "a portion of their intellect in exchange for this service.";
- break;
-
- case SPELL_ENSLAVEMENT:
- description += "causes an otherwise hostile creature "
- "to fight on your side for a while. ";
- break;
-
- case SPELL_MAGIC_MAPPING:
- description += "reveals details about the caster's surroundings. ";
- break;
-
- case SPELL_HEAL_OTHER:
- description += "heals another creature from a distance. ";
- break;
-
- case SPELL_ANIMATE_DEAD:
- description += "causes the dead to rise up and serve the caster; "
- "every corpse within a certain distance of the caster "
- "is affected. By means of this spell, powerful casters "
- "could press into service an army of the mindless undead. ";
- break;
-
- case SPELL_PAIN:
- description += "inflicts an extremely painful injury "
- "upon one living creature. ";
- break;
-
- case SPELL_EXTENSION:
- description +=
- "extends the duration of most beneficial enchantments "
- "affecting the caster. ";
- break;
-
- case SPELL_CONTROL_UNDEAD:
- description +=
- "attempts to enslave any undead in the vicinity of the caster. ";
- break;
-
- case SPELL_ANIMATE_SKELETON:
- description += "raises an inert skeleton to a state of unlife. ";
- break;
-
- case SPELL_VAMPIRIC_DRAINING:
- description += "steals the life of a living creature and grants it "
- "to the caster. Life will not be drained in excess of "
- "what the caster can capably absorb. ";
- break;
-
- case SPELL_SUMMON_WRAITHS:
- description +=
- "calls on the powers of the undead to aid the caster. ";
- break;
-
- case SPELL_DETECT_ITEMS:
- description +=
- "detects any items lying about the caster's general vicinity. ";
- break;
-
- case SPELL_BORGNJORS_REVIVIFICATION:
- description += "instantly heals any and all wounds suffered by the "
- "caster with an attendant, but also permanently lessens his or her "
- "resilience to injury -- the severity of which is dependent on "
- "(and inverse to) magical skill. ";
- break;
-
- case SPELL_BURN:
- description += "burns a creature. ";
- break;
-
- case SPELL_FREEZE:
- description += "freezes a creature. This may temporarily slow the "
- "metabolism of a cold-blooded creature. ";
- break;
-
- case SPELL_SUMMON_ELEMENTAL:
- description += "calls forth "
- "a spirit from the elemental planes to aid the caster. "
- "A large quantity of the desired element must be "
- "available; this is rarely a problem for earth and air, "
- "but may be for fire or water. The elemental will usually "
- "be friendly to casters -- especially those skilled in "
- "the appropriate form of elemental magic.";
- break;
-
- case SPELL_OZOCUBUS_REFRIGERATION:
- description += "drains the heat from the caster and her "
- "surroundings, causing harm to all creatures not resistant to "
- "cold. ";
- break;
-
- case SPELL_STICKY_FLAME:
- description += "conjures a sticky glob of liquid fire, which will "
- "adhere to and burn any creature it strikes. ";
- break;
-
- case SPELL_SUMMON_ICE_BEAST:
- description += "calls forth " "a beast of ice to serve the caster. ";
- break;
-
- case SPELL_OZOCUBUS_ARMOUR:
- description += "encases the caster's body in a protective layer "
- "of ice, the power of which depends on his or her "
- "skill with Ice magic. The caster and the caster's "
- "equipment are protected from the cold, but the "
- "spell will not function for casters already wearing "
- "heavy armour. The effects of this spell are boosted "
- "if the caster is in Ice Form. ";
- break;
-
- case SPELL_CALL_IMP:
- description += "calls forth " "a minor demon from the pits of Hell. ";
- break;
-
- case SPELL_REPEL_MISSILES:
- description += "reduces the chance of projectile attacks striking "
- "the caster. Even powerful attacks such as "
- "lightning bolts or dragon breath are affected, "
- "although smaller missiles are repelled to a "
- "much greater extent. ";
- break;
-
- case SPELL_BERSERKER_RAGE:
- description += "sends the caster into a temporary psychotic rage. ";
- break;
-
- case SPELL_DISPEL_UNDEAD:
- description +=
- "inflicts a great deal of damage on an undead creature. ";
- break;
-
- // spell 86 - Guardian
- // spell 87 - Pestilence
- // spell 99 - Thunderbolt
- // spell 100 - Flame of Cleansing
- // spell 101 - Shining Light
- // spell 102 - Summon Daeva
- // spell 103 - Abjuration II
-
- case SPELL_TWISTED_RESURRECTION:
- description += "allows its caster to imbue a mass of deceased flesh "
- "with a magical life force. Casting this spell involves "
- "the assembling several corpses together; the greater "
- "the combined mass of flesh available, the greater the "
- "chances of success. ";
- break;
-
- case SPELL_REGENERATION:
- description += "dramatically but temporarily increases the caster's "
- "recuperative abilities, while also increasing the rate "
- "of food consumption. ";
- break;
-
- case SPELL_BONE_SHARDS:
- description += "uses the bones of a skeleton (or similar materials: "
- "the rigid exoskeleton of an insect, for example) to "
- "dispense a lethal spray of slicing fragments, allowing "
- "its caster to dispense with conjurations in favour of "
- "necromancy alone to provide a low-level yet very "
- "powerful offensive spell. The use of a large and "
- "heavy skeleton (by wielding it) amplifies this spell's "
- "effect. ";
- break;
-
- case SPELL_BANISHMENT:
- description += "banishes one creature to the Abyss. Those wishing "
- "to visit that unpleasant place in person may always "
- "banish themselves. ";
- break;
-
- case SPELL_CIGOTUVIS_DEGENERATION:
- description +=
- "mutates one creature into a pulsating mass of flesh. ";
- break;
-
- case SPELL_STING:
- description += "throws a magical dart of poison. ";
- break;
-
- case SPELL_SUBLIMATION_OF_BLOOD:
- description += "converts flesh, blood, and other bodily fluids "
- "into magical energy. Casters may focus this spell "
- "on their own bodies (which can be dangerous but "
- "never directly lethal) or can wield freshly butchered "
- "flesh in order to draw power into themselves. ";
- break;
-
- case SPELL_TUKIMAS_DANCE:
- description += "causes a weapon held in the caster's hand to dance "
- "into the air and strike the caster's enemies. It will "
- "not function on magical staves and certain "
- "willful artefacts. ";
- break;
-
- case SPELL_HELLFIRE: // basically, a debug message {dlb}
- description += "should only be available from Dispater's staff. "
- "So how are you reading this? (describe.cc)";
- break;
-
- case SPELL_SUMMON_DEMON:
- description += "opens a gate to the realm of Pandemonium "
- "and draws forth one of its inhabitants "
- "to serve the caster for a time. ";
- break;
-
- case SPELL_DEMONIC_HORDE:
- description += "calls forth "
- "a small swarm of small demons "
- "to do battle with the caster's foes. ";
- break;
-
- case SPELL_SUMMON_GREATER_DEMON:
- description += "calls forth one of the greater demons of Pandemonium "
- "to serve the caster. Beware, for the spell binding it "
- "to service may not outlast "
- "that which binds it to this world! ";
- break;
-
- case SPELL_CORPSE_ROT:
- description += "rapidly accelerates the decomposition of any "
- "corpses lying around the caster, emitting in"
- "process a foul miasmic vapour, which eats away "
- "at the life force of any creature it envelops. ";
- break;
-
- case SPELL_TUKIMAS_VORPAL_BLADE:
- description += "bestows a lethal but temporary sharpness "
- "on a sword held by the caster. It will not affect "
- "weapons otherwise subject to special enchantments. ";
- break;
-
- case SPELL_FIRE_BRAND:
- description += "sets a weapon held by the caster ablaze. It will not "
- "affect weapons otherwise subject to special enchantments. ";
- break;
-
- case SPELL_FREEZING_AURA:
- description +=
- "surrounds a weapon held by the caster with an aura of "
- "freezing cold. It will not affect weapons which are "
- "otherwise subject to special enchantments. ";
- break;
-
- case SPELL_LETHAL_INFUSION:
- description += "infuses a weapon held by the caster with unholy "
- "energies. It will not affect weapons which are "
- "otherwise subject to special enchantments. ";
- break;
-
- case SPELL_CRUSH: // a theory of gravity in Crawl? {dlb}
- description += "crushes a nearby creature with waves of "
- "gravitational force. ";
- break;
-
- case SPELL_BOLT_OF_IRON:
- description += "hurls "
- "a large and heavy metal bolt " "at the caster's foes. ";
- break;
-
- case SPELL_STONE_ARROW:
- description += "hurls "
- "a sharp spine of rock outward from the caster. ";
- break;
-
- case SPELL_TOMB_OF_DOROKLOHE:
- description += "entombs the caster within four walls of rock. These "
- "walls will destroy most objects in their way, but "
- "their growth is obstructed by the presence of any "
- "creature. Beware - only the unwise cast this spell "
- "without reliable means of escape. ";
- break;
-
- case SPELL_STONEMAIL:
- description += "covers the caster with chunky scales of stone, "
- "the durability of which depends on his or her "
- "skill with Earth magic. These scales can coexist "
- "with other forms of armour, but are in and of "
- "themselves extremely heavy and cumbersome. The effects "
- "of this spell are increased if the caster is in Statue Form. ";
- break;
-
- case SPELL_SHOCK:
- description += "throws a bolt of electricity. ";
- break;
-
- case SPELL_SWIFTNESS:
- description += "imbues its caster with the ability to achieve "
- "great movement speeds. Flying spellcasters can move even "
- "faster.";
- break;
-
- case SPELL_FLY:
- description +=
- "grants to the caster the ability to fly through the air. ";
- break;
-
- case SPELL_INSULATION:
- description += "protects the caster from electric shocks. ";
- break;
-
- case SPELL_ORB_OF_ELECTROCUTION:
- description += "hurls "
- "a crackling orb of electrical energy "
- "which explodes with immense force on impact. ";
- break;
-
- case SPELL_DETECT_CREATURES:
- description += "allows the caster to detect any creatures "
- "within a certain radius. ";
- break;
-
- case SPELL_CURE_POISON_II:
- description +=
- "removes some or all toxins from the caster's system. ";
- break;
-
- case SPELL_CONTROL_TELEPORT:
- description += "allows the caster to control translocations. Be "
- "wary that controlled teleports will cause the subject to "
- "become contaminated with magical energy. ";
- break;
-
- case SPELL_POISON_AMMUNITION:
- description += "envenoms missile ammunition held by the caster. ";
- break;
-
- case SPELL_POISON_WEAPON:
- description +=
- "temporarily coats any sharp bladed weapon with poison. Will only "
- "work on weapons without an existing enchantment.";
- break;
-
- case SPELL_RESIST_POISON:
- description += "protects the caster from exposure to all poisons "
- "for a period of time. ";
- break;
-
- case SPELL_PROJECTED_NOISE:
- description += "produces a noise emanating "
- "from a place of the caster's own choosing. ";
- break;
-
- case SPELL_ALTER_SELF:
- description += "causes aberrations to form in the caster's body, "
- "leaving the caster in a weakened state "
- "(though it is not fatal in and of itself). "
- "It may fail to affect those who are already "
- "heavily mutated. ";
- break;
-
-// spell 145 - debugging ray
-
- case SPELL_RECALL:
- description += "is greatly prized by summoners and necromancers, "
- "as it allows the caster to recall any friendly "
- "creatures nearby to a position adjacent to the caster. ";
- break;
-
- case SPELL_PORTAL:
- description += "creates a gate allowing long-distance travel "
- "in relatively ordinary environments "
- "(i.e., the Dungeon only). The portal lasts "
- "long enough for the caster and nearby creatures "
- "to enter. Casters are never taken past the level "
- "limits of the current area. ";
- break;
-
- case SPELL_AGONY:
- description += "cuts the resilience of a target creature in half, "
- "although it will never cause death directly. ";
- break;
-
- case SPELL_SPIDER_FORM:
- description += "temporarily transforms the caster into a venomous, "
- "spider-like creature. Spellcasting is slightly more difficult "
- "in this form. This spell is not powerful enough to allow "
- "the caster to slip out of cursed equipment. ";
- break;
-
- case SPELL_DISRUPT:
- description += "disrupts space around another creature, "
- "causing injury.";
- break;
-
- case SPELL_DISINTEGRATE:
- description += "violently rends apart anything in a small volume of "
- "space. Can be used to cause severe damage.";
- break;
-
- case SPELL_BLADE_HANDS:
- description += "causes long, scythe-shaped blades to grow "
- "from the caster's hands. It makes spellcasting somewhat "
- "difficult. This spell is not powerful enough to force "
- "a cursed weapon from the caster's hands.";
- break;
-
- case SPELL_STATUE_FORM:
- description += "temporarily transforms the caster into a "
- "slow-moving (but extremely robust) stone statue. ";
- break;
-
- case SPELL_ICE_FORM:
- description += "temporarily transforms the caster's body into a "
- "frozen ice-creature. ";
- break;
-
- case SPELL_DRAGON_FORM:
- description += "temporarily transforms the caster into a "
- "great, fire-breathing dragon. ";
- break;
-
- case SPELL_NECROMUTATION:
- description += "first transforms the caster into a "
- "semi-corporeal apparition receptive to negative energy, "
- "then infuses that form with the powers of Death. "
- "The caster becomes resistant to "
- "cold, poison, magic and hostile negative energies. ";
- break;
-
- case SPELL_DEATH_CHANNEL:
- description += "raises living creatures slain by the caster "
- "into a state of unliving slavery as spectral horrors. ";
- break;
-
- case SPELL_SYMBOL_OF_TORMENT:
- description += "calls on the powers of Hell to cause agonising "
- "injury to any living thing in the caster's vicinity. "
- "It carries within itself a degree of danger, "
- "for any brave enough to invoke it, for the Symbol "
- "also affects its caller and indeed will not function "
- "if he or she is immune to its terrible effects. "
- "Despite its ominous power, this spell is never lethal. ";
- break;
-
- case SPELL_DEFLECT_MISSILES:
- description += "protects the caster from "
- "any kind of projectile attack, "
- "although particularly powerful attacks "
- "(lightning bolts, etc.) are deflected "
- "to a lesser extent than lighter missiles. ";
- break;
-
- case SPELL_ORB_OF_FRAGMENTATION:
- description += "throws a heavy sphere of metal "
- "which explodes on impact into a rain of "
- "deadly, jagged fragments. "
- "It can rip a creature to shreds, "
- "but proves ineffective against heavily-armoured targets. ";
- break;
-
- case SPELL_ICE_BOLT:
- description += "throws forth a chunk of ice. "
- "It is particularly effective against "
- "those creatures not immune to the effects of freezing, "
- "but the half of its destructive potential that comes from "
- "its weight and cutting edges "
- "cannot be ignored by even cold-resistant creatures. ";
- break;
-
- case SPELL_ICE_STORM:
- description += "conjures forth "
- "a raging blizzard of ice, sleet and freezing gasses. ";
- break;
-
- case SPELL_ARC:
- description += "zaps at random a nearby creature with a powerful "
- "electrical current.";
- break;
-
- case SPELL_AIRSTRIKE: // jet planes in Crawl ??? {dlb}
- description +=
- "causes the air around a creature to twist itself into "
- "a whirling vortex of meteorological fury. ";
- break;
-
- case SPELL_SHADOW_CREATURES:
- description += "weaves a creature from shadows and threads of "
- "Abyssal matter. The creature thus brought into "
- "existence will recreate some type of creature "
- "found in the caster's immediate vicinity. "
- "The spell even creates appropriate equipment for "
- "the creature, which are given a lasting substance "
- //jmf: if also conjuration:
- //"by the spell's conjuration component. ";
- //jmf: else:
- "by their firm contact with reality. ";
- break;
-
- //jmf: new spells
- case SPELL_FLAME_TONGUE:
- description += "creates a short burst of flame.";
- break;
-
- case SPELL_PASSWALL:
- description += "tunes the caster's body such that it can instantly "
- "pass through solid rock. This can be dangerous, "
- "since it is possible for the spell to expire while "
- "the caster is en route, and it also takes time for the "
- "caster to attune to the rock, during which time they will "
- "be helpless. ";
- break;
-
- case SPELL_IGNITE_POISON:
- description += "attempts to convert all poison within the caster's "
- "view into liquid flame. It is very effective against "
- "poisonous creatures or those carrying poison potions. "
- "It is also an amazingly painful way to eliminate "
- "poison from one's own system. ";
- break;
-
- case SPELL_STICKS_TO_SNAKES: // FIXME: description sucks
- description += "uses wooden items in the caster's grasp as raw "
- "material for a powerful summoning. Note that highly "
- "enchanted items, such as wizard's staves, will not be "
- "affected. ";
- // "Good examples of sticks include arrows, quarterstaves and clubs.";
- break;
-
- case SPELL_SUMMON_LARGE_MAMMAL:
- description += "summons a canine to the caster's aid.";
- break;
-
- case SPELL_SUMMON_DRAGON: //jmf: reworking, currently unavailable
- description += "summons and binds a powerful dragon to perform the "
- "caster's bidding. Beware, for the summons may succeed "
- "even as the binding fails. ";
- break;
-
- case SPELL_TAME_BEASTS:
- description += "attempts to tame animals in the caster's vicinity. "
- "It works best on animals amenable to domestication. ";
- break;
-
- case SPELL_SLEEP:
- description += "tries to lower its target's metabolic rate, "
- "inducing hypothermic hibernation. It may have side effects "
- "on cold-blooded creatures. ";
- break;
-
- case SPELL_MASS_SLEEP:
- description += "tries to lower the metabolic rate of every creature "
- "within the caster's view enough to induce hypothermic hibernation. "
- "It may have side effects on cold-blooded creatures. ";
- break;
-
-/* ******************************************************************
-// not implemented {dlb}:
- case SPELL_DETECT_MAGIC:
- description += "probes one or more items lying nearby for enchantment. "
- "An experienced diviner may glean additional information. ";
- break;
-****************************************************************** */
-
- case SPELL_DETECT_SECRET_DOORS:
- description += "is beloved by lazy dungeoneers everywhere, for it can "
- "greatly reduce time-consuming searches. ";
- break;
-
- case SPELL_SEE_INVISIBLE:
- description += "enables the caster to perceive things that are "
- "shielded from ordinary sight. ";
- break;
-
- case SPELL_FORESCRY:
- description += "makes the caster aware of the immediate future; "
- "while not far enough to predict the result of a "
- "fight, it does give the caster ample time to get "
- "out of the way of a punch (reflexes allowing). ";
- break;
-
- case SPELL_SUMMON_BUTTERFLIES:
- description +=
- "creates a shower of colourful butterflies. How pretty!";
- break;
-
- case SPELL_WARP_BRAND:
- description += "temporarily binds a localized warp field to the "
- "invoker's weapon. This spell is very dangerous to cast, "
- "as the field is likely to effect the caster as well. ";
- break;
-
- case SPELL_SILENCE:
- description += "eliminates all sound near the caster. This makes "
- "reading scrolls, casting spells, praying or yelling "
- "in the caster's vicinity impossible. (Applies to "
- "caster too, of course.) This spell will not hide your "
- "presence, since its oppressive, unnatural effect "
- "will almost certainly alert any living creature that something "
- "is very wrong. ";
- break;
-
- case SPELL_SHATTER:
- description +=
- "causes a burst of concussive force around the caster, "
- "which will damage most creatures, although those "
- "composed of stone, metal or crystal, or otherwise "
- "brittle, will particularly suffer. The magic has been "
- "known to adversely affect walls. ";
- break;
-
- case SPELL_DISPERSAL:
- description += "tries to teleport away any monsters directly beside "
- "the caster. ";
- break;
-
- case SPELL_DISCHARGE:
- description += "releases electric charges against those "
- "next to the caster. These may arc to "
- "adjacent monsters (or even the caster) before "
- "they eventually ground out. ";
- break;
-
- case SPELL_BEND:
- description +=
- "applies a localized spatial distortion to the detriment"
- " of some nearby creature. ";
- break;
-
- case SPELL_BACKLIGHT:
- description += "causes a halo of glowing light to surround and "
- "effectively outline a creature. This glow offsets "
- "the dark, musty atmosphere of the dungeon, and "
- "thereby makes the affected creature appreciably easier to hit.";
- break;
-
- case SPELL_INTOXICATE:
- description += "works by converting a small portion of brain matter "
- "into alcohol. It affects all intelligent humanoids within "
- "the caster's view (presumably including the caster). It "
- "is frequently used as an icebreaker at wizard parties. ";
- break;
-
- case SPELL_GLAMOUR: // intended only as Grey Elf ability
- description += "is an Elvish magic, which draws upon the viewing "
- "creature's credulity and the caster's comeliness "
- "to charm, confuse or render comatose. ";
- break;
-
- case SPELL_EVAPORATE:
- description += "heats a potion causing it to explode into a large "
- "cloud when thrown. The potion must be thrown immediately, "
- "as part of the spell, for this to work. ";
- break;
-
- case SPELL_FULSOME_DISTILLATION:
- description += "extracts the vile and poisonous essences from a "
- "corpse. A rotten corpse may produce a stronger potion."
- "$$You probably don't want to drink the results. ";
- break;
-
-/* ******************************************************************
-// not implemented {dlb}:
- case SPELL_ERINGYAS_SURPRISING_BOUQUET:
- description += "transmutes any wooden items in the caster's grasp "
- "into a bouquet of beautiful flowers. ";
- break;
-****************************************************************** */
-
- case SPELL_FRAGMENTATION:
- description +=
- "creates a concussive explosion within a large body of "
- "rock (or other hard material), to the detriment of "
- "any who happen to be standing nearby. ";
- break;
-
- case SPELL_AIR_WALK:
- description += "transforms the caster's body into an insubstantial "
- "cloud. The caster becomes immaterial and nearly immune "
- "to physical harm, but is vulnerable to magical fire "
- "and ice. While insubstantial the caster is, of course, "
- "unable to interact with physical objects (but may still "
- "cast spells). ";
- break;
-
- case SPELL_SANDBLAST:
- description += "creates a short blast of high-velocity particles. "
- "It works best when the caster provides some source "
- "(by wielding a stone), but will do what it can with "
- "whatever ambient grit is available. ";
- break;
-
- case SPELL_ROTTING:
- description += "causes the flesh of all those near the caster to "
- "rot. It will affect the living and many of the "
- "corporeal undead. ";
- break;
-
- case SPELL_MAXWELLS_SILVER_HAMMER:
- description += "bestows a lethal but temporary gravitic field "
- "to a crushing implement held by the caster. "
- "It will not affect weapons otherwise subject to "
- "special enchantments. ";
- break;
-
- case SPELL_CONDENSATION_SHIELD:
- description += "causes a disc of dense vapour to condense out of the "
- "air surrounding the caster. It acts like a normal "
- "shield, but its density (and therefore stopping power) "
- "depends upon the caster's skill with Ice Magic. The "
- "disc is controlled by the caster's mind and thus will "
- "not conflict with the wielding of a two-handed weapon. ";
- break;
-
- case SPELL_STONESKIN:
- description += "hardens the one's skin to a degree determined "
- "by one's skill in Earth Magic. This only works on relatively "
- "normal flesh; it will aid neither the undead nor the bodily "
- "transformed. The effects of this spell are boosted if the "
- "caster is in Statue Form. ";
- break;
-
- case SPELL_SIMULACRUM:
- description += "uses a piece of a flesh in hand to create a replica "
- "of the original being out of ice. This magic is "
- "unstable so eventually the replica will sublimate "
- "into a freezing cloud, if it isn't hacked or melted "
- "into a small puddle of water first. ";
- break;
-
- case SPELL_CONJURE_BALL_LIGHTNING:
- description += "allows the conjurer to create ball lightning. "
- "Using the spell is not without risk - ball lighting "
- "can be difficult to control. ";
- break;
-
- case SPELL_CHAIN_LIGHTNING:
- description += "releases a massive electrical discharge that "
- "arcs from target to target until it grounds out.";
- break;
-
- case SPELL_TWIST:
- description += "causes a slight spatial distortion around a monster "
- "in line of sight of the caster, causing injury. ";
- break;
-
- case SPELL_FAR_STRIKE:
- description += "allows the caster to transfer the force of a "
- "weapon strike to any target the caster can see. "
- "This spell will only deliver the impact of the blow; "
- "magical side-effects and enchantments cannot be "
- "transferred in this way. The force transferred by "
- "this spell has little to do with one's skill with "
- "weapons, and more to do with personal strength, "
- "translocation skill, and magic ability. ";
- break;
-
- case SPELL_SWAP:
- description += "allows the caster to swap positions with an adjacent "
- "being. ";
- break;
-
- case SPELL_APPORTATION:
- description += "allows the caster to pull the top item or group of "
- "similar items from a distant pile to the floor "
- "near the caster. The mass of the target item(s) will "
- "make the task more difficult, with some items too "
- "massive to ever be moved by this spell. Using this "
- "spell on a group of items can be risky; insufficient "
- "power will cause some of the items to be lost in the "
- "infinite void.";
- break;
-
- default:
- DEBUGSTR("Bad spell");
- description += "apparently does not exist. "
- "Casting it may therefore be unwise. "
-#if DEBUG
- "Instead, go fix it. ";
-#else
- "Please contact Dungeon Tech Support "
- "at /dev/null for details. ";
-#endif // DEBUG
- }
-
- print_description(description);
-
- if (getch() == 0)
- getch();
-
-#ifdef DOS_TERM
- puttext(25, 1, 80, 25, buffer);
- window(1, 1, 80, 25);
-#endif
-} // end describe_spell()
-
-
-//---------------------------------------------------------------
-//
-// describe_monsters
-//
-// Contains sketchy descriptions of every monster in the game.
-//
-//---------------------------------------------------------------
-void describe_monsters(int class_described, unsigned char which_mons)
-{
- std::string description;
-
- description.reserve(200);
-
-#ifdef DOS_TERM
- char buffer[3400];
-
- gettext(25, 1, 80, 25, buffer);
- window(25, 1, 80, 25);
-#endif
-
- clrscr();
- description = std::string( ptr_monam( &(menv[ which_mons ]), DESC_CAP_A ) );
- description += "$$";
-
- switch (class_described)
- {
- // (missing) case 423 - MONS_ANOTHER_LAVA_THING ??? 15jan2000 {dlb}
- // no entry in m_list.h 17jan200 {dlb}
- // monster has no stats!
- // mv: changed ANOTHER_LAVA_THING to SALAMANDER, added stats and
- // description
- // (missing) case 250 - MONS_PROGRAM_BUG ??? 16jan2000 {dlb}
- case MONS_KILLER_BEE_LARVA:
- description += "A small, powerless larva of killer bee.";
- break;
-
- case MONS_QUASIT:
- description += "A small twisted demon with long sharply pointed tail.";
- break;
-
- case MONS_ANGEL:
- description += "A winged holy being of unnatural beauty. "
- "It's surrounded by aura of brilliant golden light. ";
- break;
-
- case MONS_HUMAN:
- // These should only be possible from polymorphing or shapeshifting.
- description += "A remarkably nondescript person. How odd!";
- break;
-
- case MONS_GIANT_ANT:
- description += "A black ant with poisonous pincers,"
- " about the size of a large dog.";
- break;
-
- case MONS_SOLDIER_ANT:
- description += "A giant ant with large mandibles and a vicious sting.";
- break;
-
- case MONS_QUEEN_ANT:
- description += "A bloated insect, covered in thick chitinous armour."
- "Now you know where all those ants keep coming from!";
- break;
-
- case MONS_ANT_LARVA:
- description += "A baby ant. Isn't it cute?";
- break;
-
- case MONS_GIANT_BAT:
- description += "A huge black bat.";
- break;
-
- case MONS_CENTAUR:
- case MONS_CENTAUR_WARRIOR:
- description += "A hybrid with the torso of a "
- "human atop the body of a large horse. ";
- if (class_described == MONS_CENTAUR_WARRIOR)
- description += "It looks strong and aggressive. ";
- break;
-
- case MONS_YAKTAUR:
- case MONS_YAKTAUR_CAPTAIN:
- description += "Like a centaur, but half yak. ";
- if (class_described == MONS_YAKTAUR_CAPTAIN)
- description += "It looks very strong and aggressive. ";
- break;
-
- case MONS_RED_DEVIL:
- description += "The Red Devil is slightly shorter than a human, "
- "but muscular and covered in spikes and horns. Two "
- "short wings sprout from its shoulders.";
- break;
-
- case MONS_ROTTING_DEVIL:
- description += "A hideous decaying form.";
- if (you.species == SP_GHOUL)
- description += "$It smells great!";
- else if (you.species != SP_MUMMY)
- description += "$It stinks.";
- break;
-
- case MONS_HAIRY_DEVIL:
- description += "A small humanoid demon covered in brown hair. "
- "Watch out - it may have fleas!";
- break;
-
- case MONS_ICE_DEVIL:
- description += "A man-sized demon covered in glittering ice.";
- break;
-
- case MONS_BLUE_DEVIL:
- description += "A strange and nasty blue thing. It looks cold.";
- break;
-
- case MONS_IRON_DEVIL:
- description += "A hideous humanoid figure with metal skin.";
- break;
-
- case MONS_ETTIN:
- description += "A large, two headed humanoid. Most often seen "
- "wielding two weapons, so that the heads will have one less "
- "thing to bicker about.";
- break;
-
- case MONS_FUNGUS:
- description += "A lumpy grey fungus, "
- "growing well in the dank underground dungeon.";
- break;
-
- case MONS_GOBLIN:
- description += "A race of short, ugly and unfriendly humanoids.";
- break;
-
- case MONS_HOUND:
- description += "A fearsome hunting dog.";
- break;
-
- case MONS_HELL_HOUND:
- description += "A huge black dog, with glowing red eyes and "
- "smoke pouring from its fanged mouth.";
- break;
-
- case MONS_WAR_DOG:
- description += "A vicious dog, trained to kill."
- "Its neck is protected by massive spiked collar.";
- break;
-
- case MONS_IMP:
- description += "A small, ugly minor demon.";
- break;
-
- case MONS_JACKAL:
- description += "A small, dog-like scavenger. Packs of these creatures "
- "roam the underworld, searching for carrion to devour.";
- break;
-
- case MONS_KILLER_BEE:
- description += "A giant bee, bearing a deadly barb which can sting "
- "repeatedly.";
- break;
-
- case MONS_QUEEN_BEE:
- description += "Even larger and more dangerous-looking than its "
- "offspring, this creature wants you out of its hive. Now!";
- break;
-
- case MONS_BUMBLEBEE:
- description += "A very large and fat hairy bee.";
- break;
-
- case MONS_MANTICORE:
- description += "A hideous cross-breed, bearing the features of a "
- "human and a lion, with great bat-like wings. Its tail "
- "bristles with spikes, which can be loosed at potential prey.";
- break;
-
- case MONS_NECROPHAGE:
- description += "A vile undead creation of the most unholy necromancy,"
- " these creatures are made from the decaying corpses "
- "of humanoid creatures. They exist to spread disease "
- "and decay, and gain power from the decaying corpses "
- "of other beings.";
- break;
-
- case MONS_GHOUL:
- description += "An undead humanoid creature created from the decaying "
- "corpse by some unholy means of necromancy. It "
- "exists to spread disease and decay, and gains power"
- "from the decaying corpses same way as necrophage does.";
- break;
-
- case MONS_ORC:
- description += "An ugly subterranean race, orcs combine the"
- " worst features of humans, pigs, and several"
- " other unpleasant creatures.";
- break;
-
- case MONS_ORC_KNIGHT:
- description += "A heavily armoured orc, covered in scars from many "
- "past battles.";
- break;
-
- case MONS_ORC_PRIEST:
- description += "A servant of the ancient and cruel gods of the orcs,"
- " dressed in long robe. he's mumbling some strange prayers. "
- "Hope that they will remain unheard.";
- break;
-
- case MONS_ORC_HIGH_PRIEST:
- description += "An exalted servant of the orc god.";
- break;
-
- case MONS_ORC_SORCERER:
- description += "An orc who draws magical power from Hell.";
- break;
-
- case MONS_ORC_WARLORD:
- description += "A very large and strong looking orc.";
- break;
-
- case MONS_ORC_WARRIOR:
- description += "An armoured orc, obviously experienced in the ways of "
- "hacking other creatures apart.";
- break;
-
- case MONS_ORC_WIZARD:
- description += "While orcs are generally quite stupid, occasionally"
- " one develops an aptitude for magic.";
- break;
-
- case MONS_PHANTOM:
- description += "A transparent man-like undead spirit.";
- break;
-
- case MONS_RAT:
- description += "Rats which have grown large and aggressive in "
- "the pestilential dungeon environment.";
- break;
-
- case MONS_GREY_RAT:
- description += "A very large grey rat.";
- break;
-
- case MONS_GREEN_RAT:
- description += "A very large rat, with hair and skin of a "
- "most peculiar green colour.";
- break;
-
- case MONS_ORANGE_RAT:
- description += "A huge rat, with weird knobbly orange skin."
- "It glows with unholy energies. ";
- break;
-
- case MONS_SCORPION:
- description += "A giant black scorpion, its body covered in thick"
- " armour plating, and its tail tipped by a nasty "
- "venomous sting.";
- break;
-
-/* ******************************************************************
-// the tunneling worm is no more ...
-// not until it can be re-implemented safely {dlb}
- case MONS_TUNNELING_WORM:
- case MONS_WORM_TAIL:
- description += "A gargantuan worm, its huge maw capable of crushing rock into dust with little trouble.";
- break;
-****************************************************************** */
-
- case MONS_BRAIN_WORM:
- description += "A slimy mauve worm with a greatly distended head.";
- break;
-
- case MONS_LAVA_WORM:
- description += "A vicious red worm which swims through molten rock.";
- break;
-
- case MONS_SPINY_WORM:
- description += "A great black worm, its many-segmented body covered "
- "in spiky plates of chitinous armour. Acidic venom drips "
- "from its toothy maw.";
- break;
-
- case MONS_SWAMP_WORM:
- description += "A large slimy worm, adept at swimming through the "
- "muck of this foul swamp.";
- break;
-
- case MONS_WORM:
- description += "A giant worm, with unusually large teeth.";
- break;
-
- case MONS_UGLY_THING:
- description += "An ugly thing. Yuck.";
- break;
-
- case MONS_VERY_UGLY_THING:
- description += "A very ugly thing. Double yuck.";
- break;
-
- case MONS_FIRE_VORTEX:
- description += "A swirling cloud of flame.";
- break;
-
- case MONS_SPATIAL_VORTEX:
- description += "A crazily shifting twist in the fabric of reality.";
- break;
-
- case MONS_ABOMINATION_SMALL:
- description +=
- "A hideous form, created or summoned by some arcane process.";
- break;
-
- case MONS_ABOMINATION_LARGE:
- description += "A huge and hideous form, created or summoned "
- "by some arcane process.";
- break;
-
- case MONS_YELLOW_WASP:
- description += "A giant wasp covered with thick plates of yellow "
- "chitinous armour.";
- break;
-
- case MONS_RED_WASP:
- description += "A huge red wasp with a viciously barbed stinger.";
- break;
-
- case MONS_ZOMBIE_SMALL:
- description += "A corpse raised to undeath by necromancy. ";
- break;
- case MONS_ZOMBIE_LARGE:
- description += "A large corpse raised to undeath by necromancy. ";
- break;
-
- case MONS_SIMULACRUM_LARGE:
- case MONS_SIMULACRUM_SMALL:
- description += "An ice replica of a monster, that's animated by "
- "the powers of necromancy. ";
- break;
-
- case MONS_CYCLOPS:
- description += "A giant with one eye in the centre of its forehead."
- " Despite their lack of binocular vision, cyclopes "
- "throw boulders with fearsomely accuracy.";
- break;
-
- case MONS_DRAGON:
- description += "A great reptilian beast, covered in thick green "
- "scales and with two huge bat-like wings. Little trails "
- "of smoke spill from its toothy maw.";
- break;
-
- case MONS_GOLDEN_DRAGON:
- description += "A great dragon covered in shining golden scales. ";
- break;
-
- case MONS_ICE_DRAGON:
- description +=
- "Like a normal dragon, only white and covered in frost.";
- break;
-
- case MONS_IRON_DRAGON:
- description += "A very heavy and apparently flightless dragon.";
- break;
-
- case MONS_MOTTLED_DRAGON:
- description += "A small dragon with strangely mottled scales.";
- break;
-
- case MONS_QUICKSILVER_DRAGON:
- description += "A long and sinuous dragon, seemingly more neck and "
- "tail than anything else. Its skin shines like molten mercury, "
- "and magical energies arc from its pointed snout.";
- break;
-
- case MONS_SHADOW_DRAGON:
- description += "A great shadowy shape, radiating evil and death.";
- break;
-
- case MONS_SKELETAL_DRAGON:
- description += "A huge undead abomination, pieced together from "
- "the broken bones of many dragons.";
- break;
-
- case MONS_STEAM_DRAGON:
- description += "A relatively small grey dragon, with steam pouring "
- "from its mouth.";
- break;
-
- case MONS_STORM_DRAGON:
- description += "A huge and very powerful dragon. "
- "Sparks crackle along its enormous scaly wings.";
- break;
-
- case MONS_SWAMP_DRAGON:
- description += "A slimy dragon, covered in swamp muck. "
- "Poisonous gasses dribble from its snout.";
- break;
-
- case MONS_SERPENT_OF_HELL:
- description += "A huge red glowing dragon, burning with hellfire. ";
- break;
-
- case MONS_SWAMP_DRAKE:
- description += "A small and slimy dragon, covered in swamp muck. ";
- if (you.species != SP_MUMMY)
- description += "It smells horrible.";
- break;
-
- case MONS_FIREDRAKE:
- description += "A small dragon, puffing clouds of smoke.";
- break;
-
- case MONS_TWO_HEADED_OGRE:
- description += "A huge ogre with two heads on top of a "
- "bloated ogre body. It is capable of holding a weapon "
- "in each giant hand.";
- break;
-
- case MONS_FIEND:
- description += "One of the most fearsome denizens of any Hell. "
- "A huge and powerful demon wreathed in hellfire,"
- " with great scaly wings.";
- break;
-
- case MONS_ICE_FIEND:
- description += "One of the most terrible denizens of the "
- "many Hells, the Ice Fiend is a huge icy figure, "
- "covered in frost and wreathed in freezing air.";
- break;
-
- case MONS_SHADOW_FIEND:
- description += "One of the most terrible denizens of the many Hells, "
- "this horrible being appears as a great mass of "
- "writhing shadows which occasionally reveal a huge, "
- "horned skeleton.";
- break;
-
- case MONS_GIANT_SPORE:
- description += "A volatile floating ball of spores, "
- "covered in knobbly rhizome growths.";
- break;
-
- case MONS_HOBGOBLIN:
- description += "A larger and stronger relatives of goblins.";
- break;
-
- case MONS_ICE_BEAST:
- description +=
- "A terrible creature, formed of snow and crystalline ice. "
- "Its feet leave puddles of icy water on the floor.";
- break;
-
- case MONS_KOBOLD:
- description += "Reputedly the creation of an ancient demon-god, "
- "kobolds are small goblin-like creatures with canine heads.";
- break;
-
- case MONS_BIG_KOBOLD:
- description += "An unusually large kobold.";
- break;
-
- case MONS_KOBOLD_DEMONOLOGIST:
- description += "A kobold who has learned to summon and direct demons.";
- break;
-
- case MONS_LICH:
- description +=
- "A wizard who didn't want to die, a Lich is a skeletal,"
- " desiccated corpse kept alive by a mighty exercise of "
- "necromancy. These undead creatures can wield great "
- "magic and are best avoided by all but the most confident.";
- break;
-
- case MONS_ANCIENT_LICH:
- description += "A lich who has grown mighty over countless years. ";
- break;
-
- case MONS_MUMMY:
- description += "An undead figure covered in "
- "bandages and embalming fluids, "
- "compelled to walk by an ancient curse. "
- "It radiates a malign aura to those who intrude on its domain. ";
- break;
-
- case MONS_GUARDIAN_MUMMY:
- description += "An ancient warrior, embalmed "
- "and cursed to walk in undeath for eternity.";
- break;
-
- case MONS_GREATER_MUMMY:
- case MONS_MUMMY_PRIEST:
- description += "The embalmed and undead corpse of an ancient ";
- if (class_described == MONS_GREATER_MUMMY)
- description += "ruler";
- else
- description += "servant of darkness";
- description += ".";
- break;
-
- case MONS_NAGA:
- case MONS_NAGA_MAGE:
- case MONS_NAGA_WARRIOR:
- case MONS_GUARDIAN_NAGA:
- case MONS_GREATER_NAGA:
- if (you.species == SP_NAGA)
- description = "An attractive";
- else
- description = "A strange";
-
- description += " hybrid; human from the chest up,"
- " with a scaly, muscular torso trailing off like "
- " that of a snake. ";
-
- switch (class_described)
- {
- case MONS_GUARDIAN_NAGA:
- description += "These nagas are "
- "often used as guardians by powerful creatures.";
- break;
- case MONS_GREATER_NAGA:
- description += "It looks strong and aggressive.";
- break;
- case MONS_NAGA_MAGE:
- description += "An eldritch nimbus trails its motions. ";
- break;
- case MONS_NAGA_WARRIOR:
- description += "It bears scars of many past battles. ";
- break;
- }
- break;
-
- case MONS_OGRE:
- description += "A larger, uglier and fatter relative "
- "of orcs and goblins.";
- break;
-
- case MONS_OGRE_MAGE:
- description += "A rare breed of ogre, skilled in the use of magic.";
- break;
-
- case MONS_PLANT:
- description += "Few plants can grow in the unpleasant dungeon "
- "environment, but some have managed to adapt and even thrive "
- "underground in the absence of the sun.";
- break;
-
- case MONS_OKLOB_PLANT:
- description += "A vicious plant, dripping with vitriol.";
- break;
-
- case MONS_RAKSHASA:
- case MONS_RAKSHASA_FAKE:
- description += "A type of demon who comes to the material world in "
- "search of power and knowledge. Rakshasas are experts"
- " in the art of illusion, among other things.";
- break;
-
- case MONS_SNAKE:
- description += "The common dungeon snake. ";
- break;
-
- case MONS_BLACK_SNAKE:
- description += "A large black snake. ";
- break;
-
- case MONS_BROWN_SNAKE:
- description += "A large brown snake.";
- break;
-
- case MONS_GREY_SNAKE:
- description += "A very large grey python.";
- break;
-
- case MONS_LAVA_SNAKE:
- description += "A burning red snake which rears up from pools "
- "of lava and tries to bite you.";
- break;
-
- case MONS_SMALL_SNAKE:
- description += "The lesser dungeon snake.";
- break;
-
- case MONS_YELLOW_SNAKE:
- description += "A large yellow tubular reptile.";
- break;
-
- case MONS_GIANT_NEWT:
- description += "Several times the size of a normal newt, but still "
- "not really impressive.";
- break;
-
- case MONS_GIANT_GECKO:
- description += "A lizard with pads on its toes allowing it to cling "
- "to walls and ceilings. It's much larger than a normal gecko... "
- "perhaps it's something in the water?";
- break;
-
- case MONS_GIANT_IGUANA:
- case MONS_GIANT_LIZARD:
- description += "A huge lizard with great crunching jaws.";
- break;
-
- case MONS_GILA_MONSTER:
- description += "A large lizard with brightly coloured stripes and "
- "splotches.";
- break;
-
- case MONS_KOMODO_DRAGON:
- description += "An enormous monitor lizard. It's more than capable "
- "of preying on large animals. Bits of fetid and rotting flesh "
- "from its last few meals are stuck in its teeth.";
- break;
-
- case MONS_LINDWURM:
- description += "A small serpentine dragon with a pair of strong "
- "forelimbs. Its thick scales give off an eerie green glow.";
- break;
-
- case MONS_TROLL:
- description +=
- "A huge, nasty-looking creature. Its thick and knobbly hide "
- "seems to heal almost instantly from most wounds.";
- break;
-
- case MONS_DEEP_TROLL:
- description += "A stooped troll.";
- break;
-
- case MONS_IRON_TROLL:
- description +=
- "A great troll, plated with thick scales of rusty iron.";
- // you can't see its hide, but think it's thick and kobbly, too :P {dlb}
- //jmf: I thought its skin *was* the rusty iron. If so, ought to change
- // shatter_monsters in spells4.cc.
- break;
-
- case MONS_ROCK_TROLL:
- description +=
- "An enormous and very nasty-looking humanoid creature. Its "
- "rocky hide seems to heal almost instantaneously from most wounds.";
- break;
-
- case MONS_UNSEEN_HORROR:
- description +=
- "These creatures are usually unseen by the eyes of most,"
- " and those few who have seen them would rather not have.";
- break;
-
- case MONS_VAMPIRE:
- description += "A powerful undead.";
- if (you.is_undead == US_ALIVE)
- description += " It wants to drink your blood! ";
- break;
-
- case MONS_VAMPIRE_KNIGHT:
- description +=
- "A powerful warrior, with skills undiminished by undeath.";
- if (you.is_undead == US_ALIVE)
- description += " It wants to drink your blood! ";
- break;
-
- case MONS_VAMPIRE_MAGE:
- description += "Undeath has not lessened this powerful mage.";
- if (you.is_undead == US_ALIVE)
- description += " It wants to drink your blood! ";
- break;
-
- case MONS_WRAITH:
- description += "This undead spirit appears as a cloud of black mist "
- "surrounding an insubstantial skeletal form. Its eyes "
- "burn bright with unholy malevolence.";
- break;
-
- case MONS_FREEZING_WRAITH:
- description += "A cloud of freezing air surrounding an incorporeal "
- "skeletal form.";
- break;
-
- case MONS_SHADOW_WRAITH:
- description += "A mist-wreathed skeletal shadow hanging in mid-air, "
- "this creature is almost invisible even to your enhanced sight. ";
- // assumes: to read this message, has see invis
- break;
-
- case MONS_YAK:
- description += "The common dungeon yak, covered in shaggy yak hair "
- "and bearing a nasty pair of yak horns.";
- break;
-
- case MONS_DEATH_YAK:
- description += "A larger and beefier relative of the common dungeon "
- "yak. Its little red eyes gleam with hunger for living flesh.";
- break;
-
- case MONS_WYVERN:
- description += "A dragon-like creature with long sharply pointed tail."
- " Although smaller and less formidable than true dragons, "
- "wyverns are nonetheless a foe to be reckoned with.";
- break;
-
- case MONS_GIANT_EYEBALL:
- description += "A giant eyeball, with a captivating stare.";
- break;
-
- case MONS_GREAT_ORB_OF_EYES:
- description += "A levitating ball, covered in malignant eyes.";
- break;
-
- case MONS_EYE_OF_DEVASTATION:
- description += "A huge eyeball, encased in a levitating globe of "
- "incandescent energy. ";
- break;
-
- case MONS_SHINING_EYE:
- description += "A huge and strangely deformed eyeball, "
- "pulsating with light. "
- "Beauty is certainly nowhere to be found " "in this beholder. ";
- break;
-
- case MONS_EYE_OF_DRAINING:
- description +=
- "These hovering horrors are especially loathed by wizards.";
- break;
-
- case MONS_WIGHT:
- description += "An ancient warrior, kept in a state of undeath "
- "by its will to live.";
- break;
-
- case MONS_WOLF_SPIDER:
- description += "A large hairy spider with vicious mandibles, "
- "roaming the dungeon in search of food.";
- break;
-
- case MONS_REDBACK:
- description += "A vicious black spider with a splash of red on its "
- "swollen abdomen. Its mandibles drip with lethal poison.";
- break;
-
- case MONS_SHADOW:
- description +=
- "An wisp of unliving shadow, drifting on the edge of vision.";
- break;
-
- case MONS_HUNGRY_GHOST:
- description += "The undead form of someone who died of starvation,"
- " this creature wants the same thing to happen to you!";
- break;
-
- case MONS_BUTTERFLY:
- description += "A large multicoloured butterfly with beautifully "
- "patterned wings.";
- break;
-
- case MONS_WANDERING_MUSHROOM:
- description += "A large, fat mushroom.";
- break;
-
- case MONS_EFREET:
- description +=
- "A huge and muscular figure engulfed in a cloud of searing flame.";
- break;
-
- case MONS_GIANT_ORANGE_BRAIN:
- description += "A huge wrinkled brain, floating just off the floor."
- " Every now and then it seems to pulsate.";
- break;
-
- case MONS_GIANT_BEETLE:
- description += "A huge black beetle with great crunching mandibles "
- "and very hard chitinous armour.";
- break;
-
- case MONS_BORING_BEETLE:
- description +=
- "A large brown beetle with huge, rock-crushing mandibles.";
- break;
-
- case MONS_BOULDER_BEETLE:
- description +=
- "A huge grey beetle with an almost impenetrable rocky carapace.";
- break;
-
- case MONS_FLYING_SKULL:
- description +=
- "Unholy magic keeps a disembodied undead skull hovering "
- "above the floor. It has a nasty set of teeth.";
- break;
-
- case MONS_MINOTAUR:
- description += "A large muscular human with the head of a bull. "
- "It makes its home in secluded labyrinths.";
- break;
-
- case MONS_SLIME_CREATURE:
- description +=
- "An icky glob of slime, which slithers along the ground.";
- break;
-
- case MONS_HELLION:
- description += "A frightful demon, covered in roaring hellfire.";
- break;
-
- case MONS_TORMENTOR:
- description += "This malign devil is covered in all manner "
- "of claws, spines and cruel hooks.";
- break;
-
- case MONS_REAPER:
- description += "A skeletal form wielding a giant scythe. ";
- if (you.is_undead == US_ALIVE)
- description += "It has come for your soul!";
- break;
-
- case MONS_SOUL_EATER:
- description +=
- "This greater demon looks like a shadow gliding through "
- "the air towards you. It radiates an intense aura of negative power.";
- break;
-
- case MONS_BEAST:
- description += "A weird and hideous cross between beast and human.";
- break;
-
- case MONS_GLOWING_SHAPESHIFTER:
- description += "A shapeshifter who has lost control over its "
- "transformations, and is constantly changing form.";
- break;
-
- case MONS_SHAPESHIFTER:
- description += "A weird creature with the power to change its form. "
- "It is very rarely observed alive in its natural state.";
- break;
-
- case MONS_GIANT_MITE:
- description += "A large arachnid with vicious poisoned mouth-parts.";
- break;
-
- case MONS_GRIFFON:
- case MONS_HIPPOGRIFF:
- description += "A large creature with the hindquarters of a ";
- if (class_described == MONS_HIPPOGRIFF)
- description += "horse";
- else
- description += "lion";
- description += " and the wings, head, and talons of a great eagle. ";
- break;
-
- case MONS_HYDRA:
- description +=
- "A great reptilian beast, distantly related to the dragon."
- " It has many heads, and the potential to grow many more!";
- break;
-
- case MONS_SKELETON_SMALL: //MONS_SMALL_SKELETON:
- case MONS_SKELETON_LARGE: //MONS_LARGE_SKELETON:
- description +=
- "A skeleton compelled to unlife by the exercise of necromancy.";
- break;
-
- case MONS_SKELETAL_WARRIOR:
- description += "The vicious and heavily armed skeleton of a humanoid "
- "creature, animated by unholy power.";
- break;
-
- case MONS_HELL_KNIGHT:
- description += "A heavily armoured warrior, in league with the powers"
- " of Hell.";
- break;
-
- case MONS_WIZARD:
- description += "An rather eccentric person, dabbling in all sorts of"
- " arcanities.";
- break;
-
- case MONS_NECROMANCER:
- description +=
- "A wizard specializing in the practices of necromantic magic.";
- break;
-
- case MONS_GNOLL:
- description +=
- "A taller and better equipt relative of goblins and orcs.";
- break;
-
- case MONS_CLAY_GOLEM:
- description += "A huge animated clay statue.";
- break;
-
- case MONS_WOOD_GOLEM:
- description += "An animated wooden statue.";
- break;
-
- case MONS_STONE_GOLEM:
- description += "A huge animated stone statue.";
- break;
-
- case MONS_IRON_GOLEM:
- description += "A huge animated metal statue.";
- break;
-
- case MONS_CRYSTAL_GOLEM:
- description += "A huge animated crystal statue.";
- break;
-
- case MONS_TOENAIL_GOLEM:
- description += "A huge animated statue made entirely from toenail "
- "clippings. Some people just have too much time on their hands.";
- break;
-
- case MONS_ELECTRIC_GOLEM:
- description += "An animated figure made completely of electricity. ";
- break;
-
- case MONS_EARTH_ELEMENTAL:
- description += "A spirit drawn from the elemental plane of earth, "
- "which exists in this world by inhabiting a lump of earth and rocks.";
- break;
-
- case MONS_FIRE_ELEMENTAL:
- description += "A spirit drawn from the elemental plane of fire, "
- "which exists in this world as a brilliant column of raging flames.";
- break;
-
- case MONS_AIR_ELEMENTAL:
- description += "A spirit drawn from the elemental plane of air. "
- "It exists in this world as a swirling vortex of air, "
- "often dissipating and reforming.";
- break;
-
- case MONS_WATER_ELEMENTAL:
- description += "A spirit drawn from the elemental plane of water. "
- "It exists on this world as part of a body of water.";
- break;
-
- case MONS_SPECTRAL_WARRIOR: // spectre
- description += "A hideous translucent green undead spirit.";
- break;
-
- case MONS_CURSE_TOE:
- description += "A disembodied toe, hanging in the air and"
- " radiating an intense field of negative energy.";
- break;
-
- case MONS_PULSATING_LUMP:
- description += "A revolting glob of writhing flesh.";
- break;
-
- case MONS_OOZE:
- description += "A disgusting glob of grey sludge.";
- break;
-
- case MONS_BROWN_OOZE:
- description += "A viscous liquid, flowing along the floor "
- "in search of organic matter to corrode. ";
- break;
-
- case MONS_DEATH_OOZE:
- description += "A putrid mass of decaying flesh. ";
- break;
-
- case MONS_GIANT_AMOEBA:
- description += "A pulsating lump of protoplasm. ";
- break;
-
- case MONS_JELLY:
- description += "A pulsating mass of acidic protoplasm. It can and "
- "will eat almost anything, and grows a little each time...";
- break;
-
- case MONS_AZURE_JELLY:
- description += "A frosty blob of bright blue cytoplasm. ";
- break;
-
- case MONS_ACID_BLOB:
- description +=
- "A lump of sickly green flesh, dripping with lethal acid.";
- break;
-
- case MONS_JELLYFISH:
- description += "A pulsating glob of transparent flesh, waiting just "
- "below the surface to sting you with its many tentacles.";
- break;
-
- case MONS_ROYAL_JELLY:
- description += "A particularly rich and golden gelatinous thing. ";
- break;
-
- case MONS_FIRE_GIANT:
- description += "A huge ruddy humanoid with bright hair. ";
- break;
-
- case MONS_FROST_GIANT:
- description += "A huge blue humanoid with hoarfrost hair.";
- break;
-
- case MONS_HILL_GIANT:
- description +=
- "Although one of the smaller giant varieties, this hill giant is still big enough to be dangerous.";
- break;
-
- case MONS_STONE_GIANT:
- description +=
- "A gigantic humanoid with grey skin almost as hard as rock. "
- "It carries several boulders - are you up for a game of 'catch'?";
- break;
-
- case MONS_TITAN:
- description += "This lightning-limned humanoid is unusually large "
- "and powerful, even among giants.";
- break;
-
- case MONS_FLAYED_GHOST:
- description += "A hideous undead creature, with torn skin hanging "
- "from an emaciated body.";
- break;
-
- case MONS_INSUBSTANTIAL_WISP:
- description += "A thin wisp of floating gas.";
- break;
-
- case MONS_VAPOUR:
- description += "A normally invisible cloud of weird-looking vapour.";
- break;
-
- case MONS_DANCING_WEAPON:
- description += "A weapon dancing in the air. ";
- break;
-
- case MONS_ELEPHANT_SLUG:
- description += "A huge grey slug with folds of wrinkled skin. ";
- break;
-
- case MONS_GIANT_SLUG:
- description += "A huge and disgusting gastropod. ";
- break;
-
- case MONS_GIANT_SNAIL:
- description +=
- "A huge and disgusting gastropod with light green shell. ";
- break;
-
- case MONS_SHEEP:
- description += "A stupid woolly animal, with murder in its eyes. ";
- break;
-
- case MONS_HOG:
- description += "A large, fat and very ugly pig. ";
- break;
-
- case MONS_HELL_HOG:
- description += "A large, fat and very ugly pig, suckled "
- "in the pits of Hell. ";
- break;
-
- case MONS_GIANT_MOSQUITO:
- description += "A huge, bloated mosquito. It looks diseased.";
- break;
-
- case MONS_GIANT_CENTIPEDE:
- description += "It has a lot of legs.";
- break;
-
- case MONS_GIANT_BLOWFLY:
- description += "A huge and irritating fly.";
- break;
-
- case MONS_GIANT_FROG:
- description +=
- "It probably didn't get this big by eating little insects.";
- break;
-
- case MONS_GIANT_BROWN_FROG:
- description += "A very large and vicious-looking carnivorous frog. "
- "Its knobbly brown skin blends in with the rough rock of your surroundings.";
- break;
-
- case MONS_SPINY_FROG:
- description +=
- "Although slightly smaller than its cousin, the giant brown"
- " frog, the spiny frog makes up for lack of size by being"
- " covered in wickedly barbed spines and spurs.";
- break;
-
- case MONS_BLINK_FROG:
- description +=
- "A weird-looking frog, constantly blinking in and out of reality.";
- break;
-
- case MONS_GIANT_COCKROACH:
- description += "A large brown cockroach.";
- break;
-
- case MONS_PIT_FIEND:
- description += "A huge winged fiend with incredibly tough skin.";
- break;
-
- case MONS_GARGOYLE:
- description += "A hideous stone statue come to life.";
- break;
-
- case MONS_METAL_GARGOYLE:
- description += "A hideous metal statue come to life.";
- break;
-
- case MONS_MOLTEN_GARGOYLE:
- description += "A hideous melting stone statue come to life.";
- break;
-
- case MONS_ELF:
- case MONS_DEEP_ELF_SOLDIER:
- case MONS_DEEP_ELF_FIGHTER:
- case MONS_DEEP_ELF_KNIGHT:
- case MONS_DEEP_ELF_MAGE:
- case MONS_DEEP_ELF_SUMMONER:
- case MONS_DEEP_ELF_CONJURER:
- case MONS_DEEP_ELF_PRIEST:
- case MONS_DEEP_ELF_HIGH_PRIEST:
- case MONS_DEEP_ELF_DEMONOLOGIST:
- case MONS_DEEP_ELF_ANNIHILATOR:
- case MONS_DEEP_ELF_SORCERER:
- case MONS_DEEP_ELF_DEATH_MAGE:
- description +=
- "One of the race of elves which inhabits this dreary cave.$";
- switch (class_described)
- {
-
- case MONS_DEEP_ELF_SOLDIER:
- description += "This one is just common soldier.";
- break;
-
- case MONS_DEEP_ELF_FIGHTER:
- description += "This soldier has learned some magic.";
- break;
-
- case MONS_DEEP_ELF_KNIGHT:
- description += "This one bears the scars of battles past.";
- break;
-
- case MONS_DEEP_ELF_MAGE:
- description += "Mana crackles between this one's long fingers.";
- break;
-
- case MONS_DEEP_ELF_SUMMONER:
- case MONS_DEEP_ELF_CONJURER:
- description += "This one is a mage specialized in the ancient art ";
- if (class_described == MONS_DEEP_ELF_SUMMONER)
- description += "of summoning servants";
- else
- description += "of hurling energies";
- description += " of destruction.";
- break;
-
- case MONS_DEEP_ELF_PRIEST:
- description += "This one is a servant of the deep elves' god.";
- break;
-
- case MONS_DEEP_ELF_HIGH_PRIEST:
- description +=
- "This one is an exalted servant of the deep elves' god.";
- break;
-
- case MONS_DEEP_ELF_DEMONOLOGIST:
- description +=
- "This mage specialized in demonology, and is marked heavily "
- "from long years in contact with unnatural demonic forces.";
- break;
-
- case MONS_DEEP_ELF_ANNIHILATOR:
- description += "This one likes destructive magics more than most, "
- "and is better at them.";
- break;
-
- case MONS_DEEP_ELF_SORCERER:
- description += "This mighty spellcaster draws power from Hell.";
- break;
-
- case MONS_DEEP_ELF_DEATH_MAGE:
- description += "A strong negative aura surrounds this one.";
- break;
-
- case MONS_ELF:
- // These are only possible from polymorphing or shapeshifting.
- description += "This one is remarkably plain looking.";
- break;
- }
- break;
-
- case MONS_WHITE_IMP:
- description += "A small and mischievous minor demon. ";
- break;
-
- case MONS_LEMURE:
- description += "A vaguely humanoid blob of putrid white flesh. ";
- break;
-
- case MONS_UFETUBUS:
- description += "A chattering and shrieking minor demon. ";
- break;
-
- case MONS_MANES:
- description += "An ugly, twisted little minor demon. ";
- break;
-
- case MONS_MIDGE:
- description += "A small flying demon. ";
- break;
-
- case MONS_NEQOXEC:
- description += "A weirdly shaped demon. ";
- break;
-
- case MONS_ORANGE_DEMON:
- description += "A bright orange demon with a venomous stinger. ";
- break;
-
- case MONS_HELLWING:
- description +=
- "A hideous skeletal demon, with wings of ancient withered skin. ";
- break;
-
- case MONS_SMOKE_DEMON:
- description += "A writhing cloud of smoke hanging in the air. ";
- break;
-
- case MONS_YNOXINUL:
- description += "A demon with shiny metallic scales. ";
- break;
-
- case MONS_EXECUTIONER:
- description += "A horribly powerful demon. ";
- break;
-
- case MONS_GREEN_DEATH:
- description +=
- "A bloated form covered in oozing sores and exhaling clouds of lethal poison. ";
- break;
-
- case MONS_BLUE_DEATH:
- description += "A blue greater demon. ";
- break;
-
- case MONS_BALRUG:
- description +=
- "A huge and very powerful demon, wreathed in fire and shadows. ";
- break;
-
- case MONS_CACODEMON:
- description += "A hideously ugly demon of rage and legendary power. ";
- break;
-
- case MONS_DEMONIC_CRAWLER:
- description += "A long and bloated body, supported by "
- "dozens of short legs and topped with an evil-looking head. ";
- break;
-
- case MONS_SUN_DEMON:
- description +=
- "A demonic figure shining with the light and fury of a fallen star.";
- break;
-
- case MONS_SHADOW_IMP:
- description += "A small and shadowy minor demon.";
- break;
-
- case MONS_SHADOW_DEMON:
- description += "A mysterious demonic figure,"
- " constantly blurring into multiple shadows of itself.";
- break;
-
- case MONS_LOROCYPROCA:
- description += "A tall and gaunt figure, "
- "draped in long robes which flow as if alive.";
- break;
-
- case MONS_GERYON:
- description +=
- "A huge and slithery arch-demon, guarding the gates of Hell. ";
- break;
-
- case MONS_DISPATER:
- description += "The lord of the Iron City of Dis. ";
- break;
-
- case MONS_ASMODEUS:
- description +=
- "One of the arch-demons who dwell in the depths of Hell. ";
- break;
-
- case MONS_ANTAEUS:
- description += "A great titan who lives in the depths of Cocytus. ";
- break;
-
- case MONS_ERESHKIGAL:
- description +=
- "A fearsome arch-fiend who rules the deathly netherworld of Tartarus. ";
- break;
-
- case MONS_VAULT_GUARD:
- description += "A heavily armed and armoured guardian of the Vaults. ";
- break;
-
- case MONS_CURSE_SKULL:
- description +=
- "A charred skull floating in the air and rotating slowly. "
- "Mystic symbols carved into its blackened surface indicate "
- "its resistance to almost any form of attack. ";
- break;
-
- case MONS_ORB_GUARDIAN:
- description +=
- "A huge and glowing purple creature, created by the Orb to "
- "defend itself. ";
- break;
-
- case MONS_DAEVA:
- description +=
- "A divine agent of the Shining One. It manifests as a winged "
- "figure obscured by an aura of brilliant golden light. ";
- break;
-
- case MONS_SPECTRAL_THING:
- description += "A hideous glowing apparition.";
- break;
-
- case MONS_TENTACLED_MONSTROSITY:
- description +=
- "A writhing mass of tentacles, all covered in putrid mucous.";
- break;
-
- case MONS_SPHINX:
- description +=
- "A large creature with a human head, the body of a lion, and "
- "the wings of a huge bird.";
- break;
-
- case MONS_ROTTING_HULK:
- description += "A shambling undead, related to the ghoul.";
- break;
-
- case MONS_KILLER_KLOWN:
- description += "A comical figure full of life and laughter. It"
- " looks very happy to see you... but is there a slightly malicious"
- " cast to its features? Is that red facepaint or something"
- " altogether less pleasant? Join in the fun, and maybe you'll"
- " find out!";
- break;
-
- case MONS_MOTH_OF_WRATH:
- description += "A huge moth, as violent as it is hairy.";
- break;
-
- case MONS_DEATH_COB:
- description += "A dreadful undead cob of corn.";
- break;
-
- case MONS_BOGGART:
- description +=
- "A twisted little sprite-goblin. Beware of its magical tricks!";
- break;
-
- case MONS_LAVA_FISH:
- description += "A fish which lives in lava.";
- break;
-
- case MONS_BIG_FISH:
- description += "A fish of unusual size.";
- break;
-
- case MONS_GIANT_GOLDFISH:
- description +=
- "This is what happens when you give your pet goldfish too much food!";
- break;
-
- case MONS_ELECTRICAL_EEL:
- description +=
- "A small and slimy eel, crackling with electrical discharge.";
- break;
-
- case MONS_DRACONIAN:
- case MONS_RED_DRACONIAN:
- case MONS_WHITE_DRACONIAN:
- case MONS_GREEN_DRACONIAN:
- case MONS_PALE_DRACONIAN:
- case MONS_MOTTLED_DRACONIAN:
- case MONS_BLACK_DRACONIAN:
- case MONS_YELLOW_DRACONIAN:
- case MONS_PURPLE_DRACONIAN:
- case MONS_DRACONIAN_SHIFTER:
- case MONS_DRACONIAN_SCORCHER:
- case MONS_DRACONIAN_ZEALOT:
- case MONS_DRACONIAN_ANNIHILATOR:
- case MONS_DRACONIAN_CALLER:
- case MONS_DRACONIAN_MONK:
- case MONS_DRACONIAN_KNIGHT:
- {
- description += "A ";
-
- const int subsp = draco_subspecies( &menv[which_mons] );
- switch (subsp)
- {
- case MONS_DRACONIAN: description += "brown "; break;
- case MONS_BLACK_DRACONIAN: description += "black "; break;
- case MONS_MOTTLED_DRACONIAN: description += "mottled "; break;
- case MONS_YELLOW_DRACONIAN: description += "yellow "; break;
- case MONS_GREEN_DRACONIAN: description += "green "; break;
- case MONS_PURPLE_DRACONIAN: description += "purple "; break;
- case MONS_RED_DRACONIAN: description += "red "; break;
- case MONS_WHITE_DRACONIAN: description += "white "; break;
- case MONS_PALE_DRACONIAN: description += "pale "; break;
- default:
- break;
- }
-
- description += "scaled humanoid with wings.";
- break;
- }
- case MONS_PLAYER_GHOST:
- description += "The apparition of ";
- description += ghost_description();
- description += ".$";
- break;
-
- case MONS_PANDEMONIUM_DEMON:
- description += describe_demon();
- break;
-
- // mimics -- I'm not considering these descriptions a bug. -- bwr
- case MONS_GOLD_MIMIC:
- description +=
- "An apparently harmless pile of gold coins hides a nasty "
- "venomous shapechanging predator.";
- break;
-
- case MONS_WEAPON_MIMIC:
- description +=
- "An apparently abandoned weapon, actually a vicious little "
- "beast in disguise.";
- break;
-
- case MONS_ARMOUR_MIMIC:
- description +=
- "An apparently abandoned suit of finely-made armour, actually "
- "a vicious little beast in disguise.";
- break;
-
- case MONS_SCROLL_MIMIC:
- description +=
- "An ancient parchment covered in arcane runes. Did it just twitch?";
- break;
-
- case MONS_POTION_MIMIC:
- description += "A delicious looking magical drink. Go on, pick it up!";
- break;
-
- case MONS_BALL_LIGHTNING:
- description += "An oddity of nature, ball lightning bounces around "
- "behaving almost, but not quite, entirely unlike "
- "regular lightning. ";
- break;
-
- case MONS_ORB_OF_FIRE:
- description += "A globe of raw primordial fire, capable of "
- "impressive pyrotechnics.";
- break;
-
- // the quokka is no more ... {dlb}
- // the quokka is back, without cyberware -- bwr
- case MONS_QUOKKA:
- description += "A small marsupial. Don't call it a rat.";
- break;
-
- // uniques
- case MONS_MNOLEG: // was: Nemelex Xobeh - and wrong! {dlb}
- description += "A weirdly glowing figure, "
- "dancing through the twisted air of Pandemonium. ";
- break;
-
- case MONS_LOM_LOBON: // was: Sif Muna - and wrong! {dlb}
- description += "An ancient and strangely serene demon. "
- "It regards you coldly from "
- "the huge glowing eye in the centre of its forehead. ";
- break;
-
- case MONS_CEREBOV: // was: Okawaru - and wrong! {dlb}
- description += "A violent and wrathful demon, "
- "Cerebov appears as a giant human "
- "covered in shining golden armour "
- "and wielding a huge twisted sword. ";
- break;
-
- case MONS_GLOORX_VLOQ: // was: Kikubaaqudgha - and wrong! {dlb}
- description += "A shadowy figure clothed in profound darkness. ";
- break;
-
- case MONS_TERENCE:
- description += "An evil human fighter.";
- break;
-
- case MONS_JESSICA:
- description += "An evil apprentice sorceress.";
- break;
-
- case MONS_SIGMUND:
- description += "An evil and spry old human, whose eyes "
- "twinkle with madness. Sigmund wields a nasty looking scythe.";
- break;
-
- case MONS_EDMUND:
- description += "A lightly armoured warrior.";
- break;
-
- case MONS_PSYCHE:
- description += "A fair-haired magess.";
- break;
-
- case MONS_DONALD:
- description += "An adventurer like you, trying to find the Orb.";
- break;
-
- case MONS_MICHAEL:
- description += "A powerful spellcaster, dressed in a long robe.";
- break;
-
- case MONS_JOSEPH:
- description += "Looks like a mercenary.";
- break;
-
- case MONS_ERICA:
- description += "A comely spellweaver.";
- break;
-
- case MONS_JOSEPHINE:
- description += "An ugly elderly figure, dressed in Druidic clothes.";
- break;
-
- case MONS_HAROLD:
- description += "An evil human bounty hunter.";
- break;
-
- case MONS_NORBERT:
- description += "A skilled warrior.";
- break;
-
- case MONS_JOZEF:
- description += "A tall bounty hunter.";
- break;
-
- case MONS_AGNES:
- description += "A lanky warrior.";
- break;
-
- case MONS_MAUD:
- description += "An evil warrior who looks inexplicably like a rodent.";
- break;
-
- case MONS_LOUISE:
- description += "An unusually heavily armoured spellcaster.";
- break;
-
- case MONS_FRANCIS:
- description += "A wizened spellcaster.";
- break;
-
- case MONS_FRANCES:
- description += "A stout warrior, bearing a deep facial scar.";
- break;
-
- case MONS_RUPERT:
- description += "An evil berserker.";
- break;
-
- case MONS_WAYNE:
- description += "A fat, evil dwarf in a stupid looking hat.";
- break;
-
- case MONS_DUANE:
- description += "An evil mercenary with unusually large ears.";
- break;
-
- case MONS_NORRIS:
- description += "A tan, fit and thoroughly evil surfer.";
- break;
-
- case MONS_ADOLF:
- description += "A svelte fighter-mage with unfortunate facial hair.";
- break;
-
- case MONS_MARGERY:
- description += "A lithe spellcaster.";
- break;
-
- case MONS_IJYB:
- description += "A small and twisted goblin, wearing some ugly blue rags.";
- break;
-
- case MONS_BLORK_THE_ORC:
- description += "A particularly fat and ugly orc.";
- break;
-
- case MONS_EROLCHA:
- description += "An especially cunning ogre magess.";
- break;
-
- case MONS_URUG:
- description += "A rude";
- if (you.species != SP_MUMMY)
- description += ", smelly";
- description += " orc.";
- break;
-
- case MONS_SNORG:
- description += "A hairy troll.";
- break;
-
- case MONS_XTAHUA:
- description += "An ancient and mighty dragon.";
- break;
-
- case MONS_BORIS:
- description +=
- "An ancient lich. The air around his shrouded form crackles with evil energy. ";
- break;
-
- case MONS_SHUGGOTH:
- description += "A vile creature with an elongated head, spiked tail "
- "and wicked six-fingered claws. Its awesome strength is matched by "
- "its umbrage at being transported to this backwater dimension. ";
- break;
-
- case MONS_WOLF:
- description += "A large and strong grey canine.";
- break;
-
- case MONS_WARG:
- description += "A particularly large and evil looking wolf, usually "
- "found in the company of orcs.";
- break;
-
- case MONS_BEAR:
- description += "The common dungeon bear.";
- break;
-
- case MONS_GRIZZLY_BEAR:
- description += "A large, nasty bear with grey fur.";
- break;
-
- case MONS_POLAR_BEAR:
- description += "A large and very strong bear covered in glistening "
- "white fur. ";
- break;
-
- case MONS_BLACK_BEAR:
- description += "A small black bear.";
- break;
-
- case MONS_SALAMANDER: // mv: was ANOTHER_LAVA_THING
- description += "A strange half-human half-snake creature "
- "covered in thick red scales and thorns.";
- break;
-
- case MONS_PROGRAM_BUG:
- default:
- description += "If this monster is a \"program bug\", then it's "
- "recommended that you save your game and reload. Please report "
- "monsters who masquerade as program bugs or run around the "
- "dungeon without a proper description to the authorities.";
- break;
- // onocentaur - donkey
- }
-
-#if DEBUG_DIAGNOSTICS
-
- if (mons_class_flag( menv[ which_mons ].type, M_SPELLCASTER ))
- {
- int hspell_pass[6] = { MS_NO_SPELL, MS_NO_SPELL, MS_NO_SPELL,
- MS_NO_SPELL, MS_NO_SPELL, MS_NO_SPELL };
-
- int msecc = ((class_described == MONS_HELLION) ? MST_BURNING_DEVIL :
- (class_described == MONS_PANDEMONIUM_DEMON) ? MST_GHOST
- : menv[ which_mons ].number);
-
- mons_spell_list(msecc, hspell_pass);
-
- bool found_spell = false;
-
- for (int i = 0; i < 6; i++)
- {
- if (hspell_pass[i] != MS_NO_SPELL)
- {
- if (!found_spell)
- {
- description += "$Monster Spells:$";
- found_spell = true;
- }
-
- snprintf( info, INFO_SIZE, " %d: %s$", i,
- mons_spell_name( hspell_pass[i] ) );
-
- description += info;
- }
- }
- }
-
- bool has_item = false;
- for (int i = 0; i < NUM_MONSTER_SLOTS; i++)
- {
- if (menv[ which_mons ].inv[i] != NON_ITEM)
- {
- if (!has_item)
- {
- description += "$Monster Inventory:$";
- has_item = true;
- }
-
- char buff[ ITEMNAME_SIZE ];
-
- item_def item = mitm[ menv[which_mons].inv[i] ];
- set_ident_flags( item, ISFLAG_IDENT_MASK );
-
- item_name( item, DESC_NOCAP_A, buff );
- snprintf( info, INFO_SIZE, " %d: %s$", i, buff );
- description += info;
- }
- }
-
-#endif
-
- print_description(description);
-
- if (getch() == 0)
- getch();
-
-#ifdef DOS_TERM
- puttext(25, 1, 80, 25, buffer);
- window(1, 1, 80, 25);
-#endif
-} // end describe_monsters
-
-//---------------------------------------------------------------
-//
-// ghost_description
-//
-// Describes the current ghost's previous owner. The caller must
-// prepend "The apparition of" or whatever and append any trailing
-// punctuation that's wanted.
-//
-//---------------------------------------------------------------
-std::string ghost_description(bool concise)
-{
- char tmp_buff[ INFO_SIZE ];
-
- // We're fudging stats so that unarmed combat gets based off
- // of the ghost's species, not the player's stats... exact
- // stats are required anyways, all that matters is whether
- // dex >= str. -- bwr
- const int dex = 10;
- int str;
- switch (ghost.values[GVAL_SPECIES])
- {
- case SP_HILL_DWARF:
- case SP_MOUNTAIN_DWARF:
- case SP_TROLL:
- case SP_OGRE:
- case SP_OGRE_MAGE:
- case SP_MINOTAUR:
- case SP_HILL_ORC:
- case SP_CENTAUR:
- case SP_NAGA:
- case SP_MUMMY:
- case SP_GHOUL:
- str = 15;
- break;
-
- case SP_HUMAN:
- case SP_DEMIGOD:
- case SP_DEMONSPAWN:
- str = 10;
- break;
-
- default:
- str = 5;
- break;
- }
-
- snprintf( tmp_buff, sizeof(tmp_buff),
- "%s the %s, a%s %s %s",
- ghost.name,
-
- skill_title( ghost.values[GVAL_BEST_SKILL],
- ghost.values[GVAL_SKILL_LEVEL],
- ghost.values[GVAL_SPECIES],
- str, dex, GOD_NO_GOD ),
-
- (ghost.values[GVAL_EXP_LEVEL] < 4) ? " weakling" :
- (ghost.values[GVAL_EXP_LEVEL] < 7) ? "n average" :
- (ghost.values[GVAL_EXP_LEVEL] < 11) ? "n experienced" :
- (ghost.values[GVAL_EXP_LEVEL] < 16) ? " powerful" :
- (ghost.values[GVAL_EXP_LEVEL] < 22) ? " mighty" :
- (ghost.values[GVAL_EXP_LEVEL] < 26) ? " great" :
- (ghost.values[GVAL_EXP_LEVEL] < 27) ? "n awesomely powerful"
- : " legendary",
-
- ( concise? get_species_abbrev(ghost.values[GVAL_SPECIES]) :
- species_name( ghost.values[GVAL_SPECIES],
- ghost.values[GVAL_EXP_LEVEL] ) ),
-
- ( concise? get_class_abbrev(ghost.values[GVAL_CLASS]) :
- get_class_name( ghost.values[GVAL_CLASS] ) ) );
-
- return std::string(tmp_buff);
-}
-
-static void print_god_abil_desc( int abil )
-{
- const ability_def &abil_info = get_ability_def( abil );
-
- const std::string cost = "(" + make_cost_description( abil_info ) + ")";
-
- // Produce a 79 character string with cost right justified:
- std::string str( abil_info.name );
- str += std::string( 79 - str.length() - cost.length(), ' ' ) + cost + EOL;
-
- cprintf( str.c_str() );
-}
-
-
-//---------------------------------------------------------------
-//
-// describe_god
-//
-// Describes all gods. Accessible through altars (by praying), or
-// by the ^ key if player is a worshipper.
-//
-//---------------------------------------------------------------
-
-void describe_god( int which_god, bool give_title )
-{
-
- const char *description; // mv: tmp string used for printing description
- int colour; // mv: colour used for some messages
-
-#ifdef DOS_TERM
- char buffer[4000];
- gettext( 1, 1, 80, 25, buffer );
- window( 1, 1, 80, 25 );
-#endif
-
- clrscr();
-
- if (give_title)
- {
- textcolor( WHITE );
- cprintf( " Religion" EOL );
- textcolor( LIGHTGREY );
- }
-
- if (which_god == GOD_NO_GOD) //mv:no god -> say it and go away
- {
- cprintf( EOL "You are not religious." );
- goto end_god_info;
- }
-
- colour = god_colour(which_god);
-
- //mv: print god's name and title - if you can think up better titles
- //I have nothing against
- textcolor(colour);
- cprintf (god_name(which_god,true)); //print long god's name
- cprintf (EOL EOL);
-
- //mv: print god's description
- textcolor (LIGHTGRAY);
-
- switch (which_god)
- {
- case GOD_ZIN:
- description = "Zin is an ancient and revered God, dedicated to the establishment of order" EOL
- "and the destruction of the forces of chaos and night. Valued worshippers " EOL
- "can gain a variety of powers useful in the fight against the evil, but must" EOL
- "abstain from the use of necromancy and other forms of unholy magic." EOL
- "Zin appreciates long-standing faith as well as sacrifices of valued objects." EOL;
- break;
-
- case GOD_SHINING_ONE:
- description = "The Shining One is a powerful crusading deity, allied with Zin in the fight" EOL
- "against evil. Followers may be granted with the ability to summarily dispense" EOL
- "the wrath of heaven, but must never use any form of evil magic and should" EOL
- "fight honourably. The Shining One appreciates long-standing persistence in " EOL
- "the endless crusade, as well as the dedicated destruction of unholy creatures.";
- break;
-
- case GOD_KIKUBAAQUDGHA:
- description = "Kikubaaqudgha is a terrible Demon-God, served by those who seek knowledge of" EOL
- "the powers of death. Followers gain special powers over the undead, and " EOL
- "especially favoured servants can call on mighty demons to slay their foes." EOL
- "Kikubaaqudgha requires the deaths of living creatures as often as possible," EOL
- "but is not interested in the offering of corpses except at an appropriate" EOL
- "altar.";
- break;
-
- case GOD_YREDELEMNUL:
- description = "Yredelemnul is worshipped by those who seek powers over death and the undead" EOL
- "without having to learn to use necromancy. Followers can raise legions of " EOL
- "servile undead and gain a number of other useful (if unpleasant) powers." EOL
- "Yredelemnul appreciates killing, but prefers corpses to be put to use rather" EOL
- "than sacrificed.";
- break;
-
- case GOD_XOM:
- description = "Xom is a wild and unpredictable God of chaos, who seeks not worshippers but" EOL
- "playthings to toy with. Many choose to follow Xom in the hope of receiving" EOL
- "fabulous rewards and mighty powers, but Xom is nothing if not capricious. ";
- break;
-
- case GOD_VEHUMET:
- description = "Vehumet is a God of the destructive powers of magic. Followers gain various" EOL
- "useful powers to enhance their command of the hermetic arts, and the most" EOL
- "favoured stand to gain access to some of the fearsome spells in Vehumet's" EOL
- "library. One's devotion to Vehumet can be proved by the causing of as much" EOL
- "carnage and destruction as possible.";
- break;
-
- case GOD_OKAWARU:
- description = "Okawaru is a dangerous and powerful God of battle. Followers can gain a " EOL
- "number of powers useful in combat as well as various rewards, but must " EOL
- "constantly prove themselves through battle and the sacrifice of corpses" EOL
- "and valuable items.";
- break;
-
- case GOD_MAKHLEB:
- description = "Makhleb the Destroyer is a fearsome God of chaos and violent death. Followers," EOL
- "who must constantly appease Makhleb with blood, stand to gain various powers " EOL
- "of death and destruction. The Destroyer appreciates sacrifices of corpses and" EOL
- "valuable items.";
- break;
-
- case GOD_SIF_MUNA:
- description = "Sif Muna is a contemplative but powerful deity, served by those who seek" EOL
- "magical knowledge. Sif Muna appreciates sacrifices of valuable items, and" EOL
- "the casting of spells as often as possible.";
- break;
-
- case GOD_TROG:
- description = "Trog is an ancient God of anger and violence. Followers are expected to kill" EOL
- "in Trog's name and sacrifice the dead, and in return gain power in battle and" EOL
- "occasional rewards. Trog hates wizards, and followers are forbidden the use" EOL
- "of spell magic. ";
- break;
-
- case GOD_NEMELEX_XOBEH:
- description = "Nemelex is a strange and unpredictable trickster God, whose powers can be" EOL
- "invoked through the magical packs of cards which Nemelex paints in the ichor" EOL
- "of demons. Followers receive occasional gifts, and should use these gifts as" EOL
- "as much as possible. Offerings of any type of item are also appreciated.";
- break;
-
- case GOD_ELYVILON:
- description = "Elyvilon the Healer is worshipped by the healers (among others), who gain" EOL
- "their healing powers by long worship and devotion. Although Elyvilon prefers" EOL
- "a creed of pacifism, those who crusade against evil are not excluded. Elyvilon" EOL
- "appreciates the offering of weapons. ";
- break;
-
- default:
- description = "God of Program Bugs is a weird and dangerous God and his presence should" EOL
- "be reported to dev-team.";
- }
-
- cprintf(description);
- //end of printing description
-
- // title only shown for our own god
- if (you.religion == which_god)
- {
- //mv: print title based on piety
- cprintf( EOL EOL "Title - " );
- textcolor(colour);
-
- // mv: if your piety is high enough you get title
- // based on your god
- if (you.piety > 160)
- {
- cprintf((which_god == GOD_SHINING_ONE) ? "Champion of Law" :
- (which_god == GOD_ZIN) ? "Divine Warrior" :
- (which_god == GOD_ELYVILON) ? "Champion of Light" :
- (which_god == GOD_OKAWARU) ? "Master of Thousand Battles" :
- (which_god == GOD_YREDELEMNUL) ? "Master of Eternal Death" :
- (which_god == GOD_KIKUBAAQUDGHA) ? "Lord of Darkness" :
- (which_god == GOD_MAKHLEB) ? "Champion of Chaos" :
- (which_god == GOD_VEHUMET) ? "Lord of Destruction" :
- (which_god == GOD_TROG) ? "Great Slayer" :
- (which_god == GOD_NEMELEX_XOBEH) ? "Great Trickster" :
- (which_god == GOD_SIF_MUNA) ? "Master of Arcane" :
- (which_god == GOD_XOM) ? "Teddy Bear" :
- "Bogy the Lord of the Bugs"); // Xom and no god is handled before
- }
- else
- {
- //mv: most titles are still universal - if any one wants to
- //he might write specific titles for all gods or rewrite current
- //ones (I know they are not perfect)
- //btw. titles are divided according to piety levels on which you get
- //new abilities.In the main it means - new ability = new title
- switch (which_god)
- {
- case GOD_ZIN:
- case GOD_SHINING_ONE:
- case GOD_KIKUBAAQUDGHA:
- case GOD_YREDELEMNUL:
- case GOD_VEHUMET:
- case GOD_OKAWARU:
- case GOD_MAKHLEB:
- case GOD_SIF_MUNA:
- //mv: what about
- //sinner, believer, apprentice, disciple, adept, scholar, oracle
- case GOD_TROG:
- case GOD_NEMELEX_XOBEH:
- case GOD_ELYVILON:
- cprintf ( (you.piety >= 120) ? "High Priest" :
- (you.piety >= 100) ? "Elder" :
- (you.piety >= 75) ? "Priest" :
- (you.piety >= 50) ? "Deacon" :
- (you.piety >= 30) ? "Novice" :
- (you.piety > 5) ? "Believer"
- : "Sinner" );
- break;
-
- case GOD_XOM:
- cprintf( (you.experience_level >= 20) ? "Xom's favourite toy"
- : "Toy" );
- break;
-
- default:
- cprintf ("Bug");
- }
- }
- }
- // end of print title
-
- // mv: now let's print favor as Brent suggested
- // I know these messages aren't perfect so if you can
- // think up something better, do it
-
- textcolor(LIGHTGRAY);
- cprintf(EOL EOL "Favour - ");
- textcolor(colour);
-
- //mv: player is praying at altar without appropriate religion
- //it means player isn't checking his own religion and so we only
- //display favour and will go out
- if (you.religion != which_god)
- {
- textcolor (colour);
- snprintf( info, INFO_SIZE,
- (you.penance[which_god] >= 50) ? "%s's wrath is upon you!" :
- (you.penance[which_god] >= 20) ? "%s is annoyed with you." :
- (you.penance[which_god] >= 5) ? "%s well remembers your sins." :
- (you.penance[which_god] > 0) ? "%s is ready to forgive your sins." :
- (you.worshipped[which_god]) ? "%s is ambivalent towards you."
- : "%s is neutral towards you.",
- god_name(which_god) );
-
- cprintf(info);
- }
- else
- {
- if (player_under_penance()) //mv: penance check
- {
- cprintf( (you.penance[which_god] >= 50) ? "Godly wrath is upon you!" :
- (you.penance[which_god] >= 20) ? "You've transgressed heavily! Be penitent!" :
- (you.penance[which_god] >= 5 ) ? "You are under penance."
- : "You should show more discipline." );
-
- }
- else
- {
- if (which_god == GOD_XOM)
- cprintf("You are ignored.");
- else
- {
- snprintf( info, INFO_SIZE,
-
- (you.piety > 130) ? "A prized avatar of %s.":
- (you.piety > 100) ? "A shining star in the eyes of %s." :
- (you.piety > 70) ? "A rising star in the eyes of %s." :
- (you.piety > 40) ? "%s is most pleased with you." :
- (you.piety > 20) ? "%s has noted your presence." :
- (you.piety > 5) ? "%s is noncommittal."
- : "You are beneath notice.",
-
- god_name(which_god)
- );
-
- cprintf(info);
- }
- }
- //end of favour
-
- //mv: following code shows abilities given from god (if any)
-
-
- textcolor(LIGHTGRAY);
- cprintf(EOL EOL "Granted powers : (Cost)" EOL);
- textcolor(colour);
-
-
- // mv: these gods protects you during your prayer (not mentioning XOM)
- // chance for doing so is (random2(you.piety) >= 30)
- // Note that it's not depending on penance.
- // Btw. I'm not sure how to explain such divine protection
- // because god isn't really protecting player - he only sometimes
- // saves his life (probably it shouldn't be displayed at all).
- // What about this ?
- if ((which_god == GOD_ZIN
- || which_god == GOD_SHINING_ONE
- || which_god == GOD_ELYVILON
- || which_god == GOD_OKAWARU
- || which_god == GOD_YREDELEMNUL)
- && you.piety >= 30)
- {
- snprintf( info, INFO_SIZE,
- "%s %s watches over you during prayer." EOL,
- god_name(which_god),
- (you.piety >= 150) ? "carefully": // > 4/5
- (you.piety >= 90) ? "often" : // > 2/3
- "sometimes" // less than 2:3
- );
-
- cprintf(info);
- }
-
- // mv: No abilities (except divine protection)
- // under penance (fix me if I'm wrong)
- if (player_under_penance())
- {
- cprintf( "None." EOL );
- }
- else
- {
- switch (which_god) //mv: finaly let's print abilities
- {
- case GOD_ZIN:
- if (you.piety >= 30)
- print_god_abil_desc( ABIL_ZIN_REPEL_UNDEAD );
- else
- cprintf( "None." EOL );
-
- if (you.piety >= 50)
- print_god_abil_desc( ABIL_ZIN_HEALING );
-
- if (you.piety >= 75)
- print_god_abil_desc( ABIL_ZIN_PESTILENCE );
-
- if (you.piety >= 100)
- print_god_abil_desc( ABIL_ZIN_HOLY_WORD );
-
- if (you.piety >= 120)
- print_god_abil_desc( ABIL_ZIN_SUMMON_GUARDIAN );
- break;
-
- case GOD_SHINING_ONE:
- if (you.piety >= 30)
- print_god_abil_desc( ABIL_TSO_REPEL_UNDEAD );
- else
- cprintf( "None." EOL );
-
- if (you.piety >= 50)
- print_god_abil_desc( ABIL_TSO_SMITING );
-
- if (you.piety >= 75)
- print_god_abil_desc( ABIL_TSO_ANNIHILATE_UNDEAD );
-
- if (you.piety >= 100)
- print_god_abil_desc( ABIL_TSO_CLEANSING_FLAME );
-
- if (you.piety >= 120)
- print_god_abil_desc( ABIL_TSO_SUMMON_DAEVA );
- break;
-
- case GOD_KIKUBAAQUDGHA:
- if (you.piety >= 30)
- print_god_abil_desc( ABIL_KIKU_RECALL_UNDEAD_SLAVES );
- else
- cprintf( "None." EOL );
-
- if (you.piety >= 50)
- cprintf("You are protected from some of the side-effects of death magic." EOL);
-
- if (you.piety >= 75)
- print_god_abil_desc( ABIL_KIKU_ENSLAVE_UNDEAD );
-
- if (you.piety >= 120)
- print_god_abil_desc( ABIL_KIKU_INVOKE_DEATH );
- break;
-
- case GOD_YREDELEMNUL:
- if (you.piety >= 30)
- print_god_abil_desc( ABIL_YRED_ANIMATE_CORPSE );
- else
- cprintf( "None." EOL );
-
- if (you.piety >= 50)
- print_god_abil_desc( ABIL_YRED_RECALL_UNDEAD );
-
- if (you.piety >= 75)
- print_god_abil_desc( ABIL_YRED_ANIMATE_DEAD );
-
- if (you.piety >= 100)
- print_god_abil_desc( ABIL_YRED_DRAIN_LIFE );
-
- if (you.piety >= 120)
- print_god_abil_desc( ABIL_YRED_CONTROL_UNDEAD );
- break;
-
-
- case GOD_VEHUMET:
- if (you.piety >= 30)
- {
- cprintf( "You can gain power from the those you kill " EOL
- " in Vehumet's name, or those slain by your servants." EOL );
- }
- else
- cprintf( "None." EOL );
-
- if (you.piety >= 50)
- cprintf( "Vehumet assists with destructive magics during prayer." EOL );
-
- if (you.piety >= 75)
- cprintf( "During prayer you have some protection from summoned creatures." EOL );
-
- if (you.piety >= 100)
- print_god_abil_desc( ABIL_VEHUMET_CHANNEL_ENERGY );
- break;
-
-
- case GOD_OKAWARU:
- if (you.piety >= 30)
- print_god_abil_desc( ABIL_OKAWARU_MIGHT );
- else
- cprintf( "None." EOL );
-
- if (you.piety >= 50)
- print_god_abil_desc( ABIL_OKAWARU_HEALING );
-
- if (you.piety >= 120)
- print_god_abil_desc( ABIL_OKAWARU_HASTE );
- break;
-
- case GOD_MAKHLEB:
- if (you.piety >= 30)
- {
- cprintf( "You can gain power from the deaths " EOL
- " of those you kill in Makhleb's name." EOL );
- }
- else
- cprintf( "None." EOL );
-
- if (you.piety >= 50)
- print_god_abil_desc( ABIL_MAKHLEB_MINOR_DESTRUCTION );
-
- if (you.piety >= 75)
- print_god_abil_desc( ABIL_MAKHLEB_LESSER_SERVANT_OF_MAKHLEB );
-
- if (you.piety >= 100)
- print_god_abil_desc( ABIL_MAKHLEB_MAJOR_DESTRUCTION );
-
- if (you.piety >= 120)
- print_god_abil_desc( ABIL_MAKHLEB_GREATER_SERVANT_OF_MAKHLEB );
- break;
-
- case GOD_SIF_MUNA:
- if (you.piety >= 50)
- print_god_abil_desc( ABIL_SIF_MUNA_FORGET_SPELL );
- else
- cprintf( "None." EOL );
-
- if (you.piety >= 100)
- cprintf( "You are protected from some side-effects of spellcasting." EOL );
- break;
-
- case GOD_TROG:
- if (you.piety >= 30)
- print_god_abil_desc( ABIL_TROG_BERSERK );
- else
- cprintf( "None." EOL );
-
- if (you.piety >= 50)
- print_god_abil_desc( ABIL_TROG_MIGHT );
-
- if (you.piety >= 100)
- print_god_abil_desc( ABIL_TROG_HASTE_SELF );
- break;
-
- case GOD_ELYVILON:
- if (you.piety >= 30)
- print_god_abil_desc( ABIL_ELYVILON_LESSER_HEALING );
- else
- cprintf( "None." EOL );
-
- if (you.piety >= 50)
- print_god_abil_desc( ABIL_ELYVILON_PURIFICATION );
-
- if (you.piety >= 75)
- print_god_abil_desc( ABIL_ELYVILON_HEALING );
-
- if (you.piety >= 100)
- print_god_abil_desc( ABIL_ELYVILON_RESTORATION );
-
- if (you.piety >= 120)
- print_god_abil_desc( ABIL_ELYVILON_GREATER_HEALING );
- break;
-
- default: //mv: default is Xom, Nemelex and all bugs.
- cprintf( "None." EOL );
- } //end of printing abilities
- }
- }
-
-
-end_god_info: //end of everything (life, world, universe etc.)
-
- getch(); // wait until keypressed
-
-#ifdef DOS_TERM //mv: if DOS_TERM is defined than buffer is returned to screen
- //if not redraw_screen() is called everytime when this function is
- //called
- puttext(1, 1, 80, 25, buffer);
- window(1, 1, 80, 25);
-#endif
-} //mv: That's all folks.
diff --git a/stone_soup/crawl-ref/source/describe.h b/stone_soup/crawl-ref/source/describe.h
deleted file mode 100644
index 981f90ce01..0000000000
--- a/stone_soup/crawl-ref/source/describe.h
+++ /dev/null
@@ -1,64 +0,0 @@
-
-/*
- * File: describe.h
- * Summary: Functions used to print information about various game objects.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <2> 5/21/99 BWR Changed from is_artifact to is_dumpable_artifact
- * <1> 4/20/99 JDJ Added get_item_description and is_artifact.
- */
-
-#ifndef DESCRIBE_H
-#define DESCRIBE_H
-
-#include <string>
-#include "externs.h"
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: chardump - spells4
- * *********************************************************************** */
-bool is_dumpable_artifact( const item_def &item, char verbose );
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: chardump - describe
- * *********************************************************************** */
-std::string get_item_description( const item_def &item, char verbose,
- bool dump = false );
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - religion
- * *********************************************************************** */
-void describe_god( int which_god, bool give_title );
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: item_use - shopping
- * *********************************************************************** */
-void describe_item( const item_def &item );
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: direct
- * *********************************************************************** */
-void describe_monsters(int class_described, unsigned char which_mons);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: item_use
- * *********************************************************************** */
-void describe_spell(int spelled);
-
-// last updated 13oct2003 {darshan}
-/* ***********************************************************************
- * called from: describe_monsters - describe, kill_ghost - Kills
- * *********************************************************************** */
-std::string ghost_description(bool concise = false);
-
-#endif
diff --git a/stone_soup/crawl-ref/source/direct.cc b/stone_soup/crawl-ref/source/direct.cc
deleted file mode 100644
index 753adf3207..0000000000
--- a/stone_soup/crawl-ref/source/direct.cc
+++ /dev/null
@@ -1,1503 +0,0 @@
-/*
- * File: direct.cc
- * Summary: Functions used when picking squares.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <5> 01/08/01 GDL complete rewrite of direction()
- * <4> 11/23/99 LRH Looking at monsters now
- * displays more info
- * <3> 5/12/99 BWR changes to allow for space selection of target.
- * CR, ESC, and 't' in targeting.
- * <2> 5/09/99 JDJ look_around no longer prints a prompt.
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "direct.h"
-
-#include <cstdarg>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-#ifdef DOS
-#include <conio.h>
-#endif
-
-#include "externs.h"
-
-#include "debug.h"
-#include "describe.h"
-#include "itemname.h"
-#include "monstuff.h"
-#include "mon-util.h"
-#include "player.h"
-#include "shopping.h"
-#include "stuff.h"
-#include "spells4.h"
-#include "stash.h"
-#include "travel.h"
-#include "view.h"
-
-#ifdef USE_MACROS
-#include "macro.h"
-#endif
-
-enum LOSSelect
-{
- LOS_ANY = 0x00,
-
- // Check only visible squares
- LOS_VISIBLE = 0x01,
-
- // Check only hidden squares
- LOS_HIDDEN = 0x02,
-
- LOS_VISMASK = 0x03,
-
- // Flip from visible to hidden when going forward,
- // or hidden to visible when going backwards.
- LOS_FLIPVH = 0x20,
-
- // Flip from hidden to visible when going forward,
- // or visible to hidden when going backwards.
- LOS_FLIPHV = 0x40,
-
- LOS_NONE = 0xFFFF
-};
-
-// x and y offsets in the following order:
-// SW, S, SE, W, E, NW, N, NE
-static const char xcomp[9] = { -1, 0, 1, -1, 0, 1, -1, 0, 1 };
-static const char ycomp[9] = { 1, 1, 1, 0, 0, 0, -1, -1, -1 };
-
-// [dshaligram] Removed . and 5 from dirchars so it's easier to
-// special case them.
-static const char dirchars[19] = { "b1j2n3h4bbl6y7k8u9" };
-static const char DOSidiocy[10] = { "OPQKSMGHI" };
-static const char *aim_prompt = "Aim (move cursor or -/+/=, change mode with CTRL-F, select with . or >)";
-
-static void describe_feature(int mx, int my, bool oos);
-static void describe_cell(int mx, int my);
-
-static bool find_object( int x, int y, int mode );
-static bool find_monster( int x, int y, int mode );
-static bool find_feature( int x, int y, int mode );
-static char find_square( unsigned char xps, unsigned char yps,
- FixedVector<char, 2> &mfp, char direction,
- bool (*targ)(int, int, int),
- int mode = TARG_ANY,
- bool wrap = false,
- int los = LOS_ANY);
-
-static bool is_mapped(int x, int y)
-{
- return (is_player_mapped(x, y));
-}
-
-//---------------------------------------------------------------
-//
-// direction
-//
-// input: restricts : DIR_NONE accepts keypad dir or targetting
-// DIR_TARGET must use targetting.
-// DIR_DIR must use keypad direction
-//
-//
-// outputs: dist structure:
-//
-// isValid a valid target or direction was chosen
-// isCancel player hit 'escape'
-// isTarget targetting was used
-// tx,ty target x,y or logical beam extension to
-// edge of map if keypad direction used.
-// dx,dy direction delta if keypad used {-1,0,1}
-//
-// SYNOPSIS:
-//
-// gets a direction, or any of the follwing:
-//
-// * go to targetting mode
-// +,= go to targetting mode, next monster
-// - " , prev monster
-// t,p auto-select previous target
-//
-//
-// targetting mode is handled by look_around()
-//---------------------------------------------------------------
-void direction( struct dist &moves, int restrict, int mode )
-{
- bool dirChosen = false;
- bool targChosen = false;
- int dir = 0;
-
- // init
- moves.isValid = false;
- moves.isTarget = false;
- moves.isMe = false;
- moves.isCancel = false;
- moves.dx = moves.dy = 0;
- moves.tx = moves.ty = 0;
-
- // XXX. this is ALWAYS in relation to the player. But a bit of a hack
- // nonetheless! --GDL
- gotoxy( VIEW_CX + 1, VIEW_CY );
-
- int keyin = getchm(KC_TARGETING);
-
- if (keyin == 0) // DOS idiocy (emulated by win32 console)
- {
- keyin = getchm(KC_TARGETING); // grrr.
- if (keyin == '*')
- {
- targChosen = true;
- dir = 0;
- }
- else
- {
- if (strchr(DOSidiocy, keyin) == NULL)
- return;
- dirChosen = true;
- dir = (int)(strchr(DOSidiocy, keyin) - DOSidiocy);
- }
- }
- else
- {
- if (strchr( dirchars, keyin ) != NULL)
- {
- dirChosen = true;
- dir = (int)(strchr(dirchars, keyin) - dirchars) / 2;
- }
- else
- {
- switch (keyin)
- {
- case CONTROL('F'):
- mode = (mode + 1) % TARG_NUM_MODES;
-
- snprintf( info, INFO_SIZE, "Targeting mode is now: %s",
- (mode == TARG_ANY) ? "any" :
- (mode == TARG_ENEMY) ? "enemies"
- : "friends" );
-
- mpr( info );
-
- targChosen = true;
- dir = 0;
- break;
-
- case '-':
- targChosen = true;
- dir = -1;
- break;
-
- case '*':
- targChosen = true;
- dir = 0;
- break;
-
- case ';':
- targChosen = true;
- dir = -3;
- break;
-
- case '\'':
- targChosen = true;
- dir = -2;
- break;
-
- case '+':
- case '=':
- targChosen = true;
- dir = 1;
- break;
-
- case 't':
- case 'p':
- targChosen = true;
- dir = 2;
- break;
-
- case '.':
- case '5':
- dirChosen = true;
- dir = 4;
- break;
-
- case ESCAPE:
- moves.isCancel = true;
- return;
-
- default:
- break;
- }
- }
- }
-
- // at this point, we know exactly the input - validate
- if (!(targChosen || dirChosen) || (targChosen && restrict == DIR_DIR))
- {
- mpr("What an unusual direction.");
- return;
- }
-
- // special case: they typed a dir key, but they're in target-only mode
- if (dirChosen && restrict == DIR_TARGET)
- {
- mpr(aim_prompt);
- look_around( moves, false, dir, mode );
- return;
- }
-
- if (targChosen)
- {
- if (dir < 2)
- {
- mpr(aim_prompt);
- moves.prev_target = dir;
- look_around( moves, false, -1, mode );
- if (moves.prev_target != -1) // -1 means they pressed 'p'
- return;
- }
-
- // chose to aim at previous target. do we have one?
- if (you.prev_targ == MHITNOT || you.prev_targ == MHITYOU)
- {
- mpr("You haven't got a target.");
- return;
- }
-
- // we have a valid previous target (maybe)
- struct monsters *montarget = &menv[you.prev_targ];
-
- if (!mons_near(montarget) || !player_monster_visible( montarget ))
- {
- mpr("You can't see that creature any more.");
- return;
- }
- else
- {
- moves.isValid = true;
- moves.isTarget = true;
- moves.tx = montarget->x;
- moves.ty = montarget->y;
- }
- return;
- }
-
- // at this point, we have a direction, and direction is allowed.
- moves.isValid = true;
- moves.isTarget = false;
- moves.dx = xcomp[dir];
- moves.dy = ycomp[dir];
- if (xcomp[dir] == 0 && ycomp[dir] == 0)
- moves.isMe = true;
-
- // now the tricky bit - extend the target x,y out to map edge.
- int mx, my;
- mx = my = 0;
-
- if (moves.dx > 0)
- mx = (GXM - 1) - you.x_pos;
- if (moves.dx < 0)
- mx = you.x_pos;
-
- if (moves.dy > 0)
- my = (GYM - 1) - you.y_pos;
- if (moves.dy < 0)
- my = you.y_pos;
-
- if (!(mx == 0 || my == 0))
- {
- if (mx < my)
- my = mx;
- else
- mx = my;
- }
- moves.tx = you.x_pos + moves.dx * mx;
- moves.ty = you.y_pos + moves.dy * my;
-}
-
-// Attempts to describe a square that's not in line-of-sight. If
-// there's a stash on the square, announces the top item and number
-// of items, otherwise, if there's a stair that's in the travel
-// cache and noted in the Dungeon (O)verview, names the stair.
-static void describe_oos_square(int x, int y)
-{
- if (!is_mapped(x, y))
- return;
-
-#ifdef STASH_TRACKING
- describe_stash(x, y);
-#endif
- describe_feature(x, y, true);
-}
-
-//---------------------------------------------------------------
-//
-// look_around
-//
-// Accessible by the x key and when using cursor aiming. Lets you
-// find out what symbols mean, and is the way to access monster
-// descriptions.
-//
-// input: dist.prev_target : -1 is last monster
-// 0 is no monster selected
-// 1 is next monster
-//
-// input: first_move is -1 if no initial cursor move, otherwise
-// make 1 move in that direction.
-//
-//
-// output: if dist.prev_target is -1 on OUTPUT, it means that
-// player selected 'p' ot 't' for last targetted monster.
-//
-// otherwise, usual dist fields are filled in (dx and dy are
-// always zero coming back from this function)
-//
-//---------------------------------------------------------------
-
-void look_around(struct dist &moves, bool justLooking, int first_move, int mode)
-{
- int keyin = 0;
- bool dirChosen = false;
- bool targChosen = false;
- int dir = 0;
- int cx = VIEW_CX;
- int cy = VIEW_CY;
- int newcx, newcy;
- int mx, my; // actual map x,y (scratch)
- int mid; // monster id (scratch)
- FixedVector < char, 2 > monsfind_pos;
- FixedVector < char, 2 > objfind_pos;
-
- monsfind_pos[0] = objfind_pos[0] = you.x_pos;
- monsfind_pos[1] = objfind_pos[1] = you.y_pos;
-
- message_current_target();
-
- // setup initial keystroke
- if (first_move >= 0)
- keyin = (int)'1' + first_move;
- if (moves.prev_target == -1)
- keyin = '-';
- if (moves.prev_target == 1)
- keyin = '+';
- if (moves.prev_target == -2)
- keyin = '\'';
- if (moves.prev_target == -3)
- keyin = ';';
- // reset
- moves.prev_target = 0;
-
- // loop until some exit criteria reached
- while(true)
- {
- dirChosen = false;
- targChosen = false;
- newcx = cx;
- newcy = cy;
-
- // move cursor to current position
- gotoxy(cx+1, cy);
-
- if (keyin == 0)
- keyin = getchm(KC_TARGETING);
-
- // [dshaligram] Classic Crawl behaviour was to use space to select
- // targets when targeting. The patch changed the meaning of space
- // from 'confirm' to 'cancel', which surprised some folks. I'm now
- // arbitrarily defining space as 'cancel' for look-around, and
- // 'confirm' for targeting.
- if (!justLooking && keyin == ' ')
- keyin = '\r';
-
- // DOS idiocy
- if (keyin == 0)
- {
- // get the extended key
- keyin = getchm(KC_TARGETING);
-
- // look for CR - change to '5' to indicate selection
- if (keyin == 13)
- keyin = 'S';
-
- if (strchr(DOSidiocy, keyin) == NULL)
- break;
- dirChosen = true;
- dir = (int)(strchr(DOSidiocy, keyin) - DOSidiocy);
- }
- else
- {
- if (strchr(dirchars, keyin) != NULL)
- {
- dirChosen = true;
- dir = (int)(strchr(dirchars, keyin) - dirchars) / 2;
- }
- else
- {
- // handle non-directional keys
- switch (keyin)
- {
- case CONTROL('F'):
- mode = (mode + 1) % TARG_NUM_MODES;
-
- snprintf( info, INFO_SIZE, "Targeting mode is now: %s",
- (mode == TARG_ANY) ? "any" :
- (mode == TARG_ENEMY) ? "enemies"
- : "friends" );
-
- mpr( info );
- targChosen = true;
- break;
-
- case '^':
- case '\t':
- case '\\':
- case '_':
- case '<':
- case '>':
- {
- if (find_square( cx, cy, objfind_pos, 1,
- find_feature, keyin, true,
- Options.target_los_first
- ? LOS_FLIPVH : LOS_ANY))
- {
- newcx = objfind_pos[0];
- newcy = objfind_pos[1];
- }
- else
- flush_input_buffer( FLUSH_ON_FAILURE );
- targChosen = true;
- break;
- }
- case ';':
- case '/':
- case '\'':
- case '*':
- {
- dir = keyin == ';' || keyin == '/'? -1 : 1;
- if (find_square( cx, cy, objfind_pos, dir,
- find_object, 0, true,
- Options.target_los_first
- ? (dir == 1? LOS_FLIPVH : LOS_FLIPHV)
- : LOS_ANY))
-
- {
- newcx = objfind_pos[0];
- newcy = objfind_pos[1];
- }
- else
- flush_input_buffer( FLUSH_ON_FAILURE );
- targChosen = true;
- break;
- }
-
- case '-':
- case '+':
- case '=':
- {
- dir = keyin == '-'? -1 : 1;
- if (find_square( cx, cy, monsfind_pos, dir,
- find_monster, mode, Options.target_wrap ))
- {
- newcx = monsfind_pos[0];
- newcy = monsfind_pos[1];
- }
- else
- flush_input_buffer( FLUSH_ON_FAILURE );
- targChosen = true;
- break;
- }
-
- case 't':
- case 'p':
- moves.prev_target = -1;
- break;
-
- case '?':
- targChosen = true;
- mx = you.x_pos + cx - VIEW_CX;
- my = you.y_pos + cy - VIEW_CY;
- mid = mgrd[mx][my];
-
- if (mid == NON_MONSTER)
- break;
-
-#if (!DEBUG_DIAGNOSTICS)
- if (!player_monster_visible( &menv[mid] ))
- break;
-#endif
-
- describe_monsters( menv[ mid ].type, mid );
- redraw_screen();
- mesclr( true );
- // describe the cell again.
- describe_cell(view2gridX(cx), view2gridY(cy));
- break;
-
- case '\r':
- case '\n':
- case '.':
- case '5':
- // If we're in look-around mode, and the cursor is on
- // the character and there's a valid travel target
- // within the viewport, jump to that target.
- if (justLooking && cx == VIEW_CX && cy == VIEW_CY)
- {
- if (you.travel_x > 0 && you.travel_y > 0)
- {
- int nx = grid2viewX(you.travel_x);
- int ny = grid2viewY(you.travel_y);
- if (in_viewport_bounds(nx, ny))
- {
- newcx = nx;
- newcy = ny;
- targChosen = true;
- }
- }
- }
- else
- {
- dirChosen = true;
- dir = 4;
- }
- break;
-
- case ' ':
- case ESCAPE:
- moves.isCancel = true;
- mesclr( true );
- return;
-
- default:
- break;
- }
- }
- }
-
- // now we have parsed the input character completely. Reset & Evaluate:
- keyin = 0;
- if (!targChosen && !dirChosen)
- break;
-
- // check for SELECTION
- if (dirChosen && dir == 4)
- {
- // [dshaligram] We no longer vet the square coordinates if
- // we're justLooking. By not vetting the coordinates, we make 'x'
- // look_around() nicer for travel purposes.
- if (!justLooking)
- {
- // RULE: cannot target what you cannot see
- if (!in_vlos(cx, cy))
- {
- // if (!justLooking)
- mpr("Sorry, you can't target what you can't see.");
- return;
- }
- }
-
- moves.isValid = true;
- moves.isTarget = true;
- moves.tx = you.x_pos + cx - VIEW_CX;
- moves.ty = you.y_pos + cy - VIEW_CY;
-
- if (moves.tx == you.x_pos && moves.ty == you.y_pos)
- moves.isMe = true;
- else
- {
- // try to set you.previous target
- mx = you.x_pos + cx - VIEW_CX;
- my = you.y_pos + cy - VIEW_CY;
- mid = mgrd[mx][my];
-
- if (mid == NON_MONSTER)
- break;
-
- if (!player_monster_visible( &(menv[mid]) ))
- break;
-
- you.prev_targ = mid;
- }
- break;
- }
-
- // check for MOVE
- if (dirChosen)
- {
- newcx = cx + xcomp[dir];
- newcy = cy + ycomp[dir];
- }
-
- // bounds check for newcx, newcy
- if (newcx < VIEW_SX) newcx = VIEW_SX;
- if (newcx > VIEW_EX) newcx = VIEW_EX;
- if (newcy < VIEW_SY) newcy = VIEW_SY;
- if (newcy > VIEW_EY) newcy = VIEW_EY;
-
- // no-op if the cursor doesn't move.
- if (newcx == cx && newcy == cy)
- continue;
-
- // CURSOR MOVED - describe new cell.
- cx = newcx;
- cy = newcy;
- mesclr( true );
- if (!in_vlos(cx, cy))
- {
- mpr("You can't see that place.");
- describe_oos_square(you.x_pos + cx - VIEW_CX,
- you.y_pos + cy - VIEW_CY);
- continue;
- }
- describe_cell(you.x_pos + cx - VIEW_CX, you.y_pos + cy - VIEW_CY);
- } // end WHILE
-
- mesclr( true );
-} // end look_around()
-
-bool in_vlos(int x, int y)
-{
- return in_los_bounds(x, y)
- && (env.show[x - LOS_SX][y] || (x == VIEW_CX && y == VIEW_CY));
-}
-
-bool in_los(int x, int y)
-{
- const int tx = x + VIEW_CX - you.x_pos,
- ty = y + VIEW_CY - you.y_pos;
-
- if (!in_los_bounds(tx, ty))
- return (false);
-
- return (x == you.x_pos && y == you.y_pos) || env.show[tx - LOS_SX][ty];
-}
-
-static bool find_monster( int x, int y, int mode )
-{
- const int targ_mon = mgrd[ x ][ y ];
- return (targ_mon != NON_MONSTER
- && in_los(x, y)
- && player_monster_visible( &(menv[targ_mon]) )
- && !mons_is_mimic( menv[targ_mon].type )
- && (mode == TARG_ANY
- || (mode == TARG_FRIEND && mons_friendly( &menv[targ_mon] ))
- || (mode == TARG_ENEMY
- && !mons_friendly( &menv[targ_mon] )
- &&
- (Options.target_zero_exp ||
- !mons_class_flag( menv[targ_mon].type, M_NO_EXP_GAIN )) )));
-}
-
-static bool find_feature( int x, int y, int mode )
-{
- // The stair need not be in LOS if the square is mapped.
- if (!in_los(x, y) && (!Options.target_oos || !is_mapped(x, y)))
- return (false);
-
- return is_feature(mode, x, y);
-}
-
-static bool find_object(int x, int y, int mode)
-{
- const int item = igrd[x][y];
- // The square need not be in LOS if the stash tracker knows this item.
- return (item != NON_ITEM
- && (in_los(x, y)
-#ifdef STASH_TRACKING
- || (Options.target_oos && is_mapped(x, y) && is_stash(x, y))
-#endif
- ));
-}
-
-static int next_los(int dir, int los, bool wrap)
-{
- if (los == LOS_ANY)
- return (wrap? los : LOS_NONE);
-
- bool vis = los & LOS_VISIBLE;
- bool hidden = los & LOS_HIDDEN;
- bool flipvh = los & LOS_FLIPVH;
- bool fliphv = los & LOS_FLIPHV;
-
- if (!vis && !hidden)
- vis = true;
-
- if (wrap)
- {
- if (!flipvh && !fliphv)
- return (los);
-
- // We have to invert flipvh and fliphv if we're wrapping. Here's
- // why:
- //
- // * Say the cursor is on the last item in LOS, there are no
- // items outside LOS, and wrap == true. flipvh is true.
- // * We set wrap false and flip from visible to hidden, but there
- // are no hidden items. So now we need to flip back to visible
- // so we can go back to the first item in LOS. Unless we set
- // fliphv, we can't flip from hidden to visible.
- //
- los = flipvh? LOS_FLIPHV : LOS_FLIPVH;
- }
- else
- {
- if (!flipvh && !fliphv)
- return (LOS_NONE);
-
- if (flipvh && vis != (dir == 1))
- return (LOS_NONE);
-
- if (fliphv && vis == (dir == 1))
- return (LOS_NONE);
- }
-
- los = (los & ~LOS_VISMASK) | (vis? LOS_HIDDEN : LOS_VISIBLE);
- return (los);
-}
-
-bool in_viewport_bounds(int x, int y)
-{
- return (x >= VIEW_SX && x <= VIEW_EX && y >= VIEW_SY && y <= VIEW_EY);
-}
-
-bool in_los_bounds(int x, int y)
-{
- return !(x > LOS_EX || x < LOS_SX || y > LOS_EY || y < LOS_SY);
-}
-
-//---------------------------------------------------------------
-//
-// find_square
-//
-// Finds the next monster/object/whatever (moving in a spiral
-// outwards from the player, so closer targets are chosen first;
-// starts to player's left) and puts its coordinates in mfp.
-// Returns 1 if it found something, zero otherwise. If direction
-// is -1, goes backwards.
-//
-// If the game option target_zero_exp is true, zero experience
-// monsters will be targeted.
-//
-//---------------------------------------------------------------
-static char find_square( unsigned char xps, unsigned char yps,
- FixedVector<char, 2> &mfp, char direction,
- bool (*find_targ)( int x, int y, int mode ),
- int mode, bool wrap, int los )
-{
- int temp_xps = xps;
- int temp_yps = yps;
- char x_change = 0;
- char y_change = 0;
-
- bool onlyVis = false, onlyHidden = false;
-
- int i, j;
-
- if (los == LOS_NONE)
- return (0);
-
- if (los == LOS_FLIPVH || los == LOS_FLIPHV)
- {
- if (in_los_bounds(xps, yps))
- {
- // We've been told to flip between visible/hidden, so we
- // need to find what we're currently on.
- bool vis = (env.show[xps - 8][yps]
- || (xps == VIEW_CX && yps == VIEW_CY));
-
- if (wrap && (vis != (los == LOS_FLIPVH)) == (direction == 1))
- {
- // We've already flipped over into the other direction,
- // so correct the flip direction if we're wrapping.
- los = los == LOS_FLIPHV? LOS_FLIPVH : LOS_FLIPHV;
- }
-
- los = (los & ~LOS_VISMASK) | (vis? LOS_VISIBLE : LOS_HIDDEN);
- }
- else
- {
- if (wrap)
- los = LOS_HIDDEN | (direction == 1? LOS_FLIPHV : LOS_FLIPVH);
- else
- los |= LOS_HIDDEN;
- }
- }
-
- onlyVis = (los & LOS_VISIBLE);
- onlyHidden = (los & LOS_HIDDEN);
-
- const int minx = VIEW_SX, maxx = VIEW_EX,
- miny = VIEW_SY - VIEW_Y_DIFF, maxy = VIEW_EY + VIEW_Y_DIFF,
- ctrx = VIEW_CX, ctry = VIEW_CY;
-
- while (temp_xps >= minx - 1 && temp_xps <= maxx
- && temp_yps <= maxy && temp_yps >= miny - 1)
- {
- if (direction == 1 && temp_xps == minx && temp_yps == maxy)
- {
- return find_square(ctrx, ctry, mfp, direction, find_targ, mode,
- false, next_los(direction, los, wrap));
- }
- if (direction == -1 && temp_xps == ctrx && temp_yps == ctry)
- {
- return find_square(minx, maxy, mfp, direction, find_targ, mode,
- false, next_los(direction, los, wrap));
- }
-
- if (direction == 1)
- {
- if (temp_xps == minx - 1)
- {
- x_change = 0;
- y_change = -1;
- }
- else if (temp_xps == ctrx && temp_yps == ctry)
- {
- x_change = -1;
- y_change = 0;
- }
- else if (abs(temp_xps - ctrx) <= abs(temp_yps - ctry))
- {
- if (temp_xps - ctrx >= 0 && temp_yps - ctry <= 0)
- {
- if (abs(temp_xps - ctrx) > abs(temp_yps - ctry + 1))
- {
- x_change = 0;
- y_change = -1;
- if (temp_xps - ctrx > 0)
- y_change = 1;
- goto finished_spiralling;
- }
- }
- x_change = -1;
- if (temp_yps - ctry < 0)
- x_change = 1;
- y_change = 0;
- }
- else
- {
- x_change = 0;
- y_change = -1;
- if (temp_xps - ctrx > 0)
- y_change = 1;
- }
- } // end if (direction == 1)
- else
- {
- /*
- This part checks all eight surrounding squares to find the
- one that leads on to the present square.
- */
- for (i = -1; i < 2; i++)
- {
- for (j = -1; j < 2; j++)
- {
- if (i == 0 && j == 0)
- continue;
-
- if (temp_xps + i == minx - 1)
- {
- x_change = 0;
- y_change = -1;
- }
- else if (temp_xps + i - ctrx == 0 && temp_yps + j - ctry == 0)
- {
- x_change = -1;
- y_change = 0;
- }
- else if (abs(temp_xps + i - ctrx) <= abs(temp_yps + j - ctry))
- {
- const int xi = temp_xps + i - ctrx;
- const int yj = temp_yps + j - ctry;
-
- if (xi >= 0 && yj <= 0)
- {
- if (abs(xi) > abs(yj + 1))
- {
- x_change = 0;
- y_change = -1;
- if (xi > 0)
- y_change = 1;
- goto finished_spiralling;
- }
- }
-
- x_change = -1;
- if (yj < 0)
- x_change = 1;
- y_change = 0;
- }
- else
- {
- x_change = 0;
- y_change = -1;
- if (temp_xps + i - ctrx > 0)
- y_change = 1;
- }
-
- if (temp_xps + i + x_change == temp_xps
- && temp_yps + j + y_change == temp_yps)
- {
- goto finished_spiralling;
- }
- }
- }
- } // end else
-
-
- finished_spiralling:
- x_change *= direction;
- y_change *= direction;
-
- temp_xps += x_change;
- if (temp_yps + y_change <= maxy) // it can wrap, unfortunately
- temp_yps += y_change;
-
- const int targ_x = you.x_pos + temp_xps - ctrx;
- const int targ_y = you.y_pos + temp_yps - ctry;
-
- // We don't want to be looking outside the bounds of the arrays:
- //if (!in_los_bounds(temp_xps, temp_yps))
- // continue;
-
- if (temp_xps < minx - 1 || temp_xps > maxx
- || temp_yps < VIEW_SY || temp_yps > VIEW_EY)
- continue;
-
- if (targ_x < 1 || targ_x >= GXM || targ_y < 1 || targ_y >= GYM)
- continue;
-
- if ((onlyVis || onlyHidden) && onlyVis != in_los(targ_x, targ_y))
- continue;
-
- if (find_targ(targ_x, targ_y, mode)) {
- mfp[0] = temp_xps;
- mfp[1] = temp_yps;
- return (1);
- }
- }
-
- return (direction == 1?
- find_square(ctrx, ctry, mfp, direction, find_targ, mode, false,
- next_los(direction, los, wrap))
- : find_square(minx, maxy, mfp, direction, find_targ, mode, false,
- next_los(direction, los, wrap)));
-}
-
-static bool is_shopstair(int x, int y)
-{
- return (is_stair(grd[x][y]) || grd[x][y] == DNGN_ENTER_SHOP);
-}
-
-extern unsigned char (*mapch2) (unsigned char);
-static bool is_full_mapped(int x, int y)
-{
- unsigned grid = grd[x][y];
- int envch = env.map[x - 1][y - 1];
- return (envch && envch == mapch2(grid));
-}
-
-static int surround_nonshopstair_count(int x, int y)
-{
- int count = 0;
- for (int ix = -1; ix < 2; ++ix)
- {
- for (int iy = -1; iy < 2; ++iy)
- {
- int nx = x + ix, ny = y + iy;
- if (nx <= 0 || nx >= GXM || ny <= 0 || ny >= GYM)
- continue;
- if (is_full_mapped(nx, ny) && !is_shopstair(nx, ny))
- count++;
- }
- }
- return (count);
-}
-
-// For want of a better name...
-static bool clear_mapped(int x, int y)
-{
- if (!is_full_mapped(x, y))
- return (false);
-
- if (is_shopstair(x, y))
- return (surround_nonshopstair_count(x, y) > 0);
-
- return (true);
-}
-
-static void describe_feature(int mx, int my, bool oos)
-{
- if (oos && !clear_mapped(mx, my))
- return;
-
- unsigned oldfeat = grd[mx][my];
- if (oos && env.map[mx - 1][my - 1] == mapch2(DNGN_SECRET_DOOR))
- grd[mx][my] = DNGN_ROCK_WALL;
-
- std::string desc = feature_description(mx, my);
-
- grd[mx][my] = oldfeat;
-
- if (desc.length())
- {
- if (oos)
- desc = "[" + desc + "]";
- mpr(desc.c_str());
- }
-}
-
-std::string feature_description(int mx, int my)
-{
- int trf; // used for trap type??
- switch (grd[mx][my])
- {
- case DNGN_STONE_WALL:
- return ("A stone wall.");
- case DNGN_ROCK_WALL:
- case DNGN_SECRET_DOOR:
- if (you.level_type == LEVEL_PANDEMONIUM)
- return ("A wall of the weird stuff which makes up Pandemonium.");
- else
- return ("A rock wall.");
- case DNGN_PERMAROCK_WALL:
- return ("An unnaturally hard rock wall.");
- case DNGN_CLOSED_DOOR:
- return ("A closed door.");
- case DNGN_METAL_WALL:
- return ("A metal wall.");
- case DNGN_GREEN_CRYSTAL_WALL:
- return ("A wall of green crystal.");
- case DNGN_ORCISH_IDOL:
- return ("An orcish idol.");
- case DNGN_WAX_WALL:
- return ("A wall of solid wax.");
- case DNGN_SILVER_STATUE:
- return ("A silver statue.");
- case DNGN_GRANITE_STATUE:
- return ("A granite statue.");
- case DNGN_ORANGE_CRYSTAL_STATUE:
- return ("An orange crystal statue.");
- case DNGN_LAVA:
- return ("Some lava.");
- case DNGN_DEEP_WATER:
- return ("Some deep water.");
- case DNGN_SHALLOW_WATER:
- return ("Some shallow water.");
- case DNGN_UNDISCOVERED_TRAP:
- case DNGN_FLOOR:
- return ("Floor.");
- case DNGN_OPEN_DOOR:
- return ("An open door.");
- case DNGN_ROCK_STAIRS_DOWN:
- return ("A rock staircase leading down.");
- case DNGN_STONE_STAIRS_DOWN_I:
- case DNGN_STONE_STAIRS_DOWN_II:
- case DNGN_STONE_STAIRS_DOWN_III:
- return ("A stone staircase leading down.");
- case DNGN_ROCK_STAIRS_UP:
- return ("A rock staircase leading upwards.");
- case DNGN_STONE_STAIRS_UP_I:
- case DNGN_STONE_STAIRS_UP_II:
- case DNGN_STONE_STAIRS_UP_III:
- return ("A stone staircase leading up.");
- case DNGN_ENTER_HELL:
- return ("A gateway to hell.");
- case DNGN_TRAP_MECHANICAL:
- case DNGN_TRAP_MAGICAL:
- case DNGN_TRAP_III:
- for (trf = 0; trf < MAX_TRAPS; trf++)
- {
- if (env.trap[trf].x == mx
- && env.trap[trf].y == my)
- {
- break;
- }
-
- if (trf == MAX_TRAPS - 1)
- {
- mpr("Error - couldn't find that trap.");
- error_message_to_player();
- break;
- }
- }
-
- switch (env.trap[trf].type)
- {
- case TRAP_DART:
- return ("A dart trap.");
- case TRAP_ARROW:
- return ("An arrow trap.");
- case TRAP_SPEAR:
- return ("A spear trap.");
- case TRAP_AXE:
- return ("An axe trap.");
- case TRAP_TELEPORT:
- return ("A teleportation trap.");
- case TRAP_AMNESIA:
- return ("An amnesia trap.");
- case TRAP_BLADE:
- return ("A blade trap.");
- case TRAP_BOLT:
- return ("A bolt trap.");
- case TRAP_ZOT:
- return ("A Zot trap.");
- case TRAP_NEEDLE:
- return ("A needle trap.");
- default:
- mpr("An undefined trap. Huh?");
- error_message_to_player();
- break;
- }
- break;
- case DNGN_ENTER_SHOP:
- return (shop_name(mx, my));
- case DNGN_ENTER_LABYRINTH:
- return ("A labyrinth entrance.");
- case DNGN_ENTER_DIS:
- return ("A gateway to the Iron City of Dis.");
- case DNGN_ENTER_GEHENNA:
- return ("A gateway to Gehenna.");
- case DNGN_ENTER_COCYTUS:
- return ("A gateway to the freezing wastes of Cocytus.");
- case DNGN_ENTER_TARTARUS:
- return ("A gateway to the decaying netherworld of Tartarus.");
- case DNGN_ENTER_ABYSS:
- return ("A gateway to the infinite Abyss.");
- case DNGN_EXIT_ABYSS:
- return ("A gateway leading out of the Abyss.");
- case DNGN_STONE_ARCH:
- return ("An empty arch of ancient stone.");
- case DNGN_ENTER_PANDEMONIUM:
- return ("A gate leading to the halls of Pandemonium.");
- case DNGN_EXIT_PANDEMONIUM:
- return ("A gate leading out of Pandemonium.");
- case DNGN_TRANSIT_PANDEMONIUM:
- return ("A gate leading to another region of Pandemonium.");
- case DNGN_ENTER_ORCISH_MINES:
- return ("A staircase to the Orcish Mines.");
- case DNGN_ENTER_HIVE:
- return ("A staircase to the Hive.");
- case DNGN_ENTER_LAIR:
- return ("A staircase to the Lair.");
- case DNGN_ENTER_SLIME_PITS:
- return ("A staircase to the Slime Pits.");
- case DNGN_ENTER_VAULTS:
- return ("A staircase to the Vaults.");
- case DNGN_ENTER_CRYPT:
- return ("A staircase to the Crypt.");
- case DNGN_ENTER_HALL_OF_BLADES:
- return ("A staircase to the Hall of Blades.");
- case DNGN_ENTER_ZOT:
- return ("A gate to the Realm of Zot.");
- case DNGN_ENTER_TEMPLE:
- return ("A staircase to the Ecumenical Temple.");
- case DNGN_ENTER_SNAKE_PIT:
- return ("A staircase to the Snake Pit.");
- case DNGN_ENTER_ELVEN_HALLS:
- return ("A staircase to the Elven Halls.");
- case DNGN_ENTER_TOMB:
- return ("A staircase to the Tomb.");
- case DNGN_ENTER_SWAMP:
- return ("A staircase to the Swamp.");
- case DNGN_RETURN_FROM_ORCISH_MINES:
- case DNGN_RETURN_FROM_HIVE:
- case DNGN_RETURN_FROM_LAIR:
- case DNGN_RETURN_FROM_VAULTS:
- case DNGN_RETURN_FROM_TEMPLE:
- return ("A staircase back to the Dungeon.");
- case DNGN_RETURN_FROM_SLIME_PITS:
- case DNGN_RETURN_FROM_SNAKE_PIT:
- case DNGN_RETURN_FROM_SWAMP:
- return ("A staircase back to the Lair.");
- case DNGN_RETURN_FROM_CRYPT:
- case DNGN_RETURN_FROM_HALL_OF_BLADES:
- return ("A staircase back to the Vaults.");
- case DNGN_RETURN_FROM_ELVEN_HALLS:
- return ("A staircase back to the Mines.");
- case DNGN_RETURN_FROM_TOMB:
- return ("A staircase back to the Crypt.");
- case DNGN_RETURN_FROM_ZOT:
- return ("A gate leading back out of this place.");
- case DNGN_ALTAR_ZIN:
- return ("A glowing white marble altar of Zin.");
- case DNGN_ALTAR_SHINING_ONE:
- return ("A glowing golden altar of the Shining One.");
- case DNGN_ALTAR_KIKUBAAQUDGHA:
- return ("An ancient bone altar of Kikubaaqudgha.");
- case DNGN_ALTAR_YREDELEMNUL:
- return ("A basalt altar of Yredelemnul.");
- case DNGN_ALTAR_XOM:
- return ("A shimmering altar of Xom.");
- case DNGN_ALTAR_VEHUMET:
- return ("A shining altar of Vehumet.");
- case DNGN_ALTAR_OKAWARU:
- return ("An iron altar of Okawaru.");
- case DNGN_ALTAR_MAKHLEB:
- return ("A burning altar of Makhleb.");
- case DNGN_ALTAR_SIF_MUNA:
- return ("A deep blue altar of Sif Muna.");
- case DNGN_ALTAR_TROG:
- return ("A bloodstained altar of Trog.");
- case DNGN_ALTAR_NEMELEX_XOBEH:
- return ("A sparkling altar of Nemelex Xobeh.");
- case DNGN_ALTAR_ELYVILON:
- return ("A silver altar of Elyvilon.");
- case DNGN_BLUE_FOUNTAIN:
- return ("A fountain of clear blue water.");
- case DNGN_SPARKLING_FOUNTAIN:
- return ("A fountain of sparkling water.");
- case DNGN_DRY_FOUNTAIN_I:
- case DNGN_DRY_FOUNTAIN_II:
- case DNGN_DRY_FOUNTAIN_IV:
- case DNGN_DRY_FOUNTAIN_VI:
- case DNGN_DRY_FOUNTAIN_VIII:
- case DNGN_PERMADRY_FOUNTAIN:
- return ("A dry fountain.");
- }
- return ("");
-}
-
-static void describe_cell(int mx, int my)
-{
- char str_pass[ ITEMNAME_SIZE ];
- bool mimic_item = false;
-
- if (mgrd[mx][my] != NON_MONSTER)
- {
- int i = mgrd[mx][my];
-
- if (grd[mx][my] == DNGN_SHALLOW_WATER)
- {
- if (!player_monster_visible(&menv[i]) && !mons_flies(&menv[i]))
- {
- mpr("There is a strange disturbance in the water here.");
- }
- }
-
-#if DEBUG_DIAGNOSTICS
- if (!player_monster_visible( &menv[i] ))
- mpr( "There is a non-visible monster here.", MSGCH_DIAGNOSTICS );
-#else
- if (!player_monster_visible( &menv[i] ))
- goto look_clouds;
-#endif
-
- const int mon_wep = menv[i].inv[MSLOT_WEAPON];
- const int mon_arm = menv[i].inv[MSLOT_ARMOUR];
-
- strcpy(info, ptr_monam( &(menv[i]), DESC_CAP_A ));
- strcat(info, ".");
- mpr(info);
-
- if (menv[i].type != MONS_DANCING_WEAPON && mon_wep != NON_ITEM)
- {
- snprintf( info, INFO_SIZE, "%s is wielding ", mons_pronoun( menv[i].type,
- PRONOUN_CAP ));
- it_name(mon_wep, DESC_NOCAP_A, str_pass);
- strcat(info, str_pass);
-
- // 2-headed ogres can wield 2 weapons
- if ((menv[i].type == MONS_TWO_HEADED_OGRE
- || menv[i].type == MONS_ETTIN)
- && menv[i].inv[MSLOT_MISSILE] != NON_ITEM)
- {
- strcat( info, " and " );
- it_name(menv[i].inv[MSLOT_MISSILE], DESC_NOCAP_A, str_pass);
- strcat(info, str_pass);
- strcat(info, ".");
-
- mpr(info);
- }
- else
- {
- strcat(info, ".");
- mpr(info);
- }
- }
-
- if (mon_arm != NON_ITEM)
- {
- it_name( mon_arm, DESC_NOCAP_A, str_pass );
- snprintf( info, INFO_SIZE, "%s is wearing %s.",
- mons_pronoun( menv[i].type, PRONOUN_CAP ),
- str_pass );
-
- mpr( info );
- }
-
-
- if (menv[i].type == MONS_HYDRA)
- {
- snprintf( info, INFO_SIZE, "It has %d head%s.",
- menv[i].number, (menv[i].number > 1? "s" : "") );
- mpr( info );
- }
-
- print_wounds(&menv[i]);
-
-
- if (mons_is_mimic( menv[i].type ))
- mimic_item = true;
- else if (!mons_class_flag(menv[i].type, M_NO_EXP_GAIN))
- {
- if (menv[i].behaviour == BEH_SLEEP)
- {
- strcpy(info, mons_pronoun(menv[i].type, PRONOUN_CAP));
- strcat(info, " doesn't appear to have noticed you.");
- mpr(info);
- }
- // Applies to both friendlies and hostiles
- else if (menv[i].behaviour == BEH_FLEE)
- {
- strcpy(info, mons_pronoun(menv[i].type, PRONOUN_CAP));
- strcat(info, " is fleeing in terror.");
- mpr(info);
- }
- // hostile with target != you
- else if (!mons_friendly(&menv[i]) && menv[i].foe != MHITYOU)
- {
- // special case: batty monsters get set to BEH_WANDER as
- // part of their special behaviour.
- if (!testbits(menv[i].flags, MF_BATTY))
- {
- strcpy(info, mons_pronoun(menv[i].type, PRONOUN_CAP));
- strcat(info, " doesn't appear to be interested in you.");
- mpr(info);
- }
- }
- }
-
- if (menv[i].attitude == ATT_FRIENDLY)
- {
- strcpy(info, mons_pronoun(menv[i].type, PRONOUN_CAP));
- strcat(info, " is friendly.");
- mpr(info);
- }
-
- for (int p = 0; p < NUM_MON_ENCHANTS; p++)
- {
- strcpy(info, mons_pronoun(menv[i].type, PRONOUN_CAP));
- switch (menv[i].enchantment[p])
- {
- case ENCH_YOUR_ROT_I:
- case ENCH_YOUR_ROT_II:
- case ENCH_YOUR_ROT_III:
- case ENCH_YOUR_ROT_IV:
- strcat(info, " is rotting away."); //jmf: "covered in sores"?
- break;
- case ENCH_BACKLIGHT_I:
- case ENCH_BACKLIGHT_II:
- case ENCH_BACKLIGHT_III:
- case ENCH_BACKLIGHT_IV:
- strcat(info, " is softly glowing.");
- break;
- case ENCH_SLOW:
- strcat(info, " is moving slowly.");
- break;
- case ENCH_HASTE:
- strcat(info, " is moving very quickly.");
- break;
- case ENCH_CONFUSION:
- strcat(info, " appears to be bewildered and confused.");
- break;
- case ENCH_INVIS:
- strcat(info, " is slightly transparent.");
- break;
- case ENCH_CHARM:
- strcat(info, " is in your thrall.");
- break;
- case ENCH_YOUR_STICKY_FLAME_I:
- case ENCH_YOUR_STICKY_FLAME_II:
- case ENCH_YOUR_STICKY_FLAME_III:
- case ENCH_YOUR_STICKY_FLAME_IV:
- case ENCH_STICKY_FLAME_I:
- case ENCH_STICKY_FLAME_II:
- case ENCH_STICKY_FLAME_III:
- case ENCH_STICKY_FLAME_IV:
- strcat(info, " is covered in liquid flames.");
- break;
- default:
- info[0] = '\0';
- break;
- } // end switch
- if (info[0])
- mpr(info);
- }
-
-#if DEBUG_DIAGNOSTICS
- stethoscope(i);
-#endif
- }
-
-#if (!DEBUG_DIAGNOSTICS)
- // removing warning
- look_clouds:
-#endif
- if (env.cgrid[mx][my] != EMPTY_CLOUD)
- {
- const char cloud_inspected = env.cgrid[mx][my];
-
- const char cloud_type = env.cloud[ cloud_inspected ].type;
-
- strcpy(info, "There is a cloud of ");
- strcat(info,
- (cloud_type == CLOUD_FIRE
- || cloud_type == CLOUD_FIRE_MON) ? "flame" :
- (cloud_type == CLOUD_STINK
- || cloud_type == CLOUD_STINK_MON) ? "noxious fumes" :
- (cloud_type == CLOUD_COLD
- || cloud_type == CLOUD_COLD_MON) ? "freezing vapour" :
- (cloud_type == CLOUD_POISON
- || cloud_type == CLOUD_POISON_MON) ? "poison gases" :
- (cloud_type == CLOUD_GREY_SMOKE
- || cloud_type == CLOUD_GREY_SMOKE_MON) ? "grey smoke" :
- (cloud_type == CLOUD_BLUE_SMOKE
- || cloud_type == CLOUD_BLUE_SMOKE_MON) ? "blue smoke" :
- (cloud_type == CLOUD_PURP_SMOKE
- || cloud_type == CLOUD_PURP_SMOKE_MON) ? "purple smoke" :
- (cloud_type == CLOUD_STEAM
- || cloud_type == CLOUD_STEAM_MON) ? "steam" :
- (cloud_type == CLOUD_MIASMA
- || cloud_type == CLOUD_MIASMA_MON) ? "foul pestilence" :
- (cloud_type == CLOUD_BLACK_SMOKE
- || cloud_type == CLOUD_BLACK_SMOKE_MON) ? "black smoke"
- : "buggy goodness");
- strcat(info, " here.");
- mpr(info);
- }
-
- int targ_item = igrd[ mx ][ my ];
-
- if (targ_item != NON_ITEM)
- {
- // If a mimic is on this square, we pretend its the first item -- bwr
- if (mimic_item)
- mpr("There is something else lying underneath.");
- else
- {
- if (mitm[ targ_item ].base_type == OBJ_GOLD)
- {
- mpr( "A pile of gold coins." );
- }
- else
- {
- strcpy(info, "You see ");
- it_name( targ_item, DESC_NOCAP_A, str_pass);
- strcat(info, str_pass);
- strcat(info, " here.");
- mpr(info);
- }
-
- if (mitm[ targ_item ].link != NON_ITEM)
- mpr("There is something else lying underneath.");
- }
- }
-
- std::string feature_desc = feature_description(mx, my);
- mpr(feature_desc.c_str());
-}
diff --git a/stone_soup/crawl-ref/source/direct.h b/stone_soup/crawl-ref/source/direct.h
deleted file mode 100644
index d3aec5816a..0000000000
--- a/stone_soup/crawl-ref/source/direct.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * File: direct.cc
- * Summary: Functions used when picking squares.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef DIRECT_H
-#define DIRECT_H
-
-#include "externs.h"
-#include "enum.h"
-
-#define STD_DIRECTION_PROMPT "Which direction ([*+-] to target)? "
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - debug - effects - it_use3 - item_use - spells1 -
- * spells2 - spells3 - spells4
- * *********************************************************************** */
-
-#define DIR_NONE 0
-#define DIR_TARGET 1
-#define DIR_DIR 2
-
-void direction( struct dist &moves, int restricts = DIR_NONE,
- int mode = TARG_ANY );
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - direct
- * *********************************************************************** */
-void look_around( struct dist &moves, bool justLooking, int first_move = -1,
- int mode = TARG_ANY );
-
-bool in_los_bounds(int x, int y);
-bool in_viewport_bounds(int x, int y);
-bool in_los(int x, int y);
-bool in_vlos(int x, int y);
-
-std::string feature_description(int mx, int my);
-
-inline int view2gridX(int vx)
-{
- return (you.x_pos + vx - VIEW_CX);
-}
-
-inline int view2gridY(int vy)
-{
- return (you.y_pos + vy - VIEW_CY);
-}
-
-inline int grid2viewX(int gx)
-{
- return (gx - you.x_pos + VIEW_CX);
-}
-
-inline int grid2viewY(int gy)
-{
- return (gy - you.y_pos + VIEW_CY);
-}
-
-#endif
diff --git a/stone_soup/crawl-ref/source/dungeon.cc b/stone_soup/crawl-ref/source/dungeon.cc
deleted file mode 100644
index 2c38be36da..0000000000
--- a/stone_soup/crawl-ref/source/dungeon.cc
+++ /dev/null
@@ -1,8641 +0,0 @@
-/*
- * File: dungeon.cc
- * Summary: Functions used when building new levels.
- * Written by: Linley Henzell
- *
- * Modified for Crawl Reference by $Author$ on $Date$
- *
- * Change History (most recent first):
- *
- *
- * <9> 07-Aug-2001 MV clean up of give_item; distribution of
- * wands, potions and scrolls
- * underground rivers and lakes
- * <8> 02-Apr-2001 gdl cleanup; nuked all globals
- * <7> 06-Mar-2000 bwr reduced vorpal weapon freq,
- * spellbooks now hold up to eight spells.
- * <6> 11/06/99 cdl random3 -> random2
- * <5> 8/08/99 BWR Upped rarity of unique artefacts
- * <4> 7/13/99 BWR Made pole arms of speed.
- * <3> 5/22/99 BWR Made named artefact weapons
- * rarer, Sword of Power esp.
- * <2> 5/09/99 LRH Replaced some sanity checking code in
- * spellbook_template with a corrected version
- * using ASSERTs.
- * <1> -/--/-- LRH Created
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <time.h>
-
-#include "AppHdr.h"
-#include "abyss.h"
-#include "defines.h"
-#include "enum.h"
-#include "externs.h"
-#include "dungeon.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "items.h"
-#include "maps.h"
-#include "misc.h"
-#include "mon-util.h"
-#include "mon-pick.h"
-#include "monplace.h"
-#include "player.h"
-#include "randart.h"
-#include "spl-book.h"
-#include "stuff.h"
-#include "wpn-misc.h"
-
-#define MAX_PIT_MONSTERS 10
-
-struct pit_mons_def {
- int type;
- int rare;
-};
-
-struct spec_t {
- bool created;
- bool hooked_up;
- int x1;
- int y1;
- int x2;
- int y2;
-};
-
-typedef struct spec_t spec_room;
-
-// DUNGEON BUILDERS
-static bool find_in_area(int sx, int sy, int ex, int ey, unsigned char feature);
-static bool make_box(int room_x1, int room_y1, int room_x2, int room_y2,
- unsigned char floor=0, unsigned char wall=0, unsigned char avoid=0);
-static void replace_area(int sx, int sy, int ex, int ey, unsigned char replace,
- unsigned char feature);
-static int builder_by_type(int level_number, char level_type);
-static int builder_by_branch(int level_number);
-static int builder_normal(int level_number, char level_type, spec_room &s);
-static int builder_basic(int level_number);
-static void builder_extras(int level_number, int level_type);
-static void builder_items(int level_number, char level_type, int items_wanted);
-static void builder_monsters(int level_number, char level_type, int mon_wanted);
-static void place_specific_stair(unsigned char stair);
-static void place_branch_entrances(int dlevel, char level_type);
-static bool place_specific_trap(unsigned char spec_x, unsigned char spec_y,
- unsigned char spec_type);
-static void place_traps( int level_number );
-static void prepare_swamp(void);
-static void prepare_water( int level_number );
-static void check_doors(void);
-static void hide_doors(void);
-static void make_trail(int xs, int xr, int ys, int yr,int corrlength, int intersect_chance,
- int no_corr, unsigned char begin, unsigned char end=0);
-static bool make_room(int sx,int sy,int ex,int ey,int max_doors, int doorlevel);
-static void join_the_dots(unsigned char dotx1, unsigned char doty1,
- unsigned char dotx2, unsigned char doty2, char forbid_x1, char forbid_y1,
- char forbid_x2, char forbid_y2);
-static void place_pool(unsigned char pool_type, unsigned char pool_x1,
- unsigned char pool_y1, unsigned char pool_x2,
- unsigned char pool_y2);
-static void many_pools(unsigned char pool_type);
-
-#ifdef USE_RIVERS
-static void build_river(unsigned char river_type); //mv
-static void build_lake(unsigned char lake_type); //mv
-#endif // USE_RIVERS
-
-static void spotty_level(bool seeded, int iterations, bool boxy);
-static void bigger_room(void);
-static void plan_main(int level_number, char force_plan);
-static char plan_1(void);
-static char plan_2(void);
-static char plan_3(void);
-static char plan_4(char forbid_x1, char forbid_y1, char forbid_x2,
- char forbid_y2, unsigned char force_wall);
-static char plan_5(void);
-static char plan_6(int level_number);
-static bool octa_room(spec_room &sr, int oblique_max, unsigned char type_floor);
-static void labyrinth_level(int level_number);
-static void box_room(int bx1, int bx2, int by1, int by2, int wall_type);
-static int box_room_doors( int bx1, int bx2, int by1, int by2, int new_doors);
-static void city_level(int level_number);
-static void diamond_rooms(int level_number);
-
-// ITEM & SHOP FUNCTIONS
-static void place_shops(int level_number);
-static void place_spec_shop(int level_number, unsigned char shop_x,
- unsigned char shop_y, unsigned char force_s_type);
-static unsigned char item_in_shop(unsigned char shop_type);
-static bool treasure_area(int level_number, unsigned char ta1_x,
- unsigned char ta2_x, unsigned char ta1_y,
- unsigned char ta2_y);
-static int rare_weapon(int w_type);
-static bool is_weapon_special(int the_weapon);
-static void set_weapon_special(int the_weapon, int spwpn);
-static void big_room(int level_number);
-static void chequerboard(spec_room &sr, unsigned char
- target, unsigned char floor1, unsigned char floor2);
-static void roguey_level(int level_number, spec_room &sr);
-static void morgue(spec_room &sr);
-
-// SPECIAL ROOM BUILDERS
-static void special_room(int level_number, spec_room &sr);
-static void specr_2(spec_room &sr);
-static void beehive(spec_room &sr);
-static void jelly_pit(int level_number, spec_room &sr);
-
-// VAULT FUNCTIONS
-static void build_vaults(int level_number, int force_vault);
-static void build_minivaults(int level_number, int force_vault);
-static int vault_grid( int level_number, int vx, int vy, int altar_count,
- FixedVector < char, 7 > &acq_item_class,
- FixedVector < int, 7 > &mons_array,
- char vgrid, int &initial_x, int &initial_y,
- int force_vault, int &num_runes );
-
-// ALTAR FUNCTIONS
-static int pick_an_altar(void);
-static void place_altar(void);
-
-static bool got_curare_roll(const int item_level)
-{
- return one_chance_in(item_level > 27? 6 :
- item_level < 2 ? 15 :
- (364 - 7 * item_level) / 25);
-}
-
-/*
- **************************************************
- * *
- * BEGIN PUBLIC FUNCTIONS *
- * *
- **************************************************
-*/
-
-// Determines if this feature blocks movement.
-bool feat_blocks_movement(int feature)
-{
- return (feature == DNGN_ROCK_WALL ||
- feature == DNGN_STONE_WALL ||
- feature == DNGN_METAL_WALL ||
- feature == DNGN_SECRET_DOOR ||
- feature == DNGN_GREEN_CRYSTAL_WALL ||
- feature == DNGN_ORCISH_IDOL ||
- feature == DNGN_WAX_WALL ||
- feature == DNGN_PERMAROCK_WALL ||
- feature == DNGN_SILVER_STATUE ||
- feature == DNGN_GRANITE_STATUE ||
- feature == DNGN_ORANGE_CRYSTAL_STATUE);
-}
-
-void builder(int level_number, char level_type)
-{
- int i; // generic loop variable
- int x,y; // generic map loop variables
-
- // srandom(time(NULL));
-
- // blank level with DNGN_ROCK_WALL
- make_box(0,0,GXM-1,GYM-1,DNGN_ROCK_WALL,DNGN_ROCK_WALL);
-
- // delete all traps
- for (i = 0; i < MAX_TRAPS; i++)
- env.trap[i].type = TRAP_UNASSIGNED;
-
- // initialize all items
- for (i = 0; i < MAX_ITEMS; i++)
- init_item( i );
-
- // reset all monsters
- for (i = 0; i < MAX_MONSTERS; i++)
- menv[i].type = -1;
-
- // unlink all monsters and items from the grid
- for(x=0; x<GXM; x++)
- {
- for(y=0; y<GYM; y++)
- {
- mgrd[x][y] = NON_MONSTER;
- igrd[x][y] = NON_ITEM;
- }
- }
-
- // reset all shops
- for (unsigned char shcount = 0; shcount < 5; shcount++)
- {
- env.shop[shcount].type = SHOP_UNASSIGNED;
- }
-
- int skip_build;
-
- skip_build = builder_by_type(level_number, level_type);
- if (skip_build < 0)
- return;
-
- if (skip_build == 0)
- {
- skip_build = builder_by_branch(level_number);
-
- if (skip_build < 0)
- return;
- }
-
- spec_room sr = { false, false, 0, 0, 0, 0 };
-
- if (skip_build == 0)
- {
- // do 'normal' building. Well, except for the swamp.
- if (!player_in_branch( BRANCH_SWAMP ))
- skip_build = builder_normal(level_number, level_type, sr);
-
- if (skip_build == 0)
- {
- skip_build = builder_basic(level_number);
- if (skip_build == 0)
- builder_extras(level_number, level_type);
- }
- }
-
- // hook up the special room (if there is one, and it hasn't
- // been hooked up already in roguey_level()
- if (sr.created && !sr.hooked_up)
- specr_2(sr);
-
- // now place items, monster, gates, etc.
- // stairs must exist by this point. Some items and monsters
- // already exist.
-
- // time to make the swamp {dlb}:
- if (player_in_branch( BRANCH_SWAMP ))
- prepare_swamp();
-
- // figure out how many 'normal' monsters we should place
- int mon_wanted = 0;
- if (level_type == LEVEL_ABYSS
- || player_in_branch( BRANCH_ECUMENICAL_TEMPLE ))
- {
- mon_wanted = 0;
- }
- else
- {
- mon_wanted = roll_dice( 3, 10 );
-
- if (player_in_hell())
- mon_wanted += roll_dice( 3, 8 );
- else if (player_in_branch( BRANCH_HALL_OF_BLADES ))
- mon_wanted += roll_dice( 6, 8 );
-
- // unlikely - now only possible in HoB {dlb} 10mar2000
- if (mon_wanted > 60)
- mon_wanted = 60;
- }
-
- place_branch_entrances( level_number, level_type );
-
- check_doors();
-
- if (!player_in_branch( BRANCH_DIS ) && !player_in_branch( BRANCH_VAULTS ))
- hide_doors();
-
- if (!player_in_branch( BRANCH_ECUMENICAL_TEMPLE ))
- place_traps(level_number);
-
- int items_wanted = 3 + roll_dice( 3, 11 );
-
- if (level_number > 5 && one_chance_in(500 - 5 * level_number))
- items_wanted = 10 + random2avg( 90, 2 ); // rich level!
-
- // change pre-rock (105) to rock, and pre-floor (106) to floor
- replace_area( 0,0,GXM-1,GYM-1, DNGN_BUILDER_SPECIAL_WALL, DNGN_ROCK_WALL );
- replace_area( 0,0,GXM-1,GYM-1, DNGN_BUILDER_SPECIAL_FLOOR, DNGN_FLOOR );
-
- // place items
- builder_items(level_number, level_type, items_wanted);
-
- // place monsters
- builder_monsters(level_number, level_type, mon_wanted);
-
- // place shops, if appropriate
- if (player_in_branch( BRANCH_MAIN_DUNGEON )
- || player_in_branch( BRANCH_ORCISH_MINES )
- || player_in_branch( BRANCH_ELVEN_HALLS )
- || player_in_branch( BRANCH_LAIR )
- || player_in_branch( BRANCH_VAULTS )
- || player_in_branch( BRANCH_SNAKE_PIT )
- || player_in_branch( BRANCH_SWAMP ))
- {
- place_shops(level_number);
- }
-
- // If level part of Dis -> all walls metal;
- // If part of vaults -> walls depend on level;
- // If part of crypt -> all walls stone:
- if (player_in_branch( BRANCH_DIS )
- || player_in_branch( BRANCH_VAULTS )
- || player_in_branch( BRANCH_CRYPT ))
- {
- // always the case with Dis {dlb}
- unsigned char vault_wall = DNGN_METAL_WALL;
-
- if (player_in_branch( BRANCH_VAULTS ))
- {
- vault_wall = DNGN_ROCK_WALL;
-
- if (level_number > you.branch_stairs[STAIRS_VAULTS] + 2)
- vault_wall = DNGN_STONE_WALL;
-
- if (level_number > you.branch_stairs[STAIRS_VAULTS] + 4)
- vault_wall = DNGN_METAL_WALL;
-
- if (level_number > you.branch_stairs[STAIRS_VAULTS] + 6
- && one_chance_in(10))
- {
- vault_wall = DNGN_GREEN_CRYSTAL_WALL;
- }
- }
- else if (player_in_branch( BRANCH_CRYPT ))
- {
- vault_wall = DNGN_STONE_WALL;
- }
-
- replace_area(0,0,GXM-1,GYM-1,DNGN_ROCK_WALL,vault_wall);
- }
-
- // Top level of branch levels - replaces up stairs
- // with stairs back to dungeon or wherever:
- for (i = 0; i< 30; i++)
- {
- if (you.branch_stairs[i] == 0)
- break;
-
- if (level_number == you.branch_stairs[i] + 1
- && level_type == LEVEL_DUNGEON
- && you.where_are_you == BRANCH_ORCISH_MINES + i)
- {
- for (x = 1; x < GXM; x++)
- {
- for (y = 1; y < GYM; y++)
- {
- if (grd[x][y] >= DNGN_STONE_STAIRS_UP_I
- && grd[x][y] <= DNGN_ROCK_STAIRS_UP)
- {
- grd[x][y] = DNGN_RETURN_FROM_ORCISH_MINES + i;
- }
- }
- }
- }
- }
-
- // bottom level of branch - replaces down stairs with up ladders:
- for (i = 0; i < 30; i++)
- {
- if (level_number == you.branch_stairs[i] + branch_depth(i)
- && level_type == LEVEL_DUNGEON
- && you.where_are_you == BRANCH_ORCISH_MINES + i)
- {
- for (x = 1; x < GXM; x++)
- {
- for (y = 1; y < GYM; y++)
- {
- if (grd[x][y] >= DNGN_STONE_STAIRS_DOWN_I
- && grd[x][y] <= DNGN_ROCK_STAIRS_DOWN)
- {
- grd[x][y] = DNGN_ROCK_STAIRS_UP;
- }
- }
- }
- }
- }
-
- if (player_in_branch( BRANCH_CRYPT ))
- {
- if (one_chance_in(3))
- mons_place( MONS_CURSE_SKULL, BEH_SLEEP, MHITNOT, false, 0, 0 );
-
- if (one_chance_in(7))
- mons_place( MONS_CURSE_SKULL, BEH_SLEEP, MHITNOT, false, 0, 0 );
- }
-
- if (player_in_branch( BRANCH_ORCISH_MINES ) && one_chance_in(5))
- place_altar();
-
- // hall of blades (1 level deal) - no down staircases, thanks!
- if (player_in_branch( BRANCH_HALL_OF_BLADES ))
- {
- for (x = 1; x < GXM; x++)
- {
- for (y = 1; y < GYM; y++)
- {
- if (grd[x][y] >= DNGN_STONE_STAIRS_DOWN_I
- && grd[x][y] <= DNGN_ROCK_STAIRS_UP)
- {
- grd[x][y] = DNGN_FLOOR;
- }
- }
- }
- }
-
- link_items();
-
- if (!player_in_branch(BRANCH_COCYTUS) && !player_in_branch(BRANCH_SWAMP))
- prepare_water( level_number );
-} // end builder()
-
-// Returns item slot or NON_ITEM if it fails
-int items( int allow_uniques, // not just true-false,
- // because of BCR acquirement hack
- int force_class, // desired OBJECTS class {dlb}
- int force_type, // desired SUBTYPE - enum varies by OBJ
- bool dont_place, // don't randomly place item on level
- int item_level, // level of the item, can differ from global
- int item_race ) // weapon / armour racial categories
- // item_race also gives type of rune!
-{
- int temp_rand = 0; // probability determination {dlb}
- int range_charges = 0; // for OBJ_WANDS charge count {dlb}
- int temp_value = 0; // temporary value storage {dlb}
- int loopy = 0; // just another loop variable {dlb}
- int count = 0; // just another loop variable {dlb}
-
- int race_plus = 0;
- int race_plus2 = 0;
- int x_pos, y_pos;
-
- int quant = 0;
-
- FixedVector < int, SPELLBOOK_SIZE > fpass;
- int icky = 0;
- int p = 0;
-
- // find an emtpy slot for the item (with culling if required)
- p = get_item_slot(10);
- if (p == NON_ITEM)
- return (NON_ITEM);
-
- // clear all properties except mitm.base_type <used in switch below> {dlb}:
- mitm[p].sub_type = 0;
- mitm[p].flags = 0;
- mitm[p].special = 0;
- mitm[p].plus = 0;
- mitm[p].plus2 = 0;
- mitm[p].x = 0;
- mitm[p].y = 0;
- mitm[p].link = NON_ITEM;
- mitm[p].slot = 0;
- mitm[p].orig_monnum = 0;
- mitm[p].orig_place = 0;
-
- // cap item_level unless an acquirement-level item {dlb}:
- if (item_level > 50 && item_level != MAKE_GOOD_ITEM)
- item_level = 50;
-
- // determine base_type for item generated {dlb}:
- if (force_class != OBJ_RANDOM)
- mitm[p].base_type = force_class;
- else
- {
- // nice and large for subtle differences {dlb}
- temp_rand = random2(10000);
-
- mitm[p].base_type = ((temp_rand < 50) ? OBJ_STAVES : // 0.50%
- (temp_rand < 200) ? OBJ_BOOKS : // 1.50%
- (temp_rand < 450) ? OBJ_JEWELLERY :// 2.50%
- (temp_rand < 800) ? OBJ_WANDS : // 3.50%
- (temp_rand < 1500) ? OBJ_FOOD : // 7.00%
- (temp_rand < 2500) ? OBJ_ARMOUR : // 10.00%
- (temp_rand < 3500) ? OBJ_WEAPONS : // 10.00%
- (temp_rand < 4500) ? OBJ_POTIONS : // 10.00%
- (temp_rand < 6000) ? OBJ_MISSILES : // 15.00%
- (temp_rand < 8000) ? OBJ_SCROLLS // 20.00%
- : OBJ_GOLD); // 20.00%
-
- // misc items placement wholly dependent upon current depth {dlb}:
- if (item_level > 7 && (20 + item_level) >= random2(3500))
- mitm[p].base_type = OBJ_MISCELLANY;
-
- if (item_level < 7
- && (mitm[p].base_type == OBJ_BOOKS
- || mitm[p].base_type == OBJ_STAVES
- || mitm[p].base_type == OBJ_WANDS)
- && random2(7) >= item_level)
- {
- mitm[p].base_type = coinflip() ? OBJ_POTIONS : OBJ_SCROLLS;
- }
- }
-
- // determine sub_type accordingly {dlb}:
- switch (mitm[p].base_type)
- {
- case OBJ_WEAPONS:
- // generate initial weapon subtype using weighted function --
- // indefinite loop now more evident and fewer array lookups {dlb}:
- if (force_type != OBJ_RANDOM)
- mitm[p].sub_type = force_type;
- else
- {
- if (random2(20) < 20 - item_level)
- {
- // these are the common/low level weapon types
- temp_rand = random2(12);
-
- mitm[p].sub_type = ((temp_rand == 0) ? WPN_KNIFE :
- (temp_rand == 1) ? WPN_QUARTERSTAFF :
- (temp_rand == 2) ? WPN_SLING :
- (temp_rand == 3) ? WPN_SPEAR :
- (temp_rand == 4) ? WPN_HAND_AXE :
- (temp_rand == 5) ? WPN_DAGGER :
- (temp_rand == 6) ? WPN_MACE :
- (temp_rand == 7) ? WPN_DAGGER :
- (temp_rand == 8) ? WPN_CLUB :
- (temp_rand == 9) ? WPN_HAMMER :
- (temp_rand == 10) ? WPN_WHIP
- : WPN_SABRE);
- }
- else if (item_level > 6 && random2(100) < (10 + item_level)
- && one_chance_in(30))
- {
- // place the rare_weapon() == 0 weapons
- //
- // this replaced the infinite loop (wasteful) -- may need
- // to make into its own function to allow ease of tweaking
- // distribution {dlb}:
- temp_rand = random2(10);
-
- mitm[p].sub_type = ((temp_rand == 9) ? WPN_LAJATANG :
- (temp_rand == 8) ? WPN_DEMON_BLADE :
- (temp_rand == 7) ? WPN_DEMON_TRIDENT :
- (temp_rand == 6) ? WPN_DEMON_WHIP :
- (temp_rand == 5) ? WPN_DOUBLE_SWORD :
- (temp_rand == 4) ? WPN_EVENINGSTAR :
- (temp_rand == 3) ? WPN_EXECUTIONERS_AXE :
- (temp_rand == 2) ? WPN_KATANA :
- (temp_rand == 1) ? WPN_QUICK_BLADE
- /*(temp_rand == 0)*/: WPN_TRIPLE_SWORD);
- }
- else
- {
- // pick a weapon based on rarity
- for (;;)
- {
- temp_value = (unsigned char) random2(NUM_WEAPONS);
-
- if (rare_weapon(temp_value) >= random2(10) + 1)
- {
- mitm[p].sub_type = temp_value;
- break;
- }
- }
- }
- }
-
- if (allow_uniques)
- {
- // Note there is nothing to stop randarts being reproduced,
- // except vast improbability.
- if (mitm[p].sub_type != WPN_CLUB && item_level > 2
- && random2(2000) <= 100 + (item_level * 3) && coinflip())
- {
- if (you.level_type != LEVEL_ABYSS
- && you.level_type != LEVEL_PANDEMONIUM
- && one_chance_in(50))
- {
- icky = find_okay_unrandart( OBJ_WEAPONS, force_type );
-
- if (icky != -1)
- {
- quant = 1;
- make_item_unrandart( mitm[p], icky );
- break;
- }
- }
-
- make_item_randart( mitm[p] );
- mitm[p].plus = 0;
- mitm[p].plus2 = 0;
- mitm[p].plus += random2(7);
- mitm[p].plus2 += random2(7);
-
- if (one_chance_in(3))
- mitm[p].plus += random2(7);
-
- if (one_chance_in(3))
- mitm[p].plus2 += random2(7);
-
- if (one_chance_in(9))
- mitm[p].plus -= random2(7);
-
- if (one_chance_in(9))
- mitm[p].plus2 -= random2(7);
-
- quant = 1;
-
- if (one_chance_in(4))
- {
- do_curse_item( mitm[p] );
- mitm[p].plus = -random2(6);
- mitm[p].plus2 = -random2(6);
- }
- else if ((mitm[p].plus < 0 || mitm[p].plus2 < 0)
- && !one_chance_in(3))
- {
- do_curse_item( mitm[p] );
- }
- break;
- }
-
- if (item_level > 6
- && random2(3000) <= 30 + (item_level * 3) && one_chance_in(12))
- {
- if (make_item_fixed_artefact( mitm[p], (item_level == 51) ))
- break;
- }
- }
-
- ASSERT(!is_fixed_artefact(mitm[p]) && !is_random_artefact(mitm[p]));
-
- if (item_level == MAKE_GOOD_ITEM
- && force_type != OBJ_RANDOM
- && (mitm[p].sub_type == WPN_CLUB || mitm[p].sub_type == WPN_SLING))
- {
- mitm[p].sub_type = WPN_LONG_SWORD;
- }
-
- quant = 1;
-
- mitm[p].plus = 0;
- mitm[p].plus2 = 0;
- mitm[p].special = SPWPN_NORMAL;
-
- if (item_race == MAKE_ITEM_RANDOM_RACE && coinflip())
- {
- switch (mitm[p].sub_type)
- {
- case WPN_CLUB:
- if (coinflip())
- set_equip_race( mitm[p], ISFLAG_ORCISH );
- break;
-
- case WPN_MACE:
- case WPN_FLAIL:
- case WPN_SPIKED_FLAIL:
- case WPN_GREAT_MACE:
- case WPN_DIRE_FLAIL:
- if (one_chance_in(6))
- set_equip_race( mitm[p], ISFLAG_ELVEN );
- if (one_chance_in(4))
- set_equip_race( mitm[p], ISFLAG_DWARVEN );
- if (one_chance_in(3))
- set_equip_race( mitm[p], ISFLAG_ORCISH );
- break;
-
- case WPN_MORNINGSTAR:
- case WPN_HAMMER:
- if (one_chance_in(3))
- set_equip_race( mitm[p], ISFLAG_ORCISH );
- if (one_chance_in(3))
- set_equip_race( mitm[p], ISFLAG_DWARVEN );
- break;
-
- case WPN_DAGGER:
- if (one_chance_in(3))
- set_equip_race( mitm[p], ISFLAG_ORCISH );
- if (one_chance_in(4))
- set_equip_race( mitm[p], ISFLAG_DWARVEN );
- if (one_chance_in(4))
- set_equip_race( mitm[p], ISFLAG_ELVEN );
- break;
-
- case WPN_SHORT_SWORD:
- if (one_chance_in(3))
- set_equip_race( mitm[p], ISFLAG_ORCISH );
- if (one_chance_in(3))
- set_equip_race( mitm[p], ISFLAG_DWARVEN );
- if (one_chance_in(3))
- set_equip_race( mitm[p], ISFLAG_ELVEN );
- break;
-
- case WPN_FALCHION:
- if (one_chance_in(5))
- set_equip_race( mitm[p], ISFLAG_DWARVEN );
- if (one_chance_in(3))
- set_equip_race( mitm[p], ISFLAG_ORCISH );
- if (one_chance_in(3))
- set_equip_race( mitm[p], ISFLAG_ELVEN );
- break;
-
- case WPN_LONG_SWORD:
- if (one_chance_in(4))
- set_equip_race( mitm[p], ISFLAG_ORCISH );
- if (coinflip())
- set_equip_race( mitm[p], ISFLAG_ELVEN );
- break;
-
- case WPN_GREAT_SWORD:
- if (one_chance_in(3))
- set_equip_race( mitm[p], ISFLAG_ORCISH );
- break;
-
- case WPN_SCIMITAR:
- if (coinflip())
- set_equip_race( mitm[p], ISFLAG_ORCISH );
- break;
-
- case WPN_WAR_AXE:
- case WPN_HAND_AXE:
- case WPN_BROAD_AXE:
- case WPN_BATTLEAXE:
- if (one_chance_in(3))
- set_equip_race( mitm[p], ISFLAG_ORCISH );
- if (coinflip())
- set_equip_race( mitm[p], ISFLAG_DWARVEN );
- break;
-
- case WPN_SPEAR:
- case WPN_TRIDENT:
- if (one_chance_in(4))
- set_equip_race( mitm[p], ISFLAG_ORCISH );
- if (one_chance_in(4))
- set_equip_race( mitm[p], ISFLAG_ELVEN );
- break;
-
- case WPN_HALBERD:
- case WPN_GLAIVE:
- case WPN_EXECUTIONERS_AXE:
- case WPN_LOCHABER_AXE:
- if (one_chance_in(5))
- set_equip_race( mitm[p], ISFLAG_ORCISH );
- break;
-
- case WPN_QUICK_BLADE:
- if (one_chance_in(4))
- set_equip_race( mitm[p], ISFLAG_ELVEN );
- break;
-
- case WPN_KATANA:
- case WPN_LAJATANG:
- case WPN_KNIFE:
- case WPN_SLING:
- set_equip_race( mitm[p], ISFLAG_NO_RACE );
- set_item_ego_type( mitm[p], OBJ_WEAPONS, SPWPN_NORMAL );
- break;
-
- case WPN_BOW:
- if (one_chance_in(6))
- set_equip_race( mitm[p], ISFLAG_ORCISH );
- if (coinflip())
- set_equip_race( mitm[p], ISFLAG_ELVEN );
- break;
-
- case WPN_LONGBOW:
- set_equip_race( mitm[p], one_chance_in(3) ? ISFLAG_ELVEN
- : ISFLAG_NO_RACE );
- break;
-
- case WPN_CROSSBOW:
- if (one_chance_in(4))
- set_equip_race( mitm[p], ISFLAG_ORCISH );
- if (one_chance_in(4))
- set_equip_race( mitm[p], ISFLAG_DWARVEN );
- break;
-
- case WPN_HAND_CROSSBOW:
- if (one_chance_in(3))
- set_equip_race( mitm[p], ISFLAG_ELVEN );
- break;
-
- case WPN_BLOWGUN:
- if (one_chance_in(10))
- set_equip_race( mitm[p], ISFLAG_ELVEN );
- if (one_chance_in(4))
- set_equip_race( mitm[p], ISFLAG_ORCISH );
- break;
- }
- }
-
- // fine, but out-of-order relative to mitm[].special ordering {dlb}
- switch (item_race)
- {
- case MAKE_ITEM_ELVEN:
- set_equip_race( mitm[p], ISFLAG_ELVEN );
- break;
-
- case MAKE_ITEM_DWARVEN:
- set_equip_race( mitm[p], ISFLAG_DWARVEN );
- break;
-
- case MAKE_ITEM_ORCISH:
- set_equip_race( mitm[p], ISFLAG_ORCISH );
- break;
- }
-
- // if we allow acquirement-type items to be orcish, then
- // there's a good chance that we'll just strip them of
- // their ego type at the bottom of this function. -- bwr
- if (item_level == MAKE_GOOD_ITEM
- && get_equip_race( mitm[p] ) == ISFLAG_ORCISH)
- {
- set_equip_race( mitm[p], ISFLAG_NO_RACE );
- }
-
- switch (get_equip_race( mitm[p] ))
- {
- case ISFLAG_ORCISH:
- if (coinflip())
- race_plus--;
- if (coinflip())
- race_plus2++;
- break;
-
- case ISFLAG_ELVEN:
- race_plus += random2(3);
- break;
-
- case ISFLAG_DWARVEN:
- if (coinflip())
- race_plus++;
- if (coinflip())
- race_plus2++;
- break;
- }
-
- mitm[p].plus += race_plus;
- mitm[p].plus2 += race_plus2;
-
- if ((random2(200) <= 50 + item_level
- || item_level == MAKE_GOOD_ITEM
- || is_demonic(mitm[p].sub_type))
- // nobody would bother enchanting a club
- && mitm[p].sub_type != WPN_CLUB
- && mitm[p].sub_type != WPN_GIANT_CLUB
- && mitm[p].sub_type != WPN_GIANT_SPIKED_CLUB)
- {
- count = 0;
-
- do
- {
- if (random2(300) <= 100 + item_level
- || item_level == MAKE_GOOD_ITEM
- || is_demonic( mitm[p].sub_type ))
- {
- // note: this doesn't guarantee special enchantment
- switch (mitm[p].sub_type)
- {
- case WPN_EVENINGSTAR:
- if (coinflip())
- set_weapon_special(p, SPWPN_DRAINING);
- // **** intentional fall through here ****
- case WPN_MORNINGSTAR:
- if (one_chance_in(4))
- set_weapon_special(p, SPWPN_VENOM);
-
- if (one_chance_in(4))
- {
- set_weapon_special(p, (coinflip() ? SPWPN_FLAMING
- : SPWPN_FREEZING));
- }
-
- if (one_chance_in(20))
- set_weapon_special(p, SPWPN_VAMPIRICISM);
- // **** intentional fall through here ****
- case WPN_MACE:
- case WPN_GREAT_MACE:
- if ((mitm[p].sub_type == WPN_MACE
- || mitm[p].sub_type == WPN_GREAT_MACE)
- && one_chance_in(4))
- {
- set_weapon_special(p, SPWPN_DISRUPTION);
- }
- // **** intentional fall through here ****
- case WPN_FLAIL:
- case WPN_SPIKED_FLAIL:
- case WPN_DIRE_FLAIL:
- case WPN_HAMMER:
- if (one_chance_in(25))
- set_weapon_special(p, SPWPN_PAIN);
-
- if (one_chance_in(25))
- set_weapon_special(p, SPWPN_DISTORTION);
-
- if (one_chance_in(3) &&
- (!is_weapon_special(p) || one_chance_in(5)))
- set_weapon_special(p, SPWPN_VORPAL);
-
- if (one_chance_in(4))
- set_weapon_special(p, SPWPN_HOLY_WRATH);
-
- if (one_chance_in(3))
- set_weapon_special(p, SPWPN_PROTECTION);
-
- if (one_chance_in(10))
- set_weapon_special(p, SPWPN_DRAINING);
- break;
-
-
- case WPN_DAGGER:
- if (one_chance_in(10))
- set_weapon_special(p, SPWPN_PAIN);
-
- if (one_chance_in(3))
- set_weapon_special(p, SPWPN_VENOM);
- // **** intentional fall through here ****
-
- case WPN_SHORT_SWORD:
- case WPN_SABRE:
- if (one_chance_in(25))
- set_weapon_special(p, SPWPN_DISTORTION);
-
- if (one_chance_in(10))
- set_weapon_special(p, SPWPN_VAMPIRICISM);
-
- if (one_chance_in(8))
- set_weapon_special(p, SPWPN_ELECTROCUTION);
-
- if (one_chance_in(8))
- set_weapon_special(p, SPWPN_PROTECTION);
-
- if (one_chance_in(10))
- set_weapon_special(p, SPWPN_ORC_SLAYING);
-
- if (one_chance_in(8))
- {
- set_weapon_special(p,(coinflip() ? SPWPN_FLAMING
- : SPWPN_FREEZING));
- }
-
- if (one_chance_in(12))
- set_weapon_special(p, SPWPN_HOLY_WRATH);
-
- if (one_chance_in(8))
- set_weapon_special(p, SPWPN_DRAINING);
-
- if (one_chance_in(8))
- set_weapon_special(p, SPWPN_SPEED);
-
- if (one_chance_in(6))
- set_weapon_special(p, SPWPN_VENOM);
- break;
-
- case WPN_FALCHION:
- case WPN_LONG_SWORD:
- if (one_chance_in(12))
- set_weapon_special(p, SPWPN_VENOM);
- // **** intentional fall through here ****
- case WPN_SCIMITAR:
- if (one_chance_in(25))
- set_weapon_special(p, SPWPN_PAIN);
-
- if (one_chance_in(7))
- set_weapon_special(p, SPWPN_SPEED);
- // **** intentional fall through here ****
- case WPN_GREAT_SWORD:
- case WPN_DOUBLE_SWORD:
- case WPN_TRIPLE_SWORD:
- if (one_chance_in(10))
- set_weapon_special(p, SPWPN_VAMPIRICISM);
-
- if (one_chance_in(25))
- set_weapon_special(p, SPWPN_DISTORTION);
-
- if (one_chance_in(5))
- {
- set_weapon_special(p,(coinflip() ? SPWPN_FLAMING
- : SPWPN_FREEZING));
- }
-
- if (one_chance_in(7))
- set_weapon_special(p, SPWPN_PROTECTION);
-
- if (one_chance_in(8))
- set_weapon_special(p, SPWPN_ORC_SLAYING);
-
- if (one_chance_in(12))
- set_weapon_special(p, SPWPN_DRAINING);
-
- if (one_chance_in(7))
- set_weapon_special(p, SPWPN_ELECTROCUTION);
-
- if (one_chance_in(4))
- set_weapon_special(p, SPWPN_HOLY_WRATH);
-
- if (one_chance_in(4)
- && (!is_weapon_special(p) || one_chance_in(3)))
- {
- set_weapon_special(p, SPWPN_VORPAL);
- }
- break;
-
-
- case WPN_WAR_AXE:
- case WPN_BROAD_AXE:
- case WPN_BATTLEAXE:
- case WPN_EXECUTIONERS_AXE:
- if (one_chance_in(25))
- set_weapon_special(p, SPWPN_HOLY_WRATH);
-
- if (one_chance_in(14))
- set_weapon_special(p, SPWPN_DRAINING);
- // **** intentional fall through here ****
- case WPN_HAND_AXE:
- if (one_chance_in(30))
- set_weapon_special(p, SPWPN_PAIN);
-
- if (one_chance_in(10))
- set_weapon_special(p, SPWPN_VAMPIRICISM);
-
- if (one_chance_in(25))
- set_weapon_special(p, SPWPN_DISTORTION);
-
- if (one_chance_in(3)
- && (!is_weapon_special(p) || one_chance_in(5)))
- {
- set_weapon_special(p, SPWPN_VORPAL);
- }
-
- if (one_chance_in(6))
- set_weapon_special(p, SPWPN_ORC_SLAYING);
-
- if (one_chance_in(4))
- {
- set_weapon_special(p, (coinflip() ? SPWPN_FLAMING
- : SPWPN_FREEZING));
- }
-
- if (one_chance_in(8))
- set_weapon_special(p, SPWPN_ELECTROCUTION);
-
- if (one_chance_in(12))
- set_weapon_special(p, SPWPN_VENOM);
-
- break;
-
- case WPN_WHIP:
- if (one_chance_in(20))
- set_weapon_special(p, SPWPN_DISTORTION);
-
- if (one_chance_in(6))
- {
- set_weapon_special(p, (coinflip() ? SPWPN_FLAMING
- : SPWPN_FREEZING));
- }
-
- if (one_chance_in(6))
- set_weapon_special(p, SPWPN_VENOM);
-
- if (coinflip())
- set_weapon_special(p, SPWPN_REACHING);
-
- if (one_chance_in(5))
- set_weapon_special(p, SPWPN_SPEED);
-
- if (one_chance_in(5))
- set_weapon_special(p, SPWPN_ELECTROCUTION);
- break;
-
- case WPN_HALBERD:
- case WPN_GLAIVE:
- case WPN_SCYTHE:
- case WPN_TRIDENT:
- case WPN_LOCHABER_AXE:
- if (one_chance_in(30))
- set_weapon_special(p, SPWPN_HOLY_WRATH);
-
- if (one_chance_in(4))
- set_weapon_special(p, SPWPN_PROTECTION);
- // **** intentional fall through here ****
- if (one_chance_in(5))
- set_weapon_special(p, SPWPN_SPEED);
- // **** intentional fall through here ****
- case WPN_SPEAR:
- if (one_chance_in(25))
- set_weapon_special(p, SPWPN_PAIN);
-
- if (one_chance_in(10))
- set_weapon_special(p, SPWPN_VAMPIRICISM);
-
- if (one_chance_in(20))
- set_weapon_special(p, SPWPN_DISTORTION);
-
- if (one_chance_in(5) &&
- (!is_weapon_special(p) || one_chance_in(6)))
- set_weapon_special(p, SPWPN_VORPAL);
-
- if (one_chance_in(6))
- set_weapon_special(p, SPWPN_ORC_SLAYING);
-
- if (one_chance_in(6))
- {
- set_weapon_special(p, (coinflip() ? SPWPN_FLAMING
- : SPWPN_FREEZING));
- }
-
- if (one_chance_in(6))
- set_weapon_special(p, SPWPN_VENOM);
-
- if (one_chance_in(3))
- set_weapon_special(p, SPWPN_REACHING);
- break;
-
-
- case WPN_SLING:
- case WPN_HAND_CROSSBOW:
- if (coinflip())
- break;
- // **** possible intentional fall through here ****
- case WPN_BOW:
- case WPN_LONGBOW:
- case WPN_CROSSBOW:
- {
- const int tmp = random2(1000);
-
- set_weapon_special( p, (tmp < 375) ? SPWPN_FLAMING :
- (tmp < 750) ? SPWPN_FREEZING :
- (tmp < 920) ? SPWPN_PROTECTION :
- (tmp < 980) ? SPWPN_VORPAL
- : SPWPN_SPEED );
- break;
- }
- case WPN_BLOWGUN:
- if (one_chance_in(7))
- set_weapon_special(p, SPWPN_VENOM);
- break;
-
- // quarterstaff - not powerful, as this would make
- // the 'staves' skill just too good
- case WPN_QUARTERSTAFF:
- if (one_chance_in(30))
- set_weapon_special(p, SPWPN_PAIN);
-
- if (one_chance_in(20))
- set_weapon_special(p, SPWPN_DISTORTION);
-
- if (one_chance_in(5))
- set_weapon_special(p, SPWPN_SPEED);
-
- if (one_chance_in(10))
- set_weapon_special(p, SPWPN_VORPAL);
-
- if (one_chance_in(5))
- set_weapon_special(p, SPWPN_PROTECTION);
- break;
-
-
- case WPN_DEMON_TRIDENT:
- case WPN_DEMON_WHIP:
- case WPN_DEMON_BLADE:
- set_equip_race( mitm[p], ISFLAG_NO_RACE );
-
- if (one_chance_in(10))
- set_weapon_special(p, SPWPN_PAIN);
-
- if (one_chance_in(3)
- && (mitm[p].sub_type == WPN_DEMON_WHIP
- || mitm[p].sub_type == WPN_DEMON_TRIDENT))
- {
- set_weapon_special(p, SPWPN_REACHING);
- }
-
- if (one_chance_in(5))
- set_weapon_special(p, SPWPN_DRAINING);
-
- if (one_chance_in(5))
- {
- set_weapon_special(p, (coinflip() ? SPWPN_FLAMING
- : SPWPN_FREEZING));
- }
-
- if (one_chance_in(5))
- set_weapon_special(p, SPWPN_ELECTROCUTION);
-
- if (one_chance_in(5))
- set_weapon_special(p, SPWPN_VAMPIRICISM);
-
- if (one_chance_in(5))
- set_weapon_special(p, SPWPN_VENOM);
- break;
-
- case WPN_BLESSED_BLADE: // special gift of TSO
- set_weapon_special( p, SPWPN_HOLY_WRATH );
- break;
-
- // unlisted weapons have no associated, standard ego-types {dlb}
- default:
- break;
- }
- } // end if specially enchanted
-
- count++;
- }
- while (item_level == MAKE_GOOD_ITEM
- && mitm[p].special == SPWPN_NORMAL
- && count < 5);
-
- // if acquired item still not ego... enchant it up a bit.
- if (item_level == MAKE_GOOD_ITEM && mitm[p].special == SPWPN_NORMAL)
- {
- mitm[p].plus += 2 + random2(3);
- mitm[p].plus2 += 2 + random2(3);
- }
-
- const int chance = (item_level == MAKE_GOOD_ITEM) ? 200
- : item_level;
-
- // odd-looking, but this is how the algorithm compacts {dlb}:
- for (loopy = 0; loopy < 4; loopy++)
- {
- mitm[p].plus += random2(3);
-
- if (random2(350) > 20 + chance)
- break;
- }
-
- // odd-looking, but this is how the algorithm compacts {dlb}:
- for (loopy = 0; loopy < 4; loopy++)
- {
- mitm[p].plus2 += random2(3);
-
- if (random2(500) > 50 + chance)
- break;
- }
- }
- else
- {
- if (one_chance_in(12))
- {
- do_curse_item( mitm[p] );
- mitm[p].plus -= random2(4);
- mitm[p].plus2 -= random2(4);
-
- // clear specials {dlb}
- set_item_ego_type( mitm[p], OBJ_WEAPONS, SPWPN_NORMAL );
- }
- }
-
- // value was "0" comment said "orc" so I went with comment {dlb}
- if (get_equip_race(mitm[p]) == ISFLAG_ORCISH)
- {
- // no holy wrath or slay orc and 1/2 the time no-ego
- const int brand = get_weapon_brand( mitm[p] );
- if (brand == SPWPN_HOLY_WRATH
- || brand == SPWPN_ORC_SLAYING
- || (brand != SPWPN_NORMAL && coinflip()))
- {
- // this makes no sense {dlb}
- // Probably a remnant of the old code which used
- // to decrement this when the electric attack happened -- bwr
- // if (brand == SPWPN_ELECTROCUTION)
- // mitm[p].plus = 0;
-
- set_item_ego_type( mitm[p], OBJ_WEAPONS, SPWPN_NORMAL );
- }
- }
-
- if ((((is_random_artefact( mitm[p] )
- || get_weapon_brand( mitm[p] ) != SPWPN_NORMAL)
- && !one_chance_in(10))
- || ((mitm[p].plus != 0 || mitm[p].plus2 != 0)
- && one_chance_in(3)))
- && mitm[p].sub_type != WPN_CLUB
- && mitm[p].sub_type != WPN_GIANT_CLUB
- && mitm[p].sub_type != WPN_GIANT_SPIKED_CLUB
- && get_equip_desc(mitm[p]) == 0
- && get_equip_race(mitm[p]) == 0)
- {
- set_equip_desc( mitm[p], (coinflip() ? ISFLAG_GLOWING
- : ISFLAG_RUNED) );
- }
- break;
-
- case OBJ_MISSILES:
- quant = 0;
- mitm[p].plus = 0;
- mitm[p].special = SPMSL_NORMAL;
-
- temp_rand = random2(20);
- mitm[p].sub_type = (temp_rand < 6) ? MI_STONE : // 30 %
- (temp_rand < 10) ? MI_DART : // 20 %
- (temp_rand < 14) ? MI_ARROW : // 20 %
- (temp_rand < 18) ? MI_BOLT // 20 %
- : MI_NEEDLE; // 10 %
-
- if (force_type != OBJ_RANDOM)
- mitm[p].sub_type = force_type;
-
- // no fancy rocks -- break out before we get to racial/special stuff
- if (mitm[p].sub_type == MI_LARGE_ROCK)
- {
- quant = 2 + random2avg(5,2);
- break;
- }
- else if (mitm[p].sub_type == MI_STONE)
- {
- quant = 1 + random2(9) + random2(12) + random2(15) + random2(12);
- break;
- }
-
- // set racial type:
- switch (item_race)
- {
- case MAKE_ITEM_ELVEN:
- set_equip_race( mitm[p], ISFLAG_ELVEN );
- break;
-
- case MAKE_ITEM_DWARVEN:
- set_equip_race( mitm[p], ISFLAG_DWARVEN );
- break;
-
- case MAKE_ITEM_ORCISH:
- set_equip_race( mitm[p], ISFLAG_ORCISH );
- break;
-
- case MAKE_ITEM_RANDOM_RACE:
- if ((mitm[p].sub_type == MI_ARROW
- || mitm[p].sub_type == MI_DART)
- && one_chance_in(4))
- {
- // elven - not for bolts, though
- set_equip_race( mitm[p], ISFLAG_ELVEN );
- }
-
- if ((mitm[p].sub_type == MI_ARROW
- || mitm[p].sub_type == MI_BOLT
- || mitm[p].sub_type == MI_DART)
- && one_chance_in(4))
- {
- set_equip_race( mitm[p], ISFLAG_ORCISH );
- }
-
- if ((mitm[p].sub_type == MI_DART
- || mitm[p].sub_type == MI_BOLT)
- && one_chance_in(6))
- {
- set_equip_race( mitm[p], ISFLAG_DWARVEN );
- }
-
- if (mitm[p].sub_type == MI_NEEDLE)
- {
- if (one_chance_in(10))
- set_equip_race( mitm[p], ISFLAG_ELVEN );
- if (one_chance_in(6))
- set_equip_race( mitm[p], ISFLAG_ORCISH );
- }
- break;
- }
-
- // note that needles can only be poisoned
- //
- // Actually, it'd be really nice if there where
- // some paralysis or slowing poison needles, just
- // so that blowguns have some added utility over
- // the other launchers/throwing weapons. -- bwr
- if (mitm[p].sub_type == MI_NEEDLE
- && (item_level == MAKE_GOOD_ITEM || !one_chance_in(5)))
- {
- const int pois =
- item_level == MAKE_GOOD_ITEM ||
- got_curare_roll(item_level)
- ? SPMSL_CURARE : SPMSL_POISONED_II;
- set_item_ego_type( mitm[p], OBJ_MISSILES, pois );
- }
- else
- {
- // decide specials:
- if (item_level == MAKE_GOOD_ITEM)
- temp_rand = random2(150);
- else
- temp_rand = random2(2000 - 55 * item_level);
-
- set_item_ego_type( mitm[p], OBJ_MISSILES,
- (temp_rand < 60) ? SPMSL_FLAME :
- (temp_rand < 120) ? SPMSL_ICE :
- (temp_rand < 150) ? SPMSL_POISONED_II
- : SPMSL_NORMAL );
- }
-
- // orcish ammo gets poisoned a lot more often -- in the original
- // code it was poisoned every time!?
- if (get_equip_race(mitm[p]) == ISFLAG_ORCISH && one_chance_in(3))
- set_item_ego_type( mitm[p], OBJ_MISSILES, SPMSL_POISONED_II );
-
- // reduced quantity if special
- if (get_ammo_brand( mitm[p] ) != SPMSL_NORMAL )
- quant = 1 + random2(9) + random2(12) + random2(12);
- else
- quant = 1 + random2(9) + random2(12) + random2(15) + random2(12);
-
- if (10 + item_level >= random2(100))
- mitm[p].plus += random2(5);
-
- // elven arrows and dwarven bolts are quality items
- if ((get_equip_race(mitm[p]) == ISFLAG_ELVEN
- && mitm[p].sub_type == MI_ARROW)
- || (get_equip_race(mitm[p]) == ISFLAG_DWARVEN
- && mitm[p].sub_type == MI_BOLT))
- {
- mitm[p].plus += random2(3);
- }
- break;
-
- case OBJ_ARMOUR:
- quant = 1;
-
- mitm[p].plus = 0;
- mitm[p].plus2 = 0;
- mitm[p].special = SPARM_NORMAL;
-
- if (force_type != OBJ_RANDOM)
- mitm[p].sub_type = force_type;
- else
- {
- mitm[p].sub_type = random2(3);
-
- if (random2(35) <= item_level + 10)
- {
- mitm[p].sub_type = random2(5);
- if (one_chance_in(4))
- mitm[p].sub_type = ARM_ANIMAL_SKIN;
- }
-
- if (random2(60) <= item_level + 10)
- mitm[p].sub_type = random2(8);
-
- if (10 + item_level >= random2(400) && one_chance_in(20))
- mitm[p].sub_type = ARM_DRAGON_HIDE + random2(7);
-
- if (10 + item_level >= random2(500) && one_chance_in(20))
- {
- mitm[p].sub_type = ARM_STEAM_DRAGON_HIDE + random2(11);
-
- if (mitm[p].sub_type == ARM_ANIMAL_SKIN && one_chance_in(20))
- mitm[p].sub_type = ARM_CRYSTAL_PLATE_MAIL;
- }
-
- // secondary armours:
- if (one_chance_in(5))
- {
- mitm[p].sub_type = ARM_SHIELD + random2(5);
-
- if (mitm[p].sub_type == ARM_SHIELD) // 33.3%
- {
- if (coinflip())
- mitm[p].sub_type = ARM_BUCKLER; // 50.0%
- else if (one_chance_in(3))
- mitm[p].sub_type = ARM_LARGE_SHIELD; // 16.7%
- }
- }
- }
-
- if (mitm[p].sub_type == ARM_HELMET)
- {
- set_helmet_type( mitm[p], THELM_HELMET );
- set_helmet_desc( mitm[p], THELM_DESC_PLAIN );
-
- if (one_chance_in(3))
- set_helmet_type( mitm[p], random2( THELM_NUM_TYPES ) );
-
- if (one_chance_in(3))
- set_helmet_random_desc( mitm[p] );
- }
-
- if (allow_uniques == 1
- && item_level > 2
- && random2(2000) <= (100 + item_level * 3)
- && coinflip())
- {
- if ((you.level_type != LEVEL_ABYSS
- && you.level_type != LEVEL_PANDEMONIUM)
- && one_chance_in(50))
- {
- icky = find_okay_unrandart(OBJ_ARMOUR);
- if (icky != -1)
- {
- quant = 1;
- make_item_unrandart( mitm[p], icky );
- break;
- }
- }
-
- hide2armour(mitm[p]);
-
- // mitm[p].special = SPARM_RANDART_II + random2(4);
- make_item_randart( mitm[p] );
- mitm[p].plus = 0;
-
- if (mitm[p].sub_type == ARM_BOOTS
- && one_chance_in(10))
- {
- mitm[p].sub_type =
- coinflip()? ARM_NAGA_BARDING
- : ARM_CENTAUR_BARDING;
- }
-
- mitm[p].plus += random2(4);
-
- if (one_chance_in(5))
- mitm[p].plus += random2(4);
-
- if (one_chance_in(6))
- mitm[p].plus -= random2(8);
-
- quant = 1;
-
- if (one_chance_in(5))
- {
- do_curse_item( mitm[p] );
- mitm[p].plus = -random2(6);
- }
- else if (mitm[p].plus < 0 && !one_chance_in(3))
- {
- do_curse_item( mitm[p] );
- }
- break;
- }
-
- mitm[p].plus = 0;
-
- if (item_race == MAKE_ITEM_RANDOM_RACE && coinflip())
- {
- switch (mitm[p].sub_type)
- {
- case ARM_SHIELD: // shield - must do special things for this!
- case ARM_BUCKLER:
- case ARM_LARGE_SHIELD:
- if (one_chance_in(4))
- set_equip_race( mitm[p], ISFLAG_ELVEN );
- if (one_chance_in(3))
- set_equip_race( mitm[p], ISFLAG_DWARVEN );
- break;
-
- case ARM_CLOAK:
- if (one_chance_in(4))
- set_equip_race( mitm[p], ISFLAG_ORCISH );
- if (one_chance_in(4))
- set_equip_race( mitm[p], ISFLAG_DWARVEN );
- if (one_chance_in(4))
- set_equip_race( mitm[p], ISFLAG_ELVEN );
- break;
-
- case ARM_GLOVES:
- if (one_chance_in(4))
- set_equip_race( mitm[p], ISFLAG_ELVEN );
- break;
-
- case ARM_NAGA_BARDING:
- case ARM_CENTAUR_BARDING:
- case ARM_BOOTS:
- if (mitm[p].sub_type == ARM_BOOTS)
- {
- if (one_chance_in(4))
- {
- mitm[p].sub_type = ARM_NAGA_BARDING;
- break;
- }
-
- if (one_chance_in(4))
- {
- mitm[p].sub_type = ARM_CENTAUR_BARDING;
- break;
- }
- }
-
- if (one_chance_in(4))
- set_equip_race( mitm[p], ISFLAG_ORCISH );
- if (one_chance_in(4))
- set_equip_race( mitm[p], ISFLAG_ELVEN );
- if (one_chance_in(6))
- set_equip_race( mitm[p], ISFLAG_DWARVEN );
- break;
-
- case ARM_HELMET:
- if (get_helmet_type(mitm[p]) == THELM_CAP
- || get_helmet_type(mitm[p]) == THELM_WIZARD_HAT)
- {
- if (one_chance_in(6))
- set_equip_race( mitm[p], ISFLAG_ELVEN );
- }
- else
- {
- // helms and helmets
- if (one_chance_in(8))
- set_equip_race( mitm[p], ISFLAG_ORCISH );
- if (one_chance_in(6))
- set_equip_race( mitm[p], ISFLAG_DWARVEN );
- }
- break;
-
- case ARM_ROBE:
- if (one_chance_in(4))
- set_equip_race( mitm[p], ISFLAG_ELVEN );
- break;
-
- case ARM_RING_MAIL:
- case ARM_SCALE_MAIL:
- case ARM_CHAIN_MAIL:
- case ARM_SPLINT_MAIL:
- case ARM_BANDED_MAIL:
- case ARM_PLATE_MAIL:
- if (mitm[p].sub_type <= ARM_CHAIN_MAIL && one_chance_in(6))
- set_equip_race( mitm[p], ISFLAG_ELVEN );
- if (mitm[p].sub_type >= ARM_RING_MAIL && one_chance_in(5))
- set_equip_race( mitm[p], ISFLAG_DWARVEN );
- if (one_chance_in(5))
- set_equip_race( mitm[p], ISFLAG_ORCISH );
-
- default: // skins, hides, crystal plate are always plain
- break;
- }
- }
-
- switch (item_race)
- {
- case MAKE_ITEM_ELVEN:
- set_equip_race( mitm[p], ISFLAG_ELVEN );
- break;
-
- case MAKE_ITEM_DWARVEN:
- set_equip_race( mitm[p], ISFLAG_DWARVEN );
- if (coinflip())
- mitm[p].plus++;
- break;
-
- case MAKE_ITEM_ORCISH:
- set_equip_race( mitm[p], ISFLAG_ORCISH );
- break;
- }
-
-
- if (50 + item_level >= random2(250)
- || item_level == MAKE_GOOD_ITEM
- || (mitm[p].sub_type == ARM_HELMET
- && get_helmet_type(mitm[p]) == THELM_WIZARD_HAT))
- {
- mitm[p].plus += random2(3);
-
- if (mitm[p].sub_type <= ARM_PLATE_MAIL && 20 + item_level >= random2(300))
- mitm[p].plus += random2(3);
-
- if (30 + item_level >= random2(350)
- && (item_level == MAKE_GOOD_ITEM
- || (!get_equip_race(mitm[p]) == ISFLAG_ORCISH
- || (mitm[p].sub_type <= ARM_PLATE_MAIL && coinflip()))))
- {
- switch (mitm[p].sub_type)
- {
- case ARM_SHIELD: // shield - must do special things for this!
- case ARM_LARGE_SHIELD:
- case ARM_BUCKLER:
- {
- const int tmp = random2(1000);
-
- set_item_ego_type( mitm[p], OBJ_ARMOUR,
- (tmp < 40) ? SPARM_RESISTANCE :
- (tmp < 160) ? SPARM_FIRE_RESISTANCE :
- (tmp < 280) ? SPARM_COLD_RESISTANCE :
- (tmp < 400) ? SPARM_POISON_RESISTANCE :
- (tmp < 520) ? SPARM_POSITIVE_ENERGY
- : SPARM_PROTECTION );
- break; // prot
- //break;
- }
- case ARM_CLOAK:
- if (get_equip_race(mitm[p]) == ISFLAG_DWARVEN)
- break;
-
- switch (random2(4))
- {
- case 0:
- set_item_ego_type( mitm[p],
- OBJ_ARMOUR, SPARM_POISON_RESISTANCE );
- break;
-
- case 1:
- set_item_ego_type( mitm[p],
- OBJ_ARMOUR, SPARM_DARKNESS );
- break;
- case 2:
- set_item_ego_type( mitm[p],
- OBJ_ARMOUR, SPARM_MAGIC_RESISTANCE );
- break;
- case 3:
- set_item_ego_type( mitm[p],
- OBJ_ARMOUR, SPARM_PRESERVATION );
- break;
- }
- break;
-
- case ARM_HELMET:
- if (get_helmet_type(mitm[p]) == THELM_WIZARD_HAT && coinflip())
- {
- if (one_chance_in(3))
- {
- set_item_ego_type( mitm[p],
- OBJ_ARMOUR, SPARM_MAGIC_RESISTANCE );
- }
- else
- {
- set_item_ego_type( mitm[p],
- OBJ_ARMOUR, SPARM_INTELLIGENCE );
- }
- }
- else
- {
- set_item_ego_type( mitm[p], OBJ_ARMOUR,
- coinflip() ? SPARM_SEE_INVISIBLE
- : SPARM_INTELLIGENCE );
- }
- break;
-
- case ARM_GLOVES:
- set_item_ego_type( mitm[p], OBJ_ARMOUR,
- coinflip() ? SPARM_DEXTERITY
- : SPARM_STRENGTH );
- break;
-
- case ARM_BOOTS:
- case ARM_NAGA_BARDING:
- case ARM_CENTAUR_BARDING:
- {
- const int tmp = random2(600)
- + 200 * (mitm[p].sub_type != ARM_BOOTS);
-
- set_item_ego_type( mitm[p], OBJ_ARMOUR,
- (tmp < 200) ? SPARM_RUNNING :
- (tmp < 400) ? SPARM_LEVITATION :
- (tmp < 600) ? SPARM_STEALTH :
- (tmp < 700) ? SPARM_COLD_RESISTANCE
- : SPARM_FIRE_RESISTANCE );
- break;
- }
-
- case ARM_ROBE:
- switch (random2(4))
- {
- case 0:
- set_item_ego_type( mitm[p], OBJ_ARMOUR,
- coinflip() ? SPARM_COLD_RESISTANCE
- : SPARM_FIRE_RESISTANCE );
- break;
-
- case 1:
- set_item_ego_type( mitm[p],
- OBJ_ARMOUR, SPARM_MAGIC_RESISTANCE );
- break;
-
- case 2:
- set_item_ego_type( mitm[p], OBJ_ARMOUR,
- coinflip() ? SPARM_POSITIVE_ENERGY
- : SPARM_RESISTANCE );
- break;
- case 3:
- if (force_type != OBJ_RANDOM
- || is_random_artefact( mitm[p] )
- || get_armour_ego_type( mitm[p] ) != SPARM_NORMAL
- || random2(50) > 10 + item_level)
- {
- break;
- }
-
- set_item_ego_type( mitm[p], OBJ_ARMOUR, SPARM_ARCHMAGI );
- break;
- }
- break;
-
- default: // other body armours:
- set_item_ego_type( mitm[p], OBJ_ARMOUR,
- coinflip() ? SPARM_COLD_RESISTANCE
- : SPARM_FIRE_RESISTANCE );
-
- if (one_chance_in(9))
- {
- set_item_ego_type( mitm[p],
- OBJ_ARMOUR, SPARM_POSITIVE_ENERGY );
- }
-
- if (one_chance_in(5))
- {
- set_item_ego_type( mitm[p],
- OBJ_ARMOUR, SPARM_MAGIC_RESISTANCE );
- }
-
- if (one_chance_in(5))
- {
- set_item_ego_type( mitm[p],
- OBJ_ARMOUR, SPARM_POISON_RESISTANCE );
- }
-
- if (mitm[p].sub_type == ARM_PLATE_MAIL
- && one_chance_in(15))
- {
- set_item_ego_type( mitm[p],
- OBJ_ARMOUR, SPARM_PONDEROUSNESS );
- mitm[p].plus += 3 + random2(4);
- }
- break;
- }
- }
- }
- else if (one_chance_in(12))
- {
- // mitm[p].plus = (coinflip() ? 99 : 98); // 98? 99?
- do_curse_item( mitm[p] );
-
- if (one_chance_in(5))
- mitm[p].plus -= random2(3);
-
- set_item_ego_type( mitm[p], OBJ_ARMOUR, SPARM_NORMAL );
- }
-
- // if not given a racial type, and special, give shiny/runed/etc desc.
- if (get_equip_race(mitm[p]) == 0
- && get_equip_desc(mitm[p]) == 0
- && (((is_random_artefact(mitm[p])
- || get_armour_ego_type( mitm[p] ) != SPARM_NORMAL)
- && !one_chance_in(10))
- || (mitm[p].plus != 0 && one_chance_in(3))))
- {
- switch (random2(3))
- {
- case 0:
- set_equip_desc( mitm[p], ISFLAG_GLOWING );
- break;
-
- case 1:
- set_equip_desc( mitm[p], ISFLAG_RUNED );
- break;
-
- case 2:
- default:
- set_equip_desc( mitm[p], ISFLAG_EMBROIDERED_SHINY );
- break;
- }
- }
-
- // Make sure you don't get a hide from acquirement (since that
- // would be an enchanted item which somehow didn't get converted
- // into armour).
- if (item_level == MAKE_GOOD_ITEM)
- hide2armour(mitm[p]); // what of animal hides? {dlb}
-
- // skin armours + Crystal PM don't get special enchantments
- // or species, but can be randarts
- if (mitm[p].sub_type >= ARM_DRAGON_HIDE
- && mitm[p].sub_type <= ARM_SWAMP_DRAGON_ARMOUR)
- {
- set_equip_race( mitm[p], ISFLAG_NO_RACE );
- set_item_ego_type( mitm[p], OBJ_ARMOUR, SPARM_NORMAL );
- }
- break;
-
- case OBJ_WANDS:
- // determine sub_type:
- if (force_type != OBJ_RANDOM)
- mitm[p].sub_type = force_type;
- else
- {
- mitm[p].sub_type = random2( NUM_WANDS );
-
- // Adjusted distribution here -- bwr
- // Wands used to be uniform (5.26% each)
- //
- // Now:
- // invis, hasting, healing (1.11% each)
- // fireball, teleportaion (3.74% each)
- // others (6.37% each)
- if ((mitm[p].sub_type == WAND_INVISIBILITY
- || mitm[p].sub_type == WAND_HASTING
- || mitm[p].sub_type == WAND_HEALING)
- || ((mitm[p].sub_type == WAND_FIREBALL
- || mitm[p].sub_type == WAND_TELEPORTATION)
- && coinflip()))
- {
- mitm[p].sub_type = random2( NUM_WANDS );
- }
- }
-
- // determine upper bound on charges:
- range_charges = ((mitm[p].sub_type == WAND_HEALING
- || mitm[p].sub_type == WAND_HASTING
- || mitm[p].sub_type == WAND_INVISIBILITY) ? 8 :
- (mitm[p].sub_type == WAND_FLAME
- || mitm[p].sub_type == WAND_FROST
- || mitm[p].sub_type == WAND_MAGIC_DARTS
- || mitm[p].sub_type == WAND_RANDOM_EFFECTS) ? 28
- : 16);
-
- // generate charges randomly:
- mitm[p].plus = random2avg(range_charges, 3);
- //
- // set quantity to one:
- quant = 1;
- break;
-
- case OBJ_FOOD: // this can be parsed out {dlb}
- // determine sub_type:
- if (force_type == OBJ_RANDOM)
- {
- temp_rand = random2(1000);
-
- mitm[p].sub_type =
- ((temp_rand >= 750) ? FOOD_MEAT_RATION : // 25.00% chance
- (temp_rand >= 450) ? FOOD_BREAD_RATION :// 30.00% chance
- (temp_rand >= 350) ? FOOD_PEAR : // 10.00% chance
- (temp_rand >= 250) ? FOOD_APPLE : // 10.00% chance
- (temp_rand >= 150) ? FOOD_CHOKO : // 10.00% chance
- (temp_rand >= 140) ? FOOD_CHEESE : // 1.00% chance
- (temp_rand >= 130) ? FOOD_PIZZA : // 1.00% chance
- (temp_rand >= 120) ? FOOD_SNOZZCUMBER : // 1.00% chance
- (temp_rand >= 110) ? FOOD_APRICOT : // 1.00% chance
- (temp_rand >= 100) ? FOOD_ORANGE : // 1.00% chance
- (temp_rand >= 90) ? FOOD_BANANA : // 1.00% chance
- (temp_rand >= 80) ? FOOD_STRAWBERRY : // 1.00% chance
- (temp_rand >= 70) ? FOOD_RAMBUTAN : // 1.00% chance
- (temp_rand >= 60) ? FOOD_LEMON : // 1.00% chance
- (temp_rand >= 50) ? FOOD_GRAPE : // 1.00% chance
- (temp_rand >= 40) ? FOOD_SULTANA : // 1.00% chance
- (temp_rand >= 30) ? FOOD_LYCHEE : // 1.00% chance
- (temp_rand >= 20) ? FOOD_BEEF_JERKY : // 1.00% chance
- (temp_rand >= 10) ? FOOD_SAUSAGE : // 1.00% chance
- (temp_rand >= 5) ? FOOD_HONEYCOMB // 0.50% chance
- : FOOD_ROYAL_JELLY );// 0.50% chance
- }
- else
- mitm[p].sub_type = force_type;
-
- // Happens with ghoul food acquirement -- use place_chunks() outherwise
- if (mitm[p].sub_type == FOOD_CHUNK)
- {
- for (count = 0; count < 1000; count++)
- {
- temp_rand = random2( NUM_MONSTERS ); // random monster
- temp_rand = mons_species( temp_rand ); // corpse base type
-
- if (mons_weight( temp_rand ) > 0) // drops a corpse
- break;
- }
-
- // set chunk flavour (default to common dungeon rat steaks):
- mitm[p].plus = (count == 1000) ? MONS_RAT : temp_rand;
-
- // set duration
- mitm[p].special = (10 + random2(11)) * 10;
- }
-
- // determine quantity:
- if (allow_uniques > 1)
- quant = allow_uniques;
- else
- {
- quant = 1;
-
- if (mitm[p].sub_type != FOOD_MEAT_RATION
- && mitm[p].sub_type != FOOD_BREAD_RATION)
- {
- if (one_chance_in(80))
- quant += random2(3);
-
- if (mitm[p].sub_type == FOOD_STRAWBERRY
- || mitm[p].sub_type == FOOD_GRAPE
- || mitm[p].sub_type == FOOD_SULTANA)
- {
- quant += 3 + random2avg(15,2);
- }
- }
- }
- break;
-
- case OBJ_POTIONS:
- quant = 1;
-
- if (one_chance_in(18))
- quant++;
-
- if (one_chance_in(25))
- quant++;
-
- if (force_type != OBJ_RANDOM)
- mitm[p].sub_type = force_type;
- else
- {
- temp_rand = random2(9); // general type of potion;
-
- switch (temp_rand)
- {
- case 0:
- case 1:
- case 2:
- case 8:
- // healing potions
- if (one_chance_in(3))
- mitm[p].sub_type = POT_HEAL_WOUNDS; // 14.074%
- else
- mitm[p].sub_type = POT_HEALING; // 28.148%
-
- if (one_chance_in(20))
- mitm[p].sub_type = POT_CURE_MUTATION; // 2.222%
- break;
-
- case 3:
- case 4:
- // enhancements
- if (coinflip())
- mitm[p].sub_type = POT_SPEED; // 6.444%
- else
- mitm[p].sub_type = POT_MIGHT; // 6.444%
-
- if (one_chance_in(10))
- mitm[p].sub_type = POT_BERSERK_RAGE; // 1.432%
-
- if (one_chance_in(5))
- mitm[p].sub_type = POT_INVISIBILITY; // 3.580%
-
- if (one_chance_in(6))
- mitm[p].sub_type = POT_LEVITATION; // 3.580%
-
- if (one_chance_in(30))
- mitm[p].sub_type = POT_PORRIDGE; // 0.741%
- break;
-
- case 5:
- // gain ability
- mitm[p].sub_type = POT_GAIN_STRENGTH + random2(3); // 1.125%
- // or 0.375% each
-
- if (one_chance_in(10))
- mitm[p].sub_type = POT_EXPERIENCE; // 0.125%
-
- if (one_chance_in(10))
- mitm[p].sub_type = POT_MAGIC; // 0.139%
-
- if (!one_chance_in(8))
- mitm[p].sub_type = POT_RESTORE_ABILITIES; // 9.722%
-
- quant = 1;
- break;
-
- case 6:
- case 7:
- // bad things
- switch (random2(6))
- {
- case 0:
- case 4:
- // is this not always the case? - no, level one is 0 {dlb}
- if (item_level > 0)
- {
- mitm[p].sub_type = POT_POISON; // 6.475%
-
- if (item_level > 10 && one_chance_in(4))
- mitm[p].sub_type = POT_STRONG_POISON;
-
- break;
- }
-
- /* **** intentional fall through **** */ // ignored for %
- case 5:
- if (item_level > 6)
- {
- mitm[p].sub_type = POT_MUTATION; // 3.237%
- break;
- }
-
- /* **** intentional fall through **** */ // ignored for %
- case 1:
- mitm[p].sub_type = POT_SLOWING; // 3.237%
- break;
-
- case 2:
- mitm[p].sub_type = POT_PARALYSIS; // 3.237%
- break;
-
- case 3:
- mitm[p].sub_type = POT_CONFUSION; // 3.237%
- break;
-
- }
-
- if (one_chance_in(8))
- mitm[p].sub_type = POT_DEGENERATION; // 2.775%
-
- if (one_chance_in(1000)) // 0.022%
- mitm[p].sub_type = POT_DECAY;
-
- break;
- }
- }
-
- mitm[p].plus = 0;
- break;
-
- case OBJ_SCROLLS:
- // determine sub_type:
- if (force_type == OBJ_RANDOM)
- {
- // only used in certain cases {dlb}
- int depth_mod = random2(1 + item_level);
-
- temp_rand = random2(920);
-
- mitm[p].sub_type =
- ((temp_rand > 751) ? SCR_IDENTIFY : // 18.26%
- (temp_rand > 629) ? SCR_REMOVE_CURSE : // 13.26%
- (temp_rand > 554) ? SCR_TELEPORTATION : // 8.15%
- (temp_rand > 494) ? SCR_DETECT_CURSE : // 6.52%
- (temp_rand > 464) ? SCR_FEAR : // 3.26%
- (temp_rand > 434) ? SCR_NOISE : // 3.26%
- (temp_rand > 404) ? SCR_MAGIC_MAPPING : // 3.26%
- (temp_rand > 374) ? SCR_FORGETFULNESS : // 3.26%
- (temp_rand > 344) ? SCR_RANDOM_USELESSNESS :// 3.26%
- (temp_rand > 314) ? SCR_CURSE_WEAPON : // 3.26%
- (temp_rand > 284) ? SCR_CURSE_ARMOUR : // 3.26%
- (temp_rand > 254) ? SCR_RECHARGING : // 3.26%
- (temp_rand > 224) ? SCR_BLINKING : // 3.26%
- (temp_rand > 194) ? SCR_PAPER : // 3.26%
- (temp_rand > 164) ? SCR_ENCHANT_ARMOUR : // 3.26%
- (temp_rand > 134) ? SCR_ENCHANT_WEAPON_I : // 3.26%
- (temp_rand > 104) ? SCR_ENCHANT_WEAPON_II : // 3.26%
-
- // Crawl is kind to newbie adventurers {dlb}:
- // yes -- these five are messy {dlb}:
- // yes they are a hellish mess of tri-ops and long lines,
- // this formating is somewhat better -- bwr
- (temp_rand > 74) ?
- ((item_level < 4) ? SCR_TELEPORTATION
- : SCR_IMMOLATION) : // 3.26%
- (temp_rand > 59) ?
- ((depth_mod < 4) ? SCR_TELEPORTATION
- : SCR_ACQUIREMENT) : // 1.63%
- (temp_rand > 44) ?
- ((depth_mod < 4) ? SCR_DETECT_CURSE
- : SCR_SUMMONING) : // 1.63%
- (temp_rand > 29) ?
- ((depth_mod < 4) ? SCR_TELEPORTATION // 1.63%
- : SCR_ENCHANT_WEAPON_III) :
- (temp_rand > 14) ?
- ((depth_mod < 7) ? SCR_DETECT_CURSE
- : SCR_TORMENT) // 1.63%
- // default:
- : ((depth_mod < 7) ? SCR_TELEPORTATION // 1.63%
- : SCR_VORPALISE_WEAPON));
- }
- else
- mitm[p].sub_type = force_type;
-
- // determine quantity:
- temp_rand = random2(48);
-
- quant = ((temp_rand > 1
- || mitm[p].sub_type == SCR_VORPALISE_WEAPON
- || mitm[p].sub_type == SCR_ENCHANT_WEAPON_III
- || mitm[p].sub_type == SCR_ACQUIREMENT
- || mitm[p].sub_type == SCR_TORMENT) ? 1 : // 95.83%
- (temp_rand == 0) ? 2 // 2.08%
- : 3); // 2.08%
- mitm[p].plus = 0;
- break;
-
- case OBJ_JEWELLERY:
- // determine whether an unrandart will be generated {dlb}:
- if (item_level > 2
- && you.level_type != LEVEL_ABYSS
- && you.level_type != LEVEL_PANDEMONIUM
- && random2(2000) <= 100 + (item_level * 3)
- && one_chance_in(20))
- {
- icky = find_okay_unrandart(OBJ_JEWELLERY);
-
- if (icky != -1)
- {
- quant = 1;
- make_item_unrandart( mitm[p], icky );
- break;
- }
- }
-
- // otherwise, determine jewellery type {dlb}:
- if (force_type == OBJ_RANDOM)
- {
- mitm[p].sub_type = (!one_chance_in(4) ? random2(24) // rings
- : AMU_RAGE + random2(10));
-
- // Adjusted distribution here -- bwr
- if ((mitm[p].sub_type == RING_INVISIBILITY
- || mitm[p].sub_type == RING_REGENERATION
- || mitm[p].sub_type == RING_TELEPORT_CONTROL
- || mitm[p].sub_type == RING_SLAYING)
- && !one_chance_in(3))
- {
- mitm[p].sub_type = random2(24);
- }
- }
- else
- mitm[p].sub_type = force_type;
-
- // quantity is always one {dlb}:
- quant = 1;
-
- // everything begins as uncursed, unenchanted jewellery {dlb}:
- mitm[p].plus = 0;
- mitm[p].plus2 = 0;
-
- // set pluses for rings that require them {dlb}:
- switch (mitm[p].sub_type)
- {
- case RING_PROTECTION:
- case RING_STRENGTH:
- case RING_SLAYING:
- case RING_EVASION:
- case RING_DEXTERITY:
- case RING_INTELLIGENCE:
- if (one_chance_in(5)) // 20% of such rings are cursed {dlb}
- {
- do_curse_item( mitm[p] );
- mitm[p].plus = (coinflip() ? -2 : -3);
-
- if (one_chance_in(3))
- mitm[p].plus -= random2(4);
- }
- else
- {
- mitm[p].plus += 1 + (one_chance_in(3) ? random2(3)
- : random2avg(6, 2));
- }
- break;
-
- default:
- break;
- }
-
- // rings of slaying also require that pluses2 be set {dlb}:
- if (mitm[p].sub_type == RING_SLAYING)
- {
- if (item_cursed( mitm[p] ) && !one_chance_in(20))
- mitm[p].plus2 = -1 - random2avg(6, 2);
- else
- {
- mitm[p].plus2 += 1 + (one_chance_in(3) ? random2(3)
- : random2avg(6, 2));
-
- if (random2(25) < 9) // 36% of such rings {dlb}
- {
- // make "ring of damage"
- do_uncurse_item( mitm[p] );
- mitm[p].plus = 0;
- mitm[p].plus2 += 2;
- }
- }
- }
-
- // All jewellery base types should now work. -- bwr
- if (allow_uniques == 1 && item_level > 2
- && random2(2000) <= 100 + (item_level * 3) && coinflip())
- {
- make_item_randart( mitm[p] );
- break;
- }
-
- // rings of hunger and teleportation are always cursed {dlb}:
- if (mitm[p].sub_type == RING_HUNGER
- || mitm[p].sub_type == RING_TELEPORTATION
- || one_chance_in(50))
- {
- do_curse_item( mitm[p] );
- }
- break;
-
- case OBJ_BOOKS:
- create_book:
- do
- {
- mitm[p].sub_type = random2(NUM_BOOKS);
-
- if (book_rarity(mitm[p].sub_type) == 100)
- continue;
-
- if (mitm[p].sub_type != BOOK_DESTRUCTION
- && mitm[p].sub_type != BOOK_MANUAL)
- {
- if (one_chance_in(10))
- {
- if (coinflip())
- mitm[p].sub_type = BOOK_WIZARDRY;
- else
- mitm[p].sub_type = BOOK_POWER;
- }
-
- if (random2(item_level + 1) + 1 >= book_rarity(mitm[p].sub_type)
- || one_chance_in(100))
- {
- break;
- }
- else
- {
- mitm[p].sub_type = BOOK_DESTRUCTION;
- continue;
- }
- }
- }
- while (mitm[p].sub_type == BOOK_DESTRUCTION
- || mitm[p].sub_type == BOOK_MANUAL);
-
- if (book_rarity(mitm[p].sub_type) == 100)
- goto create_book;
-
- mitm[p].special = random2(5);
-
- if (one_chance_in(10))
- mitm[p].special += random2(8) * 10;
-
- if (force_type != OBJ_RANDOM)
- mitm[p].sub_type = force_type;
-
- quant = 1;
-
- // tome of destruction : rare!
- if (force_type == BOOK_DESTRUCTION
- || (random2(7000) <= item_level + 20 && item_level > 10
- && force_type == OBJ_RANDOM))
- {
- mitm[p].sub_type = BOOK_DESTRUCTION;
- }
-
- // skill manuals - also rare
- // fixed to generate manuals for *all* extant skills - 14mar2000 {dlb}
- if (force_type == BOOK_MANUAL
- || (random2(4000) <= item_level + 20 && item_level > 6
- && force_type == OBJ_RANDOM))
- {
- mitm[p].sub_type = BOOK_MANUAL;
-
- if (one_chance_in(4))
- {
- mitm[p].plus = SK_SPELLCASTING
- + random2(NUM_SKILLS - SK_SPELLCASTING);
- }
- else
- {
- mitm[p].plus = random2(SK_UNARMED_COMBAT);
-
- if (mitm[p].plus == SK_UNUSED_1)
- mitm[p].plus = SK_UNARMED_COMBAT;
- }
- }
- break;
-
- case OBJ_STAVES: // this can be parsed, too {dlb}
- if (force_type != OBJ_RANDOM)
- mitm[p].sub_type = force_type;
- else
- {
- mitm[p].sub_type = random2(13);
-
- // top three non-spell staves are in separate block -- bwr
- if (mitm[p].sub_type >= 10)
- mitm[p].sub_type = STAFF_AIR + mitm[p].sub_type - 10;
-
- // spell staves
- if (one_chance_in(20))
- mitm[p].sub_type = STAFF_SMITING + random2(10);
-
- if ((mitm[p].sub_type == STAFF_ENERGY
- || mitm[p].sub_type == STAFF_CHANNELING) && one_chance_in(4))
- {
- mitm[p].sub_type = coinflip() ? STAFF_WIZARDRY : STAFF_POWER;
- }
- }
-
- mitm[p].special = random2(NUM_STAVE_ADJ);
-
- if (item_is_rod( mitm[p] ))
- {
- mitm[p].plus2 = (9 + random2( MAX_ROD_CHARGE - 8 ))
- * ROD_CHARGE_MULT;
- mitm[p].plus = mitm[p].plus2;
- }
-
- quant = 1;
- break;
-
- case OBJ_ORBS: // always forced in current setup {dlb}
- quant = 1;
-
- if (force_type != OBJ_RANDOM)
- mitm[p].sub_type = force_type;
-
- // I think we only have one type of orb now, so ... {dlb}
- set_unique_item_status( OBJ_ORBS, mitm[p].sub_type, UNIQ_EXISTS );
- break;
-
- // I think these must always be forced, too ... {dlb}
-
- case OBJ_MISCELLANY: //mv: rewrote with use of NUM_MISCELLANY (9 Aug 01)
- if (force_type == OBJ_RANDOM)
- {
- do
- mitm[p].sub_type = random2(NUM_MISCELLANY);
- while //mv: never generated
- ((mitm[p].sub_type == MISC_RUNE_OF_ZOT)
- || (mitm[p].sub_type == MISC_HORN_OF_GERYON)
- || (mitm[p].sub_type == MISC_PORTABLE_ALTAR_OF_NEMELEX)
- // mv: others are possible but less often
- // btw. chances of generating decks are almost the same as
- // before, other chances are now distributed more steadily
- || (mitm[p].sub_type == MISC_DECK_OF_POWER && !one_chance_in(12))
- || (mitm[p].sub_type == MISC_DECK_OF_SUMMONINGS && !one_chance_in(3))
- || (mitm[p].sub_type == MISC_DECK_OF_TRICKS && !one_chance_in(3))
- || (mitm[p].sub_type == MISC_DECK_OF_WONDERS && !one_chance_in(3))
- );
-
- // filling those silly empty boxes -- bwr
- if (mitm[p].sub_type == MISC_EMPTY_EBONY_CASKET
- && !one_chance_in(20))
- {
- mitm[p].sub_type = MISC_BOX_OF_BEASTS;
- }
- }
- else
- {
- mitm[p].sub_type = force_type;
- }
-
- if (mitm[p].sub_type == MISC_DECK_OF_WONDERS
- || mitm[p].sub_type == MISC_DECK_OF_SUMMONINGS
- || mitm[p].sub_type == MISC_DECK_OF_POWER)
- {
- mitm[p].plus = 4 + random2(10);
- }
-
- if (mitm[p].sub_type == MISC_DECK_OF_TRICKS)
- mitm[p].plus = 6 + random2avg(15, 2);
-
- if (mitm[p].sub_type == MISC_RUNE_OF_ZOT)
- mitm[p].plus = item_race;
-
- quant = 1;
- break; // mv: end of rewrote;
-
- // that is, everything turns to gold if not enumerated above, so ... {dlb}
- default:
- mitm[p].base_type = OBJ_GOLD;
-
- // Note that acquirement level gold gives much less than the
- // price of a scroll of acquirement (520 gold). -- bwr
- if (item_level == MAKE_GOOD_ITEM)
- quant = 50 + random2avg(100, 2) + random2avg(100, 2);
- else
- quant = 1 + random2avg(19, 2) + random2(item_level);
- break;
- }
-
- mitm[p].quantity = quant;
-
- // should really only be used for monster inventories.
- if (dont_place)
- {
- mitm[p].x = 0;
- mitm[p].y = 0;
- mitm[p].link = NON_ITEM;
- }
- else
- {
- do
- {
- x_pos = random2(GXM);
- y_pos = random2(GYM);
- }
- while (grd[x_pos][y_pos] != DNGN_FLOOR);
-
- move_item_to_grid( &p, x_pos, y_pos );
- }
-
- item_colour( mitm[p] );
-
- // Okay, this check should be redundant since the purpose of
- // this function is to create valid items. Still, we're adding
- // this safety for fear that a report of Trog giving a non-existant
- // item might symbolize something more serious. -- bwr
- return (is_valid_item( mitm[p] ) ? p : NON_ITEM);
-} // end items()
-
-
-void give_item(int mid, int level_number) //mv: cleanup+minor changes
-{
- int temp_rand = 0; // probability determination {dlb}
-
- int bp = 0;
- int thing_created = 0;
- int hand_used = 0; // for Ettins etc.
- int xitc = 0;
- int xitt = 0;
-
- int iquan = 0;
- // forces colour and quantity, too for intial weapons {dlb}
- int force_item = 0;
-
- int item_race = MAKE_ITEM_RANDOM_RACE;
- int give_level = level_number;
-
- //mv: THIS CODE DISTRIBUTES WANDS/SCROLLS/POTIONS
- //(now only to uniques but it's easy to modify that)
- //7 Aug 01
-
- //mv - give scroll
-
- if (mons_is_unique( menv[mid].type ) && one_chance_in(3))
- {
- thing_created = items(0, OBJ_SCROLLS, OBJ_RANDOM, true, give_level, 0);
- if (thing_created == NON_ITEM)
- return;
-
- mitm[thing_created].flags = 0;
- menv[mid].inv[MSLOT_SCROLL] = thing_created;
- }
-
- //mv - give wand
- if (mons_is_unique( menv[mid].type ) && one_chance_in(5))
- {
- thing_created = items(0, OBJ_WANDS, OBJ_RANDOM, true, give_level, 0);
- if (thing_created == NON_ITEM)
- return;
-
- mitm[thing_created].flags = 0;
- menv[mid].inv[MSLOT_WAND] = thing_created;
- }
-
- //mv - give potion
- if (mons_is_unique( menv[mid].type ) && one_chance_in(3))
- {
- thing_created = items(0, OBJ_POTIONS, OBJ_RANDOM, true, give_level, 0);
- if (thing_created == NON_ITEM)
- return;
-
- mitm[thing_created].flags = 0;
- menv[mid].inv[MSLOT_POTION] = thing_created;
- }
-
-
- //end of DISTRIBUTE WANDS/POTIONS/SCROLLS CODE
-
- bp = get_item_slot();
- if (bp == NON_ITEM)
- return;
-
- mitm[bp].quantity = 0; // set below if force_item, else we toss this item!
- mitm[bp].plus = 0;
- mitm[bp].plus2 = 0;
- mitm[bp].special = 0;
- mitm[bp].orig_place = 0;
- mitm[bp].orig_monnum = 0;
-
- // this flags things to "goto give_armour" below ... {dlb}
- mitm[bp].base_type = 101;
-
- if (menv[mid].type == MONS_DANCING_WEAPON
- && player_in_branch( BRANCH_HALL_OF_BLADES ))
- {
- give_level = MAKE_GOOD_ITEM;
- }
-
- // moved setting of quantity here to keep it in mind {dlb}
- iquan = 1;
- // I wonder if this is even used, given calls to item() {dlb}
-
-
- switch (menv[mid].type)
- {
- case MONS_KOBOLD:
- // a few of the smarter kobolds have blowguns.
- if (one_chance_in(10) && level_number > 1)
- {
- mitm[bp].base_type = OBJ_WEAPONS;
- mitm[bp].sub_type = WPN_BLOWGUN;
- break;
- }
- // intentional fallthrough
- case MONS_BIG_KOBOLD:
- if (random2(5) < 3) // give hand weapon
- {
- mitm[bp].base_type = OBJ_WEAPONS;
-
- temp_rand = random2(5);
- mitm[bp].sub_type = ((temp_rand > 2) ? WPN_DAGGER : // 40%
- (temp_rand > 0) ? WPN_SHORT_SWORD // 40%
- : WPN_CLUB); // 20%
- }
- else if (random2(5) < 2) // give darts
- {
- item_race = MAKE_ITEM_NO_RACE;
- mitm[bp].base_type = OBJ_MISSILES;
- mitm[bp].sub_type = MI_DART;
- iquan = 1 + random2(5);
- }
- else
- goto give_ammo;
- break;
-
- case MONS_HOBGOBLIN:
- if (one_chance_in(3))
- item_race = MAKE_ITEM_ORCISH;
-
- if (random2(5) < 3) // give hand weapon
- {
- mitm[bp].base_type = OBJ_WEAPONS;
- mitm[bp].sub_type = WPN_CLUB;
- }
- else
- goto give_ammo;
- break;
-
- case MONS_GOBLIN:
- if (one_chance_in(3))
- item_race = MAKE_ITEM_ORCISH;
-
- if (one_chance_in(12) && level_number > 1)
- {
- mitm[bp].base_type = OBJ_WEAPONS;
- mitm[bp].base_type = WPN_BLOWGUN;
- break;
- }
- // deliberate fall through {dlb}
- case MONS_JESSICA:
- case MONS_IJYB:
- if (random2(5) < 3) // < 1 // give hand weapon
- {
- mitm[bp].base_type = OBJ_WEAPONS;
- mitm[bp].sub_type = (coinflip() ? WPN_DAGGER : WPN_CLUB);
- }
- else
- goto give_ammo;
- break;
-
- case MONS_WIGHT:
- case MONS_NORRIS:
- mitm[bp].base_type = OBJ_WEAPONS;
- mitm[bp].sub_type = (one_chance_in(6) ? WPN_WAR_AXE + random2(4)
- : WPN_MACE + random2(12));
-
- if (coinflip())
- {
- force_item = 1;
- item_race = MAKE_ITEM_NO_RACE;
- mitm[bp].plus += 1 + random2(3);
- mitm[bp].plus2 += 1 + random2(3);
-
- if (one_chance_in(5))
- set_item_ego_type( mitm[bp], OBJ_WEAPONS, SPWPN_FREEZING );
- }
-
- if (one_chance_in(3))
- do_curse_item( mitm[bp] );
- break;
-
- case MONS_GNOLL:
- case MONS_OGRE_MAGE:
- case MONS_NAGA_WARRIOR:
- case MONS_GREATER_NAGA:
- case MONS_EDMUND:
- case MONS_DUANE:
- item_race = MAKE_ITEM_NO_RACE;
-
- if (!one_chance_in(5))
- {
- mitm[bp].base_type = OBJ_WEAPONS;
-
- temp_rand = random2(5);
- mitm[bp].sub_type = ((temp_rand > 2) ? WPN_SPEAR : // 40%
- (temp_rand == 2) ? WPN_FLAIL : // 20%
- (temp_rand == 1) ? WPN_HALBERD // 20%
- : WPN_CLUB); // 20%
- }
- break;
-
- case MONS_ORC:
- if (one_chance_in(15) && level_number > 1)
- {
- mitm[bp].base_type = OBJ_WEAPONS;
- mitm[bp].base_type = WPN_BLOWGUN;
- break;
- }
- // deliberate fall through {gdl}
- case MONS_ORC_PRIEST:
- case MONS_TERENCE:
- case MONS_DRACONIAN:
- case MONS_DRACONIAN_ZEALOT:
- if (!one_chance_in(5))
- {
- mitm[bp].base_type = OBJ_WEAPONS;
-
- temp_rand = random2(240);
- mitm[bp].sub_type = ((temp_rand > 209) ? WPN_DAGGER : //12.50%
- (temp_rand > 179) ? WPN_CLUB : //12.50%
- (temp_rand > 152) ? WPN_FLAIL : //11.25%
- (temp_rand > 128) ? WPN_HAND_AXE : //10.00%
- (temp_rand > 108) ? WPN_HAMMER : // 8.33%
- (temp_rand > 88) ? WPN_HALBERD : // 8.33%
- (temp_rand > 68) ? WPN_SHORT_SWORD : // 8.33%
- (temp_rand > 48) ? WPN_MACE : // 8.33%
- (temp_rand > 38) ? WPN_WHIP : // 4.17%
- (temp_rand > 28) ? WPN_TRIDENT : // 4.17%
- (temp_rand > 18) ? WPN_FALCHION : // 4.17%
- (temp_rand > 8) ? WPN_MORNINGSTAR : // 4.17%
- (temp_rand > 2) ? WPN_WAR_AXE // 2.50%
- : WPN_SPIKED_FLAIL);// 1.25%
- }
- else
- goto give_ammo;
- break;
-
- case MONS_DEEP_ELF_FIGHTER:
- case MONS_DEEP_ELF_HIGH_PRIEST:
- case MONS_DEEP_ELF_KNIGHT:
- case MONS_DEEP_ELF_PRIEST:
- case MONS_DEEP_ELF_SOLDIER:
- item_race = MAKE_ITEM_ELVEN;
- mitm[bp].base_type = OBJ_WEAPONS;
-
- temp_rand = random2(100);
- mitm[bp].sub_type = ((temp_rand > 79) ? WPN_LONG_SWORD : // 20%
- (temp_rand > 59) ? WPN_SHORT_SWORD : // 20%
- (temp_rand > 45) ? WPN_SCIMITAR : // 14%
- (temp_rand > 31) ? WPN_MACE : // 14%
- (temp_rand > 18) ? WPN_BOW : // 13%
- (temp_rand > 5) ? WPN_HAND_CROSSBOW // 13%
- : WPN_LONGBOW); // 6%
- break;
-
- case MONS_DEEP_ELF_ANNIHILATOR:
- case MONS_DEEP_ELF_CONJURER:
- case MONS_DEEP_ELF_DEATH_MAGE:
- case MONS_DEEP_ELF_DEMONOLOGIST:
- case MONS_DEEP_ELF_MAGE:
- case MONS_DEEP_ELF_SORCERER:
- case MONS_DEEP_ELF_SUMMONER:
- case MONS_DRACONIAN_SHIFTER:
- case MONS_DRACONIAN_SCORCHER:
- case MONS_DRACONIAN_ANNIHILATOR:
- case MONS_DRACONIAN_CALLER:
- item_race = MAKE_ITEM_ELVEN;
- mitm[bp].base_type = OBJ_WEAPONS;
-
- temp_rand = random2(6);
- mitm[bp].sub_type = ((temp_rand > 3) ? WPN_LONG_SWORD : // 2 in 6
- (temp_rand > 2) ? WPN_SHORT_SWORD :// 1 in 6
- (temp_rand > 1) ? WPN_SABRE : // 1 in 6
- (temp_rand > 0) ? WPN_DAGGER // 1 in 6
- : WPN_WHIP); // 1 in 6
- break;
-
- case MONS_ORC_WARRIOR:
- case MONS_ORC_HIGH_PRIEST:
- case MONS_BLORK_THE_ORC:
- item_race = MAKE_ITEM_ORCISH;
- // deliberate fall-through {dlb}
- case MONS_DANCING_WEAPON: // give_level may have been adjusted above
- case MONS_FRANCES:
- case MONS_FRANCIS:
- case MONS_HAROLD:
- case MONS_JOSEPH:
- case MONS_LOUISE:
- case MONS_MICHAEL:
- case MONS_NAGA:
- case MONS_NAGA_MAGE:
- case MONS_RUPERT:
- case MONS_SKELETAL_WARRIOR:
- case MONS_WAYNE:
- case MONS_PALE_DRACONIAN:
- case MONS_RED_DRACONIAN:
- case MONS_WHITE_DRACONIAN:
- case MONS_GREEN_DRACONIAN:
- case MONS_MOTTLED_DRACONIAN:
- case MONS_BLACK_DRACONIAN:
- case MONS_YELLOW_DRACONIAN:
- case MONS_PURPLE_DRACONIAN:
- mitm[bp].base_type = OBJ_WEAPONS;
-
- temp_rand = random2(120);
- mitm[bp].sub_type = ((temp_rand > 109) ? WPN_LONG_SWORD : // 8.33%
- (temp_rand > 99) ? WPN_SHORT_SWORD : // 8.33%
- (temp_rand > 89) ? WPN_SCIMITAR : // 8.33%
- (temp_rand > 79) ? WPN_BATTLEAXE : // 8.33%
- (temp_rand > 69) ? WPN_HAND_AXE : // 8.33%
- (temp_rand > 59) ? WPN_HALBERD : // 8.33%
- (temp_rand > 49) ? WPN_GLAIVE : // 8.33%
- (temp_rand > 39) ? WPN_MORNINGSTAR : // 8.33%
- (temp_rand > 29) ? WPN_GREAT_MACE : // 8.33%
- (temp_rand > 19) ? WPN_TRIDENT : // 8.33%
- (temp_rand > 10) ? WPN_WAR_AXE : // 7.50%
- (temp_rand > 1) ? WPN_FLAIL : // 7.50%
- (temp_rand > 0) ? WPN_BROAD_AXE // 0.83%
- : WPN_SPIKED_FLAIL); // 0.83%
- break;
-
- case MONS_ORC_WARLORD:
- // being at the top has it's priviledges
- if (one_chance_in(3))
- give_level = MAKE_GOOD_ITEM;
- // deliberate fall-through
- case MONS_ORC_KNIGHT:
- item_race = MAKE_ITEM_ORCISH;
- // deliberate fall-through, I guess {dlb}
- case MONS_NORBERT:
- case MONS_JOZEF:
- case MONS_URUG:
- case MONS_VAULT_GUARD:
- case MONS_VAMPIRE_KNIGHT:
- case MONS_DRACONIAN_KNIGHT:
- mitm[bp].base_type = OBJ_WEAPONS;
-
- temp_rand = random2(25);
- mitm[bp].sub_type = ((temp_rand > 20) ? WPN_GREAT_SWORD : // 16%
- (temp_rand > 16) ? WPN_LONG_SWORD : // 16%
- (temp_rand > 12) ? WPN_BATTLEAXE : // 16%
- (temp_rand > 8) ? WPN_WAR_AXE : // 16%
- (temp_rand > 5) ? WPN_GREAT_MACE : // 12%
- (temp_rand > 3) ? WPN_DIRE_FLAIL : // 8%
- (temp_rand > 2) ? WPN_LOCHABER_AXE : // 4%
- (temp_rand > 1) ? WPN_GLAIVE : // 4%
- (temp_rand > 0) ? WPN_BROAD_AXE // 4%
- : WPN_HALBERD); // 4%
-
- if (one_chance_in(4))
- mitm[bp].plus += 1 + random2(3);
- break;
-
- case MONS_CYCLOPS:
- case MONS_STONE_GIANT:
- item_race = MAKE_ITEM_NO_RACE;
- mitm[bp].base_type = OBJ_MISSILES;
- mitm[bp].sub_type = MI_LARGE_ROCK;
- break;
-
- case MONS_TWO_HEADED_OGRE:
- case MONS_ETTIN:
- item_race = MAKE_ITEM_NO_RACE;
- hand_used = 0;
-
- if (menv[mid].inv[MSLOT_WEAPON] != NON_ITEM)
- hand_used = 1;
-
- mitm[bp].base_type = OBJ_WEAPONS;
- mitm[bp].sub_type = (one_chance_in(3) ? WPN_GIANT_SPIKED_CLUB
- : WPN_GIANT_CLUB);
-
- if (one_chance_in(10) || menv[mid].type == MONS_ETTIN)
- {
- mitm[bp].sub_type = ((one_chance_in(10)) ? WPN_DIRE_FLAIL
- : WPN_GREAT_MACE);
- }
- break;
-
- case MONS_REAPER:
- give_level = MAKE_GOOD_ITEM;
- // intentional fall-through...
-
- case MONS_SIGMUND:
- item_race = MAKE_ITEM_NO_RACE;
- mitm[bp].base_type = OBJ_WEAPONS;
- mitm[bp].sub_type = WPN_SCYTHE;
- break;
-
- case MONS_BALRUG:
- item_race = MAKE_ITEM_NO_RACE;
- mitm[bp].base_type = OBJ_WEAPONS;
- mitm[bp].sub_type = WPN_DEMON_WHIP;
- break;
-
- case MONS_RED_DEVIL:
- if (!one_chance_in(3))
- {
- item_race = MAKE_ITEM_NO_RACE;
- mitm[bp].base_type = OBJ_WEAPONS;
- mitm[bp].sub_type = (one_chance_in(3) ? WPN_DEMON_TRIDENT
- : WPN_TRIDENT);
- }
- break;
-
- case MONS_OGRE:
- case MONS_HILL_GIANT:
- case MONS_EROLCHA:
- item_race = MAKE_ITEM_NO_RACE;
- mitm[bp].base_type = OBJ_WEAPONS;
-
- mitm[bp].sub_type = (one_chance_in(3) ? WPN_GIANT_SPIKED_CLUB
- : WPN_GIANT_CLUB);
-
- if (one_chance_in(10))
- {
- mitm[bp].sub_type = (one_chance_in(10) ? WPN_DIRE_FLAIL
- : WPN_GREAT_MACE);
- }
- break;
-
- case MONS_CENTAUR:
- case MONS_CENTAUR_WARRIOR:
- item_race = MAKE_ITEM_NO_RACE;
- mitm[bp].base_type = OBJ_WEAPONS;
- mitm[bp].sub_type = WPN_BOW;
- if (menv[mid].type == MONS_CENTAUR_WARRIOR
- && one_chance_in(3))
- mitm[bp].sub_type = WPN_LONGBOW;
- break;
-
- case MONS_YAKTAUR:
- case MONS_YAKTAUR_CAPTAIN:
- item_race = MAKE_ITEM_NO_RACE;
- mitm[bp].base_type = OBJ_WEAPONS;
- mitm[bp].sub_type = WPN_CROSSBOW;
- break;
-
- case MONS_EFREET:
- case MONS_ERICA:
- force_item = 1;
- item_race = MAKE_ITEM_NO_RACE;
- mitm[bp].base_type = OBJ_WEAPONS;
- mitm[bp].sub_type = WPN_SCIMITAR;
- mitm[bp].plus = random2(5);
- mitm[bp].plus2 = random2(5);
- mitm[bp].colour = RED; // forced by force_item above {dlb}
- set_item_ego_type( mitm[bp], OBJ_WEAPONS, SPWPN_FLAMING );
- break;
-
- case MONS_ANGEL:
- force_item = 1;
- mitm[bp].base_type = OBJ_WEAPONS;
- mitm[bp].colour = WHITE; // forced by force_item above {dlb}
-
- set_equip_desc( mitm[bp], ISFLAG_GLOWING );
- if (one_chance_in(3))
- {
- mitm[bp].sub_type = (one_chance_in(3) ? WPN_GREAT_MACE : WPN_MACE);
- set_item_ego_type( mitm[bp], OBJ_WEAPONS, SPWPN_HOLY_WRATH );
- }
- else
- {
- mitm[bp].sub_type = WPN_LONG_SWORD;
- }
-
- mitm[bp].plus = 1 + random2(3);
- mitm[bp].plus2 = 1 + random2(3);
- break;
-
- case MONS_DAEVA:
- force_item = 1;
- mitm[bp].base_type = OBJ_WEAPONS;
- mitm[bp].colour = WHITE; // forced by force_item above {dlb}
-
- mitm[bp].sub_type = (one_chance_in(4) ? WPN_BLESSED_BLADE
- : WPN_LONG_SWORD);
-
- set_equip_desc( mitm[bp], ISFLAG_GLOWING );
- set_item_ego_type( mitm[bp], OBJ_WEAPONS, SPWPN_HOLY_WRATH );
- mitm[bp].plus = 1 + random2(3);
- mitm[bp].plus2 = 1 + random2(3);
- break;
-
- case MONS_HELL_KNIGHT:
- case MONS_MAUD:
- case MONS_ADOLF:
- case MONS_MARGERY:
- force_item = 1;
- mitm[bp].base_type = OBJ_WEAPONS;
- mitm[bp].sub_type = WPN_LONG_SWORD + random2(3);
-
- if (one_chance_in(7))
- mitm[bp].sub_type = WPN_HALBERD;
- if (one_chance_in(7))
- mitm[bp].sub_type = WPN_GLAIVE;
- if (one_chance_in(7))
- mitm[bp].sub_type = WPN_GREAT_MACE;
- if (one_chance_in(7))
- mitm[bp].sub_type = WPN_BATTLEAXE;
- if (one_chance_in(7))
- mitm[bp].sub_type = WPN_WAR_AXE;
- if (one_chance_in(7))
- mitm[bp].sub_type = WPN_BROAD_AXE;
- if (one_chance_in(7))
- mitm[bp].sub_type = WPN_DEMON_TRIDENT;
- if (one_chance_in(7))
- mitm[bp].sub_type = WPN_DEMON_BLADE;
- if (one_chance_in(7))
- mitm[bp].sub_type = WPN_DEMON_WHIP;
-
- temp_rand = random2(3);
- set_equip_desc( mitm[bp], (temp_rand == 1) ? ISFLAG_GLOWING :
- (temp_rand == 2) ? ISFLAG_RUNED
- : ISFLAG_NO_DESC );
-
- if (one_chance_in(3))
- set_item_ego_type( mitm[bp], OBJ_WEAPONS, SPWPN_FLAMING );
- else if (one_chance_in(3))
- {
- temp_rand = random2(5);
-
- set_item_ego_type( mitm[bp], OBJ_WEAPONS,
- ((temp_rand == 0) ? SPWPN_DRAINING :
- (temp_rand == 1) ? SPWPN_VORPAL :
- (temp_rand == 2) ? SPWPN_PAIN :
- (temp_rand == 3) ? SPWPN_DISTORTION
- : SPWPN_SPEED) );
- }
-
- mitm[bp].plus += random2(6);
- mitm[bp].plus2 += random2(6);
-
- mitm[bp].colour = RED; // forced by force_item above {dlb}
-
- if (one_chance_in(3))
- mitm[bp].colour = DARKGREY;
- if (one_chance_in(5))
- mitm[bp].colour = CYAN;
- break;
-
- case MONS_FIRE_GIANT:
- force_item = 1;
- mitm[bp].base_type = OBJ_WEAPONS;
- mitm[bp].sub_type = WPN_GREAT_SWORD;
- mitm[bp].plus = 0;
- mitm[bp].plus2 = 0;
- set_item_ego_type( mitm[bp], OBJ_WEAPONS, SPWPN_FLAMING );
-
- mitm[bp].colour = RED; // forced by force_item above {dlb}
- if (one_chance_in(3))
- mitm[bp].colour = DARKGREY;
- if (one_chance_in(5))
- mitm[bp].colour = CYAN;
- break;
-
- case MONS_FROST_GIANT:
- force_item = 1;
- mitm[bp].base_type = OBJ_WEAPONS;
- mitm[bp].sub_type = WPN_BATTLEAXE;
- mitm[bp].plus = 0;
- mitm[bp].plus2 = 0;
- set_item_ego_type( mitm[bp], OBJ_WEAPONS, SPWPN_FREEZING );
-
- // forced by force_item above {dlb}
- mitm[bp].colour = (one_chance_in(3) ? WHITE : CYAN);
- break;
-
- case MONS_KOBOLD_DEMONOLOGIST:
- case MONS_ORC_WIZARD:
- case MONS_ORC_SORCERER:
- item_race = MAKE_ITEM_ORCISH;
- // deliberate fall-through, I guess {dlb}
- case MONS_NECROMANCER:
- case MONS_WIZARD:
- case MONS_PSYCHE:
- case MONS_DONALD:
- case MONS_JOSEPHINE:
- case MONS_AGNES:
- mitm[bp].base_type = OBJ_WEAPONS;
- mitm[bp].sub_type = WPN_DAGGER;
- break;
-
- case MONS_CEREBOV:
- force_item = 1;
- make_item_fixed_artefact( mitm[bp], false, SPWPN_SWORD_OF_CEREBOV );
- break;
-
- case MONS_DISPATER:
- force_item = 1;
- make_item_fixed_artefact( mitm[bp], false, SPWPN_STAFF_OF_DISPATER );
- break;
-
- case MONS_ASMODEUS:
- force_item = 1;
- make_item_fixed_artefact( mitm[bp], false, SPWPN_SCEPTRE_OF_ASMODEUS );
- break;
-
- case MONS_GERYON:
- //mv: probably should be moved out of this switch,
- //but it's not worth of it, unless we have more
- //monsters with misc. items
- mitm[bp].base_type = OBJ_MISCELLANY;
- mitm[bp].sub_type = MISC_HORN_OF_GERYON;
- break;
-
- case MONS_SALAMANDER: //mv: new 8 Aug 2001
- //Yes, they've got really nice items, but
- //it's almost impossible to get them
- force_item = 1;
- item_race = MAKE_ITEM_NO_RACE;
- mitm[bp].base_type = OBJ_WEAPONS;
- temp_rand = random2(6);
-
- mitm[bp].sub_type = ((temp_rand == 5) ? WPN_GREAT_SWORD :
- (temp_rand == 4) ? WPN_TRIDENT :
- (temp_rand == 3) ? WPN_SPEAR :
- (temp_rand == 2) ? WPN_GLAIVE :
- (temp_rand == 1) ? WPN_BOW
- : WPN_HALBERD);
-
- if (mitm[bp].sub_type == WPN_BOW)
- set_item_ego_type( mitm[bp], OBJ_WEAPONS, SPWPN_FLAME );
- else
- set_item_ego_type( mitm[bp], OBJ_WEAPONS, SPWPN_FLAMING );
-
- mitm[bp].plus = random2(5);
- mitm[bp].plus2 = random2(5);
- mitm[bp].colour = RED; // forced by force_item above {dlb}
- break;
- } // end "switch(menv[mid].type)"
-
- // only happens if something in above switch doesn't set it {dlb}
- if (mitm[bp].base_type == 101)
- {
- mitm[bp].base_type = OBJ_UNASSIGNED;
- goto give_ammo;
- }
-
- mitm[bp].x = 0;
- mitm[bp].y = 0;
- mitm[bp].link = NON_ITEM;
-
- if (force_item)
- mitm[bp].quantity = iquan;
- else if (mons_is_unique( menv[mid].type ))
- {
- if (random2(100) <= 9 + menv[mid].hit_dice)
- give_level = MAKE_GOOD_ITEM;
- else
- give_level = level_number + 5;
- }
-
- xitc = mitm[bp].base_type;
- xitt = mitm[bp].sub_type;
-
- // Note this mess, all the work above doesn't mean much unless
- // force_item is set... otherwise we're just going to take the
- // base and subtypes and create a new item. -- bwr
- thing_created = ((force_item) ? bp : items( 0, xitc, xitt, true,
- give_level, item_race) );
-
- if (thing_created == NON_ITEM)
- return;
-
- mitm[thing_created].x = 0;
- mitm[thing_created].y = 0;
- mitm[thing_created].link = NON_ITEM;
- unset_ident_flags( mitm[thing_created], ISFLAG_IDENT_MASK );
-
- //mv: now every item gets in appropriate slot
- //no more miscellany in potion slot etc. (19 May 2001)
- // hand_used = 0 unless Ettin's 2nd hand etc.
- if ( mitm[thing_created].base_type == OBJ_WEAPONS )
- menv[mid].inv[hand_used] = thing_created;
- else if ( mitm[thing_created].base_type == OBJ_MISSILES )
- menv[mid].inv[MSLOT_MISSILE] = thing_created;
- else if ( mitm[thing_created].base_type == OBJ_SCROLLS )
- menv[mid].inv[MSLOT_SCROLL] = thing_created;
- else if ( mitm[thing_created].base_type == OBJ_GOLD )
- menv[mid].inv[MSLOT_GOLD] = thing_created;
- else if ( mitm[thing_created].base_type == OBJ_POTIONS )
- menv[mid].inv[MSLOT_POTION] = thing_created;
- else if ( mitm[thing_created].base_type == OBJ_MISCELLANY )
- menv[mid].inv[MSLOT_MISCELLANY] = thing_created;
-
-
- if (get_weapon_brand( mitm[thing_created] ) == SPWPN_PROTECTION )
- menv[mid].armour_class += 5;
-
- if (!force_item || mitm[thing_created].colour == BLACK)
- item_colour( mitm[thing_created] );
-
- give_ammo:
- // mv: gives ammunition
- // note that item_race is not reset for this section
- if (menv[mid].inv[MSLOT_WEAPON] != NON_ITEM
- && launches_things( mitm[menv[mid].inv[MSLOT_WEAPON]].sub_type ))
- {
- xitc = OBJ_MISSILES;
- xitt = launched_by(mitm[menv[mid].inv[MSLOT_WEAPON]].sub_type);
-
- thing_created = items( 0, xitc, xitt, true, give_level, item_race );
- if (thing_created == NON_ITEM)
- return;
-
- // monsters will always have poisoned needles -- otherwise
- // they are just going to behave badly --GDL
- if (xitt == MI_NEEDLE)
- set_item_ego_type(mitm[thing_created], OBJ_MISSILES,
- got_curare_roll(give_level)?
- SPMSL_CURARE
- : SPMSL_POISONED);
-
- mitm[thing_created].x = 0;
- mitm[thing_created].y = 0;
- mitm[thing_created].flags = 0;
- menv[mid].inv[MSLOT_MISSILE] = thing_created;
-
- item_colour( mitm[thing_created] );
- } // end if needs ammo
-
- bp = get_item_slot();
- if (bp == NON_ITEM)
- return;
-
- mitm[bp].x = 0;
- mitm[bp].y = 0;
- mitm[bp].link = NON_ITEM;
- mitm[bp].orig_place = 0;
- mitm[bp].orig_monnum = 0;
-
- item_race = MAKE_ITEM_RANDOM_RACE;
- give_level = 1 + (level_number / 2);
-
- int force_colour = 0; //mv: important !!! Items with force_colour = 0
- //are colored defaultly after following
- //switch. Others will get force_colour.
-
- switch (menv[mid].type)
- {
- case MONS_DEEP_ELF_ANNIHILATOR:
- case MONS_DEEP_ELF_CONJURER:
- case MONS_DEEP_ELF_DEATH_MAGE:
- case MONS_DEEP_ELF_DEMONOLOGIST:
- case MONS_DEEP_ELF_FIGHTER:
- case MONS_DEEP_ELF_HIGH_PRIEST:
- case MONS_DEEP_ELF_KNIGHT:
- case MONS_DEEP_ELF_MAGE:
- case MONS_DEEP_ELF_PRIEST:
- case MONS_DEEP_ELF_SOLDIER:
- case MONS_DEEP_ELF_SORCERER:
- case MONS_DEEP_ELF_SUMMONER:
- if (item_race == MAKE_ITEM_RANDOM_RACE)
- item_race = MAKE_ITEM_ELVEN;
- // deliberate fall through {dlb}
- case MONS_IJYB:
- case MONS_ORC:
- case MONS_ORC_HIGH_PRIEST:
- case MONS_ORC_PRIEST:
- case MONS_ORC_SORCERER:
- if (item_race == MAKE_ITEM_RANDOM_RACE)
- item_race = MAKE_ITEM_ORCISH;
- // deliberate fall through {dlb}
- case MONS_ERICA:
- case MONS_HAROLD:
- case MONS_JOSEPH:
- case MONS_JOSEPHINE:
- case MONS_JOZEF:
- case MONS_NORBERT:
- case MONS_PSYCHE:
- case MONS_TERENCE:
- if (random2(5) < 2)
- {
- mitm[bp].base_type = OBJ_ARMOUR;
-
- switch (random2(8))
- {
- case 0:
- case 1:
- case 2:
- case 3:
- mitm[bp].sub_type = ARM_LEATHER_ARMOUR;
- break;
- case 4:
- case 5:
- mitm[bp].sub_type = ARM_RING_MAIL;
- break;
- case 6:
- mitm[bp].sub_type = ARM_SCALE_MAIL;
- break;
- case 7:
- mitm[bp].sub_type = ARM_CHAIN_MAIL;
- break;
- }
- }
- else
- return;
- break;
-
- case MONS_DUANE:
- case MONS_EDMUND:
- case MONS_RUPERT:
- case MONS_URUG:
- case MONS_WAYNE:
- mitm[bp].base_type = OBJ_ARMOUR;
- mitm[bp].sub_type = ARM_LEATHER_ARMOUR + random2(4);
- break;
-
- case MONS_ORC_WARLORD:
- // being at the top has it's priviledges
- if (one_chance_in(3))
- give_level = MAKE_GOOD_ITEM;
- // deliberate fall through
- case MONS_ORC_KNIGHT:
- case MONS_ORC_WARRIOR:
- if (item_race == MAKE_ITEM_RANDOM_RACE)
- item_race = MAKE_ITEM_ORCISH;
- // deliberate fall through {dlb}
- case MONS_ADOLF:
- case MONS_HELL_KNIGHT:
- case MONS_LOUISE:
- case MONS_MARGERY:
- case MONS_MAUD:
- case MONS_VAMPIRE_KNIGHT:
- case MONS_VAULT_GUARD:
- mitm[bp].base_type = OBJ_ARMOUR;
- mitm[bp].sub_type = ARM_CHAIN_MAIL + random2(4);
- break;
-
- case MONS_ANGEL:
- case MONS_SIGMUND:
- case MONS_WIGHT:
- item_race = MAKE_ITEM_NO_RACE;
- mitm[bp].base_type = OBJ_ARMOUR;
- mitm[bp].sub_type = ARM_ROBE;
- force_colour = WHITE; //mv: always white
- break;
-
- case MONS_NAGA:
- case MONS_NAGA_MAGE:
- case MONS_NAGA_WARRIOR:
- if (!one_chance_in(3))
- return;
- // deliberate fall through {dlb}
- case MONS_DONALD:
- case MONS_GREATER_NAGA:
- case MONS_JESSICA:
- case MONS_KOBOLD_DEMONOLOGIST:
- case MONS_OGRE_MAGE:
- case MONS_DRACONIAN:
- case MONS_RED_DRACONIAN:
- case MONS_WHITE_DRACONIAN:
- case MONS_GREEN_DRACONIAN:
- case MONS_PALE_DRACONIAN:
- case MONS_MOTTLED_DRACONIAN:
- case MONS_BLACK_DRACONIAN:
- case MONS_YELLOW_DRACONIAN:
- case MONS_PURPLE_DRACONIAN:
- case MONS_DRACONIAN_SHIFTER:
- case MONS_DRACONIAN_SCORCHER:
- case MONS_DRACONIAN_ANNIHILATOR:
- case MONS_DRACONIAN_CALLER:
- case MONS_DRACONIAN_MONK:
- case MONS_DRACONIAN_ZEALOT:
- case MONS_DRACONIAN_KNIGHT:
- case MONS_ORC_WIZARD:
- case MONS_WIZARD:
- item_race = MAKE_ITEM_NO_RACE;
- mitm[bp].base_type = OBJ_ARMOUR;
- mitm[bp].sub_type = ARM_ROBE;
- break;
-
- case MONS_BORIS:
- give_level = MAKE_GOOD_ITEM;
- // fall-through
- case MONS_AGNES:
- case MONS_BLORK_THE_ORC:
- case MONS_FRANCES:
- case MONS_FRANCIS:
- case MONS_NECROMANCER:
- case MONS_VAMPIRE_MAGE:
- mitm[bp].base_type = OBJ_ARMOUR;
- mitm[bp].sub_type = ARM_ROBE;
- force_colour = DARKGREY; //mv: always darkgrey
- break;
-
- default:
- return;
- } // end of switch(menv [mid].type)
-
- iquan = 1; //because it may have been set earlier
- //by giving ammo or weapons {dlb}
-
- xitc = mitm[bp].base_type;
- xitt = mitm[bp].sub_type;
-
- if (mons_is_unique( menv[mid].type ) && give_level != MAKE_GOOD_ITEM)
- {
- if (random2(100) < 9 + menv[mid].hit_dice)
- give_level = MAKE_GOOD_ITEM;
- else
- give_level = level_number + 5;
- }
-
- thing_created = items( 0, xitc, xitt, true, give_level, item_race );
-
- if (thing_created == NON_ITEM)
- return;
-
- mitm[thing_created].x = 0;
- mitm[thing_created].y = 0;
- mitm[thing_created].link = NON_ITEM;
- menv[mid].inv[MSLOT_ARMOUR] = thing_created;
-
- //mv: all items with force_colour = 0 are colored via items().
- if (force_colour)
- mitm[thing_created].colour = force_colour;
-
- menv[mid].armour_class += property( mitm[thing_created], PARM_AC );
-
- const int armour_plus = mitm[thing_created].plus;
-
- ASSERT(abs(armour_plus) < 20);
-
- if (abs(armour_plus) < 20)
- menv[mid].armour_class += armour_plus;
-
- menv[mid].evasion += property( mitm[thing_created], PARM_EVASION ) / 2;
-
- if (menv[mid].evasion < 1)
- menv[mid].evasion = 1; // This *shouldn't* happen.
-} // end give_item()
-
-//---------------------------------------------------------------------------
-// PRIVATE HELPER FUNCTIONS
-//---------------------------------------------------------------------------
-
-static bool is_weapon_special(int the_weapon)
-{
- return (mitm[the_weapon].special != SPWPN_NORMAL);
-} // end is_weapon_special()
-
-static void set_weapon_special(int the_weapon, int spwpn)
-{
- set_item_ego_type( mitm[the_weapon], OBJ_WEAPONS, spwpn );
-} // end set_weapon_special()
-
-static void check_doors(void)
-{
- unsigned char ig;
- unsigned char solid_count = 0; // clarifies innermost loop {dlb}
- int x,y;
-
- for (x = 1; x < GXM-1; x++)
- {
- for (y = 1; y < GYM-1; y++)
- {
- ig = grd[x][y];
-
- if (ig != DNGN_CLOSED_DOOR)
- continue;
-
- solid_count = 0;
-
- // first half of each conditional represents bounds checking {dlb}:
- if (grid_is_solid( grd[x - 1][y] ))
- solid_count++;
-
- if (grid_is_solid( grd[x + 1][y] ))
- solid_count++;
-
- if (grid_is_solid( grd[x][y - 1] ))
- solid_count++;
-
- if (grid_is_solid( grd[x][y + 1] ))
- solid_count++;
-
- grd[x][y] = ((solid_count < 2) ? DNGN_FLOOR : DNGN_CLOSED_DOOR);
- }
- }
-} // end check_doors()
-
-static void hide_doors(void)
-{
- unsigned char dx = 0, dy = 0; // loop variables
- unsigned char wall_count = 0; // clarifies inner loop {dlb}
-
- for (dx = 1; dx < GXM-1; dx++)
- {
- for (dy = 1; dy < GYM-1; dy++)
- {
- // only one out of four doors are candidates for hiding {gdl}:
- if (grd[dx][dy] == DNGN_CLOSED_DOOR && one_chance_in(4))
- {
- wall_count = 0;
-
- if (grd[dx - 1][dy] == DNGN_ROCK_WALL)
- wall_count++;
-
- if (grd[dx + 1][dy] == DNGN_ROCK_WALL)
- wall_count++;
-
- if (grd[dx][dy - 1] == DNGN_ROCK_WALL)
- wall_count++;
-
- if (grd[dx][dy + 1] == DNGN_ROCK_WALL)
- wall_count++;
-
- // if door is attached to more than one wall, hide it {dlb}:
- if (wall_count > 1)
- grd[dx][dy] = DNGN_SECRET_DOOR;
- }
- }
- }
-} // end hide_doors()
-
-static void prepare_swamp(void)
-{
- int i, j; // loop variables
- int temp_rand; // probability determination {dlb}
-
- for (i = 10; i < (GXM - 10); i++)
- {
- for (j = 10; j < (GYM - 10); j++)
- {
- // doors -> floors {dlb}
- if (grd[i][j] == DNGN_CLOSED_DOOR || grd[i][j] == DNGN_SECRET_DOOR)
- grd[i][j] = DNGN_FLOOR;
-
- // floors -> shallow water 1 in 3 times {dlb}
- if (grd[i][j] == DNGN_FLOOR && one_chance_in(3))
- grd[i][j] = DNGN_SHALLOW_WATER;
-
- // walls -> deep/shallow water or remain unchanged {dlb}
- if (grd[i][j] == DNGN_ROCK_WALL)
- {
- temp_rand = random2(6);
-
- if (temp_rand > 0) // 17% chance unchanged {dlb}
- {
- grd[i][j] = ((temp_rand > 2) ? DNGN_SHALLOW_WATER // 50%
- : DNGN_DEEP_WATER); // 33%
- }
- }
- }
- }
-} // end prepare_swamp()
-
-// Gives water which is next to ground/shallow water a chance of being
-// shallow. Checks each water space.
-static void prepare_water( int level_number )
-{
- int i, j, k, l; // loop variables {dlb}
- unsigned char which_grid; // code compaction {dlb}
-
- for (i = 10; i < (GXM - 10); i++)
- {
- for (j = 10; j < (GYM - 10); j++)
- {
- if (grd[i][j] == DNGN_DEEP_WATER)
- {
- for (k = -1; k < 2; k++)
- {
- for (l = -1; l < 2; l++)
- {
- if (k != 0 || l != 0)
- {
- which_grid = grd[i + k][j + l];
-
- // must come first {dlb}
- if (which_grid == DNGN_SHALLOW_WATER
- && one_chance_in( 8 + level_number ))
- {
- grd[i][j] = DNGN_SHALLOW_WATER;
- }
- else if (which_grid >= DNGN_FLOOR
- && random2(100) < 80 - level_number * 4)
- {
- grd[i][j] = DNGN_SHALLOW_WATER;
- }
- }
- }
- }
- }
- }
- }
-} // end prepare_water()
-
-static bool find_in_area(int sx, int sy, int ex, int ey, unsigned char feature)
-{
- int x,y;
-
- if (feature != 0)
- {
- for(x = sx; x <= ex; x++)
- {
- for(y = sy; y <= ey; y++)
- {
- if (grd[x][y] == feature)
- return (true);
- }
- }
- }
-
- return (false);
-}
-
-// stamp a box. can avoid a possible type, and walls and floors can
-// be different (or not stamped at all)
-// Note that the box boundaries are INclusive.
-static bool make_box(int room_x1, int room_y1, int room_x2, int room_y2,
- unsigned char floor, unsigned char wall, unsigned char avoid)
-{
- int bx,by;
-
- // check for avoidance
- if (find_in_area(room_x1, room_y1, room_x2, room_y2, avoid))
- return false;
-
- // draw walls
- if (wall != 0)
- {
- for(bx=room_x1; bx<=room_x2; bx++)
- {
- grd[bx][room_y1] = wall;
- grd[bx][room_y2] = wall;
- }
- for(by=room_y1+1; by<room_y2; by++)
- {
- grd[room_x1][by] = wall;
- grd[room_x2][by] = wall;
- }
- }
-
- // draw floor
- if (floor != 0)
- {
- for(bx=room_x1 + 1; bx < room_x2; bx++)
- for(by=room_y1 + 1; by < room_y2; by++)
- grd[bx][by] = floor;
- }
-
- return true;
-}
-
-// take care of labyrinth, abyss, pandemonium
-// returns 1 if we should skip further generation,
-// -1 if we should immediately quit, and 0 otherwise.
-static int builder_by_type(int level_number, char level_type)
-{
- if (level_type == LEVEL_LABYRINTH)
- {
- labyrinth_level(level_number);
- return -1;
- }
-
- if (level_type == LEVEL_ABYSS)
- {
- generate_abyss();
- return 1;
- }
-
- if (level_type == LEVEL_PANDEMONIUM)
- {
- char which_demon = -1;
- // Could do spotty_level, but that doesn't always put all paired
- // stairs reachable from each other which isn't a problem in normal
- // dungeon but could be in Pandemonium
- if (one_chance_in(15))
- {
- do
- {
- which_demon = random2(4);
-
- // makes these things less likely as you find more
- if (one_chance_in(4))
- {
- which_demon = -1;
- break;
- }
- }
- while (you.unique_creatures[40 + which_demon] == 1);
- }
-
- if (which_demon >= 0)
- {
- you.unique_creatures[40 + which_demon] = 1;
- build_vaults(level_number, which_demon + 60);
- }
- else
- {
- plan_main(level_number, 0);
- build_minivaults(level_number, 300 + random2(9));
- }
-
- return 1;
- }
-
- // must be normal dungeon
- return 0;
-}
-
-// returns 1 if we should skip further generation,
-// -1 if we should immediately quit, and 0 otherwise.
-static int builder_by_branch(int level_number)
-{
- switch (you.where_are_you)
- {
- case BRANCH_HIVE:
- if (level_number == you.branch_stairs[STAIRS_HIVE]
- + branch_depth(STAIRS_HIVE))
- build_vaults(level_number, 80);
- else
- spotty_level(false, 100 + random2(500), false);
- return 1;
-
- case BRANCH_SLIME_PITS:
- if (level_number == you.branch_stairs[STAIRS_SLIME_PITS]
- + branch_depth(STAIRS_SLIME_PITS))
- {
- build_vaults(level_number, 81);
- }
- else
- spotty_level(false, 100 + random2(500), false);
- return 1;
-
- case BRANCH_VAULTS:
- if (level_number == you.branch_stairs[STAIRS_VAULTS]
- + branch_depth(STAIRS_VAULTS))
- {
- build_vaults(level_number, 82);
- return 1;
- }
- break;
-
- case BRANCH_HALL_OF_BLADES:
- if (level_number == you.branch_stairs[STAIRS_HALL_OF_BLADES]
- + branch_depth(STAIRS_HALL_OF_BLADES))
- {
- build_vaults(level_number, 83);
- return 1;
- }
- break;
-
- case BRANCH_HALL_OF_ZOT:
- if (level_number == you.branch_stairs[STAIRS_HALL_OF_ZOT]
- + branch_depth(STAIRS_HALL_OF_ZOT))
- {
- build_vaults(level_number, 84);
- return 1;
- }
- break;
-
- case BRANCH_ECUMENICAL_TEMPLE:
- if (level_number == you.branch_stairs[STAIRS_ECUMENICAL_TEMPLE]
- + branch_depth(STAIRS_ECUMENICAL_TEMPLE))
- {
- build_vaults(level_number, 85);
- return 1;
- }
- break;
-
- case BRANCH_SNAKE_PIT:
- if (level_number == you.branch_stairs[STAIRS_SNAKE_PIT]
- + branch_depth(STAIRS_SNAKE_PIT))
- {
- build_vaults(level_number, 86);
- return 1;
- }
- break;
-
- case BRANCH_ELVEN_HALLS:
- if (level_number == you.branch_stairs[STAIRS_ELVEN_HALLS]
- + branch_depth(STAIRS_ELVEN_HALLS))
- {
- build_vaults(level_number, 87);
- return 1;
- }
- break;
-
- case BRANCH_TOMB:
- if (level_number == you.branch_stairs[STAIRS_TOMB] + 1)
- {
- build_vaults(level_number, 88);
- return 1;
- }
- else if (level_number == you.branch_stairs[STAIRS_TOMB] + 2)
- {
- build_vaults(level_number, 89);
- return 1;
- }
- else if (level_number == you.branch_stairs[STAIRS_TOMB] + 3)
- {
- build_vaults(level_number, 90);
- return 1;
- }
- break;
-
- case BRANCH_SWAMP:
- if (level_number == you.branch_stairs[STAIRS_SWAMP]
- + branch_depth(STAIRS_SWAMP))
- {
- build_vaults(level_number, 91);
- return 1;
- }
- break;
-
- case BRANCH_ORCISH_MINES:
- spotty_level(false, 100 + random2(500), false);
- return 1;
-
- case BRANCH_LAIR:
- if (!one_chance_in(3))
- {
- spotty_level(false, 100 + random2(500), false);
- return 1;
- }
- break;
-
- case BRANCH_VESTIBULE_OF_HELL:
- build_vaults( level_number, 50 );
- link_items();
- return -1;
-
- case BRANCH_DIS:
- if (level_number == 33)
- {
- build_vaults(level_number, 51);
- return 1;
- }
- break;
-
- case BRANCH_GEHENNA:
- if (level_number == 33)
- {
- build_vaults(level_number, 52);
- return 1;
- }
- break;
-
- case BRANCH_COCYTUS:
- if (level_number == 33)
- {
- build_vaults(level_number, 53);
- return 1;
- }
- break;
-
- case BRANCH_TARTARUS:
- if (level_number == 33)
- {
- build_vaults(level_number, 54);
- return 1;
- }
- break;
-
- default:
- break;
- }
- return 0;
-}
-
-// returns 1 if we should dispense with city building,
-// 0 otherwise. Also sets special_room if one is generated
-// so that we can link it up later.
-
-static int builder_normal(int level_number, char level_type, spec_room &sr)
-{
- UNUSED( level_type );
-
- bool skipped = false;
- bool done_city = false;
-
- if (player_in_branch( BRANCH_DIS ))
- {
- city_level(level_number);
- return 1;
- }
-
- if (player_in_branch( BRANCH_MAIN_DUNGEON )
- && level_number > 10 && level_number < 23 && one_chance_in(9))
- {
- // Can't have vaults on you.where_are_you != BRANCH_MAIN_DUNGEON levels
- build_vaults(level_number, 100);
- return 1;
- }
-
- if (player_in_branch( BRANCH_VAULTS ))
- {
- if (one_chance_in(3))
- city_level(level_number);
- else
- plan_main(level_number, 4);
- return 1;
- }
-
- if (level_number > 7 && level_number < 23)
- {
- if (one_chance_in(16))
- {
- spotty_level(false, 0, coinflip());
- return 1;
- }
-
- if (one_chance_in(16))
- {
- bigger_room();
- return 1;
- }
- }
-
- if (level_number > 2 && level_number < 23 && one_chance_in(3))
- {
- plan_main(level_number, 0);
-
- if (one_chance_in(3) && level_number > 6)
- build_minivaults(level_number, 200);
-
- return 1;
- }
-
- if (one_chance_in(3))
- skipped = true;
-
- //V was 3
- if (!skipped && one_chance_in(7))
- {
- // sometimes roguey_levels generate a special room
- roguey_level(level_number, sr);
-
- if (level_number > 6
- && player_in_branch( BRANCH_MAIN_DUNGEON )
- && one_chance_in(4))
- {
- build_minivaults(level_number, 200);
- return 1;
- }
- }
- else
- {
- if (!skipped && level_number > 13 && one_chance_in(8))
- {
- if (one_chance_in(3))
- city_level(level_number);
- else
- plan_main(level_number, 4);
- done_city = true;
- }
- }
-
- // maybe create a special room, if roguey_level hasn't done it
- // already.
- if (!sr.created && level_number > 5 && !done_city && one_chance_in(5))
- special_room(level_number, sr);
-
- return 0;
-}
-
-// returns 1 if we should skip extras(), otherwise 0
-static int builder_basic(int level_number)
-{
- int temp_rand;
- int doorlevel = random2(11);
- int corrlength = 2 + random2(14);
- int roomsize = 4 + random2(5) + random2(6);
- int no_corr = (one_chance_in(100) ? 500 + random2(500) : 30 + random2(200));
- int intersect_chance = (one_chance_in(20) ? 400 : random2(20));
-
- make_trail( 35, 30, 35, 20, corrlength, intersect_chance, no_corr,
- DNGN_STONE_STAIRS_DOWN_I, DNGN_STONE_STAIRS_UP_I );
-
- make_trail( 10, 15, 10, 15, corrlength, intersect_chance, no_corr,
- DNGN_STONE_STAIRS_DOWN_II, DNGN_STONE_STAIRS_UP_II );
-
- make_trail(50,20,10,15,corrlength,intersect_chance,no_corr,
- DNGN_STONE_STAIRS_DOWN_III, DNGN_STONE_STAIRS_UP_III);
-
- if (one_chance_in(4))
- {
- make_trail( 10, 20, 40, 20, corrlength, intersect_chance, no_corr,
- DNGN_ROCK_STAIRS_DOWN );
- }
-
- if (one_chance_in(4))
- {
- make_trail( 50, 20, 40, 20, corrlength, intersect_chance, no_corr,
- DNGN_ROCK_STAIRS_UP );
- }
-
-
- if (level_number > 1 && one_chance_in(16))
- big_room(level_number);
-
- if (random2(level_number) > 6 && one_chance_in(3))
- diamond_rooms(level_number);
-
- // make some rooms:
- int i, no_rooms, max_doors;
- int sx,sy,ex,ey, time_run;
-
- temp_rand = random2(750);
- time_run = 0;
-
- no_rooms = ((temp_rand > 63) ? (5 + random2avg(29, 2)) : // 91.47% {dlb}
- (temp_rand > 14) ? 100 // 6.53% {dlb}
- : 1); // 2.00% {dlb}
-
- max_doors = 2 + random2(8);
-
- for (i = 0; i < no_rooms; i++)
- {
- sx = 8 + random2(50);
- sy = 8 + random2(40);
- ex = sx + 2 + random2(roomsize);
- ey = sy + 2 + random2(roomsize);
-
- if (!make_room(sx,sy,ex,ey,max_doors, doorlevel))
- {
- time_run++;
- i--;
- }
-
- if (time_run > 30)
- {
- time_run = 0;
- i++;
- }
- }
-
- // make some more rooms:
- no_rooms = 1 + random2(3);
- max_doors = 1;
-
- for (i = 0; i < no_rooms; i++)
- {
- sx = 8 + random2(55);
- sy = 8 + random2(45);
- ex = sx + 5 + random2(6);
- ey = sy + 5 + random2(6);
-
- if (!make_room(sx,sy,ex,ey,max_doors, doorlevel))
- {
- time_run++;
- i--;
- }
-
- if (time_run > 30)
- {
- time_run = 0;
- i++;
- }
- }
-
- return 0;
-}
-
-static void builder_extras( int level_number, int level_type )
-{
- UNUSED( level_type );
-
- if (level_number >= 11 && level_number <= 23 && one_chance_in(15))
- place_specific_stair(DNGN_ENTER_LABYRINTH);
-
- if (level_number > 6
- && player_in_branch( BRANCH_MAIN_DUNGEON )
- && one_chance_in(3))
- {
- build_minivaults(level_number, 200);
- return;
- }
-
- if (level_number > 5 && one_chance_in(10))
- {
- many_pools( (coinflip() ? DNGN_DEEP_WATER : DNGN_LAVA) );
- return;
- }
-
-#ifdef USE_RIVERS
- //mv: it's better to be here so other dungeon features
- // are not overriden by water
- int river_type = one_chance_in( 5 + level_number ) ? DNGN_SHALLOW_WATER
- : DNGN_DEEP_WATER;
-
- if (level_number > 11
- && (one_chance_in(5) || (level_number > 15 && !one_chance_in(5))))
- {
- river_type = DNGN_LAVA;
- }
-
- if (player_in_branch( BRANCH_GEHENNA ))
- {
- river_type = DNGN_LAVA;
-
- if (coinflip())
- build_river( river_type );
- else
- build_lake( river_type );
- }
- else if (player_in_branch( BRANCH_COCYTUS ))
- {
- river_type = DNGN_DEEP_WATER;
-
- if (coinflip())
- build_river( river_type );
- else
- build_lake( river_type );
- }
-
-
- if (level_number > 8 && one_chance_in(16))
- build_river( river_type );
- else if (level_number > 8 && one_chance_in(12))
- {
- build_lake( (river_type != DNGN_SHALLOW_WATER) ? river_type
- : DNGN_DEEP_WATER );
- }
-#endif // USE_RIVERS
-}
-
-static void place_traps(int level_number)
-{
- int i;
- int num_traps = random2avg(9, 2);
-
- for (i = 0; i < num_traps; i++)
- {
- // traps can be placed in vaults
- if (env.trap[i].type != TRAP_UNASSIGNED)
- continue;
-
- do
- {
- env.trap[i].x = 10 + random2(GXM - 20);
- env.trap[i].y = 10 + random2(GYM - 20);
- }
- while (grd[env.trap[i].x][env.trap[i].y] != DNGN_FLOOR);
-
- unsigned char &trap_type = env.trap[i].type;
- trap_type = TRAP_DART;
-
- if ((random2(1 + level_number) > 1) && one_chance_in(4))
- trap_type = TRAP_NEEDLE;
- if (random2(1 + level_number) > 3)
- trap_type = TRAP_SPEAR;
- if (random2(1 + level_number) > 5)
- trap_type = TRAP_AXE;
-
- // Note we're boosting arrow trap numbers by moving it
- // down the list, and making spear and axe traps rarer.
- if (trap_type == TRAP_DART?
- random2(1 + level_number) > 2
- : one_chance_in(7))
- trap_type = TRAP_ARROW;
-
- if (random2(1 + level_number) > 7)
- trap_type = TRAP_BOLT;
- if (random2(1 + level_number) > 11)
- trap_type = TRAP_BLADE;
-
- if ((random2(1 + level_number) > 14 && one_chance_in(3))
- || (player_in_branch( BRANCH_HALL_OF_ZOT ) && coinflip()))
- {
- trap_type = TRAP_ZOT;
- }
-
- if (one_chance_in(20))
- trap_type = TRAP_TELEPORT;
- if (one_chance_in(40))
- trap_type = TRAP_AMNESIA;
-
- grd[env.trap[i].x][env.trap[i].y] = DNGN_UNDISCOVERED_TRAP;
- } // end "for i"
-} // end place_traps()
-
-static void place_specific_stair(unsigned char stair)
-{
- int sx, sy;
-
- do
- {
- sx = random2(GXM-10);
- sy = random2(GYM-10);
- }
- while(grd[sx][sy] != DNGN_FLOOR || mgrd[sx][sy] != NON_MONSTER);
-
- grd[sx][sy] = stair;
-}
-
-
-static void place_branch_entrances(int dlevel, char level_type)
-{
- unsigned char stair;
- unsigned char entrance;
- int sx, sy;
-
- if (!level_type == LEVEL_DUNGEON)
- return;
-
- if (player_in_branch( BRANCH_MAIN_DUNGEON ))
- {
- // stair to HELL
- if (dlevel >= 20 && dlevel <= 27)
- place_specific_stair(DNGN_ENTER_HELL);
-
- // stair to PANDEMONIUM
- if (dlevel >= 20 && dlevel <= 50 && (dlevel == 23 || one_chance_in(4)))
- place_specific_stair(DNGN_ENTER_PANDEMONIUM);
-
- // stairs to ABYSS
- if (dlevel >= 20 && dlevel <= 30 && (dlevel == 24 || one_chance_in(3)))
- place_specific_stair(DNGN_ENTER_ABYSS);
-
- // level 26: replaces all down stairs with staircases to Zot:
- if (dlevel == 26)
- {
- for (sx = 1; sx < GXM; sx++)
- {
- for (sy = 1; sy < GYM; sy++)
- {
- if (grd[sx][sy] >= DNGN_STONE_STAIRS_DOWN_I
- && grd[sx][sy] <= DNGN_ROCK_STAIRS_DOWN)
- {
- grd[sx][sy] = DNGN_ENTER_ZOT;
- }
- }
- }
- }
- }
-
- // place actual branch entrances
- for (int branch = 0; branch < 30; branch++)
- {
- stair = 0;
- entrance = 100;
-
- if (you.branch_stairs[branch] == 100) // set in newgame
- break;
-
- if (you.branch_stairs[branch] != dlevel)
- continue;
-
- // decide if this branch leaves from this level
- switch(branch)
- {
- case STAIRS_ORCISH_MINES:
- case STAIRS_HIVE:
- case STAIRS_LAIR:
- case STAIRS_VAULTS:
- case STAIRS_ECUMENICAL_TEMPLE:
- entrance = BRANCH_MAIN_DUNGEON;
- break;
-
- case STAIRS_SLIME_PITS:
- case STAIRS_SWAMP:
- case STAIRS_SNAKE_PIT:
- entrance = BRANCH_LAIR;
- break;
-
- case STAIRS_ELVEN_HALLS:
- entrance = BRANCH_ORCISH_MINES;
- break;
-
- case STAIRS_CRYPT:
- case STAIRS_HALL_OF_BLADES:
- entrance = BRANCH_VAULTS;
- break;
-
- case STAIRS_TOMB:
- entrance = BRANCH_CRYPT;
- break;
-
- default:
- entrance = 100;
- break;
- }
-
- if (you.where_are_you != entrance)
- continue;
-
- stair = branch + DNGN_ENTER_ORCISH_MINES;
- place_specific_stair(stair);
- } // end loop - possible branch entrances
-}
-
-static void make_trail(int xs, int xr, int ys, int yr, int corrlength,
- int intersect_chance, int no_corr, unsigned char begin,
- unsigned char end)
-{
- int x_start, y_start; // begin point
- int x_ps, y_ps; // end point
- int finish = 0;
- int length = 0;
- int temp_rand;
-
- // temp positions
- int dir_x = 0;
- int dir_y = 0;
- int dir_x2, dir_y2;
-
- do
- {
- x_start = xs + random2(xr);
- y_start = ys + random2(yr);
- }
- while (grd[x_start][y_start] != DNGN_ROCK_WALL
- && grd[x_start][y_start] != DNGN_FLOOR);
-
- // assign begin feature
- if (begin != 0)
- grd[x_start][y_start] = begin;
- x_ps = x_start;
- y_ps = y_start;
-
- // wander
- do // (while finish < no_corr)
- {
- dir_x2 = ((x_ps < 15) ? 1 : 0);
-
- if (x_ps > 65)
- dir_x2 = -1;
-
- dir_y2 = ((y_ps < 15) ? 1 : 0);
-
- if (y_ps > 55)
- dir_y2 = -1;
-
- temp_rand = random2(10);
-
- // Put something in to make it go to parts of map it isn't in now
- if (coinflip())
- {
- if (dir_x2 != 0 && temp_rand < 6)
- dir_x = dir_x2;
-
- if (dir_x2 == 0 || temp_rand >= 6)
- dir_x = (coinflip()? -1 : 1);
-
- dir_y = 0;
- }
- else
- {
- if (dir_y2 != 0 && temp_rand < 6)
- dir_y = dir_y2;
-
- if (dir_y2 == 0 || temp_rand >= 6)
- dir_y = (coinflip()? -1 : 1);
-
- dir_x = 0;
- }
-
- if (dir_x == 0 && dir_y == 0)
- continue;
-
- if (x_ps < 8)
- {
- dir_x = 1;
- dir_y = 0;
- }
-
- if (y_ps < 8)
- {
- dir_y = 1;
- dir_x = 0;
- }
-
- if (x_ps > (GXM - 8))
- {
- dir_x = -1;
- dir_y = 0;
- }
-
- if (y_ps > (GYM - 8))
- {
- dir_y = -1;
- dir_x = 0;
- }
-
- // corridor length.. change only when going vertical?
- if (dir_x == 0 || length == 0)
- length = random2(corrlength) + 2;
-
- int bi = 0;
-
- for (bi = 0; bi < length; bi++)
- {
- // Below, I've changed the values of the unimportant variable from
- // 0 to random2(3) - 1 to avoid getting stuck on the "stuck!" bit
- if (x_ps < 9)
- {
- dir_y = 0; //random2(3) - 1;
- dir_x = 1;
- }
-
- if (x_ps > (GXM - 9))
- {
- dir_y = 0; //random2(3) - 1;
- dir_x = -1;
- }
-
- if (y_ps < 9)
- {
- dir_y = 1;
- dir_x = 0; //random2(3) - 1;
- }
-
- if (y_ps > (GYM - 9))
- {
- dir_y = -1;
- dir_x = 0; //random2(3) - 1;
- }
-
- // don't interfere with special rooms
- if (grd[x_ps + dir_x][y_ps + dir_y] == DNGN_BUILDER_SPECIAL_WALL)
- break;
-
- // see if we stop due to intersection with another corridor/room
- if (grd[x_ps + 2 * dir_x][y_ps + 2 * dir_y] == DNGN_FLOOR
- && !one_chance_in(intersect_chance))
- break;
-
- x_ps += dir_x;
- y_ps += dir_y;
-
- if (grd[x_ps][y_ps] == DNGN_ROCK_WALL)
- grd[x_ps][y_ps] = DNGN_FLOOR;
- }
-
- if (finish == no_corr - 1 && grd[x_ps][y_ps] != DNGN_FLOOR)
- finish -= 2;
-
- finish++;
- }
- while (finish < no_corr);
-
- // assign end feature
- if (end != 0)
- grd[x_ps][y_ps] = end;
-}
-
-static int good_door_spot(int x, int y)
-{
- if ((!grid_is_solid(grd[x][y]) && grd[x][y] < DNGN_ENTER_PANDEMONIUM)
- || grd[x][y] == DNGN_CLOSED_DOOR)
- {
- return 1;
- }
-
- return 0;
-}
-
-// return TRUE if a room was made successfully
-static bool make_room(int sx,int sy,int ex,int ey,int max_doors, int doorlevel)
-{
- int find_door = 0;
- int diag_door = 0;
- int rx,ry;
-
- // check top & bottom for possible doors
- for (rx = sx; rx <= ex; rx++)
- {
- find_door += good_door_spot(rx,sy);
- find_door += good_door_spot(rx,ey);
- }
-
- // check left and right for possible doors
- for (ry = sy+1; ry < ey; ry++)
- {
- find_door += good_door_spot(sx,ry);
- find_door += good_door_spot(ex,ry);
- }
-
- diag_door += good_door_spot(sx,sy);
- diag_door += good_door_spot(ex,sy);
- diag_door += good_door_spot(sx,ey);
- diag_door += good_door_spot(ex,ey);
-
- if ((diag_door + find_door) > 1 && max_doors == 1)
- return false;
-
- if (find_door == 0 || find_door > max_doors)
- return false;
-
- // look for 'special' rock walls - don't interrupt them
- if (find_in_area(sx,sy,ex,ey,DNGN_BUILDER_SPECIAL_WALL))
- return false;
-
- // convert the area to floor
- for (rx=sx; rx<=ex; rx++)
- {
- for(ry=sy; ry<=ey; ry++)
- {
- if (grd[rx][ry] <= DNGN_FLOOR)
- grd[rx][ry] = DNGN_FLOOR;
- }
- }
-
- // put some doors on the sides (but not in corners),
- // where it makes sense to do so.
- for(ry=sy+1; ry<ey; ry++)
- {
- // left side
- if (grd[sx-1][ry] == DNGN_FLOOR
- && grid_is_solid(grd[sx-1][ry-1])
- && grid_is_solid(grd[sx-1][ry+1]))
- {
- if (random2(10) < doorlevel)
- grd[sx-1][ry] = DNGN_CLOSED_DOOR;
- }
-
- // right side
- if (grd[ex+1][ry] == DNGN_FLOOR
- && grid_is_solid(grd[ex+1][ry-1])
- && grid_is_solid(grd[ex+1][ry+1]))
- {
- if (random2(10) < doorlevel)
- grd[ex+1][ry] = DNGN_CLOSED_DOOR;
- }
- }
-
- // put some doors on the top & bottom
- for(rx=sx+1; rx<ex; rx++)
- {
- // top
- if (grd[rx][sy-1] == DNGN_FLOOR
- && grid_is_solid(grd[rx-1][sy-1])
- && grid_is_solid(grd[rx+1][sy-1]))
- {
- if (random2(10) < doorlevel)
- grd[rx][sy-1] = DNGN_CLOSED_DOOR;
- }
-
- // bottom
- if (grd[rx][ey+1] == DNGN_FLOOR
- && grid_is_solid(grd[rx-1][ey+1])
- && grid_is_solid(grd[rx+1][ey+1]))
- {
- if (random2(10) < doorlevel)
- grd[rx][ey+1] = DNGN_CLOSED_DOOR;
- }
- }
-
- return true;
-} //end make_room()
-
-static void builder_monsters(int level_number, char level_type, int mon_wanted)
-{
- int i = 0;
- int totalplaced = 0;
- int not_used=0;
- int x,y;
- int lava_spaces, water_spaces;
- int aq_creatures;
- int swimming_things[4];
-
- if (level_type == LEVEL_PANDEMONIUM)
- return;
-
- for (i = 0; i < mon_wanted; i++)
- {
- if (place_monster( not_used, RANDOM_MONSTER, level_number, BEH_SLEEP,
- MHITNOT, false, 1, 1, true ))
- {
- totalplaced++;
- }
- }
-
- // Unique beasties:
- int which_unique;
-
- if (level_number > 0
- && you.level_type == LEVEL_DUNGEON // avoid generating on temp levels
- && !player_in_hell()
- && !player_in_branch( BRANCH_ORCISH_MINES )
- && !player_in_branch( BRANCH_HIVE )
- && !player_in_branch( BRANCH_LAIR )
- && !player_in_branch( BRANCH_SLIME_PITS )
- && !player_in_branch( BRANCH_ECUMENICAL_TEMPLE ))
- {
- while(one_chance_in(3))
- {
- which_unique = -1; // 30 in total
-
- while(which_unique < 0 || you.unique_creatures[which_unique])
- {
- // sometimes, we just quit if a unique is already placed.
- if (which_unique >= 0 && !one_chance_in(3))
- {
- which_unique = -1;
- break;
- }
-
- which_unique = ((level_number > 19) ? 20 + random2(11) :
- (level_number > 16) ? 13 + random2(10) :
- (level_number > 13) ? 9 + random2( 9) :
- (level_number > 9) ? 6 + random2( 5) :
- (level_number > 7) ? 4 + random2( 4) :
- (level_number > 3) ? 2 + random2( 4)
- : random2(4));
- }
-
- // usually, we'll have quit after a few tries. Make sure we don't
- // create unique[-1] by accident.
- if (which_unique < 0)
- break;
-
- // note: unique_creatures 40 + used by unique demons
- if (place_monster( not_used, 280 + which_unique, level_number,
- BEH_SLEEP, MHITNOT, false, 1, 1, true ))
- {
- totalplaced++;
- }
- }
- }
-
- // do aquatic and lava monsters:
-
- // count the number of lava and water tiles {dlb}:
- lava_spaces = 0;
- water_spaces = 0;
-
- for (x = 0; x < GXM; x++)
- {
- for (y = 0; y < GYM; y++)
- {
- if (grd[x][y] == DNGN_LAVA)
- {
- lava_spaces++;
- }
- else if (grd[x][y] == DNGN_DEEP_WATER
- || grd[x][y] == DNGN_SHALLOW_WATER)
- {
- water_spaces++;
- }
- }
- }
-
- if (lava_spaces > 49)
- {
- for (i = 0; i < 4; i++)
- {
- swimming_things[i] = MONS_LAVA_WORM + random2(3);
-
- //mv: this is really ugly, but easiest
- //IMO generation of water/lava beasts should be changed,
- //because we want data driven code and not things like it
- if (one_chance_in(30))
- swimming_things[i] = MONS_SALAMANDER;
- }
-
- aq_creatures = random2avg(9, 2) + (random2(lava_spaces) / 10);
-
- if (aq_creatures > 15)
- aq_creatures = 15;
-
- for (i = 0; i < aq_creatures; i++)
- {
- if (place_monster( not_used, swimming_things[ random2(4) ],
- level_number, BEH_SLEEP, MHITNOT,
- false, 1, 1, true ))
- {
- totalplaced++;
- }
-
- if (totalplaced > 99)
- break;
- }
- }
-
- if (water_spaces > 49)
- {
- for (i = 0; i < 4; i++)
- {
- // mixing enums and math ticks me off !!! 15jan2000 {dlb}
- swimming_things[i] = MONS_BIG_FISH + random2(4);
-
- // swamp worms and h2o elementals generated below: {dlb}
- if (player_in_branch( BRANCH_SWAMP ) && !one_chance_in(3))
- swimming_things[i] = MONS_SWAMP_WORM;
- }
-
- if (level_number >= 25 && one_chance_in(5))
- swimming_things[0] = MONS_WATER_ELEMENTAL;
-
- if (player_in_branch( BRANCH_COCYTUS ))
- swimming_things[3] = MONS_WATER_ELEMENTAL;
-
- aq_creatures = random2avg(9, 2) + (random2(water_spaces) / 10);
-
- if (aq_creatures > 15)
- aq_creatures = 15;
-
- for (i = 0; i < aq_creatures; i++)
- {
- if (place_monster( not_used, swimming_things[ random2(4) ],
- level_number, BEH_SLEEP, MHITNOT,
- false, 1, 1, true ))
- {
- totalplaced++;
- }
-
- if (totalplaced > 99)
- break;
- }
- }
-}
-
-static void builder_items(int level_number, char level_type, int items_wanted)
-{
- UNUSED( level_type );
-
- int i = 0;
- unsigned char specif_type = OBJ_RANDOM;
- int items_levels = level_number;
- int item_no;
-
- if (player_in_branch( BRANCH_VAULTS ))
- {
- items_levels *= 15;
- items_levels /= 10;
- }
- else if (player_in_branch( BRANCH_ORCISH_MINES ))
- {
- specif_type = OBJ_GOLD; /* lots of gold in the orcish mines */
- }
-
- if (player_in_branch( BRANCH_VESTIBULE_OF_HELL )
- || player_in_hell()
- || player_in_branch( BRANCH_SLIME_PITS )
- || player_in_branch( BRANCH_HALL_OF_BLADES )
- || player_in_branch( BRANCH_ECUMENICAL_TEMPLE ))
- {
- /* No items in hell, the slime pits, the Hall */
- return;
- }
- else
- {
- for (i = 0; i < items_wanted; i++)
- items( 1, specif_type, OBJ_RANDOM, false, items_levels, 250 );
-
- // Make sure there's a very good chance of a knife being placed
- // in the first five levels, but not a guarantee of one. The
- // intent of this is to reduce the advantage that "cutting"
- // starting weapons have. -- bwr
- if (player_in_branch( BRANCH_MAIN_DUNGEON )
- && level_number < 5 && coinflip())
- {
- item_no = items( 0, OBJ_WEAPONS, WPN_KNIFE, false, 0, 250 );
-
- // 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].special = 0; // no ego type
- }
- }
- }
-}
-
-// the entire intent of this function is to find a
-// hallway from a special room to a floor space somewhere,
-// changing the special room wall (DNGN_BUILDER_SPECIAL_WALL)
-// to a closed door, and normal rock wall to pre-floor.
-// Anything that might otherwise block the hallway is changed
-// to pre-floor.
-static void specr_2(spec_room &sr)
-{
- int bkout = 0;
- int cx = 0, cy = 0;
- int sx = 0, sy = 0;
- int dx = 0, dy = 0;
- int i,j;
-
- // paranoia -- how did we get here if there's no actual special room??
- if (!sr.created)
- return;
-
- grolko:
-
- if (bkout > 100)
- return;
-
- switch (random2(4))
- {
- case 0:
- // go up from north edge
- cx = sr.x1 + (random2(sr.x2 - sr.x1));
- cy = sr.y1;
- dx = 0;
- dy = -1;
- break;
- case 1:
- // go down from south edge
- cx = sr.x1 + (random2(sr.x2 - sr.x1));
- cy = sr.y2;
- dx = 0;
- dy = 1;
- break;
- case 2:
- // go left from west edge
- cy = sr.y1 + (random2(sr.y2 - sr.y1));
- cx = sr.x1;
- dx = -1;
- dy = 0;
- break;
- case 3:
- // go right from east edge
- cy = sr.y1 + (random2(sr.y2 - sr.y1));
- cx = sr.x2;
- dx = 1;
- dy = 0;
- break;
- }
-
- sx = cx;
- sy = cy;
-
- for (i = 0; i < 100; i++)
- {
- sx += dx;
- sy += dy;
-
- // quit if we run off the map before finding floor
- if (sx < 6 || sx > (GXM - 7) || sy < 6 || sy > (GYM - 7))
- {
- bkout++;
- goto grolko;
- }
-
- // look around for floor
- if (i > 0)
- {
- if (grd[sx + 1][sy] == DNGN_FLOOR)
- break;
- if (grd[sx][sy + 1] == DNGN_FLOOR)
- break;
- if (grd[sx - 1][sy] == DNGN_FLOOR)
- break;
- if (grd[sx][sy - 1] == DNGN_FLOOR)
- break;
- }
- }
-
- sx = cx;
- sy = cy;
-
- for (j = 0; j < i + 2; j++)
- {
- if (grd[sx][sy] == DNGN_BUILDER_SPECIAL_WALL)
- grd[sx][sy] = DNGN_CLOSED_DOOR;
-
- if (j > 0 && grd[sx + dx][sy + dy] > DNGN_ROCK_WALL
- && grd[sx + dx][sy + dy] < DNGN_FLOOR)
- grd[sx][sy] = DNGN_BUILDER_SPECIAL_FLOOR;
-
- if (grd[sx][sy] == DNGN_ROCK_WALL)
- grd[sx][sy] = DNGN_BUILDER_SPECIAL_FLOOR;
-
- sx += dx;
- sy += dy;
- }
-
- sr.hooked_up = true;
-} // end specr_2()
-
-// Fill special room sr with monsters from the pit_list at density%...
-// then place a "lord of the pit" of lord_type at (lordx, lordy).
-static void fill_monster_pit( spec_room &sr,
- FixedVector<pit_mons_def, MAX_PIT_MONSTERS> &pit_list,
- int density, int lord_type, int lordx, int lordy )
-{
- int i, x, y;
-
- // make distribution cumulative
- for (i = 1; i < MAX_PIT_MONSTERS; i++)
- {
- // assuming that the first zero rarity is the end of the list:
- if (!pit_list[i].rare)
- break;
-
- pit_list[i].rare = pit_list[i].rare + pit_list[i - 1].rare;
- }
-
- const int num_types = i;
- const int rare_sum = pit_list[num_types - 1].rare;
-
- // calculate die_size, factoring in the density% of the pit
- const int die_size = (rare_sum * 100) / density;
-
-#if DEBUG_DIAGNOSTICS
- for (i = 0; i < num_types; i++)
- {
- char buff[ ITEMNAME_SIZE ];
-
- const int delta = ((i > 0) ? pit_list[i].rare - pit_list[i - 1].rare
- : pit_list[i].rare);
-
- const float perc = (static_cast<float>( delta ) * 100.0)
- / static_cast<float>( rare_sum );
-
- mprf( MSGCH_DIAGNOSTICS, "%6.2f%%: %s", perc,
- moname( pit_list[i].type, true, DESC_PLAIN, buff ) );
- }
-#endif
-
- // put the boss monster down
- if (lord_type != MONS_PROGRAM_BUG)
- mons_place( lord_type, BEH_SLEEP, MHITNOT, true, lordx, lordy );
-
- // place monsters and give them items {dlb}:
- for (x = sr.x1; x <= sr.x2; x++)
- {
- for (y = sr.y1; y <= sr.y2; y++)
- {
- // avoid the boss (or anyone else we may have dropped already)
- if (mgrd[x][y] != NON_MONSTER)
- continue;
-
- const int roll = random2( die_size );
-
- // density skip (no need to iterate)
- if (roll >= rare_sum)
- continue;
-
- // run throught the cumulative chances and place a monster
- for (i = 0; i < num_types; i++)
- {
- if (roll < pit_list[i].rare)
- {
- mons_place( pit_list[i].type, BEH_SLEEP, MHITNOT,
- true, x, y );
- break;
- }
- }
- }
- }
-}
-
-static void special_room(int level_number, spec_room &sr)
-{
- char spec_room_type = SROOM_LAIR_KOBOLD;
- int lev_mons;
- int thing_created = 0;
- int x, y;
-
- unsigned char obj_type = OBJ_RANDOM; // used in calling items() {dlb}
- unsigned char i; // general purpose loop variable {dlb}
- int temp_rand = 0; // probability determination {dlb}
-
- FixedVector < int, 10 > mons_alloc; // was [20] {dlb}
-
- char lordx = 0, lordy = 0;
-
- // overwrites anything; this function better be called early on during
- // creation..
- int room_x1 = 8 + random2(55);
- int room_y1 = 8 + random2(45);
- int room_x2 = room_x1 + 4 + random2avg(6,2);
- int room_y2 = room_y1 + 4 + random2avg(6,2);
-
- // do special walls & floor
- make_box( room_x1, room_y1, room_x2, room_y2,
- DNGN_BUILDER_SPECIAL_FLOOR, DNGN_BUILDER_SPECIAL_WALL );
-
- // set up passed in spec_room structure
- sr.created = true;
- sr.hooked_up = false;
- sr.x1 = room_x1 + 1;
- sr.x2 = room_x2 - 1;
- sr.y1 = room_y1 + 1;
- sr.y2 = room_y2 - 1;
-
- if (level_number < 7)
- spec_room_type = SROOM_LAIR_KOBOLD;
- else
- {
- spec_room_type = random2(NUM_SPECIAL_ROOMS);
-
- if (level_number < 23 && one_chance_in(4))
- spec_room_type = SROOM_BEEHIVE;
-
- if ((level_number > 13 && spec_room_type == SROOM_LAIR_KOBOLD)
- || (level_number < 16 && spec_room_type == SROOM_MORGUE)
- || (level_number < 17 && one_chance_in(4)))
- {
- spec_room_type = SROOM_LAIR_ORC;
- }
-
- if (level_number > 19 && coinflip())
- spec_room_type = SROOM_MORGUE;
-
- if (level_number > 13
- && one_chance_in(level_number > 23? 4 :
- level_number > 18? 5 : 6))
- spec_room_type = SROOM_JELLY_PIT;
- }
-
- switch (spec_room_type)
- {
- case SROOM_LAIR_ORC:
- // determine which monster array to generate {dlb}:
- lev_mons = ((level_number > 24) ? 3 :
- (level_number > 15) ? 2 :
- (level_number > 9) ? 1
- : 0);
-
- // fill with baseline monster type {dlb}:
- for (i = 0; i < 10; i++)
- {
- mons_alloc[i] = MONS_ORC;
- }
-
- // fill in with special monster types {dlb}:
- switch (lev_mons)
- {
- case 0:
- mons_alloc[9] = MONS_ORC_WARRIOR;
- break;
- case 1:
- mons_alloc[8] = MONS_ORC_WARRIOR;
- mons_alloc[9] = MONS_ORC_WARRIOR;
- break;
- case 2:
- mons_alloc[6] = MONS_ORC_KNIGHT;
- mons_alloc[7] = MONS_ORC_WARRIOR;
- mons_alloc[8] = MONS_ORC_WARRIOR;
- mons_alloc[9] = MONS_OGRE;
- break;
- case 3:
- mons_alloc[2] = MONS_ORC_WARRIOR;
- mons_alloc[3] = MONS_ORC_WARRIOR;
- mons_alloc[4] = MONS_ORC_WARRIOR;
- mons_alloc[5] = MONS_ORC_KNIGHT;
- mons_alloc[6] = MONS_ORC_KNIGHT;
- mons_alloc[7] = MONS_OGRE;
- mons_alloc[8] = MONS_OGRE;
- mons_alloc[9] = MONS_TROLL;
- break;
- }
-
- // place monsters and give them items {dlb}:
- for (x = sr.x1; x <= sr.x2; x++)
- {
- for (y = sr.y1; y <= sr.y2; y++)
- {
- if (one_chance_in(4))
- continue;
-
- mons_place( mons_alloc[random2(10)], BEH_SLEEP, MHITNOT,
- true, x, y );
- }
- }
- break;
-
- case SROOM_LAIR_KOBOLD:
- lordx = sr.x1 + random2(sr.x2 - sr.x1);
- lordy = sr.y1 + random2(sr.y2 - sr.y1);
-
- // determine which monster array to generate {dlb}:
- lev_mons = ((level_number < 4) ? 0 :
- (level_number < 6) ? 1 : (level_number < 9) ? 2 : 3);
-
- // fill with baseline monster type {dlb}:
- for (i = 0; i < 10; i++)
- {
- mons_alloc[i] = MONS_KOBOLD;
- }
-
- // fill in with special monster types {dlb}:
- // in this case, they are uniformly the same {dlb}:
- for (i = (7 - lev_mons); i < 10; i++)
- {
- mons_alloc[i] = MONS_BIG_KOBOLD;
- }
-
- // place monsters and give them items {dlb}:
- for (x = sr.x1; x <= sr.x2; x++)
- {
- for (y = sr.y1; y <= sr.y2; y++)
- {
- if (one_chance_in(4))
- continue;
-
- // we'll put the boss down later.
- if (x == lordx && y == lordy)
- continue;
-
- mons_place( mons_alloc[random2(10)], BEH_SLEEP, MHITNOT,
- true, x, y );
- }
- }
-
- // put the boss monster down
- mons_place( MONS_BIG_KOBOLD, BEH_SLEEP, MHITNOT, true, lordx, lordy );
-
- break;
-
- case SROOM_TREASURY:
- // should only appear in deep levels, with a guardian
- // Maybe have several types of treasure room?
- // place treasure {dlb}:
- for (x = sr.x1; x <= sr.x2; x++)
- {
- for (y = sr.y1; y <= sr.y2; y++)
- {
- temp_rand = random2(11);
-
- obj_type = ((temp_rand > 8) ? OBJ_WEAPONS : // 2 in 11
- (temp_rand > 6) ? OBJ_ARMOUR : // 2 in 11
- (temp_rand > 5) ? OBJ_MISSILES : // 1 in 11
- (temp_rand > 4) ? OBJ_WANDS : // 1 in 11
- (temp_rand > 3) ? OBJ_SCROLLS : // 1 in 11
- (temp_rand > 2) ? OBJ_JEWELLERY : // 1 in 11
- (temp_rand > 1) ? OBJ_BOOKS : // 1 in 11
- (temp_rand > 0) ? OBJ_STAVES // 1 in 11
- : OBJ_POTIONS); // 1 in 11
-
- thing_created = items( 1, obj_type, OBJ_RANDOM, true,
- level_number * 3, 250 );
-
- if (thing_created != NON_ITEM)
- {
- mitm[thing_created].x = x;
- mitm[thing_created].y = y;
- }
- }
- }
-
- // place guardian {dlb}:
- mons_place( MONS_GUARDIAN_NAGA, BEH_SLEEP, MHITNOT, true,
- sr.x1 + random2( sr.x2 - sr.x1 ),
- sr.y1 + random2( sr.y2 - sr.y1 ) );
-
- break;
-
- case SROOM_BEEHIVE:
- beehive(sr);
- break;
-
- case SROOM_MORGUE:
- morgue(sr);
- break;
-
- case SROOM_JELLY_PIT:
- jelly_pit(level_number, sr);
- break;
- }
-} // end special_room()
-
-// fills a special room with bees
-static void beehive(spec_room &sr)
-{
- int i;
- int x,y;
-
- for (x = sr.x1; x <= sr.x2; x++)
- {
- for (y = sr.y1; y <= sr.y2; y++)
- {
- if (coinflip())
- continue;
-
- i = get_item_slot();
- if (i == NON_ITEM)
- goto finished_food;
-
- mitm[i].quantity = 1;
- mitm[i].base_type = OBJ_FOOD;
- mitm[i].sub_type = (one_chance_in(25) ? FOOD_ROYAL_JELLY
- : FOOD_HONEYCOMB);
- mitm[i].x = x;
- mitm[i].y = y;
-
- item_colour( mitm[i] );
- }
- }
-
-
- finished_food:
-
- int queenx = sr.x1 + random2(sr.x2 - sr.x1);
- int queeny = sr.y1 + random2(sr.y2 - sr.y1);
-
- for (x = sr.x1; x <= sr.x2; x++)
- {
- for (y = sr.y1; y <= sr.y2; y++)
- {
- if (x == queenx && y == queeny)
- continue;
-
- // the hive is chock full of bees!
-
- mons_place( one_chance_in(7) ? MONS_KILLER_BEE_LARVA
- : MONS_KILLER_BEE,
- BEH_SLEEP, MHITNOT, true, x, y );
- }
- }
-
- mons_place( MONS_QUEEN_BEE, BEH_SLEEP, MHITNOT, true, queenx, queeny );
-} // end beehive()
-
-static void build_minivaults(int level_number, int force_vault)
-{
- // for some weird reason can't put a vault on level 1, because monster equip
- // isn't generated.
- int altar_count = 0;
-
- FixedVector < char, 7 > acq_item_class;
- // hack - passing chars through '...' promotes them to ints, which
- // barfs under gcc in fixvec.h. So don't.
- acq_item_class[0] = OBJ_WEAPONS;
- acq_item_class[1] = OBJ_ARMOUR;
- acq_item_class[2] = OBJ_WEAPONS;
- acq_item_class[3] = OBJ_JEWELLERY;
- acq_item_class[4] = OBJ_BOOKS;
- acq_item_class[5] = OBJ_STAVES;
- acq_item_class[6] = OBJ_MISCELLANY;
-
- FixedVector < int, 7 > mons_array(RANDOM_MONSTER,
- RANDOM_MONSTER,
- RANDOM_MONSTER,
- RANDOM_MONSTER,
- RANDOM_MONSTER,
- RANDOM_MONSTER,
- RANDOM_MONSTER);
-
- char vgrid[81][81];
-
- if (force_vault == 200)
- {
- force_vault = 200 + random2(37);
- }
-
- vault_main(vgrid, mons_array, force_vault, level_number);
-
- int vx, vy;
- int v1x, v1y;
-
- /* find a target area which can be safely overwritten: */
- while(1)
- {
- //if ( one_chance_in(1000) ) return;
- v1x = 12 + random2(45);
- v1y = 12 + random2(35);
-
- for (vx = v1x; vx < v1x + 12; vx++)
- {
- for (vy = v1y; vy < v1y + 12; vy++)
- {
- if (one_chance_in(2000))
- return;
-
- if ((grd[vx][vy] != DNGN_FLOOR
- && grd[vx][vy] != DNGN_ROCK_WALL
- && grd[vx][vy] != DNGN_CLOSED_DOOR
- && grd[vx][vy] != DNGN_SECRET_DOOR)
- || igrd[vx][vy] != NON_ITEM
- || mgrd[vx][vy] != NON_MONSTER)
- {
- goto out_of_check;
- }
- }
- }
-
- /* must not be completely isolated: */
- for (vx = v1x; vx < v1x + 12; vx++)
- {
- // if (vx != v1x && vx != v1x + 12) continue;
- for (vy = v1y; vy < v1y + 12; vy++)
- {
- // if (vy != v1y && vy != v1y + 12) continue;
- if (grd[vx][vy] == DNGN_FLOOR
- || grd[vx][vy] == DNGN_CLOSED_DOOR
- || grd[vx][vy] == DNGN_SECRET_DOOR)
- goto break_out;
- }
- }
-
- out_of_check:
- continue;
-
- break_out:
- break;
- }
-
- for (vx = v1x; vx < v1x + 12; vx++)
- {
- for (vy = v1y; vy < v1y + 12; vy++)
- {
- grd[vx][vy] = vgrid[vx - v1x][vy - v1y];
- }
- }
-
- // these two are throwaways:
- int initial_x, initial_y;
- int num_runes = 0;
-
- // paint the minivault onto the grid
- for (vx = v1x; vx < v1x + 12; vx++)
- {
- for (vy = v1y; vy < v1y + 12; vy++)
- {
- altar_count = vault_grid( level_number, vx, vy, altar_count,
- acq_item_class, mons_array,
- grd[vx][vy], initial_x, initial_y,
- force_vault, num_runes );
- }
- }
-} // end build_minivaults()
-
-static void build_vaults(int level_number, int force_vault)
-{
- // for some weird reason can't put a vault on level 1, because monster equip
- // isn't generated.
- int i,j; // general loop variables
- int altar_count = 0;
- FixedVector < char, 10 > stair_exist;
- char stx, sty;
- int initial_x=0, initial_y=0;
-
- FixedVector < char, 7 > acq_item_class;
- // hack - passing chars through '...' promotes them to ints, which
- // barfs under gcc in fixvec.h. So don't. -- GDL
- acq_item_class[0] = OBJ_WEAPONS;
- acq_item_class[1] = OBJ_ARMOUR;
- acq_item_class[2] = OBJ_WEAPONS;
- acq_item_class[3] = OBJ_JEWELLERY;
- acq_item_class[4] = OBJ_BOOKS;
- acq_item_class[5] = OBJ_STAVES;
- acq_item_class[6] = OBJ_MISCELLANY;
-
- FixedVector < int, 7 > mons_array(RANDOM_MONSTER,
- RANDOM_MONSTER,
- RANDOM_MONSTER,
- RANDOM_MONSTER,
- RANDOM_MONSTER,
- RANDOM_MONSTER,
- RANDOM_MONSTER);
-
- int roomsss = 10 + random2(90);
- int which_room = 0;
-
- bool exclusive = (one_chance_in(10) ? false : true);
-
- //bool exclusive2 = coinflip(); // usage commented out below {dlb}
-
- char vgrid[81][81];
-
- char gluggy = vault_main(vgrid, mons_array, force_vault, level_number);
-
- int vx, vy;
- int v1x = 0, v1y = 0, v2x = 0, v2y = 0;
-
- //int item_made;
-
- char dig_dir_x = 0;
- char dig_dir_y = 0;
- char dig_place_x = 0;
- char dig_place_y = 0;
- int num_runes = 0;
-
- // note: assumes *no* previous item (I think) or monster (definitely)
- // placement
- for (vx = 0; vx < GXM; vx++)
- {
- for (vy = 0; vy < GYM; vy++)
- {
- altar_count = vault_grid( level_number, vx, vy, altar_count,
- acq_item_class, mons_array,
- vgrid[vy][vx], initial_x, initial_y,
- force_vault, num_runes );
- }
- }
-
- switch (gluggy)
- {
- case MAP_NORTH:
- v1x = 1;
- v2x = GXM;
- v1y = 1;
- v2y = 35;
- initial_y++;
- dig_dir_x = 0;
- dig_dir_y = 1;
- break;
-
- case MAP_NORTHWEST:
- v1x = 1;
- v2x = 40;
- v1y = 1;
- v2y = 35;
- initial_y++;
- dig_dir_x = 1;
- dig_dir_y = 0;
- break;
-
- case MAP_NORTHEAST:
- v1x = 40;
- v2x = GXM;
- v1y = 1;
- v2y = 35;
- initial_y++;
- dig_dir_x = -1;
- dig_dir_y = 0;
- break;
-
- case MAP_SOUTHWEST:
- v1x = 1;
- v2x = 40;
- v1y = 35;
- v2y = GYM;
- initial_y--;
- dig_dir_x = 0;
- dig_dir_y = -1;
- break;
-
- case MAP_SOUTHEAST:
- v1x = 40;
- v2x = GXM;
- v1y = 35;
- v2y = GYM;
- initial_y--;
- dig_dir_x = 0;
- dig_dir_y = -1;
- break;
-
- case MAP_ENCOMPASS:
- return;
-
- case MAP_NORTH_DIS:
- v1x = 1;
- v2x = GXM;
- v1y = 1;
- v2y = 35;
- plan_4(1, 1, 80, 35, DNGN_METAL_WALL);
- goto vstair;
- }
-
- char cnx, cny;
- char romx1[30], romy1[30], romx2[30], romy2[30];
-
- for (i = 0; i < roomsss; i++)
- {
- do
- {
- romx1[which_room] = 10 + random2(50);
- romy1[which_room] = 10 + random2(40);
- romx2[which_room] = romx1[which_room] + 2 + random2(8);
- romy2[which_room] = romy1[which_room] + 2 + random2(8);
- }
- while ((romx1[which_room] >= v1x && romx1[which_room] <= v2x
- && romy1[which_room] >= v1y && romy1[which_room] <= v2y)
- || (romx2[which_room] >= v1x && romx2[which_room] <= v2x
- && romy2[which_room] >= v1y && romy2[which_room] <= v2y));
-
- if (i == 0)
- {
- join_the_dots(initial_x, initial_y, romx1[which_room], romy1[which_room],
- v1x, v1y, v2x, v2y);
- }
- else if (exclusive)
- {
- for (cnx = romx1[which_room] - 1; cnx < romx2[which_room] + 1;
- cnx++)
- {
- for (cny = romy1[which_room] - 1; cny < romy2[which_room] + 1;
- cny++)
- {
- if (grd[cnx][cny] != DNGN_ROCK_WALL)
- goto continuing;
- }
- }
- }
-
- replace_area(romx1[which_room], romy1[which_room], romx2[which_room],
- romy2[which_room], DNGN_ROCK_WALL, DNGN_FLOOR);
-
- if (which_room > 0) // && !exclusive2
- {
- const int rx1 = romx1[which_room];
- const int rx2 = romx2[which_room];
- const int prev_rx1 = romx1[which_room - 1];
- const int prev_rx2 = romx2[which_room - 1];
-
- const int ry1 = romy1[which_room];
- const int ry2 = romy2[which_room];
- const int prev_ry1 = romy1[which_room - 1];
- const int prev_ry2 = romy2[which_room - 1];
-
- join_the_dots( rx1 + random2( rx2 - rx1 ),
- ry1 + random2( ry2 - ry1 ),
- prev_rx1 + random2( prev_rx2 - prev_rx1 ),
- prev_ry1 + random2( prev_ry2 - prev_ry1 ),
- v1x, v1y, v2x, v2y);
- }
-
- which_room++;
-
- if (which_room >= 29)
- break;
-
- continuing:
- continue; // next i loop
-
- }
-
- vstair:
- dig_place_x = initial_x;
- dig_place_y = initial_y;
-
- if (gluggy != MAP_NORTH_DIS)
- {
- for (i = 0; i < 40; i++)
- {
- dig_place_x += dig_dir_x;
- dig_place_y += dig_dir_y;
-
- if (dig_place_x < 10 || dig_place_x > (GXM - 10)
- || dig_place_y < 10 || dig_place_y > (GYM - 10))
- {
- break;
- }
-
- if (grd[dig_place_x][dig_place_y] == DNGN_ROCK_WALL)
- grd[dig_place_x][dig_place_y] = DNGN_FLOOR;
- }
- }
-
- unsigned char pos_x, pos_y;
-
- for (stx = 0; stx < 10; stx++)
- stair_exist[stx] = 0;
-
- for (stx = 0; stx < GXM; stx++)
- {
- for (sty = 0; sty < GYM; sty++)
- {
- if (grd[stx][sty] >= DNGN_STONE_STAIRS_DOWN_I
- && grd[stx][sty] <= DNGN_ROCK_STAIRS_UP)
- {
- stair_exist[grd[stx][sty] - 82] = 1;
- }
- }
- }
-
- if (player_in_branch( BRANCH_DIS ))
- {
- for (sty = 0; sty < 5; sty++)
- stair_exist[sty] = 1;
-
- for (sty = 6; sty < 10; sty++)
- stair_exist[sty] = 0;
- }
-
- for (j = 0; j < (coinflip()? 4 : 3); j++)
- {
- for (i = 0; i < 2; i++)
- {
-
- if (stair_exist[(82 + j + (i * 4)) - 82] == 1) // does this look funny to *you*? {dlb}
- continue;
-
- do
- {
- pos_x = 10 + random2(GXM - 20);
- pos_y = 10 + random2(GYM - 20);
- }
- while (grd[pos_x][pos_y] != DNGN_FLOOR
- || (pos_x >= v1x && pos_x <= v2x && pos_y >= v1y
- && pos_y <= v2y));
-
- grd[pos_x][pos_y] = j + ((i == 0) ? DNGN_STONE_STAIRS_DOWN_I
- : DNGN_STONE_STAIRS_UP_I);
- }
- }
-} // end build_vaults()
-
-// returns altar_count - seems rather odd to me to force such a return
-// when I believe the value is only used in the case of the ecumenical
-// temple - oh, well... {dlb}
-static int vault_grid( int level_number, int vx, int vy, int altar_count,
- FixedVector < char, 7 > &acq_item_class,
- FixedVector < int, 7 > &mons_array,
- char vgrid, int &initial_x, int &initial_y,
- int force_vault, int &num_runes)
-{
- int not_used;
-
- // first, set base tile for grids {dlb}:
- grd[vx][vy] = ((vgrid == 'x') ? DNGN_ROCK_WALL :
- (vgrid == 'X') ? DNGN_PERMAROCK_WALL :
- (vgrid == 'c') ? DNGN_STONE_WALL :
- (vgrid == 'v') ? DNGN_METAL_WALL :
- (vgrid == 'b') ? DNGN_GREEN_CRYSTAL_WALL :
- (vgrid == 'a') ? DNGN_WAX_WALL :
- (vgrid == '+') ? DNGN_CLOSED_DOOR :
- (vgrid == '=') ? DNGN_SECRET_DOOR :
- (vgrid == 'w') ? DNGN_DEEP_WATER :
- (vgrid == 'l') ? DNGN_LAVA :
- (vgrid == '>') ? DNGN_ROCK_STAIRS_DOWN :
- (vgrid == '<') ? DNGN_ROCK_STAIRS_UP :
- (vgrid == '}') ? DNGN_STONE_STAIRS_DOWN_I :
- (vgrid == '{') ? DNGN_STONE_STAIRS_UP_I :
- (vgrid == ')') ? DNGN_STONE_STAIRS_DOWN_II :
- (vgrid == '(') ? DNGN_STONE_STAIRS_UP_II :
- (vgrid == ']') ? DNGN_STONE_STAIRS_DOWN_III :
- (vgrid == '[') ? DNGN_STONE_STAIRS_UP_III :
- (vgrid == 'A') ? DNGN_STONE_ARCH :
- (vgrid == 'B') ? (DNGN_ALTAR_ZIN + altar_count) :// see below
- (vgrid == 'C') ? pick_an_altar() : // f(x) elsewhere {dlb}
-
- (vgrid == 'F') ? (one_chance_in(100)
- ? (coinflip() ? DNGN_SILVER_STATUE
- : DNGN_ORANGE_CRYSTAL_STATUE)
- : DNGN_GRANITE_STATUE) :
-
- (vgrid == 'I') ? DNGN_ORCISH_IDOL :
- (vgrid == 'S') ? DNGN_SILVER_STATUE :
- (vgrid == 'G') ? DNGN_GRANITE_STATUE :
- (vgrid == 'H') ? DNGN_ORANGE_CRYSTAL_STATUE :
- (vgrid == 'T') ? DNGN_BLUE_FOUNTAIN :
- (vgrid == 'U') ? DNGN_SPARKLING_FOUNTAIN :
- (vgrid == 'V') ? DNGN_PERMADRY_FOUNTAIN :
- (vgrid == '\0')? DNGN_ROCK_WALL :
- DNGN_FLOOR); // includes everything else
-
- // then, handle oddball grids {dlb}:
- switch (vgrid)
- {
- case 'B':
- altar_count++;
- break;
- case '@':
- initial_x = vx;
- initial_y = vy;
- break;
- case '^':
- place_specific_trap(vx, vy, TRAP_RANDOM);
- break;
- }
-
- // then, handle grids that place "stuff" {dlb}:
- switch (vgrid) // yes, I know this is a bit ugly ... {dlb}
- {
- case 'R':
- case '$':
- case '%':
- case '*':
- case '|':
- case 'P': // possible rune
- case 'O': // definite rune
- case 'Z': // definite orb
- {
- int item_made = NON_ITEM;
- unsigned char which_class = OBJ_RANDOM;
- unsigned char which_type = OBJ_RANDOM;
- int which_depth;
- bool possible_rune = one_chance_in(3); // lame, I know {dlb}
- int spec = 250;
-
- if (vgrid == 'R')
- {
- which_class = OBJ_FOOD;
- which_type = (one_chance_in(3) ? FOOD_ROYAL_JELLY
- : FOOD_HONEYCOMB);
- }
- else if (vgrid == '$')
- {
- which_class = OBJ_GOLD;
- which_type = OBJ_RANDOM;
- }
- else if (vgrid == '%' || vgrid == '*')
- {
- which_class = OBJ_RANDOM;
- which_type = OBJ_RANDOM;
- }
- else if (vgrid == 'Z')
- {
- which_class = OBJ_ORBS;
- which_type = ORB_ZOT;
- }
- else if (vgrid == '|'
- || (vgrid == 'P' && (!possible_rune || num_runes > 0))
- || (vgrid == 'O' && num_runes > 0))
- {
- which_class = acq_item_class[random2(7)];
- which_type = OBJ_RANDOM;
- }
- else // for 'P' (1 out of 3 times) {dlb}
- {
- which_class = OBJ_MISCELLANY;
- which_type = MISC_RUNE_OF_ZOT;
- num_runes++;
-
- if (you.level_type == LEVEL_PANDEMONIUM)
- {
- if (force_vault >= 60 && force_vault <= 63)
- spec = force_vault;
- else
- spec = 50;
- }
- else if (you.level_type == LEVEL_ABYSS)
- spec = 51;
- else
- spec = you.where_are_you;
- }
-
- which_depth = ((vgrid == '|'
- || vgrid == 'P'
- || vgrid == 'O'
- || vgrid == 'Z') ? MAKE_GOOD_ITEM :
- (vgrid == '*') ? 5 + (level_number * 2)
- : level_number);
-
- item_made = items( 1, which_class, which_type, true,
- which_depth, spec );
-
- if (item_made != NON_ITEM)
- {
- mitm[item_made].x = vx;
- mitm[item_made].y = vy;
- }
- }
- break;
- }
-
- // finally, handle grids that place monsters {dlb}:
- if (vgrid >= '0' && vgrid <= '9')
- {
- int monster_level;
- int monster_type_thing;
-
- monster_level = ((vgrid == '8') ? (4 + (level_number * 2)) :
- (vgrid == '9') ? (5 + level_number) : level_number);
-
- if (monster_level > 30) // very high level monsters more common here
- monster_level = 30;
-
- monster_type_thing = ((vgrid == '8'
- || vgrid == '9'
- || vgrid == '0') ? RANDOM_MONSTER
- : mons_array[(vgrid - '1')]);
-
- place_monster( not_used, monster_type_thing, monster_level, BEH_SLEEP,
- MHITNOT, true, vx, vy, false);
- }
-
- // again, this seems odd, given that this is just one of many
- // vault types {dlb}
- return (altar_count);
-} // end vault_grid()
-
-static void replace_area(int sx, int sy, int ex, int ey, unsigned char replace,
- unsigned char feature)
-{
- int x,y;
- for(x=sx; x<=ex; x++)
- for(y=sy; y<=ey; y++)
- if (grd[x][y] == replace)
- grd[x][y] = feature;
-}
-
-static void join_the_dots(unsigned char dotx1, unsigned char doty1,
- unsigned char dotx2, unsigned char doty2,
- char forbid_x1, char forbid_y1, char forbid_x2,
- char forbid_y2)
-{
- if (dotx1 == dotx2 && doty1 == doty2)
- return;
-
- char atx = dotx1, aty = doty1;
-
- int join_count = 0;
-
- grd[atx][aty] = DNGN_FLOOR;
-
- do
- {
- join_count++;
-
- if (join_count > 10000) // just insurance
- return;
-
- if (atx < dotx2
- && (forbid_x1 == 0
- || (atx + 1 < forbid_x1 || atx + 1 > forbid_x2
- || (aty > forbid_y2 || aty < forbid_y1))))
- {
- atx++;
- goto continuing;
- }
-
- if (atx > dotx2
- && (forbid_x2 == 0
- || (atx - 1 > forbid_x2 || atx - 1 < forbid_x1
- || (aty > forbid_y2 || aty < forbid_y1))))
- {
- atx--;
- goto continuing;
- }
-
- if (aty > doty2
- && (forbid_y2 == 0
- || (aty - 1 > forbid_y2 || aty - 1 < forbid_y1
- || (atx > forbid_x2 || atx < forbid_x1))))
- {
- aty--;
- goto continuing;
- }
-
- if (aty < doty2
- && (forbid_y1 == 0
- || (aty + 1 < forbid_y1 || aty + 1 > forbid_y2
- || (atx > forbid_x2 || atx < forbid_x1))))
- {
- aty++;
- goto continuing;
- }
-
- continuing:
- grd[atx][aty] = DNGN_FLOOR;
-
- }
- while (atx != dotx2 || aty != doty2);
-} // end join_the_dots()
-
-static void place_pool(unsigned char pool_type, unsigned char pool_x1,
- unsigned char pool_y1, unsigned char pool_x2,
- unsigned char pool_y2)
-{
- int i, j;
- unsigned char left_edge, right_edge;
-
- // don't place LAVA pools in crypt.. use shallow water instead.
- if (pool_type == DNGN_LAVA
- && (player_in_branch(BRANCH_CRYPT) || player_in_branch(BRANCH_TOMB)))
- {
- pool_type = DNGN_SHALLOW_WATER;
- }
-
- if (pool_x1 >= pool_x2 - 4 || pool_y1 >= pool_y2 - 4)
- return;
-
- left_edge = pool_x1 + 2 + random2(pool_x2 - pool_x1);
- right_edge = pool_x2 - 2 - random2(pool_x2 - pool_x1);
-
- for (j = pool_y1 + 1; j < pool_y2 - 1; j++)
- {
- for (i = pool_x1 + 1; i < pool_x2 - 1; i++)
- {
- if (i >= left_edge && i <= right_edge && grd[i][j] == DNGN_FLOOR)
- grd[i][j] = pool_type;
- }
-
- if (j - pool_y1 < (pool_y2 - pool_y1) / 2 || one_chance_in(4))
- {
- if (left_edge > pool_x1 + 1)
- left_edge -= random2(3);
-
- if (right_edge < pool_x2 - 1)
- right_edge += random2(3);
- }
-
- if (left_edge < pool_x2 - 1
- && (j - pool_y1 >= (pool_y2 - pool_y1) / 2
- || left_edge <= pool_x1 + 2 || one_chance_in(4)))
- {
- left_edge += random2(3);
- }
-
- if (right_edge > pool_x1 + 1
- && (j - pool_y1 >= (pool_y2 - pool_y1) / 2
- || right_edge >= pool_x2 - 2 || one_chance_in(4)))
- {
- right_edge -= random2(3);
- }
- }
-} // end place_pool()
-
-static void many_pools(unsigned char pool_type)
-{
- int pools = 0;
- int i = 0, j = 0, k = 0, l = 0;
- int m = 0, n = 0;
- int no_pools = 20 + random2avg(9, 2);
- int timeout = 0;
-
- if (player_in_branch( BRANCH_COCYTUS ))
- pool_type = DNGN_DEEP_WATER;
- else if (player_in_branch( BRANCH_GEHENNA ))
- pool_type = DNGN_LAVA;
-
- do
- {
- timeout++;
-
- if (timeout >= 30000)
- break;
-
- i = 6 + random2( GXM - 26 );
- j = 6 + random2( GYM - 26 );
- k = i + 2 + roll_dice( 2, 9 );
- l = j + 2 + roll_dice( 2, 9 );
-
- for (m = i; m < k; m++)
- {
- for (n = j; n < l; n++)
- {
- if (grd[m][n] != DNGN_FLOOR)
- goto continue_pools;
- }
- }
-
- place_pool(pool_type, i, j, k, l);
- pools++;
-
- continue_pools:
- continue;
- }
- while (pools < no_pools);
-} // end many_pools()
-
-void item_colour( item_def &item )
-{
- int switchnum = 0;
- int temp_value;
-
- switch (item.base_type)
- {
- case OBJ_WEAPONS:
- if (is_unrandom_artefact( item ))
- break; // unrandarts already coloured
-
- if (is_fixed_artefact( item ))
- {
- switch (item.special) // was: - 180, but that is *wrong* {dlb}
- {
- case SPWPN_SINGING_SWORD:
- case SPWPN_SCEPTRE_OF_TORMENT:
- item.colour = YELLOW;
- break;
- case SPWPN_WRATH_OF_TROG:
- case SPWPN_SWORD_OF_POWER:
- item.colour = RED;
- break;
- case SPWPN_SCYTHE_OF_CURSES:
- item.colour = DARKGREY;
- break;
- case SPWPN_MACE_OF_VARIABILITY:
- item.colour = random_colour();
- break;
- case SPWPN_GLAIVE_OF_PRUNE:
- item.colour = MAGENTA;
- break;
- case SPWPN_SWORD_OF_ZONGULDROK:
- item.colour = LIGHTGREY;
- break;
- case SPWPN_KNIFE_OF_ACCURACY:
- item.colour = LIGHTCYAN;
- break;
- case SPWPN_STAFF_OF_OLGREB:
- item.colour = GREEN;
- break;
- case SPWPN_VAMPIRES_TOOTH:
- item.colour = WHITE;
- break;
- case SPWPN_STAFF_OF_WUCAD_MU:
- item.colour = BROWN;
- break;
- }
- break;
- }
-
- if (is_demonic( item.sub_type ))
- item.colour = random_colour();
- else if (launches_things( item.sub_type ))
- item.colour = BROWN;
- else
- {
- switch (item.sub_type)
- {
- case WPN_CLUB:
- case WPN_GIANT_CLUB:
- case WPN_GIANT_SPIKED_CLUB:
- case WPN_ANCUS:
- case WPN_WHIP:
- case WPN_QUARTERSTAFF:
- item.colour = BROWN;
- break;
- case WPN_QUICK_BLADE:
- item.colour = LIGHTBLUE;
- break;
- case WPN_EXECUTIONERS_AXE:
- item.colour = RED;
- break;
- default:
- item.colour = LIGHTCYAN;
- if (get_equip_race(item) == ISFLAG_DWARVEN)
- item.colour = CYAN;
- break;
- }
- }
-
- // I don't think this is ever done -- see start of case {dlb}:
- if (is_random_artefact( item ) && one_chance_in(5))
- item.colour = random_colour();
- break;
-
- case OBJ_MISSILES:
- switch (item.sub_type)
- {
- case MI_STONE:
- case MI_LARGE_ROCK:
- case MI_ARROW:
- item.colour = BROWN;
- break;
- case MI_NEEDLE:
- item.colour = WHITE;
- break;
- default:
- item.colour = LIGHTCYAN;
- if (get_equip_race(item) == ISFLAG_DWARVEN)
- item.colour = CYAN;
- break;
- }
- break;
-
- case OBJ_ARMOUR:
- if (is_unrandom_artefact( item ))
- break; /* unrandarts have already been coloured */
-
- switch (item.sub_type)
- {
- case ARM_CLOAK:
- case ARM_ROBE:
- case ARM_NAGA_BARDING:
- case ARM_CENTAUR_BARDING:
- case ARM_CAP:
- item.colour = random_colour();
- break;
-
- case ARM_HELMET:
- //caps and wizard's hats are random coloured
- if (get_helmet_type(item) == THELM_CAP
- || get_helmet_type(item) == THELM_WIZARD_HAT)
- {
- item.colour = random_colour();
- }
- else
- item.colour = LIGHTCYAN;
- break;
-
- case ARM_BOOTS: // maybe more interesting boot colours?
- case ARM_GLOVES:
- case ARM_LEATHER_ARMOUR:
- item.colour = BROWN;
- break;
- case ARM_DRAGON_HIDE:
- case ARM_DRAGON_ARMOUR:
- item.colour = mons_colour( MONS_DRAGON );
- break;
- case ARM_TROLL_HIDE:
- case ARM_TROLL_LEATHER_ARMOUR:
- item.colour = mons_colour( MONS_TROLL );
- break;
- case ARM_CRYSTAL_PLATE_MAIL:
- item.colour = LIGHTGREY;
- break;
- case ARM_ICE_DRAGON_HIDE:
- case ARM_ICE_DRAGON_ARMOUR:
- item.colour = mons_colour( MONS_ICE_DRAGON );
- break;
- case ARM_STEAM_DRAGON_HIDE:
- case ARM_STEAM_DRAGON_ARMOUR:
- item.colour = mons_colour( MONS_STEAM_DRAGON );
- break;
- case ARM_MOTTLED_DRAGON_HIDE:
- case ARM_MOTTLED_DRAGON_ARMOUR:
- item.colour = mons_colour( MONS_MOTTLED_DRAGON );
- break;
- case ARM_STORM_DRAGON_HIDE:
- case ARM_STORM_DRAGON_ARMOUR:
- item.colour = mons_colour( MONS_STORM_DRAGON );
- break;
- case ARM_GOLD_DRAGON_HIDE:
- case ARM_GOLD_DRAGON_ARMOUR:
- item.colour = mons_colour( MONS_GOLDEN_DRAGON );
- break;
- case ARM_ANIMAL_SKIN:
- item.colour = BROWN;
- break;
- case ARM_SWAMP_DRAGON_HIDE:
- case ARM_SWAMP_DRAGON_ARMOUR:
- item.colour = mons_colour( MONS_SWAMP_DRAGON );
- break;
- default:
- item.colour = LIGHTCYAN;
- if (get_equip_race(item) == ISFLAG_DWARVEN)
- item.colour = CYAN;
- break;
- }
-
- // I don't think this is ever done -- see start of case {dlb}:
- if (is_random_artefact( item ) && one_chance_in(5))
- item.colour = random_colour();
- break;
-
- case OBJ_WANDS:
- item.special = you.item_description[IDESC_WANDS][item.sub_type];
-
- switch (item.special % 12)
- {
- case 0: //"iron wand"
- item.colour = CYAN;
- break;
- case 1: //"brass wand"
- case 5: //"gold wand"
- item.colour = YELLOW;
- break;
- case 2: //"bone wand"
- case 8: //"ivory wand"
- case 9: //"glass wand"
- case 10: //"lead wand"
- default:
- item.colour = LIGHTGREY;
- break;
- case 3: //"wooden wand"
- case 4: //"copper wand"
- case 7: //"bronze wand"
- item.colour = BROWN;
- break;
- case 6: //"silver wand"
- item.colour = WHITE;
- break;
- case 11: //"plastic wand"
- item.colour = random_colour();
- break;
- }
-
- if (item.special / 12 == 9)
- item.colour = DARKGREY;
-
- // rare wands (eg disintegration - these will be very rare):
- // maybe only 1 thing, like: crystal, shining, etc.
- break;
-
- case OBJ_POTIONS:
- item.special = you.item_description[IDESC_POTIONS][item.sub_type];
-
- switch (item.special % 14)
- {
- case 0: //"clear potion"
- default:
- item.colour = LIGHTGREY;
- break;
- case 1: //"blue potion"
- case 7: //"inky potion"
- item.colour = BLUE;
- break;
- case 2: //"black potion"
- item.colour = DARKGREY;
- break;
- case 3: //"silvery potion"
- case 13: //"white potion"
- item.colour = WHITE;
- break;
- case 4: //"cyan potion"
- item.colour = CYAN;
- break;
- case 5: //"purple potion"
- item.colour = MAGENTA;
- break;
- case 6: //"orange potion"
- item.colour = LIGHTRED;
- break;
- case 8: //"red potion"
- item.colour = RED;
- break;
- case 9: //"yellow potion"
- item.colour = YELLOW;
- break;
- case 10: //"green potion"
- item.colour = GREEN;
- break;
- case 11: //"brown potion"
- item.colour = BROWN;
- break;
- case 12: //"pink potion"
- item.colour = LIGHTMAGENTA;
- break;
- }
- break;
-
- case OBJ_FOOD:
- switch (item.sub_type)
- {
- case FOOD_BEEF_JERKY:
- case FOOD_BREAD_RATION:
- case FOOD_LYCHEE:
- case FOOD_MEAT_RATION:
- case FOOD_RAMBUTAN:
- case FOOD_SAUSAGE:
- case FOOD_SULTANA:
- item.colour = BROWN;
- break;
- case FOOD_BANANA:
- case FOOD_CHEESE:
- case FOOD_HONEYCOMB:
- case FOOD_LEMON:
- case FOOD_PIZZA:
- case FOOD_ROYAL_JELLY:
- item.colour = YELLOW;
- break;
- case FOOD_PEAR:
- item.colour = LIGHTGREEN;
- break;
- case FOOD_CHOKO:
- case FOOD_SNOZZCUMBER:
- item.colour = GREEN;
- break;
- case FOOD_APRICOT:
- case FOOD_ORANGE:
- item.colour = LIGHTRED;
- break;
- case FOOD_STRAWBERRY:
- item.colour = RED;
- break;
- case FOOD_APPLE:
- item.colour = (coinflip() ? RED : GREEN);
- break;
- case FOOD_GRAPE:
- item.colour = (coinflip() ? MAGENTA : GREEN);
- break;
- case FOOD_CHUNK:
- // set the appropriate colour of the meat:
- temp_value = mons_colour( item.plus );
- item.colour = (temp_value == BLACK) ? LIGHTRED : temp_value;
- break;
- default:
- item.colour = BROWN;
- }
- break;
-
- case OBJ_JEWELLERY:
- /* unrandarts have already been coloured */
- if (is_unrandom_artefact( item ))
- break;
- else if (is_random_artefact( item ))
- {
- item.colour = random_colour();
- break;
- }
-
- item.colour = YELLOW;
- item.special = you.item_description[IDESC_RINGS][item.sub_type];
-
- switchnum = item.special % 13;
-
- switch (switchnum)
- {
- case 0:
- case 5:
- item.colour = BROWN;
- break;
- case 1:
- case 8:
- case 11:
- item.colour = LIGHTGREY;
- break;
- case 2:
- case 6:
- item.colour = YELLOW;
- break;
- case 3:
- case 4:
- item.colour = CYAN;
- break;
- case 7:
- item.colour = BROWN;
- break;
- case 9:
- case 10:
- item.colour = WHITE;
- break;
- case 12:
- item.colour = GREEN;
- break;
- case 13:
- item.colour = LIGHTCYAN;
- break;
- }
-
- if (item.sub_type >= AMU_RAGE)
- {
- switch (switchnum)
- {
- case 0: //"zirconium amulet"
- case 9: //"ivory amulet"
- case 11: //"platinum amulet"
- item.colour = WHITE;
- break;
- case 1: //"sapphire amulet"
- item.colour = LIGHTBLUE;
- break;
- case 2: //"golden amulet"
- case 6: //"brass amulet"
- item.colour = YELLOW;
- break;
- case 3: //"emerald amulet"
- item.colour = GREEN;
- break;
- case 4: //"garnet amulet"
- case 8: //"ruby amulet"
- item.colour = RED;
- break;
- case 5: //"bronze amulet"
- case 7: //"copper amulet"
- item.colour = BROWN;
- break;
- case 10: //"bone amulet"
- item.colour = LIGHTGREY;
- break;
- case 12: //"jade amulet"
- item.colour = GREEN;
- break;
- case 13: //"plastic amulet"
- item.colour = random_colour();
- }
- }
-
- // blackened - same for both rings and amulets
- if (item.special / 13 == 5)
- item.colour = DARKGREY;
- break;
-
- case OBJ_SCROLLS:
- item.colour = LIGHTGREY;
- item.special = you.item_description[IDESC_SCROLLS][item.sub_type];
- item.plus = you.item_description[IDESC_SCROLLS_II][item.sub_type];
- break;
-
- case OBJ_BOOKS:
- switch (item.special % 10)
- {
- case 0:
- case 1:
- default:
- item.colour = random_colour();
- break;
- case 2:
- item.colour = (one_chance_in(3) ? BROWN : DARKGREY);
- break;
- case 3:
- item.colour = CYAN;
- break;
- case 4:
- item.colour = LIGHTGREY;
- break;
- }
- break;
-
- case OBJ_STAVES:
- item.colour = BROWN;
- break;
-
- case OBJ_ORBS:
- item.colour = LIGHTMAGENTA;
- break;
-
- case OBJ_MISCELLANY:
- switch (item.sub_type)
- {
- case MISC_BOTTLED_EFREET:
- case MISC_STONE_OF_EARTH_ELEMENTALS:
- item.colour = BROWN;
- break;
-
- case MISC_AIR_ELEMENTAL_FAN:
- case MISC_CRYSTAL_BALL_OF_ENERGY:
- case MISC_CRYSTAL_BALL_OF_FIXATION:
- case MISC_CRYSTAL_BALL_OF_SEEING:
- case MISC_DISC_OF_STORMS:
- case MISC_HORN_OF_GERYON:
- case MISC_LANTERN_OF_SHADOWS:
- item.colour = LIGHTGREY;
- break;
-
- case MISC_LAMP_OF_FIRE:
- item.colour = YELLOW;
- break;
-
- case MISC_BOX_OF_BEASTS:
- item.colour = DARKGREY;
- break;
-
- case MISC_RUNE_OF_ZOT:
- switch (item.plus)
- {
- case RUNE_DIS: // iron
- item.colour = CYAN;
- break;
-
- case RUNE_COCYTUS: // icy
- item.colour = LIGHTBLUE;
- break;
-
- case RUNE_TARTARUS: // bone
- item.colour = WHITE;
- break;
-
- case RUNE_SLIME_PITS: // slimy
- item.colour = GREEN;
- break;
-
- case RUNE_SNAKE_PIT: // serpentine
- case RUNE_ELVEN_HALLS: // elven
- item.colour = LIGHTGREEN;
- break;
-
- case RUNE_VAULTS: // silver
- item.colour = LIGHTGREY;
- break;
-
- case RUNE_TOMB: // golden
- item.colour = YELLOW;
- break;
-
- case RUNE_SWAMP: // decaying
- item.colour = BROWN;
- break;
-
- // These two are hardly unique, but since colour isn't used for
- // stacking, so we don't have to worry to much about this. -- bwr
- case RUNE_DEMONIC: // random pandemonium demonlords
- case RUNE_ABYSSAL: // random in abyss
- item.colour = random_colour();
- break;
-
- case RUNE_MNOLEG: // glowing
- item.colour = coinflip() ? MAGENTA : LIGHTMAGENTA;
- break;
-
- case RUNE_LOM_LOBON: // magical
- item.colour = BLUE;
- break;
-
- case RUNE_CEREBOV: // fiery
- item.colour = coinflip() ? RED : LIGHTRED;
- break;
-
- case RUNE_GEHENNA: // obsidian
- case RUNE_GLOORX_VLOQ: // dark
- default:
- item.colour = DARKGREY;
- break;
- }
- break;
-
- case MISC_EMPTY_EBONY_CASKET:
- item.colour = DARKGREY;
- break;
-
- case MISC_DECK_OF_SUMMONINGS:
- case MISC_DECK_OF_WONDERS:
- case MISC_DECK_OF_TRICKS:
- case MISC_DECK_OF_POWER:
- default:
- item.colour = random_colour();
- break;
- }
- break;
-
- case OBJ_CORPSES:
- // set the appropriate colour of the body:
- temp_value = mons_colour( item.plus );
- item.colour = (temp_value == BLACK) ? LIGHTRED : temp_value;
- break;
-
- case OBJ_GOLD:
- item.colour = YELLOW;
- break;
- }
-} // end item_colour()
-
-// Checks how rare a weapon is. Many of these have special routines for
-// placement, especially those with a rarity of zero. Chance is out of 10.
-static int rare_weapon(int w_type)
-{
- // zero value weapons must be placed specially -- see items() {dlb}
- if (is_demonic(w_type))
- return 0;
-
- return (weapon_rarity(w_type));
-} // end rare_weapon()
-
-//jmf: generate altar based on where you are, or possibly randomly
-static int pick_an_altar(void)
-{
- int altar_type = 0;
- int temp_rand; // probability determination {dlb}
-
- if (player_in_branch( BRANCH_SLIME_PITS )
- || player_in_branch( BRANCH_ECUMENICAL_TEMPLE )
- || you.level_type == LEVEL_LABYRINTH)
- {
- // no extra altars in temple, none at all in slime pits or labyrinth
- altar_type = DNGN_FLOOR;
- }
- else if (you.level_type == LEVEL_DUNGEON && !one_chance_in(5))
- {
- switch (you.where_are_you)
- {
- case BRANCH_CRYPT:
- altar_type = (coinflip() ? DNGN_ALTAR_KIKUBAAQUDGHA
- : DNGN_ALTAR_YREDELEMNUL);
- break;
-
- case BRANCH_ORCISH_MINES: // violent gods
- temp_rand = random2(5);
-
- altar_type = ((temp_rand == 0) ? DNGN_ALTAR_VEHUMET :
- (temp_rand == 1) ? DNGN_ALTAR_MAKHLEB :
- (temp_rand == 2) ? DNGN_ALTAR_OKAWARU :
- (temp_rand == 3) ? DNGN_ALTAR_TROG
- : DNGN_ALTAR_XOM);
- break;
-
- case BRANCH_VAULTS: // "lawful" gods
- temp_rand = random2(7);
-
- altar_type = ((temp_rand == 0) ? DNGN_ALTAR_ELYVILON :
- (temp_rand == 1) ? DNGN_ALTAR_SIF_MUNA :
- (temp_rand == 2) ? DNGN_ALTAR_SHINING_ONE :
- (temp_rand == 3 || temp_rand == 4) ? DNGN_ALTAR_OKAWARU
- : DNGN_ALTAR_ZIN);
- break;
-
- case BRANCH_HALL_OF_BLADES:
- altar_type = DNGN_ALTAR_OKAWARU;
- break;
-
- case BRANCH_ELVEN_HALLS: // "magic" gods
- temp_rand = random2(4);
-
- altar_type = ((temp_rand == 0) ? DNGN_ALTAR_VEHUMET :
- (temp_rand == 1) ? DNGN_ALTAR_SIF_MUNA :
- (temp_rand == 2) ? DNGN_ALTAR_XOM
- : DNGN_ALTAR_MAKHLEB);
- break;
-
- case BRANCH_TOMB:
- altar_type = DNGN_ALTAR_KIKUBAAQUDGHA;
- break;
-
- default:
- do
- {
- altar_type = DNGN_ALTAR_ZIN + random2(NUM_GODS - 1);
- }
- while (altar_type == DNGN_ALTAR_NEMELEX_XOBEH);
- break;
- }
- }
- else
- {
- // Note: this case includes the pandemonium or the abyss.
- temp_rand = random2(9);
-
- altar_type = ((temp_rand == 0) ? DNGN_ALTAR_ZIN :
- (temp_rand == 1) ? DNGN_ALTAR_SHINING_ONE :
- (temp_rand == 2) ? DNGN_ALTAR_KIKUBAAQUDGHA :
- (temp_rand == 3) ? DNGN_ALTAR_XOM :
- (temp_rand == 4) ? DNGN_ALTAR_OKAWARU :
- (temp_rand == 5) ? DNGN_ALTAR_MAKHLEB :
- (temp_rand == 6) ? DNGN_ALTAR_SIF_MUNA :
- (temp_rand == 7) ? DNGN_ALTAR_TROG
- : DNGN_ALTAR_ELYVILON);
- }
-
- return (altar_type);
-} // end pick_an_altar()
-
-static void place_altar(void)
-{
- int px, py;
- int i, j;
- int k = 0, l = 0;
- int altar_type = pick_an_altar();
-
- while(true)
- {
- rand_px:
-
- px = 15 + random2(55);
- py = 15 + random2(45);
- k++;
-
- if (k == 5000)
- return;
-
- l = 0;
-
- for (i = px - 2; i < px + 3; i++)
- {
- for (j = py - 2; j < py + 3; j++)
- {
- if (grd[i][j] == DNGN_FLOOR)
- l++;
-
- if ((grd[i][j] != DNGN_ROCK_WALL
- && grd[i][j] != DNGN_CLOSED_DOOR
- && grd[i][j] != DNGN_SECRET_DOOR
- && grd[i][j] != DNGN_FLOOR)
- || mgrd[i][j] != NON_MONSTER)
- {
- goto rand_px;
- }
- }
- }
-
- if (l == 0)
- goto rand_px;
-
- for (i = px - 2; i < px + 3; i++)
- {
- for (j = py - 2; j < py + 3; j++)
- {
- grd[i][j] = DNGN_FLOOR;
- }
- }
-
- grd[px][py] = altar_type;
-
- return;
- }
-} // end place_altar()
-
-static void place_shops(int level_number)
-{
- int temp_rand = 0; // probability determination {dlb}
- int timeout = 0;
-
- unsigned char no_shops = 0;
- unsigned char shop_place_x = 0;
- unsigned char shop_place_y = 0;
-
- temp_rand = random2(125);
-
-#if DEBUG_SHOPS
- no_shops = MAX_SHOPS;
-#else
- no_shops = ((temp_rand > 28) ? 0 : // 76.8%
- (temp_rand > 4) ? 1 // 19.2%
- : 1 + random2( MAX_SHOPS )); // 4.0%
-
- if (no_shops == 0 || level_number < 3)
- return;
-#endif
-
- for (int i = 0; i < no_shops; i++)
- {
- timeout = 0;
-
- do
- {
- shop_place_x = random2(GXM - 20) + 10;
- shop_place_y = random2(GYM - 20) + 10;
-
- timeout++;
-
- if (timeout > 20000)
- return;
- }
- while (grd[shop_place_x][shop_place_y] != DNGN_FLOOR);
-
- place_spec_shop(level_number, shop_place_x, shop_place_y, SHOP_RANDOM);
- }
-} // end place_shops()
-
-static void place_spec_shop( int level_number,
- unsigned char shop_x, unsigned char shop_y,
- unsigned char force_s_type )
-{
- int orb = 0;
- int i = 0;
- int j = 0; // loop variable
- int item_level;
-
- for (i = 0; i < MAX_SHOPS; i++)
- {
- if (env.shop[i].type == SHOP_UNASSIGNED)
- break;
- }
-
- if (i == MAX_SHOPS)
- return;
-
- for (j = 0; j < 3; j++)
- {
- env.shop[i].keeper_name[j] = 1 + random2(200);
- }
-
- env.shop[i].level = level_number * 2;
-
- env.shop[i].type = (force_s_type != SHOP_RANDOM) ? force_s_type
- : random2(NUM_SHOPS);
-
- if (env.shop[i].type == SHOP_FOOD)
- {
- env.shop[i].greed = 10 + random2(5);
- }
- else if (env.shop[i].type != SHOP_WEAPON_ANTIQUE
- && env.shop[i].type != SHOP_ARMOUR_ANTIQUE
- && env.shop[i].type != SHOP_GENERAL_ANTIQUE)
- {
- env.shop[i].greed = 10 + random2(5) + random2(level_number / 2);
- }
- else
- {
- env.shop[i].greed = 15 + random2avg(19, 2) + random2(level_number);
- }
-
- int plojy = 5 + random2avg(12, 3);
-
- for (j = 0; j < plojy; j++)
- {
- if (env.shop[i].type != SHOP_WEAPON_ANTIQUE
- && env.shop[i].type != SHOP_ARMOUR_ANTIQUE
- && env.shop[i].type != SHOP_GENERAL_ANTIQUE)
- {
- item_level = level_number + random2((level_number + 1) * 2);
- }
- else
- {
- item_level = level_number + random2((level_number + 1) * 3);
- }
-
- if (one_chance_in(4))
- item_level = MAKE_GOOD_ITEM;
-
- // don't generate gold in shops! This used to be possible with
- // General Stores (see item_in_shop() below) (GDL)
- while(true)
- {
- orb = items( 1, item_in_shop(env.shop[i].type), OBJ_RANDOM, true,
- item_level, 250 );
-
- if (orb != NON_ITEM
- && mitm[orb].base_type != OBJ_GOLD
- && (env.shop[i].type != SHOP_GENERAL_ANTIQUE
- || (mitm[orb].base_type != OBJ_MISSILES
- && mitm[orb].base_type != OBJ_FOOD)))
- {
- break;
- }
-
- // reset object and try again
- if (orb != NON_ITEM)
- {
- mitm[orb].base_type = OBJ_UNASSIGNED;
- mitm[orb].quantity = 0;
- }
- }
-
- if (orb == NON_ITEM)
- break;
-
- // set object 'position' (gah!) & ID status
- mitm[orb].x = 0;
- mitm[orb].y = 5 + i;
-
- if (env.shop[i].type != SHOP_WEAPON_ANTIQUE
- && env.shop[i].type != SHOP_ARMOUR_ANTIQUE
- && env.shop[i].type != SHOP_GENERAL_ANTIQUE)
- {
- set_ident_flags( mitm[orb], ISFLAG_IDENT_MASK );
- }
- }
-
- env.shop[i].x = shop_x;
- env.shop[i].y = shop_y;
-
- grd[shop_x][shop_y] = DNGN_ENTER_SHOP;
-} // end place_spec_shop()
-
-static unsigned char item_in_shop(unsigned char shop_type)
-{
- switch (shop_type)
- {
- case SHOP_WEAPON:
- if (one_chance_in(5))
- return (OBJ_MISSILES);
- // *** deliberate fall through here {dlb} ***
- case SHOP_WEAPON_ANTIQUE:
- return (OBJ_WEAPONS);
-
- case SHOP_ARMOUR:
- case SHOP_ARMOUR_ANTIQUE:
- return (OBJ_ARMOUR);
-
- case SHOP_GENERAL:
- case SHOP_GENERAL_ANTIQUE:
- return (OBJ_RANDOM);
-
- case SHOP_JEWELLERY:
- return (OBJ_JEWELLERY);
-
- case SHOP_WAND:
- return (OBJ_WANDS);
-
- case SHOP_BOOK:
- return (OBJ_BOOKS);
-
- case SHOP_FOOD:
- return (OBJ_FOOD);
-
- case SHOP_DISTILLERY:
- return (OBJ_POTIONS);
-
- case SHOP_SCROLL:
- return (OBJ_SCROLLS);
- }
-
- return (OBJ_RANDOM);
-} // end item_in_shop()
-
-static void spotty_level(bool seeded, int iterations, bool boxy)
-{
- // assumes starting with a level full of rock walls (1)
- int i, j, k, l;
-
- if (!seeded)
- {
- for (i = DNGN_STONE_STAIRS_DOWN_I; i < DNGN_ROCK_STAIRS_UP; i++)
- {
- if (i == DNGN_ROCK_STAIRS_DOWN
- || (i == DNGN_STONE_STAIRS_UP_I
- && !player_in_branch( BRANCH_SLIME_PITS )))
- {
- continue;
- }
-
- do
- {
- j = 10 + random2(GXM - 20);
- k = 10 + random2(GYM - 20);
- }
- while (grd[j][k] != DNGN_ROCK_WALL
- && grd[j + 1][k] != DNGN_ROCK_WALL);
-
- grd[j][k] = i;
-
- // creating elevators
- if (i == DNGN_STONE_STAIRS_DOWN_I
- && !player_in_branch( BRANCH_SLIME_PITS ))
- {
- grd[j + 1][k] = DNGN_STONE_STAIRS_UP_I;
- }
-
- if (grd[j][k - 1] == DNGN_ROCK_WALL)
- grd[j][k - 1] = DNGN_FLOOR;
- if (grd[j][k + 1] == DNGN_ROCK_WALL)
- grd[j][k + 1] = DNGN_FLOOR;
- if (grd[j - 1][k] == DNGN_ROCK_WALL)
- grd[j - 1][k] = DNGN_FLOOR;
- if (grd[j + 1][k] == DNGN_ROCK_WALL)
- grd[j + 1][k] = DNGN_FLOOR;
- }
- } // end if !seeded
-
- l = iterations;
-
- // boxy levels have more clearing, so they get fewer iterations:
- if (l == 0)
- l = 200 + random2( (boxy ? 750 : 1500) );
-
- for (i = 0; i < l; i++)
- {
- do
- {
- j = random2(GXM - 20) + 10;
- k = random2(GYM - 20) + 10;
- }
- while (grd[j][k] == DNGN_ROCK_WALL
- && grd[j - 1][k] == DNGN_ROCK_WALL
- && grd[j + 1][k] == DNGN_ROCK_WALL
- && grd[j][k - 1] == DNGN_ROCK_WALL
- && grd[j][k + 1] == DNGN_ROCK_WALL
- && grd[j - 2][k] == DNGN_ROCK_WALL
- && grd[j + 2][k] == DNGN_ROCK_WALL
- && grd[j][k - 2] == DNGN_ROCK_WALL
- && grd[j][k + 2] == DNGN_ROCK_WALL);
-
- if (grd[j][k] == DNGN_ROCK_WALL)
- grd[j][k] = DNGN_FLOOR;
- if (grd[j][k - 1] == DNGN_ROCK_WALL)
- grd[j][k - 1] = DNGN_FLOOR;
- if (grd[j][k + 1] == DNGN_ROCK_WALL)
- grd[j][k + 1] = DNGN_FLOOR;
- if (grd[j - 1][k] == DNGN_ROCK_WALL)
- grd[j - 1][k] = DNGN_FLOOR;
- if (grd[j + 1][k] == DNGN_ROCK_WALL)
- grd[j + 1][k] = DNGN_FLOOR;
-
- if (boxy)
- {
- if (grd[j - 1][k - 1] == DNGN_ROCK_WALL)
- grd[j - 1][k - 1] = DNGN_FLOOR;
- if (grd[j + 1][k + 1] == DNGN_ROCK_WALL)
- grd[j + 1][k + 1] = DNGN_FLOOR;
- if (grd[j - 1][k + 1] == DNGN_ROCK_WALL)
- grd[j - 1][k + 1] = DNGN_FLOOR;
- if (grd[j + 1][k - 1] == DNGN_ROCK_WALL)
- grd[j + 1][k - 1] = DNGN_FLOOR;
- }
- }
-} // end spotty_level()
-
-static void bigger_room(void)
-{
- unsigned char i, j;
-
- for (i = 10; i < (GXM - 10); i++)
- {
- for (j = 10; j < (GYM - 10); j++)
- {
- if (grd[i][j] == DNGN_ROCK_WALL)
- grd[i][j] = DNGN_FLOOR;
- }
- }
-
- many_pools(DNGN_DEEP_WATER);
-
- if (one_chance_in(3))
- {
- if (coinflip())
- build_river( DNGN_DEEP_WATER );
- else
- build_lake( DNGN_DEEP_WATER );
- }
-
- int pair_count = coinflip() ? 4 : 3;
-
- for (j = 0; j < pair_count; j++)
- {
- for (i = 0; i < 2; i++)
- {
- place_specific_stair( j + ((i==0) ? DNGN_STONE_STAIRS_DOWN_I
- : DNGN_STONE_STAIRS_UP_I) );
- }
- }
-} // end bigger_room()
-
-// various plan_xxx functions
-static void plan_main(int level_number, char force_plan)
-{
- // possible values for do_stairs:
- // 0 - stairs already done
- // 1 - stairs already done, do spotty
- // 2 - no stairs
- // 3 - no stairs, do spotty
- char do_stairs = 0;
- unsigned char special_grid = (one_chance_in(3) ? DNGN_METAL_WALL
- : DNGN_STONE_WALL);
- int i,j;
-
- if (!force_plan)
- force_plan = 1 + random2(12);
-
- do_stairs = ((force_plan == 1) ? plan_1() :
- (force_plan == 2) ? plan_2() :
- (force_plan == 3) ? plan_3() :
- (force_plan == 4) ? plan_4(0, 0, 0, 0, 99) :
- (force_plan == 5) ? (one_chance_in(9) ? plan_5()
- : plan_3()) :
- (force_plan == 6) ? plan_6(level_number)
- : plan_3());
-
- if (do_stairs == 3 || do_stairs == 1)
- spotty_level(true, 0, coinflip());
-
- if (do_stairs == 2 || do_stairs == 3)
- {
- int pair_count = coinflip()?4:3;
-
- for (j = 0; j < pair_count; j++)
- {
- for (i = 0; i < 2; i++)
- {
- place_specific_stair( j + ((i==0) ? DNGN_STONE_STAIRS_DOWN_I
- : DNGN_STONE_STAIRS_UP_I) );
- }
- }
- }
-
- if (one_chance_in(20))
- replace_area(0,0,GXM-1,GYM-1,DNGN_ROCK_WALL,special_grid);
-} // end plan_main()
-
-static char plan_1(void)
-{
- int temp_rand = 0; // probability determination {dlb}
-
- unsigned char width = (10 - random2(7)); // value range of [4,10] {dlb}
-
- replace_area(10, 10, (GXM - 10), (10 + width), DNGN_ROCK_WALL, DNGN_FLOOR);
- replace_area(10, (60 - width), (GXM - 10), (GYM - 10),
- DNGN_ROCK_WALL, DNGN_FLOOR);
- replace_area(10, 10, (10 + width), (GYM - 10), DNGN_ROCK_WALL, DNGN_FLOOR);
- replace_area((60 - width), 10, (GXM - 10), (GYM - 10),
- DNGN_ROCK_WALL, DNGN_FLOOR);
-
- // possible early returns {dlb}:
- temp_rand = random2(4);
-
- if (temp_rand > 2) // 25% chance {dlb}
- return 3;
- else if (temp_rand > 1) // 25% chance {dlb}
- return 2;
- else // 50% chance {dlb}
- {
- unsigned char width2 = (coinflip()? (1 + random2(5)) : 5);
-
- replace_area(10, (35 - width2), (GXM - 10), (35 + width2),
- DNGN_ROCK_WALL, DNGN_FLOOR);
- replace_area((40 - width2), 10, (40 + width2), (GYM - 10),
- DNGN_ROCK_WALL, DNGN_FLOOR);
- }
-
- // possible early returns {dlb}:
- temp_rand = random2(4);
-
- if (temp_rand > 2) // 25% chance {dlb}
- return 3;
- else if (temp_rand > 1) // 25% chance {dlb}
- return 2;
- else // 50% chance {dlb}
- {
- temp_rand = random2(15);
-
- if (temp_rand > 7) // 7 in 15 odds {dlb}
- {
- spec_room sr = { false, false, 0,0,0,0 };
- sr.x1 = 25;
- sr.y1 = 25;
- sr.x2 = (GXM - 25);
- sr.y2 = (GYM - 25);
-
- int oblique_max = 0;
- if (coinflip())
- oblique_max = 5 + random2(20);
-
- temp_rand = random2(7);
-
- unsigned char floor_type = ((temp_rand > 1) ? DNGN_FLOOR : // 5/7
- (temp_rand > 0) ? DNGN_DEEP_WATER// 1/7
- : DNGN_LAVA); // 1/7
- octa_room(sr, oblique_max, floor_type);
- }
- }
-
- // final return {dlb}:
- return (one_chance_in(5) ? 3 : 2);
-} // end plan_1()
-
-// just a cross:
-static char plan_2(void)
-{
- char width2 = (5 - random2(5)); // value range of [1,5] {dlb}
-
- replace_area(10, (35 - width2), (GXM - 10), (35 + width2),
- DNGN_ROCK_WALL, DNGN_FLOOR);
- replace_area((40 - width2), 10, (40 + width2), (GYM - 10),
- DNGN_ROCK_WALL, DNGN_FLOOR);
-
- return (one_chance_in(4) ? 2 : 3);
-} // end plan_2()
-
-static char plan_3(void)
-{
-
- /* Draws a room, then another and links them together, then another and etc
- Of course, this can easily end up looking just like a make_trail level.
- */
- int i;
- char cnx, cny;
- int roomsss = 30 + random2(90);
-
- bool exclusive = (one_chance_in(10) ? false : true);
- bool exclusive2 = coinflip();
-
- char romx1[30], romy1[30], romx2[30], romy2[30];
-
- int which_room = 0;
-
- for (i = 0; i < roomsss; i++)
- {
- romx1[which_room] = 10 + random2(50);
- romy1[which_room] = 10 + random2(40);
- romx2[which_room] = romx1[which_room] + 2 + random2(8);
- romy2[which_room] = romy1[which_room] + 2 + random2(8);
-
- if (exclusive)
- {
- for (cnx = romx1[which_room] - 1; cnx < romx2[which_room] + 1;
- cnx++)
- {
- for (cny = romy1[which_room] - 1; cny < romy2[which_room] + 1;
- cny++)
- {
- if (grd[cnx][cny] != DNGN_ROCK_WALL)
- goto continuing;
- }
- }
- }
-
- replace_area(romx1[which_room], romy1[which_room], romx2[which_room],
- romy2[which_room], DNGN_ROCK_WALL, DNGN_FLOOR);
-
- if (which_room > 0 && !exclusive2)
- {
- const int rx1 = romx1[which_room];
- const int rx2 = romx2[which_room];
- const int prev_rx1 = romx1[which_room - 1];
- const int prev_rx2 = romx2[which_room - 1];
-
- const int ry1 = romy1[which_room];
- const int ry2 = romy2[which_room];
- const int prev_ry1 = romy1[which_room - 1];
- const int prev_ry2 = romy2[which_room - 1];
-
- join_the_dots( rx1 + random2( rx2 - rx1 ),
- ry1 + random2( ry2 - ry1 ),
- prev_rx1 + random2( prev_rx2 - prev_rx1 ),
- prev_ry1 + random2( prev_ry2 - prev_ry1 ),
- 0, 0, 0, 0 );
- }
-
- which_room++;
-
- if (which_room >= 29)
- break;
-
- continuing:
- continue;
- }
-
- if (exclusive2)
- {
- for (i = 0; i < which_room; i++)
- {
- if (i > 0)
- {
- const int rx1 = romx1[i];
- const int rx2 = romx2[i];
- const int prev_rx1 = romx1[i - 1];
- const int prev_rx2 = romx2[i - 1];
-
- const int ry1 = romy1[i];
- const int ry2 = romy2[i];
- const int prev_ry1 = romy1[i - 1];
- const int prev_ry2 = romy2[i - 1];
-
- join_the_dots( rx1 + random2( rx2 - rx1 ),
- ry1 + random2( ry2 - ry1 ),
- prev_rx1 + random2( prev_rx2 - prev_rx1 ),
- prev_ry1 + random2( prev_ry2 - prev_ry1 ),
- 0, 0, 0, 0 );
- }
- }
- }
-
- return 2;
-} // end plan_3()
-
-static char plan_4(char forbid_x1, char forbid_y1, char forbid_x2,
- char forbid_y2, unsigned char force_wall)
-{
- // a more chaotic version of city level
- int temp_rand; // req'd for probability checking
-
- int number_boxes = 5000;
- unsigned char drawing = DNGN_ROCK_WALL;
- char b1x, b1y, b2x, b2y;
- char cnx, cny;
- int i;
-
- temp_rand = random2(81);
-
- number_boxes = ((temp_rand > 48) ? 4000 : // odds: 32 in 81 {dlb}
- (temp_rand > 24) ? 3000 : // odds: 24 in 81 {dlb}
- (temp_rand > 8) ? 5000 : // odds: 16 in 81 {dlb}
- (temp_rand > 0) ? 2000 // odds: 8 in 81 {dlb}
- : 1000); // odds: 1 in 81 {dlb}
-
- if (force_wall != 99)
- drawing = force_wall;
- else
- {
- temp_rand = random2(18);
-
- drawing = ((temp_rand > 7) ? DNGN_ROCK_WALL : // odds: 10 in 18 {dlb}
- (temp_rand > 2) ? DNGN_STONE_WALL // odds: 5 in 18 {dlb}
- : DNGN_METAL_WALL); // odds: 3 in 18 {dlb}
- }
-
- replace_area(10, 10, (GXM - 10), (GYM - 10), DNGN_ROCK_WALL, DNGN_FLOOR);
-
- // replace_area can also be used to fill in:
- for (i = 0; i < number_boxes; i++)
- {
-
- b1x = 11 + random2(45);
- b1y = 11 + random2(35);
-
- b2x = b1x + 3 + random2(7) + random2(5);
- b2y = b1y + 3 + random2(7) + random2(5);
-
- if (forbid_x1 != 0 || forbid_x2 != 0)
- {
- if (b1x <= forbid_x2 && b1x >= forbid_x1
- && b1y <= forbid_y2 && b1y >= forbid_y1)
- {
- goto continuing;
- }
- else if (b2x <= forbid_x2 && b2x >= forbid_x1
- && b2y <= forbid_y2 && b2y >= forbid_y1)
- {
- goto continuing;
- }
- }
-
- for (cnx = b1x - 1; cnx < b2x + 1; cnx++)
- {
- for (cny = b1y - 1; cny < b2y + 1; cny++)
- {
- if (grd[cnx][cny] != DNGN_FLOOR)
- goto continuing;
- }
- }
-
- if (force_wall == 99)
- {
- // NB: comparison reversal here - combined
- temp_rand = random2(1200);
-
- // probabilities *not meant* to sum to one! {dlb}
- if (temp_rand < 417) // odds: 261 in 1200 {dlb}
- drawing = DNGN_ROCK_WALL;
- else if (temp_rand < 156) // odds: 116 in 1200 {dlb}
- drawing = DNGN_STONE_WALL;
- else if (temp_rand < 40) // odds: 40 in 1200 {dlb}
- drawing = DNGN_METAL_WALL;
- }
-
- temp_rand = random2(210);
-
- if (temp_rand > 71) // odds: 138 in 210 {dlb}
- replace_area(b1x, b1y, b2x, b2y, DNGN_FLOOR, drawing);
- else // odds: 72 in 210 {dlb}
- box_room(b1x, b2x - 1, b1y, b2y - 1, drawing);
-
- continuing:
- continue;
- }
-
- if (forbid_x1 == 0 && one_chance_in(4)) // a market square
- {
- spec_room sr = { false, false, 0, 0, 0, 0 };
- sr.x1 = 25;
- sr.y1 = 25;
- sr.x2 = 55;
- sr.y2 = 45;
-
- int oblique_max = 0;
- if (!one_chance_in(4))
- oblique_max = 5 + random2(20); // used elsewhere {dlb}
-
- unsigned char feature = DNGN_FLOOR;
- if (one_chance_in(10))
- feature = coinflip()? DNGN_DEEP_WATER : DNGN_LAVA;
-
- octa_room(sr, oblique_max, feature);
- }
-
- return 2;
-} // end plan_4()
-
-static char plan_5(void)
-{
- unsigned char imax = 5 + random2(20); // value range of [5,24] {dlb}
-
- for (unsigned char i = 0; i < imax; i++)
- {
- join_the_dots( random2(GXM - 20) + 10, random2(GYM - 20) + 10,
- random2(GXM - 20) + 10, random2(GYM - 20) + 10,
- 0, 0, 0, 0 );
- }
-
- if (!one_chance_in(4))
- spotty_level(true, 100, coinflip());
-
- return 2;
-} // end plan_5()
-
-static char plan_6(int level_number)
-{
- spec_room sr = { false, false, 0,0,0,0 };
-
- // circle of standing stones (well, kind of)
- sr.x1 = 10;
- sr.x2 = (GXM - 10);
- sr.y1 = 10;
- sr.y2 = (GYM - 10);
-
- octa_room(sr, 14, DNGN_FLOOR);
-
- replace_area(23, 23, 26, 26, DNGN_FLOOR, DNGN_STONE_WALL);
- replace_area(23, 47, 26, 50, DNGN_FLOOR, DNGN_STONE_WALL);
- replace_area(55, 23, 58, 26, DNGN_FLOOR, DNGN_STONE_WALL);
- replace_area(55, 47, 58, 50, DNGN_FLOOR, DNGN_STONE_WALL);
- replace_area(39, 20, 43, 23, DNGN_FLOOR, DNGN_STONE_WALL);
- replace_area(39, 50, 43, 53, DNGN_FLOOR, DNGN_STONE_WALL);
- replace_area(20, 30, 23, 33, DNGN_FLOOR, DNGN_STONE_WALL);
- replace_area(20, 40, 23, 43, DNGN_FLOOR, DNGN_STONE_WALL);
- replace_area(58, 30, 61, 33, DNGN_FLOOR, DNGN_STONE_WALL);
- replace_area(58, 40, 61, 43, DNGN_FLOOR, DNGN_STONE_WALL);
-
- grd[35][32] = DNGN_STONE_WALL;
- grd[46][32] = DNGN_STONE_WALL;
- grd[35][40] = DNGN_STONE_WALL;
- grd[46][40] = DNGN_STONE_WALL;
-
- grd[69][34] = DNGN_STONE_STAIRS_DOWN_I;
- grd[69][35] = DNGN_STONE_STAIRS_DOWN_II;
- grd[69][36] = DNGN_STONE_STAIRS_DOWN_III;
-
- grd[10][34] = DNGN_STONE_STAIRS_UP_I;
- grd[10][35] = DNGN_STONE_STAIRS_UP_II;
- grd[10][36] = DNGN_STONE_STAIRS_UP_III;
-
- // This "back door" is often one of the easier ways to get out of
- // pandemonium... the easiest is to use the banish spell.
- //
- // Note, that although "level_number > 20" will work for most
- // trips to pandemonium (through regular portals), it won't work
- // for demonspawn who gate themselves there. -- bwr
- if (((player_in_branch( BRANCH_MAIN_DUNGEON ) && level_number > 20)
- || you.level_type == LEVEL_PANDEMONIUM)
- && (coinflip() || you.mutation[ MUT_PANDEMONIUM ]))
- {
- grd[40][36] = DNGN_ENTER_ABYSS;
- grd[41][36] = DNGN_ENTER_ABYSS;
- }
-
- return 0;
-} // end plan_6()
-
-static bool octa_room(spec_room &sr, int oblique_max, unsigned char type_floor)
-{
- int x,y;
-
- // hack - avoid lava in the crypt {gdl}
- if ((player_in_branch( BRANCH_CRYPT ) || player_in_branch( BRANCH_TOMB ))
- && type_floor == DNGN_LAVA)
- {
- type_floor = DNGN_SHALLOW_WATER;
- }
-
- int oblique = oblique_max;
-
- // check octagonal room for special; avoid if exists
- for (x = sr.x1; x < sr.x2; x++)
- {
- for (y = sr.y1 + oblique; y < sr.y2 - oblique; y++)
- {
- if (grd[x][y] == DNGN_BUILDER_SPECIAL_WALL)
- return false;
- }
-
- if (oblique > 0)
- oblique--;
-
- if (x > sr.x2 - oblique_max)
- oblique += 2;
- }
-
- oblique = oblique_max;
-
-
- for (x = sr.x1; x < sr.x2; x++)
- {
- for (y = sr.y1 + oblique; y < sr.y2 - oblique; y++)
- {
- if (grd[x][y] == DNGN_ROCK_WALL)
- grd[x][y] = type_floor;
-
- if (grd[x][y] == DNGN_FLOOR && type_floor == DNGN_SHALLOW_WATER)
- grd[x][y] = DNGN_SHALLOW_WATER;
-
- if (grd[x][y] == DNGN_CLOSED_DOOR && type_floor >= MINMOVE)
- grd[x][y] = DNGN_FLOOR; // ick
- }
-
- if (oblique > 0)
- oblique--;
-
- if (x > sr.x2 - oblique_max)
- oblique += 2;
- }
-
- return true;
-} // end octa_room()
-
-static void labyrinth_level(int level_number)
-{
- int temp_rand; // probability determination {dlb}
-
- int keep_lx = 0, keep_ly = 0;
- int keep_lx2 = 0, keep_ly2 = 0;
- char start_point_x = 10;
- char start_point_y = 10;
- char going_x = 1;
- char going_y = (coinflip() ? 0 : 1);
- bool do_2 = false;
- int clear_space = 1;
- unsigned char traps_put2 = 0;
-
- if (coinflip())
- {
- start_point_x = (GXM - 10);
- going_x = -1;
- }
-
- if (coinflip())
- {
- start_point_y = (GYM - 10);
-
- if (going_y == 1)
- going_y = -1;
- }
-
- int lx = start_point_x;
- int ly = start_point_y;
-
- if (going_y)
- goto do_y;
-
- do_x:
- traps_put2 = 0;
- clear_space = 0; // ( coinflip()? 3 : 2 );
-
- do
- {
- lx += going_x;
-
- if (grd[lx][ly] == DNGN_ROCK_WALL)
- grd[lx][ly] = DNGN_FLOOR;
- }
- while (lx < (GXM - 8) && lx > 8
- && grd[lx + going_x * (2 + clear_space)][ly] == DNGN_ROCK_WALL);
-
- going_x = 0;
-
- if (ly < 32)
- going_y = 1;
- else if (ly > 37)
- going_y = -1;
- else
- goto finishing;
-
- do_y: // if (going_y != 0)
- if (do_2)
- {
- lx = keep_lx2;
- ly = keep_ly2;
- }
-
- // do_2 = false is the problem
- if (coinflip())
- {
- clear_space = 0;
- do_2 = false;
- }
- else
- {
- clear_space = 2;
- do_2 = true;
- }
-
- do
- {
- ly += going_y;
-
- if (grd[lx][ly] == DNGN_ROCK_WALL)
- grd[lx][ly] = DNGN_FLOOR;
- }
- while (ly < (GYM - 8) && ly > 8
- && grd[lx][ly + going_y * (2 + clear_space)] == DNGN_ROCK_WALL);
-
- keep_lx = lx;
- keep_ly = ly;
-
- if (lx < 37)
- going_x = 1;
- else if (lx > 42)
- going_x = -1;
-
- if (ly < 33)
- ly += 2;
- else if (ly > 37)
- ly -= 2;
-
- clear_space = ((!do_2) ? 6 : 2);
-
- do
- {
- lx += going_x;
-
- if (grd[lx][ly] == DNGN_ROCK_WALL)
- grd[lx][ly] = DNGN_FLOOR;
- }
- while (lx < (GXM - 8) && lx > 8
- && grd[lx + going_x * (2 + clear_space)][ly] == DNGN_ROCK_WALL);
-
- if (do_2)
- {
- keep_lx2 = lx;
- keep_ly2 = ly;
- }
-
- lx = keep_lx;
- ly = keep_ly;
-
- going_y = 0;
-
- if (lx < 37)
- going_x = 1;
- else if (lx > 42)
- going_x = -1;
- else
- goto finishing;
-
- goto do_x;
-
- finishing:
- start_point_x = 10 + random2(GXM - 20);
-
- int treasure_item = 0;
-
- unsigned char glopop = OBJ_RANDOM; // used in calling items() {dlb}
-
- int num_items = 8 + random2avg(9, 2);
- for (int i = 0; i < num_items; i++)
- {
- temp_rand = random2(11);
-
- glopop = ((temp_rand == 0 || temp_rand == 9) ? OBJ_WEAPONS :
- (temp_rand == 1 || temp_rand == 10) ? OBJ_ARMOUR :
- (temp_rand == 2) ? OBJ_MISSILES :
- (temp_rand == 3) ? OBJ_WANDS :
- (temp_rand == 4) ? OBJ_MISCELLANY :
- (temp_rand == 5) ? OBJ_SCROLLS :
- (temp_rand == 6) ? OBJ_JEWELLERY :
- (temp_rand == 7) ? OBJ_BOOKS
- /* (temp_rand == 8) */ : OBJ_STAVES);
-
- treasure_item = items( 1, glopop, OBJ_RANDOM, true,
- level_number * 3, 250 );
-
- if (treasure_item != NON_ITEM)
- {
- mitm[treasure_item].x = lx;
- mitm[treasure_item].y = ly;
- }
- }
-
- mons_place( MONS_MINOTAUR, BEH_SLEEP, MHITNOT, true, lx, ly );
-
- grd[lx][ly] = DNGN_ROCK_STAIRS_UP;
-
- link_items();
-
- // turn rock walls into undiggable stone or metal:
- temp_rand = random2(50);
-
- unsigned char wall_xform = ((temp_rand > 10) ? DNGN_STONE_WALL // 78.0%
- : DNGN_METAL_WALL); // 22.0%
-
- replace_area(0,0,GXM-1,GYM-1,DNGN_ROCK_WALL,wall_xform);
-
-} // end labyrinth_level()
-
-static bool is_wall(int x, int y)
-{
- unsigned char feat = grd[x][y];
-
- switch (feat)
- {
- case DNGN_ROCK_WALL:
- case DNGN_STONE_WALL:
- case DNGN_METAL_WALL:
- case DNGN_GREEN_CRYSTAL_WALL:
- case DNGN_WAX_WALL:
- return true;
- default:
- return false;
- }
-}
-
-
-static int box_room_door_spot(int x, int y)
-{
- // if there is a door near us embedded in rock, we have to be a door too.
- if ((grd[x-1][y] == DNGN_CLOSED_DOOR && is_wall(x-1,y-1) && is_wall(x-1,y+1))
- || (grd[x+1][y] == DNGN_CLOSED_DOOR && is_wall(x+1,y-1) && is_wall(x+1,y+1))
- || (grd[x][y-1] == DNGN_CLOSED_DOOR && is_wall(x-1,y-1) && is_wall(x+1,y-1))
- || (grd[x][y+1] == DNGN_CLOSED_DOOR && is_wall(x-1,y+1) && is_wall(x+1,y+1)))
- {
- grd[x][y] = DNGN_CLOSED_DOOR;
- return 2;
- }
-
- // to be a good spot for a door, we need non-wall on two sides and
- // wall on two sides.
- bool nor = is_wall(x, y-1);
- bool sou = is_wall(x, y+1);
- bool eas = is_wall(x-1, y);
- bool wes = is_wall(x+1, y);
-
- if (nor == sou && eas == wes && nor != eas)
- return 1;
-
- return 0;
-}
-
-static int box_room_doors( int bx1, int bx2, int by1, int by2, int new_doors)
-{
- int good_doors[200]; // 1 == good spot, 2 == door placed!
- int spot;
- int i,j;
- int doors_placed = new_doors;
-
- // sanity
- if ( 2 * ( (bx2 - bx1) + (by2-by1) ) > 200)
- return 0;
-
- // go through, building list of good door spots, and replacing wall
- // with door if we're about to block off another door.
- int spot_count = 0;
-
- // top & bottom
- for(i=bx1+1; i<bx2; i++)
- {
- good_doors[spot_count ++] = box_room_door_spot(i, by1);
- good_doors[spot_count ++] = box_room_door_spot(i, by2);
- }
- // left & right
- for(i=by1+1; i<by2; i++)
- {
- good_doors[spot_count ++] = box_room_door_spot(bx1, i);
- good_doors[spot_count ++] = box_room_door_spot(bx2, i);
- }
-
- if (new_doors == 0)
- {
- // count # of doors we HAD to place
- for(i=0; i<spot_count; i++)
- if (good_doors[i] == 2)
- doors_placed++;
-
- return doors_placed;
- }
-
- // Avoid an infinite loop if there are not enough good spots. --KON
- j = 0;
- for (i=0; i<spot_count; i++)
- if (good_doors[i] == 1)
- j++;
- if (new_doors > j)
- new_doors = j;
-
- while(new_doors > 0 && spot_count > 0)
- {
- spot = random2(spot_count);
- if (good_doors[spot] != 1)
- continue;
-
- j = 0;
- for(i=bx1+1; i<bx2; i++)
- {
- if (spot == j++)
- {
- grd[i][by1] = DNGN_CLOSED_DOOR;
- break;
- }
- if (spot == j++)
- {
- grd[i][by2] = DNGN_CLOSED_DOOR;
- break;
- }
- }
-
- for(i=by1+1; i<by2; i++)
- {
- if (spot == j++)
- {
- grd[bx1][i] = DNGN_CLOSED_DOOR;
- break;
- }
- if (spot == j++)
- {
- grd[bx2][i] = DNGN_CLOSED_DOOR;
- break;
- }
- }
-
- // try not to put a door in the same place twice
- good_doors[spot] = 2;
- new_doors --;
- }
-
- return doors_placed;
-}
-
-
-static void box_room(int bx1, int bx2, int by1, int by2, int wall_type)
-{
- // hack -- avoid lava in the crypt. {gdl}
- if ((player_in_branch( BRANCH_CRYPT ) || player_in_branch( BRANCH_TOMB ))
- && wall_type == DNGN_LAVA)
- {
- wall_type = DNGN_SHALLOW_WATER;
- }
-
- int temp_rand, new_doors, doors_placed;
-
- // do top & bottom walls
- replace_area(bx1,by1,bx2,by1,DNGN_FLOOR,wall_type);
- replace_area(bx1,by2,bx2,by2,DNGN_FLOOR,wall_type);
-
- // do left & right walls
- replace_area(bx1,by1+1,bx1,by2-1,DNGN_FLOOR,wall_type);
- replace_area(bx2,by1+1,bx2,by2-1,DNGN_FLOOR,wall_type);
-
- // sometimes we have to place doors, or else we shut in other buildings' doors
- doors_placed = box_room_doors(bx1, bx2, by1, by2, 0);
-
- temp_rand = random2(100);
- new_doors = (temp_rand > 45) ? 2 :
- ((temp_rand > 22) ? 1 : 3);
-
- // small rooms don't have as many doors
- if ((bx2-bx1)*(by2-by1) < 36)
- new_doors--;
-
- new_doors -= doors_placed;
- if (new_doors > 0)
- box_room_doors(bx1, bx2, by1, by2, new_doors);
-}
-
-static void city_level(int level_number)
-{
- int temp_rand; // probability determination {dlb}
- int wall_type; // remember, can have many wall types in one level
- int wall_type_room; // simplifies logic of innermost loop {dlb}
-
- int xs = 0, ys = 0;
- int x1 = 0, x2 = 0;
- int y1 = 0, y2 = 0;
- int i,j;
-
- temp_rand = random2(8);
-
- wall_type = ((temp_rand > 4) ? DNGN_ROCK_WALL : // 37.5% {dlb}
- (temp_rand > 1) ? DNGN_STONE_WALL // 37.5% {dlb}
- : DNGN_METAL_WALL); // 25.0% {dlb}
-
- if (one_chance_in(100))
- wall_type = DNGN_GREEN_CRYSTAL_WALL;
-
- make_box( 7, 7, GXM-7, GYM-7, DNGN_FLOOR );
-
- for (i = 0; i < 5; i++)
- {
- for (j = 0; j < 4; j++)
- {
- xs = 8 + (i * 13);
- ys = 8 + (j * 14);
- x1 = xs + random2avg(5, 2);
- y1 = ys + random2avg(5, 2);
- x2 = xs + 11 - random2avg(5, 2);
- y2 = ys + 11 - random2avg(5, 2);
-
- temp_rand = random2(280);
-
- if (temp_rand > 39) // 85.7% draw room(s) {dlb}
- {
- wall_type_room = ((temp_rand > 63) ? wall_type : // 77.1%
- (temp_rand > 54) ? DNGN_STONE_WALL : // 3.2%
- (temp_rand > 45) ? DNGN_ROCK_WALL // 3.2%
- : DNGN_METAL_WALL); // 2.1%
-
- if (one_chance_in(250))
- wall_type_room = DNGN_GREEN_CRYSTAL_WALL;
-
- box_room(x1, x2, y1, y2, wall_type_room);
-
- // inner room - neat.
- if (x2 - x1 > 5 && y2 - y1 > 5 && one_chance_in(8))
- {
- box_room(x1 + 2, x2 - 2, y1 + 2, y2 - 2, wall_type);
-
- // treasure area.. neat.
- if (one_chance_in(3))
- treasure_area(level_number, x1 + 3, x2 - 3, y1 + 3, y2 - 3);
- }
- }
- }
- }
-
- int stair_count = coinflip() ? 2 : 1;
-
- for (j = 0; j < stair_count; j++)
- {
- for (i = 0; i < 2; i++)
- {
- place_specific_stair( j + ((i==0) ? DNGN_STONE_STAIRS_DOWN_I
- : DNGN_STONE_STAIRS_UP_I) );
- }
- }
-
-} // end city_level()
-
-static bool treasure_area(int level_number, unsigned char ta1_x,
- unsigned char ta2_x, unsigned char ta1_y,
- unsigned char ta2_y)
-{
- int x_count = 0;
- int y_count = 0;
- int item_made = 0;
-
- ta2_x++;
- ta2_y++;
-
- if (ta2_x <= ta1_x || ta2_y <= ta1_y)
- return false;
-
- if ((ta2_x - ta1_x) * (ta2_y - ta1_y) >= 40)
- return false;
-
- for (x_count = ta1_x; x_count < ta2_x; x_count++)
- {
- for (y_count = ta1_y; y_count < ta2_y; y_count++)
- {
- if (grd[x_count][y_count] != DNGN_FLOOR || coinflip())
- continue;
-
- item_made = items( 1, OBJ_RANDOM, OBJ_RANDOM, true,
- random2( level_number * 2 ), 250 );
-
- if (item_made != NON_ITEM)
- {
- mitm[item_made].x = x_count;
- mitm[item_made].y = y_count;
- }
- }
- }
-
- return true;
-} // end treasure_area()
-
-static void diamond_rooms(int level_number)
-{
- char numb_diam = 1 + random2(10);
- char type_floor = DNGN_DEEP_WATER;
- int runthru = 0;
- int i, oblique_max;
-
- // I guess no diamond rooms in either of these places {dlb}:
- if (player_in_branch( BRANCH_DIS ) || player_in_branch( BRANCH_TARTARUS ))
- return;
-
- if (level_number > 5 + random2(5) && coinflip())
- type_floor = DNGN_SHALLOW_WATER;
-
- if (level_number > 10 + random2(5) && coinflip())
- type_floor = DNGN_DEEP_WATER;
-
- if (level_number > 17 && coinflip())
- type_floor = DNGN_LAVA;
-
- if (level_number > 10 && one_chance_in(15))
- type_floor = (coinflip()? DNGN_STONE_WALL : DNGN_ROCK_WALL);
-
- if (level_number > 12 && one_chance_in(20))
- type_floor = DNGN_METAL_WALL;
-
- if (player_in_branch( BRANCH_GEHENNA ))
- type_floor = DNGN_LAVA;
- else if (player_in_branch( BRANCH_COCYTUS ))
- type_floor = DNGN_DEEP_WATER;
-
- for (i = 0; i < numb_diam; i++)
- {
- spec_room sr = { false, false, 0, 0, 0, 0 };
-
- sr.x1 = 8 + random2(43);
- sr.y1 = 8 + random2(35);
- sr.x2 = sr.x1 + 5 + random2(15);
- sr.y2 = sr.y1 + 5 + random2(10);
-
- oblique_max = (sr.x2 - sr.x1) / 2; //random2(20) + 5;
-
- if (!octa_room(sr, oblique_max, type_floor))
- {
- runthru++;
- if (runthru > 9)
- {
- runthru = 0;
- }
- else
- {
- i--;
- continue;
- }
- }
- } // end "for(bk...)"
-} // end diamond_rooms()
-
-static void big_room(int level_number)
-{
- unsigned char type_floor = DNGN_FLOOR;
- unsigned char type_2 = DNGN_FLOOR;
- int i, j, k, l;
-
- spec_room sr = { false, false, 0, 0, 0, 0 };
- int oblique;
-
- if (one_chance_in(4))
- {
- oblique = 5 + random2(20);
-
- sr.x1 = 8 + random2(30);
- sr.y1 = 8 + random2(22);
- sr.x2 = sr.x1 + 20 + random2(10);
- sr.y2 = sr.y1 + 20 + random2(8);
-
- // usually floor, except at higher levels
- if (!one_chance_in(5) || level_number < 8 + random2(8))
- {
- octa_room(sr, oblique, DNGN_FLOOR);
- return;
- }
-
- // default is lava.
- type_floor = DNGN_LAVA;
-
- if (level_number > 7)
- {
- type_floor = ((random2(level_number) < 14) ? DNGN_DEEP_WATER
- : DNGN_LAVA);
- }
-
- octa_room(sr, oblique, type_floor);
- }
-
- // what now?
- sr.x1 = 8 + random2(30);
- sr.y1 = 8 + random2(22);
- sr.x2 = sr.x1 + 20 + random2(10);
- sr.y2 = sr.y1 + 20 + random2(8);
-
- // check for previous special
- if (find_in_area(sr.x1, sr.y1, sr.x2, sr.y2, DNGN_BUILDER_SPECIAL_WALL))
- return;
-
- if (level_number > 7 && one_chance_in(4))
- {
- type_floor = ((random2(level_number) < 14) ? DNGN_DEEP_WATER
- : DNGN_LAVA);
- }
-
- // make the big room.
- replace_area(sr.x1, sr.y1, sr.x2, sr.y2, DNGN_ROCK_WALL, type_floor);
- replace_area(sr.x1, sr.y1, sr.x2, sr.y2, DNGN_CLOSED_DOOR, type_floor);
-
- if (type_floor == DNGN_FLOOR)
- type_2 = DNGN_ROCK_WALL + random2(4);
-
- // no lava in the Crypt or Tomb, thanks!
- if (player_in_branch( BRANCH_CRYPT ) || player_in_branch( BRANCH_TOMB ))
- {
- if (type_floor == DNGN_LAVA)
- type_floor = DNGN_SHALLOW_WATER;
-
- if (type_2 == DNGN_LAVA)
- type_2 = DNGN_SHALLOW_WATER;
- }
-
- // sometimes make it a chequerboard
- if (one_chance_in(4))
- {
- chequerboard( sr, type_floor, type_floor, type_2 );
- }
- // sometimes make an inside room w/ stone wall.
- else if (one_chance_in(6))
- {
- i = sr.x1;
- j = sr.y1;
- k = sr.x2;
- l = sr.y2;
-
- do
- {
- i += 2 + random2(3);
- j += 2 + random2(3);
- k -= 2 + random2(3);
- l -= 2 + random2(3);
- // check for too small
- if (i >= k - 3)
- break;
- if (j >= l - 3)
- break;
-
- box_room(i, k, j, l, DNGN_STONE_WALL);
-
- }
- while (level_number < 1500); // ie forever
- }
-} // end big_room()
-
-// helper function for chequerboard rooms
-// note that box boundaries are INclusive
-static void chequerboard( spec_room &sr, unsigned char target,
- unsigned char floor1, unsigned char floor2 )
-{
- int i, j;
-
- if (sr.x2 < sr.x1 || sr.y2 < sr.y1)
- return;
-
- for (i = sr.x1; i <= sr.x2; i++)
- {
- for (j = sr.y1; j <= sr.y2; j++)
- {
- if (grd[i][j] == target)
- grd[i][j] = (((i + j) % 2) ? floor2 : floor1);
- }
- }
-} // end chequerboard()
-
-static void roguey_level(int level_number, spec_room &sr)
-{
- int bcount_x, bcount_y;
- int cn = 0;
- int i;
-
- FixedVector < unsigned char, 30 > rox1;
- FixedVector < unsigned char, 30 > rox2;
- FixedVector < unsigned char, 30 > roy1;
- FixedVector < unsigned char, 30 > roy2;
-
- for (bcount_y = 0; bcount_y < 5; bcount_y++)
- {
- for (bcount_x = 0; bcount_x < 5; bcount_x++)
- {
- // rooms:
- rox1[cn] = bcount_x * 13 + 8 + random2(4);
- roy1[cn] = bcount_y * 11 + 8 + random2(4);
-
- rox2[cn] = rox1[cn] + 3 + random2(8);
- roy2[cn] = roy1[cn] + 3 + random2(6);
-
- // bounds
- if (rox2[cn] > GXM-8)
- rox2[cn] = GXM-8;
-
- cn++;
- }
- }
-
- cn = 0;
-
- for (i = 0; i < 25; i++)
- {
- replace_area( rox1[i], roy1[i], rox2[i], roy2[i],
- DNGN_ROCK_WALL, DNGN_FLOOR );
-
- // inner room?
- if (rox2[i] - rox1[i] > 5 && roy2[i] - roy1[i] > 5)
- {
- if (random2(100 - level_number) < 3)
- {
- if (!one_chance_in(4))
- {
- box_room( rox1[i] + 2, rox2[i] - 2, roy1[i] + 2,
- roy2[i] - 2, (coinflip() ? DNGN_STONE_WALL
- : DNGN_ROCK_WALL) );
- }
- else
- {
- box_room( rox1[i] + 2, rox2[i] - 2, roy1[i] + 2,
- roy2[i] - 2, DNGN_METAL_WALL );
- }
-
- if (coinflip())
- {
- treasure_area( level_number, rox1[i] + 3, rox2[i] - 3,
- roy1[i] + 3, roy2[i] - 3 );
- }
- }
- }
- } // end "for i"
-
- // Now, join them together:
- FixedVector < char, 2 > pos;
- FixedVector < char, 2 > jpos;
-
- char doing = 0;
-
- char last_room = 0;
- int bp;
-
- for (bp = 0; bp < 2; bp++)
- {
- for (i = 0; i < 25; i++)
- {
- if (bp == 0 && (!(i % 5) || i == 0))
- continue;
-
- if (bp == 1 && i < 5)
- continue;
-
- switch (bp)
- {
- case 0:
- last_room = i - 1;
- pos[0] = rox1[i]; // - 1;
- pos[1] = roy1[i] + random2(roy2[i] - roy1[i]);
- jpos[0] = rox2[last_room]; // + 1;
- jpos[1] = roy1[last_room]
- + random2(roy2[last_room] - roy1[last_room]);
- break;
-
- case 1:
- last_room = i - 5;
- pos[1] = roy1[i]; // - 1;
- pos[0] = rox1[i] + random2(rox2[i] - rox1[i]);
- jpos[1] = roy2[last_room]; // + 1;
- jpos[0] = rox1[last_room]
- + random2(rox2[last_room] - rox1[last_room]);
- break;
- }
-
- while (pos[0] != jpos[0] || pos[1] != jpos[1])
- {
- doing = (coinflip()? 1 : 0);
-
- if (pos[doing] < jpos[doing])
- pos[doing]++;
- else if (pos[doing] > jpos[doing])
- pos[doing]--;
-
- if (grd[pos[0]][pos[1]] == DNGN_ROCK_WALL)
- grd[pos[0]][pos[1]] = DNGN_FLOOR;
- }
-
- if (grd[pos[0]][pos[1]] == DNGN_FLOOR)
- {
- if ((grd[pos[0] + 1][pos[1]] == DNGN_ROCK_WALL
- && grd[pos[0] - 1][pos[1]] == DNGN_ROCK_WALL)
- || (grd[pos[0]][pos[1] + 1] == DNGN_ROCK_WALL
- && grd[pos[0]][pos[1] - 1] == DNGN_ROCK_WALL))
- {
- grd[pos[0]][pos[1]] = 103;
- }
- }
- } // end "for bp, for i"
- }
-
- // is one of them a special room?
- if (level_number > 8 && one_chance_in(10))
- {
- int spec_room_done = random2(25);
-
- sr.created = true;
- sr.hooked_up = true;
- sr.x1 = rox1[spec_room_done];
- sr.x2 = rox2[spec_room_done];
- sr.y1 = roy1[spec_room_done];
- sr.y2 = roy2[spec_room_done];
- special_room( level_number, sr );
-
- // make the room 'special' so it doesn't get overwritten
- // by something else (or put monsters in walls, etc..).
-
- // top
- replace_area(sr.x1-1, sr.y1-1, sr.x2+1,sr.y1-1, DNGN_ROCK_WALL, DNGN_BUILDER_SPECIAL_WALL);
- replace_area(sr.x1-1, sr.y1-1, sr.x2+1,sr.y1-1, DNGN_FLOOR, DNGN_BUILDER_SPECIAL_FLOOR);
- replace_area(sr.x1-1, sr.y1-1, sr.x2+1,sr.y1-1, DNGN_CLOSED_DOOR, DNGN_BUILDER_SPECIAL_FLOOR);
-
- // bottom
- replace_area(sr.x1-1, sr.y2+1, sr.x2+1,sr.y2+1, DNGN_ROCK_WALL, DNGN_BUILDER_SPECIAL_WALL);
- replace_area(sr.x1-1, sr.y2+1, sr.x2+1,sr.y2+1, DNGN_FLOOR, DNGN_BUILDER_SPECIAL_FLOOR);
- replace_area(sr.x1-1, sr.y2+1, sr.x2+1,sr.y2+1, DNGN_CLOSED_DOOR, DNGN_BUILDER_SPECIAL_FLOOR);
-
- // left
- replace_area(sr.x1-1, sr.y1-1, sr.x1-1, sr.y2+1, DNGN_ROCK_WALL, DNGN_BUILDER_SPECIAL_WALL);
- replace_area(sr.x1-1, sr.y1-1, sr.x1-1, sr.y2+1, DNGN_FLOOR, DNGN_BUILDER_SPECIAL_FLOOR);
- replace_area(sr.x1-1, sr.y1-1, sr.x1-1, sr.y2+1, DNGN_CLOSED_DOOR, DNGN_BUILDER_SPECIAL_FLOOR);
-
- // right
- replace_area(sr.x2+1, sr.y1-1, sr.x2+1, sr.y2+1, DNGN_ROCK_WALL, DNGN_BUILDER_SPECIAL_WALL);
- replace_area(sr.x2+1, sr.y1-1, sr.x2+1, sr.y2+1, DNGN_FLOOR, DNGN_BUILDER_SPECIAL_FLOOR);
- replace_area(sr.x2+1, sr.y1-1, sr.x2+1, sr.y2+1, DNGN_CLOSED_DOOR, DNGN_BUILDER_SPECIAL_FLOOR);
- }
-
- int stair_count = coinflip() ? 2 : 1;
-
- for (int j = 0; j < stair_count; j++)
- {
- for (i = 0; i < 2; i++)
- {
- place_specific_stair(j + ((i==0) ? DNGN_STONE_STAIRS_DOWN_I
- : DNGN_STONE_STAIRS_UP_I));
- }
- }
-} // end roguey_level()
-
-static void morgue(spec_room &sr)
-{
- int temp_rand = 0; // probability determination {dlb}
- int x,y;
-
- for (x = sr.x1; x <= sr.x2; x++)
- {
- for (y = sr.y1; y <= sr.y2; y++)
- {
- if (grd[x][y] == DNGN_FLOOR || grd[x][y] == DNGN_BUILDER_SPECIAL_FLOOR)
- {
- int mon_type;
- temp_rand = random2(24);
-
- mon_type = ((temp_rand > 11) ? MONS_ZOMBIE_SMALL : // 50.0%
- (temp_rand > 7) ? MONS_WIGHT : // 16.7%
- (temp_rand > 3) ? MONS_NECROPHAGE : // 16.7%
- (temp_rand > 0) ? MONS_WRAITH // 12.5%
- : MONS_VAMPIRE); // 4.2%
-
- mons_place( mon_type, BEH_SLEEP, MHITNOT, true, x, y );
- }
- }
- }
-} // end morgue()
-
-static void jelly_pit(int level_number, spec_room &sr)
-{
- FixedVector< pit_mons_def, MAX_PIT_MONSTERS > pit_list;
- const int lordx = sr.x1 + random2(sr.x2 - sr.x1);
- const int lordy = sr.y1 + random2(sr.y2 - sr.y1);
-
- for (int i = 0; i < MAX_PIT_MONSTERS; i++)
- {
- pit_list[i].type = MONS_PROGRAM_BUG;
- pit_list[i].rare = 0;
- }
-
-#if DEBUG_DIAGNOSTICS
- mprf( MSGCH_DIAGNOSTICS, "Build: Jelly Pit" );
-#endif
- pit_list[0].type = MONS_OOZE;
- pit_list[0].rare = 27 - level_number / 5;
-
- pit_list[1].type = MONS_JELLY;
- pit_list[1].rare = 20;
-
- pit_list[2].type = MONS_BROWN_OOZE;
- pit_list[2].rare = 3 + level_number;
-
- pit_list[3].type = MONS_DEATH_OOZE;
- pit_list[3].rare = 2 + (2 * level_number) / 3;
-
- if (level_number >= 12)
- {
- pit_list[4].type = MONS_AZURE_JELLY;
- pit_list[4].rare = 1 + (level_number - 12) / 3;
- }
-
- if (level_number >= 15)
- {
- pit_list[5].type = MONS_ACID_BLOB;
- pit_list[5].rare = 1 + (level_number - 15) / 4;
- }
-
- fill_monster_pit( sr, pit_list, 90, MONS_PROGRAM_BUG, lordx, lordy );
-}
-
-static bool place_specific_trap(unsigned char spec_x, unsigned char spec_y,
- unsigned char spec_type)
-{
- if (spec_type == TRAP_RANDOM)
- spec_type = random2(NUM_TRAPS);
-
- for (int tcount = 0; tcount < MAX_TRAPS; tcount++)
- {
- if (env.trap[tcount].type == TRAP_UNASSIGNED)
- {
- env.trap[tcount].type = spec_type;
- env.trap[tcount].x = spec_x;
- env.trap[tcount].y = spec_y;
- grd[spec_x][spec_y] = DNGN_UNDISCOVERED_TRAP;
- return true;
- }
-
- if (tcount >= MAX_TRAPS - 1)
- return false;
- }
-
- return false;
-} // end place_specific_trap()
-
-void define_zombie( int mid, int ztype, int cs, int power )
-{
- int mons_sec2 = 0;
- int zombie_size = 0;
- bool ignore_rarity = false;
- int test, cls;
-
- if (power > 27)
- power = 27;
-
- // set size based on zombie class (cs)
- switch(cs)
- {
- case MONS_ZOMBIE_SMALL:
- case MONS_SIMULACRUM_SMALL:
- case MONS_SKELETON_SMALL:
- zombie_size = 1;
- break;
-
- case MONS_ZOMBIE_LARGE:
- case MONS_SIMULACRUM_LARGE:
- case MONS_SKELETON_LARGE:
- zombie_size = 2;
- break;
-
- case MONS_SPECTRAL_THING:
- zombie_size = -1;
- break;
-
- default:
- // this should NEVER happen.
- perror("\ncreate_zombie() got passed incorrect zombie type!\n");
- end(0);
- break;
- }
-
- // that is, random creature from which to fashion undead
- if (ztype == 250)
- {
- // how OOD this zombie can be.
- int relax = 5;
-
- // pick an appropriate creature to make a zombie out of,
- // levelwise. The old code was generating absolutely
- // incredible OOD zombies.
- while(true)
- {
- // this limit can be updated if mons->number goes >8 bits..
- test = random2(182); // not guaranteed to be valid, so..
- cls = mons_species(test);
- if (cls == MONS_PROGRAM_BUG)
- continue;
-
- // on certain branches, zombie creation will fail if we use
- // the mons_rarity() functions, because (for example) there
- // are NO zombifiable "native" abyss creatures. Other branches
- // where this is a problem are hell levels and the crypt.
- // we have to watch for summoned zombies on other levels, too,
- // such as the Temple, HoB, and Slime Pits.
- if (you.level_type != LEVEL_DUNGEON
- || player_in_hell()
- || player_in_branch( BRANCH_HALL_OF_ZOT )
- || player_in_branch( BRANCH_VESTIBULE_OF_HELL )
- || player_in_branch( BRANCH_ECUMENICAL_TEMPLE )
- || player_in_branch( BRANCH_CRYPT )
- || player_in_branch( BRANCH_TOMB )
- || player_in_branch( BRANCH_HALL_OF_BLADES )
- || player_in_branch( BRANCH_SNAKE_PIT )
- || player_in_branch( BRANCH_SLIME_PITS )
- || one_chance_in(1000))
- {
- ignore_rarity = true;
- }
-
- // don't make out-of-rarity zombies when we don't have to
- if (!ignore_rarity && mons_rarity(cls) == 0)
- continue;
-
- // monster class must be zombifiable
- if (!mons_zombie_size(cls))
- continue;
-
- // if skeleton, monster must have a skeleton
- if ((cs == MONS_SKELETON_SMALL || cs == MONS_SKELETON_LARGE)
- && !mons_skeleton(cls))
- {
- continue;
- }
-
- // size must match, but you can make a spectral thing out of anything.
- if (mons_zombie_size(cls) != zombie_size && zombie_size >= 0)
- continue;
-
- // hack -- non-dungeon zombies are always made out of nastier
- // monsters
- if (you.level_type != LEVEL_DUNGEON && mons_power(cls) > 8)
- break;
-
- // check for rarity.. and OOD - identical to mons_place()
- int level, diff, chance;
-
- level = mons_level( cls ) - 4;
- diff = level - power;
-
- chance = (ignore_rarity) ? 100
- : mons_rarity(cls) - (diff * diff) / 2;
-
- if (power > level - relax && power < level + relax
- && random2avg(100, 2) <= chance)
- {
- break;
- }
-
- // every so often, we'll relax the OOD restrictions. Avoids
- // infinite loops (if we don't do this, things like creating
- // a large skeleton on level 1 may hang the game!
- if (one_chance_in(5))
- relax++;
- }
-
- // set type and secondary appropriately
- menv[mid].number = cls;
- mons_sec2 = cls;
- }
- else
- {
- menv[mid].number = mons_species(ztype);
- mons_sec2 = menv[mid].number;
- }
-
- menv[mid].type = menv[mid].number;
-
- define_monster(mid);
-
- menv[mid].hit_points = hit_points( menv[mid].hit_dice, 6, 5 );
- menv[mid].max_hit_points = menv[mid].hit_points;
-
- menv[mid].armour_class -= 2;
-
- if (menv[mid].armour_class < 0)
- menv[mid].armour_class = 0;
-
- menv[mid].evasion -= 5;
-
- if (menv[mid].evasion < 0)
- menv[mid].evasion = 0;
-
- menv[mid].speed -= 2;
-
- if (menv[mid].speed < 3)
- menv[mid].speed = 3;
-
- menv[mid].speed_increment = 70;
- menv[mid].number = mons_sec2;
-
- if (cs == MONS_ZOMBIE_SMALL || cs == MONS_ZOMBIE_LARGE)
- {
- menv[mid].type = ((mons_zombie_size(menv[mid].number) == 2)
- ? MONS_ZOMBIE_LARGE : MONS_ZOMBIE_SMALL);
- }
- else if (cs == MONS_SKELETON_SMALL || cs == MONS_SKELETON_LARGE)
- {
- menv[mid].hit_points = hit_points( menv[mid].hit_dice, 5, 4 );
- menv[mid].max_hit_points = menv[mid].hit_points;
-
- menv[mid].armour_class -= 4;
-
- if (menv[mid].armour_class < 0)
- menv[mid].armour_class = 0;
-
- menv[mid].evasion -= 2;
-
- if (menv[mid].evasion < 0)
- menv[mid].evasion = 0;
-
- menv[mid].type = ((mons_zombie_size( menv[mid].number ) == 2)
- ? MONS_SKELETON_LARGE : MONS_SKELETON_SMALL);
- }
- else if (cs == MONS_SIMULACRUM_SMALL || cs == MONS_SIMULACRUM_LARGE)
- {
- // Simulacrum aren't tough, but you can create piles of them. -- bwr
- menv[mid].hit_points = hit_points( menv[mid].hit_dice, 1, 4 );
- menv[mid].max_hit_points = menv[mid].hit_points;
- menv[mid].type = ((mons_zombie_size( menv[mid].number ) == 2)
- ? MONS_SIMULACRUM_LARGE : MONS_SIMULACRUM_SMALL);
- }
- else if (cs == MONS_SPECTRAL_THING)
- {
- menv[mid].hit_points = hit_points( menv[mid].hit_dice, 4, 4 );
- menv[mid].max_hit_points = menv[mid].hit_points;
- menv[mid].armour_class += 4;
- menv[mid].type = MONS_SPECTRAL_THING;
- }
-
- menv[mid].number = mons_sec2;
-} // end define_zombie()
-
-#ifdef USE_RIVERS
-
-static void build_river( unsigned char river_type ) //mv
-{
- int i,j;
- int y, width;
-
- if (player_in_branch( BRANCH_CRYPT ) || player_in_branch( BRANCH_TOMB ))
- return;
-
- // if (one_chance_in(10))
- // build_river(river_type);
-
- // Made rivers less wide... min width five rivers were too annoying. -- bwr
- width = 3 + random2(4);
- y = 10 - width + random2avg( GYM-10, 3 );
-
- for (i = 5; i < (GXM - 5); i++)
- {
- if (one_chance_in(3)) y++;
- if (one_chance_in(3)) y--;
- if (coinflip()) width++;
- if (coinflip()) width--;
-
- if (width < 2) width = 2;
- if (width > 6) width = 6;
-
- for (j = y; j < y+width ; j++)
- {
- if (j >= 5 && j <= GYM - 5)
- {
- // Note that vaults might have been created in this area!
- // So we'll avoid the silliness of orcs/royal jelly on
- // lava and deep water grids. -- bwr
- if (!one_chance_in(200)
- // && grd[i][j] == DNGN_FLOOR
- && mgrd[i][j] == NON_MONSTER
- && igrd[i][j] == NON_ITEM)
- {
- if (width == 2 && river_type == DNGN_DEEP_WATER
- && coinflip())
- {
- grd[i][j] = DNGN_SHALLOW_WATER;
- }
- else
- grd[i][j] = river_type;
- }
- }
- }
- }
-} // end build_river()
-
-static void build_lake(unsigned char lake_type) //mv
-{
- int i, j;
- int x1, y1, x2, y2;
-
- if (player_in_branch( BRANCH_CRYPT ) || player_in_branch( BRANCH_TOMB ))
- return;
-
- // if (one_chance_in (10))
- // build_lake(lake_type);
-
- x1 = 5 + random2(GXM - 30);
- y1 = 5 + random2(GYM - 30);
- x2 = x1 + 4 + random2(16);
- y2 = y1 + 8 + random2(12);
- // mpr("lake");
-
- for (j = y1; j < y2; j++)
- {
- if (coinflip()) x1 += random2(3);
- if (coinflip()) x1 -= random2(3);
- if (coinflip()) x2 += random2(3);
- if (coinflip()) x2 -= random2(3);
-
- // mv: this does much more worse effects
- // if (coinflip()) x1 = x1 -2 + random2(5);
- // if (coinflip()) x2 = x2 -2 + random2(5);
-
- if ((j-y1) < ((y2-y1) / 2))
- {
- x2 += random2(3);
- x1 -= random2(3);
- }
- else
- {
- x2 -= random2(3);
- x1 += random2(3);
- }
-
- for (i = x1; i < x2 ; i++)
- {
- if ((j >= 5 && j <= GYM - 5) && (i >= 5 && i <= GXM - 5))
- {
- // Note that vaults might have been created in this area!
- // So we'll avoid the silliness of monsters and items
- // on lava and deep water grids. -- bwr
- if (!one_chance_in(200)
- // && grd[i][j] == DNGN_FLOOR
- && mgrd[i][j] == NON_MONSTER
- && igrd[i][j] == NON_ITEM)
- {
- grd[i][j] = lake_type;
- }
- }
- }
- }
-} // end lake()
-
-#endif // USE_RIVERS
diff --git a/stone_soup/crawl-ref/source/dungeon.h b/stone_soup/crawl-ref/source/dungeon.h
deleted file mode 100644
index 2da0e50a0c..0000000000
--- a/stone_soup/crawl-ref/source/dungeon.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * File: dungeon.cc
- * Summary: Functions used when building new levels.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef DUNGEON_H
-#define DUNGEON_H
-
-#include "FixVec.h"
-#include "externs.h"
-
-#define MAKE_GOOD_ITEM 351
-
-void item_colour( item_def &item );
-
-bool feat_blocks_movement(int feature);
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: files
- * *********************************************************************** */
-void builder(int level_number, char level_type);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: abyss - debug - dungeon - effects - religion - spells4
- * *********************************************************************** */
-int items( int allow_uniques, int force_class, int force_type,
- bool dont_place, int item_level, int item_race );
-
-// last updated 13mar2001 {gdl}
-/* ***********************************************************************
- * called from: dungeon monplace
- * *********************************************************************** */
-void give_item(int mid, int level_number);
-
-
-// last updated 13mar2001 {gdl}
-/* ***********************************************************************
- * called from: dungeon monplace
- * *********************************************************************** */
-void define_zombie(int mid, int ztype, int cs, int power);
-
-bool is_wall(int feature);
-
-#endif
diff --git a/stone_soup/crawl-ref/source/effects.cc b/stone_soup/crawl-ref/source/effects.cc
deleted file mode 100644
index d021041131..0000000000
--- a/stone_soup/crawl-ref/source/effects.cc
+++ /dev/null
@@ -1,1508 +0,0 @@
-/*
- * File: effects.cc
- * Summary: Misc stuff.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "effects.h"
-
-#include <string.h>
-#include <stdio.h>
-
-#include "externs.h"
-
-#include "beam.h"
-#include "direct.h"
-#include "dungeon.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "items.h"
-#include "misc.h"
-#include "monplace.h"
-#include "monstuff.h"
-#include "mon-util.h"
-#include "mutation.h"
-#include "newgame.h"
-#include "ouch.h"
-#include "player.h"
-#include "randart.h"
-#include "skills2.h"
-#include "spells3.h"
-#include "spells4.h"
-#include "spl-book.h"
-#include "spl-util.h"
-#include "stuff.h"
-#include "view.h"
-#include "wpn-misc.h"
-
-// torment_monsters is called with power 0 because torment is
-// UNRESISTABLE except for being undead or having torment
-// resistance! Even if we used maximum power of 1000, high
-// level monsters and characters would save too often. (GDL)
-
-static int torment_monsters(int x, int y, int pow, int garbage)
-{
- UNUSED( pow );
- UNUSED( garbage );
-
- // is player?
- if (x == you.x_pos && y == you.y_pos)
- {
- if (you.is_undead || you.mutation[MUT_TORMENT_RESISTANCE])
- mpr("You feel a surge of unholy energy.");
- else
- {
- mpr("Your body is wracked with pain!");
- dec_hp((you.hp / 2) - 1, false);
- }
-
- return 1;
- }
-
- // check for monster in cell
- int mon = mgrd[x][y];
-
- if (mon == NON_MONSTER)
- return 0;
-
- struct monsters *monster = &menv[mon];
-
- if (monster->type == -1)
- return 0;
-
- if (mons_res_negative_energy( monster ) >= 3)
- return 0;
-
- monster->hit_points = 1 + (monster->hit_points / 2);
- simple_monster_message(monster, " convulses!");
-
- return 1;
-}
-
-void torment(int tx, int ty)
-{
- apply_area_within_radius(torment_monsters, tx, ty, 0, 8, 0);
-} // end torment()
-
-void banished(unsigned char gate_type)
-{
- you_teleport2( false );
-
- // this is to ensure that you're standing on a suitable space (67)
- grd[you.x_pos][you.y_pos] = gate_type;
-
- down_stairs(true, you.your_level, true); // heh heh
- untag_followers(); // safety
-} // end banished()
-
-bool forget_spell(void)
-{
- if (!you.spell_no)
- return (false);
-
- // find a random spell to forget:
- int slot = -1;
- int num = 0;
-
- for (int i = 0; i < 25; i++)
- {
- if (you.spells[i] != SPELL_NO_SPELL)
- {
- num++;
- if (one_chance_in( num ))
- slot = i;
- }
- }
-
- if (slot == -1) // should never happen though
- return (false);
-
- del_spell_from_memory_by_slot( slot );
-
- return (true);
-} // end forget_spell()
-
-// use player::decrease_stats() instead iff:
-// (a) player_sust_abil() should not factor in; and
-// (b) there is no floor to the final stat values {dlb}
-bool lose_stat(unsigned char which_stat, unsigned char stat_loss, bool force)
-{
- bool statLowered = false; // must initialize to false {dlb}
- char *ptr_stat = 0; // NULL {dlb}
- char *ptr_redraw = 0; // NULL {dlb}
- char newValue = 0; // holds new value, for comparison to old {dlb}
-
- // begin outputing message: {dlb}
- strcpy(info, "You feel ");
-
- // set pointers to appropriate variables: {dlb}
- if (which_stat == STAT_RANDOM)
- which_stat = random2(NUM_STATS);
-
- switch (which_stat)
- {
- case STAT_STRENGTH:
- strcat(info, "weakened");
- ptr_stat = &you.strength;
- ptr_redraw = &you.redraw_strength;
- break;
-
- case STAT_DEXTERITY:
- strcat(info, "clumsy");
- ptr_stat = &you.dex;
- ptr_redraw = &you.redraw_dexterity;
- break;
-
- case STAT_INTELLIGENCE:
- strcat(info, "dopey");
- ptr_stat = &you.intel;
- ptr_redraw = &you.redraw_intelligence;
- break;
- }
-
- // scale modifier by player_sust_abil() - right-shift
- // permissible because stat_loss is unsigned: {dlb}
- if (!force)
- stat_loss >>= player_sust_abil();
-
- // newValue is current value less modifier: {dlb}
- newValue = *ptr_stat - stat_loss;
-
- // XXX: Death by stat loss is currently handled in the redraw code. -- bwr
- if (newValue < 0)
- newValue = 0;
-
- // conceivable that stat was already *at* three
- // or stat_loss zeroed by player_sust_abil(): {dlb}
- //
- // Actually, that code was somewhat flawed. Several race-class combos
- // can start with a stat lower than three, and this block (which
- // used to say '!=' would actually cause stat gain with the '< 3'
- // check that used to be above. Crawl has stat-death code and I
- // don't see why we shouldn't be using it here. -- bwr
- if (newValue < *ptr_stat)
- {
- *ptr_stat = newValue;
- *ptr_redraw = 1;
-
- // handle burden change, where appropriate: {dlb}
- if (ptr_stat == &you.strength)
- burden_change();
-
- statLowered = true; // that is, stat was lowered (not just changed)
- }
-
- // a warning to player that s/he cut it close: {dlb}
- if (!statLowered)
- strcat(info, " for a moment");
-
- // finish outputting message: {dlb}
- strcat(info, ".");
- mpr(info);
-
- return (statLowered);
-} // end lose_stat()
-
-void direct_effect(struct bolt &pbolt)
-{
- int damage_taken = 0;
-
- switch (pbolt.type)
- {
- case DMNBM_HELLFIRE:
- mpr( "You are engulfed in a burst of hellfire!" );
- strcpy( pbolt.beam_name, "hellfire" );
- pbolt.ex_size = 1;
- pbolt.flavour = BEAM_HELLFIRE;
- pbolt.is_explosion = true;
- pbolt.type = SYM_ZAP;
- pbolt.colour = RED;
- pbolt.thrower = KILL_MON_MISSILE;
- pbolt.aux_source = NULL;
- pbolt.is_beam = false;
- pbolt.is_tracer = false;
- pbolt.hit = 20;
- pbolt.damage = dice_def( 3, 20 );
- pbolt.aux_source = "burst of hellfire";
- explosion( pbolt );
- break;
-
- case DMNBM_SMITING:
- mpr( "Something smites you!" );
- strcpy( pbolt.beam_name, "smiting" ); // for ouch
- pbolt.aux_source = "by divine providence";
- damage_taken = 7 + random2avg(11, 2);
- break;
-
- case DMNBM_BRAIN_FEED:
- // lose_stat() must come last {dlb}
- if (one_chance_in(3) && lose_stat(STAT_INTELLIGENCE, 1))
- mpr("Something feeds on your intellect!");
- else
- mpr("Something tries to feed on your intellect!");
- break;
-
- case DMNBM_MUTATION:
- mpr("Strange energies course through your body.");
- if (one_chance_in(5))
- mutate(100);
- else
- give_bad_mutation();
- break;
- }
-
- // apply damage and handle death, where appropriate {dlb}
- if (damage_taken > 0)
- ouch(damage_taken, pbolt.beam_source, KILLED_BY_BEAM, pbolt.aux_source);
-
- return;
-} // end direct_effect()
-
-// monster-to-monster
-void mons_direct_effect(struct bolt &pbolt, int i)
-{
- // note the translation here - important {dlb}
- int o = menv[i].foe;
- struct monsters *monster = &menv[o];
- int damage_taken = 0;
-
- // annoy the target
- behaviour_event(monster, ME_ANNOY, i);
-
- switch (pbolt.type)
- {
- case DMNBM_HELLFIRE:
- simple_monster_message(monster, " is engulfed in hellfire.");
- strcpy(pbolt.beam_name, "hellfire");
- pbolt.flavour = BEAM_LAVA;
-
- damage_taken = 5 + random2(10) + random2(5);
- damage_taken = mons_adjust_flavoured(monster, pbolt, damage_taken);
- break;
-
- case DMNBM_SMITING:
- simple_monster_message(monster, " is smitten.");
- strcpy(pbolt.beam_name, "smiting");
- pbolt.flavour = BEAM_MISSILE;
-
- damage_taken += 7 + random2avg(11, 2);
- break;
-
- case DMNBM_BRAIN_FEED: // not implemented here (nor, probably, can be)
- break;
-
- case DMNBM_MUTATION:
- if (mons_holiness(monster) != MH_NATURAL)
- simple_monster_message(monster, " is unaffected.");
- else if (check_mons_resist_magic( monster, pbolt.ench_power ))
- simple_monster_message(monster, " resists.");
- else
- monster_polymorph(monster, RANDOM_MONSTER, 100);
- break;
- }
-
- // apply damage and handle death, where appropriate {dlb}
- if (damage_taken > 0)
- {
- hurt_monster(monster, damage_taken);
-
- if (monster->hit_points < 1)
- monster_die(monster, KILL_MON_MISSILE, i);
- }
-
- return;
-} // end mons_direct_effect()
-
-void random_uselessness(unsigned char ru, unsigned char sc_read_2)
-{
- char wc[30];
- int temp_rand = 0; // probability determination {dlb}
-
- switch (ru)
- {
- case 0:
- strcpy(info, "The dust glows a ");
- weird_colours(random2(256), wc);
- strcat(info, wc);
- strcat(info, " colour!");
- mpr(info);
- break;
-
- case 1:
- mpr("The scroll reassembles itself in your hand!");
- inc_inv_item_quantity( sc_read_2, 1 );
- break;
-
- case 2:
- if (you.equip[EQ_WEAPON] != -1)
- {
- char str_pass[ ITEMNAME_SIZE ];
- in_name(you.equip[EQ_WEAPON], DESC_CAP_YOUR, str_pass);
- strcpy(info, str_pass);
- strcat(info, " glows ");
- weird_colours(random2(256), wc);
- strcat(info, wc);
- strcat(info, " for a moment.");
- mpr(info);
- }
- else
- {
- canned_msg(MSG_NOTHING_HAPPENS);
- }
- break;
-
- case 3:
- strcpy(info, "You hear the distant roaring of an enraged ");
-
- temp_rand = random2(8);
-
- strcat(info, (temp_rand == 0) ? "frog" :
- (temp_rand == 1) ? "pill bug" :
- (temp_rand == 2) ? "millipede" :
- (temp_rand == 3) ? "eggplant" :
- (temp_rand == 4) ? "albino dragon" :
- (temp_rand == 5) ? "dragon" :
- (temp_rand == 6) ? "human"
- : "slug");
-
- strcat(info, "!");
- mpr(info);
- break;
-
- case 4:
- // josh declares mummies can't smell {dlb}
- if (you.species != SP_MUMMY)
- {
- strcpy(info, "You smell ");
-
- temp_rand = random2(8);
-
- strcat(info, (temp_rand == 0) ? "coffee." :
- (temp_rand == 1) ? "salt." :
- (temp_rand == 2) ? "burning hair!" :
- (temp_rand == 3) ? "baking bread." :
- (temp_rand == 4) ? "something weird." :
- (temp_rand == 5) ? "wet wool." :
- (temp_rand == 6) ? "sulphur."
- : "fire and brimstone!");
- mpr(info);
- }
- break;
-
- case 5:
- mpr("You experience a momentary feeling of inescapable doom!");
- break;
-
- case 6:
- strcpy(info, "Your ");
-
- temp_rand = random2(3);
-
- strcat(info, (temp_rand == 0) ? "ears itch." :
- (temp_rand == 1) ? "brain hurts!"
- : "nose twitches suddenly!");
- mpr(info);
- break;
-
- case 7:
- mpr("You hear the tinkle of a tiny bell.");
- cast_summon_butterflies( 100 );
- break;
-
- case 8:
- strcpy(info, "You hear ");
-
- temp_rand = random2(9);
-
- strcat(info, (temp_rand == 0) ? "snatches of song" :
- (temp_rand == 1) ? "a voice call someone else's name" :
- (temp_rand == 2) ? "a very strange noise" :
- (temp_rand == 3) ? "roaring flame" :
- (temp_rand == 4) ? "a very strange noise indeed" :
- (temp_rand == 5) ? "the chiming of a distant gong" :
- (temp_rand == 6) ? "the bellowing of a yak" :
- (temp_rand == 7) ? "a crunching sound"
- : "the tinkle of an enormous bell");
- strcat(info, ".");
- mpr(info);
- break;
- }
-
- return;
-} // end random_uselessness()
-
-bool acquirement(unsigned char force_class, int agent)
-{
- int thing_created = 0;
- int iteration = 0;
-
- // Remember lava!
- unsigned char class_wanted = OBJ_RANDOM;
- unsigned char type_wanted = OBJ_RANDOM;
-
- unsigned char unique = 1;
- unsigned char acqc = 0;
-
- const int max_has_value = 100;
- FixedVector< int, max_has_value > already_has;
-
- char best_spell = 99;
- char best_any = 99;
- unsigned char keyin;
-
- for (acqc = 0; acqc < max_has_value; acqc++)
- already_has[acqc] = 0;
-
- int spell_skills = 0;
- for (int i = SK_SPELLCASTING; i <= SK_POISON_MAGIC; i++)
- spell_skills += you.skills[i];
-
- if (force_class == OBJ_RANDOM)
- {
- mpr("This is a scroll of acquirement!");
-
- query:
- mpr( "[a|A] Weapon [b|B] Armour [c|C] Jewellery [d|D] Book" );
- mpr( "[e|E] Staff [f|F] Food [g|G] Miscellaneous [h|H] Gold" );
-
- //mpr("[r|R] - Just give me something good.");
- mpr("What kind of item would you like to acquire? ", MSGCH_PROMPT);
-
- keyin = tolower( get_ch() );
-
- if (keyin == 'a')
- class_wanted = OBJ_WEAPONS;
- else if (keyin == 'b')
- class_wanted = OBJ_ARMOUR;
- else if (keyin == 'c')
- class_wanted = OBJ_JEWELLERY;
- else if (keyin == 'd')
- class_wanted = OBJ_BOOKS;
- else if (keyin == 'e')
- class_wanted = OBJ_STAVES;
- else if (keyin == 'f')
- class_wanted = OBJ_FOOD;
- else if (keyin == 'g')
- class_wanted = OBJ_MISCELLANY;
- else if (keyin == 'h')
- class_wanted = OBJ_GOLD;
- }
- else
- class_wanted = force_class;
-
- for (acqc = 0; acqc < ENDOFPACK; acqc++)
- {
- if (is_valid_item( you.inv[acqc] )
- && you.inv[acqc].base_type == class_wanted)
- {
- ASSERT( you.inv[acqc].sub_type < max_has_value );
- already_has[you.inv[acqc].sub_type] += you.inv[acqc].quantity;
- }
- }
-
- if (class_wanted == OBJ_FOOD)
- {
- // food is a little less predicatable now -- bwr
-
- if (you.species == SP_GHOUL)
- {
- type_wanted = one_chance_in(10) ? FOOD_ROYAL_JELLY
- : FOOD_CHUNK;
- }
- else
- {
- // Meat is better than bread (except for herbivors), and
- // by choosing it as the default we don't have to worry
- // about special cases for carnivorous races (ie kobold)
- type_wanted = FOOD_MEAT_RATION;
-
- if (you.mutation[MUT_HERBIVOROUS])
- type_wanted = FOOD_BREAD_RATION;
-
- // If we have some regular rations, then we're probably be more
- // interested in faster foods (escpecially royal jelly)...
- // otherwise the regular rations should be a good enough offer.
- if (already_has[FOOD_MEAT_RATION]
- + already_has[FOOD_BREAD_RATION] >= 2 || coinflip())
- {
- type_wanted = one_chance_in(5) ? FOOD_HONEYCOMB
- : FOOD_ROYAL_JELLY;
- }
- }
-
- // quantity is handled by unique for food
- unique = 3 + random2(5);
-
- // giving more of the lower food value items
- if (type_wanted == FOOD_HONEYCOMB || type_wanted == FOOD_CHUNK)
- {
- unique += random2avg(10, 2);
- }
- }
- else if (class_wanted == OBJ_WEAPONS)
- {
- // Now asking for a weapon is biased towards your skills,
- // although launchers are right out for now. -- bwr
- int count = 0;
- int skill = SK_FIGHTING;
-
- // Can't do much with launchers, so we'll avoid them for now -- bwr
- for (int i = SK_SHORT_BLADES; i < SK_DARTS; i++)
- {
- if (i == SK_UNUSED_1)
- continue;
-
- // Adding a small constant allows for the occasional
- // weapon in an untrained skill. Since the game
- // doesn't allow for much in the way of good launchers,
- // we'll lower their weight.
-
- int weight = 0;
-
- weight = you.skills[i] + 3;
- if (weight)
- {
- count += weight;
-
- if (random2(count) < weight)
- skill = i;
- }
- }
-
- if (skill == SK_STAVES)
- type_wanted = WPN_QUARTERSTAFF; // only one in this class
- else
- {
- count = 0;
-
- // skipping clubs, knives, blowguns
- for (int i = WPN_MACE; i < NUM_WEAPONS; i++)
- {
- // skipping launchers
- if (i == WPN_SLING)
- i = WPN_GLAIVE;
-
- // skipping giant clubs
- if (i == WPN_GIANT_CLUB)
- i = WPN_EVENINGSTAR;
-
- // skipping knife and blowgun
- if (i == WPN_KNIFE)
- i = WPN_FALCHION;
-
- // blessed blades can only be created by the player, never found
- if (i == WPN_BLESSED_BLADE)
- continue;
-
- // "rare" weapons are only considered some of the time...
- // still, the chance is higher than actual random creation
- int wskill = range_skill(OBJ_WEAPONS, i);
- if (wskill == SK_RANGED_COMBAT)
- wskill = weapon_skill(OBJ_WEAPONS, i);
- if (wskill == skill
- && (i < WPN_EVENINGSTAR || i > WPN_BROAD_AXE
- || (i >= WPN_HAMMER && i <= WPN_SABRE)
- || one_chance_in(4)))
- {
- count++;
- if (one_chance_in( count ))
- type_wanted = i;
- }
- }
- }
- }
- else if (class_wanted == OBJ_MISSILES)
- {
- int count = 0;
- int skill = SK_RANGED_COMBAT;
-
- for (int i = SK_SLINGS; i <= SK_DARTS; i++)
- {
- if (you.skills[i])
- {
- count += you.skills[i];
- if (random2(count) < you.skills[i])
- skill = i;
- }
- }
-
- switch (skill)
- {
- case SK_SLINGS:
- type_wanted = MI_STONE;
- break;
-
- case SK_BOWS:
- type_wanted = MI_ARROW;
- break;
-
- case SK_CROSSBOWS:
- type_wanted = MI_DART;
- for (int i = 0; i < ENDOFPACK; i++)
- {
- // Assuming that crossbow in inventory means that they
- // want bolts for it (not darts for a hand crossbow)...
- // perhaps we should check for both and compare ammo
- // amounts on hand?
- if (is_valid_item( you.inv[i] )
- && you.inv[i].base_type == OBJ_WEAPONS
- && you.inv[i].sub_type == WPN_CROSSBOW)
- {
- type_wanted = MI_BOLT;
- break;
- }
- }
- break;
-
- case SK_DARTS:
- type_wanted = MI_DART;
- for (int i = 0; i < ENDOFPACK; i++)
- {
- if (is_valid_item( you.inv[i] )
- && you.inv[i].base_type == OBJ_WEAPONS
- && you.inv[i].sub_type == WPN_BLOWGUN)
- {
- // Assuming that blowgun in inventory means that they
- // may want needles for it (but darts might also be
- // wanted). Maybe expand this... see above comment.
- if (coinflip())
- type_wanted = MI_NEEDLE;
- break;
- }
- }
- break;
-
- default:
- type_wanted = MI_DART;
- break;
- }
- }
- else if (class_wanted == OBJ_ARMOUR)
- {
- // Increasing the representation of the non-body armour
- // slots here to make up for the fact that there's one
- // one type of item for most of them. -- bwr
- //
- // OBJ_RANDOM is body armour and handled below
- type_wanted = (coinflip()) ? OBJ_RANDOM : ARM_SHIELD + random2(5);
-
- // mutation specific problems (horns allow caps)
- if ((you.mutation[MUT_HOOVES] && type_wanted == ARM_BOOTS)
- || (you.mutation[MUT_CLAWS] >= 3 && type_wanted == ARM_GLOVES))
- {
- type_wanted = OBJ_RANDOM;
- }
-
- // some species specific fitting problems
- switch (you.species)
- {
- case SP_OGRE:
- case SP_OGRE_MAGE:
- case SP_TROLL:
- case SP_RED_DRACONIAN:
- case SP_WHITE_DRACONIAN:
- case SP_GREEN_DRACONIAN:
- case SP_GOLDEN_DRACONIAN:
- case SP_GREY_DRACONIAN:
- case SP_BLACK_DRACONIAN:
- case SP_PURPLE_DRACONIAN:
- case SP_MOTTLED_DRACONIAN:
- case SP_PALE_DRACONIAN:
- case SP_UNK0_DRACONIAN:
- case SP_UNK1_DRACONIAN:
- case SP_BASE_DRACONIAN:
- case SP_SPRIGGAN:
- if (type_wanted == ARM_GLOVES || type_wanted == ARM_BOOTS)
- {
- type_wanted = OBJ_RANDOM;
- }
- else if (type_wanted == ARM_SHIELD)
- {
- if (you.species == SP_SPRIGGAN)
- type_wanted = ARM_BUCKLER;
- else if (coinflip()) // giant races: 50/50 shield/large shield
- type_wanted = ARM_LARGE_SHIELD;
- }
- else if (type_wanted == OBJ_RANDOM)
- {
- type_wanted = ARM_ROBE; // no heavy armour, see below
- }
- break;
-
- case SP_KENKU:
- if (type_wanted == ARM_BOOTS)
- type_wanted = OBJ_RANDOM;
- break;
-
- default:
- break;
- }
-
- // Now we'll randomly pick a body armour (light only in the
- // case of ARM_ROBE). Unlike before, now we're only giving
- // out the finished products here, never the hides. -- bwr
- if (type_wanted == OBJ_RANDOM || type_wanted == ARM_ROBE)
- {
- // start with normal base armour
- if (type_wanted == ARM_ROBE)
- type_wanted = coinflip() ? ARM_ROBE : ARM_ANIMAL_SKIN;
- else
- {
- type_wanted = ARM_ROBE + random2(8);
-
- if (one_chance_in(10) && you.skills[SK_ARMOUR] >= 10)
- type_wanted = ARM_CRYSTAL_PLATE_MAIL;
-
- if (one_chance_in(10))
- type_wanted = ARM_ANIMAL_SKIN;
- }
-
- // everyone can wear things made from hides
- if (one_chance_in(20))
- {
- int rnd = random2(20);
-
- type_wanted = (rnd < 4) ? ARM_TROLL_LEATHER_ARMOUR : // 20%
- (rnd < 8) ? ARM_STEAM_DRAGON_ARMOUR : // 20%
- (rnd < 11) ? ARM_MOTTLED_DRAGON_ARMOUR : // 15%
- (rnd < 14) ? ARM_SWAMP_DRAGON_ARMOUR : // 15%
- (rnd < 16) ? ARM_DRAGON_ARMOUR : // 10%
- (rnd < 18) ? ARM_ICE_DRAGON_ARMOUR : // 10%
- (rnd < 19) ? ARM_STORM_DRAGON_ARMOUR // 5%
- : ARM_GOLD_DRAGON_ARMOUR; // 5%
- }
- }
- }
- else if (class_wanted != OBJ_GOLD)
- {
-
- do
- {
- unsigned char i;
-
- switch (class_wanted)
- {
- case OBJ_JEWELLERY:
- // Try for a base type the player hasn't identified
- for (i = 0; i < 10; i++)
- {
- type_wanted = random2(24);
-
- if (one_chance_in(3))
- type_wanted = AMU_RAGE + random2(10);
-
- if (get_ident_type(OBJ_JEWELLERY, type_wanted) == ID_UNKNOWN_TYPE)
- {
- break;
- }
- }
- break;
-
- case OBJ_BOOKS:
- // remember, put rarer books higher in the list
- iteration = 1;
- type_wanted = NUM_BOOKS;
-
- best_spell = best_skill( SK_SPELLCASTING, (NUM_SKILLS - 1),
- best_spell );
-
- which_book:
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE,
- "acquirement: iteration = %d, best_spell = %d",
- iteration, best_spell );
-
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif //jmf: debugging
-
- switch (best_spell)
- {
- default:
- case SK_SPELLCASTING:
- if (you.skills[SK_SPELLCASTING] <= 3
- && !you.had_book[BOOK_CANTRIPS])
- {
- // Handful of level one spells, very useful for the
- // new spellcaster who's asking for a book -- bwr
- type_wanted = BOOK_CANTRIPS;
- }
- else if (!you.had_book[BOOK_MINOR_MAGIC_I])
- type_wanted = BOOK_MINOR_MAGIC_I + random2(3);
- else if (!you.had_book[BOOK_WIZARDRY])
- type_wanted = BOOK_WIZARDRY;
- else if (!you.had_book[BOOK_CONTROL])
- type_wanted = BOOK_CONTROL;
- else if (!you.had_book[BOOK_POWER])
- type_wanted = BOOK_POWER;
- break;
-
- case SK_POISON_MAGIC:
- if (!you.had_book[BOOK_YOUNG_POISONERS])
- type_wanted = BOOK_YOUNG_POISONERS;
- else if (!you.had_book[BOOK_ENVENOMATIONS])
- type_wanted = BOOK_ENVENOMATIONS;
- break;
-
- case SK_EARTH_MAGIC:
- if (!you.had_book[BOOK_GEOMANCY])
- type_wanted = BOOK_GEOMANCY;
- else if (!you.had_book[BOOK_EARTH])
- type_wanted = BOOK_EARTH;
- break;
-
- case SK_AIR_MAGIC:
- // removed the book of clouds... all the other elements
- // (and most other spell skills) only get two.
- if (!you.had_book[BOOK_AIR])
- type_wanted = BOOK_AIR;
- else if (!you.had_book[BOOK_SKY])
- type_wanted = BOOK_SKY;
- break;
-
- case SK_ICE_MAGIC:
- if (!you.had_book[BOOK_FROST])
- type_wanted = BOOK_FROST;
- else if (!you.had_book[BOOK_ICE])
- type_wanted = BOOK_ICE;
- break;
-
- case SK_FIRE_MAGIC:
- if (!you.had_book[BOOK_FLAMES])
- type_wanted = BOOK_FLAMES;
- else if (!you.had_book[BOOK_FIRE])
- type_wanted = BOOK_FIRE;
- break;
-
- case SK_SUMMONINGS:
- if (!you.had_book[BOOK_CALLINGS])
- type_wanted = BOOK_CALLINGS;
- else if (!you.had_book[BOOK_SUMMONINGS])
- type_wanted = BOOK_SUMMONINGS;
-
- // now a Vehumet special -- bwr
- // else if (!you.had_book[BOOK_DEMONOLOGY])
- // type_wanted = BOOK_DEMONOLOGY;
- break;
-
- case SK_ENCHANTMENTS:
- best_any = best_skill(SK_FIGHTING, (NUM_SKILLS - 1), 99);
-
- // So many enchantment books! I really can't feel
- // guilty at all for dividing out the fighting
- // books and forcing the player to raise a fighting
- // skill (or enchantments in the case of Crusaders)
- // to get the remaining books... enchantments are
- // much too good (most spells, lots of books here,
- // id wand charges, gives magic resistance),
- // something will eventually have to be done. -- bwr
- if (best_any >= SK_FIGHTING
- && best_any <= SK_STAVES)
- {
- // Fighter mage's get the fighting enchantment books
- if (!you.had_book[BOOK_WAR_CHANTS])
- type_wanted = BOOK_WAR_CHANTS;
- else if (!you.had_book[BOOK_TUKIMA])
- type_wanted = BOOK_TUKIMA;
- }
- else if (!you.had_book[BOOK_CHARMS])
- type_wanted = BOOK_CHARMS;
- else if (!you.had_book[BOOK_HINDERANCE])
- type_wanted = BOOK_HINDERANCE;
- else if (!you.had_book[BOOK_ENCHANTMENTS])
- type_wanted = BOOK_ENCHANTMENTS;
- break;
-
- case SK_CONJURATIONS:
- if (!you.had_book[BOOK_CONJURATIONS_I])
- type_wanted = give_first_conjuration_book();
- else if (!you.had_book[BOOK_TEMPESTS])
- type_wanted = BOOK_TEMPESTS;
-
- // now a Vehumet special -- bwr
- // else if (!you.had_book[BOOK_ANNIHILATIONS])
- // type_wanted = BOOK_ANNIHILATIONS;
- break;
-
- case SK_NECROMANCY:
- if (!you.had_book[BOOK_NECROMANCY])
- type_wanted = BOOK_NECROMANCY;
- else if (!you.had_book[BOOK_DEATH])
- type_wanted = BOOK_DEATH;
- else if (!you.had_book[BOOK_UNLIFE])
- type_wanted = BOOK_UNLIFE;
-
- // now a Kikubaaqudgha special -- bwr
- // else if (!you.had_book[BOOK_NECRONOMICON])
- // type_wanted = BOOK_NECRONOMICON;
- break;
-
- case SK_TRANSLOCATIONS:
- if (!you.had_book[BOOK_SPATIAL_TRANSLOCATIONS])
- type_wanted = BOOK_SPATIAL_TRANSLOCATIONS;
- else if (!you.had_book[BOOK_WARP])
- type_wanted = BOOK_WARP;
- break;
-
- case SK_TRANSMIGRATION:
- if (!you.had_book[BOOK_CHANGES])
- type_wanted = BOOK_CHANGES;
- else if (!you.had_book[BOOK_TRANSFIGURATIONS])
- type_wanted = BOOK_TRANSFIGURATIONS;
- else if (!you.had_book[BOOK_MUTATIONS])
- type_wanted = BOOK_MUTATIONS;
- break;
-
- case SK_DIVINATIONS: //jmf: added 24mar2000
- if (!you.had_book[BOOK_SURVEYANCES])
- type_wanted = BOOK_SURVEYANCES;
- else if (!you.had_book[BOOK_DIVINATIONS])
- type_wanted = BOOK_DIVINATIONS;
- break;
- }
-/*
- if (type_wanted == 99 && glof == best_skill(SK_SPELLCASTING, (NUM_SKILLS - 1), 99))
-*/
- if (type_wanted == NUM_BOOKS && iteration == 1)
- {
- best_spell = best_skill( SK_SPELLCASTING, (NUM_SKILLS - 1),
- best_skill(SK_SPELLCASTING,
- (NUM_SKILLS - 1), 99) );
- iteration++;
- goto which_book;
- }
-
- // if we don't have a book, try and get a new one.
- if (type_wanted == NUM_BOOKS)
- {
- do
- {
- type_wanted = random2(NUM_BOOKS);
- if (one_chance_in(500))
- break;
- }
- while (you.had_book[type_wanted]);
- }
-
- // if the book is invalid find any valid one.
- while (book_rarity(type_wanted) == 100
- || type_wanted == BOOK_DESTRUCTION
- || type_wanted == BOOK_MANUAL)
- {
- type_wanted = random2(NUM_BOOKS);
- }
- break;
-
- case OBJ_STAVES:
- type_wanted = random2(13);
-
- if (type_wanted >= 10)
- type_wanted = STAFF_AIR + type_wanted - 10;
-
- // Elemental preferences -- bwr
- if (type_wanted == STAFF_FIRE || type_wanted == STAFF_COLD)
- {
- if (you.skills[SK_FIRE_MAGIC] > you.skills[SK_ICE_MAGIC])
- type_wanted = STAFF_FIRE;
- else if (you.skills[SK_FIRE_MAGIC] != you.skills[SK_ICE_MAGIC])
- type_wanted = STAFF_COLD;
- }
- else if (type_wanted == STAFF_AIR || type_wanted == STAFF_EARTH)
- {
- if (you.skills[SK_AIR_MAGIC] > you.skills[SK_EARTH_MAGIC])
- type_wanted = STAFF_AIR;
- else if (you.skills[SK_AIR_MAGIC] != you.skills[SK_EARTH_MAGIC])
- type_wanted = STAFF_EARTH;
- }
-
- best_spell = best_skill( SK_SPELLCASTING, (NUM_SKILLS-1), 99 );
-
- // If we're going to give out an enhancer stave,
- // we should at least bias things towards the
- // best spell skill. -- bwr
- switch (best_spell)
- {
- case SK_FIRE_MAGIC:
- if (!already_has[STAFF_FIRE])
- type_wanted = STAFF_FIRE;
- break;
-
- case SK_ICE_MAGIC:
- if (!already_has[STAFF_COLD])
- type_wanted = STAFF_COLD;
- break;
-
- case SK_AIR_MAGIC:
- if (!already_has[STAFF_AIR])
- type_wanted = STAFF_AIR;
- break;
-
- case SK_EARTH_MAGIC:
- if (!already_has[STAFF_EARTH])
- type_wanted = STAFF_EARTH;
- break;
-
- case SK_POISON_MAGIC:
- if (!already_has[STAFF_POISON])
- type_wanted = STAFF_POISON;
- break;
-
- case SK_NECROMANCY:
- if (!already_has[STAFF_DEATH])
- type_wanted = STAFF_DEATH;
- break;
-
- case SK_CONJURATIONS:
- if (!already_has[STAFF_CONJURATION])
- type_wanted = STAFF_CONJURATION;
- break;
-
- case SK_ENCHANTMENTS:
- if (!already_has[STAFF_ENCHANTMENT])
- type_wanted = STAFF_ENCHANTMENT;
- break;
-
- case SK_SUMMONINGS:
- if (!already_has[STAFF_SUMMONING])
- type_wanted = STAFF_SUMMONING;
- break;
-
- case SK_EVOCATIONS:
- if (!one_chance_in(4))
- type_wanted = STAFF_SMITING + random2(10);
- break;
-
- default: // invocations and leftover spell schools
- switch (random2(5))
- {
- case 0:
- type_wanted = STAFF_WIZARDRY;
- break;
-
- case 1:
- type_wanted = STAFF_POWER;
- break;
-
- case 2:
- type_wanted = STAFF_ENERGY;
- break;
-
- case 3:
- type_wanted = STAFF_CHANNELING;
- break;
-
- case 4:
- break;
- }
- break;
- }
-
- // Increased chance of getting spell staff for new or
- // non-spellcasters. -- bwr
- if (one_chance_in(20)
- || (spell_skills <= 1 // short on spells
- && (type_wanted < STAFF_SMITING // already making one
- || type_wanted >= STAFF_AIR)
- && !one_chance_in(4)))
- {
- type_wanted = (coinflip() ? STAFF_STRIKING
- : STAFF_SMITING + random2(10));
- }
- break;
-
- case OBJ_MISCELLANY:
- do
- type_wanted = random2(NUM_MISCELLANY);
- while (type_wanted == MISC_HORN_OF_GERYON
- || type_wanted == MISC_RUNE_OF_ZOT
- || type_wanted == MISC_PORTABLE_ALTAR_OF_NEMELEX
- || type_wanted == MISC_CRYSTAL_BALL_OF_FIXATION
- || type_wanted == MISC_EMPTY_EBONY_CASKET);
- break;
-
- default:
- mesclr();
- goto query;
- }
-
- ASSERT( type_wanted < max_has_value );
- }
- while (already_has[type_wanted] && !one_chance_in(200));
- }
-
- if (grid_destroys_items(grd[you.x_pos][you.y_pos]))
- {
- // how sad (and stupid)
- mprf(MSGCH_SOUND,
- grid_item_destruction_message(grd[you.x_pos][you.y_pos]));
- }
- else
- {
- // BCR - unique is now used for food quantity.
- thing_created = items( unique, class_wanted, type_wanted, true,
- MAKE_GOOD_ITEM, 250 );
-
- if (thing_created == NON_ITEM)
- {
- mpr("The demon of the infinite void smiles at you.");
- return (false);
- }
-
- // remove curse flag from item
- do_uncurse_item( mitm[thing_created] );
-
- if (mitm[thing_created].base_type == OBJ_BOOKS)
- {
- if (mitm[thing_created].base_type == BOOK_MINOR_MAGIC_I
- || mitm[thing_created].base_type == BOOK_MINOR_MAGIC_II
- || mitm[thing_created].base_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;
- }
- else if (mitm[thing_created].base_type == BOOK_CONJURATIONS_I
- || mitm[thing_created].base_type == BOOK_CONJURATIONS_II)
- {
- you.had_book[ BOOK_CONJURATIONS_I ] = 1;
- you.had_book[ BOOK_CONJURATIONS_II ] = 1;
- }
- else
- {
- you.had_book[ mitm[thing_created].sub_type ] = 1;
- }
- }
- else if (mitm[thing_created].base_type == OBJ_JEWELLERY)
- {
- switch (mitm[thing_created].sub_type)
- {
- case RING_SLAYING:
- // make sure plus to damage is >= 1
- mitm[thing_created].plus2 = abs( mitm[thing_created].plus2 );
- if (mitm[thing_created].plus2 == 0)
- mitm[thing_created].plus2 = 1;
- // fall through...
-
- case RING_PROTECTION:
- case RING_STRENGTH:
- case RING_INTELLIGENCE:
- case RING_DEXTERITY:
- case RING_EVASION:
- // make sure plus is >= 1
- mitm[thing_created].plus = abs( mitm[thing_created].plus );
- if (mitm[thing_created].plus == 0)
- mitm[thing_created].plus = 1;
- break;
-
- case RING_HUNGER:
- case AMU_INACCURACY:
- // these are the only truly bad pieces of jewellery
- if (!one_chance_in(9))
- make_item_randart( mitm[thing_created] );
- break;
-
- default:
- break;
- }
- }
- else if (mitm[thing_created].base_type == OBJ_WEAPONS
- && !is_fixed_artefact( mitm[thing_created] ))
- {
- // HACK: make unwieldable weapons wieldable
- // Note: messing with fixed artefacts is probably very bad.
- switch (you.species)
- {
- case SP_DEMONSPAWN:
- case SP_MUMMY:
- case SP_GHOUL:
- {
- int brand = get_weapon_brand( mitm[thing_created] );
- if (brand == SPWPN_HOLY_WRATH
- || brand == SPWPN_DISRUPTION)
- {
- if (!is_random_artefact( mitm[thing_created] ))
- {
- set_item_ego_type( mitm[thing_created],
- OBJ_WEAPONS, SPWPN_VORPAL );
- }
- else
- {
- // keep reseting seed until it's good:
- for (; brand == SPWPN_HOLY_WRATH
- || brand == SPWPN_DISRUPTION;
- brand = get_weapon_brand(mitm[thing_created]))
- {
- make_item_randart( mitm[thing_created] );
- }
- }
- }
- }
- break;
-
- case SP_HALFLING:
- case SP_GNOME:
- case SP_KOBOLD:
- case SP_SPRIGGAN:
- switch (mitm[thing_created].sub_type)
- {
- case WPN_LONGBOW:
- mitm[thing_created].sub_type = WPN_BOW;
- break;
-
- case WPN_GREAT_SWORD:
- case WPN_TRIPLE_SWORD:
- mitm[thing_created].sub_type =
- (coinflip() ? WPN_FALCHION : WPN_LONG_SWORD);
- break;
-
- case WPN_GREAT_MACE:
- case WPN_DIRE_FLAIL:
- mitm[thing_created].sub_type =
- (coinflip() ? WPN_MACE : WPN_FLAIL);
- break;
-
- case WPN_BATTLEAXE:
- case WPN_EXECUTIONERS_AXE:
- mitm[thing_created].sub_type =
- (coinflip() ? WPN_HAND_AXE : WPN_WAR_AXE);
- break;
-
- case WPN_HALBERD:
- case WPN_GLAIVE:
- case WPN_SCYTHE:
- case WPN_LOCHABER_AXE:
- mitm[thing_created].sub_type =
- (coinflip() ? WPN_SPEAR : WPN_TRIDENT);
- break;
- }
- break;
-
- default:
- break;
- }
- }
- else if (mitm[thing_created].base_type == OBJ_ARMOUR
- && !is_fixed_artefact( mitm[thing_created] ))
- {
- // HACK: make unwearable hats and boots wearable
- // Note: messing with fixed artefacts is probably very bad.
- switch (mitm[thing_created].sub_type)
- {
- case ARM_HELMET:
- if ((get_helmet_type(mitm[thing_created]) == THELM_HELM
- || get_helmet_type(mitm[thing_created]) == THELM_HELMET)
- && ((you.species >= SP_OGRE && you.species <= SP_OGRE_MAGE)
- || player_genus(GENPC_DRACONIAN)
- || you.species == SP_MINOTAUR
- || you.species == SP_KENKU
- || you.species == SP_SPRIGGAN
- || you.mutation[MUT_HORNS]))
- {
- // turn it into a cap or wizard hat
- set_helmet_type( mitm[thing_created],
- coinflip() ? THELM_CAP : THELM_WIZARD_HAT );
-
- mitm[thing_created].colour = random_colour();
- }
- break;
-
- case ARM_BOOTS:
- if (you.species == SP_NAGA)
- mitm[thing_created].sub_type = ARM_NAGA_BARDING;
- else if (you.species == SP_CENTAUR)
- mitm[thing_created].sub_type = ARM_CENTAUR_BARDING;
-
- // fix illegal barding ego types caused by above hack
- if (mitm[thing_created].sub_type != ARM_BOOTS
- && get_armour_ego_type( mitm[thing_created] )
- == SPARM_RUNNING)
- {
- set_item_ego_type(
- mitm[thing_created], OBJ_ARMOUR, SPARM_NORMAL );
- }
- break;
-
- default:
- break;
- }
- }
-
- move_item_to_grid( &thing_created, you.x_pos, you.y_pos );
-
- // This should never actually be NON_ITEM because of the way
- // move_item_to_grid works (doesn't create a new item ever),
- // but we're checking it anyways. -- bwr
- if (thing_created != NON_ITEM)
- {
- canned_msg(MSG_SOMETHING_APPEARS);
- origin_acquired(mitm[thing_created], agent);
- }
- }
-
- // Well, the item may have fallen in the drink, but the intent is
- // that acquirement happened. -- bwr
- return (true);
-} // end acquirement()
-
-bool recharge_wand(void)
-{
- if (you.equip[EQ_WEAPON] == -1)
- return (false);
-
- item_def &wand = you.inv[ you.equip[EQ_WEAPON] ];
-
- if (wand.base_type != OBJ_WANDS && !item_is_rod(wand))
- return (false);
-
- int charge_gain = 0;
- if (wand.base_type == OBJ_WANDS)
- {
- switch (wand.sub_type)
- {
- case WAND_INVISIBILITY:
- case WAND_FIREBALL:
- case WAND_HEALING:
- charge_gain = 3;
- break;
-
- case WAND_LIGHTNING:
- case WAND_DRAINING:
- charge_gain = 4;
- break;
-
- case WAND_FIRE:
- case WAND_COLD:
- charge_gain = 5;
- break;
-
- default:
- charge_gain = 8;
- break;
- }
-
- char str_pass[ ITEMNAME_SIZE ];
- item_name(wand, DESC_CAP_YOUR, str_pass);
- mprf("%s glows for a moment.", str_pass);
-
- wand.plus += 1 + random2avg( ((charge_gain - 1) * 3) + 1, 3 );
-
- if (wand.plus > charge_gain * 3)
- wand.plus = charge_gain * 3;
- }
- else
- {
- // This is a rod.
- bool work = false;
-
- if (wand.plus2 <= MAX_ROD_CHARGE * ROD_CHARGE_MULT)
- {
- wand.plus2 += ROD_CHARGE_MULT;
-
- if (wand.plus2 > MAX_ROD_CHARGE * ROD_CHARGE_MULT)
- wand.plus2 = MAX_ROD_CHARGE * ROD_CHARGE_MULT;
-
- work = true;
- }
-
- if (wand.plus < wand.plus2)
- {
- wand.plus = wand.plus2;
- work = true;
- }
-
- if (!work)
- return (false);
-
- char str_pass[ITEMNAME_SIZE];
- item_name( wand, DESC_CAP_YOUR, str_pass );
- mprf("%s glows for a moment.", str_pass);
- }
-
- you.wield_change = true;
- return (true);
-} // end recharge_wand()
-
-void yell(void)
-{
- bool targ_prev = false;
- int mons_targd = MHITNOT;
- struct dist targ;
-
- if (silenced(you.x_pos, you.y_pos))
- {
- mpr("You are unable to make a sound!");
- return;
- }
-
- mpr("What do you say?", MSGCH_PROMPT);
- mpr(" ! - Yell");
- mpr(" a - Order allies to attack a monster");
-
- if (!(you.prev_targ == MHITNOT || you.prev_targ == MHITYOU))
- {
- struct monsters *target = &menv[you.prev_targ];
-
- if (mons_near(target) && player_monster_visible(target))
- {
- mpr(" p - Order allies to attack your previous target");
- targ_prev = true;
- }
- }
-
- strcpy(info, " Anything else - Stay silent");
-
- if (one_chance_in(20))
- strcat(info, " (and be thought a fool)");
-
- mpr(info);
-
- unsigned char keyn = get_ch();
-
- switch (keyn)
- {
- case '!':
- mpr("You yell for attention!", MSGCH_SOUND);
- you.turn_is_over = 1;
- noisy( 12, you.x_pos, you.y_pos );
- return;
-
- case 'a':
- mpr("Gang up on whom?", MSGCH_PROMPT);
- direction( targ, DIR_TARGET, TARG_ENEMY );
-
- if (targ.isCancel)
- {
- canned_msg(MSG_OK);
- return;
- }
-
- if (!targ.isValid || mgrd[targ.tx][targ.ty] == NON_MONSTER)
- {
- mpr("Yeah, whatever.");
- return;
- }
-
- mons_targd = mgrd[targ.tx][targ.ty];
- break;
-
- case 'p':
- if (targ_prev)
- {
- mons_targd = you.prev_targ;
- break;
- }
- /* fall through... */
- default:
- mpr("Okely-dokely.");
- return;
- }
-
- you.pet_target = mons_targd;
-
- noisy( 10, you.x_pos, you.y_pos );
- mpr("Attack!");
-} // end yell()
diff --git a/stone_soup/crawl-ref/source/effects.h b/stone_soup/crawl-ref/source/effects.h
deleted file mode 100644
index b7442a493e..0000000000
--- a/stone_soup/crawl-ref/source/effects.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * File: effects.cc
- * Summary: Misc stuff.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef EFFECTS_H
-#define EFFECTS_H
-
-#include "externs.h"
-
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: ability - acr - beam - decks - fight - religion - spells
- * *********************************************************************** */
-void banished(unsigned char gate_type);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: spells
- * *********************************************************************** */
-bool forget_spell(void);
-
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: fight - it_use2 - it_use3 - items - religion - spells -
- * spells2 - spells4
- * *********************************************************************** */
-bool lose_stat(unsigned char which_stat, unsigned char stat_loss,
- bool force = false);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: item_use - spell - spells
- * *********************************************************************** */
-void random_uselessness(unsigned char ru, unsigned char sc_read_2);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - decks - item_use - religion
- * *********************************************************************** */
-bool acquirement(unsigned char force_class, int agent);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: item_use
- * *********************************************************************** */
-bool recharge_wand(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: mstuff2
- * *********************************************************************** */
-void direct_effect(struct bolt &pbolt);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: mstuff2
- * *********************************************************************** */
-void mons_direct_effect(struct bolt &pbolt, int i);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void yell(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: ability - decks - fight - it_use3 - item_use - mstuff2 -
- * spell
- * *********************************************************************** */
-void torment( int tx, int ty );
-
-
-#endif
diff --git a/stone_soup/crawl-ref/source/enum.h b/stone_soup/crawl-ref/source/enum.h
deleted file mode 100644
index c084ec3154..0000000000
--- a/stone_soup/crawl-ref/source/enum.h
+++ /dev/null
@@ -1,3719 +0,0 @@
-/*
- * File: enum.h
- * Summary: Global (ick) enums.
- * Written by: Daniel Ligon
- *
- * Change History (most recent first):
- *
- * <11> 7 Aug 01 MV Changed MSLOT_UNASSIGNED_I to MSLOT_MISCELLANY
- * added NUM_MISCELLANY, changed MONS_ANOTHER_
- * LAVA_THING to MONS_SALAMANDER
- * <10> 7/29/00 JDJ Changed NUM_SPELL_TYPES to 14 (from 32767!).
- * 24jun2000 jmf Changed comment spacing so stuff fit in 80
- * columns; deleted some leading numbers in
- * comments (reasoning as above).
- * Also removed many "must be last" comments,
- * esp. where less-than-accurate.
- * <9> 10jan2000 dlb extensive - see changes.340 S
- * <8> 04nov1999 cdl added killed_by
- * <7> 29sep1999 BCR Added comments showing where uniques are
- * <6> 25sep1999 CDL Added commands
- * <5> 09sep1999 BWR Removed Great Swords skill
- * <4> 06aug1999 BWR added branch and level types
- * <3> 02jun1999 DML beams, clouds, ench, ms, kill,
- * other minor changes
- * <2> 26may1999 JDJ Added a header guard.
- * <1> --/--/-- CDL Created
- */
-
-
-#ifndef ENUM_H
-#define ENUM_H
-
-enum ability_type
-{
- ABIL_NON_ABILITY = -1,
- ABIL_SPIT_POISON = 1, // 1
- ABIL_GLAMOUR,
- ABIL_MAPPING,
- ABIL_TELEPORTATION,
- ABIL_BREATHE_FIRE, // 5
- ABIL_BLINK,
- ABIL_BREATHE_FROST,
- ABIL_BREATHE_POISON,
- ABIL_BREATHE_LIGHTNING,
- ABIL_SPIT_ACID, // 10
- ABIL_BREATHE_POWER,
- ABIL_EVOKE_BERSERK,
- ABIL_BREATHE_STICKY_FLAME,
- ABIL_BREATHE_STEAM,
- ABIL_FLY, // 15
- ABIL_SUMMON_MINOR_DEMON,
- ABIL_SUMMON_DEMONS,
- ABIL_HELLFIRE,
- ABIL_TORMENT,
- ABIL_RAISE_DEAD, // 20
- ABIL_CONTROL_DEMON,
- ABIL_TO_PANDEMONIUM,
- ABIL_CHANNELING,
- ABIL_THROW_FLAME,
- ABIL_THROW_FROST, // 25
- ABIL_BOLT_OF_DRAINING,
- ABIL_BREATHE_HELLFIRE,
- ABIL_FLY_II,
- ABIL_DELAYED_FIREBALL,
- ABIL_MUMMY_RESTORATION, // 30
- ABIL_EVOKE_MAPPING,
- ABIL_EVOKE_TELEPORTATION,
- ABIL_EVOKE_BLINK, // 33
- ABIL_EVOKE_TURN_INVISIBLE = 51, // 51
- ABIL_EVOKE_TURN_VISIBLE,
- ABIL_EVOKE_LEVITATE,
- ABIL_EVOKE_STOP_LEVITATING,
- ABIL_END_TRANSFORMATION, // 55
- ABIL_ZIN_REPEL_UNDEAD = 110, // 110
- ABIL_ZIN_HEALING,
- ABIL_ZIN_PESTILENCE,
- ABIL_ZIN_HOLY_WORD,
- ABIL_ZIN_SUMMON_GUARDIAN, // 114
- ABIL_TSO_REPEL_UNDEAD = 120, // 120
- ABIL_TSO_SMITING,
- ABIL_TSO_ANNIHILATE_UNDEAD,
- ABIL_TSO_CLEANSING_FLAME,
- ABIL_TSO_SUMMON_DAEVA, // 124
- ABIL_KIKU_RECALL_UNDEAD_SLAVES = 130, // 130
- ABIL_KIKU_ENSLAVE_UNDEAD = 132, // 132
- ABIL_KIKU_INVOKE_DEATH, // 133
- ABIL_YRED_ANIMATE_CORPSE = 140, // 140
- ABIL_YRED_RECALL_UNDEAD,
- ABIL_YRED_ANIMATE_DEAD,
- ABIL_YRED_DRAIN_LIFE,
- ABIL_YRED_CONTROL_UNDEAD, // 144
- ABIL_VEHUMET_CHANNEL_ENERGY = 160, // 160
- ABIL_OKAWARU_MIGHT = 170, // 170
- ABIL_OKAWARU_HEALING,
- ABIL_OKAWARU_HASTE, // 172
- ABIL_MAKHLEB_MINOR_DESTRUCTION = 180, // 180
- ABIL_MAKHLEB_LESSER_SERVANT_OF_MAKHLEB,
- ABIL_MAKHLEB_MAJOR_DESTRUCTION,
- ABIL_MAKHLEB_GREATER_SERVANT_OF_MAKHLEB, // 183
- ABIL_SIF_MUNA_FORGET_SPELL = 190, // 190
- ABIL_TROG_BERSERK = 200, // 200
- ABIL_TROG_MIGHT,
- ABIL_TROG_HASTE_SELF, // 202
- ABIL_ELYVILON_LESSER_HEALING = 220, // 220
- ABIL_ELYVILON_PURIFICATION,
- ABIL_ELYVILON_HEALING,
- ABIL_ELYVILON_RESTORATION,
- ABIL_ELYVILON_GREATER_HEALING, // 224
- ABIL_CHARM_SNAKE,
- ABIL_TRAN_SERPENT_OF_HELL,
- ABIL_ROTTING,
- ABIL_TORMENT_II,
- ABIL_PAIN,
- ABIL_ENSLAVE_UNDEAD,
- ABIL_BOLT_OF_FIRE,
- ABIL_BOLT_OF_COLD,
- ABIL_HELLFROST,
- ABIL_RENOUNCE_RELIGION = 250 // 250
-};
-
-enum ability_flag_type
-{
- ABFLAG_NONE = 0x00000000,
- ABFLAG_BREATH = 0x00000001, // ability uses DUR_BREATH_WEAPON
- ABFLAG_DELAY = 0x00000002, // ability has its own delay (ie glamour)
- ABFLAG_PAIN = 0x00000004, // ability must hurt player (ie torment)
- ABFLAG_EXHAUSTION = 0x00000008, // fails if you.exhausted
- ABFLAG_INSTANT = 0x00000010, // doesn't take time to use
- ABFLAG_PERMANENT_HP = 0x00000020, // costs permanent HPs
- ABFLAG_PERMANENT_MP = 0x00000040 // costs permanent MPs
-};
-
-enum activity_type
-{
- ACT_NONE = 0,
- ACT_MULTIDROP,
- ACT_RUNNING,
- ACT_TRAVELING,
- ACT_MACRO,
-
- ACT_ACTIVITY_COUNT
-};
-
-enum activity_interrupt_type
-{
- AI_FORCE_INTERRUPT = 0, // Forcibly kills any activity
- AI_KEYPRESS = 0x01,
- AI_FULL_HP = 0x02, // Player is fully healed
- AI_FULL_MP = 0x04, // Player has recovered all mp
- AI_STATUE = 0x08, // Bad statue has come into view
- AI_HUNGRY = 0x10, // Hunger increased
- AI_MESSAGE = 0x20, // Message was displayed
- AI_HP_LOSS = 0x40,
- AI_BURDEN_CHANGE = 0x80,
- AI_STAT_CHANGE = 0x100,
- AI_SEE_MONSTER = 0x200,
- AI_TELEPORT = 0x400
-};
-
-enum activity_interrupt_payload_type
-{
- AIP_NONE,
- AIP_INT,
- AIP_STRING,
- AIP_MONSTER,
- AIP_HP_LOSS
-};
-
-enum ammunition_description_type
-{
- DAMMO_ORCISH = 3, // 3
- DAMMO_ELVEN,
- DAMMO_DWARVEN // 5
-};
-
-// Various ways to get the acquirement effect.
-enum acquirement_agent_type
-{
- AQ_SCROLL = 0,
-
- // Empty space for the gods
-
- AQ_CARD_ACQUISITION = 100,
- AQ_CARD_VIOLENCE,
- AQ_CARD_PROTECTION,
- AQ_CARD_KNOWLEDGE,
-
- AQ_WIZMODE = 200
-};
-
-enum armour_type
-{
- ARM_ROBE, // 0
- ARM_LEATHER_ARMOUR,
- ARM_RING_MAIL,
- ARM_SCALE_MAIL,
- ARM_CHAIN_MAIL,
- ARM_SPLINT_MAIL, // 5
- ARM_BANDED_MAIL,
- ARM_PLATE_MAIL,
- ARM_SHIELD,
- ARM_CLOAK,
- ARM_HELMET, // 10
- ARM_GLOVES,
- ARM_BOOTS,
- ARM_BUCKLER,
- ARM_LARGE_SHIELD,
- ARM_DRAGON_HIDE, // 15
- ARM_TROLL_HIDE,
- ARM_CRYSTAL_PLATE_MAIL,
- ARM_DRAGON_ARMOUR,
- ARM_TROLL_LEATHER_ARMOUR,
- ARM_ICE_DRAGON_HIDE, // 20
- ARM_ICE_DRAGON_ARMOUR,
- ARM_STEAM_DRAGON_HIDE,
- ARM_STEAM_DRAGON_ARMOUR,
- ARM_MOTTLED_DRAGON_HIDE,
- ARM_MOTTLED_DRAGON_ARMOUR, // 25
- ARM_STORM_DRAGON_HIDE,
- ARM_STORM_DRAGON_ARMOUR,
- ARM_GOLD_DRAGON_HIDE,
- ARM_GOLD_DRAGON_ARMOUR,
- ARM_ANIMAL_SKIN, // 30
- ARM_SWAMP_DRAGON_HIDE,
- ARM_SWAMP_DRAGON_ARMOUR,
- ARM_STUDDED_LEATHER_ARMOUR,
- ARM_CAP,
- ARM_CENTAUR_BARDING, // 35
- ARM_NAGA_BARDING,
-
- NUM_ARMOURS
-};
-
-// these are for the old system (still used for reading old files)
-enum armour_description_type
-{
- DARM_PLAIN, // added for the heck of it, 15 Apr 2000 {dlb}
- DARM_EMBROIDERED_SHINY = 1, // which it is dependent upon armour subtype {dlb}
- DARM_RUNED,
- DARM_GLOWING,
- DARM_ELVEN,
- DARM_DWARVEN, // 5
- DARM_ORCISH
-};
-
-enum armour_property_type
-{
- PARM_AC, // 0
- PARM_EVASION
-};
-
-enum attribute_type
-{
- ATTR_DIVINE_LIGHTNING_PROTECTION, // 0
- // ATTR_SPEC_AIR, // don't use this!
- // ATTR_SPEC_EARTH,
- ATTR_CONTROL_TELEPORT = 3,
- ATTR_WALK_SLOWLY,
- ATTR_TRANSFORMATION, // 5
- ATTR_CARD_COUNTDOWN,
- ATTR_CARD_TABLE,
- ATTR_NUM_DEMONIC_POWERS,
- ATTR_WAS_SILENCED, //jmf: added for silenced messages
- ATTR_GOD_GIFT_COUNT, //jmf: added to help manage god gift giving
- ATTR_EXPENSIVE_FLIGHT, //jmf: flag for "manual flight" (ie wings)
- ATTR_DEMONIC_SCALES, //jmf: remember which kind of scales to improve
- ATTR_WALLS,
- ATTR_LAST_WALLS,
- ATTR_DELAYED_FIREBALL, // bwr: reserve fireballs
- ATTR_DEMONIC_POWER_1,
- ATTR_DEMONIC_POWER_2,
- ATTR_DEMONIC_POWER_3,
- ATTR_DEMONIC_POWER_4,
- ATTR_DEMONIC_POWER_5, // 19
- NUM_ATTRIBUTES = 30 // must be at least 30
-};
-
-enum band_type
-{
- BAND_NO_BAND = 0,
- BAND_KOBOLDS = 1,
- BAND_ORCS,
- BAND_ORC_KNIGHT,
- BAND_KILLER_BEES,
- BAND_FLYING_SKULLS, // 5
- BAND_SLIME_CREATURES,
- BAND_YAKS,
- BAND_UGLY_THINGS,
- BAND_HELL_HOUNDS,
- BAND_JACKALS, // 10
- BAND_HELL_KNIGHTS,
- BAND_ORC_HIGH_PRIEST,
- BAND_GNOLLS, // 13
- BAND_BUMBLEBEES = 16,
- BAND_CENTAURS,
- BAND_YAKTAURS,
- BAND_INSUBSTANTIAL_WISPS,
- BAND_OGRE_MAGE, // 20
- BAND_DEATH_YAKS,
- BAND_NECROMANCER,
- BAND_BALRUG,
- BAND_CACODEMON,
- BAND_EXECUTIONER, // 25
- BAND_HELLWING,
- BAND_DEEP_ELF_FIGHTER,
- BAND_DEEP_ELF_KNIGHT,
- BAND_DEEP_ELF_HIGH_PRIEST,
- BAND_KOBOLD_DEMONOLOGIST, // 30
- BAND_NAGAS,
- BAND_WAR_DOGS,
- BAND_GREY_RATS,
- BAND_GREEN_RATS,
- BAND_ORANGE_RATS, // 35
- BAND_SHEEP,
- BAND_GHOULS,
- BAND_DEEP_TROLLS,
- BAND_HOGS,
- BAND_HELL_HOGS, // 40
- BAND_GIANT_MOSQUITOES,
- BAND_BOGGARTS,
- BAND_BLINK_FROGS,
- BAND_SKELETAL_WARRIORS, // 44
- BAND_DRACONIAN, // 45
- NUM_BANDS // always last
-};
-
-enum beam_type // beam[].flavour
-{
- BEAM_MISSILE, // 0
- BEAM_MMISSILE, // 1 - and similarly unresistable things
- BEAM_FIRE,
- BEAM_COLD,
- BEAM_MAGIC,
- BEAM_ELECTRICITY, // 5
- BEAM_POISON,
- BEAM_NEG,
- BEAM_ACID,
- BEAM_MIASMA,
- // BEAM_EXPLOSION, // 10 - use is_explosion, and BEAM of flavour
- BEAM_SPORE = 11,
- BEAM_POISON_ARROW,
- BEAM_HELLFIRE,
- BEAM_NAPALM,
- BEAM_STEAM, // 15
- BEAM_HELLFROST,
- BEAM_ENERGY,
- BEAM_HOLY, // 18 - aka beam of cleansing, golden flame
- BEAM_FRAG,
- BEAM_LAVA, // 20
- BEAM_BACKLIGHT,
- BEAM_SLEEP,
- BEAM_ICE, // 23
- BEAM_NUKE = 27, // 27
- BEAM_RANDOM, // currently translates into FIRE..ACID
-
- // These used to be handled in the colour field:
- BEAM_SLOW, // BLACK
- BEAM_HASTE, // BLUE
- BEAM_HEALING, // GREEN
- BEAM_PARALYSIS, // CYAN
- BEAM_CONFUSION, // RED
- BEAM_INVISIBILITY, // MAGENTA
- BEAM_DIGGING, // BROWN
- BEAM_TELEPORT, // LIGHTGREY
- BEAM_POLYMORPH, // DARKGREY
- BEAM_CHARM, // LIGHTBLUE
- BEAM_BANISH, // LIGHTGREEN
- BEAM_DEGENERATE, // LIGHTCYAN
- BEAM_ENSLAVE_UNDEAD, // LIGHTRED
- BEAM_PAIN, // LIGHTMAGENTA
- BEAM_DISPEL_UNDEAD, // YELLOW
- BEAM_DISINTEGRATION, // WHITE
- BEAM_ENSLAVE_DEMON, // colour "16"
- BEAM_BLINK,
- BEAM_PETRIFY,
-
- // new beams for evaporate
- BEAM_POTION_STINKING_CLOUD,
- BEAM_POTION_POISON,
- BEAM_POTION_MIASMA,
- BEAM_POTION_STEAM,
- BEAM_POTION_FIRE,
- BEAM_POTION_COLD,
- BEAM_POTION_BLACK_SMOKE,
- BEAM_POTION_BLUE_SMOKE,
- BEAM_POTION_PURP_SMOKE,
- BEAM_POTION_RANDOM,
-
- BEAM_LINE_OF_SIGHT // only used for checking monster LOS
-};
-
-enum book_type
-{
- BOOK_MINOR_MAGIC_I, // 0
- BOOK_MINOR_MAGIC_II,
- BOOK_MINOR_MAGIC_III,
- BOOK_CONJURATIONS_I,
- BOOK_CONJURATIONS_II,
- BOOK_FLAMES, // 5
- BOOK_FROST,
- BOOK_SUMMONINGS,
- BOOK_FIRE,
- BOOK_ICE,
- BOOK_SURVEYANCES, // 10
- BOOK_SPATIAL_TRANSLOCATIONS,
- BOOK_ENCHANTMENTS,
- BOOK_YOUNG_POISONERS,
- BOOK_TEMPESTS,
- BOOK_DEATH, // 15
- BOOK_HINDERANCE,
- BOOK_CHANGES,
- BOOK_TRANSFIGURATIONS,
- BOOK_PRACTICAL_MAGIC,
- BOOK_WAR_CHANTS, // 20
- BOOK_CLOUDS,
- BOOK_HEALING,
- BOOK_NECROMANCY,
- BOOK_NECRONOMICON,
- BOOK_CALLINGS, // 25
- BOOK_CHARMS,
- BOOK_DEMONOLOGY,
- BOOK_AIR,
- BOOK_SKY,
- BOOK_DIVINATIONS, // 30
- BOOK_WARP,
- BOOK_ENVENOMATIONS,
- BOOK_ANNIHILATIONS,
- BOOK_UNLIFE,
- BOOK_DESTRUCTION, // 35
- BOOK_CONTROL,
- BOOK_MUTATIONS,
- BOOK_TUKIMA,
- BOOK_GEOMANCY,
- BOOK_EARTH, // 40
- BOOK_MANUAL,
- BOOK_WIZARDRY,
- BOOK_POWER,
- BOOK_CANTRIPS, //jmf: 04jan2000
- BOOK_PARTY_TRICKS, // 45 //jmf: 04jan2000
- BOOK_BEASTS,
- BOOK_STALKING, // renamed -- assassination was confusing -- bwr
- NUM_BOOKS
-};
-
-enum branch_type // you.where_are_you
-{
- BRANCH_MAIN_DUNGEON, // 0
- BRANCH_DIS,
- BRANCH_GEHENNA,
- BRANCH_VESTIBULE_OF_HELL,
- BRANCH_COCYTUS,
- BRANCH_TARTARUS, // 5
- BRANCH_INFERNO, // unimplemented
- BRANCH_THE_PIT, // 7 // unimplemented
- BRANCH_ORCISH_MINES = 10, // 10
- BRANCH_HIVE,
- BRANCH_LAIR,
- BRANCH_SLIME_PITS,
- BRANCH_VAULTS,
- BRANCH_CRYPT, // 15
- BRANCH_HALL_OF_BLADES,
- BRANCH_HALL_OF_ZOT,
- BRANCH_ECUMENICAL_TEMPLE,
- BRANCH_SNAKE_PIT,
- BRANCH_ELVEN_HALLS, // 20
- BRANCH_TOMB,
- BRANCH_SWAMP,
- BRANCH_CAVERNS
-};
-
-enum branch_stair_type // you.branch_stairs[] - 10 less than BRANCHES {dlb}
-{
- STAIRS_ORCISH_MINES, // 0
- STAIRS_HIVE,
- STAIRS_LAIR,
- STAIRS_SLIME_PITS,
- STAIRS_VAULTS,
- STAIRS_CRYPT, // 5
- STAIRS_HALL_OF_BLADES,
- STAIRS_HALL_OF_ZOT,
- STAIRS_ECUMENICAL_TEMPLE,
- STAIRS_SNAKE_PIT,
- STAIRS_ELVEN_HALLS, // 10
- STAIRS_TOMB,
- STAIRS_SWAMP,
- STAIRS_CAVERNS
-};
-
-enum burden_state_type // you.burden_state
-{
- BS_UNENCUMBERED, // 0
- BS_ENCUMBERED = 2, // 2
- BS_OVERLOADED = 5 // 5
-};
-
-enum canned_message_type // canned_msg() - unsigned char
-{
- MSG_SOMETHING_APPEARS, // 0
- MSG_NOTHING_HAPPENS,
- MSG_YOU_RESIST,
- MSG_TOO_BERSERK,
- MSG_NOTHING_CARRIED,
- MSG_CANNOT_DO_YET,
- MSG_OK,
- MSG_UNTHINKING_ACT,
- MSG_SPELL_FIZZLES,
- MSG_HUH,
- MSG_EMPTY_HANDED,
- MSG_NOT_IN_PRESENT_FORM,
- MSG_TOO_CONFUSED,
- MSG_DISORIENTED,
- MSG_CANT_REACH
-};
-
-enum char_set_type
-{
- CSET_ASCII, // flat 7-bit ASCII
- CSET_IBM, // 8-bit ANSI/Code Page 437
- CSET_DEC, // 8-bit DEC, 0xE0-0xFF shifted for line drawing chars
- NUM_CSET
-};
-
-enum cloud_type
-{
- CLOUD_NONE, // 0
- CLOUD_FIRE, // 1
- CLOUD_STINK, // 2
- CLOUD_COLD, // 3
- CLOUD_POISON, // 4
- CLOUD_GREY_SMOKE = 5, // 5: found 11jan2000 {dlb}
- CLOUD_BLUE_SMOKE = 6, // 6: found 11jan2000 {dlb}
- CLOUD_PURP_SMOKE = 7, // was: CLOUD_ENERGY and wrong 19jan2000 {dlb}
- CLOUD_STEAM, // 8
- CLOUD_MIASMA = 9, // 9: found 11jan2000 {dlb}
- CLOUD_BLACK_SMOKE = 10, //was: CLOUD_STICKY_FLAME and wrong 19jan2000 {dlb}
- CLOUD_RANDOM = 98,
- CLOUD_DEBUGGING = 99, // 99: used once as 'nonexistent cloud' {dlb}
-// if env.cloud_type > 100, it is a monster's cloud {dlb}
- CLOUD_FIRE_MON = 101, // 101: found 11jan2000 {dlb}
- CLOUD_STINK_MON = 102, // 102: found 11jan2000 {dlb}
- CLOUD_COLD_MON = 103, // 103: added 11jan2000 {dlb}
- CLOUD_POISON_MON = 104, // 104
- CLOUD_GREY_SMOKE_MON = 105, // 105: found 11jan2000 {dlb}
- CLOUD_BLUE_SMOKE_MON = 106, // 106: found 11jan2000 {dlb}
- CLOUD_PURP_SMOKE_MON = 107, // 107:
- CLOUD_STEAM_MON = 108, // 108: added 11jan2000 {dlb}
- CLOUD_MIASMA_MON = 109, // 109: added 11jan2000 {dlb}
- CLOUD_BLACK_SMOKE_MON = 110 // 110: added 19jan2000 {dlb}
-};
-
-enum command_type
-{
- CMD_NO_CMD = 1000, // 1000
- CMD_MOVE_NOWHERE,
- CMD_MOVE_LEFT,
- CMD_MOVE_DOWN,
- CMD_MOVE_UP,
- CMD_MOVE_RIGHT,
- CMD_MOVE_UP_LEFT,
- CMD_MOVE_DOWN_LEFT,
- CMD_MOVE_UP_RIGHT,
- CMD_MOVE_DOWN_RIGHT,
- CMD_RUN_LEFT, // 1000 + 10
- CMD_RUN_DOWN,
- CMD_RUN_UP,
- CMD_RUN_RIGHT,
- CMD_RUN_UP_LEFT,
- CMD_RUN_DOWN_LEFT,
- CMD_RUN_UP_RIGHT,
- CMD_RUN_DOWN_RIGHT,
- CMD_OPEN_DOOR_LEFT,
- CMD_OPEN_DOOR_DOWN,
- CMD_OPEN_DOOR_UP, // 1000 + 20
- CMD_OPEN_DOOR_RIGHT,
- CMD_OPEN_DOOR_UP_LEFT,
- CMD_OPEN_DOOR_DOWN_LEFT,
- CMD_OPEN_DOOR_UP_RIGHT,
- CMD_OPEN_DOOR_DOWN_RIGHT,
- CMD_OPEN_DOOR,
- CMD_CLOSE_DOOR,
- CMD_REST,
- CMD_GO_UPSTAIRS,
- CMD_GO_DOWNSTAIRS, // 1000 + 30
- CMD_TOGGLE_AUTOPICKUP,
- CMD_PICKUP,
- CMD_DROP,
- CMD_BUTCHER,
- CMD_INSPECT_FLOOR,
- CMD_EXAMINE_OBJECT,
- CMD_EVOKE,
- CMD_WIELD_WEAPON,
- CMD_WEAPON_SWAP,
- CMD_THROW, // 1000 + 40
- CMD_FIRE,
- CMD_WEAR_ARMOUR,
- CMD_REMOVE_ARMOUR,
- CMD_WEAR_JEWELLERY,
- CMD_REMOVE_JEWELLERY,
- CMD_LIST_WEAPONS,
- CMD_LIST_ARMOUR,
- CMD_LIST_JEWELLERY,
- CMD_ZAP_WAND,
- CMD_CAST_SPELL, // 1000 + 50
- CMD_MEMORISE_SPELL,
- CMD_USE_ABILITY,
- CMD_PRAY,
- CMD_EAT,
- CMD_QUAFF,
- CMD_READ,
- CMD_LOOK_AROUND,
- CMD_SEARCH,
- CMD_SHOUT,
- CMD_DISARM_TRAP, // 1000 + 60
- CMD_CHARACTER_DUMP,
- CMD_DISPLAY_COMMANDS,
- CMD_DISPLAY_INVENTORY,
- CMD_DISPLAY_KNOWN_OBJECTS,
- CMD_DISPLAY_MUTATIONS,
- CMD_DISPLAY_SKILLS,
- CMD_DISPLAY_MAP,
- CMD_DISPLAY_OVERMAP,
- CMD_DISPLAY_RELIGION,
- CMD_DISPLAY_CHARACTER_STATUS, // 1000 + 70
- CMD_EXPERIENCE_CHECK,
- CMD_GET_VERSION,
- CMD_ADJUST_INVENTORY,
- CMD_REPLAY_MESSAGES,
- CMD_REDRAW_SCREEN,
- CMD_MACRO_ADD,
- CMD_MACRO_SAVE,
- CMD_SAVE_GAME,
- CMD_SAVE_GAME_NOW,
- CMD_SUSPEND_GAME, // 1000 + 80
- CMD_QUIT,
- CMD_WIZARD,
- CMD_DESTROY_ITEM,
- CMD_OBSOLETE_INVOKE,
-
- CMD_MARK_STASH,
- CMD_FORGET_STASH,
- CMD_SEARCH_STASHES,
- CMD_EXPLORE,
- CMD_INTERLEVEL_TRAVEL,
- CMD_FIX_WAYPOINT,
-
- CMD_CLEAR_MAP
-};
-
-enum confirm_level_type
-{
- CONFIRM_NONE_EASY,
- CONFIRM_SAFE_EASY,
- CONFIRM_ALL_EASY
-};
-
-enum conduct_type
-{
- DID_NECROMANCY = 1, // vamp/drain/pain wpns, Zong/Curses
- DID_UNHOLY, // demon wpns, demon spells
- DID_ATTACK_HOLY,
- DID_ATTACK_FRIEND,
- DID_FRIEND_DIES,
- DID_STABBING,
- DID_POISON,
- DID_DEDICATED_BUTCHERY,
- DID_DEDICATED_KILL_LIVING,
- DID_DEDICATED_KILL_UNDEAD,
- DID_DEDICATED_KILL_DEMON,
- DID_DEDICATED_KILL_NATURAL_EVIL, // unused
- DID_DEDICATED_KILL_WIZARD,
- DID_DEDICATED_KILL_PRIEST, // unused
-
- // [dshaligram] No distinction between killing Angels during prayer or
- // otherwise, borrowed from bwr 4.1.
- DID_KILL_ANGEL,
- DID_LIVING_KILLED_BY_UNDEAD_SLAVE,
- DID_LIVING_KILLED_BY_SERVANT,
- DID_UNDEAD_KILLED_BY_SERVANT,
- DID_DEMON_KILLED_BY_SERVANT,
- DID_NATURAL_EVIL_KILLED_BY_SERVANT, // unused
- DID_ANGEL_KILLED_BY_SERVANT,
- DID_SPELL_MEMORISE,
- DID_SPELL_CASTING,
- DID_SPELL_PRACTISE,
- DID_SPELL_NONUTILITY, // unused
- DID_CARDS,
- DID_STIMULANTS, // unused
- DID_EAT_MEAT, // unused
- DID_CREATED_LIFE, // unused
-
- NUM_CONDUCTS
-};
-
-enum corpse_effect_type
-{
- CE_NOCORPSE, // 0
- CE_CLEAN, // 1
- CE_CONTAMINATED, // 2
- CE_POISONOUS, // 3
- CE_HCL, // 4
- CE_MUTAGEN_RANDOM, // 5
- CE_MUTAGEN_GOOD, // 6 - may be worth implementing {dlb}
- CE_MUTAGEN_BAD, // 7 - may be worth implementing {dlb}
- CE_RANDOM, // 8 - not used, but may be worth implementing {dlb}
- CE_ROTTEN = 50 // 50 - must remain at 50 for now {dlb}
-};
-
-enum corpse_type
-{
- CORPSE_BODY, // 0
- CORPSE_SKELETON
-};
-
-enum death_knight_type
-{
- DK_NO_SELECTION,
- DK_NECROMANCY,
- DK_YREDELEMNUL,
- DK_RANDOM
-};
-
-enum deck_type
-{
- DECK_OF_WONDERS, // 0
- DECK_OF_SUMMONING,
- DECK_OF_TRICKS,
- DECK_OF_POWER,
- DECK_OF_PUNISHMENT
-};
-
-enum delay_type
-{
- DELAY_NOT_DELAYED,
- DELAY_EAT,
- DELAY_ARMOUR_ON,
- DELAY_ARMOUR_OFF,
- DELAY_MEMORISE,
- DELAY_BUTCHER,
- DELAY_AUTOPICKUP,
- DELAY_WEAPON_SWAP, // for easy_butcher
- DELAY_PASSWALL,
- DELAY_DROP_ITEM,
- DELAY_ASCENDING_STAIRS,
- DELAY_DESCENDING_STAIRS,
- DELAY_INTERUPTABLE = 100, // simple interuptable delay
- DELAY_UNINTERUPTABLE // simple uninteruptable delay
-};
-
-enum demon_beam_type
-{
- DMNBM_HELLFIRE, // 0
- DMNBM_SMITING,
- DMNBM_BRAIN_FEED,
- DMNBM_MUTATION
-};
-
-enum demon_class_type
-{
- DEMON_LESSER, // 0: Class V
- DEMON_COMMON, // 1: Class II-IV
- DEMON_GREATER, // 2: Class I
- DEMON_RANDOM // any of the above
-};
-
-enum description_level_type
-{
- DESC_CAP_THE, // 0
- DESC_NOCAP_THE, // 1
- DESC_CAP_A, // 2
- DESC_NOCAP_A, // 3
- DESC_CAP_YOUR, // 4
- DESC_NOCAP_YOUR, // 5
- DESC_PLAIN, // 6
- DESC_NOCAP_ITS, // 7
- DESC_INVENTORY_EQUIP, // 8
- DESC_INVENTORY // 8
-};
-
-enum dragon_class_type
-{
- DRAGON_LIZARD,
- DRAGON_DRACONIAN,
- DRAGON_DRAGON
-};
-
-enum game_direction_type
-{
- DIR_DESCENDING = 0, // 0 - change and lose savefile compatibility (!!!)
- DIR_ASCENDING = 1 // 1 - change and lose savefile compatibility (!!!)
-};
-
-// NOTE: The order of these is very important to their usage!
-enum dungeon_char_type
-{
- DCHAR_WALL, // 0
- DCHAR_WALL_MAGIC,
- DCHAR_FLOOR,
- DCHAR_FLOOR_MAGIC,
- DCHAR_DOOR_OPEN,
- DCHAR_DOOR_CLOSED, // 5
- DCHAR_TRAP,
- DCHAR_STAIRS_DOWN,
- DCHAR_STAIRS_UP,
- DCHAR_ALTAR,
- DCHAR_ARCH, // 10
- DCHAR_FOUNTAIN,
- DCHAR_WAVY,
- DCHAR_STATUE,
- DCHAR_INVIS_EXPOSED,
- DCHAR_ITEM_DETECTED, // 15
- DCHAR_ITEM_ORB,
- DCHAR_ITEM_WEAPON,
- DCHAR_ITEM_ARMOUR,
- DCHAR_ITEM_WAND,
- DCHAR_ITEM_FOOD, // 20
- DCHAR_ITEM_SCROLL,
- DCHAR_ITEM_RING,
- DCHAR_ITEM_POTION,
- DCHAR_ITEM_MISSILE,
- DCHAR_ITEM_BOOK, // 25
- DCHAR_ITEM_STAVE,
- DCHAR_ITEM_MISCELLANY,
- DCHAR_ITEM_CORPSE,
- DCHAR_ITEM_GOLD,
- DCHAR_ITEM_AMULET, // 30
- DCHAR_CLOUD, // 31
- NUM_DCHAR_TYPES
-};
-
-enum drop_mode_type
-{
- DM_SINGLE,
- DM_MULTI
-};
-
-// lowest grid value which can be occupied (walk, swim, fly)
-#define MINMOVE 31
-
-// lowest grid value which can be seen through
-#define MINSEE 11
-
-enum dungeon_feature_type
-{
- DNGN_UNSEEN, // 0
- DNGN_ROCK_WALL,
- DNGN_STONE_WALL,
- DNGN_CLOSED_DOOR,
- DNGN_METAL_WALL,
- DNGN_SECRET_DOOR, // 5
- DNGN_GREEN_CRYSTAL_WALL,
- DNGN_ORCISH_IDOL,
- DNGN_WAX_WALL, // 8
- DNGN_PERMAROCK_WALL, // 9 - for undiggable walls
-
- DNGN_SILVER_STATUE = 21, // 21
- DNGN_GRANITE_STATUE,
- DNGN_ORANGE_CRYSTAL_STATUE, // 23
- DNGN_STATUE_RESERVED_1,
- DNGN_STATUE_RESERVED_2, // 25
-
- DNGN_LAVA = 61, // 61
- DNGN_DEEP_WATER, // 62
- DNGN_SHALLOW_WATER = 65, // 65
- DNGN_WATER_STUCK,
-
- DNGN_FLOOR, // 67
- DNGN_EXIT_HELL, // 68
- DNGN_ENTER_HELL, // 69
- DNGN_OPEN_DOOR, // 70
- // DNGN_BRANCH_STAIRS, // 71
- DNGN_TRAP_MECHANICAL = 75, // 75
- DNGN_TRAP_MAGICAL,
- DNGN_TRAP_III,
- DNGN_UNDISCOVERED_TRAP, // 78
-
- DNGN_ENTER_SHOP = 80, // 80
- DNGN_ENTER_LABYRINTH,
-
- DNGN_STONE_STAIRS_DOWN_I,
- DNGN_STONE_STAIRS_DOWN_II,
- DNGN_STONE_STAIRS_DOWN_III,
- DNGN_ROCK_STAIRS_DOWN, // 85 - was this supposed to be a ladder? {dlb}
-
- DNGN_STONE_STAIRS_UP_I,
- DNGN_STONE_STAIRS_UP_II,
- DNGN_STONE_STAIRS_UP_III,
- DNGN_ROCK_STAIRS_UP, // 89 - was this supposed to be a ladder? {dlb}
-
- DNGN_ENTER_DIS = 92, // 92
- DNGN_ENTER_GEHENNA,
- DNGN_ENTER_COCYTUS,
- DNGN_ENTER_TARTARUS, // 95
- DNGN_ENTER_ABYSS,
- DNGN_EXIT_ABYSS,
- DNGN_STONE_ARCH,
- DNGN_ENTER_PANDEMONIUM,
- DNGN_EXIT_PANDEMONIUM, // 100
- DNGN_TRANSIT_PANDEMONIUM, // 101
-
- DNGN_BUILDER_SPECIAL_WALL = 105, // 105; builder() only
- DNGN_BUILDER_SPECIAL_FLOOR, // 106; builder() only
-
- DNGN_ENTER_ORCISH_MINES = 110, // 110
- DNGN_ENTER_HIVE,
- DNGN_ENTER_LAIR,
- DNGN_ENTER_SLIME_PITS,
- DNGN_ENTER_VAULTS,
- DNGN_ENTER_CRYPT, // 115
- DNGN_ENTER_HALL_OF_BLADES,
- DNGN_ENTER_ZOT,
- DNGN_ENTER_TEMPLE,
- DNGN_ENTER_SNAKE_PIT,
- DNGN_ENTER_ELVEN_HALLS, // 120
- DNGN_ENTER_TOMB,
- DNGN_ENTER_SWAMP, // 122
- DNGN_ENTER_RESERVED_1,
- DNGN_ENTER_RESERVED_2,
- DNGN_ENTER_RESERVED_3,
- DNGN_ENTER_RESERVED_4, // 126
-
- DNGN_RETURN_FROM_ORCISH_MINES = 130, // 130
- DNGN_RETURN_FROM_HIVE,
- DNGN_RETURN_FROM_LAIR,
- DNGN_RETURN_FROM_SLIME_PITS,
- DNGN_RETURN_FROM_VAULTS,
- DNGN_RETURN_FROM_CRYPT, // 135
- DNGN_RETURN_FROM_HALL_OF_BLADES,
- DNGN_RETURN_FROM_ZOT,
- DNGN_RETURN_FROM_TEMPLE,
- DNGN_RETURN_FROM_SNAKE_PIT,
- DNGN_RETURN_FROM_ELVEN_HALLS, // 140
- DNGN_RETURN_FROM_TOMB,
- DNGN_RETURN_FROM_SWAMP, // 142
- DNGN_RETURN_RESERVED_1,
- DNGN_RETURN_RESERVED_2,
- DNGN_RETURN_RESERVED_3,
- DNGN_RETURN_RESERVED_4, // 146
-
- DNGN_ALTAR_ZIN = 180, // 180
- DNGN_ALTAR_SHINING_ONE,
- DNGN_ALTAR_KIKUBAAQUDGHA,
- DNGN_ALTAR_YREDELEMNUL,
- DNGN_ALTAR_XOM,
- DNGN_ALTAR_VEHUMET, // 185
- DNGN_ALTAR_OKAWARU,
- DNGN_ALTAR_MAKHLEB,
- DNGN_ALTAR_SIF_MUNA,
- DNGN_ALTAR_TROG,
- DNGN_ALTAR_NEMELEX_XOBEH, // 190
- DNGN_ALTAR_ELYVILON, // 191
-
- DNGN_BLUE_FOUNTAIN = 200, // 200
- DNGN_DRY_FOUNTAIN_I,
- DNGN_SPARKLING_FOUNTAIN, // aka 'Magic Fountain' {dlb}
- DNGN_DRY_FOUNTAIN_II,
- DNGN_DRY_FOUNTAIN_III,
- DNGN_DRY_FOUNTAIN_IV, // 205
- DNGN_DRY_FOUNTAIN_V,
- DNGN_DRY_FOUNTAIN_VI,
- DNGN_DRY_FOUNTAIN_VII,
- DNGN_DRY_FOUNTAIN_VIII,
- DNGN_PERMADRY_FOUNTAIN = 210, // added (from dungeon.cc/maps.cc) 22jan2000 {dlb}
-
- // Real terrain must all occur before 256 to guarantee it fits
- // into the unsigned char used for the grid!
-
- // There aren't really terrain, but they're passed in and used
- // to get their appearance character so I'm putting them here for now.
- DNGN_ITEM_ORB = 256,
- DNGN_INVIS_EXPOSED = 257,
- DNGN_ITEM_WEAPON = 258,
- DNGN_ITEM_ARMOUR = 259,
- DNGN_ITEM_WAND = 260,
- DNGN_ITEM_FOOD = 261,
- DNGN_ITEM_UNUSED_1 = 262,
- DNGN_ITEM_SCROLL = 263,
- DNGN_ITEM_RING = 264,
- DNGN_ITEM_POTION = 265,
- DNGN_ITEM_MISSILE = 266,
- DNGN_ITEM_BOOK = 267,
- DNGN_ITEM_UNUSED_2 = 268,
- DNGN_ITEM_STAVE = 269,
- DNGN_ITEM_MISCELLANY = 270,
- DNGN_ITEM_CORPSE = 271,
- DNGN_ITEM_GOLD = 272,
- DNGN_ITEM_AMULET = 273,
- DNGN_ITEM_DETECTED = 274,
-
- DNGN_CLOUD = 280,
- NUM_FEATURES, // for use in lookup table in view.cc
-
- DNGN_RANDOM,
- DNGN_START_OF_MONSTERS = 297 // don't go past here! see view.cc
-};
-
-enum duration_type
-{
- DUR_LIQUID_FLAMES, // 0
- DUR_ICY_ARMOUR,
- DUR_REPEL_MISSILES,
- DUR_PRAYER,
- DUR_REGENERATION,
- DUR_SWIFTNESS, // 5
- DUR_INSULATION,
- DUR_STONEMAIL,
- DUR_CONTROLLED_FLIGHT,
- DUR_TELEPORT,
- DUR_CONTROL_TELEPORT, // 10
- DUR_RESIST_POISON,
- DUR_BREATH_WEAPON,
- DUR_TRANSFORMATION,
- DUR_DEATH_CHANNEL,
- DUR_DEFLECT_MISSILES, // 15
-//jmf: new durations:
- DUR_FORESCRY,
- DUR_SEE_INVISIBLE,
- DUR_WEAPON_BRAND, // general "branding" spell counter
- DUR_SILENCE,
- DUR_GLAMOUR, // 20
- DUR_CONDENSATION_SHIELD = 23, // 23
- DUR_STONESKIN,
- DUR_REPEL_UNDEAD, // 25
- DUR_STUN,
- DUR_CUT, // 27
- NUM_DURATIONS = 30 // must be at least 30
-};
-
-// various elemental colour schemes... used for abstracting random short lists
-enum element_type
-{
- EC_FIRE = 32, // fiery colours (must be first and > higest colour)
- EC_ICE, // icy colours
- EC_EARTH, // earthy colours
- EC_ELECTRICITY, // electrical side of air
- EC_AIR, // non-electric and general air magic
- EC_POISON, // used only for venom mage and stalker stuff
- EC_WATER, // used only for the elemental
- EC_MAGIC, // general magical effect
- EC_MUTAGENIC, // transmute, poly, radiation effects
- EC_WARP, // teleportation and anything similar
- EC_ENCHANT, // magical enhancements
- EC_HEAL, // holy healing (not necromantic stuff)
- EC_HOLY, // general "good" god effects
- EC_DARK, // darkness
- EC_DEATH, // currently only assassin (and equal to EC_NECRO)
- EC_NECRO, // necromancy stuff
- EC_UNHOLY, // demonology stuff
- EC_VEHUMET, // vehumet's odd-ball colours
- EC_CRYSTAL, // colours of crystal
- EC_BLOOD, // colours of blood
- EC_SMOKE, // colours of smoke
- EC_SLIME, // colours of slime
- EC_JEWEL, // colourful
- EC_ELVEN, // used for colouring elf fabric items
- EC_DWARVEN, // used for colouring dwarf fabric items
- EC_ORCISH, // used for colouring orc fabric items
- EC_GILA, // gila monster colours
- EC_FLOOR, // colour of the area's floor
- EC_ROCK, // colour of the area's rock
- EC_STONE, // colour of the area's stone
- EC_RANDOM // any colour (except BLACK)
-};
-
-enum enchant_type
-{
- ENCH_NONE = 0, // 0
- ENCH_SLOW,
- ENCH_HASTE, // 2
- ENCH_FEAR = 4, // 4
- ENCH_CONFUSION, // 5
- ENCH_INVIS,
- ENCH_YOUR_POISON_I,
- ENCH_YOUR_POISON_II,
- ENCH_YOUR_POISON_III,
- ENCH_YOUR_POISON_IV, // 10
- ENCH_YOUR_SHUGGOTH_I, //jmf: Shuggothim!
- ENCH_YOUR_SHUGGOTH_II,
- ENCH_YOUR_SHUGGOTH_III,
- ENCH_YOUR_SHUGGOTH_IV,
- ENCH_YOUR_ROT_I, // 15 //jmf: rotting effect for monsters
- ENCH_YOUR_ROT_II,
- ENCH_YOUR_ROT_III,
- ENCH_YOUR_ROT_IV,
- ENCH_SUMMON = 19, // 19
- ENCH_ABJ_I, // 20
- ENCH_ABJ_II,
- ENCH_ABJ_III,
- ENCH_ABJ_IV,
- ENCH_ABJ_V,
- ENCH_ABJ_VI, // 25
- ENCH_BACKLIGHT_I, //jmf: backlight for Corona spell
- ENCH_BACKLIGHT_II,
- ENCH_BACKLIGHT_III,
- ENCH_BACKLIGHT_IV,
- ENCH_CHARM = 30, // 30
- ENCH_YOUR_STICKY_FLAME_I,
- ENCH_YOUR_STICKY_FLAME_II,
- ENCH_YOUR_STICKY_FLAME_III,
- ENCH_YOUR_STICKY_FLAME_IV, // 34
- ENCH_GLOWING_SHAPESHIFTER = 38, // 38
- ENCH_SHAPESHIFTER,
- ENCH_TP_I, // 40
- ENCH_TP_II,
- ENCH_TP_III,
- ENCH_TP_IV, // 43
- ENCH_POISON_I = 57, // 57
- ENCH_POISON_II,
- ENCH_POISON_III,
- ENCH_POISON_IV, // 60
- ENCH_STICKY_FLAME_I,
- ENCH_STICKY_FLAME_II,
- ENCH_STICKY_FLAME_III,
- ENCH_STICKY_FLAME_IV,
- ENCH_FRIEND_ABJ_I, // no longer used
- ENCH_FRIEND_ABJ_II, // no longer used
- ENCH_FRIEND_ABJ_III, // no longer used
- ENCH_FRIEND_ABJ_IV, // no longer used
- ENCH_FRIEND_ABJ_V, // no longer used
- ENCH_FRIEND_ABJ_VI, // no longer used
- ENCH_CREATED_FRIENDLY, // no longer used
- ENCH_SLEEP_WARY,
- ENCH_SUBMERGED, // 73 (includes air elementals in air)
- ENCH_SHORT_LIVED, // 74 for ball lightning
- NUM_ENCHANTMENTS
-};
-
-enum enchant_retval
-{
- ERV_FAIL,
- ERV_NEW,
- ERV_INCREASED
-};
-
-enum enchant_stat_type
-{
- ENCHANT_TO_HIT,
- ENCHANT_TO_DAM
-};
-
-enum equipment_type
-{
- EQ_NONE = -1,
-
- EQ_WEAPON, // 0
- EQ_CLOAK,
- EQ_HELMET,
- EQ_GLOVES,
- EQ_BOOTS,
- EQ_SHIELD, // 5
- EQ_BODY_ARMOUR,
- EQ_LEFT_RING,
- EQ_RIGHT_RING,
- EQ_AMULET,
- NUM_EQUIP,
-
- // these aren't actual equipment slots, they're categories for functions
- EQ_STAFF = 100, // weapon with base_type OBJ_STAVES
- EQ_RINGS, // check both rings
- EQ_RINGS_PLUS, // check both rings and sum plus
- EQ_RINGS_PLUS2, // check both rings and sum plus2
- EQ_ALL_ARMOUR // check all armour types
-};
-
-enum fire_type
-{
- FIRE_NONE,
- FIRE_LAUNCHER,
- FIRE_DART,
- FIRE_STONE,
- FIRE_DAGGER,
- FIRE_SPEAR,
- FIRE_HAND_AXE,
- FIRE_CLUB,
- FIRE_ROCK,
- NUM_FIRE_TYPES
-};
-
-enum flush_reason_type
-{
- FLUSH_ON_FAILURE, // spell/ability failed to cast
- FLUSH_BEFORE_COMMAND, // flush before getting a command
- FLUSH_ON_MESSAGE, // flush when printing a message
- FLUSH_ON_WARNING_MESSAGE, // flush on MSGCH_WARN messages
- FLUSH_ON_DANGER_MESSAGE, // flush on MSGCH_DANGER messages
- FLUSH_ON_PROMPT, // flush on MSGCH_PROMPT messages
- FLUSH_ON_UNSAFE_YES_OR_NO_PROMPT, // flush when !safe set to yesno()
- FLUSH_LUA, // flush when Lua wants to flush
- NUM_FLUSH_REASONS
-};
-
-enum food_type
-{
- FOOD_MEAT_RATION, // 0
- FOOD_BREAD_RATION,
- FOOD_PEAR,
- FOOD_APPLE,
- FOOD_CHOKO,
- FOOD_HONEYCOMB, // 5
- FOOD_ROYAL_JELLY,
- FOOD_SNOZZCUMBER,
- FOOD_PIZZA,
- FOOD_APRICOT,
- FOOD_ORANGE, // 10
- FOOD_BANANA,
- FOOD_STRAWBERRY,
- FOOD_RAMBUTAN,
- FOOD_LEMON,
- FOOD_GRAPE, // 15
- FOOD_SULTANA,
- FOOD_LYCHEE,
- FOOD_BEEF_JERKY,
- FOOD_CHEESE,
- FOOD_SAUSAGE, // 20
- FOOD_CHUNK,
- NUM_FOODS
-};
-
-enum genus_type
-{
- GENPC_DRACONIAN, // 0
- GENPC_ELVEN, // 1
- GENPC_DWARVEN // 2
-};
-
-enum gender_type
-{
- GENDER_NEUTER,
- GENDER_MALE,
- GENDER_FEMALE
-};
-
-enum ghost_value_type
-{
- GVAL_MAX_HP, // 0
- GVAL_EV,
- GVAL_AC,
- GVAL_SEE_INVIS,
- GVAL_RES_FIRE,
- GVAL_RES_COLD, // 5
- GVAL_RES_ELEC,
- GVAL_DAMAGE,
- GVAL_BRAND,
- GVAL_SPECIES,
- GVAL_BEST_SKILL, // 10
- GVAL_SKILL_LEVEL,
- GVAL_EXP_LEVEL,
- GVAL_CLASS,
- GVAL_SPELL_1, // 14
- GVAL_SPELL_2,
- GVAL_SPELL_3,
- GVAL_SPELL_4,
- GVAL_SPELL_5,
- GVAL_SPELL_6, // 19
- NUM_GHOST_VALUES, // should always be last value
-
- // these values are for demonlords, which override the above:
- GVAL_DEMONLORD_SPELLCASTER = 9,
- GVAL_DEMONLORD_FLY, // 10
- GVAL_DEMONLORD_UNUSED, // 11
- GVAL_DEMONLORD_HIT_DICE, // 12
- GVAL_DEMONLORD_CYCLE_COLOUR // 13
-};
-
-enum god_type
-{
- GOD_NO_GOD, // 0 -- must be zero
- GOD_ZIN,
- GOD_SHINING_ONE,
- GOD_KIKUBAAQUDGHA,
- GOD_YREDELEMNUL,
- GOD_XOM, // 5
- GOD_VEHUMET,
- GOD_OKAWARU,
- GOD_MAKHLEB,
- GOD_SIF_MUNA,
- GOD_TROG, // 10
- GOD_NEMELEX_XOBEH,
- GOD_ELYVILON,
- NUM_GODS, // always after last god
-
- GOD_RANDOM = 100
-};
-
-enum hands_reqd_type
-{
- HANDS_ONE,
- HANDS_HALF,
- HANDS_TWO,
-
- HANDS_DOUBLE // not a level, marks double ended weapons (== half)
-};
-
-enum helmet_type
-{
- THELM_HELMET = 0x0000,
- THELM_HELM = 0x0001,
- THELM_CAP = 0x0002,
- THELM_WIZARD_HAT = 0x0003,
- THELM_NUM_TYPES = 4,
-
- THELM_SPECIAL = 0x0004, // type used only for artefacts (mask, hat)
- THELM_TYPE_MASK = 0x00ff,
-
- THELM_DESC_PLAIN = 0x0000,
- THELM_DESC_WINGED = 0x0100,
- THELM_DESC_HORNED = 0x0200,
- THELM_DESC_CRESTED = 0x0300,
- THELM_DESC_PLUMED = 0x0400,
- THELM_DESC_SPIKED = 0x0500,
- THELM_DESC_VISORED = 0x0600,
- THELM_DESC_JEWELLED = 0x0700,
-
- THELM_DESC_MASK = 0xff00
-};
-
-
-enum boot_type // used in pluses2
-{
- TBOOT_BOOTS = 0,
- TBOOT_NAGA_BARDING,
- TBOOT_CENTAUR_BARDING,
- NUM_BOOT_TYPES
-};
-
-
-enum hunger_state // you.hunger_state
-{
- HS_RAVENOUS, // 0: not used within code, really
- HS_STARVING,
- HS_HUNGRY,
- HS_SATIATED, // "not hungry" state
- HS_FULL,
- HS_ENGORGED // 5
-};
-
-enum item_status_flag_type // per item flags: ie. ident status, cursed status
-{
- ISFLAG_KNOW_CURSE = 0x00000001, // curse status
- ISFLAG_KNOW_TYPE = 0x00000002, // artefact name, sub/special types
- ISFLAG_KNOW_PLUSES = 0x00000004, // to hit/to dam/to AC/charges
- ISFLAG_KNOW_PROPERTIES = 0x00000008, // know special artefact properties
- ISFLAG_IDENT_MASK = 0x0000000F, // mask of all id related flags
-
- // these three masks are of the minimal flags set upon using equipment:
- ISFLAG_EQ_WEAPON_MASK = 0x0000000B, // mask of flags for weapon equip
- ISFLAG_EQ_ARMOUR_MASK = 0x0000000F, // mask of flags for armour equip
- ISFLAG_EQ_JEWELLERY_MASK = 0x0000000F, // mask of flags for known jewellery
-
- ISFLAG_CURSED = 0x00000100, // cursed
- ISFLAG_RESERVED_1 = 0x00000200, // reserved
- ISFLAG_RESERVED_2 = 0x00000400, // reserved
- ISFLAG_RESERVED_3 = 0x00000800, // reserved
- ISFLAG_CURSE_MASK = 0x00000F00, // mask of all curse related flags
-
- ISFLAG_RANDART = 0x00001000, // special value is seed
- ISFLAG_UNRANDART = 0x00002000, // is an unrandart
- ISFLAG_ARTEFACT_MASK = 0x00003000, // randart or unrandart
- ISFLAG_DROPPED = 0x00004000, // dropped item (no autopickup)
- ISFLAG_THROWN = 0x00008000, // thrown missile weapon
-
- // these don't have to remain as flags
- ISFLAG_NO_DESC = 0x00000000, // used for clearing these flags
- ISFLAG_GLOWING = 0x00010000, // weapons or armour
- ISFLAG_RUNED = 0x00020000, // weapons or armour
- ISFLAG_EMBROIDERED_SHINY = 0x00040000, // armour: depends on sub-type
- ISFLAG_COSMETIC_MASK = 0x00070000, // mask of cosmetic descriptions
-
- ISFLAG_NO_RACE = 0x00000000, // used for clearing these flags
- ISFLAG_ORCISH = 0x01000000, // low quality items
- ISFLAG_DWARVEN = 0x02000000, // strong and robust items
- ISFLAG_ELVEN = 0x04000000, // light and accurate items
- ISFLAG_RACIAL_MASK = 0x07000000, // mask of racial equipment types
-
- ISFLAG_DEBUG_MARK = 0x80000000 // used for testing item structure
-};
-
-enum item_description_type
-{
- IDESC_WANDS,
- IDESC_POTIONS,
- IDESC_SCROLLS, // special field (like the others)
- IDESC_RINGS,
- IDESC_SCROLLS_II,
- NUM_IDESC
-};
-
-enum item_make_species_type
-{
- MAKE_ITEM_ELVEN = 1,
- MAKE_ITEM_DWARVEN = 2,
- MAKE_ITEM_ORCISH = 3,
-
- MAKE_ITEM_NO_RACE = 100,
- MAKE_ITEM_RANDOM_RACE = 250
-};
-
-enum item_origin_dump_selector
-{
- IODS_PRICE = 0, // Extra info is provided based on price
- IODS_ARTIFACTS = 1, // Extra information on artifacts
- IODS_EGO_ARMOUR = 2,
- IODS_EGO_WEAPON = 4,
- IODS_JEWELLERY = 8,
- IODS_RUNES = 16,
- IODS_RODS = 32,
- IODS_STAVES = 64,
- IODS_BOOKS = 128,
- IODS_EVERYTHING = 0xFF
-};
-
-enum item_type_id_type
-{
- IDTYPE_WANDS = 0,
- IDTYPE_SCROLLS,
- IDTYPE_JEWELLERY,
- IDTYPE_POTIONS,
- NUM_IDTYPE
-};
-
-enum item_type_id_state_type // used for values in id[4][50]
-{
- ID_UNKNOWN_TYPE = 0,
- ID_KNOWN_TYPE,
- ID_TRIED_TYPE
-};
-
-enum jewellery_type
-{
- RING_REGENERATION, // 0
- RING_PROTECTION,
- RING_PROTECTION_FROM_FIRE,
- RING_POISON_RESISTANCE,
- RING_PROTECTION_FROM_COLD,
- RING_STRENGTH, // 5
- RING_SLAYING,
- RING_SEE_INVISIBLE,
- RING_INVISIBILITY,
- RING_HUNGER,
- RING_TELEPORTATION, // 10
- RING_EVASION,
- RING_SUSTAIN_ABILITIES,
- RING_SUSTENANCE,
- RING_DEXTERITY,
- RING_INTELLIGENCE, // 15
- RING_WIZARDRY,
- RING_MAGICAL_POWER,
- RING_LEVITATION,
- RING_LIFE_PROTECTION,
- RING_PROTECTION_FROM_MAGIC, // 20
- RING_FIRE,
- RING_ICE,
- RING_TELEPORT_CONTROL, // 23
- AMU_RAGE = 35, // 35
- AMU_RESIST_SLOW,
- AMU_CLARITY,
- AMU_WARDING,
- AMU_RESIST_CORROSION,
- AMU_THE_GOURMAND, // 40
- AMU_CONSERVATION,
- AMU_CONTROLLED_FLIGHT,
- AMU_INACCURACY,
- AMU_RESIST_MUTATION,
- NUM_JEWELLERY
-};
-
-enum job_type
-{
- JOB_FIGHTER, // 0
- JOB_WIZARD,
- JOB_PRIEST,
- JOB_THIEF,
- JOB_GLADIATOR,
- JOB_NECROMANCER, // 5
- JOB_PALADIN,
- JOB_ASSASSIN,
- JOB_BERSERKER,
- JOB_HUNTER,
- JOB_CONJURER, // 10
- JOB_ENCHANTER,
- JOB_FIRE_ELEMENTALIST,
- JOB_ICE_ELEMENTALIST,
- JOB_SUMMONER,
- JOB_AIR_ELEMENTALIST, // 15
- JOB_EARTH_ELEMENTALIST,
- JOB_CRUSADER,
- JOB_DEATH_KNIGHT,
- JOB_VENOM_MAGE,
- JOB_CHAOS_KNIGHT, // 20
- JOB_TRANSMUTER,
- JOB_HEALER, // 22
- JOB_QUITTER, // 23 -- this is job 'x', don't use
- JOB_REAVER, // 24
- JOB_STALKER, // 25
- JOB_MONK,
- JOB_WARPER,
- JOB_WANDERER, // 23
- NUM_JOBS, // always after the last job
-
- JOB_UNKNOWN = 100
-};
-
-enum kill_method_type
-{
- KILLED_BY_MONSTER, // 0
- KILLED_BY_POISON,
- KILLED_BY_CLOUD,
- KILLED_BY_BEAM, // 3
- KILLED_BY_DEATHS_DOOR, // should be deprecated, but you never know {dlb}
- KILLED_BY_LAVA, // 5
- KILLED_BY_WATER,
- KILLED_BY_STUPIDITY,
- KILLED_BY_WEAKNESS,
- KILLED_BY_CLUMSINESS,
- KILLED_BY_TRAP, // 10
- KILLED_BY_LEAVING,
- KILLED_BY_WINNING,
- KILLED_BY_QUITTING,
- KILLED_BY_DRAINING,
- KILLED_BY_STARVATION, // 15
- KILLED_BY_FREEZING,
- KILLED_BY_BURNING,
- KILLED_BY_WILD_MAGIC,
- KILLED_BY_XOM,
- KILLED_BY_STATUE, // 20
- KILLED_BY_ROTTING,
- KILLED_BY_TARGETTING,
- KILLED_BY_SPORE,
- KILLED_BY_TSO_SMITING,
- KILLED_BY_PETRIFICATION, // 25
- KILLED_BY_SOMETHING = 27,
- KILLED_BY_FALLING_DOWN_STAIRS,
- KILLED_BY_ACID,
- KILLED_BY_CURARE,
- KILLED_BY_MELTING,
- KILLED_BY_BLEEDING,
-
- NUM_KILLBY
-};
-
-enum kill_category
-{
- KC_YOU,
- KC_FRIENDLY,
- KC_OTHER,
- KC_NCATEGORIES
-};
-
-enum killer_type // monster_die(), thing_thrown
-{
- KILL_YOU = 1, // 1
- KILL_MON,
- KILL_YOU_MISSILE,
- KILL_MON_MISSILE,
- KILL_MISC, // 5
- KILL_RESET, // abjuration, etc.
- KILL_DISMISSED // only on new game startup
-};
-
-#define YOU_KILL(x) ((x) == KILL_YOU || (x) == KILL_YOU_MISSILE)
-#define MON_KILL(x) ((x) == KILL_MON || (x) == KILL_MON_MISSILE)
-
-enum launch_retval
-{
- LRET_FUMBLED = 0, // must be left as 0
- LRET_LAUNCHED,
- LRET_THROWN
-};
-
-enum level_area_type // you.level_type
-{
- LEVEL_DUNGEON, // 0
- LEVEL_LABYRINTH,
- LEVEL_ABYSS,
- LEVEL_PANDEMONIUM
-};
-
-enum load_mode_type
-{
- LOAD_START_GAME,
- LOAD_RESTART_GAME,
- LOAD_ENTER_LEVEL
-};
-
-enum map_section_type // see maps.cc and dungeon.cc {dlb}
-{
- MAP_NORTH = 1, // 1
- MAP_NORTHWEST,
- MAP_NORTHEAST,
- MAP_SOUTHWEST,
- MAP_SOUTHEAST, // 5
- MAP_ENCOMPASS,
- MAP_NORTH_DIS
-};
-
-// if you mess with this list, you'll need to make changes in initfile.cc
-enum msg_channel_type
-{
- MSGCH_PLAIN, // regular text
- MSGCH_PROMPT, // various prompts
- MSGCH_GOD, // god/religion (param is god)
- MSGCH_DURATION, // effect down/warnings
- MSGCH_DANGER, // serious life threats (ie very large HP attacks)
- MSGCH_WARN, // much less serious threats
- MSGCH_FOOD, // hunger notices
- MSGCH_RECOVERY, // recovery from disease/stat/poison condition
- MSGCH_SOUND, // messages about things the player hears
- MSGCH_TALK, // monster talk (param is monster type)
- MSGCH_INTRINSIC_GAIN, // player level/stat/species-power gains
- MSGCH_MUTATION, // player gain/lose mutations
- MSGCH_MONSTER_SPELL, // monsters casting spells
- MSGCH_MONSTER_ENCHANT,// monsters enchantments up and down
- MSGCH_MONSTER_DAMAGE, // monster damage reports (param is level)
- MSGCH_MONSTER_TARGET, // message marking the monster as a target
- MSGCH_ROTTEN_MEAT, // messages about chunks/corpses becoming rotten
- MSGCH_EQUIPMENT, // equipment listing messages
- MSGCH_FLOOR_ITEMS, // like equipment, but lists of floor items
- MSGCH_MULTITURN_ACTION, // delayed action messages
- MSGCH_DIAGNOSTICS, // various diagnostic messages
- NUM_MESSAGE_CHANNELS // always last
-};
-
-enum msg_colour_type
-{
- MSGCOL_BLACK = 0, // the order of these colours is important
- MSGCOL_BLUE,
- MSGCOL_GREEN,
- MSGCOL_CYAN,
- MSGCOL_RED,
- MSGCOL_MAGENTA,
- MSGCOL_BROWN,
- MSGCOL_LIGHTGRAY,
- MSGCOL_DARKGRAY,
- MSGCOL_LIGHTBLUE,
- MSGCOL_LIGHTGREEN,
- MSGCOL_LIGHTCYAN,
- MSGCOL_LIGHTMAGENTA,
- MSGCOL_YELLOW,
- MSGCOL_WHITE,
- MSGCOL_DEFAULT, // use default colour
- MSGCOL_ALTERNATE, // use secondary default colour scheme
- MSGCOL_MUTED, // don't print messages
- MSGCOL_PLAIN // same as plain channel
-};
-
-enum misc_item_type
-{
- MISC_BOTTLED_EFREET, // 0
- MISC_CRYSTAL_BALL_OF_SEEING,
- MISC_AIR_ELEMENTAL_FAN,
- MISC_LAMP_OF_FIRE,
- MISC_STONE_OF_EARTH_ELEMENTALS,
- MISC_LANTERN_OF_SHADOWS, // 5
- MISC_HORN_OF_GERYON,
- MISC_BOX_OF_BEASTS,
- MISC_DECK_OF_WONDERS,
- MISC_DECK_OF_SUMMONINGS,
- MISC_CRYSTAL_BALL_OF_ENERGY, // 10
- MISC_EMPTY_EBONY_CASKET,
- MISC_CRYSTAL_BALL_OF_FIXATION,
- MISC_DISC_OF_STORMS,
- MISC_RUNE_OF_ZOT,
- MISC_DECK_OF_TRICKS, // 15
- MISC_DECK_OF_POWER,
- MISC_PORTABLE_ALTAR_OF_NEMELEX,
- NUM_MISCELLANY // mv: used for random generation
-};
-
-enum missile_type
-{
- MI_STONE, // 0
- MI_ARROW,
- MI_BOLT,
- MI_DART,
- MI_NEEDLE,
- MI_LARGE_ROCK, //jmf: it'd be nice to move MI_LARGE_ROCK to DEBRIS_ROCK
- NUM_MISSILES,
- MI_NONE // was MI_EGGPLANT... used for launch type detection
-};
-
-// properties of the monster class (other than resists/vulnerabilities)
-enum mons_class_flags
-{
- M_NO_FLAGS = 0,
-
- M_SPELLCASTER = (1<< 0), // any non-physical-attack powers,
- M_ACTUAL_SPELLS = (1<< 1), // monster is a wizard,
- M_PRIEST = (1<< 2), // monster is a priest
- M_FIGHTER = (1<< 3), // monster is skilled fighter
-
- M_FLIES = (1<< 4), // will crash to ground if paralysed?
- M_LEVITATE = (1<< 5), // ... but not if this is set
- M_INVIS = (1<< 6), // is created invis
- M_SEE_INVIS = (1<< 7), // can see invis
- M_SPEAKS = (1<< 8), // uses talking code
- M_CONFUSED = (1<< 9), // monster is perma-confused,
- M_BATTY = (1<<10), // monster is batty
- M_SPLITS = (1<<11), // monster can split
- M_AMPHIBIOUS = (1<<12), // monster can swim in water,
- M_THICK_SKIN = (1<<13), // monster has more effective AC,
- M_HUMANOID = (1<<14), // for Glamour
- M_COLD_BLOOD = (1<<15), // susceptible to cold
- M_WARM_BLOOD = (1<<16), // no effect currently
- M_REGEN = (1<<17), // regenerates quickly
- M_BURROWS = (1<<18), // monster digs through rock
- M_EVIL = (1<<19), // monster vulnerable to holy spells
-
- M_ON_FIRE = (1<<20), // XXX: Potentially ditchable
- M_FROZEN = (1<<21), // XXX: Potentially ditchable
-
-
- M_SPECIAL_ABILITY = (1<<26), // XXX: eventually make these spells?
- M_COLOUR_SHIFT = (1<<27), // flag for element colour shifters
- M_DCHAR_SYMBOL = (1<<28), // monster looks like a DCHAR terrain
-
- M_NO_SKELETON = (1<<29), // boneless corpses
- M_NO_WOUNDS = (1<<30), // doesn't show would level
- M_NO_EXP_GAIN = (1<<31) // worth 0 xp
-};
-
-enum mon_resist_flags
-{
- MR_NO_FLAGS = 0,
-
- // resistances
- // Notes:
- // - negative energy is mostly handled via mons_has_life_force()
- // - acid is handled mostly by genus (jellies) plus non-living
- MR_RES_ELEC = (1<< 0),
- MR_RES_POISON = (1<< 1),
- MR_RES_FIRE = (1<< 2),
- MR_RES_HELLFIRE = (1<< 3),
- MR_RES_COLD = (1<< 4),
- MR_RES_HELLFROST = (1<< 5),
-
- // vulnerabilities
- MR_VUL_ELEC = (1<< 6),
- MR_VUL_POISON = (1<< 7),
- MR_VUL_FIRE = (1<< 8),
- MR_VUL_COLD = (1<< 9),
-
- // melee armour resists/vulnerabilities
- // XXX: how to do combos (bludgeon/slice, bludgeon/pierce)
- MR_RES_PIERCE = (1<<10),
- MR_RES_SLICE = (1<<11),
- MR_RES_BLUDGEON = (1<<12),
-
- MR_VUL_PIERCE = (1<<13),
- MR_VUL_SLICE = (1<<14),
- MR_VUL_BLUDGEON = (1<<15)
-};
-
-enum targ_mode_type
-{
- TARG_ANY,
- TARG_ENEMY,
- TARG_FRIEND,
- TARG_NUM_MODES
-};
-
-// note this order is very sensitive... look at mons_is_unique()
-enum monster_type // (int) menv[].type
-{
- MONS_GIANT_ANT, // 0
- MONS_GIANT_BAT,
- MONS_CENTAUR,
- MONS_RED_DEVIL,
- MONS_ETTIN,
- MONS_FUNGUS, // 5
- MONS_GOBLIN,
- MONS_HOUND,
- MONS_IMP,
- MONS_JACKAL,
- MONS_KILLER_BEE, // 10
- MONS_KILLER_BEE_LARVA,
- MONS_MANTICORE,
- MONS_NECROPHAGE,
- MONS_ORC,
- MONS_PHANTOM, // 15
- MONS_QUASIT,
- MONS_RAT,
- MONS_SCORPION, // 18
- //MONS_TUNNELING_WORM, // deprecated and now officially removed {dlb}
- MONS_UGLY_THING = 20, // 20
- MONS_FIRE_VORTEX,
- MONS_WORM,
- MONS_ABOMINATION_SMALL,
- MONS_YELLOW_WASP,
- MONS_ZOMBIE_SMALL, // 25
- MONS_ANGEL,
- MONS_GIANT_BEETLE,
- MONS_CYCLOPS,
- MONS_DRAGON,
- MONS_TWO_HEADED_OGRE, // 30
- MONS_FIEND,
- MONS_GIANT_SPORE,
- MONS_HOBGOBLIN,
- MONS_ICE_BEAST,
- MONS_JELLY, // 35
- MONS_KOBOLD,
- MONS_LICH,
- MONS_MUMMY,
- MONS_GUARDIAN_NAGA,
- MONS_OGRE, // 40
- MONS_PLANT,
- MONS_QUEEN_BEE,
- MONS_RAKSHASA,
- MONS_SNAKE,
- MONS_TROLL, // 45
- MONS_UNSEEN_HORROR,
- MONS_VAMPIRE,
- MONS_WRAITH,
- MONS_ABOMINATION_LARGE,
- MONS_YAK, // 50
- MONS_ZOMBIE_LARGE,
- MONS_ORC_WARRIOR,
- MONS_KOBOLD_DEMONOLOGIST,
- MONS_ORC_WIZARD,
- MONS_ORC_KNIGHT, // 55
- //MONS_WORM_TAIL = 56, // deprecated and now officially removed {dlb}
- MONS_WYVERN = 57, // 57
- MONS_BIG_KOBOLD,
- MONS_GIANT_EYEBALL,
- MONS_WIGHT, // 60
- MONS_OKLOB_PLANT,
- MONS_WOLF_SPIDER,
- MONS_SHADOW,
- MONS_HUNGRY_GHOST,
- MONS_EYE_OF_DRAINING, // 65
- MONS_BUTTERFLY,
- MONS_WANDERING_MUSHROOM,
- MONS_EFREET,
- MONS_BRAIN_WORM,
- MONS_GIANT_ORANGE_BRAIN, // 70
- MONS_BOULDER_BEETLE,
- MONS_FLYING_SKULL,
- MONS_HELL_HOUND,
- MONS_MINOTAUR,
- MONS_ICE_DRAGON, // 75
- MONS_SLIME_CREATURE,
- MONS_FREEZING_WRAITH,
- MONS_RAKSHASA_FAKE,
- MONS_GREAT_ORB_OF_EYES,
- MONS_HELLION, // 80
- MONS_ROTTING_DEVIL,
- MONS_TORMENTOR,
- MONS_REAPER,
- MONS_SOUL_EATER,
- MONS_HAIRY_DEVIL, // 85
- MONS_ICE_DEVIL,
- MONS_BLUE_DEVIL,
- MONS_BEAST,
- MONS_IRON_DEVIL, // 89
- MONS_GLOWING_SHAPESHIFTER = 98, // 98
- MONS_SHAPESHIFTER,
- MONS_GIANT_MITE, // 100
- MONS_STEAM_DRAGON,
- MONS_VERY_UGLY_THING,
- MONS_ORC_SORCERER,
- MONS_HIPPOGRIFF,
- MONS_GRIFFON, // 105
- MONS_HYDRA,
- MONS_SKELETON_SMALL,
- MONS_SKELETON_LARGE,
- MONS_HELL_KNIGHT,
- MONS_NECROMANCER, // 110
- MONS_WIZARD,
- MONS_ORC_PRIEST,
- MONS_ORC_HIGH_PRIEST,
- MONS_HUMAN,
- MONS_GNOLL, // 115
- MONS_CLAY_GOLEM,
- MONS_WOOD_GOLEM,
- MONS_STONE_GOLEM,
- MONS_IRON_GOLEM,
- MONS_CRYSTAL_GOLEM, // 120
- MONS_TOENAIL_GOLEM,
- MONS_MOTTLED_DRAGON,
- MONS_EARTH_ELEMENTAL,
- MONS_FIRE_ELEMENTAL,
- MONS_AIR_ELEMENTAL, // 125
- MONS_ICE_FIEND,
- MONS_SHADOW_FIEND,
- MONS_BROWN_SNAKE,
- MONS_GIANT_LIZARD,
- MONS_SPECTRAL_WARRIOR, // 130
- MONS_PULSATING_LUMP,
- MONS_STORM_DRAGON,
- MONS_YAKTAUR,
- MONS_DEATH_YAK,
- MONS_ROCK_TROLL, // 135
- MONS_STONE_GIANT,
- MONS_FLAYED_GHOST,
- MONS_BUMBLEBEE,
- MONS_REDBACK,
- MONS_INSUBSTANTIAL_WISP, // 140
- MONS_VAPOUR,
- MONS_OGRE_MAGE,
- MONS_SPINY_WORM,
- MONS_DANCING_WEAPON,
- MONS_TITAN, // 145
- MONS_GOLDEN_DRAGON,
- MONS_ELF,
- MONS_LINDWURM,
- MONS_ELEPHANT_SLUG,
- MONS_WAR_DOG, // 150
- MONS_GREY_RAT,
- MONS_GREEN_RAT,
- MONS_ORANGE_RAT,
- MONS_BLACK_SNAKE,
- MONS_SHEEP, // 155
- MONS_GHOUL,
- MONS_HOG,
- MONS_GIANT_MOSQUITO,
- MONS_GIANT_CENTIPEDE,
- MONS_IRON_TROLL, // 160
- MONS_NAGA,
- MONS_FIRE_GIANT,
- MONS_FROST_GIANT,
- MONS_FIREDRAKE,
- MONS_SHADOW_DRAGON, // 165
- MONS_YELLOW_SNAKE,
- MONS_GREY_SNAKE,
- MONS_DEEP_TROLL,
- MONS_GIANT_BLOWFLY,
- MONS_RED_WASP, // 170
- MONS_SWAMP_DRAGON,
- MONS_SWAMP_DRAKE,
- MONS_DEATH_DRAKE,
- MONS_SOLDIER_ANT,
- MONS_HILL_GIANT,
- MONS_QUEEN_ANT, // 175
- MONS_ANT_LARVA,
- MONS_GIANT_FROG,
- MONS_GIANT_BROWN_FROG,
- MONS_SPINY_FROG,
- MONS_BLINK_FROG, // 180
- MONS_GIANT_COCKROACH,
- MONS_SMALL_SNAKE, // 182
- //jmf: new monsters
- MONS_SHUGGOTH, //jmf: added for evil spells
- MONS_WOLF, //jmf: added
- MONS_WARG, //jmf: added for orc mines
- MONS_BEAR, //jmf: added bears!
- MONS_GRIZZLY_BEAR,
- MONS_POLAR_BEAR,
- MONS_BLACK_BEAR, // 189
- MONS_SIMULACRUM_SMALL,
- MONS_SIMULACRUM_LARGE,
- //jmf: end new monsters
- MONS_WHITE_IMP = 220, // 220
- MONS_LEMURE,
- MONS_UFETUBUS,
- MONS_MANES,
- MONS_MIDGE,
- MONS_NEQOXEC, // 225
- MONS_ORANGE_DEMON,
- MONS_HELLWING,
- MONS_SMOKE_DEMON,
- MONS_YNOXINUL,
- MONS_EXECUTIONER, // 230
- MONS_GREEN_DEATH,
- MONS_BLUE_DEATH,
- MONS_BALRUG,
- MONS_CACODEMON,
- MONS_DEMONIC_CRAWLER, // 235
- MONS_SUN_DEMON,
- MONS_SHADOW_IMP,
- MONS_SHADOW_DEMON,
- MONS_LOROCYPROCA,
- MONS_SHADOW_WRAITH, // 240
- MONS_GIANT_AMOEBA,
- MONS_GIANT_SLUG,
- MONS_GIANT_SNAIL,
- MONS_SPATIAL_VORTEX,
- MONS_PIT_FIEND, // 245
- MONS_BORING_BEETLE,
- MONS_GARGOYLE,
- MONS_METAL_GARGOYLE,
- MONS_MOLTEN_GARGOYLE,
- MONS_PROGRAM_BUG, // 250
-// BCR - begin first batch of uniques.
- MONS_MNOLEG,
- MONS_LOM_LOBON,
- MONS_CEREBOV,
- MONS_GLOORX_VLOQ, // 254
- MONS_MOLLUSC_LORD, // 255 - deprecated, but still referenced in code {dlb}
-// BCR - End first batch of uniques.
- MONS_NAGA_MAGE = 260, // 260
- MONS_NAGA_WARRIOR,
- MONS_ORC_WARLORD,
- MONS_DEEP_ELF_SOLDIER,
- MONS_DEEP_ELF_FIGHTER,
- MONS_DEEP_ELF_KNIGHT, // 265
- MONS_DEEP_ELF_MAGE,
- MONS_DEEP_ELF_SUMMONER,
- MONS_DEEP_ELF_CONJURER,
- MONS_DEEP_ELF_PRIEST,
- MONS_DEEP_ELF_HIGH_PRIEST, // 270
- MONS_DEEP_ELF_DEMONOLOGIST,
- MONS_DEEP_ELF_ANNIHILATOR,
- MONS_DEEP_ELF_SORCERER,
- MONS_DEEP_ELF_DEATH_MAGE,
- MONS_BROWN_OOZE, // 275
- MONS_AZURE_JELLY,
- MONS_DEATH_OOZE,
- MONS_ACID_BLOB,
- MONS_ROYAL_JELLY,
-// BCR - begin second batch of uniques.
- MONS_TERENCE, // 280
- MONS_JESSICA,
- MONS_IJYB,
- MONS_SIGMUND,
- MONS_BLORK_THE_ORC,
- MONS_EDMUND, // 285
- MONS_PSYCHE,
- MONS_EROLCHA,
- MONS_DONALD,
- MONS_URUG,
- MONS_MICHAEL, // 290
- MONS_JOSEPH,
- MONS_SNORG, // was Anita - Snorg is correct 16jan2000 {dlb}
- MONS_ERICA,
- MONS_JOSEPHINE,
- MONS_HAROLD, // 295
- MONS_NORBERT,
- MONS_JOZEF,
- MONS_AGNES,
- MONS_MAUD,
- MONS_LOUISE, // 300
- MONS_FRANCIS,
- MONS_FRANCES,
- MONS_RUPERT,
- MONS_WAYNE,
- MONS_DUANE, // 305
- MONS_XTAHUA,
- MONS_NORRIS,
- MONS_ADOLF,
- MONS_MARGERY,
- MONS_BORIS, // 310
-// BCR - end second batch of uniques.
-
- MONS_DRACONIAN,
- MONS_BLACK_DRACONIAN,
- MONS_MOTTLED_DRACONIAN,
- MONS_YELLOW_DRACONIAN,
- MONS_GREEN_DRACONIAN, // 315
- MONS_PURPLE_DRACONIAN,
- MONS_RED_DRACONIAN,
- MONS_WHITE_DRACONIAN,
- MONS_PALE_DRACONIAN,
- MONS_DRACONIAN_CALLER, // 320
- MONS_DRACONIAN_MONK,
- MONS_DRACONIAN_ZEALOT,
- MONS_DRACONIAN_SHIFTER,
- MONS_DRACONIAN_ANNIHILATOR,
- MONS_DRACONIAN_KNIGHT, // 325
- MONS_DRACONIAN_SCORCHER,
-
- // The Lords of Hell:
- MONS_GERYON = 340, // 340
- MONS_DISPATER,
- MONS_ASMODEUS,
- MONS_ANTAEUS,
- MONS_ERESHKIGAL, // 344
-
- MONS_ANCIENT_LICH = 356, // 356
- MONS_OOZE, // 357
-
- MONS_VAULT_GUARD = 360, // 360
- MONS_CURSE_SKULL,
- MONS_VAMPIRE_KNIGHT,
- MONS_VAMPIRE_MAGE,
- MONS_SHINING_EYE,
- MONS_ORB_GUARDIAN, // 365
- MONS_DAEVA,
- MONS_SPECTRAL_THING,
- MONS_GREATER_NAGA,
- MONS_SKELETAL_DRAGON,
- MONS_TENTACLED_MONSTROSITY, // 370
- MONS_SPHINX,
- MONS_ROTTING_HULK,
- MONS_GUARDIAN_MUMMY,
- MONS_GREATER_MUMMY,
- MONS_MUMMY_PRIEST, // 375
- MONS_CENTAUR_WARRIOR,
- MONS_YAKTAUR_CAPTAIN,
- MONS_KILLER_KLOWN,
- MONS_ELECTRIC_GOLEM, // replacing the guardian robot -- bwr
- MONS_BALL_LIGHTNING, // replacing the dorgi -- bwr
- MONS_ORB_OF_FIRE, // Swords renamed to fit -- bwr
- MONS_QUOKKA, // Quokka are a type of wallaby, returned -- bwr 382
-
-
- MONS_EYE_OF_DEVASTATION = 385, // 385
- MONS_MOTH_OF_WRATH,
- MONS_DEATH_COB,
- MONS_CURSE_TOE,
- MONS_GOLD_MIMIC,
- MONS_WEAPON_MIMIC, // 390
- MONS_ARMOUR_MIMIC,
- MONS_SCROLL_MIMIC,
- MONS_POTION_MIMIC,
- MONS_HELL_HOG,
- MONS_SERPENT_OF_HELL, // 395
- MONS_BOGGART,
- MONS_QUICKSILVER_DRAGON,
- MONS_IRON_DRAGON,
- MONS_SKELETAL_WARRIOR, // 399
- MONS_PLAYER_GHOST, // 400
- MONS_PANDEMONIUM_DEMON, // 401
-
- MONS_GIANT_NEWT, // 402
- MONS_GIANT_GECKO, // 403
- MONS_GIANT_IGUANA, // 404
- MONS_GILA_MONSTER, // 405
- MONS_KOMODO_DRAGON, // 406
-
- // Lava monsters:
- MONS_LAVA_WORM = 420, // 420
- MONS_LAVA_FISH,
- MONS_LAVA_SNAKE,
- MONS_SALAMANDER, // 423 mv: was another lava thing
-
- // Water monsters:
- MONS_BIG_FISH = 430, // 430
- MONS_GIANT_GOLDFISH,
- MONS_ELECTRICAL_EEL,
- MONS_JELLYFISH,
- MONS_WATER_ELEMENTAL,
- MONS_SWAMP_WORM, // 435
-
- NUM_MONSTERS, // used for polymorph
- RANDOM_MONSTER = 1000, // used to distinguish between a random monster and using program bugs for error trapping {dlb}
- WANDERING_MONSTER = 2500 // only used in monster placement routines - forced limit checks {dlb}
-
-};
-
-enum beh_type
-{
- BEH_SLEEP, // 0
- BEH_WANDER,
- BEH_SEEK,
- BEH_FLEE,
- BEH_CORNERED,
- BEH_PANIC, // like flee but without running away
- BEH_INVESTIGATE, // investigating an ME_DISTURB
- NUM_BEHAVIOURS, // max # of legal states
- BEH_CHARMED, // hostile-but-charmed; create only
- BEH_FRIENDLY, // used during creation only
- BEH_HOSTILE, // creation only
- BEH_GOD_GIFT, // creation only
- BEH_GUARD // creation only - monster is guard
-};
-
-enum mon_attitude_type
-{
- ATT_HOSTILE, // 0, default in most cases
- ATT_FRIENDLY, // created friendly (or tamed?)
- ATT_NEUTRAL
-};
-
-enum mon_event_type
-{
- ME_EVAL, // 0, evaluate monster AI state
- ME_DISTURB, // noisy
- ME_ANNOY, // annoy at range
- ME_ALERT, // alert to presence
- ME_WHACK, // physical attack
- ME_SHOT, // attack at range
- ME_SCARE, // frighten monster
- ME_CORNERED // cannot flee
-};
-
-enum mon_flight_type
-{
- FLY_NOT,
- FLY_POWERED, // wings, etc... paralysis == fall
- FLY_LEVITATION // doesn't require physical effort
-};
-
-// Note: These are currently stored in chars!!!
-// Need to fix struct monsters and the savefile if you want more.
-enum monster_flag_type
-{
- MF_CREATED_FRIENDLY = 0x01, // no benefit from killing
- MF_GOD_GIFT = 0x02, // player not penalized by its death
- MF_BATTY = 0x04, // flutters like a bat
- MF_JUST_SUMMONED = 0x08, // monster skips next available action
- MF_TAKING_STAIRS = 0x10, // is following player through stairs
-
- MF_UNUSED_I = 0x20,
- MF_UNUSED_II = 0x40,
- MF_UNUSED_III = 0x80
-};
-
-enum mon_dam_level_type
-{
- MDAM_OKAY,
- MDAM_LIGHTLY_DAMAGED,
- MDAM_MODERATELY_DAMAGED,
- MDAM_HEAVILY_DAMAGED,
- MDAM_HORRIBLY_DAMAGED,
- MDAM_ALMOST_DEAD,
- MDAM_DEAD
-};
-
-enum mon_desc_type // things that cross categorical lines {dlb}
-{
- MDSC_LEAVES_HIDE, // 0
- MDSC_REGENERATES,
- MDSC_NOMSG_WOUNDS
-};
-
-enum mon_holy_type // matches (char) H_foo in mon-util.h, see: monster_holiness()
-{
- MH_HOLY, // 0 - was -1
- MH_NATURAL, // 1 - was 0
- MH_UNDEAD, // 2 - was 1
- MH_DEMONIC, // 3 - was 2
- MH_NONLIVING, // golems and other constructs
- MH_PLANT // plants
-};
-
-enum mon_inv_type // (int) menv[].inv[]
-{
- MSLOT_WEAPON,
- MSLOT_MISSILE, // although it is a second weapon for MONS_TWO_HEADED_OGRE - how to reconcile cleanly? {dlb}
- MSLOT_ARMOUR,
- MSLOT_MISCELLANY, //mv: used for misc. obj. (7 Aug 2001)
- MSLOT_POTION, // mv: now used only for potions (7 Aug 2001)
- MSLOT_WAND, //
- MSLOT_SCROLL,
- MSLOT_GOLD, //mv: used for money :) (7 Aug 2001)
- NUM_MONSTER_SLOTS = 8 // value must remain 8 for savefile compatibility {dlb}
-};
-
-// order of these is important:
-enum mon_itemuse_type
-{
- MONUSE_NOTHING,
- MONUSE_EATS_ITEMS,
- MONUSE_OPEN_DOORS,
- MONUSE_STARTING_EQUIPMENT,
- MONUSE_WEAPONS_ARMOUR,
- MONUSE_MAGIC_ITEMS
-};
-
-// XXX: someday merge these into SPELL_
-enum mon_spell_type
-{
- MS_MMISSILE, // 0
- MS_FLAME,
- MS_FROST,
- MS_PARALYSIS,
- MS_SLOW,
- MS_HASTE, // 5
- MS_CONFUSE, // 6 - do not deprecate!!! 13jan2000 {dlb}
- MS_VENOM_BOLT,
- MS_FIRE_BOLT,
- MS_COLD_BOLT,
- MS_LIGHTNING_BOLT, // 10
- MS_INVIS,
- MS_FIREBALL,
- MS_HEAL,
- MS_TELEPORT,
- MS_TELEPORT_OTHER, // 15
- MS_BLINK,
- MS_CRYSTAL_SPEAR,
- MS_DIG,
- MS_NEGATIVE_BOLT,
- MS_HELLFIRE_BURST, // 20
- MS_VAMPIRE_SUMMON,
- MS_ORB_ENERGY,
- MS_BRAIN_FEED,
- MS_LEVEL_SUMMON,
- MS_FAKE_RAKSHASA_SUMMON, // 25
- MS_STEAM_BALL,
- MS_SUMMON_DEMON,
- MS_ANIMATE_DEAD,
- MS_PAIN,
- MS_SMITE, // 30
- MS_STICKY_FLAME,
- MS_POISON_BLAST,
- MS_SUMMON_DEMON_LESSER,
- MS_SUMMON_UFETUBUS,
- MS_PURPLE_BLAST, // 35
- MS_SUMMON_BEAST, // MS_GERYON was not descriptive - renamed 13jan2000 {dlb}
- MS_ENERGY_BOLT,
- MS_STING,
- MS_IRON_BOLT,
- MS_STONE_ARROW, // 40
- MS_POISON_SPLASH,
- MS_SUMMON_UNDEAD,
- MS_MUTATION, // 43
- MS_CANTRIP,
- MS_DISINTEGRATE, // 45
- MS_MARSH_GAS,
- MS_QUICKSILVER_BOLT,
- MS_TORMENT,
- MS_HELLFIRE,
- MS_METAL_SPLINTERS, // 50
- MS_SUMMON_DEMON_GREATER, // [foo]_1 was confusing - renamed 13jan2000 {dlb}
- MS_BANISHMENT,
- MS_CONTROLLED_BLINK,
- MS_CONTROL_UNDEAD,
- MS_MIASMA, // 55
- MS_SUMMON_LIZARDS,
- MS_BLINK_OTHER,
- MS_DISPEL_UNDEAD,
- MS_HELLFROST,
- MS_POISON_ARROW, // 60
- // XXX: before adding more monster versions of player spells we should
- // consider merging the two lists into one and just having monsters
- // fail to implement the ones that are impractical.
- NUM_MONSTER_SPELLS,
- MS_NO_SPELL = 100
-};
-
-// XXX: These still need to be applied in mon-data.h
-enum mon_spellbook_type
-{
- MST_ORC_WIZARD_I = 0,
- MST_ORC_WIZARD_II,
- MST_ORC_WIZARD_III,
- MST_GUARDIAN_NAGA = 10,
- MST_LICH_I = 20,
- MST_LICH_II,
- MST_LICH_III,
- MST_LICH_IV,
- MST_BURNING_DEVIL = 30,
- MST_VAMPIRE = 40,
- MST_VAMPIRE_KNIGHT,
- MST_VAMPIRE_MAGE,
- MST_EFREET = 50,
- MST_KILLER_KLOWN,
- MST_BRAIN_WORM,
- MST_GIANT_ORANGE_BRAIN,
- MST_RAKSHASA,
- MST_GREAT_ORB_OF_EYES, // 55
- MST_ORC_SORCERER,
- MST_STEAM_DRAGON,
- MST_HELL_KNIGHT_I,
- MST_HELL_KNIGHT_II,
- MST_NECROMANCER_I, // 60
- MST_NECROMANCER_II,
- MST_WIZARD_I,
- MST_WIZARD_II,
- MST_WIZARD_III,
- MST_WIZARD_IV, // 65
- MST_WIZARD_V,
- MST_ORC_PRIEST,
- MST_ORC_HIGH_PRIEST,
- MST_MOTTLED_DRAGON,
- MST_ICE_FIEND, // 70
- MST_SHADOW_FIEND,
- MST_TORMENTOR,
- MST_STORM_DRAGON,
- MST_WHITE_IMP,
- MST_YNOXINUL, // 75
- MST_NEQOXEC,
- MST_HELLWING,
- MST_SMOKE_DEMON,
- MST_CACODEMON,
- MST_GREEN_DEATH, // 80
- MST_BALRUG,
- MST_BLUE_DEATH,
- MST_GERYON,
- MST_DISPATER,
- MST_ASMODEUS, // 85
- MST_ERESHKIGAL,
- MST_ANTAEUS, // 87
- MST_MNOLEG = 90,
- MST_LOM_LOBON,
- MST_CEREBOV,
- MST_GLOORX_VLOQ,
- MST_TITAN,
- MST_GOLDEN_DRAGON, // 95
- MST_DEEP_ELF_SUMMONER,
- MST_DEEP_ELF_CONJURER_I,
- MST_DEEP_ELF_CONJURER_II,
- MST_DEEP_ELF_PRIEST,
- MST_DEEP_ELF_HIGH_PRIEST, // 100
- MST_DEEP_ELF_DEMONOLOGIST,
- MST_DEEP_ELF_ANNIHILATOR,
- MST_DEEP_ELF_SORCERER,
- MST_DEEP_ELF_DEATH_MAGE,
- MST_KOBOLD_DEMONOLOGIST, // 105
- MST_NAGA,
- MST_NAGA_MAGE,
- MST_CURSE_SKULL,
- MST_SHINING_EYE,
- MST_FROST_GIANT, // 110
- MST_ANGEL,
- MST_DAEVA,
- MST_SHADOW_DRAGON,
- MST_SPHINX,
- MST_MUMMY, // 115
- MST_ELECTRIC_GOLEM,
- MST_ORB_OF_FIRE,
- MST_SHADOW_IMP,
- MST_GHOST,
- MST_HELL_HOG, // 120
- MST_SWAMP_DRAGON,
- MST_SWAMP_DRAKE,
- MST_SERPENT_OF_HELL,
- MST_BOGGART,
- MST_EYE_OF_DEVASTATION, // 125
- MST_QUICKSILVER_DRAGON,
- MST_IRON_DRAGON,
- MST_SKELETAL_WARRIOR,
- MST_MYSTIC,
- MST_DEATH_DRAKE, // 130
- MST_DRAC_SCORCHER, // As Bioster would say.. pig*s
- MST_DRAC_CALLER,
- MST_DRAC_SHIFTER,
- NUM_MSTYPES,
- MST_NO_SPELLS = 250
-};
-
-enum mutation_type
-{
- MUT_TOUGH_SKIN, // 0
- MUT_STRONG,
- MUT_CLEVER,
- MUT_AGILE,
- MUT_GREEN_SCALES,
- MUT_BLACK_SCALES, // 5
- MUT_GREY_SCALES,
- MUT_BONEY_PLATES,
- MUT_REPULSION_FIELD,
- MUT_POISON_RESISTANCE,
- MUT_CARNIVOROUS, // 10
- MUT_HERBIVOROUS,
- MUT_HEAT_RESISTANCE,
- MUT_COLD_RESISTANCE,
- MUT_SHOCK_RESISTANCE,
- MUT_REGENERATION, // 15
- MUT_FAST_METABOLISM,
- MUT_SLOW_METABOLISM,
- MUT_WEAK,
- MUT_DOPEY,
- MUT_CLUMSY, // 20
- MUT_TELEPORT_CONTROL,
- MUT_TELEPORT,
- MUT_MAGIC_RESISTANCE,
- MUT_FAST,
- MUT_ACUTE_VISION, // 25
- MUT_DEFORMED,
- MUT_TELEPORT_AT_WILL,
- MUT_SPIT_POISON,
- MUT_MAPPING,
- MUT_BREATHE_FLAMES, // 30
- MUT_BLINK,
- MUT_HORNS,
- MUT_STRONG_STIFF,
- MUT_FLEXIBLE_WEAK,
- MUT_LOST, // 35
- MUT_CLARITY,
- MUT_BERSERK,
- MUT_DETERIORATION,
- MUT_BLURRY_VISION,
- MUT_MUTATION_RESISTANCE, // 40
- MUT_FRAIL,
- MUT_ROBUST,
- MUT_TORMENT_RESISTANCE,
- MUT_NEGATIVE_ENERGY_RESISTANCE,
- MUT_SUMMON_MINOR_DEMONS, // 45
- MUT_SUMMON_DEMONS,
- MUT_HURL_HELLFIRE,
- MUT_CALL_TORMENT,
- MUT_RAISE_DEAD,
- MUT_CONTROL_DEMONS, // 50
- MUT_PANDEMONIUM,
- MUT_DEATH_STRENGTH,
- MUT_CHANNEL_HELL,
- MUT_DRAIN_LIFE,
- MUT_THROW_FLAMES, // 55
- MUT_THROW_FROST,
- MUT_SMITE, // 57
- MUT_CLAWS, //jmf: added
- MUT_HOOVES, //jmf: etc.
- MUT_BREATHE_POISON, // 60
- MUT_STINGER,
- MUT_BIG_WINGS,
- MUT_BLUE_MARKS, // 63 - decorative, as in "mark of the devil"
- MUT_GREEN_MARKS, // 64
- MUT_RED_SCALES = 70, // 70
- MUT_NACREOUS_SCALES,
- MUT_GREY2_SCALES,
- MUT_METALLIC_SCALES,
- MUT_BLACK2_SCALES,
- MUT_WHITE_SCALES, // 75
- MUT_YELLOW_SCALES,
- MUT_BROWN_SCALES,
- MUT_BLUE_SCALES,
- MUT_PURPLE_SCALES,
- MUT_SPECKLED_SCALES, // 80
- MUT_ORANGE_SCALES,
- MUT_INDIGO_SCALES,
- MUT_RED2_SCALES,
- MUT_IRIDESCENT_SCALES,
- MUT_PATTERNED_SCALES, // 85
- NUM_MUTATIONS
-};
-
-enum object_class_type // (unsigned char) mitm[].base_type
-{
- OBJ_WEAPONS, // 0
- OBJ_MISSILES,
- OBJ_ARMOUR,
- OBJ_WANDS,
- OBJ_FOOD, // 4
- OBJ_UNKNOWN_I = 5, // (use unknown) labeled as books in invent.cc {dlb}
- OBJ_SCROLLS = 6, // 6
- OBJ_JEWELLERY,
- OBJ_POTIONS, // 8
- OBJ_UNKNOWN_II = 9, // (use unknown, stackable) labeled as gems in invent.cc {dlb}
- OBJ_BOOKS = 10, // 10
- OBJ_STAVES,
- OBJ_ORBS,
- OBJ_MISCELLANY,
- OBJ_CORPSES,
- OBJ_GOLD, // important role as upper limit to chardump::dump_inventory() {dlb}
- OBJ_GEMSTONES, // found in itemname.cc, labeled as miscellaneous in invent.cc {dlb}
- NUM_OBJECT_CLASSES,
- OBJ_UNASSIGNED = 100, // must remain set to 100 {dlb}
- OBJ_RANDOM = 255 // must remain set to 255 {dlb} - also used
- // for blanket random sub_type .. see dungeon::items()
-};
-
-enum object_selector
-{
- OSEL_ANY = -1,
- OSEL_WIELD = -2
-};
-
-enum orb_type
-{
- ORB_ZOT // 0
-};
-
-enum potion_type
-{
- POT_HEALING, // 0
- POT_HEAL_WOUNDS,
- POT_SPEED,
- POT_MIGHT,
- POT_GAIN_STRENGTH,
- POT_GAIN_DEXTERITY, // 5
- POT_GAIN_INTELLIGENCE,
- POT_LEVITATION,
- POT_POISON,
- POT_SLOWING,
- POT_PARALYSIS, // 10
- POT_CONFUSION,
- POT_INVISIBILITY,
- POT_PORRIDGE,
- POT_DEGENERATION,
- POT_DECAY, // 15
- POT_WATER,
- POT_EXPERIENCE,
- POT_MAGIC,
- POT_RESTORE_ABILITIES,
- POT_STRONG_POISON, // 20
- POT_BERSERK_RAGE,
- POT_CURE_MUTATION,
- POT_MUTATION,
- NUM_POTIONS
-};
-
-enum pronoun_type
-{
- PRONOUN_CAP, // 0
- PRONOUN_NOCAP, // 1
- PRONOUN_CAP_POSSESSIVE, // 2
- PRONOUN_NOCAP_POSSESSIVE, // 3
- PRONOUN_REFLEXIVE // 4 (reflexive is always lowercase)
-};
-
-enum proximity_type // proximity to player to create monster
-{
- PROX_ANYWHERE,
- PROX_CLOSE_TO_PLAYER,
- PROX_AWAY_FROM_PLAYER,
- PROX_NEAR_STAIRS
-};
-
-enum randart_prop_type
-{
- RAP_BRAND, // 0
- RAP_AC,
- RAP_EVASION,
- RAP_STRENGTH,
- RAP_INTELLIGENCE,
- RAP_DEXTERITY, // 5
- RAP_FIRE,
- RAP_COLD,
- RAP_ELECTRICITY,
- RAP_POISON,
- RAP_NEGATIVE_ENERGY, // 10
- RAP_MAGIC,
- RAP_EYESIGHT,
- RAP_INVISIBLE,
- RAP_LEVITATE,
- RAP_BLINK, // 15
- RAP_CAN_TELEPORT,
- RAP_BERSERK,
- RAP_MAPPING,
- RAP_NOISES,
- RAP_PREVENT_SPELLCASTING, // 20
- RAP_CAUSE_TELEPORTATION,
- RAP_PREVENT_TELEPORTATION,
- RAP_ANGRY,
- RAP_METABOLISM,
- RAP_MUTAGENIC, // 25
- RAP_ACCURACY,
- RAP_DAMAGE,
- RAP_CURSED,
- RAP_STEALTH,
- RAP_NUM_PROPERTIES
-};
-
-enum read_book_action_type
-{
- RBOOK_USE_STAFF,
- RBOOK_MEMORISE,
- RBOOK_READ_SPELL
-};
-
-enum run_check_type
-{
- RCHECK_LEFT,
- RCHECK_FRONT,
- RCHECK_RIGHT
-};
-
-enum run_dir_type
-{
- RDIR_UP = 0,
- RDIR_UP_RIGHT,
- RDIR_RIGHT,
- RDIR_DOWN_RIGHT,
- RDIR_DOWN,
- RDIR_DOWN_LEFT,
- RDIR_LEFT,
- RDIR_UP_LEFT,
- RDIR_REST
-};
-
-enum rune_type
-{
- // Note: that runes DIS-SWAMP have the same numberic value as the branch
- RUNE_DIS = 1,
- RUNE_GEHENNA,
- RUNE_COCYTUS = 4,
- RUNE_TARTARUS,
- RUNE_SLIME_PITS = 13,
- RUNE_VAULTS,
- RUNE_SNAKE_PIT = 19,
- RUNE_ELVEN_HALLS, // unused
- RUNE_TOMB,
- RUNE_SWAMP,
-
- // Runes 50 and 51 are for Pandemonium (general demon) and the Abyss
- RUNE_DEMONIC = 50,
- RUNE_ABYSSAL,
-
- // Runes 60-63 correspond to the Pandemonium demonlords,
- // and are equal to the corresponding vault.
- RUNE_MNOLEG = 60,
- RUNE_LOM_LOBON,
- RUNE_CEREBOV,
- RUNE_GLOORX_VLOQ,
- NUM_RUNE_TYPES, // should always be last
- RUNE_NONE
-};
-
-enum score_format_type
-{
- SCORE_TERSE, // one line
- SCORE_REGULAR, // two lines (name, cause, blank)
- SCORE_VERBOSE // everything (dates, times, god, etc)
-};
-
-enum scroll_type
-{
- SCR_IDENTIFY, // 0
- SCR_TELEPORTATION,
- SCR_FEAR,
- SCR_NOISE,
- SCR_REMOVE_CURSE,
- SCR_DETECT_CURSE, // 5
- SCR_SUMMONING,
- SCR_ENCHANT_WEAPON_I,
- SCR_ENCHANT_ARMOUR,
- SCR_TORMENT,
- SCR_RANDOM_USELESSNESS, // 10
- SCR_CURSE_WEAPON,
- SCR_CURSE_ARMOUR,
- SCR_IMMOLATION,
- SCR_BLINKING,
- SCR_PAPER, // 15
- SCR_MAGIC_MAPPING,
- SCR_FORGETFULNESS,
- SCR_ACQUIREMENT,
- SCR_ENCHANT_WEAPON_II,
- SCR_VORPALISE_WEAPON, // 20
- SCR_RECHARGING,
- SCR_ENCHANT_WEAPON_III,
- NUM_SCROLLS
-};
-
-enum shop_type // (unsigned char) env.sh_type[], item_in_shop(), in_a_shop()
-{
- SHOP_WEAPON, // 0
- SHOP_ARMOUR,
- SHOP_WEAPON_ANTIQUE,
- SHOP_ARMOUR_ANTIQUE,
- SHOP_GENERAL_ANTIQUE,
- SHOP_JEWELLERY, // 5
- SHOP_WAND,
- SHOP_BOOK,
- SHOP_FOOD,
- SHOP_DISTILLERY,
- SHOP_SCROLL, // 10
- SHOP_GENERAL,
- NUM_SHOPS, // must remain last 'regular' member {dlb}
- SHOP_UNASSIGNED = 100, // keep set at 100 for now {dlb}
- SHOP_RANDOM = 255 // keep set at 255 for now {dlb}
-};
-
-enum shout_type
-{
- S_SILENT, // silent
- S_SHOUT, // shout
- S_BARK, // bark
- S_SHOUT2, // shout twice
- S_ROAR, // roar
- S_SCREAM, // scream
- S_BELLOW, // bellow (?)
- S_SCREECH, // screech
- S_BUZZ, // buzz
- S_MOAN, // moan
- S_WHINE, // irritating whine (mosquito)
- S_CROAK, // frog croak
- S_GROWL, // for bears
- S_HISS, // for snakes and lizards
- NUM_SHOUTS,
- S_RANDOM
-};
-
-// These are often addressed relative to each other (esp. delta SIZE_MEDIUM)
-enum size_type
-{
- SIZE_TINY, // rat/bat
- SIZE_LITTLE, // spriggan
- SIZE_SMALL, // halfling/kobold/gnome
- SIZE_MEDIUM, // human/elf/dwarf
- SIZE_LARGE, // troll/ogre
- SIZE_BIG, // centaur/naga/large quadrupeds
- SIZE_GIANT, // giant
- SIZE_HUGE, // dragon
- NUM_SIZE_LEVELS,
- SIZE_CHARACTER // transformations that don't change size
-};
-
-enum skill_type
-{
- SK_FIGHTING, // 0
- SK_SHORT_BLADES,
- SK_LONG_SWORDS,
- SK_UNUSED_1, // SK_GREAT_SWORDS - now unused
- SK_AXES,
- SK_MACES_FLAILS, // 5
- SK_POLEARMS,
- SK_STAVES,
- SK_SLINGS,
- SK_BOWS,
- SK_CROSSBOWS, // 10
- SK_DARTS,
- SK_RANGED_COMBAT,
- SK_ARMOUR,
- SK_DODGING,
- SK_STEALTH, // 15
- SK_STABBING,
- SK_SHIELDS,
- SK_TRAPS_DOORS,
- SK_UNARMED_COMBAT, // 19
- SK_SPELLCASTING = 25, // 25
- SK_CONJURATIONS,
- SK_ENCHANTMENTS,
- SK_SUMMONINGS,
- SK_NECROMANCY,
- SK_TRANSLOCATIONS, // 30
- SK_TRANSMIGRATION,
- SK_DIVINATIONS,
- SK_FIRE_MAGIC,
- SK_ICE_MAGIC,
- SK_AIR_MAGIC, // 35
- SK_EARTH_MAGIC,
- SK_POISON_MAGIC,
- SK_INVOCATIONS,
- SK_EVOCATIONS,
- NUM_SKILLS, // must remain last regular member
-
- SK_BLANK_LINE, // used for skill output
- SK_COLUMN_BREAK, // used for skill output
- SK_NONE
-};
-
-enum special_armour_type
-{
- SPARM_NORMAL, // 0
- SPARM_RUNNING,
- SPARM_FIRE_RESISTANCE,
- SPARM_COLD_RESISTANCE,
- SPARM_POISON_RESISTANCE,
- SPARM_SEE_INVISIBLE, // 5
- SPARM_DARKNESS,
- SPARM_STRENGTH,
- SPARM_DEXTERITY,
- SPARM_INTELLIGENCE,
- SPARM_PONDEROUSNESS, // 10
- SPARM_LEVITATION,
- SPARM_MAGIC_RESISTANCE,
- SPARM_PROTECTION,
- SPARM_STEALTH,
- SPARM_RESISTANCE, // 15
- SPARM_POSITIVE_ENERGY,
- SPARM_ARCHMAGI,
- SPARM_PRESERVATION, // 18
- SPARM_RANDART_I = 25, // must remain at 25 for now - how high do they go? {dlb}
- SPARM_RANDART_II = 26, // 26
- SPARM_RANDART_III = 27, // 27
- SPARM_RANDART_IV = 28, // 28
- SPARM_RANDART_V = 29 // 29 - highest value found thus far {dlb}
-};
-
-enum special_missile_type // to separate from weapons in general {dlb}
-{
- SPMSL_NORMAL, // 0
- SPMSL_FLAME, // 1
- SPMSL_ICE, // 2
- SPMSL_POISONED, // 3 - from poison_ammo() enchantment {dlb}
- SPMSL_POISONED_II, // 4
- SPMSL_CURARE // 5
-};
-
-enum special_room_type
-{
- SROOM_LAIR_ORC, // 0
- SROOM_LAIR_KOBOLD,
- SROOM_TREASURY,
- SROOM_BEEHIVE,
- SROOM_JELLY_PIT,
- SROOM_MORGUE,
- NUM_SPECIAL_ROOMS // 5 - must remain final member {dlb}
-};
-
-enum special_ring_type // jewellery mitm[].special values
-{
- SPRING_RANDART = 200,
- SPRING_UNRANDART = 201
-};
-
-// order is important on these (see player_speed())
-enum speed_type
-{
- SPEED_SLOWED,
- SPEED_NORMAL,
- SPEED_HASTED
-};
-
-enum brand_type // equivalent to (you.inv[].special or mitm[].special) % 30
-{
- SPWPN_NORMAL, // 0
- SPWPN_FLAMING,
- SPWPN_FREEZING,
- SPWPN_HOLY_WRATH,
- SPWPN_ELECTROCUTION,
- SPWPN_ORC_SLAYING, // 5
- SPWPN_VENOM,
- SPWPN_PROTECTION,
- SPWPN_DRAINING,
- SPWPN_SPEED,
- SPWPN_VORPAL, // 10
- SPWPN_FLAME,
- SPWPN_FROST,
- SPWPN_VAMPIRICISM,
- SPWPN_DISRUPTION,
- SPWPN_PAIN, // 15
- SPWPN_DISTORTION,
- SPWPN_REACHING, // 17
- SPWPN_CONFUSE,
- SPWPN_RANDART_I = 25, // 25
- SPWPN_RANDART_II,
- SPWPN_RANDART_III,
- SPWPN_RANDART_IV,
- SPWPN_RANDART_V,
- NUM_SPECIAL_WEAPONS,
- SPWPN_DUMMY_CRUSHING, // ONLY TEMPORARY USAGE -- converts to VORPAL
-
- // everything above this point is a special artefact wield:
- SPWPN_SINGING_SWORD = 181, // 181
- SPWPN_WRATH_OF_TROG,
- SPWPN_SCYTHE_OF_CURSES,
- SPWPN_MACE_OF_VARIABILITY,
- SPWPN_GLAIVE_OF_PRUNE, // 185
- SPWPN_SCEPTRE_OF_TORMENT,
- SPWPN_SWORD_OF_ZONGULDROK,
-
- // these three are not generated randomly {dlb}
- SPWPN_SWORD_OF_CEREBOV,
- SPWPN_STAFF_OF_DISPATER,
- SPWPN_SCEPTRE_OF_ASMODEUS, // 190
-
- SPWPN_SWORD_OF_POWER,
- SPWPN_KNIFE_OF_ACCURACY,
- SPWPN_STAFF_OF_OLGREB,
- SPWPN_VAMPIRES_TOOTH,
- SPWPN_STAFF_OF_WUCAD_MU // 195
-};
-
-enum special_wield_type // you.special_wield
-{
- SPWLD_NONE, // 0
- SPWLD_SING,
- SPWLD_TROG,
- SPWLD_CURSE,
- SPWLD_VARIABLE, // 4
- SPWLD_PRUNE, // 5 - implicit in it_use3::special_wielded() {dlb}
- SPWLD_TORMENT, // 6
- SPWLD_ZONGULDROK,
- SPWLD_POWER,
- SPWLD_WUCAD_MU, // 9
- SPWLD_OLGREB, // 10
- SPWLD_SHADOW = 50, // 50
- SPWLD_HUM, // 51 - see it_use3::special_wielded() {dlb}
- SPWLD_CHIME, // 52 - see it_use3::special_wielded() {dlb}
- SPWLD_BECKON, // 53 - see it_use3::special_wielded() {dlb}
- SPWLD_SHOUT // 54 - see it_use3::special_wielded() {dlb}
-};
-
-enum species_type
-{
- SP_HUMAN = 1, // 1
- SP_ELF,
- SP_HIGH_ELF,
- SP_GREY_ELF,
- SP_DEEP_ELF, // 5
- SP_SLUDGE_ELF,
- SP_HILL_DWARF,
- SP_MOUNTAIN_DWARF,
- SP_HALFLING,
- SP_HILL_ORC, // 10
- SP_KOBOLD,
- SP_MUMMY,
- SP_NAGA,
- SP_GNOME,
- SP_OGRE, // 15
- SP_TROLL,
- SP_OGRE_MAGE,
- SP_RED_DRACONIAN,
- SP_WHITE_DRACONIAN,
- SP_GREEN_DRACONIAN, // 20
- SP_GOLDEN_DRACONIAN,
- SP_GREY_DRACONIAN,
- SP_BLACK_DRACONIAN,
- SP_PURPLE_DRACONIAN,
- SP_MOTTLED_DRACONIAN, // 25
- SP_PALE_DRACONIAN,
- SP_UNK0_DRACONIAN,
- SP_UNK1_DRACONIAN,
- SP_BASE_DRACONIAN,
- SP_CENTAUR, // 30
- SP_DEMIGOD,
- SP_SPRIGGAN,
- SP_MINOTAUR,
- SP_DEMONSPAWN,
- SP_GHOUL, // 35
- SP_KENKU,
- SP_MERFOLK,
- NUM_SPECIES, // always after the last species
-
- SP_UNKNOWN = 100
-};
-
-enum spell_type
-{
- SPELL_IDENTIFY, // 0
- SPELL_TELEPORT_SELF,
- SPELL_CAUSE_FEAR,
- SPELL_CREATE_NOISE,
- SPELL_REMOVE_CURSE,
- SPELL_MAGIC_DART, // 5
- SPELL_FIREBALL,
- SPELL_SWAP,
- SPELL_APPORTATION,
- SPELL_TWIST,
- SPELL_FAR_STRIKE, // 10
- SPELL_DELAYED_FIREBALL,
- SPELL_STRIKING,
- SPELL_CONJURE_FLAME,
- SPELL_DIG,
- SPELL_BOLT_OF_FIRE, // 15
- SPELL_BOLT_OF_COLD,
- SPELL_LIGHTNING_BOLT,
- SPELL_BOLT_OF_MAGMA, // 18
- SPELL_POLYMORPH_OTHER = 20, // 20
- SPELL_SLOW,
- SPELL_HASTE,
- SPELL_PARALYZE,
- SPELL_CONFUSE,
- SPELL_INVISIBILITY, // 25
- SPELL_THROW_FLAME,
- SPELL_THROW_FROST,
- SPELL_CONTROLLED_BLINK,
- SPELL_FREEZING_CLOUD,
- SPELL_MEPHITIC_CLOUD, // 30
- SPELL_RING_OF_FLAMES,
- SPELL_RESTORE_STRENGTH,
- SPELL_RESTORE_INTELLIGENCE,
- SPELL_RESTORE_DEXTERITY,
- SPELL_VENOM_BOLT, // 35
- SPELL_OLGREBS_TOXIC_RADIANCE,
- SPELL_TELEPORT_OTHER,
- SPELL_LESSER_HEALING,
- SPELL_GREATER_HEALING,
- SPELL_CURE_POISON_I, // 40
- SPELL_PURIFICATION,
- SPELL_DEATHS_DOOR,
- SPELL_SELECTIVE_AMNESIA,
- SPELL_MASS_CONFUSION,
- SPELL_SMITING, // 45
- SPELL_REPEL_UNDEAD,
- SPELL_HOLY_WORD,
- SPELL_DETECT_CURSE,
- SPELL_SUMMON_SMALL_MAMMAL,
- SPELL_ABJURATION_I, // 50
- SPELL_SUMMON_SCORPIONS,
- SPELL_LEVITATION,
- SPELL_BOLT_OF_DRAINING,
- SPELL_LEHUDIBS_CRYSTAL_SPEAR,
- SPELL_BOLT_OF_INACCURACY, // 55
- SPELL_POISONOUS_CLOUD,
- SPELL_FIRE_STORM,
- SPELL_DETECT_TRAPS,
- SPELL_BLINK,
- SPELL_ISKENDERUNS_MYSTIC_BLAST, // 60
- SPELL_SWARM,
- SPELL_SUMMON_HORRIBLE_THINGS,
- SPELL_ENSLAVEMENT,
- SPELL_MAGIC_MAPPING,
- SPELL_HEAL_OTHER, // 65
- SPELL_ANIMATE_DEAD,
- SPELL_PAIN,
- SPELL_EXTENSION,
- SPELL_CONTROL_UNDEAD,
- SPELL_ANIMATE_SKELETON, // 70
- SPELL_VAMPIRIC_DRAINING,
- SPELL_SUMMON_WRAITHS,
- SPELL_DETECT_ITEMS,
- SPELL_BORGNJORS_REVIVIFICATION,
- SPELL_BURN, // 75
- SPELL_FREEZE,
- SPELL_SUMMON_ELEMENTAL,
- SPELL_OZOCUBUS_REFRIGERATION,
- SPELL_STICKY_FLAME,
- SPELL_SUMMON_ICE_BEAST, // 80
- SPELL_OZOCUBUS_ARMOUR,
- SPELL_CALL_IMP,
- SPELL_REPEL_MISSILES,
- SPELL_BERSERKER_RAGE,
- SPELL_DISPEL_UNDEAD, // 85
- SPELL_GUARDIAN,
- SPELL_PESTILENCE,
- SPELL_THUNDERBOLT,
- SPELL_FLAME_OF_CLEANSING,
- SPELL_SHINING_LIGHT, // 90
- SPELL_SUMMON_DAEVA,
- SPELL_ABJURATION_II,
- SPELL_FULSOME_DISTILLATION, // 93
- SPELL_POISON_ARROW, // 94
- SPELL_TWISTED_RESURRECTION = 110, // 110
- SPELL_REGENERATION,
- SPELL_BONE_SHARDS,
- SPELL_BANISHMENT,
- SPELL_CIGOTUVIS_DEGENERATION,
- SPELL_STING, // 115
- SPELL_SUBLIMATION_OF_BLOOD,
- SPELL_TUKIMAS_DANCE,
- SPELL_HELLFIRE,
- SPELL_SUMMON_DEMON,
- SPELL_DEMONIC_HORDE, // 120
- SPELL_SUMMON_GREATER_DEMON,
- SPELL_CORPSE_ROT,
- SPELL_TUKIMAS_VORPAL_BLADE,
- SPELL_FIRE_BRAND,
- SPELL_FREEZING_AURA, // 125
- SPELL_LETHAL_INFUSION,
- SPELL_CRUSH,
- SPELL_BOLT_OF_IRON,
- SPELL_STONE_ARROW,
- SPELL_TOMB_OF_DOROKLOHE, // 130
- SPELL_STONEMAIL,
- SPELL_SHOCK,
- SPELL_SWIFTNESS,
- SPELL_FLY,
- SPELL_INSULATION, // 135
- SPELL_ORB_OF_ELECTROCUTION,
- SPELL_DETECT_CREATURES,
- SPELL_CURE_POISON_II,
- SPELL_CONTROL_TELEPORT,
- SPELL_POISON_AMMUNITION, // 140
- SPELL_POISON_WEAPON,
- SPELL_RESIST_POISON,
- SPELL_PROJECTED_NOISE,
- SPELL_ALTER_SELF,
- SPELL_DEBUGGING_RAY, // 145
- SPELL_RECALL,
- SPELL_PORTAL,
- SPELL_AGONY,
- SPELL_SPIDER_FORM,
- SPELL_DISRUPT, // 150
- SPELL_DISINTEGRATE,
- SPELL_BLADE_HANDS,
- SPELL_STATUE_FORM,
- SPELL_ICE_FORM,
- SPELL_DRAGON_FORM, // 155
- SPELL_NECROMUTATION,
- SPELL_DEATH_CHANNEL,
- SPELL_SYMBOL_OF_TORMENT,
- SPELL_DEFLECT_MISSILES,
- SPELL_ORB_OF_FRAGMENTATION, // 160
- SPELL_ICE_BOLT,
- SPELL_ICE_STORM,
- SPELL_ARC,
- SPELL_AIRSTRIKE,
- SPELL_SHADOW_CREATURES, // 165
- SPELL_CONFUSING_TOUCH,
- SPELL_SURE_BLADE,
-//jmf: new spells
- SPELL_FLAME_TONGUE,
- SPELL_PASSWALL,
- SPELL_IGNITE_POISON, // 170
- SPELL_STICKS_TO_SNAKES,
- SPELL_SUMMON_LARGE_MAMMAL, // e.g. hound
- SPELL_SUMMON_DRAGON,
- SPELL_TAME_BEASTS, // charm/enslave but only animals
- SPELL_SLEEP, // 175
- SPELL_MASS_SLEEP,
- SPELL_DETECT_MAGIC, //jmf: unfinished, perhaps useless
- SPELL_DETECT_SECRET_DOORS,
- SPELL_SEE_INVISIBLE,
- SPELL_FORESCRY, // 180
- SPELL_SUMMON_BUTTERFLIES,
- SPELL_WARP_BRAND,
- SPELL_SILENCE,
- SPELL_SHATTER,
- SPELL_DISPERSAL, // 185
- SPELL_DISCHARGE,
- SPELL_BEND,
- SPELL_BACKLIGHT,
- SPELL_INTOXICATE, // confusion but only "smart" creatures
- SPELL_GLAMOUR, // charm/confuse/sleep but only "smart" creatures 190
- SPELL_EVAPORATE, // turn a potion into a cloud
- SPELL_ERINGYAS_SURPRISING_BOUQUET, // turn sticks into herbivore food
- SPELL_FRAGMENTATION, // replacement for "orb of frag"
- SPELL_AIR_WALK, // "dematerialize" (air/transmigration)
- SPELL_SANDBLAST, // mini-frag; can use stones for material comp 195
- SPELL_ROTTING, // evil god power or necromantic transmigration
- SPELL_MAXWELLS_SILVER_HAMMER, // vorpal-brand maces etc.
- SPELL_CONDENSATION_SHIELD, // "shield" of icy vapour
- SPELL_SEMI_CONTROLLED_BLINK, //jmf: to test effect
- SPELL_STONESKIN, // 200
- SPELL_SIMULACRUM,
- SPELL_CONJURE_BALL_LIGHTNING,
- SPELL_CHAIN_LIGHTNING, // 203 (be wary of 209/210, see below)
- NUM_SPELLS,
- SPELL_NO_SPELL = 210 // 210 - added 22jan2000 {dlb}
-};
-
-enum spflag_type
-{
- SPFLAG_NONE = 0x0000,
- SPFLAG_DIR_OR_TARGET = 0x0001, // use DIR_NONE targeting
- SPFLAG_TARGET = 0x0002, // use DIR_TARGET targeting
- SPFLAG_GRID = 0x0004, // use DIR_GRID targeting
- SPFLAG_DIR = 0x0008, // use DIR_DIR targeting
- SPFLAG_TARGETING_MASK = 0x000f, // used to test for targeting
- SPFLAG_HELPFUL = 0x0010, // TARG_FRIENDS used
- SPFLAG_NOT_SELF = 0x0020, // aborts on isMe
- SPFLAG_UNHOLY = 0x0040 // counts at "unholy"
-};
-
-enum spret_type
-{
- SPRET_ABORT = 0, // should be left as 0
- SPRET_FAIL,
- SPRET_SUCCESS
-};
-
-enum spschool_flag_type
-{
- SPTYP_NONE = 0, // "0" is reserved for no type at all {dlb}
- SPTYP_CONJURATION = 1, // was 11, but only for old typematch routine {dlb}
- SPTYP_ENCHANTMENT = 1<<1,
- SPTYP_FIRE = 1<<2,
- SPTYP_ICE = 1<<3,
- SPTYP_TRANSMIGRATION = 1<<4,
- SPTYP_NECROMANCY = 1<<5,
- SPTYP_SUMMONING = 1<<6,
- SPTYP_DIVINATION = 1<<7,
- SPTYP_TRANSLOCATION = 1<<8,
- SPTYP_POISON = 1<<9,
- SPTYP_EARTH = 1<<10,
- SPTYP_AIR = 1<<11,
- SPTYP_HOLY = 1<<12, //jmf: moved to accomodate "random" miscast f/x
- SPTYP_LAST_EXPONENT = 12, //jmf: ``NUM_SPELL_TYPES'' kinda useless
- NUM_SPELL_TYPES = 14,
- SPTYP_RANDOM = 1<<14
-};
-
-enum slot_select_mode
-{
- SS_FORWARD = 0,
- SS_BACKWARD = 1
-};
-
-enum stat_type
-{
- STAT_STRENGTH, // 0
- STAT_DEXTERITY,
- STAT_INTELLIGENCE,
- NUM_STATS, // added for increase_stats() {dlb}
- STAT_ALL, // must remain after NUM_STATS -- added to handle royal jelly, etc. {dlb}
- STAT_RANDOM = 255 // leave at 255, added for increase_stats() handling {dlb}
-};
-
-enum statue_type
-{
- STATUE_SILVER,
- STATUE_ORANGE_CRYSTAL,
- NUM_STATUE_TYPES
-};
-
-enum status_redraw_flag_type
-{
- REDRAW_HUNGER = 0x00000001,
- REDRAW_BURDEN = 0x00000002,
- REDRAW_LINE_1_MASK = 0x00000003,
-
- REDRAW_PRAYER = 0x00000100,
- REDRAW_REPEL_UNDEAD = 0x00000200,
- REDRAW_BREATH = 0x00000400,
- REDRAW_REPEL_MISSILES = 0x00000800,
- REDRAW_REGENERATION = 0x00001000,
- REDRAW_INSULATION = 0x00002000,
- REDRAW_FLY = 0x00004000,
- REDRAW_INVISIBILITY = 0x00008000,
- REDRAW_LINE_2_MASK = 0x0000ff00,
-
- REDRAW_CONFUSION = 0x00010000,
- REDRAW_POISONED = 0x00020000,
- REDRAW_LIQUID_FLAMES = 0x00040000,
- REDRAW_DISEASED = 0x00080000,
- REDRAW_CONTAMINATED = 0x00100000,
- REDRAW_SWIFTNESS = 0x00200000,
- REDRAW_SPEED = 0x00400000,
- REDRAW_LINE_3_MASK = 0x007f0000
-};
-
-enum stave_type
-{
- STAFF_WIZARDRY, // 0
- STAFF_POWER,
- STAFF_FIRE,
- STAFF_COLD,
- STAFF_POISON,
- STAFF_ENERGY, // 5
- STAFF_DEATH,
- STAFF_CONJURATION,
- STAFF_ENCHANTMENT,
- STAFF_SUMMONING,
- STAFF_SMITING, // 10
- STAFF_SPELL_SUMMONING,
- STAFF_DESTRUCTION_I,
- STAFF_DESTRUCTION_II,
- STAFF_DESTRUCTION_III,
- STAFF_DESTRUCTION_IV, // 15
- STAFF_WARDING,
- STAFF_DISCOVERY,
- STAFF_DEMONOLOGY, // 18
- STAFF_STRIKING, // 19
- STAFF_AIR = 25, // 25
- STAFF_EARTH,
- STAFF_CHANNELING,
- NUM_STAVES // must remain last member {dlb}
-};
-
-// beam[].type - note that this (and its variants) also accepts values from other enums - confusing {dlb}
-enum zap_symbol_type
-{
- SYM_SPACE = ' ', // 32
- SYM_FLASK = '!', // 33
- SYM_BOLT = '#', // 35
- SYM_CHUNK = '%', // 37
- SYM_OBJECT = '(', // 40 - actually used for books, but... {dlb}
- SYM_WEAPON = ')', // 41
- SYM_ZAP = '*', // 42
- SYM_BURST = '+', // 43
- SYM_STICK = '/', // 47
- SYM_TRINKET = '=', // 61
- SYM_SCROLL = '?', // 63
- SYM_DEBUG = 'X', // 88
- SYM_ARMOUR = '[', // 91
- SYM_MISSILE = '`', // 96
- SYM_EXPLOSION = '#'
-};
-
-enum tag_type // used during save/load process to identify data blocks
-{
- TAG_VERSION = 0, // should NEVER be read in!
- TAG_YOU = 1, // 'you' structure
- TAG_YOU_ITEMS, // your items
- TAG_YOU_DUNGEON, // dungeon specs (stairs, branches, features)
- TAG_LEVEL, // various grids & clouds
- TAG_LEVEL_ITEMS, // items/traps
- TAG_LEVEL_MONSTERS, // monsters
- TAG_GHOST, // ghost
- TAG_LEVEL_ATTITUDE, // monster attitudes
- NUM_TAGS
-};
-
-enum tag_file_type // file types supported by tag system
-{
- TAGTYPE_PLAYER=0, // Foo.sav
- TAGTYPE_LEVEL, // Foo.00a, .01a, etc.
- TAGTYPE_GHOST // bones.xxx
-};
-
-
-enum transformation_type
-{
- TRAN_NONE, // 0
- TRAN_SPIDER,
- TRAN_BLADE_HANDS,
- TRAN_STATUE,
- TRAN_ICE_BEAST,
- TRAN_DRAGON, // 5
- TRAN_LICH,
- TRAN_SERPENT_OF_HELL,
- TRAN_AIR,
- NUM_TRANSFORMATIONS // must remain last member {dlb}
-};
-
-enum trap_type // env.trap_type[]
-{
- TRAP_DART, // 0
- TRAP_ARROW,
- TRAP_SPEAR,
- TRAP_AXE,
- TRAP_TELEPORT,
- TRAP_AMNESIA, // 5
- TRAP_BLADE,
- TRAP_BOLT,
- TRAP_ZOT,
- TRAP_NEEDLE,
- NUM_TRAPS, // must remain last 'regular' member {dlb}
- TRAP_UNASSIGNED = 100, // keep set at 100 for now {dlb}
- TRAP_NONTELEPORT = 254,
- TRAP_RANDOM = 255 // set at 255 to avoid potential conflicts {dlb}
-};
-
-enum unarmed_attack_type
-{
- UNAT_NO_ATTACK, // 0
- UNAT_KICK,
- UNAT_HEADBUTT,
- UNAT_TAILSLAP,
- UNAT_PUNCH
-};
-
-enum undead_state_type // you.is_undead
-{
- US_ALIVE, // 0
- US_HUNGRY_DEAD,
- US_UNDEAD
-};
-
-enum unique_item_status_type
-{
- UNIQ_NOT_EXISTS = 0,
- UNIQ_EXISTS = 1,
- UNIQ_LOST_IN_ABYSS = 2
-};
-
-// NOTE: THE ORDER AND VALUE OF THESE IS CURRENTLY VERY IMPORTANT!
-enum vault_type
-{
- VAULT_VAULT_1 = 0,
- VAULT_VAULT_2 = 1,
- VAULT_VAULT_3 = 2,
- VAULT_VAULT_4 = 3,
- VAULT_VAULT_5 = 4,
- VAULT_VAULT_6 = 5,
- VAULT_VAULT_7 = 6,
- VAULT_VAULT_8 = 7,
- VAULT_VAULT_9 = 8,
- VAULT_VAULT_10 = 9,
- VAULT_ORC_TEMPLE = 10,
- VAULT_FARM_AND_COUNTRY = 11,
- VAULT_FORT_YAKTAUR = 12,
- VAULT_BOX_LEVEL = 13,
- VAULT_MY_MAP = 14,
-
- VAULT_VESTIBULE_MAP = 50,
- VAULT_CASTLE_DIS = 51,
- VAULT_ASMODEUS = 52,
- VAULT_ANTAEUS = 53,
- VAULT_ERESHKIGAL = 54,
-
- VAULT_MNOLEG = 60,
- VAULT_LOM_LOBON = 61,
- VAULT_CEREBOV = 62,
- VAULT_GLOORX_VLOQ = 63,
- // VAULT_MOLLUSC = 64,
-
- VAULT_BEEHIVE = 80,
- VAULT_SLIME_PIT = 81,
- VAULT_BOTTOM_OF_VAULTS = 82,
- VAULT_HALL_OF_BLADES = 83,
- VAULT_HALL_OF_ZOT = 84,
- VAULT_TEMPLE = 85,
- VAULT_SNAKE_PIT = 86,
- VAULT_ELF_HALL = 87,
- VAULT_TOMB_1 = 88,
- VAULT_TOMB_2 = 89,
- VAULT_TOMB_3 = 90,
- VAULT_SWAMP = 91,
-
- VAULT_RANDOM = 100,
-
- VAULT_MINIVAULT_1 = 200,
- VAULT_MINIVAULT_2 = 201,
- VAULT_MINIVAULT_3 = 202,
- VAULT_MINIVAULT_4 = 203,
- VAULT_MINIVAULT_5 = 204,
- VAULT_MINIVAULT_6 = 205,
- VAULT_MINIVAULT_7 = 206,
- VAULT_MINIVAULT_8 = 207,
- VAULT_MINIVAULT_9 = 208,
- VAULT_MINIVAULT_10 = 209,
- VAULT_MINIVAULT_11 = 210,
- VAULT_MINIVAULT_12 = 211,
- VAULT_MINIVAULT_13 = 212,
- VAULT_MINIVAULT_14 = 213,
- VAULT_MINIVAULT_15 = 214,
- VAULT_MINIVAULT_16 = 215,
- VAULT_MINIVAULT_17 = 216,
- VAULT_MINIVAULT_18 = 217,
- VAULT_MINIVAULT_19 = 218,
- VAULT_MINIVAULT_20 = 219,
- VAULT_MINIVAULT_21 = 220,
- VAULT_MINIVAULT_22 = 221,
- VAULT_MINIVAULT_23 = 222,
- VAULT_MINIVAULT_24 = 223,
- VAULT_MINIVAULT_25 = 224,
- VAULT_MINIVAULT_26 = 225,
- VAULT_MINIVAULT_27 = 226,
- VAULT_MINIVAULT_28 = 227,
- VAULT_MINIVAULT_29 = 228,
- VAULT_MINIVAULT_30 = 229,
- VAULT_MINIVAULT_31 = 230,
- VAULT_MINIVAULT_32 = 231,
- VAULT_MINIVAULT_33 = 232,
- VAULT_MINIVAULT_34 = 233,
- VAULT_MINIVAULT_35 = 234,
-
- VAULT_RAND_DEMON_1 = 300,
- VAULT_RAND_DEMON_2 = 301,
- VAULT_RAND_DEMON_3 = 302,
- VAULT_RAND_DEMON_4 = 303,
- VAULT_RAND_DEMON_5 = 304,
- VAULT_RAND_DEMON_6 = 305,
- VAULT_RAND_DEMON_7 = 306,
- VAULT_RAND_DEMON_8 = 307,
- VAULT_RAND_DEMON_9 = 308
-};
-
-enum vorpal_damage_type
-{
- // Types of damage a weapon can do... currently assuming that anything
- // with BLUDGEON always does "AND" with any other specified types,
- // and and sets not including BLUDGEON are "OR".
- DAM_BASH = 0x0000, // non-melee weapon blugeoning
- DAM_BLUDGEON = 0x0001, // crushing
- DAM_SLICE = 0x0002, // slicing/chopping
- DAM_PIERCE = 0x0004, // stabbing/piercing
- DAM_WHIP = 0x0008, // whip slashing (no butcher)
-
- // These are used for vorpal weapon desc (don't set more than one)
- DVORP_NONE = 0x0000, // used for non-melee weapons
- DVORP_CRUSHING = 0x1000,
- DVORP_SLICING = 0x2000,
- DVORP_PIERCING = 0x3000,
- DVORP_CHOPPING = 0x4000, // used for axes
- DVORP_SLASHING = 0x5000, // used for whips
- DVORP_STABBING = 0x6000, // used for knives/daggers
-
- // These are shortcuts to tie vorpal/damage types for easy setting...
- // as above, setting more than one vorpal type is trouble.
- DAMV_NON_MELEE = DVORP_NONE | DAM_BASH, // launchers
- DAMV_CRUSHING = DVORP_CRUSHING | DAM_BLUDGEON,
- DAMV_SLICING = DVORP_SLICING | DAM_SLICE,
- DAMV_PIERCING = DVORP_PIERCING | DAM_PIERCE,
- DAMV_CHOPPING = DVORP_CHOPPING | DAM_SLICE,
- DAMV_SLASHING = DVORP_SLASHING | DAM_WHIP,
- DAMV_STABBING = DVORP_STABBING | DAM_PIERCE,
-
- DAM_MASK = 0x0fff, // strips vorpal specification
- DAMV_MASK = 0xf000 // strips non-vorpal specification
-};
-
-// NOTE: This order is very special! Its basically the same as ZAP_*,
-// and there are bits of the code that still use that fact.. see zap_wand().
-enum wand_type // mitm[].subtype
-{
- WAND_FLAME, // 0
- WAND_FROST,
- WAND_SLOWING,
- WAND_HASTING,
- WAND_MAGIC_DARTS,
- WAND_HEALING, // 5
- WAND_PARALYSIS,
- WAND_FIRE,
- WAND_COLD,
- WAND_CONFUSION,
- WAND_INVISIBILITY, // 10
- WAND_DIGGING,
- WAND_FIREBALL,
- WAND_TELEPORTATION,
- WAND_LIGHTNING,
- WAND_POLYMORPH_OTHER, // 15
- WAND_ENSLAVEMENT,
- WAND_DRAINING,
- WAND_RANDOM_EFFECTS,
- WAND_DISINTEGRATION,
- NUM_WANDS // must remain last member {dlb}
-};
-
-enum weapon_type
-{
-// Base weapons
- WPN_CLUB, // 0
- WPN_MACE,
- WPN_FLAIL,
- WPN_DAGGER,
- WPN_MORNINGSTAR,
- WPN_SHORT_SWORD, // 5
- WPN_LONG_SWORD,
- WPN_GREAT_SWORD,
- WPN_SCIMITAR,
- WPN_HAND_AXE,
- WPN_BATTLEAXE, // 10
- WPN_SPEAR,
- WPN_HALBERD,
- WPN_SLING,
- WPN_BOW,
- WPN_CROSSBOW, // 15
- WPN_HAND_CROSSBOW,
- WPN_GLAIVE,
- WPN_QUARTERSTAFF,
-// these three not created ordinarily
- WPN_SCYTHE,
- WPN_GIANT_CLUB, // 20
- WPN_GIANT_SPIKED_CLUB,
-// "rare" weapons - some have special cases and are uncommon
- WPN_EVENINGSTAR,
- WPN_QUICK_BLADE,
- WPN_KATANA,
- WPN_EXECUTIONERS_AXE, // 25
- WPN_DOUBLE_SWORD,
- WPN_TRIPLE_SWORD,
- WPN_HAMMER,
- WPN_ANCUS,
- WPN_WHIP, // 30
- WPN_SABRE,
- WPN_DEMON_BLADE,
- WPN_DEMON_WHIP,
- WPN_DEMON_TRIDENT,
- WPN_BROAD_AXE, // 35
-// base items (continued)
- WPN_WAR_AXE,
- WPN_TRIDENT,
- WPN_SPIKED_FLAIL,
- WPN_GREAT_MACE,
- WPN_DIRE_FLAIL, // 40
- WPN_KNIFE,
- WPN_BLOWGUN,
- WPN_FALCHION,
- WPN_BLESSED_BLADE, // 44
- WPN_LONGBOW,
- WPN_LAJATANG,
- WPN_LOCHABER_AXE,
-
- NUM_WEAPONS, // 48 - must be last regular member {dlb}
-
-// special cases
- WPN_UNARMED = 500, // 500
- WPN_UNKNOWN = 1000, // 1000
- WPN_RANDOM
-};
-
-enum weapon_description_type
-{
- DWPN_PLAIN = 0, // 0 - added to round out enum {dlb}
- DWPN_RUNED = 1, // 1
- DWPN_GLOWING,
- DWPN_ORCISH,
- DWPN_ELVEN,
- DWPN_DWARVEN // 5
-};
-
-enum weapon_property_type
-{
- PWPN_DAMAGE, // 0
- PWPN_HIT,
- PWPN_SPEED
-};
-
-#ifdef WIZARD
-
-enum wizard_option_type
-{
- WIZ_NEVER, // protect player from accidental wiz
- WIZ_NO, // don't start character in wiz mode
- WIZ_YES // start character in wiz mode
-};
-
-#endif
-
-enum zap_type
-{
- ZAP_FLAME, // 0
- ZAP_FROST,
- ZAP_SLOWING,
- ZAP_HASTING,
- ZAP_MAGIC_DARTS,
- ZAP_HEALING, // 5
- ZAP_PARALYSIS,
- ZAP_FIRE,
- ZAP_COLD,
- ZAP_CONFUSION,
- ZAP_INVISIBILITY, // 10
- ZAP_DIGGING,
- ZAP_FIREBALL,
- ZAP_TELEPORTATION,
- ZAP_LIGHTNING,
- ZAP_POLYMORPH_OTHER, // 15
- ZAP_VENOM_BOLT,
- ZAP_NEGATIVE_ENERGY,
- ZAP_CRYSTAL_SPEAR,
- ZAP_BEAM_OF_ENERGY,
- ZAP_MYSTIC_BLAST, // 20
- ZAP_ENSLAVEMENT,
- ZAP_PAIN,
- ZAP_STICKY_FLAME,
- ZAP_DISPEL_UNDEAD,
- ZAP_CLEANSING_FLAME, // 25
- ZAP_BONE_SHARDS,
- ZAP_BANISHMENT,
- ZAP_DEGENERATION,
- ZAP_STING,
- ZAP_HELLFIRE, // 30
- ZAP_IRON_BOLT,
- ZAP_STRIKING,
- ZAP_STONE_ARROW,
- ZAP_ELECTRICITY,
- ZAP_ORB_OF_ELECTRICITY, // 35
- ZAP_SPIT_POISON,
- ZAP_DEBUGGING_RAY,
- ZAP_BREATHE_FIRE,
- ZAP_BREATHE_FROST,
- ZAP_BREATHE_ACID, // 40
- ZAP_BREATHE_POISON,
- ZAP_BREATHE_POWER,
- ZAP_ENSLAVE_UNDEAD,
- ZAP_AGONY,
- ZAP_DISRUPTION, // 45
- ZAP_DISINTEGRATION, // 46
- // ZAP_ISKS_CROSS, // 47: Isk's Cross -- commented out, deprecated {dlb}
- ZAP_BREATHE_STEAM = 48, // 48
- ZAP_CONTROL_DEMON,
- ZAP_ORB_OF_FRAGMENTATION, // 50
- ZAP_ICE_BOLT,
- ZAP_ICE_STORM,
- ZAP_BACKLIGHT, //jmf: added next bunch 19mar2000
- ZAP_SLEEP,
- ZAP_FLAME_TONGUE,
- ZAP_SANDBLAST,
- ZAP_SMALL_SANDBLAST,
- ZAP_MAGMA,
- ZAP_POISON_ARROW,
- ZAP_BREATHE_STICKY_FLAME,
- ZAP_BREATHE_LIGHTNING,
- ZAP_PETRIFY,
- ZAP_HELLFROST,
- NUM_ZAPS // must remain last member {dlb}
-};
-
-enum zombie_size_type
-{
- Z_NOZOMBIE,
- Z_SMALL,
- Z_BIG
-};
-
-#endif // ENUM_H
diff --git a/stone_soup/crawl-ref/source/externs.h b/stone_soup/crawl-ref/source/externs.h
deleted file mode 100644
index 525ec77614..0000000000
--- a/stone_soup/crawl-ref/source/externs.h
+++ /dev/null
@@ -1,850 +0,0 @@
-/*
- * File: externs.h
- * Summary: Fixed size 2D vector class that asserts if you do something bad.
- * Written by: Linley Henzell
- *
- * Modified for Crawl Reference by $Author$ on $Date$
- *
- * Change History (most recent first):
- *
- * <3> 7/29/00 JDJ Renamed sh_x, sh_y, sh_greed, sh_type, sh_level so
- * they start with shop.
- * <2> 7/29/00 JDJ Switched to using bounds checked array classes.
- * Made a few char arrays unsigned char arrays.
- */
-
-#ifndef EXTERNS_H
-#define EXTERNS_H
-
-#include <queue>
-#include <vector>
-#include <list>
-#include <string>
-
-#include <map>
-
-#include <time.h>
-
-#include "defines.h"
-#include "enum.h"
-#include "FixAry.h"
-#include "Kills.h"
-#include "libutil.h"
-#include "message.h"
-
-#define INFO_SIZE 200 // size of message buffers
-#define ITEMNAME_SIZE 200 // size of item names/shop names/etc
-#define HIGHSCORE_SIZE 800 // <= 10 Lines for long format scores
-
-#define MAX_NUM_GODS 21
-
-extern char info[INFO_SIZE]; // defined in acr.cc {dlb}
-
-extern unsigned char show_green; // defined in view.cc {dlb}
-
-// defined in mon-util.cc -- w/o this screen redraws *really* slow {dlb}
-extern FixedVector<unsigned short, 1000> mcolour;
-
-#ifdef SHORT_FILE_NAMES
- const int kNameLen = 30;
- const int kFileNameLen = 6;
- const int kFileNameSize = 5 + kFileNameLen;
-
-#else
- #ifdef SAVE_DIR_PATH
- // file name length has to be able to cover full paths -- bwross
- const int kNameLen = 30;
- const int kFileNameLen = 250;
- const int kFileNameSize = 5 + kFileNameLen;
- #else
- const int kNameLen = 30;
- const int kFileNameLen = 28;
- const int kFileNameSize = 5 + kFileNameLen;
- #endif
-#endif
-
-
-// Length of Path + File Name
-const int kPathLen = 256;
-
-// This value is used to mark that the current berserk is free from
-// penalty (Xom's granted or from a deck of cards).
-#define NO_BERSERK_PENALTY -1
-
-struct monsters;
-struct ait_hp_loss;
-
-struct activity_interrupt_data
-{
- activity_interrupt_payload_type apt;
- const void *data;
-
- activity_interrupt_data()
- : apt(AIP_NONE), data(NULL)
- {
- }
- activity_interrupt_data(const int *i)
- : apt(AIP_INT), data(i)
- {
- }
- activity_interrupt_data(const char *s)
- : apt(AIP_STRING), data(s)
- {
- }
- activity_interrupt_data(const std::string &s)
- : apt(AIP_STRING), data(s.c_str())
- {
- }
- activity_interrupt_data(const monsters *m)
- : apt(AIP_MONSTER), data(m)
- {
- }
- activity_interrupt_data(const ait_hp_loss *ahl)
- : apt(AIP_HP_LOSS), data(ahl)
- {
- }
- activity_interrupt_data(const activity_interrupt_data &a)
- : apt(a.apt), data(a.data)
- {
- }
-};
-
-struct ait_hp_loss
-{
- int hp;
- int hurt_type; // KILLED_BY_POISON, etc.
-
- ait_hp_loss(int _hp, int _ht) : hp(_hp), hurt_type(_ht) { }
-};
-
-struct coord_def
-{
- int x;
- int y;
-
- // coord_def( int x_in = 0, int y_in = 0 ) : x(x_in), y(y_in) {};
- bool operator == (const coord_def &other) const {
- return x == other.x && y == other.y;
- }
-
- bool operator != (const coord_def &other) const {
- return x != other.x || y != other.y;
- }
-};
-
-struct dice_def
-{
- int num;
- int size;
-
- dice_def( int n = 0, int s = 0 ) : num(n), size(s) {}
-};
-
-// output from direction() function:
-struct dist
-{
- bool isValid; // valid target chosen?
- bool isTarget; // target (true), or direction (false)?
- bool isMe; // selected self (convenience: tx == you.x_pos,
- // ty == you.y_pos)
- bool isCancel; // user cancelled (usually <ESC> key)
- int tx,ty; // target x,y or logical extension of beam to map edge
- int dx,dy; // delta x and y if direction - always -1,0,1
-
- // internal use - ignore
- int prev_target; // previous target
-};
-
-
-struct bolt
-{
- // INPUT parameters set by caller
- int range; // minimum range
- int rangeMax; // maximum range
- int type; // missile gfx
- int colour;
- int flavour;
- int source_x, source_y; // beam origin
- dice_def damage;
- int ench_power, hit;
- int target_x, target_y; // intended target
- char thrower; // what kind of thing threw this?
- char ex_size; // explosion radius (0==none)
- int beam_source; // NON_MONSTER or monster index #
- char beam_name[40];
- bool is_beam; // beams? (can hits multiple targets?)
- bool is_explosion;
- bool is_big_cloud; // expands into big_cloud at endpoint
- bool is_enchant; // no block/dodge, but mag resist
- bool is_energy; // mostly energy/non-physical attack
- bool is_launched; // was fired from launcher?
- bool is_thrown; // was thrown from hand?
- bool target_first; // targeting by direction
- const char *aux_source; // source of KILL_MISC beams
-
- // OUTPUT parameters (tracing, ID)
- bool obvious_effect; // did an 'obvious' effect happen?
- int fr_count, foe_count; // # of times a friend/foe is "hit"
- int fr_power, foe_power; // total levels/hit dice affected
-
- // INTERNAL use - should not usually be set outside of beam.cc
- bool is_tracer; // is this a tracer?
- bool aimed_at_feet; // this was aimed at self!
- bool msg_generated; // an appropriate msg was already mpr'd
- bool in_explosion_phase; // explosion phase (as opposed to beam phase)
- bool smart_monster; // tracer firer can guess at other mons. resists?
- bool can_see_invis; // tracer firer can see invisible?
- bool is_friendly; // tracer firer is enslaved or pet
- int foe_ratio; // 100* foe ratio (see mons_should_fire())
-
- // A contstructor to try and fix some of the bugs that occur because
- // this struct never seems to be properly initialized. Definition
- // is over in misc.cc for lack of a better place (short of inlining
- // it here).
- bolt();
-};
-
-
-struct run_check_dir
-{
- unsigned char grid;
- char dx;
- char dy;
-};
-
-
-struct delay_queue_item
-{
- int type;
- int duration;
- int parm1;
- int parm2;
-};
-
-
-struct item_def
-{
- unsigned char base_type; // basic class (ie OBJ_WEAPON)
- unsigned char sub_type; // type within that class (ie WPN_DAGGER)
- short plus; // +to hit, charges, corpse mon id
- short plus2; // +to dam, sub-sub type for boots and helms
- long special; // special stuff
- unsigned char colour; // item colour
- unsigned long flags; // item statuc flags
- short quantity; // number of items
-
- short x; // x-location; for inventory items = -1
- short y; // y-location; for inventory items = -1
- short link; // link to next item; for inventory items = slot
- short slot; // Inventory letter
-
- unsigned short orig_place;
- short orig_monnum;
-
- item_def() : base_type(0), sub_type(0), plus(0), plus2(0),
- special(0L), colour(0), flags(0L), quantity(0),
- x(0), y(0), link(0), slot(0), orig_place(0),
- orig_monnum(0)
- {
- }
-};
-
-class input_history
-{
-public:
- input_history(size_t size);
-
- void new_input(const std::string &s);
- void clear();
-
- const std::string *prev();
- const std::string *next();
-
- void go_end();
-private:
- typedef std::list<std::string> string_list;
-
- string_list history;
- string_list::iterator pos;
- size_t maxsize;
-};
-
-struct player
-{
- activity_type activity; // The current multiturn activity, usually set
- // to ACT_NONE
- char turn_is_over; // flag signaling that player has performed a timed action
-
- unsigned char prev_targ;
- char your_name[kNameLen];
-
- unsigned char species;
-
- char run_x;
- char run_y;
-
- // Coordinates of last travel target; note that this is never used by
- // travel itself, only by the level-map to remember the last travel target.
- short travel_x, travel_y;
-
- FixedVector< run_check_dir, 3 > run_check; // array of grids to check
- signed char running; // Nonzero if running/traveling.
-
- char special_wield;
- char deaths_door;
- char fire_shield;
-
- double elapsed_time; // total amount of elapsed time in the game
-
- unsigned char synch_time; // amount to wait before calling handle_time
-
- unsigned char disease;
-
- char max_level;
-
- int x_pos;
- int y_pos;
-
- int hunger;
- FixedVector<char, NUM_EQUIP> equip;
-
- int hp;
- int hp_max;
- int base_hp; // temporary max HP loss (rotting)
- int base_hp2; // base HPs from levels (and permanent loss)
-
- int magic_points;
- int max_magic_points;
- int base_magic_points; // temporary max MP loss? (currently unused)
- int base_magic_points2; // base MPs from levels and potions of magic
-
- char strength;
- char intel;
- char dex;
- char max_strength;
- char max_intel;
- char max_dex;
-
- char hunger_state;
-
- bool wield_change; // redraw weapon
-
- unsigned long redraw_status_flags;
- char redraw_hit_points;
- char redraw_magic_points;
- char redraw_strength;
- char redraw_intelligence;
- char redraw_dexterity;
- char redraw_experience;
- char redraw_armour_class;
-
- char redraw_gold;
- char redraw_evasion;
-
- unsigned char flash_colour;
-
- unsigned char hit_points_regeneration;
- unsigned char magic_points_regeneration;
-
- unsigned long experience;
- int experience_level;
- unsigned int gold;
- int char_class;
- char class_name[30];
- // char speed; // now unused
- int time_taken;
-
- char shield_blocks; // number of shield blocks since last action
-
- FixedVector< item_def, ENDOFPACK > inv;
-
- int burden;
- char burden_state;
- FixedVector<unsigned char, 25> spells;
- char spell_no;
- unsigned char char_direction; //
-
- unsigned char pet_target;
-
- int your_level; // offset by one (-1 == 0, 0 == 1, etc.) for display
-
- // durational things. Why didn't I do this for haste etc
- // right from the start? Oh well.
- FixedVector<int, NUM_DURATIONS> duration;
-
- int invis;
- int conf;
- int paralysis;
- int slow;
- int haste;
- int might;
- int levitation;
-
- int poison;
- int rotting;
- int berserker;
-
- int exhausted; // fatigue counter for berserk
-
- int berserk_penalty; // pelnalty for moving while berserk
-
- FixedVector<unsigned char, 30> attribute; // see ATTRIBUTES in enum.h
-
- char is_undead; // see UNDEAD_STATES in enum.h
-
- std::queue< delay_queue_item > delay_queue; // pending actions
-
- FixedVector<unsigned char, 50> skills;
- FixedVector<unsigned char, 50> practise_skill;
- FixedVector<unsigned int, 50> skill_points;
- FixedVector<unsigned char, 50> skill_order;
- int skill_cost_level;
- int total_skill_points;
- int exp_available;
-
- FixedArray<unsigned char, 5, 50> item_description;
- FixedVector<unsigned char, 50> unique_items;
- FixedVector<unsigned char, 50> unique_creatures;
-
- KillMaster kills;
-
- char level_type;
-
- char where_are_you;
-
- FixedVector<unsigned char, 30> branch_stairs;
-
- char religion;
- unsigned char piety;
- unsigned char gift_timeout;
- FixedVector<unsigned char, MAX_NUM_GODS> penance;
- FixedVector<unsigned char, MAX_NUM_GODS> worshipped;
- FixedVector<short, MAX_NUM_GODS> num_gifts;
-
-
- FixedVector<unsigned char, 100> mutation;
- FixedVector<unsigned char, 100> demon_pow;
- unsigned char magic_contamination;
-
- char confusing_touch;
- char sure_blade;
-
- FixedVector<unsigned char, 50> had_book;
-
- unsigned char betrayal;
- unsigned char normal_vision; // how far the species gets to see
- unsigned char current_vision; // current sight radius (cells)
-
- unsigned char hell_exit; // which level plyr goes to on hell exit.
-
- // This field is here even in non-WIZARD compiles, since the
- // player might have been playing previously under wiz mode.
- bool wizard; // true if player has entered wiz mode.
- time_t birth_time; // start time of game
-
- time_t start_time; // start time of session
- long real_time; // real time played (in seconds)
- long num_turns; // number of turns taken
-
- int old_hunger; // used for hunger delta-meter (see output.cc)
-
- // Warning: these two are quite different.
- //
- // The spell table is an index to a specific spell slot (you.spells).
- // The ability table lists the ability (ABIL_*) which prefers that letter.
- //
- // In other words, the spell table contains hard links and the ability
- // table contains soft links.
- FixedVector<int, 52> spell_letter_table; // ref to spell by slot
- FixedVector<int, 52> ability_letter_table; // ref to ability by enum
-};
-
-extern struct player you;
-
-struct monsters
-{
- int type;
- int hit_points;
- int max_hit_points;
- int hit_dice;
- int armour_class; // great -- more mixed american/proper spelling
- int evasion;
- unsigned int speed;
- unsigned int speed_increment;
- unsigned char x;
- unsigned char y;
- unsigned char target_x;
- unsigned char target_y;
- FixedVector<int, 8> inv;
- unsigned char attitude; // from MONS_ATTITUDE
- unsigned int behaviour;
- unsigned int foe;
- FixedVector<unsigned int, NUM_MON_ENCHANTS> enchantment;
- unsigned char flags; // bitfield of boolean flags
- unsigned int number; // #heads (hydra), etc.
- int foe_memory; // how long to 'remember' foe x,y
- // once they go out of sight
-};
-
-struct cloud_struct
-{
- unsigned char x;
- unsigned char y;
- unsigned char type;
- int decay;
-};
-
-struct shop_struct
-{
- unsigned char x;
- unsigned char y;
- unsigned char greed;
- unsigned char type;
- unsigned char level;
-
- FixedVector<unsigned char, 3> keeper_name;
-};
-
-struct trap_struct
-{
- unsigned char x;
- unsigned char y;
- unsigned char type;
-};
-
-struct crawl_environment
-{
- unsigned char rock_colour;
- unsigned char floor_colour;
-
- FixedVector< item_def, MAX_ITEMS > item; // item list
- FixedVector< monsters, MAX_MONSTERS > mons; // monster list
-
- FixedArray< unsigned char, GXM, GYM > grid; // terrain grid
- FixedArray< unsigned char, GXM, GYM > mgrid; // monster grid
- FixedArray< int, GXM, GYM > igrid; // item grid
- FixedArray< unsigned char, GXM, GYM > cgrid; // cloud grid
-
- FixedArray< unsigned short, GXM, GYM > map; // discovered terrain
-
- FixedArray< unsigned int, 19, 19> show; // view window char
- FixedArray< unsigned short, 19, 19> show_col; // view window colour
-
- FixedVector< cloud_struct, MAX_CLOUDS > cloud; // cloud list
- unsigned char cloud_no;
-
- FixedVector< shop_struct, MAX_SHOPS > shop; // shop list
- FixedVector< trap_struct, MAX_TRAPS > trap; // trap list
-
- FixedVector< int, 20 > mons_alloc;
- int trap_known;
- double elapsed_time; // used during level load
-};
-
-extern struct crawl_environment env;
-
-
-struct ghost_struct
-{
- char name[20];
- FixedVector< short, NUM_GHOST_VALUES > values;
-};
-
-
-extern struct ghost_struct ghost;
-
-
-extern void (*viewwindow) (char, bool);
-
-
-struct system_environment
-{
- char *crawl_name;
- char *crawl_pizza;
- char *crawl_rc;
- char *crawl_dir;
- char *home; // only used by MULTIUSER systems
- bool board_with_nail; // Easter Egg silliness
-};
-
-extern system_environment SysEnv;
-
-struct message_filter
-{
- int channel; // Use -1 to match any channel.
- text_pattern pattern; // Empty pattern matches any message
-
- message_filter( int ch, const std::string &s )
- : channel(ch), pattern(s)
- {
- }
-
- message_filter( const std::string &s ) : channel(-1), pattern(s) { }
-
- bool is_filtered( int ch, const std::string &s ) const {
- bool channel_match = ch == channel || channel == -1;
- if (!channel_match || pattern.empty())
- return channel_match;
- return pattern.matches(s);
- }
-
-};
-
-struct sound_mapping
-{
- text_pattern pattern;
- std::string soundfile;
-};
-
-struct colour_mapping
-{
- text_pattern pattern;
- int colour;
-};
-
-class formatted_string
-{
-public:
- formatted_string() : ops() { }
- formatted_string(const std::string &s);
-
- operator std::string() const;
- void display(int start = 0, int end = -1) const;
- std::string tostring(int start = 0, int end = -1) const;
-
- void cprintf(const char *s, ...);
- void cprintf(const std::string &s);
- void gotoxy(int x, int y);
- void textcolor(int color);
-
-private:
- enum fs_op_type
- {
- FSOP_COLOUR,
- FSOP_CURSOR,
- FSOP_TEXT
- };
-
- struct fs_op
- {
- fs_op_type type;
- int x, y;
- std::string text;
-
- fs_op(int color)
- : type(FSOP_COLOUR), x(color), y(-1), text()
- {
- }
-
- fs_op(int cx, int cy)
- : type(FSOP_CURSOR), x(cx), y(cy), text()
- {
- }
-
- fs_op(const std::string &s)
- : type(FSOP_TEXT), x(-1), y(-1), text(s)
- {
- }
-
- operator fs_op_type () const
- {
- return type;
- }
- void display() const;
- };
-
- std::vector<fs_op> ops;
-};
-
-struct game_options
-{
- bool ascii_display; // Defaults to true ifdef USE_ASCII_CHARACTERS
- long autopickups; // items to autopickup
- bool verbose_dump; // make character dumps contain more detail
- bool detailed_stat_dump; // add detailed stat and resist dump
- bool colour_map; // add colour to the map
- bool clean_map; // remove unseen clouds/monsters
- bool show_uncursed; // label known uncursed items as "uncursed"
- bool always_greet; // display greeting message when reloading
- bool easy_open; // open doors with movement
- bool easy_armour; // allow auto-removing of armour
- bool easy_butcher; // open doors with movement
- int easy_confirm; // make yesno() confirming easier
- int easy_quit_item_prompts; // make item prompts quitable on space
- int colour[16]; // macro fg colours to other colours
- int background; // select default background colour
- int channels[NUM_MESSAGE_CHANNELS]; // msg channel colouring
- int weapon; // auto-choose weapon for character
- int chaos_knight; // choice of god for Chaos Knights (Xom/Makleb)
- int death_knight; // choice of god/necromancy for Death Knights
- int priest; // choice of god for priests (Zin/Yred)
- bool random_pick; // randomly generate character
- int hp_warning; // percentage hp for danger warning
- int hp_attention; // percentage hp for danger attention
- char race; // preselected race
- char cls; // preselected class
- bool terse_hand; // use terse description for wielded item
- bool delay_message_clear; // avoid clearing messages each turn
- unsigned friend_brand; // Attribute for branding friendly monsters
- bool no_dark_brand; // Attribute for branding friendly monsters
- bool macro_meta_entry; // Allow user to use \{foo} sequences when
- // creating macros
-
- int fire_items_start; // index of first item for fire command
- FixedVector<int, NUM_FIRE_TYPES> fire_order; // order for 'f' command
-
- bool auto_list; // automatically jump to appropriate item lists
-
- bool flush_input[NUM_FLUSH_REASONS]; // when to flush input buff
- bool lowercase_invocations; // prefer lowercase invocations
-
- int num_colours; // used for setting up curses colour table (8 or 16)
-
-#ifdef WIZARD
- int wiz_mode; // yes, no, never in wiz mode to start
-#endif
-
- // internal use only:
- int sc_entries; // # of score entries
- int sc_format; // Format for score entries
-
- std::vector<text_pattern> banned_objects; // Objects we'll never pick up
- bool pickup_thrown; // Pickup thrown missiles
- bool pickup_dropped; // Pickup dropped objects
- int travel_delay; // How long to pause between travel moves
-
- std::vector<message_filter> stop_travel; // Messages that stop travel
-
- int stash_tracking; // How stashes are tracked
-
- bool travel_colour; // Colour levelmap using travel information?
- int travel_stair_cost;
-
- int travel_exclude_radius2; // Square of the travel exclude radius
- bool show_waypoints;
-
- bool item_colour; // Colour items on level map
-
- unsigned detected_monster_colour; // Colour of detected monsters
- unsigned detected_item_colour; // Colour of detected items
- unsigned remembered_monster_colour; // Colour for monsters remembered
- // on the map.
-
- unsigned heap_brand; // Highlight heaps of items in the playing area
- unsigned stab_brand; // Highlight monsters that are stabbable
- unsigned may_stab_brand; // Highlight potential stab candidates
-
- int explore_stop; // Stop exploring if a previously unseen
- // item comes into view
-
- std::vector<sound_mapping> sound_mappings;
- std::vector<colour_mapping> menu_colour_mappings;
-
- int dump_kill_places; // How to dump place information for kills.
- int dump_message_count; // How many old messages to dump
-
- int dump_item_origins; // Show where items came from?
- int dump_item_origin_price;
-
- bool target_zero_exp; // If true, targeting targets zero-exp
- // monsters.
- bool target_wrap; // Wrap around from last to first target
- bool target_oos; // 'x' look around can target out-of-LOS
- bool target_los_first; // 'x' look around first goes to visible
- // objects/features, then goes to stuff
- // outside LOS.
-
- int drop_mode; // Controls whether single or multidrop
- // is the default.
-
- bool easy_exit_menu; // Menus are easier to get out of
-
- int assign_item_slot; // How free slots are assigned
-
- std::vector<text_pattern> drop_filter;
-
- FixedVector< unsigned, ACT_ACTIVITY_COUNT > activity_interrupts;
-
- // Previous startup options
- bool remember_name; // Remember and reprompt with last name
-
- bool dos_use_background_intensity;
-
- int level_map_cursor_step; // The cursor increment in the level
- // map.
-
- // If the player prefers to merge kill records, this option can do that.
- int kill_map[KC_NCATEGORIES];
-
- // Parameters for fight simulations.
- long fsim_rounds;
- int fsim_str, fsim_int, fsim_dex;
- int fsim_xl;
- std::string fsim_mons;
- std::vector<std::string> fsim_kit;
-
- typedef std::map<std::string, std::string> opt_map;
- opt_map named_options; // All options not caught above are
- // recorded here.
-
- ///////////////////////////////////////////////////////////////////////
- // These options cannot be directly set by the user. Instead they're
- // set indirectly to the choices the user made for the last character
- // created. XXX: Isn't there a better place for these?
- std::string prev_name;
- char prev_race;
- char prev_cls;
- int prev_ck, prev_dk, prev_pr;
- int prev_weapon;
- bool prev_randpick;
-};
-
-extern game_options Options;
-
-struct tagHeader
-{
- short tagID;
- long offset;
-};
-
-struct scorefile_entry
-{
- char version;
- char release;
- long points;
- char name[kNameLen];
- long uid; // for multiuser systems
- char race;
- char cls;
- char race_class_name[5]; // overrides race & cls if non-null
- char lvl; // player level.
- char best_skill; // best skill #
- char best_skill_lvl; // best skill level
- int death_type;
- int death_source; // 0 or monster TYPE
- int mon_num; // sigh...
- char death_source_name[40]; // overrides death_source
- char auxkilldata[ITEMNAME_SIZE]; // weapon wielded, spell cast, etc
- char dlvl; // dungeon level (relative)
- char level_type; // what kind of level died on..
- char branch; // dungeon branch
- int final_hp; // actual current HPs (probably <= 0)
- int final_max_hp; // net HPs after rot
- int final_max_max_hp; // gross HPs before rot
- int damage; // damage of final attack
- int str; // final str (useful for nickname)
- int intel; // final int
- int dex; // final dex (useful for nickname)
- int god; // god
- int piety; // piety
- int penance; // penance
- char wiz_mode; // character used wiz mode
- time_t birth_time; // start time of character
- time_t death_time; // end time of character
- long real_time; // real playing time in seconds
- long num_turns; // number of turns taken
- int num_diff_runes; // number of rune types in inventory
- int num_runes; // total number of runes in inventory
-};
-
-#endif // EXTERNS_H
diff --git a/stone_soup/crawl-ref/source/fight.cc b/stone_soup/crawl-ref/source/fight.cc
deleted file mode 100644
index a478f6002a..0000000000
--- a/stone_soup/crawl-ref/source/fight.cc
+++ /dev/null
@@ -1,4041 +0,0 @@
-/*
- * File: fight.cc
- * Summary: Functions used during combat.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <11> 07-jul-2000 JDJ Fixed some of the code in you_attack so it doesn't
- * index past the end of arrays for unarmed attacks.
- * <10> 03-mar-2000 bwr changes for new spells, no stave magic
- * skill practising
- * <9> 11/23/99 LRH Now you don't get xp/piety for killing
- * monsters who were created friendly
- * <8> 11/14/99 cdl evade with random40(ev) vice random2(ev)
- * <7> 10/ 8/99 BCR Large races get a smaller
- * penalty for large shields
- * <6> 9/09/99 BWR Code for 1-1/2 hand weapons
- * <5> 8/08/99 BWR Reduced power of EV/shields
- * <4> 6/22/99 BWR Changes to stabbing code, made
- * most gods not care about the
- * deathes of summoned monsters
- * <3> 5/21/99 BWR Upped learning of armour skill
- * in combat slightly.
- * <2> 5/12/99 BWR Fixed a bug where burdened
- * barehanded attacks where free
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "fight.h"
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#ifdef DOS
-#include <conio.h>
-#endif
-
-#include "externs.h"
-
-#include "beam.h"
-#include "cloud.h"
-#include "debug.h"
-#include "delay.h"
-#include "effects.h"
-#include "food.h"
-#include "it_use2.h"
-#include "items.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "macro.h"
-#include "misc.h"
-#include "monplace.h"
-#include "mon-pick.h"
-#include "monstuff.h"
-#include "mon-util.h"
-#include "mstuff2.h"
-#include "mutation.h"
-#include "ouch.h"
-#include "player.h"
-#include "randart.h"
-#include "religion.h"
-#include "skills.h"
-#include "spells1.h"
-#include "spells3.h"
-#include "spells4.h"
-#include "spl-cast.h"
-#include "stuff.h"
-#include "view.h"
-#include "wpn-misc.h"
-
-#define HIT_WEAK 7
-#define HIT_MED 18
-#define HIT_STRONG 36
-// ... was 5, 12, 21
-// how these are used will be replaced by a function in a second ... :P {dlb}
-
-static int weapon_type_modify( int weap, char noise[80], char noise2[80],
- int damage );
-
-static void stab_message(struct monsters *defender, int stab_bonus);
-
-int weapon_str_weight( int wpn_class, int wpn_type );
-
-static inline int player_weapon_str_weight( void );
-static inline int player_weapon_dex_weight( void );
-
-static inline int calc_stat_to_hit_base( void );
-static inline int calc_stat_to_dam_base( void );
-
-/*
- **************************************************
- * *
- * BEGIN PUBLIC FUNCTIONS *
- * *
- **************************************************
-*/
-
-#if 0
-#define GUARANTEED_HIT_PERCENTAGE 5
-
-bool test_hit( int to_hit, int ev, int bonus )
-{
- if (random2(100) < 2 * GUARANTEED_HIT_PERCENTAGE)
- return (coinflip());
-
- return (random2( to_hit ) + bonus >= ev);
-}
-#endif
-
-// This function returns the "extra" stats the player gets because of
-// choice of weapon... it's used only for giving warnings when a player
-// weilds a less than ideal weapon.
-int effective_stat_bonus( int wepType )
-{
-#ifdef USE_NEW_COMBAT_STATS
- int str_weight;
- if (wepType == -1)
- str_weight = player_weapon_str_weight();
- else
- str_weight = weapon_str_weight( OBJ_WEAPONS, wepType );
-
- return ((you.strength - you.dex) * (str_weight - 5) / 10);
-#else
- return (0);
-#endif
-}
-
-// Returns true if you hit the monster.
-bool you_attack(int monster_attacked, bool unarmed_attacks)
-{
- struct monsters *defender = &menv[monster_attacked];
-
- int your_to_hit;
- int damage_done = 0;
- bool hit = false;
- unsigned char stab_bonus = 0; // this is never negative {dlb}
- int temp_rand; // for probability determination {dlb}
-
- const int weapon = you.equip[EQ_WEAPON];
- const bool ur_armed = (weapon != -1); // compacts code a bit {dlb}
- const bool bearing_shield = (you.equip[EQ_SHIELD] != -1);
-
- const int melee_brand = player_damage_brand();
-
- bool water_attack = false;
-
- char damage_noise[80], damage_noise2[80];
-
- int heavy_armour = 0;
- char str_pass[ ITEMNAME_SIZE ];
-
-#if DEBUG_DIAGNOSTICS
- char st_prn[ 20 ];
-#endif
-
- FixedVector< char, RA_PROPERTIES > art_proprt;
-
- if (ur_armed && you.inv[weapon].base_type == OBJ_WEAPONS
- && is_random_artefact( you.inv[weapon] ))
- {
- randart_wpn_properties( you.inv[weapon], art_proprt );
- }
- else
- {
- // Probably over protective, but in this code we're going
- // to play it safe. -- bwr
- for (int i = 0; i < RA_PROPERTIES; i++)
- art_proprt[i] = 0;
- }
-
- // heavy armour modifiers for shield borne
- if (bearing_shield)
- {
- switch (you.inv[you.equip[EQ_SHIELD]].sub_type)
- {
- case ARM_SHIELD:
- if (you.skills[SK_SHIELDS] < random2(7))
- heavy_armour++;
- break;
- case ARM_LARGE_SHIELD:
- if ((you.species >= SP_OGRE && you.species <= SP_OGRE_MAGE)
- || player_genus(GENPC_DRACONIAN))
- {
- if (you.skills[SK_SHIELDS] < random2(13))
- heavy_armour++; // was potentially "+= 3" {dlb}
- }
- else
- {
- for (int i = 0; i < 3; i++)
- {
- if (you.skills[SK_SHIELDS] < random2(13))
- heavy_armour += random2(3);
- }
- }
- break;
- default:
- break;
- }
- }
-
- // heavy armour modifiers for PARM_EVASION
- if (you.equip[EQ_BODY_ARMOUR] != -1)
- {
- const int ev_pen = property( you.inv[you.equip[EQ_BODY_ARMOUR]],
- PARM_EVASION );
-
- if (ev_pen < 0 && random2(you.skills[SK_ARMOUR]) < abs( ev_pen ))
- heavy_armour += random2( abs(ev_pen) );
- }
-
- // ??? what is the reasoning behind this ??? {dlb}
- // My guess is that its supposed to encourage monk-style play -- bwr
- if (!ur_armed)
- heavy_armour *= (coinflip() ? 3 : 2);
-
- // Calculate the following two flags in advance
- // to know what player does this combat turn:
- bool can_do_unarmed_combat = false;
-
- if (you.burden_state == BS_UNENCUMBERED
- && random2(20) < you.skills[SK_UNARMED_COMBAT]
- && random2(1 + heavy_armour) < 2)
- {
- can_do_unarmed_combat = true;
- }
-
- // if we're not getting potential unarmed attacks, and not wearing a
- // shield, and have a suitable uncursed weapon we get the bonus.
- bool use_hand_and_a_half_bonus = false;
-
- int wpn_skill = SK_UNARMED_COMBAT;
- int hands_reqd = HANDS_ONE;
-
- if (weapon != -1)
- {
- wpn_skill = weapon_skill( you.inv[weapon].base_type,
- you.inv[weapon].sub_type );
-
- hands_reqd = hands_reqd_for_weapon( you.inv[weapon].base_type,
- you.inv[weapon].sub_type );
- }
-
- if (unarmed_attacks
- && !can_do_unarmed_combat
- && !bearing_shield && ur_armed
- && !item_cursed( you.inv[ weapon ] )
- && hands_reqd == HANDS_HALF)
- {
- // currently: +1 dam, +1 hit, -1 spd (loosly)
- use_hand_and_a_half_bonus = true;
- }
-
-/*
- **************************************************************************
- * *
- * IMPORTANT: When altering damage routines, must also change in ouch.cc *
- * for saving of player ghosts. *
- * *
- **************************************************************************
- */
- bool helpless = mons_class_flag(defender->type, M_NO_EXP_GAIN);
-
- if (mons_friendly(defender))
- did_god_conduct(DID_ATTACK_FRIEND, 5);
-
- if (you.pet_target == MHITNOT)
- you.pet_target = monster_attacked;
-
- // fumbling in shallow water <early return>:
- if (player_in_water() && !player_is_swimming())
- {
- if (random2(you.dex) < 4 || one_chance_in(5))
- {
- mpr("Unstable footing causes you to fumble your attack.");
- return (false);
- }
- }
-
- // wet merfolk
- if (player_is_swimming()
- // monster not a water creature
- && monster_habitat( defender->type ) != DNGN_DEEP_WATER
- && !mons_class_flag( defender->type, M_AMPHIBIOUS )
- // monster in water
- && (grd[defender->x][defender->y] == DNGN_SHALLOW_WATER
- || grd[defender->x][defender->y] == DNGN_DEEP_WATER)
- // monster not flying
- && !mons_flies( defender ))
- {
- water_attack = true;
- }
-
- // preliminary to_hit modifications:
- your_to_hit = 15 + (calc_stat_to_hit_base() / 2);
-
- if (water_attack)
- your_to_hit += 5;
-
- if (wearing_amulet(AMU_INACCURACY))
- your_to_hit -= 5;
-
- // if you can't see yourself, you're a little less acurate.
- if (you.invis && !player_see_invis())
- your_to_hit -= 5;
-
- your_to_hit += random2(1 + you.skills[SK_FIGHTING]);
-
- if (ur_armed)
- {
- if (wpn_skill)
- your_to_hit += random2(you.skills[wpn_skill] + 1);
- }
- else // ...you must be unarmed
- {
- your_to_hit += (you.species == SP_TROLL
- || you.species == SP_GHOUL) ? 4 : 2;
-
- your_to_hit += random2(1 + you.skills[SK_UNARMED_COMBAT]);
- }
-
- // energy expenditure in terms of food:
- make_hungry(3, true);
-
- if (ur_armed
- && you.inv[ weapon ].base_type == OBJ_WEAPONS
- && is_random_artefact( you.inv[ weapon ] ))
- {
- if (art_proprt[RAP_ANGRY] >= 1)
- {
- if (random2(1 + art_proprt[RAP_ANGRY]))
- {
- go_berserk(false);
- }
- }
- }
-
- switch (you.special_wield)
- {
- case SPWLD_TROG:
- if (coinflip())
- go_berserk(false);
- break;
-
- case SPWLD_WUCAD_MU:
- if (one_chance_in(9))
- {
- miscast_effect( SPTYP_DIVINATION, random2(9), random2(70), 100,
- "the Staff of Wucad Mu" );
- }
- break;
- default:
- break;
- }
-
- if (you.mutation[MUT_BERSERK])
- {
- if (random2(100) < (you.mutation[MUT_BERSERK] * 10) - 5)
- go_berserk(false);
- }
-
- if (ur_armed)
- {
- if (you.inv[ weapon ].base_type == OBJ_WEAPONS)
- {
- // there was some stupid conditional here that applied this
- // "if (plus >= 0)" and "else" that .. which is all
- // cases (d'oh!) {dlb}
- your_to_hit += you.inv[ weapon ].plus;
- your_to_hit += property( you.inv[ weapon ], PWPN_HIT );
-
- if (get_equip_race(you.inv[ weapon ]) == ISFLAG_ELVEN
- && player_genus(GENPC_ELVEN))
- {
- your_to_hit += (coinflip() ? 2 : 1);
- }
- }
- else if (item_is_staff( you.inv[ weapon ] ))
- {
- /* magical staff */
- your_to_hit += property( you.inv[ weapon ], PWPN_HIT );
- }
- }
-
- your_to_hit += slaying_bonus(PWPN_HIT); // see: player.cc
-
- if (you.hunger_state == HS_STARVING)
- your_to_hit -= 3;
-
- your_to_hit -= heavy_armour;
-
-#if DEBUG_DIAGNOSTICS
- int roll_hit = your_to_hit;
-#endif
-
- // why does this come here and not later? {dlb}
- // apparently to give the following pluses more significance -- bwr
- your_to_hit = random2(your_to_hit);
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "to hit die: %d; rolled value: %d",
- roll_hit, your_to_hit );
-
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- if (use_hand_and_a_half_bonus)
- your_to_hit += random2(3);
-
- if (ur_armed && wpn_skill == SK_SHORT_BLADES && you.sure_blade)
- your_to_hit += 5 + random2limit( you.sure_blade, 10 );
-
- int damage = 1;
-
- if (!ur_armed) // empty-handed
- {
- damage = 3;
-
- if (you.confusing_touch)
- {
- // just trying to touch is easier that trying to damage
- // special_brand = SPWPN_CONFUSE;
- your_to_hit += random2(you.dex);
- // no base hand damage while using this spell
- damage = 0;
- }
-
- // if (you.mutation[MUT_DRAIN_LIFE])
- // special_brand = SPWPN_DRAINING;
-
- if (you.attribute[ATTR_TRANSFORMATION] != TRAN_NONE)
- {
- switch (you.attribute[ATTR_TRANSFORMATION])
- {
- case TRAN_SPIDER:
- damage = 5;
- // special_brand = SPWPN_VENOM;
- your_to_hit += random2(10);
- break;
- case TRAN_ICE_BEAST:
- damage = 12;
- // special_brand = SPWPN_FREEZING;
- your_to_hit += random2(10);
- break;
- case TRAN_BLADE_HANDS:
- damage = 12 + (you.strength / 4) + (you.dex / 4);
- your_to_hit += random2(12);
- break;
- case TRAN_STATUE:
- damage = 12 + you.strength;
- your_to_hit += random2(9);
- break;
- case TRAN_SERPENT_OF_HELL:
- case TRAN_DRAGON:
- damage = 20 + you.strength;
- your_to_hit += random2(10);
- break;
- case TRAN_LICH:
- damage = 5;
- // special_brand = SPWPN_DRAINING;
- your_to_hit += random2(10);
- break;
- case TRAN_AIR:
- damage = 0;
- your_to_hit = 0;
- break;
- }
- }
- else if (you.equip[ EQ_GLOVES ] == -1)
- {
- // claw damage only applies for bare hands
- if (you.species == SP_TROLL)
- damage += 5;
- else if (you.species == SP_GHOUL)
- damage += 2;
-
- damage += (you.mutation[ MUT_CLAWS ] * 2);
- }
-
- damage += you.skills[SK_UNARMED_COMBAT];
- }
- else
- {
- if (you.inv[ weapon ].base_type == OBJ_WEAPONS
- || item_is_staff( you.inv[ weapon ] ))
- {
- damage = property( you.inv[ weapon ], PWPN_DAMAGE );
- }
- }
-
-#if DEBUG_DIAGNOSTICS
- const int base_damage = damage;
-#endif
-
- //jmf: check for backlight enchantment
- if (mons_has_ench(defender, ENCH_BACKLIGHT_I, ENCH_BACKLIGHT_IV))
- your_to_hit += 2 + random2(8);
-
- int weapon_speed2 = 10;
- int min_speed = 3;
-
- if (ur_armed)
- {
- if (you.inv[ weapon ].base_type == OBJ_WEAPONS
- || item_is_staff( you.inv[ weapon ] ))
- {
- weapon_speed2 = property( you.inv[ weapon ], PWPN_SPEED );
- weapon_speed2 -= you.skills[ wpn_skill ] / 2;
-
- min_speed = property( you.inv[ weapon ], PWPN_SPEED ) / 2;
-
- // Short blades can get up to at least unarmed speed.
- if (wpn_skill == SK_SHORT_BLADES && min_speed > 5)
- min_speed = 5;
-
- // Using both hands can get a weapon up to speed 7
- if ((hands_reqd == HANDS_TWO || use_hand_and_a_half_bonus)
- && min_speed > 7)
- {
- min_speed = 7;
- }
-
- // never go faster than speed 3 (ie 3 attacks per round)
- if (min_speed < 3)
- min_speed = 3;
-
- // Hand and a half bonus only helps speed up to a point, any more
- // than speed 10 must come from skill and the weapon
- if (use_hand_and_a_half_bonus && weapon_speed2 > 10)
- weapon_speed2--;
-
- // apply minimum to weapon skill modification
- if (weapon_speed2 < min_speed)
- weapon_speed2 = min_speed;
-
- if (you.inv[weapon].base_type == OBJ_WEAPONS
- && melee_brand == SPWPN_SPEED)
- {
- weapon_speed2 = (weapon_speed2 + 1) / 2;
- }
- }
- }
- else
- {
- // Unarmed speed
- if (you.burden_state == BS_UNENCUMBERED
- && one_chance_in(heavy_armour + 1))
- {
- weapon_speed2 = 10 - you.skills[SK_UNARMED_COMBAT] / 3;
-
- if (weapon_speed2 < 4)
- weapon_speed2 = 4;
- }
- }
-
- if (bearing_shield)
- {
- switch (you.inv[you.equip[EQ_SHIELD]].sub_type)
- {
- case ARM_LARGE_SHIELD:
- if (you.skills[SK_SHIELDS] <= 10 + random2(17))
- weapon_speed2++;
- // [dshaligram] Fall-through
-
- case ARM_SHIELD:
- if (you.skills[SK_SHIELDS] <= 3 + random2(17))
- weapon_speed2++;
- break;
- }
- }
-
- // Never allow anything faster than 3 to get through... three attacks
- // per round is enough... 5 or 10 is just silly. -- bwr
- if (weapon_speed2 < 3)
- weapon_speed2 = 3;
-
- you.time_taken *= weapon_speed2;
- you.time_taken /= 10;
-
- if (you.time_taken < 1)
- you.time_taken = 1;
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "Weapon speed: %d; min: %d; speed: %d; attack time: %d",
- weapon_speed2, min_speed, weapon_speed2, you.time_taken );
-
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- // DO STABBING
-
- bool stabAttempt = false;
- bool rollNeeded = true;
-
- // This ordering is important!
-
- // not paying attention (but not batty)
- if (defender->foe != MHITYOU && !testbits(defender->flags, MF_BATTY))
- {
- stabAttempt = true;
- stab_bonus = 3;
- }
-
- // confused (but not perma-confused)
- if (mons_has_ench(defender, ENCH_CONFUSION)
- && !mons_class_flag(defender->type, M_CONFUSED))
- {
- stabAttempt = true;
- stab_bonus = 2;
- }
-
- // fleeing
- if (defender->behaviour == BEH_FLEE)
- {
- stabAttempt = true;
- stab_bonus = 2;
- }
-
- // sleeping
- if (defender->behaviour == BEH_SLEEP)
- {
- stabAttempt = true;
- rollNeeded = false;
- stab_bonus = 1;
- }
-
- // helpless (plants, etc)
- if (helpless)
- stabAttempt = false;
-
- // see if we need to roll against dexterity / stabbing
- if (stabAttempt && rollNeeded)
- stabAttempt = (random2(200) <= you.skills[SK_STABBING] + you.dex);
-
- // check for invisibility - no stabs on invisible monsters.
- if (!player_monster_visible( defender ))
- {
- stabAttempt = false;
- stab_bonus = 0;
- }
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "your to-hit: %d; defender EV: %d",
- your_to_hit, defender->evasion );
-
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- if ((your_to_hit >= defender->evasion || one_chance_in(30))
- || ((defender->speed_increment <= 60
- || defender->behaviour == BEH_SLEEP)
- && !one_chance_in(10 + you.skills[SK_STABBING])))
- {
- hit = true;
- int dammod = 78;
-
- const int dam_stat_val = calc_stat_to_dam_base();
-
- if (dam_stat_val > 11)
- dammod += (random2(dam_stat_val - 11) * 2);
- else if (dam_stat_val < 9)
- dammod -= (random2(9 - dam_stat_val) * 3);
-
- damage *= dammod; //random2(you.strength);
- damage /= 78;
-
-#if DEBUG_DIAGNOSTICS
- const int str_damage = damage;
-#endif
-
- // Yes, this isn't the *2 damage that monsters get, but since
- // monster hps and player hps are different (as are the sizes
- // of the attacks) it just wouldn't be fair to give merfolk
- // that gross a potential... still they do get something for
- // making use of the water. -- bwr
- if (water_attack)
- damage += random2avg(10,2);
-
-#if DEBUG_DIAGNOSTICS
- const int water_damage = damage;
-#endif
-
- // apply damage bonus from ring of slaying
- // (before randomization -- some of these rings
- // are stupidly powerful) -- GDL
- damage += slaying_bonus(PWPN_DAMAGE);
-
-#if DEBUG_DIAGNOSTICS
- const int slay_damage = damage;
-
- snprintf( info, INFO_SIZE,
- "melee base: %d; str: %d; water: %d; to-dam: %d",
- base_damage, str_damage, water_damage, slay_damage );
-
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- damage_done = random2(damage);
-
-#if DEBUG_DIAGNOSTICS
- const int roll_damage = damage_done;
-#endif
-
- if (ur_armed && (you.inv[ weapon ].base_type == OBJ_WEAPONS
- || item_is_staff( you.inv[ weapon ] )))
- {
- damage_done *= 25 + (random2( you.skills[ wpn_skill ] + 1 ));
- damage_done /= 25;
- }
-
-#if DEBUG_DIAGNOSTICS
- const int skill_damage = damage_done;
-#endif
-
- damage_done *= 30 + (random2(you.skills[SK_FIGHTING] + 1));
- damage_done /= 30;
-
-#if DEBUG_DIAGNOSTICS
- const int fight_damage = damage_done;
-#endif
-
- if (you.might > 1)
- damage_done += 1 + random2(10);
-
- if (you.hunger_state == HS_STARVING)
- damage_done -= random2(5);
-
-#if DEBUG_DIAGNOSTICS
- const int preplus_damage = damage_done;
- int plus_damage = damage_done;
- int bonus_damage = damage_done;
-#endif
-
- if (ur_armed && you.inv[ weapon ].base_type == OBJ_WEAPONS)
- {
- int hoggl = you.inv[ weapon ].plus2;
-
- damage_done += (hoggl > -1) ? (random2(1 + hoggl)) : (hoggl);
-
-#if DEBUG_DIAGNOSTICS
- plus_damage = damage_done;
-#endif
-
- // removed 2-handed weapons from here... their "bonus" is
- // already included in the damage stat for the weapon -- bwr
- if (use_hand_and_a_half_bonus)
- damage_done += random2(3);
-
- if (get_equip_race(you.inv[ weapon ]) == ISFLAG_DWARVEN
- && player_genus(GENPC_DWARVEN))
- {
- damage_done += random2(3);
- }
-
- if (get_equip_race(you.inv[ weapon ]) == ISFLAG_ORCISH
- && you.species == SP_HILL_ORC && coinflip())
- {
- damage_done++;
- }
-
-#if DEBUG_DIAGNOSTICS
- bonus_damage = damage_done;
-#endif
-
- if (!launches_things( you.inv[ weapon ].sub_type )
- && !item_ident( you.inv[ weapon ], ISFLAG_KNOW_PLUSES )
- && random2(100) < you.skills[ wpn_skill ])
- {
- set_ident_flags( you.inv[ weapon ], ISFLAG_KNOW_PLUSES );
- strcpy(info, "You are wielding ");
- in_name( weapon , DESC_NOCAP_A, str_pass );
- strcat(info, str_pass);
- strcat(info, ".");
- mpr(info);
- more();
- you.wield_change = true;
- }
- }
-
- // The stabbing message looks better here:
- if (stabAttempt)
- {
- // construct reasonable message
- stab_message( defender, stab_bonus );
-
- exercise(SK_STABBING, 1 + random2avg(5, 4));
-
- if (mons_holiness(defender) == MH_NATURAL
- || mons_holiness(defender) == MH_HOLY)
- {
- did_god_conduct(DID_STABBING, 4);
- }
- }
- else
- {
- stab_bonus = 0;
- // ok.. if you didn't backstab, you wake up the neighborhood.
- // I can live with that.
- alert_nearby_monsters();
- }
-
-#if DEBUG_DIAGNOSTICS
- int stab_damage = damage_done;
-#endif
-
- if (stab_bonus)
- {
- // lets make sure we have some damage to work with...
- if (damage_done < 1)
- damage_done = 1;
-
- if (defender->behaviour == BEH_SLEEP)
- {
- // Sleeping moster wakes up when stabbed but may be groggy
- if (random2(200) <= you.skills[SK_STABBING] + you.dex)
- {
- unsigned int stun = random2( you.dex + 1 );
-
- if (defender->speed_increment > stun)
- defender->speed_increment -= stun;
- else
- defender->speed_increment = 0;
- }
- }
-
- switch (wpn_skill)
- {
- case SK_SHORT_BLADES:
- {
- int bonus = (you.dex * (you.skills[SK_STABBING] + 1)) / 5;
-
- if (you.inv[ weapon ].sub_type != WPN_DAGGER)
- bonus /= 2;
-
- bonus = stepdown_value( bonus, 10, 10, 30, 30 );
-
- damage_done += bonus;
- }
- // fall through
- case SK_LONG_SWORDS:
- damage_done *= 10 + you.skills[SK_STABBING] /
- (stab_bonus + (wpn_skill == SK_SHORT_BLADES ? 0 : 1));
- damage_done /= 10;
- // fall through
- default:
- damage_done *= 12 + you.skills[SK_STABBING] / stab_bonus;
- damage_done /= 12;
- }
-
-#if DEBUG_DIAGNOSTICS
- stab_damage = damage_done;
-#endif
-
- // when stabbing we can get by some of the armour
- if (defender->armour_class > 0)
- {
- int ac = defender->armour_class
- - random2( you.skills[SK_STABBING] / stab_bonus );
-
- if (ac > 0)
- damage_done -= random2(1 + ac);
- }
- }
- else
- {
- // apply AC normally
- if (defender->armour_class > 0)
- damage_done -= random2(1 + defender->armour_class);
- }
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE,
- "melee roll: %d; skill: %d; fight: %d; pre wpn plus: %d",
- roll_damage, skill_damage, fight_damage, preplus_damage );
-
- mpr( info, MSGCH_DIAGNOSTICS );
-
- snprintf( info, INFO_SIZE,
- "melee plus: %d; bonus: %d; stab: %d; post AC: %d",
- plus_damage, bonus_damage, stab_damage, damage_done );
-
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- // This doesn't actually modify damage -- bwr
- damage_done = weapon_type_modify( weapon, damage_noise, damage_noise2,
- damage_done );
-
- if (damage_done < 0)
- damage_done = 0;
-
- // always upset monster regardless of damage
- behaviour_event(defender, ME_WHACK, MHITYOU);
-
- if (hurt_monster(defender, damage_done))
- {
- if (ur_armed && wpn_skill)
- {
- if (!helpless || you.skills[ wpn_skill ] < 2)
- exercise( wpn_skill, 1 );
- }
- else
- {
- if (!helpless || you.skills[SK_UNARMED_COMBAT] < 2)
- exercise(SK_UNARMED_COMBAT, 1);
- }
-
- if ((!helpless || you.skills[SK_FIGHTING] < 2)
- && one_chance_in(3))
- {
- exercise(SK_FIGHTING, 1);
- }
- }
-
- if (defender->hit_points < 1)
- {
-#if DEBUG_DIAGNOSTICS
- /* note: doesn't take account of special weapons etc */
- snprintf( info, INFO_SIZE, "Hit for %d.", damage_done );
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
- if (ur_armed && melee_brand == SPWPN_VAMPIRICISM)
- {
- if (mons_holiness(defender) == MH_NATURAL
- && damage_done > 0 && you.hp < you.hp_max
- && !one_chance_in(5))
- {
- mpr("You feel better.");
-
- // more than if not killed
- inc_hp(1 + random2(damage_done), false);
-
- if (you.hunger_state != HS_ENGORGED)
- lessen_hunger(30 + random2avg(59, 2), true);
-
- did_god_conduct(DID_NECROMANCY, 2);
- }
- }
-
- monster_die(defender, KILL_YOU, 0);
-
- if (defender->type == MONS_GIANT_SPORE)
- {
- snprintf( info, INFO_SIZE, "You %s the giant spore.", damage_noise);
- mpr(info);
- }
- else if (defender->type == MONS_BALL_LIGHTNING)
- {
- snprintf( info, INFO_SIZE, "You %s the ball lightning.", damage_noise);
- mpr(info);
- }
- return (true);
- }
-
- if (damage_done < 1 && player_monster_visible( defender ))
- {
- hit = true;
-
- snprintf( info, INFO_SIZE, "You %s ", damage_noise);
- strcat(info, ptr_monam(defender, DESC_NOCAP_THE));
- strcat(info, ", but do no damage.");
- mpr(info);
- }
- }
- else
- {
- hit = false;
-
- // upset only non-sleeping monsters if we missed
- if (defender->behaviour != BEH_SLEEP)
- behaviour_event( defender, ME_WHACK, MHITYOU );
-
- if ((your_to_hit + heavy_armour / 2) >= defender->evasion)
- strcpy(info, "Your armour prevents you from hitting ");
- else
- strcpy(info, "You miss ");
-
- strcat(info, ptr_monam(defender, DESC_NOCAP_THE));
- strcat(info, ".");
- mpr(info);
- }
-
- if (hit && damage_done > 0
- || (hit && damage_done < 1 && mons_has_ench(defender,ENCH_INVIS)))
- {
- strcpy(info, "You ");
- strcat(info, damage_noise);
- strcat(info, " ");
- strcat(info, ptr_monam(defender, DESC_NOCAP_THE));
- strcat(info, damage_noise2);
-
-#if DEBUG_DIAGNOSTICS
- strcat( info, " for " );
- /* note: doesn't take account of special weapons etc */
- itoa( damage_done, st_prn, 10 );
- strcat( info, st_prn );
-#endif
- if (damage_done < HIT_WEAK)
- strcat(info, ".");
- else if (damage_done < HIT_MED)
- strcat(info, "!");
- else if (damage_done < HIT_STRONG)
- strcat(info, "!!");
- else
- strcat(info, "!!!");
-
- mpr(info);
-
- if (mons_holiness(defender) == MH_HOLY)
- did_god_conduct(DID_KILL_ANGEL, 1);
-
- if (you.special_wield == SPWLD_TORMENT)
- {
- torment(you.x_pos, you.y_pos);
- did_god_conduct(DID_UNHOLY, 5);
- }
-
- if (you.special_wield == SPWLD_ZONGULDROK
- || you.special_wield == SPWLD_CURSE)
- {
- did_god_conduct(DID_NECROMANCY, 3);
- }
- }
-
- if (defender->type == MONS_JELLY
- || defender->type == MONS_BROWN_OOZE
- || defender->type == MONS_ACID_BLOB
- || defender->type == MONS_ROYAL_JELLY)
- {
- weapon_acid(5);
- }
-
- /* remember, damage_done is still useful! */
- if (hit)
- {
- int specdam = 0;
-
- if (ur_armed
- && you.inv[ weapon ].base_type == OBJ_WEAPONS
- && is_demonic( you.inv[ weapon ].sub_type ))
- {
- did_god_conduct(DID_UNHOLY, 1);
- }
-
- if (mons_holiness(defender) == MH_HOLY)
- did_god_conduct(DID_ATTACK_HOLY, defender->hit_dice);
-
- if (defender->type == MONS_HYDRA)
- {
- const int dam_type = player_damage_type();
- const int wpn_brand = player_damage_brand();
-
- if ((dam_type == DVORP_SLICING || dam_type == DVORP_CHOPPING)
- && damage_done > 0
- && (damage_done >= 4 || wpn_brand == SPWPN_VORPAL || coinflip()))
- {
- defender->number--;
-
- temp_rand = random2(4);
- const char *const verb = (temp_rand == 0) ? "slice" :
- (temp_rand == 1) ? "lop" :
- (temp_rand == 2) ? "chop" : "hack";
-
- if (defender->number < 1)
- {
- snprintf( info, INFO_SIZE, "You %s %s's last head off!",
- verb, ptr_monam(defender, DESC_NOCAP_THE) );
- mpr( info );
-
- defender->hit_points = -1;
- }
- else
- {
- snprintf( info, INFO_SIZE, "You %s one of %s's heads off!",
- verb, ptr_monam(defender, DESC_NOCAP_THE) );
- mpr( info );
-
- if (wpn_brand == SPWPN_FLAMING)
- mpr( "The flame cauterises the wound!" );
- else if (defender->number < 19)
- {
- simple_monster_message( defender, " grows two more!" );
- defender->number += 2;
- heal_monster( defender, 8 + random2(8), true );
- }
- }
-
- // if the hydra looses a head:
- // - it's dead if it has none remaining (HP set to -1)
- // - flame used to cauterise doesn't do extra damage
- // - ego weapons do their additional damage to the
- // hydra's decapitated head, so it's ignored.
- //
- // ... and so we skip the special damage.
- goto mons_dies;
- }
- }
-
- // jmf: BEGIN STAFF HACK
- // How much bonus damage will a staff of <foo> do?
- // FIXME: make these not macros. inline functions?
- // actually, it will all be pulled out and replaced by functions -- {dlb}
- //
- // This is similar to the previous, in both value and distribution, except
- // that instead of just SKILL, its now averaged with Evocations. -- bwr
-#define STAFF_DAMAGE(SKILL) (roll_dice( 3, 1 + (you.skills[(SKILL)] + you.skills[SK_EVOCATIONS]) / 12 ))
-
-#define STAFF_COST 2
-
- // magic staves have their own special damage
- if (ur_armed && item_is_staff( you.inv[weapon] ))
- {
- specdam = 0;
-
- if (you.magic_points >= STAFF_COST
- && random2(20) <= you.skills[SK_EVOCATIONS])
- {
- switch (you.inv[weapon].sub_type)
- {
- case STAFF_AIR:
- if (damage_done + you.skills[SK_AIR_MAGIC] > random2(30))
- {
- if (mons_res_elec(defender))
- break;
-
- specdam = STAFF_DAMAGE(SK_AIR_MAGIC);
-
- if (specdam)
- {
- snprintf( info, INFO_SIZE, "%s is jolted!",
- ptr_monam(defender, DESC_CAP_THE) );
- mpr(info);
- }
- }
- break;
-
- case STAFF_COLD: // FIXME: I don't think I used these right ...
- if (mons_res_cold(defender) > 0)
- break;
-
- specdam = STAFF_DAMAGE(SK_ICE_MAGIC);
-
- if (mons_res_cold(defender) < 0)
- specdam += STAFF_DAMAGE(SK_ICE_MAGIC);
-
- if (specdam)
- {
-
- snprintf( info, INFO_SIZE, "You freeze %s!",
- ptr_monam(defender, DESC_NOCAP_THE) );
- mpr(info);
- }
- break;
-
- case STAFF_EARTH:
- if (mons_flies(defender))
- break; //jmf: lame, but someone ought to resist
-
- specdam = STAFF_DAMAGE(SK_EARTH_MAGIC);
-
- if (specdam)
- {
- snprintf( info, INFO_SIZE, "You crush %s!",
- ptr_monam(defender, DESC_NOCAP_THE) );
- mpr(info);
- }
- break;
-
- case STAFF_FIRE:
- if (mons_res_fire(defender) > 0)
- break;
-
- specdam = STAFF_DAMAGE(SK_FIRE_MAGIC);
-
- if (mons_res_fire(defender) < 0)
- specdam += STAFF_DAMAGE(SK_FIRE_MAGIC);
-
- if (specdam)
- {
- snprintf( info, INFO_SIZE, "You burn %s!",
- ptr_monam(defender, DESC_NOCAP_THE) );
- mpr(info);
- }
- break;
-
- case STAFF_POISON:
- // cap chance at 30% -- let staff of Olgreb shine
- temp_rand = damage_done + you.skills[SK_POISON_MAGIC];
-
- if (temp_rand > 30)
- temp_rand = 30;
-
- if (random2(100) < temp_rand)
- poison_monster(defender, true);
- break;
-
- case STAFF_DEATH:
- if (mons_res_negative_energy(defender) > 0)
- break;
-
- if (random2(8) <= you.skills[SK_NECROMANCY])
- {
- specdam = STAFF_DAMAGE(SK_NECROMANCY);
-
- if (specdam)
- {
- snprintf( info, INFO_SIZE, "%s convulses in agony!",
- ptr_monam(defender, DESC_CAP_THE) );
- mpr(info);
-
- did_god_conduct(DID_NECROMANCY, 4);
- }
- }
- break;
-
- case STAFF_POWER:
- case STAFF_SUMMONING:
- case STAFF_CHANNELING:
- case STAFF_CONJURATION:
- case STAFF_ENCHANTMENT:
- case STAFF_ENERGY:
- case STAFF_WIZARDRY:
- break;
-
- default:
- mpr("You're wielding some staff I've never heard of! (fight.cc)");
- break;
- } // end switch
- }
-
- if (specdam > 0)
- {
- dec_mp(STAFF_COST);
-
- if (!item_ident( you.inv[weapon], ISFLAG_KNOW_TYPE ))
- {
- set_ident_flags( you.inv[weapon], ISFLAG_KNOW_TYPE );
- strcpy(info, "You are wielding ");
- in_name( weapon, DESC_NOCAP_A, str_pass);
- strcat(info, str_pass);
- strcat(info, ".");
- mpr(info);
- more();
- you.wield_change = true;
- }
- }
-#undef STAFF_DAMAGE
-#undef STAFF_COST
-// END STAFF HACK
- }
- else
- {
- // handle special brand damage (unarmed or armed non-staff ego):
- int res = 0;
-
- switch (melee_brand)
- {
- case SPWPN_NORMAL:
- break;
-
- case SPWPN_FLAMING:
- specdam = 0;
-
- res = mons_res_fire(defender);
- if (ur_armed && you.inv[weapon].special == SPWPN_SWORD_OF_CEREBOV)
- {
- if (res < 3 && res > 0)
- res = 0;
- else if (res == 0)
- res = -1;
- }
-
- if (res == 0)
- specdam = random2(damage_done) / 2 + 1;
- else if (res < 0)
- specdam = random2(damage_done) + 1;
-
- if (specdam)
- {
- strcpy(info, "You burn ");
- strcat(info, ptr_monam(defender, DESC_NOCAP_THE));
-
- if (specdam < 3)
- strcat(info, ".");
- else if (specdam < 7)
- strcat(info, "!");
- else
- strcat(info, "!!");
-
- mpr(info);
- }
- break;
-
- case SPWPN_FREEZING:
- specdam = 0;
-
- res = mons_res_cold(defender);
- if (res == 0)
- specdam = 1 + random2(damage_done) / 2;
- else if (res < 0)
- specdam = 1 + random2(damage_done);
-
- if (specdam)
- {
- strcpy(info, "You freeze ");
- strcat(info, ptr_monam(defender, DESC_NOCAP_THE));
-
- if (specdam < 3)
- strcat(info, ".");
- else if (specdam < 7)
- strcat(info, "!");
- else
- strcat(info, "!!");
-
- mpr(info);
- }
- break;
-
- case SPWPN_HOLY_WRATH:
- // there should be a case in here for holy monsters,
- // see elsewhere in fight.cc {dlb}
- specdam = 0;
- switch (mons_holiness(defender))
- {
- case MH_UNDEAD:
- specdam = 1 + random2(damage_done);
- break;
-
- case MH_DEMONIC:
- specdam = 1 + (random2(damage_done * 15) / 10);
- break;
-
- default:
- break;
- }
- break;
-
-
- case SPWPN_ELECTROCUTION:
- specdam = 0;
-
- if (mons_flies(defender))
- break;
- else if (mons_res_elec(defender) > 0)
- break;
- else if (one_chance_in(3))
- {
- mpr("There is a sudden explosion of sparks!");
- specdam = random2avg(28, 3);
- }
- break;
-
- case SPWPN_ORC_SLAYING:
- if (mons_species(defender->type) == MONS_ORC)
- hurt_monster(defender, 1 + random2(damage_done));
- break;
-
- case SPWPN_VENOM:
- if (!one_chance_in(4))
- poison_monster(defender, true);
- break;
-
- case SPWPN_DRAINING:
- if (mons_res_negative_energy(defender) > 0 || one_chance_in(3))
- break;
-
- strcpy(info, "You drain ");
- strcat(info, ptr_monam(defender, DESC_NOCAP_THE));
- strcat(info, "!");
- mpr(info);
-
- if (one_chance_in(5))
- defender->hit_dice--;
-
- defender->max_hit_points -= 2 + random2(3);
- defender->hit_points -= 2 + random2(3);
-
- if (defender->hit_points >= defender->max_hit_points)
- defender->hit_points = defender->max_hit_points;
-
- if (defender->hit_dice < 1)
- defender->hit_points = 0;
-
- specdam = 1 + (random2(damage_done) / 2);
- did_god_conduct( DID_NECROMANCY, 2 );
- break;
-
- /* 9 = speed - done before */
-
- case SPWPN_VORPAL:
- specdam = 1 + random2(damage_done) / 2;
- break;
-
- case SPWPN_VAMPIRICISM:
- specdam = 0; // NB: does no extra damage
-
- if (mons_holiness(defender) != MH_NATURAL)
- break;
- else if (mons_res_negative_energy(defender) > 0)
- break;
- else if (damage_done < 1)
- break;
- else if (you.hp == you.hp_max || one_chance_in(5))
- break;
-
- mpr("You feel better.");
-
- // thus is probably more valuable on larger weapons?
- if (ur_armed
- && is_fixed_artefact( you.inv[weapon] )
- && you.inv[weapon].special == SPWPN_VAMPIRES_TOOTH)
- {
- inc_hp(damage_done, false);
- }
- else
- inc_hp(1 + random2(damage_done), false);
-
- if (you.hunger_state != HS_ENGORGED)
- lessen_hunger(random2avg(59, 2), true);
-
- did_god_conduct( DID_NECROMANCY, 2 );
- break;
-
- case SPWPN_DISRUPTION:
- specdam = 0;
- if (mons_holiness(defender) == MH_UNDEAD && !one_chance_in(3))
- {
- simple_monster_message(defender, " shudders.");
- specdam += random2avg((1 + (damage_done * 3)), 3);
- }
- break;
-
- case SPWPN_PAIN:
- specdam = 0;
- if (mons_res_negative_energy(defender) <= 0
- && random2(8) <= you.skills[SK_NECROMANCY])
- {
- simple_monster_message(defender, " convulses in agony.");
- specdam += random2( 1 + you.skills[SK_NECROMANCY] );
- }
- did_god_conduct(DID_NECROMANCY, 4);
- break;
-
- case SPWPN_DISTORTION:
- //jmf: blink frogs *like* distortion
- // I think could be amended to let blink frogs "grow" like
- // jellies do {dlb}
- if (defender->type == MONS_BLINK_FROG)
- {
- if (one_chance_in(5))
- {
- simple_monster_message( defender,
- " basks in the translocular energy." );
- heal_monster(defender, 1 + random2avg(7, 2), true); // heh heh
- }
- break;
- }
-
- if (one_chance_in(3))
- {
- strcpy(info, "Space bends around ");
- strcat(info, ptr_monam(defender, DESC_NOCAP_THE));
- strcat(info, ".");
- mpr(info);
- specdam += 1 + random2avg(7, 2);
- break;
- }
-
- if (one_chance_in(3))
- {
- strcpy(info, "Space warps horribly around ");
- strcat(info, ptr_monam(defender, DESC_NOCAP_THE));
- strcat(info, "!");
- mpr(info);
- specdam += 3 + random2avg(24, 2);
- break;
- }
-
- if (one_chance_in(3))
- {
- monster_blink(defender);
- break;
- }
-
- if (coinflip())
- {
- monster_teleport(defender, coinflip());
- break;
- }
-
- if (coinflip())
- {
- monster_die(defender, KILL_RESET, 0);
- return (true);
- }
- break;
-
- case SPWPN_CONFUSE:
- {
- // declaring these just to pass to the enchant function
- struct bolt beam_temp;
- beam_temp.flavour = BEAM_CONFUSION;
-
- mons_ench_f2( defender, beam_temp );
-
- you.confusing_touch -= random2(20);
-
- if (you.confusing_touch < 1)
- you.confusing_touch = 1;
- }
- break;
- } /* end switch */
- }
-
- /* remember, the hydra function sometimes skips straight to mons_dies */
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "brand: %d; melee special damage: %d",
- melee_brand, specdam );
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- hurt_monster( defender, specdam );
- } // end if (hit)
-
- mons_dies:
- if (defender->hit_points < 1)
- {
- monster_die(defender, KILL_YOU, 0);
- return (hit);
- }
-
- if (unarmed_attacks)
- {
- char attack_name[20] = "";
- int sc_dam = 0;
- int brand = SPWPN_NORMAL;
-
- int unarmed_attack = UNAT_NO_ATTACK;
-
- if (can_do_unarmed_combat)
- {
- if (you.species == SP_NAGA)
- unarmed_attack = UNAT_HEADBUTT;
- else
- unarmed_attack = (coinflip() ? UNAT_HEADBUTT : UNAT_KICK);
-
- if ((you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON
- || player_genus(GENPC_DRACONIAN)
- || (you.species == SP_MERFOLK && player_is_swimming())
- || you.mutation[ MUT_STINGER ])
- && one_chance_in(3))
- {
- unarmed_attack = UNAT_TAILSLAP;
- }
-
- if (coinflip())
- unarmed_attack = UNAT_PUNCH;
- }
-
- for (unsigned char scount = 0; scount < 4; scount++)
- {
- brand = SPWPN_NORMAL;
-
- switch (scount)
- {
- case 0:
- if (unarmed_attack != UNAT_KICK) //jmf: hooves mutation
- {
- if ((you.species != SP_CENTAUR && !you.mutation[MUT_HOOVES])
- || coinflip())
- {
- continue;
- }
- }
-
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_SERPENT_OF_HELL
- || you.attribute[ATTR_TRANSFORMATION] == TRAN_ICE_BEAST
- || you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON
- || you.attribute[ATTR_TRANSFORMATION] == TRAN_SPIDER)
- {
- continue;
- }
-
- strcpy(attack_name, "kick");
- sc_dam = ((you.mutation[MUT_HOOVES]
- || you.species == SP_CENTAUR) ? 10 : 5);
- break;
-
- case 1:
- if (unarmed_attack != UNAT_HEADBUTT)
- {
- if ((you.species != SP_MINOTAUR
- && (!you.mutation[MUT_HORNS]
- && you.species != SP_KENKU))
- || !one_chance_in(3))
- {
- continue;
- }
- }
-
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_SERPENT_OF_HELL
- || you.attribute[ATTR_TRANSFORMATION] == TRAN_SPIDER
- || you.attribute[ATTR_TRANSFORMATION] == TRAN_ICE_BEAST
- || you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON)
- {
- continue;
- }
-
- strcpy(attack_name, (you.species == SP_KENKU) ? "peck"
- : "headbutt");
-
- sc_dam = 5 + you.mutation[MUT_HORNS] * 3;
-
- if (you.species == SP_MINOTAUR)
- sc_dam += 5;
-
- if (you.equip[EQ_HELMET] != -1
- && (get_helmet_type(you.inv[you.equip[EQ_HELMET]]) == THELM_HELMET
- || get_helmet_type(you.inv[you.equip[EQ_HELMET]]) == THELM_HELM))
- {
- sc_dam += 2;
-
- if (get_helmet_desc(you.inv[you.equip[EQ_HELMET]]) == THELM_DESC_SPIKED
- || get_helmet_desc(you.inv[you.equip[EQ_HELMET]]) == THELM_DESC_HORNED)
- {
- sc_dam += 3;
- }
- }
- break;
-
- case 2: /* draconians */
- if (unarmed_attack != UNAT_TAILSLAP)
- {
- // not draconian and not wet merfolk
- if ((!player_genus(GENPC_DRACONIAN)
- && (!(you.species == SP_MERFOLK && player_is_swimming()))
- && !you.mutation[ MUT_STINGER ])
- || (!one_chance_in(4)))
-
- {
- continue;
- }
- }
-
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_SPIDER
- || you.attribute[ATTR_TRANSFORMATION] == TRAN_ICE_BEAST)
- {
- continue;
- }
-
- strcpy(attack_name, "tail-slap");
- sc_dam = 6;
-
- if (you.mutation[ MUT_STINGER ] > 0)
- {
- sc_dam += (you.mutation[ MUT_STINGER ] * 2 - 1);
- brand = SPWPN_VENOM;
- }
-
- /* grey dracs have spiny tails, or something */
- // maybe add this to player messaging {dlb}
- //
- // STINGER mutation doesn't give extra damage here... that
- // would probably be a bit much, we'll still get the
- // poison bonus so it's still somewhat good.
- if (you.species == SP_GREY_DRACONIAN && you.experience_level >= 7)
- {
- sc_dam = 12;
- }
- break;
-
- case 3:
- if (unarmed_attack != UNAT_PUNCH)
- continue;
-
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_SERPENT_OF_HELL
- || you.attribute[ATTR_TRANSFORMATION] == TRAN_SPIDER
- || you.attribute[ATTR_TRANSFORMATION] == TRAN_ICE_BEAST
- || you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON)
- {
- continue;
- }
-
- /* no punching with a shield or 2-handed wpn, except staves */
- if (bearing_shield || coinflip()
- || (ur_armed && hands_reqd == HANDS_TWO
- && you.inv[weapon].base_type != OBJ_STAVES
- && you.inv[weapon].sub_type != WPN_QUARTERSTAFF) )
- {
- continue;
- }
-
- strcpy(attack_name, "punch");
-
- /* applied twice */
- sc_dam = 5 + you.skills[SK_UNARMED_COMBAT] / 3;
-
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_BLADE_HANDS)
- {
- strcpy(attack_name, "slash");
- sc_dam += 6;
- }
- break;
-
- /* To add more, add to while part of loop below as well */
- default:
- continue;
-
- }
-
- your_to_hit = 13 + you.dex / 2 + you.skills[SK_UNARMED_COMBAT] / 2
- + you.skills[SK_FIGHTING] / 5;
-
- if (wearing_amulet(AMU_INACCURACY))
- your_to_hit -= 5;
-
- make_hungry(2, true);
-
- if (you.hunger_state == HS_STARVING)
- your_to_hit -= 3;
-
- your_to_hit += slaying_bonus(PWPN_HIT);
- your_to_hit = random2(your_to_hit);
-
- damage = sc_dam; //4 + you.experience_level / 3;
-
- alert_nearby_monsters();
-
- if (your_to_hit >= defender->evasion || one_chance_in(30))
- {
- bool hit = true;
- int dammod = 10;
-
- const int dam_stat_val = calc_stat_to_dam_base();
-
- if (dam_stat_val > 11)
- dammod += random2(dam_stat_val - 11) / 3;
- if (dam_stat_val < 9)
- dammod -= random2(9 - dam_stat_val) / 2;
-
- damage *= dammod;
- damage /= 10;
-
- damage += slaying_bonus(PWPN_DAMAGE);
-
- damage_done = (int) random2(damage);
-
- damage_done *= 40 + (random2(you.skills[SK_FIGHTING] + 1));
- damage_done /= 40;
-
- damage_done *= 25 + (random2(you.skills[SK_UNARMED_COMBAT]+1));
- damage_done /= 25;
-
- if (you.might > 1)
- damage_done += 1 + random2(10);
-
- if (you.hunger_state == HS_STARVING)
- damage_done -= random2(5);
-
- damage_done -= random2(1 + defender->armour_class);
-
- if (damage_done < 1)
- damage_done = 0;
- else
- hurt_monster(defender, damage_done);
-
- if (damage_done > 0)
- {
- if ((!helpless || you.skills[SK_FIGHTING] < 2)
- && one_chance_in(5))
- {
- exercise(SK_FIGHTING, 1);
- }
-
- if (!helpless || you.skills[SK_UNARMED_COMBAT] < 2)
- exercise(SK_UNARMED_COMBAT, 1);
-
- strcpy(info, "You ");
- strcat(info, attack_name);
- strcat(info, " ");
- strcat(info, ptr_monam(defender, DESC_NOCAP_THE));
-
-#if DEBUG_DIAGNOSTICS
- strcat(info, " for ");
- itoa(damage_done, st_prn, 10);
- strcat(info, st_prn);
-#endif
-
- if (damage_done < HIT_WEAK)
- strcat(info, ".");
- else if (damage_done < HIT_MED)
- strcat(info, "!");
- else if (damage_done < HIT_STRONG)
- strcat(info, "!!");
- else
- strcat(info, "!!!");
-
- mpr(info);
-
- if (brand == SPWPN_VENOM && coinflip())
- poison_monster( defender, true );
-
- if (mons_holiness(defender) == MH_HOLY)
- did_god_conduct(DID_KILL_ANGEL, 1);
-
- hit = true;
- }
- else // no damage was done
- {
- strcpy(info, "You ");
- strcat(info, attack_name);
- strcat(info, " ");
- strcat(info, ptr_monam(defender, DESC_NOCAP_THE));
-
- if (player_monster_visible( defender ))
- strcat(info, ", but do no damage.");
- else
- strcat(info, ".");
-
- mpr(info);
- hit = true;
- }
-
-
- if (defender->hit_points < 1)
- {
- monster_die(defender, KILL_YOU, 0);
-
- if (defender->type == MONS_GIANT_SPORE)
- {
- strcpy(info, "You ");
- strcat(info, attack_name);
- strcat(info, "the giant spore.");
- mpr(info);
- }
- else if (defender->type == MONS_BALL_LIGHTNING)
- {
- strcpy(info, "You ");
- strcat(info, attack_name);
- strcat(info, "the ball lightning.");
- mpr(info);
- }
- return (true);
- }
- }
- else
- {
- strcpy(info, "Your ");
- strcat(info, attack_name);
- strcat(info, " misses ");
- strcat(info, ptr_monam(defender, DESC_NOCAP_THE));
- strcat(info, ".");
- mpr(info);
- }
- }
- }
-
- if (hit)
- print_wounds(defender);
-
- return (hit);
-} // end you_attack()
-
-void monster_attack(int monster_attacking)
-{
- struct monsters *attacker = &menv[monster_attacking];
-
- int damage_taken = 0;
- bool hit = false;
- bool blocked = false;
-
- // being attacked by a water creature while standing in water?
- bool water_attack = false;
-
- bool bearing_shield = (you.equip[EQ_SHIELD] != -1);
-
- int mmov_x = 0;
- int specdam = 0;
- char heads = 0; // for hydras {dlb}
- int hand_used = 0;
- int extraDamage = 0; // from special mon. attacks (burn, freeze, etc)
- int resistValue = 0; // player resist value (varies)
- int wpn_speed;
- char str_pass[ ITEMNAME_SIZE ];
-
-#if DEBUG_DIAGNOSTICS
- char st_prn[ 20 ];
-#endif
-
- if (attacker->type == MONS_HYDRA)
- heads = attacker->number;
-
- if (mons_friendly(attacker))
- return;
-
- // This should happen after the mons_friendly check so we're
- // only disturbed by hostiles. -- bwr
- if (you_are_delayed())
- stop_delay();
-
- if (attacker->type == MONS_GIANT_SPORE
- || attacker->type == MONS_BALL_LIGHTNING)
- {
- attacker->hit_points = -1;
- return;
- }
-
- // if a friend wants to help, they can attack <monster_attacking>
- if (you.pet_target == MHITNOT)
- you.pet_target = monster_attacking;
-
- if (mons_has_ench( attacker, ENCH_SUBMERGED ))
- return;
-
- if (you.duration[DUR_REPEL_UNDEAD]
- && mons_holiness( attacker ) == MH_UNDEAD
- && !check_mons_resist_magic( attacker, you.piety ))
- {
- simple_monster_message(attacker,
- " tries to attack you, but is repelled by your holy aura.");
- return;
- }
-
- if (wearing_amulet(AMU_WARDING)
- || (you.religion == GOD_VEHUMET && you.duration[DUR_PRAYER]
- && (!player_under_penance() && you.piety >= 75)))
- {
- if (mons_has_ench(attacker, ENCH_ABJ_I, ENCH_ABJ_VI))
- {
- // should be scaled {dlb}
- if (coinflip())
- {
- simple_monster_message(attacker,
- " tries to attack you, but flinches away.");
- return;
- }
- }
- }
-
- if (grd[attacker->x][attacker->y] == DNGN_SHALLOW_WATER
- && !mons_flies( attacker )
- && !mons_class_flag( attacker->type, M_AMPHIBIOUS )
- && monster_habitat( attacker->type ) == DNGN_FLOOR
- && one_chance_in(4))
- {
- simple_monster_message(attacker, " splashes around in the water.");
- return;
- }
-
- if (player_in_water()
- && !player_is_swimming()
- && monster_habitat( attacker->type ) == DNGN_DEEP_WATER)
- {
- water_attack = true;
- simple_monster_message(attacker,
- " uses the watery terrain to its advantage.");
- }
-
- char runthru;
-
- for (runthru = 0; runthru < 4; runthru++)
- {
- blocked = false;
- wpn_speed = 0; // 0 = didn't attack w/ weapon
-
- if (attacker->type == MONS_HYDRA)
- {
- if (heads < 1)
- break;
- runthru = 0;
- heads--;
- }
-
- char mdam = mons_damage( attacker->type, runthru );
-
- if (attacker->type == MONS_ZOMBIE_SMALL
- || attacker->type == MONS_ZOMBIE_LARGE
- || attacker->type == MONS_SKELETON_SMALL
- || attacker->type == MONS_SKELETON_LARGE
- || attacker->type == MONS_SIMULACRUM_SMALL
- || attacker->type == MONS_SIMULACRUM_LARGE
- || attacker->type == MONS_SPECTRAL_THING)
- {
- mdam = mons_damage(attacker->number, runthru);
-
- // these are cumulative, of course: {dlb}
- if (mdam > 1)
- mdam--;
- if (mdam > 4)
- mdam--;
- if (mdam > 11)
- mdam--;
- if (mdam > 14)
- mdam--;
- }
-
- if (mdam == 0)
- break;
-
- if ((attacker->type == MONS_TWO_HEADED_OGRE
- || attacker->type == MONS_ETTIN)
- && runthru == 1)
- {
- hand_used = 1;
- }
-
- damage_taken = 0;
-
- int mons_to_hit = 16 + attacker->hit_dice; //* attacker->hit_dice;//* 3
-
- if (water_attack)
- mons_to_hit += 5;
-
- if (attacker->inv[hand_used] != NON_ITEM
- && mitm[attacker->inv[hand_used]].base_type == OBJ_WEAPONS)
- {
- mons_to_hit += mitm[attacker->inv[hand_used]].plus;
-
- mons_to_hit += property( mitm[attacker->inv[hand_used]], PWPN_HIT );
-
- wpn_speed = property( mitm[attacker->inv[hand_used]], PWPN_SPEED );
- }
-
- // Factors against blocking
- // [dshaligram] Scaled back HD effect to 50% of previous, reduced
- // shield_blocks multiplier to 5.
- const int con_block =
- random2(15 + attacker->hit_dice / 2
- + (5 * you.shield_blocks * you.shield_blocks));
-
- // Factors for blocking:
- // [dshaligram] Added weighting for shields skill, increased dex bonus
- // from .2 to .25
- const int pro_block =
- random2(player_shield_class())
- + (random2(you.dex) / 4)
- + (random2(skill_bump(SK_SHIELDS)) / 4)
- - 1;
-
- if (!you.paralysis && !you_are_delayed() && !you.conf
- && player_monster_visible( attacker )
- && player_shield_class() > 0
- && con_block <= pro_block)
- {
- you.shield_blocks++;
-
- snprintf( info, INFO_SIZE, "You block %s's attack.",
- ptr_monam( attacker, DESC_NOCAP_THE ) );
-
- mpr(info);
-
- blocked = true;
- hit = false;
-
- if (bearing_shield && one_chance_in(4))
- exercise(SK_SHIELDS, 1);
- }
- else if (player_light_armour() && one_chance_in(3))
- {
- exercise(SK_DODGING, 1);
- }
-
- const int player_dodge = random2limit(player_evasion(), 40)
- + random2(you.dex) / 3
- - (player_monster_visible(attacker) ? 2 : 14)
- - (you_are_delayed() ? 5 : 0);
-
- if (!blocked
- && (random2(mons_to_hit) >= player_dodge || one_chance_in(30)))
- {
- hit = true;
-
- int damage_size = 0;
-
- if (attacker->inv[hand_used] != NON_ITEM
- && mitm[attacker->inv[hand_used]].base_type == OBJ_WEAPONS
- && (mitm[attacker->inv[hand_used]].sub_type < WPN_SLING
- || mitm[attacker->inv[hand_used]].sub_type > WPN_CROSSBOW))
- {
- damage_size = property( mitm[attacker->inv[hand_used]],
- PWPN_DAMAGE );
-
- damage_taken = random2(damage_size);
-
- if (get_equip_race(mitm[attacker->inv[hand_used]]) == ISFLAG_ORCISH
- && mons_species(attacker->type) == MONS_ORC
- && coinflip())
- {
- damage_taken++;
- }
-
- if (mitm[attacker->inv[hand_used]].plus2 >= 0)
- {
- /* + or 0 to-dam */
- damage_taken += random2(mitm[attacker->inv[hand_used]].plus2 + 1);
- }
- else
- {
- /* - to-dam */
- damage_taken -= (random2(1 + abs(mitm[attacker->inv[hand_used]].plus2)));
- }
-
- damage_taken -= 1 + random2(3); //1;
- }
-
- damage_size += mdam;
- damage_taken += 1 + random2(mdam);
-
- if (water_attack)
- damage_taken *= 2;
-
- int ac = player_AC();
-
- if (ac > 0)
- {
- int damage_reduction = random2(ac + 1);
-
- if (!player_light_armour())
- {
- const int body_arm_ac = property( you.inv[you.equip[EQ_BODY_ARMOUR]],
- PARM_AC );
-
- int percent = 2 * (you.skills[SK_ARMOUR] + body_arm_ac);
-
- if (percent > 50)
- percent = 50;
-
- int min = 1 + (damage_size * percent) / 100;
-
- if (min > ac / 2)
- min = ac / 2;
-
- if (damage_reduction < min)
- damage_reduction = min;
- }
-
- damage_taken -= damage_reduction;
- }
-
- if (damage_taken < 1)
- damage_taken = 0;
-
- }
- else if (!blocked)
- {
- hit = false;
- simple_monster_message(attacker, " misses you.");
- }
-
- if (damage_taken < 1 && hit && !blocked)
- {
- simple_monster_message(attacker,
- " hits you but doesn't do any damage.");
- }
-
- if (damage_taken > 0)
- {
- hit = true;
-
- mmov_x = attacker->inv[hand_used];
-
- strcpy(info, ptr_monam(attacker, DESC_CAP_THE));
- strcat(info, " hits you");
-
-#if DEBUG_DIAGNOSTICS
- strcat(info, " for ");
- // note: doesn't take account of special weapons etc
- itoa( damage_taken, st_prn, 10 );
- strcat( info, st_prn );
-#endif
-
- if (attacker->type != MONS_DANCING_WEAPON && mmov_x != NON_ITEM
- && mitm[mmov_x].base_type == OBJ_WEAPONS
- && !launches_things( mitm[mmov_x].sub_type ))
- {
- strcat(info, " with ");
- it_name(mmov_x, DESC_NOCAP_A, str_pass); // was 7
- strcat(info, str_pass);
- }
-
- strcat(info, "!");
-
- mpr( info, MSGCH_PLAIN );
-
- if (hit)
- {
- if (you.equip[EQ_BODY_ARMOUR] != -1)
- {
- const int body_arm_mass = item_mass( you.inv[you.equip[EQ_BODY_ARMOUR]] );
-
- if (!player_light_armour() && coinflip()
- && random2(1000) <= body_arm_mass)
- {
- // raised from 1 {bwross}
- exercise(SK_ARMOUR, (coinflip() ? 2 : 1));
- }
- }
- }
-
- /* special attacks: */
- int mclas = attacker->type;
-
- if (mclas == MONS_KILLER_KLOWN)
- {
- switch (random2(6))
- {
- case 0:
- // comment and enum do not match {dlb}
- mclas = MONS_SNAKE; // scorp
- break;
- case 1:
- mclas = MONS_NECROPHAGE;
- break;
- case 2:
- mclas = MONS_WRAITH;
- break;
- case 3:
- mclas = MONS_FIRE_ELEMENTAL;
- break;
- case 4:
- mclas = MONS_ICE_BEAST;
- break;
- case 5:
- mclas = MONS_PHANTOM;
- break;
- }
- }
-
- switch (mclas)
- {
- case MONS_GILA_MONSTER:
- case MONS_GIANT_ANT:
- case MONS_WOLF_SPIDER:
- case MONS_REDBACK:
- if (player_res_poison())
- break;
-
- if (one_chance_in(20)
- || (damage_taken > 3 && one_chance_in(4)))
- {
- simple_monster_message( attacker,
- "'s bite was poisonous!" );
-
- if (attacker->type == MONS_REDBACK)
- poison_player( random2avg(9, 2) + 3 );
- else
- poison_player(1);
- }
- break;
-
- case MONS_KILLER_BEE:
- case MONS_BUMBLEBEE:
- if (!player_res_poison()
- && (one_chance_in(20)
- || (damage_taken > 2 && one_chance_in(3))))
-
- {
- simple_monster_message( attacker, " stings you!" );
-
- if (attacker->type == MONS_BUMBLEBEE)
- poison_player( random2(3) );
- else
- poison_player(1);
- }
- break;
-
- case MONS_ROTTING_DEVIL:
- case MONS_NECROPHAGE:
- case MONS_GHOUL:
- case MONS_DEATH_OOZE:
- if (you.is_undead)
- break;
-
- // both sides call random2() - looking familiar by now {dlb}
- if (one_chance_in(20) || (damage_taken > 2 && one_chance_in(3)))
- {
- rot_player( 2 + random2(3) );
-
- if (damage_taken > 5)
- rot_hp(1);
- }
-
- if (one_chance_in(4))
- disease_player( 50 + random2(100) );
- break;
-
- case MONS_KOMODO_DRAGON:
- case MONS_GIANT_MOSQUITO:
- if (!one_chance_in(3))
- disease_player( 50 + random2(100) );
- break;
-
- case MONS_FIRE_VORTEX:
- attacker->hit_points = -10;
- // fall through -- intentional? {dlb}
- case MONS_FIRE_ELEMENTAL:
- case MONS_BALRUG:
- case MONS_SUN_DEMON:
- strcpy(info, "You are engulfed in flames");
-
- resistValue = player_res_fire();
- extraDamage = 15 + random2(15);
- if (resistValue > 0)
- {
- extraDamage /= (1 + resistValue * resistValue);
- }
- else
- {
- if (resistValue < 0)
- extraDamage += 8 + random2(8);
- }
-
- strcat(info, (extraDamage < 10) ? "." :
- (extraDamage < 25) ? "!" :
- "!!");
-
- mpr(info);
-
- if (you.duration[DUR_CONDENSATION_SHIELD] > 0)
- {
- mpr("Your icy shield dissipates!", MSGCH_DURATION);
- you.duration[DUR_CONDENSATION_SHIELD] = 0;
- you.redraw_armour_class = 1;
- }
-
- damage_taken += extraDamage;
- scrolls_burn(1, OBJ_SCROLLS);
- break;
-
- case MONS_SMALL_SNAKE:
- case MONS_SNAKE:
- case MONS_GIANT_MITE:
- case MONS_GOLD_MIMIC:
- case MONS_WEAPON_MIMIC:
- case MONS_ARMOUR_MIMIC:
- case MONS_SCROLL_MIMIC:
- case MONS_POTION_MIMIC:
- if (!player_res_poison()
- && (one_chance_in(20)
- || (damage_taken > 2 && one_chance_in(4))))
- {
- poison_player(1);
- }
- break;
-
- case MONS_QUEEN_BEE:
- case MONS_GIANT_CENTIPEDE:
- case MONS_SOLDIER_ANT:
- case MONS_QUEEN_ANT:
- if (!player_res_poison())
- {
- strcpy(info, ptr_monam(attacker, DESC_CAP_THE));
- strcat(info, " stings you!");
- mpr(info);
-
- poison_player(2);
- }
- break;
-
- case MONS_SCORPION:
- case MONS_BROWN_SNAKE:
- case MONS_BLACK_SNAKE:
- case MONS_YELLOW_SNAKE:
- case MONS_SPINY_FROG:
- if (!player_res_poison()
- && (one_chance_in(15)
- || (damage_taken > 2 && one_chance_in(4))))
- // ^^^yep, this should be a function^^^ {dlb}
- {
- strcpy(info, ptr_monam(attacker, DESC_CAP_THE));
- strcat(info, " poisons you!");
- mpr(info);
-
- poison_player(1);
- }
- break;
-
- case MONS_SHADOW_DRAGON:
- case MONS_SPECTRAL_THING:
- if (coinflip())
- break;
- // fall-through {dlb}
- case MONS_WIGHT: // less likely because wights do less damage
- case MONS_WRAITH:
-
- // enum does not match comment 14jan2000 {dlb}
- case MONS_SOUL_EATER: // shadow devil
-
- // enum does not match comment 14jan2000 {dlb}
- case MONS_SPECTRAL_WARRIOR: // spectre
-
- case MONS_SHADOW_FIEND:
- case MONS_ORANGE_RAT:
- case MONS_SHADOW_WRAITH:
- case MONS_ANCIENT_LICH:
- case MONS_LICH:
- case MONS_BORIS:
- if (one_chance_in(30) || (damage_taken > 5 && coinflip()))
- drain_exp();
- break;
-
-
- case MONS_RED_WASP:
- if (!player_res_poison())
- poison_player( (coinflip() ? 2 : 1) );
- // intentional fall-through {dlb}
- case MONS_YELLOW_WASP:
- strcpy(info, ptr_monam(attacker, DESC_CAP_THE));
- strcat(info, " stings you.");
- mpr(info);
-
- if (!player_res_poison()
- && (one_chance_in(20)
- || (damage_taken > 2 && !one_chance_in(3))))
- // maybe I should flip back the other way? {dlb}
- {
- if (you.paralysis > 0)
- mpr("You still can't move!", MSGCH_WARN);
- else
- mpr("You suddenly lose the ability to move!", MSGCH_WARN);
-
- you.paralysis += 1 + random2(3);
- }
- break;
-
- case MONS_SPINY_WORM:
- if (!player_res_poison())
- {
- strcpy(info, ptr_monam(attacker, DESC_CAP_THE));
- strcat(info, " stings you!");
- mpr(info);
-
- poison_player( 2 + random2(4) );
- }
- // intentional fall-through {dlb}
- case MONS_BROWN_OOZE:
- case MONS_ACID_BLOB:
- case MONS_ROYAL_JELLY:
- case MONS_JELLY:
- mpr("You are splashed with acid!");
- splash_with_acid(3);
- break;
-
- case MONS_SIMULACRUM_SMALL:
- case MONS_SIMULACRUM_LARGE:
- strcpy(info, ptr_monam(attacker, DESC_CAP_THE));
-
- resistValue = player_res_cold();
- if (resistValue > 0)
- extraDamage = 0;
- else if (resistValue == 0)
- {
- extraDamage += roll_dice( 1, 4 );
- strcat(info, " chills you.");
- }
- else if (resistValue < 0)
- {
- extraDamage = roll_dice( 2, 4 );
- strcat(info, " freezes you.");
- }
-
- mpr(info);
- damage_taken += extraDamage;
- scrolls_burn( 1, OBJ_POTIONS );
- break;
-
- case MONS_ICE_DEVIL:
- case MONS_ICE_BEAST:
- case MONS_FREEZING_WRAITH:
- case MONS_ICE_FIEND:
- case MONS_WHITE_IMP:
- case MONS_ANTAEUS:
- case MONS_AZURE_JELLY:
- extraDamage = attacker->hit_dice + random2(attacker->hit_dice * 2);
- resistValue = player_res_cold();
-
- if (resistValue > 0)
- {
- extraDamage /= (1 + resistValue * resistValue);
- }
-
- if (resistValue < 0)
- {
- extraDamage += attacker->hit_dice +
- random2(attacker->hit_dice * 2);
- }
-
- if (extraDamage > 4)
- {
- strcpy(info, ptr_monam(attacker, DESC_CAP_THE));
- if (extraDamage < 10)
- strcat(info, " chills you.");
- else
- strcat(info, " freezes you!");
- if (extraDamage > 19)
- strcat(info, "!");
- mpr(info);
- }
-
- damage_taken += extraDamage;
-
- scrolls_burn(1, OBJ_POTIONS);
- break;
-
- case MONS_ELECTRIC_GOLEM:
- if (!player_res_electricity())
- {
- damage_taken += attacker->hit_dice
- + random2(attacker->hit_dice * 2);
-
- strcpy(info, ptr_monam(attacker, DESC_CAP_THE));
- strcat(info, " shocks you!");
- mpr(info);
- }
- break;
-
- case MONS_VAMPIRE:
- if (you.is_undead)
- break;
-
-/* ******************************************************************
- if ( damage_taken > 6 && one_chance_in(3) || !one_chance_in(20))
- {
- mpr("You feel less resilient.");
- you.hp_max -= ( coinflip() ? 2 : 1 );
- deflate_hp(you.hp_max, false);
- heal_monster(attacker, 5 + random2(8), true);
- }
-****************************************************************** */
-
- // heh heh {dlb}
- // oh, this is mean! {gdl}
- if (heal_monster(attacker, random2(damage_taken), true))
- simple_monster_message(attacker, " draws strength from your injuries!");
-
- break;
-
- case MONS_SHADOW:
- if (player_prot_life() <= random2(3)
- && (one_chance_in(20)
- || (damage_taken > 0 && one_chance_in(3))))
- {
- lose_stat(STAT_STRENGTH, 1);
- }
- break;
-
- case MONS_HUNGRY_GHOST:
- if (you.is_undead == US_UNDEAD)
- break;
-
- if (one_chance_in(20) || (damage_taken > 0 && coinflip()))
- make_hungry(400, false);
- break;
-
- case MONS_GUARDIAN_NAGA:
- break;
-
- case MONS_PHANTOM:
- case MONS_INSUBSTANTIAL_WISP:
- case MONS_BLINK_FROG:
- case MONS_MIDGE:
- if (one_chance_in(3))
- {
- simple_monster_message(attacker, " blinks.");
- monster_blink(attacker);
- }
- break;
-
- case MONS_JELLYFISH:
- case MONS_ORANGE_DEMON:
- // if ( !one_chance_in(3) ) break;
- if (player_res_poison())
- break;
-
- if (attacker->type == MONS_ORANGE_DEMON
- && (!one_chance_in(4) || runthru != 1))
- {
- break;
- }
-
- strcpy(info, ptr_monam(attacker, DESC_CAP_THE));
- strcat(info, " stings you!");
- mpr(info);
-
- poison_player(1);
- lose_stat(STAT_STRENGTH, 1);
- break;
-
- case MONS_PULSATING_LUMP:
- if (one_chance_in(3))
- {
- if (one_chance_in(5))
- mutate(100);
- else
- give_bad_mutation();
- }
- break;
- } // end of switch for special attacks.
- /* use brek for level drain, maybe with beam variables,
- because so many creatures use it. */
- }
-
- /* special weapons */
- if (hit
- && (attacker->inv[hand_used] != NON_ITEM
- || ((attacker->type == MONS_PLAYER_GHOST
- || attacker->type == MONS_PANDEMONIUM_DEMON)
- && ghost.values[ GVAL_BRAND ] != SPWPN_NORMAL)))
- {
- unsigned char itdam;
-
- if (attacker->type == MONS_PLAYER_GHOST
- || attacker->type == MONS_PANDEMONIUM_DEMON)
- {
- itdam = ghost.values[ GVAL_BRAND ];
- }
- else
- itdam = mitm[attacker->inv[hand_used]].special;
-
- specdam = 0;
-
- switch (itdam)
- {
- case SPWPN_NORMAL:
- default:
- break;
-
- case SPWPN_SWORD_OF_CEREBOV:
- case SPWPN_FLAMING:
- specdam = 0;
- resistValue = player_res_fire();
-
- if (itdam == SPWPN_SWORD_OF_CEREBOV)
- resistValue -= 1;
-
- if (resistValue > 0)
- {
- damage_taken += (random2(damage_taken) / 2 + 1) /
- (1 + (resistValue * resistValue));
- }
-
- if (resistValue <= 0)
- specdam = random2(damage_taken) / 2 + 1;
-
- if (resistValue < 0)
- specdam += random2(damage_taken) / 2 + 1;
-
- if (specdam)
- {
- simple_monster_message(attacker, " burns you.");
-/* **********************
-
-commented out for now
- if (specdam < 3)
- strcat(info, ".");
- if (specdam >= 3 && specdam < 7)
- strcat(info, "!");
- if (specdam >= 7)
- strcat(info, "!!");
-
-*********************** */
- }
-
- if (you.duration[DUR_CONDENSATION_SHIELD] > 0)
- {
- mpr("Your icy shield dissipates!", MSGCH_DURATION);
- you.duration[DUR_CONDENSATION_SHIELD] = 0;
- you.redraw_armour_class = 1;
- }
- break;
-
- case SPWPN_FREEZING:
- specdam = 0;
- resistValue = player_res_cold();
-
- if (resistValue <= 0)
- specdam = random2(damage_taken) / 2 + 1;
-
- if (resistValue < 0)
- specdam += random2(damage_taken) / 2 + 1;
-
- if (resistValue > 0)
- {
- damage_taken += (random2(damage_taken) / 2 + 1) /
- (1 + (resistValue * resistValue));
- }
-
- if (specdam)
- {
- simple_monster_message(attacker, " freezes you.");
-
-/* **********************
-
-commented out for now
- if (specdam < 3)
- strcat(info, ".");
- if (specdam >= 3 && specdam < 7)
- strcat(info, "!");
- if (specdam >= 7)
- strcat(info, "!!");
-
-*********************** */
- }
- break;
-
-
- case SPWPN_HOLY_WRATH:
- if (attacker->type == MONS_PLAYER_GHOST)
- break; // ghosts can't wield holy wrath
-
- if (you.is_undead)
- {
- specdam = random2(damage_taken);
-
- if (specdam)
- {
- strcpy(info, "The wound is extremely painful");
-
- if (specdam < 3)
- strcat(info, ".");
- else if (specdam < 7)
- strcat(info, "!");
- else
- strcat(info, "!!");
-
- mpr(info);
- }
- }
- break;
-
- case SPWPN_ELECTROCUTION:
- // This runs the risk of making levitation into a
- // cheap version of the Resist spell (with added
- // bonuses), so it shouldn't be used anywhere else,
- // and should possibly be removed from this case as
- // well. -- bwr
- if (player_is_levitating()) // you're not grounded
- break;
-
- if (player_res_electricity()) // resist lightning
- break;
-
- specdam = 0;
-
- // This is related to old code where elec wpns had charges
-#if 0
- if (menv[monster_attacking].type != MONS_PLAYER_GHOST
- && (mitm[attacker->inv[hand_used]].plus2 <= 0
- || item_cursed( mitm[attacker->inv[hand_used]] )))
- {
- break;
- }
-#endif
-
- if (one_chance_in(3))
- {
- mpr("You are electrocuted!");
- specdam += 10 + random2(15);
- }
- break;
-
- case SPWPN_ORC_SLAYING:
- if (you.species == SP_HILL_ORC)
- {
- specdam = random2(damage_taken);
-
- if (specdam)
- {
- strcpy(info, "The wound is extremely painful");
-
- if (specdam < 3)
- strcat(info, ".");
- else if (specdam < 7)
- strcat(info, "!");
- else
- strcat(info, "!!");
-
- mpr(info);
- }
- }
- break;
-
- case SPWPN_STAFF_OF_OLGREB:
- case SPWPN_VENOM:
- if (!player_res_poison() && one_chance_in(3))
- {
- simple_monster_message(attacker,
- (attacker->type == MONS_DANCING_WEAPON)
- ? " is poisoned!" : "'s weapon is poisoned!");
-
- poison_player(2);
- }
- break;
-
- case SPWPN_PROTECTION:
- break;
-
- case SPWPN_DRAINING:
- drain_exp();
- specdam = random2(damage_taken) / (2 + player_prot_life()) + 1;
- break;
-
- case SPWPN_SPEED:
- wpn_speed = (wpn_speed + 1) / 2;
- break;
-
- case SPWPN_VORPAL:
- specdam = 1 + (random2(damage_taken) / 2);
- break;
-
- case SPWPN_VAMPIRES_TOOTH:
- case SPWPN_VAMPIRICISM:
- specdam = 0; // note does no extra damage
-
- if (you.is_undead)
- break;
-
- if (one_chance_in(5))
- break;
-
- // heh heh {dlb}
- if (heal_monster(attacker, 1 + random2(damage_taken), true))
- simple_monster_message(attacker, " draws strength from your injuries!");
- break;
-
- case SPWPN_DISRUPTION:
- if (attacker->type == MONS_PLAYER_GHOST)
- break;
-
- if (you.is_undead)
- {
- specdam = random2(damage_taken) + random2(damage_taken)
- + random2(damage_taken) + random2(damage_taken);
-
- if (specdam)
- {
- strcpy(info, "You are blasted by holy energy");
-
- if (specdam < 7)
- strcat(info, ".");
- else if (specdam < 15)
- strcat(info, "!");
- else
- strcat(info, "!!");
-
- mpr(info);
- }
- }
- break;
-
-
- case SPWPN_DISTORTION:
- //if ( !one_chance_in(3) ) break;
-
- if (one_chance_in(3))
- {
- mpr("Your body is twisted painfully.");
- specdam += 1 + random2avg(7, 2);
- break;
- }
-
- if (one_chance_in(3))
- {
- mpr("Your body is terribly warped!");
- specdam += 3 + random2avg(24, 2);
- break;
- }
-
- if (one_chance_in(3))
- {
- random_blink(true);
- break;
- }
-
- if (coinflip())
- {
- you_teleport();
- break;
- }
-
- if (coinflip())
- {
- you_teleport2( true, one_chance_in(5) );
- break;
- }
-
- if (coinflip() && you.level_type != LEVEL_ABYSS)
- {
- banished(DNGN_ENTER_ABYSS);
- break;
- }
- break;
- } // end of switch
- } // end of special weapons
-
- damage_taken += specdam;
-
- if (damage_taken > 0)
- {
- ouch(damage_taken, monster_attacking, KILLED_BY_MONSTER);
-
- if (you.religion == GOD_XOM && you.hp <= you.hp_max / 3
- && one_chance_in(10))
- {
- Xom_acts(true, you.experience_level, false);
- }
- }
-
- // adjust time taken if monster used weapon
- if (wpn_speed > 0)
- {
- // only get one third penalty/bonus for second weapons.
- if (runthru > 0)
- wpn_speed = (20 + wpn_speed) / 3;
-
- attacker->speed_increment -= (wpn_speed - 10) / 2;
- }
- } // end of for runthru
-
- return;
-} // end monster_attack()
-
-bool monsters_fight(int monster_attacking, int monster_attacked)
-{
- struct monsters *attacker = &menv[monster_attacking];
- struct monsters *defender = &menv[monster_attacked];
-
- int weapon = -1; // monster weapon, if any
- int damage_taken = 0;
- bool hit = false;
- int mmov_x = 0;
- bool water_attack = false;
- int specdam = 0;
- int hand_used = 0;
- bool sees = false;
- int wpn_speed; // 0 == didn't use actual weapon
- int habitat = monster_habitat( attacker->type );
- char str_pass[ ITEMNAME_SIZE ];
-
-#if DEBUG_DIAGNOSTICS
- char st_prn[ 20 ];
-#endif
-
- if (attacker->type == MONS_GIANT_SPORE
- || attacker->type == MONS_BALL_LIGHTNING)
- {
- attacker->hit_points = -1;
- return false;
- }
-
- if (mons_has_ench( attacker, ENCH_SUBMERGED )
- && habitat != DNGN_FLOOR
- && habitat != monster_habitat( defender->type ))
- {
- return false;
- }
-
- if (grd[attacker->x][attacker->y] == DNGN_SHALLOW_WATER
- && !mons_flies( attacker )
- && !mons_class_flag( attacker->type, M_AMPHIBIOUS )
- && habitat == DNGN_FLOOR
- && one_chance_in(4))
- {
- mpr("You hear a splashing noise.");
- return true;
- }
-
- if (grd[defender->x][defender->y] == DNGN_SHALLOW_WATER
- && !mons_flies(defender)
- && habitat == DNGN_DEEP_WATER)
- {
- water_attack = true;
- }
-
- if (mons_near(attacker) && mons_near(defender))
- sees = true;
-
- // now disturb defender, regardless
- behaviour_event(defender, ME_WHACK, monster_attacking);
-
- char runthru;
-
- for (runthru = 0; runthru < 4; runthru++)
- {
- char mdam = mons_damage(attacker->type, runthru);
- wpn_speed = 0;
-
- if (attacker->type == MONS_ZOMBIE_SMALL
- || attacker->type == MONS_ZOMBIE_LARGE
- || attacker->type == MONS_SKELETON_SMALL
- || attacker->type == MONS_SKELETON_LARGE
- || attacker->type == MONS_SIMULACRUM_SMALL
- || attacker->type == MONS_SIMULACRUM_LARGE
- || attacker->type == MONS_SPECTRAL_THING)
- // what do these things have in common? {dlb}
- {
- mdam = mons_damage(attacker->number, runthru);
- // cumulative reductions - series of if-conditions
- // is necessary: {dlb}
- if (mdam > 1)
- mdam--;
- if (mdam > 2)
- mdam--;
- if (mdam > 5)
- mdam--;
- if (mdam > 9)
- mdam--; // was: "-= 2" {dlb}
- }
-
- if (mdam == 0)
- break;
-
- if ((attacker->type == MONS_TWO_HEADED_OGRE
- || attacker->type == MONS_ETTIN)
- && runthru == 1 && attacker->inv[MSLOT_MISSILE] != NON_ITEM)
- {
- hand_used = 1;
- }
-
- damage_taken = 0;
-
- int mons_to_hit = 20 + attacker->hit_dice * 5;
- // * menv [monster_attacking].hit_dice; // * 3
-
- if (water_attack)
- mons_to_hit += 5;
-
- weapon = attacker->inv[hand_used];
-
- if (weapon != NON_ITEM)
- {
- mons_to_hit += mitm[weapon].plus;
- // mons_to_hit += 3 * property( mitm[weapon], PWPN_HIT );
- mons_to_hit += property( mitm[weapon], PWPN_HIT );
-
- wpn_speed = property( mitm[ weapon ], PWPN_SPEED );
- }
-
- mons_to_hit = random2(mons_to_hit);
-
- if (mons_to_hit >= defender->evasion
- || ((defender->speed_increment <= 60
- || defender->behaviour == BEH_SLEEP) && !one_chance_in(20)))
- {
- hit = true;
-
- if (attacker->inv[hand_used] != NON_ITEM
- && mitm[attacker->inv[hand_used]].base_type == OBJ_WEAPONS
- && !launches_things( mitm[attacker->inv[hand_used]].sub_type ))
- {
- damage_taken = random2(property( mitm[attacker->inv[hand_used]],
- PWPN_DAMAGE ));
-
- if (get_equip_race(mitm[attacker->inv[hand_used]]) == ISFLAG_ORCISH
- && mons_species(attacker->type) == MONS_ORC
- && coinflip())
- {
- damage_taken++;
- }
-
- //if (mitm[mons_inv[i][0]].plus > 80) damage_taken -= 100;
- // damage_taken += mitm[mons_inv[i][0]].plus;
-
- if (mitm[attacker->inv[hand_used]].plus2 >= 0)
- {
- /* + or 0 to-dam */
- damage_taken += random2(mitm[attacker->inv[hand_used]].plus2 + 1);
- }
- else
- {
- /* - to-dam */
- damage_taken -= random2(abs(mitm[attacker->inv[hand_used]].plus2 + 1));
- }
-
- damage_taken -= 1 + random2(3); //1;
- }
-
- damage_taken += 1 + random2(mdam);
-
- if (water_attack)
- damage_taken *= 2;
-
- damage_taken -= random2(1 + defender->armour_class);
-
- if (damage_taken < 1)
- damage_taken = 0;
- }
- else
- {
- hit = false;
-
- if (sees)
- {
- strcpy(info, ptr_monam(attacker, DESC_CAP_THE));
- strcat(info, " misses ");
- strcat(info, ptr_monam(defender, DESC_NOCAP_THE));
- strcat(info, ".");
- mpr(info);
- }
- }
-
- if (damage_taken < 1 && hit)
- {
- if (sees)
- {
- strcpy(info, ptr_monam(attacker, DESC_CAP_THE));
- strcat(info, " hits ");
- strcat(info, ptr_monam(defender, DESC_NOCAP_THE));
-
-#if DEBUG_DIAGNOSTICS
- strcat(info, " for ");
- // note: doesn't take account of special weapons etc
- itoa(damage_taken, st_prn, 10);
- strcat(info, st_prn);
-#endif
- strcat(info, "."); // but doesn't do any you.damage.");
- mpr(info);
- }
- }
-
- if (hit) //(int) damage_taken > 0)
- {
- int mmov_x = attacker->inv[hand_used];
-
- if (sees)
- {
- strcpy(info, ptr_monam(attacker, DESC_CAP_THE));
- strcat(info, " hits ");
- strcat(info, ptr_monam(defender, DESC_NOCAP_THE));
-
- if (attacker->type != MONS_DANCING_WEAPON
- && attacker->inv[hand_used] != NON_ITEM
- && mitm[attacker->inv[hand_used]].base_type == OBJ_WEAPONS
- && !launches_things( mitm[attacker->inv[hand_used]].sub_type ))
- {
- strcat(info, " with ");
- it_name(mmov_x, DESC_NOCAP_A, str_pass); // was 7
- strcat(info, str_pass);
- }
-
- strcat(info, "! ");
- mpr(info);
- }
-
- // special attacks:
- switch (attacker->type)
- {
- // enum does not match comment 14jan2000 {dlb}
- case MONS_CENTAUR: // cockatrice
- case MONS_JELLY:
- case MONS_GUARDIAN_NAGA:
- break;
-
- case MONS_GIANT_ANT:
- case MONS_WOLF_SPIDER:
- case MONS_REDBACK:
- case MONS_SPINY_WORM:
- case MONS_JELLYFISH:
- case MONS_ORANGE_DEMON:
- if (attacker->type == MONS_SPINY_WORM || one_chance_in(20)
- || (damage_taken > 3 && one_chance_in(4)))
- {
- if (sees)
- {
- strcpy(info, ptr_monam(attacker, DESC_CAP_THE));
- strcat(info, " stings ");
- strcat(info, ptr_monam(defender, DESC_NOCAP_THE));
- strcat(info, ".");
- mpr(info);
- }
- poison_monster(defender, false);
- }
- break;
-
- case MONS_KILLER_BEE:
- case MONS_BUMBLEBEE:
- if (one_chance_in(20)
- || (damage_taken > 2 && one_chance_in(3)))
- {
- if (sees)
- {
- strcpy(info, ptr_monam(attacker, DESC_CAP_THE));
- strcat(info, " stings ");
- strcpy(info, ptr_monam(defender, DESC_NOCAP_THE));
- strcat(info, ".");
- mpr(info);
- }
- poison_monster(defender, false);
- }
- break;
-
- case MONS_NECROPHAGE:
- case MONS_ROTTING_DEVIL:
- case MONS_GHOUL:
- case MONS_DEATH_OOZE:
- if (mons_res_negative_energy( defender ))
- break;
-
- if (one_chance_in(20)
- || (damage_taken > 2 && one_chance_in(3)))
- {
- defender->max_hit_points -= 1 + random2(3);
-
- if (defender->hit_points > defender->max_hit_points)
- defender->hit_points = defender->max_hit_points;
- }
- break;
-
- case MONS_FIRE_VORTEX:
- attacker->hit_points = -10;
- // deliberate fall-through
- case MONS_FIRE_ELEMENTAL:
- case MONS_BALRUG:
- case MONS_SUN_DEMON:
- specdam = 0;
- if (mons_res_fire(defender) == 0)
- specdam = 15 + random2(15);
- else if (mons_res_fire(defender) < 0)
- specdam = 20 + random2(25);
-
- if (specdam)
- simple_monster_message(defender, " is engulfed in flame!");
-
- damage_taken += specdam;
- break;
-
- case MONS_QUEEN_BEE:
- case MONS_GIANT_CENTIPEDE:
- case MONS_SOLDIER_ANT:
- case MONS_QUEEN_ANT:
- //if ((damage_taken > 2 && one_chance_in(3) ) || one_chance_in(20) )
- //{
- if (sees)
- {
- strcpy(info, ptr_monam(attacker, DESC_CAP_THE));
- strcat(info, " stings ");
- strcat(info, ptr_monam(defender, DESC_NOCAP_THE));
- strcat(info, ".");
- mpr(info);
- }
- poison_monster(defender, false);
- //}
- break;
-
- // enum does not match comment 14jan2000 {dlb}
- case MONS_SCORPION: // snake
- case MONS_BROWN_SNAKE:
- case MONS_BLACK_SNAKE:
- case MONS_YELLOW_SNAKE:
- case MONS_GOLD_MIMIC:
- case MONS_WEAPON_MIMIC:
- case MONS_ARMOUR_MIMIC:
- case MONS_SCROLL_MIMIC:
- case MONS_POTION_MIMIC:
- if (one_chance_in(20) || (damage_taken > 2 && one_chance_in(4)))
- poison_monster(defender, false);
- break;
-
- case MONS_SHADOW_DRAGON:
- case MONS_SPECTRAL_THING:
- if (coinflip())
- break;
- // intentional fall-through
- case MONS_WIGHT:
- case MONS_WRAITH:
- case MONS_SOUL_EATER:
- case MONS_SHADOW_FIEND:
- case MONS_SPECTRAL_WARRIOR:
- case MONS_ORANGE_RAT:
- case MONS_ANCIENT_LICH:
- case MONS_LICH:
- case MONS_BORIS:
- if (mons_res_negative_energy( defender ))
- break;
-
- if (one_chance_in(30) || (damage_taken > 5 && coinflip()))
- {
- simple_monster_message(defender, " is drained.");
-
- if (one_chance_in(5))
- defender->hit_dice--;
-
- defender->max_hit_points -= 2 + random2(3);
- defender->hit_points -= 2 + random2(3);
-
- if (defender->hit_points >= defender->max_hit_points)
- defender->hit_points = defender->max_hit_points;
-
- if (defender->hit_points < 1 || defender->hit_dice < 1)
- {
- monster_die(defender, KILL_MON, monster_attacking);
- return true;
- }
- }
- break;
-
- // enum does not match comment 14jan2000 {dlb}
- case MONS_WORM: // giant wasp
- break;
-
- case MONS_SIMULACRUM_SMALL:
- case MONS_SIMULACRUM_LARGE:
- specdam = 0;
-
- if (mons_res_cold(defender) == 0)
- specdam = roll_dice( 1, 4 );
- else if (mons_res_cold(defender) < 0)
- specdam = roll_dice( 2, 4 );
-
- if (specdam && sees)
- {
- strcpy(info, ptr_monam(attacker, DESC_CAP_THE));
- strcat(info, " freezes ");
- strcat(info, ptr_monam(defender, DESC_NOCAP_THE));
- strcat(info, ".");
- mpr(info);
- }
-
- damage_taken += specdam;
- break;
-
- case MONS_ICE_DEVIL:
- case MONS_ICE_BEAST:
- case MONS_FREEZING_WRAITH:
- case MONS_ICE_FIEND:
- case MONS_WHITE_IMP:
- case MONS_AZURE_JELLY:
- case MONS_ANTAEUS:
- specdam = 0;
- if (mons_res_cold(defender) == 0)
- {
- specdam = attacker->hit_dice + random2(attacker->hit_dice * 2);
- }
- else if (mons_res_cold(defender) < 0)
- {
- specdam = random2(attacker->hit_dice * 3) + (attacker->hit_dice * 2);
- }
-
- if (specdam && sees)
- {
- strcpy(info, ptr_monam(attacker, DESC_CAP_THE));
- strcat(info, " freezes ");
- strcat(info, ptr_monam(defender, DESC_NOCAP_THE));
- strcat(info, ".");
- mpr(info);
- }
- damage_taken += specdam;
- break;
-
- case MONS_ELECTRIC_GOLEM:
- if (mons_flies(defender) == 0 && mons_res_elec(defender) == 0)
- {
- specdam = attacker->hit_dice + random2(attacker->hit_dice * 2);
- }
-
- if (specdam && sees)
- {
- strcpy(info, ptr_monam(attacker, DESC_CAP_THE));
- strcat(info, " shocks ");
- strcat(info, ptr_monam(defender, DESC_NOCAP_THE));
- strcat(info, ".");
- mpr(info);
- }
- damage_taken += specdam;
- break;
-
- case MONS_VAMPIRE:
- case MONS_VAMPIRE_KNIGHT:
- case MONS_VAMPIRE_MAGE:
- if (mons_res_negative_energy(defender) > 0)
- break;
-
- // heh heh {dlb}
- if (heal_monster(attacker, random2(damage_taken), true))
- simple_monster_message(attacker, " is healed.");
- break;
- }
- }
-
- // special weapons:
- if (hit
- && (attacker->inv[hand_used] != NON_ITEM
- || ((attacker->type == MONS_PLAYER_GHOST
- || attacker->type == MONS_PANDEMONIUM_DEMON)
- && ghost.values[ GVAL_BRAND ] != SPWPN_NORMAL)))
- {
- unsigned char itdam;
-
- if (attacker->type == MONS_PLAYER_GHOST
- || attacker->type == MONS_PANDEMONIUM_DEMON)
- {
- itdam = ghost.values[ GVAL_BRAND ];
- }
- else
- itdam = mitm[attacker->inv[hand_used]].special;
-
- specdam = 0;
-
- if (attacker->type == MONS_PLAYER_GHOST
- || attacker->type == MONS_PANDEMONIUM_DEMON)
- {
- switch (itdam)
- {
- case SPWPN_NORMAL:
- default:
- break;
-
- case SPWPN_SWORD_OF_CEREBOV:
- case SPWPN_FLAMING:
- specdam = 0;
-
- if (itdam == SPWPN_SWORD_OF_CEREBOV
- || mons_res_fire(defender) <= 0)
- {
- specdam = 1 + random2(damage_taken);
- }
-
- if (specdam)
- {
- if (sees)
- {
- strcpy(info, ptr_monam(attacker, DESC_CAP_THE));
- strcat(info, " burns ");
- strcat(info, ptr_monam(defender, DESC_NOCAP_THE ));
-
- if (specdam < 3)
- strcat(info, ".");
- else if (specdam < 7)
- strcat(info, "!");
- else
- strcat(info, "!!");
-
- mpr(info);
- }
- }
- break;
-
- case SPWPN_FREEZING:
- specdam = 0;
-
- if (mons_res_cold(defender) <= 0)
- specdam = 1 + random2(damage_taken);
-
- if (specdam)
- {
- if (sees)
- {
- mmov_x = attacker->inv[hand_used];
-
- strcpy(info, ptr_monam(attacker, DESC_CAP_THE));
- strcat(info, " freezes ");
- strcat(info, ptr_monam(defender, DESC_NOCAP_THE));
-
- if (specdam < 3)
- strcat(info, ".");
- else if (specdam < 7)
- strcat(info, "!");
- else
- strcat(info, "!!");
-
- mpr(info);
- }
- }
- break;
-
- case SPWPN_HOLY_WRATH:
- if (attacker->type == MONS_PLAYER_GHOST)
- break;
- specdam = 0;
- switch (mons_holiness(defender))
- {
- case MH_HOLY:
- // I would think that it would do zero damage {dlb}
- damage_taken -= 5 + random2(5);
- break;
-
- case MH_UNDEAD:
- specdam += 1 + random2(damage_taken);
- break;
-
- case MH_DEMONIC:
- specdam += 1 + (random2(damage_taken) * 15) / 10;
- break;
-
- default:
- break;
- }
- break;
-
- case SPWPN_ELECTROCUTION:
- //if ( attacker->type == MONS_PLAYER_GHOST ) break;
- if (mons_flies(defender) > 0 || mons_res_elec(defender) > 0)
- break;
-
- specdam = 0;
-
-#if 0
- // more of the old code... -- bwr
- if (menv[monster_attacking].type != MONS_PLAYER_GHOST
- && (mitm[attacker->inv[hand_used]].plus2 <= 0
- || item_cursed( mitm[attacker->inv[hand_used]] )))
- {
- break;
- }
-#endif
-
- if (one_chance_in(3))
- {
- if (sees)
- mpr("There is a sudden explosion of sparks!");
-
- specdam += 10 + random2(15);
- //mitm[attacker->inv[hand_used]].plus2 --;
- }
- break;
-
- case SPWPN_ORC_SLAYING:
- if (mons_species(defender->type) == MONS_ORC)
- hurt_monster(defender, 1 + random2(damage_taken));
- break;
-
- case SPWPN_STAFF_OF_OLGREB:
- case SPWPN_VENOM:
- if (!one_chance_in(3))
- poison_monster(defender, false);
- break;
-
- //case 7: // protection
-
- case SPWPN_DRAINING:
- if (!mons_res_negative_energy( defender )
- && (one_chance_in(30)
- || (damage_taken > 5 && coinflip())))
- {
- simple_monster_message(defender, " is drained");
-
- if (one_chance_in(5))
- defender->hit_dice--;
-
- defender->max_hit_points -= 2 + random2(3);
- defender->hit_points -= 2 + random2(3);
-
- if (defender->hit_points >= defender->max_hit_points)
- defender->hit_points = defender->max_hit_points;
-
- if (defender->hit_points < 1
- || defender->hit_dice < 1)
- {
- monster_die(defender, KILL_MON, monster_attacking);
- return true;
- }
- specdam = 1 + (random2(damage_taken) / 2);
- }
- break;
-
- case SPWPN_SPEED:
- wpn_speed = (wpn_speed + 1) / 2;
- break;
-
- case SPWPN_VORPAL:
- specdam += 1 + (random2(damage_taken) / 2);
- break;
-
- case SPWPN_VAMPIRES_TOOTH:
- case SPWPN_VAMPIRICISM:
- specdam = 0; // note does no extra damage
-
- if (mons_res_negative_energy( defender ))
- break;
-
- if (one_chance_in(5))
- break;
-
- // heh heh {dlb}
- if (heal_monster(attacker, 1 + random2(damage_taken), true))
- simple_monster_message(attacker, " is healed.");
- break;
-
- case SPWPN_DISRUPTION:
- if (attacker->type == MONS_PLAYER_GHOST)
- break;
-
- specdam = 0;
-
- if (mons_holiness(defender) == MH_UNDEAD
- && !one_chance_in(3))
- {
- simple_monster_message(defender, " shudders.");
- specdam += random2avg(1 + (3 * damage_taken), 3);
- }
- break;
-
-
- case SPWPN_DISTORTION:
- if (one_chance_in(3))
- {
- if (mons_near(defender)
- && player_monster_visible(defender))
- {
- strcpy(info, "Space bends around ");
- strcat(info, ptr_monam(defender, DESC_NOCAP_THE));
- strcat(info, ".");
- mpr(info);
- }
-
- specdam += 1 + random2avg(7, 2);
- break;
- }
- if (one_chance_in(3))
- {
- if (mons_near(defender)
- && player_monster_visible(defender))
- {
- strcpy(info, "Space warps horribly around ");
- strcat(info, ptr_monam(defender, DESC_NOCAP_THE));
- strcat(info, "!");
- mpr(info);
- }
-
- specdam += 3 + random2avg(24, 2);
- break;
- }
-
- if (one_chance_in(3))
- {
- monster_blink(defender);
- break;
- }
-
- if (coinflip())
- {
- monster_teleport(defender, coinflip());
- break;
- }
-
- if (coinflip())
- {
- monster_die(defender, KILL_RESET, monster_attacking);
- break;
- }
- break;
- }
- }
- } // end of if special weapon
-
- damage_taken += specdam;
-
- if (damage_taken > 0)
- {
- hurt_monster(defender, damage_taken);
-
- if (defender->hit_points < 1)
- {
- monster_die(defender, KILL_MON, monster_attacking);
- return true;
- }
- }
-
- // speed adjustment for weapon using monsters
- if (wpn_speed > 0)
- {
- // only get one third penalty/bonus for second weapons.
- if (runthru > 0)
- wpn_speed = (20 + wpn_speed) / 3;
-
- attacker->speed_increment -= (wpn_speed - 10) / 2;
- }
- } // end of for runthru
-
- return true;
-} // end monsters_fight()
-
-
-/*
- **************************************************
- * *
- * END PUBLIC FUNCTIONS *
- * *
- **************************************************
-*/
-
-
-// Added by DML 6/10/99.
-// For now, always returns damage: that is, it never modifies values,
-// just adds 'color'.
-static int weapon_type_modify( int weapnum, char noise[80], char noise2[80],
- int damage )
-{
- int weap_type = WPN_UNKNOWN;
-
- if (weapnum == -1)
- weap_type = WPN_UNARMED;
- else if (item_is_staff( you.inv[weapnum] ))
- weap_type = WPN_QUARTERSTAFF;
- else if (you.inv[weapnum].base_type == OBJ_WEAPONS)
- weap_type = you.inv[weapnum].sub_type;
-
- noise2[0] = '\0';
-
- // All weak hits look the same, except for when the player
- // has a non-weapon in hand. -- bwr
- if (damage < HIT_WEAK)
- {
- if (weap_type != WPN_UNKNOWN)
- strcpy( noise, "hit" );
- else
- strcpy( noise, "clumsily bash" );
-
- return (damage);
- }
-
- // take transformations into account, if no weapon is weilded
- if (weap_type == WPN_UNARMED
- && you.attribute[ATTR_TRANSFORMATION] != TRAN_NONE)
- {
- switch (you.attribute[ATTR_TRANSFORMATION])
- {
- case TRAN_SPIDER:
- if (damage < HIT_STRONG)
- strcpy( noise, "bite" );
- else
- strcpy( noise, "maul" );
- break;
- case TRAN_BLADE_HANDS:
- if (damage < HIT_MED)
- strcpy( noise, "slash" );
- else if (damage < HIT_STRONG)
- strcpy( noise, "slice" );
- else
- strcpy( noise, "shred" );
- break;
- case TRAN_ICE_BEAST:
- case TRAN_STATUE:
- case TRAN_LICH:
- if (damage < HIT_MED)
- strcpy( noise, "punch" );
- else
- strcpy( noise, "pummel" );
- break;
- case TRAN_DRAGON:
- case TRAN_SERPENT_OF_HELL:
- if (damage < HIT_MED)
- strcpy( noise, "claw" );
- else if (damage < HIT_STRONG)
- strcpy( noise, "bite" );
- else
- strcpy( noise, "maul" );
- break;
- case TRAN_AIR:
- strcpy( noise, "buffet" );
- break;
- } // transformations
-
- return (damage);
- }
-
- switch (weap_type)
- {
- case WPN_KNIFE:
- case WPN_DAGGER:
- case WPN_SHORT_SWORD:
- case WPN_TRIDENT:
- case WPN_DEMON_TRIDENT:
- case WPN_SPEAR:
- if (damage < HIT_MED)
- strcpy( noise, "puncture" );
- else if (damage < HIT_STRONG)
- strcpy( noise, "impale" );
- else
- {
- strcpy( noise, "spit" );
- strcpy( noise2, " like a pig" );
- }
- return (damage);
-
- case WPN_BOW:
- case WPN_LONGBOW:
- case WPN_CROSSBOW:
- case WPN_HAND_CROSSBOW:
- if (damage < HIT_STRONG)
- strcpy( noise, "puncture" );
- else
- strcpy( noise, "skewer" );
- return (damage);
-
- case WPN_LONG_SWORD:
- case WPN_GREAT_SWORD:
- case WPN_SCIMITAR:
- case WPN_FALCHION:
- case WPN_HALBERD:
- case WPN_GLAIVE:
- case WPN_HAND_AXE:
- case WPN_WAR_AXE:
- case WPN_BROAD_AXE:
- case WPN_BATTLEAXE:
- case WPN_SCYTHE:
- case WPN_QUICK_BLADE:
- case WPN_KATANA:
- case WPN_LAJATANG:
- case WPN_EXECUTIONERS_AXE:
- case WPN_DOUBLE_SWORD:
- case WPN_TRIPLE_SWORD:
- case WPN_SABRE:
- case WPN_DEMON_BLADE:
- case WPN_BLESSED_BLADE:
- if (damage < HIT_MED)
- strcpy( noise, "slash" );
- else if (damage < HIT_STRONG)
- strcpy( noise, "slice" );
- else
- {
- strcpy( noise, "open" );
- strcpy( noise2, " like a pillowcase" );
- }
- return (damage);
-
- case WPN_SLING:
- case WPN_CLUB:
- case WPN_MACE:
- case WPN_FLAIL:
- case WPN_GREAT_MACE:
- case WPN_DIRE_FLAIL:
- case WPN_QUARTERSTAFF:
- case WPN_GIANT_CLUB:
- case WPN_HAMMER:
- case WPN_ANCUS:
- case WPN_MORNINGSTAR: /*for now, just a bludgeoning weapon */
- case WPN_SPIKED_FLAIL: /*for now, just a bludgeoning weapon */
- case WPN_EVENINGSTAR:
- case WPN_GIANT_SPIKED_CLUB:
- if (damage < HIT_MED)
- strcpy( noise, "sock" );
- else if (damage < HIT_STRONG)
- strcpy( noise, "bludgeon" );
- else
- {
- strcpy( noise, "crush" );
- strcpy( noise2, " like a grape" );
- }
- return (damage);
-
- case WPN_WHIP:
- case WPN_DEMON_WHIP:
- if (damage < HIT_MED)
- strcpy( noise, "whack" );
- else
- strcpy( noise, "thrash" );
- return (damage);
-
- case WPN_UNARMED:
- if (you.species == SP_TROLL || you.mutation[MUT_CLAWS])
- {
- if (damage < HIT_MED)
- strcpy( noise, "claw" );
- else if (damage < HIT_STRONG)
- strcpy( noise, "mangle" );
- else
- strcpy( noise, "eviscerate" );
- }
- else
- {
- if (damage < HIT_MED)
- strcpy( noise, "punch" );
- else
- strcpy( noise, "pummel" );
- }
- return (damage);
-
- case WPN_UNKNOWN:
- default:
- strcpy( noise, "hit" );
- return (damage);
- }
-} // end weapon_type_modify()
-
-// Returns a value between 0 and 10 representing the weight given to str
-int weapon_str_weight( int wpn_class, int wpn_type )
-{
- int ret;
-
- const int wpn_skill = weapon_skill( wpn_class, wpn_type );
- const int hands_reqd = hands_reqd_for_weapon( wpn_class, wpn_type );
-
- // These are low values, because we'll be adding some bonus to the
- // larger weapons later. Remember also that 1-1/2-hand weapons get
- // a bonus in player_weapon_str_weight() as well (can't be done
- // here because this function is used for cases where the weapon
- // isn't being used by the player).
-
- // Reasonings:
- // - Short Blades are the best for the dexterous... although they
- // are very limited in damage potential
- // - Long Swords are better for the dexterous, the two-handed
- // swords are a 50/50 split; bastard swords are in between.
- // - Staves: didn't want to punish the mages who want to use
- // these... made it a 50/50 split after the 2-hnd bonus
- // - Polearms: Spears and tridents are the only ones that can
- // be used one handed and are poking weapons, which requires
- // more agility than strength. The other ones also require a
- // fair amount of agility so they end up at 50/50 (most can poke
- // as well as slash... although slashing is not their strong
- // point).
- // - Axes are weighted and edged and so require mostly strength,
- // but not as much as Maces and Flails, which are typically
- // blunt and spiked weapons.
- switch (wpn_skill)
- {
- case SK_SHORT_BLADES: ret = 2; break;
- case SK_LONG_SWORDS: ret = 3; break;
- case SK_STAVES: ret = 3; break; // == 5 after 2-hand bonus
- case SK_POLEARMS: ret = 3; break; // most are +2 for 2-hands
- case SK_AXES: ret = 6; break;
- case SK_MACES_FLAILS: ret = 7; break;
- default: ret = 5; break;
- }
-
- // whips are special cased (because they are not much like maces)
- if (wpn_type == WPN_WHIP || wpn_type == WPN_DEMON_WHIP)
- ret = 2;
- else if (wpn_type == WPN_QUICK_BLADE) // high dex is very good for these
- ret = 1;
-
- if (hands_reqd == HANDS_TWO)
- ret += 2;
-
- // most weapons are capped at 8
- if (ret > 8)
- {
- // these weapons are huge, so strength plays a larger role
- if (wpn_type == WPN_GIANT_CLUB || wpn_type == WPN_GIANT_SPIKED_CLUB)
- ret = 9;
- else
- ret = 8;
- }
-
- return (ret);
-}
-
-// Returns a value from 0 to 10 representing the weight of strength to
-// dexterity for the players currently wielded weapon.
-static inline int player_weapon_str_weight( void )
-{
- const int weapon = you.equip[ EQ_WEAPON ];
-
- // unarmed, weighted slightly towards dex -- would have been more,
- // but then we'd be punishing Trolls and Ghouls who are strong and
- // get special unarmed bonuses.
- if (weapon == -1)
- return (4);
-
- int ret = weapon_str_weight( you.inv[weapon].base_type, you.inv[weapon].sub_type );
-
- const bool shield = (you.equip[EQ_SHIELD] != -1);
- const int hands_reqd = hands_reqd_for_weapon( you.inv[weapon].base_type,
- you.inv[weapon].sub_type );
-
- if (hands_reqd == HANDS_HALF && !shield)
- ret += 1;
-
- return (ret);
-}
-
-// weapon_dex_weight() + weapon_str_weight == 10 so we only need define
-// one of these.
-static inline int player_weapon_dex_weight( void )
-{
- return (10 - player_weapon_str_weight());
-}
-
-static inline int calc_stat_to_hit_base( void )
-{
-#ifdef USE_NEW_COMBAT_STATS
-
- // towards_str_avg is a variable, whose sign points towards strength,
- // and the magnitude is half the difference (thus, when added directly
- // to you.dex it gives the average of the two.
- const signed int towards_str_avg = (you.strength - you.dex) / 2;
-
- // dex is modified by strength towards the average, by the
- // weighted amount weapon_str_weight() / 10.
- return (you.dex + towards_str_avg * player_weapon_str_weight() / 10);
-
-#else
- return (you.dex);
-#endif
-}
-
-
-static inline int calc_stat_to_dam_base( void )
-{
-#ifdef USE_NEW_COMBAT_STATS
-
- const signed int towards_dex_avg = (you.dex - you.strength) / 2;
- return (you.strength + towards_dex_avg * player_weapon_dex_weight() / 10);
-
-#else
- return (you.strength);
-#endif
-}
-
-static void stab_message( struct monsters *defender, int stab_bonus )
-{
- int r = random2(6); // for randomness
-
- switch(stab_bonus)
- {
- case 3: // big melee, monster surrounded/not paying attention
- if (r<3)
- {
- snprintf( info, INFO_SIZE, "You strike %s from a blind spot!",
- ptr_monam(defender, DESC_NOCAP_THE) );
- }
- else
- {
- snprintf( info, INFO_SIZE, "You catch %s momentarily off-guard.",
- ptr_monam(defender, DESC_NOCAP_THE) );
- }
- break;
- case 2: // confused/fleeing
- if (r<4)
- {
- snprintf( info, INFO_SIZE, "You catch %s completely off-guard!",
- ptr_monam(defender, DESC_NOCAP_THE) );
- }
- else
- {
- snprintf( info, INFO_SIZE, "You strike %s from behind!",
- ptr_monam(defender, DESC_NOCAP_THE) );
- }
- break;
- case 1:
- snprintf( info, INFO_SIZE, "%s fails to defend %s.",
- ptr_monam(defender, DESC_CAP_THE),
- mons_pronoun( defender->type, PRONOUN_REFLEXIVE ) );
- break;
- } // end switch
-
- mpr(info);
-}
-
diff --git a/stone_soup/crawl-ref/source/fight.h b/stone_soup/crawl-ref/source/fight.h
deleted file mode 100644
index 9b54b8b339..0000000000
--- a/stone_soup/crawl-ref/source/fight.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * File: fight.cc
- * Summary: Functions used during combat.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef FIGHT_H
-#define FIGHT_H
-
-
-#include "externs.h"
-
-// added Sept 18, 2000 -- bwr
-/* ***********************************************************************
- * called from: item_use.cc
- * *********************************************************************** */
-int effective_stat_bonus( int wepType = -1 );
-
-// added Sept 18, 2000 -- bwr
-/* ***********************************************************************
- * called from: describe.cc
- * *********************************************************************** */
-int weapon_str_weight( int wpn_class, int wpn_type );
-
-
-// last updated: 08jun2000 {dlb}
-/* ***********************************************************************
- * called from: acr - it_use3
- * *********************************************************************** */
-bool you_attack(int monster_attacked, bool unarmed_attacks);
-
-
-// last updated: 08jun2000 {dlb}
-/* ***********************************************************************
- * called from: monstuff
- * *********************************************************************** */
-void monster_attack(int monster_attacking);
-
-
-// last updated: 08jun2000 {dlb}
-/* ***********************************************************************
- * called from: monstuff
- * *********************************************************************** */
-bool monsters_fight(int monster_attacking, int monster_attacked);
-
-
-#endif
diff --git a/stone_soup/crawl-ref/source/files.cc b/stone_soup/crawl-ref/source/files.cc
deleted file mode 100644
index 6c13965702..0000000000
--- a/stone_soup/crawl-ref/source/files.cc
+++ /dev/null
@@ -1,2112 +0,0 @@
-/*
- * File: files.cc
- * Summary: Functions used to save and load levels/games.
- * Written by: Linley Henzell and Alexey Guzeev
- *
- * Modified for Crawl Reference by $Author$ on $Date$
- *
- * Change History (most recent first):
- *
- * <7> 19 June 2000 GDL Change handle to FILE *
- * <6> 11/14/99 cdl Don't let player ghosts follow you up/down
- * <5> 7/13/99 BWR Monsters now regenerate hps off level &
- ghosts teleport
- * <4> 6/13/99 BWR Added tmp file pairs to save file.
- * <3> 6/11/99 DML Replaced temp file deletion code.
- *
- * <2> 5/12/99 BWR Multiuser system support,
- * including appending UID to
- * name, and compressed saves
- * in the SAVE_DIR_PATH directory
- *
- * <1> --/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "files.h"
-#include "version.h"
-
-#include <string.h>
-#include <string>
-#include <stdlib.h>
-#include <stdio.h>
-#include <ctype.h>
-
-#ifdef DOS
-#include <conio.h>
-#include <file.h>
-#endif
-
-#ifdef UNIX
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#endif
-
-#ifdef USE_EMX
-#include <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
-#endif
-
-#ifdef OS9
-#include <stat.h>
-#else
-#include <sys/stat.h>
-#endif
-
-#ifdef __MINGW32__
-#include <io.h>
-#endif
-
-#include "externs.h"
-
-#include "cloud.h"
-#include "clua.h"
-#include "debug.h"
-#include "dungeon.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "items.h"
-#include "message.h"
-#include "misc.h"
-#include "monstuff.h"
-#include "mon-util.h"
-#include "mstuff2.h"
-#include "player.h"
-#include "randart.h"
-#include "skills2.h"
-#include "stash.h"
-#include "stuff.h"
-#include "tags.h"
-#include "travel.h"
-#include "wpn-misc.h"
-
-void save_level(int level_saved, bool was_a_labyrinth, char where_were_you);
-
-// temp file pairs used for file level cleanup
-extern FixedArray < bool, MAX_LEVELS, MAX_BRANCHES > tmp_file_pairs;
-
-/*
- Order for looking for conjurations for the 1st & 2nd spell slots,
- when finding spells to be remembered by a player's ghost:
- */
-unsigned char search_order_conj[] = {
-/* 0 */
- SPELL_LEHUDIBS_CRYSTAL_SPEAR,
- SPELL_BOLT_OF_DRAINING,
- SPELL_AGONY,
- SPELL_DISINTEGRATE,
- SPELL_LIGHTNING_BOLT,
- SPELL_STICKY_FLAME,
- SPELL_ISKENDERUNS_MYSTIC_BLAST,
- SPELL_BOLT_OF_FIRE,
- SPELL_BOLT_OF_COLD,
- SPELL_FIREBALL,
- SPELL_DELAYED_FIREBALL,
-/* 10 */
- SPELL_VENOM_BOLT,
- SPELL_BOLT_OF_IRON,
- SPELL_STONE_ARROW,
- SPELL_THROW_FLAME,
- SPELL_THROW_FROST,
- SPELL_PAIN,
- SPELL_STING,
- SPELL_MAGIC_DART,
- SPELL_NO_SPELL, // end search
-};
-
-/*
- Order for looking for summonings and self-enchants for the 3rd spell slot:
- */
-unsigned char search_order_third[] = {
-/* 0 */
- SPELL_SYMBOL_OF_TORMENT,
- SPELL_SUMMON_GREATER_DEMON,
- SPELL_SUMMON_WRAITHS,
- SPELL_SUMMON_HORRIBLE_THINGS,
- SPELL_SUMMON_DEMON,
- SPELL_DEMONIC_HORDE,
- SPELL_HASTE,
- SPELL_ANIMATE_DEAD,
- SPELL_INVISIBILITY,
- SPELL_CALL_IMP,
- SPELL_SUMMON_SMALL_MAMMAL,
-/* 10 */
- SPELL_CONTROLLED_BLINK,
- SPELL_BLINK,
- SPELL_NO_SPELL, // end search
-};
-
-/*
- Order for looking for enchants for the 4th + 5th spell slot. If fails, will
- go through conjs.
- Note: Dig must be in misc2 (5th) position to work.
- */
-unsigned char search_order_misc[] = {
-/* 0 */
- SPELL_AGONY,
- SPELL_BANISHMENT,
- SPELL_PARALYZE,
- SPELL_CONFUSE,
- SPELL_SLOW,
- SPELL_POLYMORPH_OTHER,
- SPELL_TELEPORT_OTHER,
- SPELL_DIG,
- SPELL_NO_SPELL, // end search
-};
-
-/* Last slot (emergency) can only be teleport self or blink. */
-
-static void redraw_all(void)
-{
- you.redraw_hit_points = 1;
- you.redraw_magic_points = 1;
- you.redraw_strength = 1;
- you.redraw_intelligence = 1;
- you.redraw_dexterity = 1;
- you.redraw_armour_class = 1;
- you.redraw_evasion = 1;
- you.redraw_experience = 1;
- you.redraw_gold = 1;
-
- you.redraw_status_flags = REDRAW_LINE_1_MASK | REDRAW_LINE_2_MASK | REDRAW_LINE_3_MASK;
-}
-
-struct ghost_struct ghost;
-
-unsigned char translate_spell(unsigned char spel);
-unsigned char search_third_list(unsigned char ignore_spell);
-unsigned char search_second_list(unsigned char ignore_spell);
-unsigned char search_first_list(unsigned char ignore_spell);
-
-void add_spells( struct ghost_struct &gs );
-void generate_random_demon();
-
-static bool determine_version( FILE *restoreFile,
- char &majorVersion, char &minorVersion );
-
-static void restore_version( FILE *restoreFile,
- char majorVersion, char minorVersion );
-
-static bool determine_level_version( FILE *levelFile,
- char &majorVersion, char &minorVersion );
-
-static void restore_level_version( FILE *levelFile,
- char majorVersion, char minorVersion );
-
-static bool determine_ghost_version( FILE *ghostFile,
- char &majorVersion, char &minorVersion );
-
-static void restore_ghost_version( FILE *ghostFile,
- char majorVersion, char minorVersion );
-
-static void restore_tagged_file( FILE *restoreFile, int fileType,
- char minorVersion );
-
-static void load_ghost();
-
-std::string get_savedir_filename(const char *prefix, const char *suffix,
- const char *extension)
-{
- char filename[1200];
-#ifdef SAVE_DIR_PATH
- snprintf(filename, sizeof filename, SAVE_DIR_PATH "%s%d%s.%s",
- prefix, (int) getuid(), suffix, extension);
-#else
- snprintf(filename, sizeof filename, "%s%s.%s",
- prefix, suffix, extension);
-#ifdef DOS
- strupr(filename);
-#endif
-#endif
- return std::string(filename);
-}
-
-std::string get_prefs_filename()
-{
- return get_savedir_filename("start", "ns", "prf");
-}
-
-void make_filename( char *buf, const char *prefix, int level, int where,
- bool isLabyrinth, bool isGhost )
-{
- UNUSED( isGhost );
-
- char suffix[4], lvl[5];
- char finalprefix[kFileNameLen];
-
- strcpy(suffix, (level < 10) ? "0" : "");
- itoa(level, lvl, 10);
- strcat(suffix, lvl);
- suffix[2] = where + 97;
- suffix[3] = '\0';
-
- // init buf
- buf[0] = '\0';
-
-#ifdef SAVE_DIR_PATH
- strcpy(buf, SAVE_DIR_PATH);
-#endif
-
- strncpy(finalprefix, prefix, kFileNameLen);
- finalprefix[kFileNameLen] = '\0';
-
- strcat(buf, finalprefix);
-
-#ifdef SAVE_DIR_PATH
- // everyone sees everyone else's ghosts. :)
- char uid[10];
- if (!isGhost)
- {
- itoa( (int) getuid(), uid, 10 );
- strcat(buf, uid);
- }
-#endif
-
- strcat(buf, ".");
- if (isLabyrinth)
- strcat(buf, "lab"); // temporary level
- else
- strcat(buf, suffix);
-}
-
-static void write_tagged_file( FILE *dataFile, char majorVersion,
- char minorVersion, int fileType )
-{
- struct tagHeader th;
-
- // find all relevant tags
- char tags[NUM_TAGS];
- tag_set_expected(tags, fileType);
-
- // write version
- struct tagHeader versionTag;
- versionTag.offset = 0;
- versionTag.tagID = TAG_VERSION;
- marshallByte(versionTag, majorVersion);
- marshallByte(versionTag, minorVersion);
- tag_write(versionTag, dataFile);
-
- // all other tags
- for(int i=1; i<NUM_TAGS; i++)
- {
- if (tags[i] == 1)
- {
- tag_construct(th, i);
- tag_write(th, dataFile);
- }
- }
-}
-
-bool travel_load_map( char branch, int absdepth )
-{
- char cha_fil[kFileNameSize];
-
- make_filename( cha_fil, you.your_name, absdepth, branch,
- false, false );
-#ifdef DOS
- strupr(cha_fil);
-#endif
-
- // Try to open level savefile.
- FILE *levelFile = fopen(cha_fil, "rb");
- if (!levelFile)
- return false;
-
- // BEGIN -- must load the old level : pre-load tasks
-
- // LOAD various tags
- char majorVersion;
- char minorVersion;
-
- if (!determine_level_version( levelFile, majorVersion, minorVersion )
- || majorVersion != SAVE_MAJOR_VERSION)
- {
- fclose(levelFile);
- return false;
- }
-
- tag_read(levelFile, minorVersion);
-
- fclose( levelFile );
-
- return true;
-}
-
-void load( unsigned char stair_taken, int load_mode, bool was_a_labyrinth,
- char old_level, char where_were_you2 )
-{
- int j = 0;
- int i = 0, count_x = 0, count_y = 0;
- char cha_fil[kFileNameSize];
-
- int foll_class[8];
- int foll_hp[8];
- int foll_hp_max[8];
- unsigned char foll_HD[8];
- int foll_AC[8];
- char foll_ev[8];
- unsigned char foll_speed[8];
- unsigned char foll_speed_inc[8];
-
- unsigned char foll_targ_1_x[8];
- unsigned char foll_targ_1_y[8];
- unsigned char foll_beh[8];
- unsigned char foll_att[8];
- int foll_sec[8];
- unsigned char foll_hit[8];
-
- unsigned char foll_ench[8][NUM_MON_ENCHANTS];
- unsigned char foll_flags[8];
-
- item_def foll_item[8][8];
-
- int itmf = 0;
- int ic = 0;
- int imn = 0;
- int val;
-
- bool just_created_level = false;
-
-#ifdef DOS_TERM
- window(1, 1, 80, 25);
-#endif
-
- make_filename( cha_fil, you.your_name, you.your_level, you.where_are_you,
- you.level_type != LEVEL_DUNGEON, false );
-
- if (you.level_type == LEVEL_DUNGEON)
- {
- if (tmp_file_pairs[you.your_level][you.where_are_you] == false)
- {
- // make sure old file is gone
- unlink(cha_fil);
-
- // save the information for later deletion -- DML 6/11/99
- tmp_file_pairs[you.your_level][you.where_are_you] = true;
- }
- }
-
- you.prev_targ = MHITNOT;
-
- int following = -1;
- int minvc = 0;
-
- // Don't delete clouds just because the player saved and restarted.
- if (load_mode != LOAD_RESTART_GAME)
- {
- for (int clouty = 0; clouty < MAX_CLOUDS; ++clouty)
- delete_cloud( clouty );
-
- ASSERT( env.cloud_no == 0 );
- }
-
- // This block is to grab followers and save the old level to disk.
- if (load_mode == LOAD_ENTER_LEVEL)
- {
- // grab followers
- for (count_x = you.x_pos - 1; count_x < you.x_pos + 2; count_x++)
- {
- for (count_y = you.y_pos - 1; count_y < you.y_pos + 2; count_y++)
- {
- if (count_x == you.x_pos && count_y == you.y_pos)
- continue;
-
- following++;
- foll_class[following] = -1;
-
- if (mgrd[count_x][count_y] == NON_MONSTER)
- continue;
-
- struct monsters *fmenv = &menv[mgrd[count_x][count_y]];
-
- if (fmenv->type == MONS_PLAYER_GHOST
- && fmenv->hit_points < fmenv->max_hit_points / 2)
- {
- mpr("The ghost fades into the shadows.");
- monster_teleport(fmenv, true);
- continue;
- }
-
- // monster has to be already tagged in order to follow:
- if (!testbits( fmenv->flags, MF_TAKING_STAIRS ))
- continue;
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "%s is following.",
- ptr_monam( fmenv, DESC_CAP_THE ) );
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- foll_class[following] = fmenv->type;
- foll_hp[following] = fmenv->hit_points;
- foll_hp_max[following] = fmenv->max_hit_points;
- foll_HD[following] = fmenv->hit_dice;
- foll_AC[following] = fmenv->armour_class;
- foll_ev[following] = fmenv->evasion;
- foll_speed[following] = fmenv->speed;
- foll_speed_inc[following] = fmenv->speed_increment;
- foll_targ_1_x[following] = fmenv->target_x;
- foll_targ_1_y[following] = fmenv->target_y;
-
- for (minvc = 0; minvc < NUM_MONSTER_SLOTS; ++minvc)
- {
- const int item = fmenv->inv[minvc];
- if (item == NON_ITEM)
- {
- foll_item[following][minvc].quantity = 0;
- continue;
- }
-
- foll_item[following][minvc] = mitm[item];
- destroy_item( item );
- }
-
- foll_beh[following] = fmenv->behaviour;
- foll_att[following] = fmenv->attitude;
- foll_sec[following] = fmenv->number;
- foll_hit[following] = fmenv->foe;
-
- for (j = 0; j < NUM_MON_ENCHANTS; j++)
- {
- foll_ench[following][j] = fmenv->enchantment[j];
- fmenv->enchantment[j] = ENCH_NONE;
- }
-
- foll_flags[following] = fmenv->flags;
-
- fmenv->flags = 0;
- fmenv->type = -1;
- fmenv->hit_points = 0;
- fmenv->max_hit_points = 0;
- fmenv->hit_dice = 0;
- fmenv->armour_class = 0;
- fmenv->evasion = 0;
-
- mgrd[count_x][count_y] = NON_MONSTER;
- }
- } // end of grabbing followers
-
- if (!was_a_labyrinth)
- save_level( old_level, false, where_were_you2 );
-
- was_a_labyrinth = false;
- }
-
- // clear out ghost/demon lord information:
- strcpy( ghost.name, "" );
- for (ic = 0; ic < NUM_GHOST_VALUES; ++ic)
- ghost.values[ic] = 0;
-
-#ifdef DOS
- strupr(cha_fil);
-#endif
-
- // Try to open level savefile.
- FILE *levelFile = fopen(cha_fil, "rb");
-
- // GENERATE new level when the file can't be opened:
- if (levelFile == NULL)
- {
- strcpy(ghost.name, "");
-
- for (imn = 0; imn < NUM_GHOST_VALUES; ++imn)
- ghost.values[imn] = 0;
-
- builder( you.your_level, you.level_type );
- just_created_level = true;
-
- if (you.level_type == LEVEL_PANDEMONIUM)
- generate_random_demon();
-
- if (you.your_level > 1 && one_chance_in(3))
- load_ghost();
- }
- else
- {
- // BEGIN -- must load the old level : pre-load tasks
-
- // LOAD various tags
- char majorVersion = 0;
- char minorVersion = 0;
-
- if (!determine_level_version( levelFile, majorVersion, minorVersion ))
- {
- perror("\nLevel file appears to be invalid.\n");
- end(-1);
- }
-
- restore_level_version( levelFile, majorVersion, minorVersion );
-
- // sanity check - EOF
- if (!feof( levelFile ))
- {
- snprintf( info, INFO_SIZE, "\nIncomplete read of \"%s\" - aborting.\n", cha_fil);
- perror(info);
- end(-1);
- }
-
- fclose( levelFile );
-
- // POST-LOAD tasks :
- link_items();
- redraw_all();
- }
-
- // closes all the gates if you're on the way out
- for (i = 0; i < GXM; i++)
- {
- for (j = 0; j < GYM; j++)
- {
- if (just_created_level)
- env.map[i][j] = 0;
-
- if (you.char_direction == DIR_ASCENDING
- && you.level_type != LEVEL_PANDEMONIUM)
- {
- if (grd[i][j] == DNGN_ENTER_HELL
- || grd[i][j] == DNGN_ENTER_ABYSS
- || grd[i][j] == DNGN_ENTER_PANDEMONIUM)
- {
- grd[i][j] = DNGN_STONE_ARCH;
- }
- }
-
- if (load_mode != LOAD_RESTART_GAME)
- env.cgrid[i][j] = EMPTY_CLOUD;
- }
- }
-
- // This next block is for cases where we want to look for a stairs
- // to place the player.
- if (load_mode != LOAD_RESTART_GAME && you.level_type != LEVEL_ABYSS)
- {
- bool find_first = true;
-
- // Order is important here:
- if (you.level_type == LEVEL_DUNGEON
- && where_were_you2 == BRANCH_VESTIBULE_OF_HELL
- && stair_taken == DNGN_STONE_STAIRS_UP_I)
- {
- // leaving hell - look for entry potal first
- stair_taken = DNGN_ENTER_HELL;
- find_first = false;
- }
- else if (stair_taken == DNGN_EXIT_PANDEMONIUM)
- {
- stair_taken = DNGN_ENTER_PANDEMONIUM;
- find_first = false;
- }
- else if (stair_taken == DNGN_EXIT_ABYSS)
- {
- stair_taken = DNGN_ENTER_ABYSS;
- find_first = false;
- }
- else if (stair_taken == DNGN_ENTER_HELL
- || stair_taken == DNGN_ENTER_LABYRINTH)
- {
- // the vestibule and labyrith always start from this stair
- stair_taken = DNGN_STONE_STAIRS_UP_I;
- }
- else if (stair_taken >= DNGN_STONE_STAIRS_DOWN_I
- && stair_taken <= DNGN_ROCK_STAIRS_DOWN)
- {
- // look for coresponding up stair
- stair_taken += (DNGN_STONE_STAIRS_UP_I - DNGN_STONE_STAIRS_DOWN_I);
- }
- else if (stair_taken >= DNGN_STONE_STAIRS_UP_I
- && stair_taken <= DNGN_ROCK_STAIRS_UP)
- {
- // look for coresponding down stair
- stair_taken += (DNGN_STONE_STAIRS_DOWN_I - DNGN_STONE_STAIRS_UP_I);
- }
- else if (stair_taken >= DNGN_RETURN_FROM_ORCISH_MINES
- && stair_taken < 150) // 20 slots reserved
- {
- // find entry point to subdungeon when leaving
- stair_taken += (DNGN_ENTER_ORCISH_MINES - DNGN_RETURN_FROM_ORCISH_MINES);
- }
- else if (stair_taken >= DNGN_ENTER_ORCISH_MINES
- && stair_taken < DNGN_RETURN_FROM_ORCISH_MINES)
- {
- // find exit staircase from subdungeon when entering
- stair_taken += (DNGN_RETURN_FROM_ORCISH_MINES - DNGN_ENTER_ORCISH_MINES);
- }
- else if (stair_taken >= DNGN_ENTER_DIS
- && stair_taken <= DNGN_TRANSIT_PANDEMONIUM)
- {
- // when entering a hell or pandemonium
- stair_taken = DNGN_STONE_STAIRS_UP_I;
- }
- else // Note: stair_taken can equal things like DNGN_FLOOR
- {
- // just find a nice empty square
- stair_taken = DNGN_FLOOR;
- find_first = false;
- }
-
- int found = 0;
- int x_pos = 0, y_pos = 0;
-
- // Start by looking for the expected entry point:
- for (count_x = 0; count_x < GXM; count_x++)
- {
- for (count_y = 0; count_y < GYM; count_y++)
- {
- if (grd[count_x][count_y] == stair_taken)
- {
- found++;
- if (one_chance_in( found ))
- {
- x_pos = count_x;
- y_pos = count_y;
- }
-
- if (find_first)
- goto found_stair; // double break
- }
- }
- }
-
-found_stair:
- if (!found)
- {
- // See if we can find a stairway in the "right" direction:
- for (count_x = 0; count_x < GXM; count_x++)
- {
- for (count_y = 0; count_y < GYM; count_y++)
- {
- if (stair_taken <= DNGN_ROCK_STAIRS_DOWN)
- {
- // looking for any down stairs
- if (grd[count_x][count_y] >= DNGN_STONE_STAIRS_DOWN_I
- && grd[count_x][count_y] <= DNGN_ROCK_STAIRS_DOWN)
- {
- found++;
- if (one_chance_in( found ))
- {
- x_pos = count_x;
- y_pos = count_y;
- }
- }
- }
- else
- {
- // looking for any up stairs
- if (grd[count_x][count_y] >= DNGN_STONE_STAIRS_UP_I
- && grd[count_x][count_y] <= DNGN_ROCK_STAIRS_UP)
- {
- found++;
- if (one_chance_in( found ))
- {
- x_pos = count_x;
- y_pos = count_y;
- }
- }
- }
- }
- }
-
- if (!found)
- {
- // Still not found? Look for any clear terrain:
- for (count_x = 0; count_x < GXM; count_x++)
- {
- for (count_y = 0; count_y < GYM; count_y++)
- {
- if (grd[count_x][count_y] >= DNGN_FLOOR)
- {
- found++;
- if (one_chance_in( found ))
- {
- x_pos = count_x;
- y_pos = count_y;
- }
- }
- }
- }
- }
- }
-
- // If still not found, the level is very buggy.
- ASSERT( found );
-
- you.x_pos = x_pos;
- you.y_pos = y_pos;
- }
- else if (load_mode != LOAD_RESTART_GAME && you.level_type == LEVEL_ABYSS)
- {
- you.x_pos = 45;
- you.y_pos = 35;
- }
-
- // This should fix the "monster occuring under the player" bug?
- if (mgrd[you.x_pos][you.y_pos] != NON_MONSTER)
- monster_teleport(&menv[mgrd[you.x_pos][you.y_pos]], true);
- /*
- if (you.level_type == LEVEL_LABYRINTH || you.level_type == LEVEL_ABYSS)
- grd[you.x_pos][you.y_pos] = DNGN_FLOOR;
- */
- following = 0;
- int fmenv = -1;
-
- // actually "move" the followers if applicable
- if ((you.level_type == LEVEL_DUNGEON
- || you.level_type == LEVEL_PANDEMONIUM)
- && load_mode == LOAD_ENTER_LEVEL)
- {
- for (ic = 0; ic < 2; ic++)
- {
- for (count_x = you.x_pos - 6; count_x < you.x_pos + 7;
- count_x++)
- {
- for (count_y = you.y_pos - 6; count_y < you.y_pos + 7;
- count_y++)
- {
- if (ic == 0
- && ((count_x < you.x_pos - 1)
- || (count_x > you.x_pos + 1)
- || (count_y < you.y_pos - 1)
- || (count_y > you.y_pos + 1)))
- {
- continue;
- }
-
- if (count_x == you.x_pos && count_y == you.y_pos)
- continue;
-
- if (mgrd[count_x][count_y] != NON_MONSTER
- || grd[count_x][count_y] < DNGN_FLOOR)
- {
- continue;
- }
-
- while (menv[following].type != -1)
- {
- following++;
-
- if (following >= MAX_MONSTERS)
- goto out_of_foll;
- }
-
- while (fmenv < 7)
- {
- fmenv++;
-
- if (foll_class[fmenv] == -1)
- continue;
-
- menv[following].type = foll_class[fmenv];
- menv[following].hit_points = foll_hp[fmenv];
- menv[following].max_hit_points = foll_hp_max[fmenv];
- menv[following].hit_dice = foll_HD[fmenv];
- menv[following].armour_class = foll_AC[fmenv];
- menv[following].evasion = foll_ev[fmenv];
- menv[following].speed = foll_speed[fmenv];
- menv[following].x = count_x;
- menv[following].y = count_y;
- menv[following].target_x = 0;
- menv[following].target_y = 0;
- menv[following].speed_increment = foll_speed_inc[fmenv];
-
- for (minvc = 0; minvc < NUM_MONSTER_SLOTS; minvc++)
- {
-
- if (!is_valid_item(foll_item[fmenv][minvc]))
- {
- menv[following].inv[minvc] = NON_ITEM;
- continue;
- }
-
- itmf = get_item_slot(0);
- if (itmf == NON_ITEM)
- {
- menv[following].inv[minvc] = NON_ITEM;
- continue;
- }
-
- mitm[itmf] = foll_item[fmenv][minvc];
- mitm[itmf].x = 0;
- mitm[itmf].y = 0;
- mitm[itmf].link = NON_ITEM;
-
- menv[following].inv[minvc] = itmf;
- }
-
- menv[following].behaviour = foll_beh[fmenv];
- menv[following].attitude = foll_att[fmenv];
- menv[following].number = foll_sec[fmenv];
- menv[following].foe = foll_hit[fmenv];
-
- for (j = 0; j < NUM_MON_ENCHANTS; j++)
- menv[following].enchantment[j]=foll_ench[fmenv][j];
-
- menv[following].flags = foll_flags[fmenv];
- menv[following].flags |= MF_JUST_SUMMONED;
-
- mgrd[count_x][count_y] = following;
- break;
- }
- }
- }
- }
- } // end of moving followers
-
- out_of_foll:
- redraw_all();
-
- // Sanity forcing of monster inventory items (required?)
- for (i = 0; i < MAX_MONSTERS; i++)
- {
- if (menv[i].type == -1)
- continue;
-
- for (j = 0; j < NUM_MONSTER_SLOTS; j++)
- {
- if (menv[i].inv[j] == NON_ITEM)
- continue;
-
- /* items carried by monsters shouldn't be linked */
- if (mitm[menv[i].inv[j]].link != NON_ITEM)
- mitm[menv[i].inv[j]].link = NON_ITEM;
- }
- }
-
- // Translate stairs for pandemonium levels:
- if (you.level_type == LEVEL_PANDEMONIUM)
- {
- for (count_x = 0; count_x < GXM; count_x++)
- {
- for (count_y = 0; count_y < GYM; count_y++)
- {
- if (grd[count_x][count_y] >= DNGN_STONE_STAIRS_UP_I
- && grd[count_x][count_y] <= DNGN_ROCK_STAIRS_UP)
- {
- if (one_chance_in( you.mutation[MUT_PANDEMONIUM] ? 5 : 50 ))
- grd[count_x][count_y] = DNGN_EXIT_PANDEMONIUM;
- else
- grd[count_x][count_y] = DNGN_FLOOR;
- }
-
- if (grd[count_x][count_y] >= DNGN_ENTER_LABYRINTH
- && grd[count_x][count_y] <= DNGN_ROCK_STAIRS_DOWN)
- {
- grd[count_x][count_y] = DNGN_TRANSIT_PANDEMONIUM;
- }
- }
- }
- }
-
- // Things to update for player entering level
- if (load_mode == LOAD_ENTER_LEVEL)
- {
- // update corpses and fountains
- if (env.elapsed_time != 0.0)
- update_level( you.elapsed_time - env.elapsed_time );
-
- // Centaurs have difficulty with stairs
- val = ((you.species != SP_CENTAUR) ? player_movement_speed() : 15);
-
- // new levels have less wary monsters:
- if (just_created_level)
- val /= 2;
-
- val -= (stepdown_value( check_stealth(), 50, 50, 150, 150 ) / 10);
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "arrival time: %d", val );
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- if (val > 0)
- {
- you.time_taken = val;
- handle_monsters();
- }
- }
-
- // Save the created/updated level out to disk:
- save_level( you.your_level, (you.level_type != LEVEL_DUNGEON),
- you.where_are_you );
-} // end load()
-
-void save_level(int level_saved, bool was_a_labyrinth, char where_were_you)
-{
- char cha_fil[kFileNameSize];
-
- make_filename( cha_fil, you.your_name, level_saved, where_were_you,
- was_a_labyrinth, false );
-
- you.prev_targ = MHITNOT;
-
-#ifdef DOS
- strupr(cha_fil);
-#endif
-
- FILE *saveFile = fopen(cha_fil, "wb");
-
- if (saveFile == NULL)
- {
- strcpy(info, "Unable to open \"");
- strcat(info, cha_fil );
- strcat(info, "\" for writing!");
- perror(info);
- end(-1);
- }
-
- // nail all items to the ground
- fix_item_coordinates();
-
- // 4.0 initial genesis of saved format
- // 4.1 added attitude tag
- // 4.2 replaced old 'enchantment1' and with 'flags' (bitfield)
- // 4.3 changes to make the item structure more sane
- // 4.4 changes to the ghost save section
- // 4.5 spell and ability letter arrays
- // 4.6 inventory slots of items
- // 4.7 origin tracking for items
- // 4.8 widened env.map to 2 bytes
-
- // [dshaligram] Winding major version back all the way to 0.
- write_tagged_file( saveFile, SAVE_MAJOR_VERSION, 8, TAGTYPE_LEVEL );
-
- fclose(saveFile);
-
-#ifdef SHARED_FILES_CHMOD_PRIVATE
- chmod(cha_fil, SHARED_FILES_CHMOD_PRIVATE);
-#endif
-} // end save_level()
-
-void save_game(bool leave_game)
-{
- char charFile[kFileNameSize];
-#ifdef STASH_TRACKING
- char stashFile[kFileNameSize + 4];
-#endif
- char killFile[kFileNameSize + 4];
- char travelCacheFile[kFileNameSize + 4];
-#ifdef CLUA_BINDINGS
- char luaFile[kFileNameSize + 4];
-#endif
-
-#ifdef SAVE_PACKAGE_CMD
- char cmd_buff[1024];
- char name_buff[kFileNameSize];
-
- snprintf( name_buff, sizeof(name_buff),
- SAVE_DIR_PATH "%s%d", you.your_name, (int) getuid() );
-
- snprintf( cmd_buff, sizeof(cmd_buff),
- SAVE_PACKAGE_CMD, name_buff, name_buff );
-
-#ifdef STASH_TRACKING
- strcpy(stashFile, name_buff);
-#endif
-#ifdef CLUA_BINDINGS
- strcpy(luaFile, name_buff);
-#endif
- strcpy(killFile, name_buff);
- strcpy(travelCacheFile, name_buff);
- snprintf( charFile, sizeof(charFile),
- "%s.sav", name_buff );
-
-#else
- strncpy(charFile, you.your_name, kFileNameLen);
- charFile[kFileNameLen] = 0;
-
-#ifdef STASH_TRACKING
- strcpy(stashFile, charFile);
-#endif
-#ifdef CLUA_BINDINGS
- strcpy(luaFile, charFile);
-#endif
- strcpy(killFile, charFile);
- strcpy(travelCacheFile, charFile);
- strcat(charFile, ".sav");
-
-#ifdef DOS
- strupr(charFile);
-#ifdef STASH_TRACKING
- strupr(stashFile);
-#endif
-#ifdef CLUA_BINDINGS
- strupr(luaFile);
-#endif
- strupr(killFile);
- strupr(travelCacheFile);
-#endif
-#endif
-
-#ifdef STASH_TRACKING
- strcat(stashFile, ".st");
-#endif
-#ifdef CLUA_BINDINGS
- strcat(luaFile, ".lua");
-#endif
- strcat(killFile, ".kil");
- strcat(travelCacheFile, ".tc");
-
-#ifdef STASH_TRACKING
- FILE *stashf = fopen(stashFile, "wb");
- if (stashf)
- {
- stashes.save(stashf);
- fclose(stashf);
-
-#ifdef SHARED_FILES_CHMOD_PRIVATE
- // change mode (unices)
- chmod(stashFile, SHARED_FILES_CHMOD_PRIVATE);
-#endif
- }
-#endif // STASH_TRACKING
-
-#ifdef CLUA_BINDINGS
- clua.save(luaFile);
-#ifdef SHARED_FILES_CHMOD_PRIVATE
- // change mode; note that luaFile may not exist
- chmod(luaFile, SHARED_FILES_CHMOD_PRIVATE);
-#endif
-#endif // CLUA_BINDINGS
-
- FILE *travelf = fopen(travelCacheFile, "wb");
- if (travelf)
- {
- travel_cache.save(travelf);
- fclose(travelf);
-#ifdef SHARED_FILES_CHMOD_PRIVATE
- // change mode (unices)
- chmod(travelCacheFile, SHARED_FILES_CHMOD_PRIVATE);
-#endif
- }
-
- FILE *killf = fopen(killFile, "wb");
- if (killf)
- {
- you.kills.save(killf);
- fclose(killf);
-
-#ifdef SHARED_FILES_CHMOD_PRIVATE
- // change mode (unices)
- chmod(killFile, SHARED_FILES_CHMOD_PRIVATE);
-#endif
- }
-
- FILE *saveFile = fopen(charFile, "wb");
-
- if (saveFile == NULL)
- {
- strcpy(info, "Unable to open \"");
- strcat(info, charFile );
- strcat(info, "\" for writing!");
- perror(info);
- end(-1);
- }
-
- // 4.0 initial genesis of saved format
- // 4.1 changes to make the item structure more sane
- // 4.2 spell and ability tables
- // 4.3 added you.magic_contamination (05/03/05)
- // 4.4 added item origins
- // 4.5 added num_gifts
-
- write_tagged_file( saveFile, SAVE_MAJOR_VERSION, 5, TAGTYPE_PLAYER );
-
- fclose(saveFile);
-
-#ifdef SHARED_FILES_CHMOD_PRIVATE
- // change mode (unices)
- chmod(charFile, SHARED_FILES_CHMOD_PRIVATE);
-#endif
-
- // if just save, early out
- if (!leave_game)
- return;
-
- // must be exiting -- save level & goodbye!
- save_level(you.your_level, (you.level_type != LEVEL_DUNGEON),
- you.where_are_you);
-
-#ifdef DOS_TERM
- window(1, 1, 80, 25);
-#endif
-
- clrscr();
-
-#ifdef SAVE_PACKAGE_CMD
- if (system( cmd_buff ) != 0)
- {
- cprintf( EOL "Warning: Zip command (SAVE_PACKAGE_CMD) returned non-zero value!" EOL );
- }
-
-#ifdef SHARED_FILES_CHMOD_PRIVATE
- strcat( name_buff, PACKAGE_SUFFIX );
- // change mode (unices)
- chmod( name_buff, SHARED_FILES_CHMOD_PRIVATE );
-#endif
-
-#endif
-
- cprintf( "See you soon, %s!" EOL , you.your_name );
-
- end(0);
-} // end save_game()
-
-void load_ghost(void)
-{
- char majorVersion;
- char minorVersion;
- char cha_fil[kFileNameSize];
- int imn;
- int i;
-
- make_filename( cha_fil, "bones", you.your_level, you.where_are_you,
- (you.level_type != LEVEL_DUNGEON), true );
-
- FILE *gfile = fopen(cha_fil, "rb");
-
- if (gfile == NULL)
- return; // no such ghost.
-
- if (!determine_ghost_version(gfile, majorVersion, minorVersion))
- {
- fclose(gfile);
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "Ghost file \"%s\" seems to be invalid.",
- cha_fil);
- mpr( info, MSGCH_DIAGNOSTICS );
- more();
-#endif
- return;
- }
-
- restore_ghost_version(gfile, majorVersion, minorVersion);
-
- // sanity check - EOF
- if (!feof(gfile))
- {
- fclose(gfile);
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "Incomplete read of \"%s\".", cha_fil);
- mpr( info, MSGCH_DIAGNOSTICS );
- more();
-#endif
- return;
- }
-
- fclose(gfile);
-
-#if DEBUG_DIAGNOSTICS
- mpr( "Loaded ghost.", MSGCH_DIAGNOSTICS );
-#endif
-
- // remove bones file - ghosts are hardly permanent.
- unlink(cha_fil);
-
- // translate ghost to monster and place.
- for (imn = 0; imn < MAX_MONSTERS - 10; imn++)
- {
- if (menv[imn].type != -1)
- continue;
-
- menv[imn].type = MONS_PLAYER_GHOST;
- menv[imn].hit_dice = ghost.values[ GVAL_EXP_LEVEL ];
- menv[imn].hit_points = ghost.values[ GVAL_MAX_HP ];
- menv[imn].max_hit_points = ghost.values[ GVAL_MAX_HP ];
- menv[imn].armour_class = ghost.values[ GVAL_AC];
- menv[imn].evasion = ghost.values[ GVAL_EV ];
- menv[imn].speed = 10;
- menv[imn].speed_increment = 70;
- menv[imn].attitude = ATT_HOSTILE;
- menv[imn].behaviour = BEH_WANDER;
- menv[imn].flags = 0;
- menv[imn].foe = MHITNOT;
- menv[imn].foe_memory = 0;
-
- menv[imn].number = 250;
-
- for (i = GVAL_SPELL_1; i <= GVAL_SPELL_6; i++)
- {
- if (ghost.values[i] != MS_NO_SPELL)
- {
- menv[imn].number = MST_GHOST;
- break;
- }
- }
-
- for (i = 0; i < NUM_MONSTER_SLOTS; i++)
- menv[imn].inv[i] = NON_ITEM;
-
- for (i = 0; i < NUM_MON_ENCHANTS; i++)
- menv[imn].enchantment[i] = ENCH_NONE;
-
- do
- {
- menv[imn].x = random2(GXM - 20) + 10;
- menv[imn].y = random2(GYM - 20) + 10;
- }
- while ((grd[menv[imn].x][menv[imn].y] != DNGN_FLOOR)
- || (mgrd[menv[imn].x][menv[imn].y] != NON_MONSTER));
-
- mgrd[menv[imn].x][menv[imn].y] = imn;
- break;
- }
-}
-
-
-void restore_game(void)
-{
- char char_f[kFileNameSize];
- char kill_f[kFileNameSize];
- char travel_f[kFileNameSize];
-#ifdef STASH_TRACKING
- char stash_f[kFileNameSize];
-#endif
-
-#ifdef CLUA_BINDINGS
- char lua_f[kFileNameSize];
-#endif
-
-#ifdef SAVE_DIR_PATH
- snprintf( char_f, sizeof(char_f),
- SAVE_DIR_PATH "%s%d", you.your_name, (int) getuid() );
-#else
- strncpy(char_f, you.your_name, kFileNameLen);
- char_f[kFileNameLen] = 0;
-#endif
-
- strcpy(kill_f, char_f);
- strcpy(travel_f, char_f);
-#ifdef CLUA_BINDINGS
- strcpy(lua_f, char_f);
- strcat(lua_f, ".lua");
-#endif
-#ifdef STASH_TRACKING
- strcpy(stash_f, char_f);
- strcat(stash_f, ".st");
-#endif
- strcat(kill_f, ".kil");
- strcat(travel_f, ".tc");
- strcat(char_f, ".sav");
-
-#ifdef DOS
- strupr(char_f);
-#ifdef STASH_TRACKING
- strupr(stash_f);
-#endif
- strupr(kill_f);
- strupr(travel_f);
-#ifdef CLUA_BINDINGS
- strupr(lua_f);
-#endif
-#endif
-
- FILE *restoreFile = fopen(char_f, "rb");
-
- if (restoreFile == NULL)
- {
- strcpy(info, "Unable to open \"");
- strcat(info, char_f );
- strcat(info, "\" for reading!");
- perror(info);
- end(-1);
- }
-
- char majorVersion = 0;
- char minorVersion = 0;
-
- if (!determine_version(restoreFile, majorVersion, minorVersion))
- {
- perror("\nSavefile appears to be invalid.\n");
- end(-1);
- }
-
- restore_version(restoreFile, majorVersion, minorVersion);
-
- // sanity check - EOF
- if (!feof(restoreFile))
- {
- snprintf( info, INFO_SIZE, "\nIncomplete read of \"%s\" - aborting.\n", char_f);
- perror(info);
- end(-1);
- }
-
- fclose(restoreFile);
-
-#ifdef STASH_TRACKING
- FILE *stashFile = fopen(stash_f, "rb");
- if (stashFile)
- {
- stashes.load(stashFile);
- fclose(stashFile);
- }
-#endif
-
-#ifdef CLUA_BINDINGS
- clua.execfile( lua_f );
-#endif // CLUA_BINDINGS
-
- FILE *travelFile = fopen(travel_f, "rb");
- if (travelFile)
- {
- travel_cache.load(travelFile);
- fclose(travelFile);
- }
-
- FILE *killFile = fopen(kill_f, "rb");
- if (killFile)
- {
- you.kills.load(killFile);
- fclose(killFile);
- }
-}
-
-static bool determine_version( FILE *restoreFile,
- char &majorVersion, char &minorVersion )
-{
- // read first two bytes.
- char buf[2];
- if (read2(restoreFile, buf, 2) != 2)
- return false; // empty file?
-
- // otherwise, read version and validate.
- majorVersion = buf[0];
- minorVersion = buf[1];
-
- if (majorVersion == SAVE_MAJOR_VERSION)
- return true;
-
- return false; // if its not 0, no idea
-}
-
-static void restore_version( FILE *restoreFile,
- char majorVersion, char minorVersion )
-{
- // assuming the following check can be removed once we can read all
- // savefile versions.
- if (majorVersion != SAVE_MAJOR_VERSION)
- {
- snprintf( info, INFO_SIZE, "\nSorry, this release cannot read a v%d.%d savefile.\n",
- majorVersion, minorVersion);
- perror(info);
- end(-1);
- }
-
- switch(majorVersion)
- {
- case SAVE_MAJOR_VERSION:
- restore_tagged_file(restoreFile, TAGTYPE_PLAYER, minorVersion);
- break;
- default:
- break;
- }
-}
-
-// generic v4 restore function
-static void restore_tagged_file( FILE *restoreFile, int fileType,
- char minorVersion )
-{
- int i;
-
- char tags[NUM_TAGS];
- tag_set_expected(tags, fileType);
-
- while(1)
- {
- i = tag_read(restoreFile, minorVersion);
- if (i == 0) // no tag!
- break;
- tags[i] = 0; // tag read
- }
-
- // go through and init missing tags
- for(i=0; i<NUM_TAGS; i++)
- {
- if (tags[i] == 1) // expected but never read
- tag_missing(i, minorVersion);
- }
-}
-
-static bool determine_level_version( FILE *levelFile,
- char &majorVersion, char &minorVersion )
-{
- // read first two bytes.
- char buf[2];
- if (read2(levelFile, buf, 2) != 2)
- return false; // empty file?
-
- // otherwise, read version and validate.
- majorVersion = buf[0];
- minorVersion = buf[1];
-
- if (majorVersion == SAVE_MAJOR_VERSION)
- return true;
-
- return false; // if its not SAVE_MAJOR_VERSION, no idea
-}
-
-static void restore_level_version( FILE *levelFile,
- char majorVersion, char minorVersion )
-{
- // assuming the following check can be removed once we can read all
- // savefile versions.
- if (majorVersion != SAVE_MAJOR_VERSION)
- {
- snprintf( info, INFO_SIZE, "\nSorry, this release cannot read a v%d.%d level file.\n",
- majorVersion, minorVersion);
- perror(info);
- end(-1);
- }
-
- switch(majorVersion)
- {
- case SAVE_MAJOR_VERSION:
- restore_tagged_file(levelFile, TAGTYPE_LEVEL, minorVersion);
- break;
- default:
- break;
- }
-}
-
-static bool determine_ghost_version( FILE *ghostFile,
- char &majorVersion, char &minorVersion )
-{
- // read first two bytes.
- char buf[2];
- if (read2(ghostFile, buf, 2) != 2)
- return false; // empty file?
-
- // check for pre-v4 -- simply started right in with ghost name.
- if (isprint(buf[0]) && buf[0] > 4)
- {
- majorVersion = 0;
- minorVersion = 0;
- rewind(ghostFile);
- return true;
- }
-
- // otherwise, read version and validate.
- majorVersion = buf[0];
- minorVersion = buf[1];
-
- if (majorVersion == SAVE_MAJOR_VERSION)
- return true;
-
- return false; // if its not SAVE_MAJOR_VERSION, no idea!
-}
-
-static void restore_ghost_version( FILE *ghostFile,
- char majorVersion, char minorVersion )
-{
- switch(majorVersion)
- {
- case SAVE_MAJOR_VERSION:
- restore_tagged_file(ghostFile, TAGTYPE_GHOST, minorVersion);
- break;
- default:
- break;
- }
-}
-
-void save_ghost( bool force )
-{
- char cha_fil[kFileNameSize];
- const int wpn = you.equip[EQ_WEAPON];
-
- if (!force && (you.your_level < 2 || you.is_undead))
- return;
-
- make_filename( cha_fil, "bones", you.your_level, you.where_are_you,
- (you.level_type != LEVEL_DUNGEON), true );
-
- FILE *gfile = fopen(cha_fil, "rb");
-
- // don't overwrite existing bones!
- if (gfile != NULL)
- {
- fclose(gfile);
- return;
- }
-
- memcpy(ghost.name, you.your_name, 20);
-
- ghost.values[ GVAL_MAX_HP ] = ((you.hp_max >= 150) ? 150 : you.hp_max);
- ghost.values[ GVAL_EV ] = player_evasion();
- ghost.values[ GVAL_AC ] = player_AC();
- ghost.values[ GVAL_SEE_INVIS ] = player_see_invis();
- ghost.values[ GVAL_RES_FIRE ] = player_res_fire();
- ghost.values[ GVAL_RES_COLD ] = player_res_cold();
- ghost.values[ GVAL_RES_ELEC ] = player_res_electricity();
-
- /* note - as ghosts, automatically get res poison + prot_life */
-
- int d = 4;
- int e = 0;
-
- if (wpn != -1)
- {
- if (you.inv[wpn].base_type == OBJ_WEAPONS
- || you.inv[wpn].base_type == OBJ_STAVES)
- {
- d = property( you.inv[wpn], PWPN_DAMAGE );
-
- d *= 25 + you.skills[weapon_skill( you.inv[wpn].base_type,
- you.inv[wpn].sub_type )];
- d /= 25;
-
- if (you.inv[wpn].base_type == OBJ_WEAPONS)
- {
- if (is_random_artefact( you.inv[wpn] ))
- e = randart_wpn_property( you.inv[wpn], RAP_BRAND );
- else
- e = you.inv[wpn].special;
- }
- }
- }
- else
- {
- /* Unarmed combat */
- if (you.species == SP_TROLL)
- d += you.experience_level;
-
- d += you.skills[SK_UNARMED_COMBAT];
- }
-
- d *= 30 + you.skills[SK_FIGHTING];
- d /= 30;
-
- d += you.strength / 4;
-
- if (d > 50)
- d = 50;
-
- ghost.values[ GVAL_DAMAGE ] = d;
- ghost.values[ GVAL_BRAND ] = e;
- ghost.values[ GVAL_SPECIES ] = you.species;
- ghost.values[ GVAL_BEST_SKILL ] = best_skill(SK_FIGHTING, (NUM_SKILLS - 1), 99);
- ghost.values[ GVAL_SKILL_LEVEL ] = you.skills[best_skill(SK_FIGHTING, (NUM_SKILLS - 1), 99)];
- ghost.values[ GVAL_EXP_LEVEL ] = you.experience_level;
- ghost.values[ GVAL_CLASS ] = you.char_class;
-
- add_spells(ghost);
-
- gfile = fopen(cha_fil, "wb");
-
- if (gfile == NULL)
- {
- strcpy(info, "Error creating ghost file: ");
- strcat(info, cha_fil);
- mpr(info);
- more();
- return;
- }
-
- // 4.0-4.3 old tagged savefile (values as unsigned char)
- // 4.4 new tagged savefile (values as signed short)
- write_tagged_file( gfile, SAVE_MAJOR_VERSION, 4, TAGTYPE_GHOST );
-
- fclose(gfile);
-
-#if DEBUG_DIAGNOSTICS
- mpr( "Saved ghost.", MSGCH_DIAGNOSTICS );
-#endif
-
-#ifdef SHARED_FILES_CHMOD_PUBLIC
- chmod(cha_fil, SHARED_FILES_CHMOD_PUBLIC);
-#endif
-} // end save_ghost()
-
-/*
- Used when creating ghosts: goes through and finds spells for the ghost to
- cast. Death is a traumatic experience, so ghosts only remember a few spells.
- */
-void add_spells( struct ghost_struct &gs )
-{
- int i = 0;
-
- for (i = GVAL_SPELL_1; i <= GVAL_SPELL_6; i++)
- gs.values[i] = SPELL_NO_SPELL;
-
- gs.values[ GVAL_SPELL_1 ] = search_first_list(SPELL_NO_SPELL);
- gs.values[ GVAL_SPELL_2 ] = search_first_list(gs.values[GVAL_SPELL_1]);
- gs.values[ GVAL_SPELL_3 ] = search_second_list(SPELL_NO_SPELL);
- gs.values[ GVAL_SPELL_4 ] = search_third_list(SPELL_NO_SPELL);
-
- if (gs.values[ GVAL_SPELL_4 ] == SPELL_NO_SPELL)
- gs.values[ GVAL_SPELL_4 ] = search_first_list(SPELL_NO_SPELL);
-
- gs.values[ GVAL_SPELL_5 ] = search_first_list(gs.values[GVAL_SPELL_4]);
-
- if (gs.values[ GVAL_SPELL_5 ] == SPELL_NO_SPELL)
- gs.values[ GVAL_SPELL_5 ] = search_first_list(gs.values[GVAL_SPELL_4]);
-
- if (player_has_spell( SPELL_DIG ))
- gs.values[ GVAL_SPELL_5 ] = SPELL_DIG;
-
- /* Looks for blink/tport for emergency slot */
- if (player_has_spell( SPELL_CONTROLLED_BLINK )
- || player_has_spell( SPELL_BLINK ))
- {
- gs.values[ GVAL_SPELL_6 ] = SPELL_CONTROLLED_BLINK;
- }
-
- if (player_has_spell( SPELL_TELEPORT_SELF ))
- gs.values[ GVAL_SPELL_6 ] = SPELL_TELEPORT_SELF;
-
- for (i = GVAL_SPELL_1; i <= GVAL_SPELL_6; i++)
- gs.values[i] = translate_spell( gs.values[i] );
-} // end add_spells()
-
-unsigned char search_first_list(unsigned char ignore_spell)
-{
- for (int i = 0; i < 20; i++)
- {
- if (search_order_conj[i] == SPELL_NO_SPELL)
- return SPELL_NO_SPELL;
-
- if (search_order_conj[i] == ignore_spell)
- continue;
-
- if (player_has_spell(search_order_conj[i]))
- return search_order_conj[i];
- }
-
- return SPELL_NO_SPELL;
-} // end search_first_list()
-
-unsigned char search_second_list(unsigned char ignore_spell)
-{
- for (int i = 0; i < 20; i++)
- {
- if (search_order_third[i] == SPELL_NO_SPELL)
- return SPELL_NO_SPELL;
-
- if (search_order_third[i] == ignore_spell)
- continue;
-
- if (player_has_spell(search_order_third[i]))
- return search_order_third[i];
- }
-
- return SPELL_NO_SPELL;
-} // end search_second_list()
-
-unsigned char search_third_list(unsigned char ignore_spell)
-{
- for (int i = 0; i < 20; i++)
- {
- if (search_order_misc[i] == SPELL_NO_SPELL)
- return SPELL_NO_SPELL;
-
- if (search_order_misc[i] == ignore_spell)
- continue;
-
- if (player_has_spell(search_order_misc[i]))
- return search_order_misc[i];
- }
-
- return SPELL_NO_SPELL;
-} // end search_third_list()
-
-
-/*
- When passed the number for a player spell, returns the equivalent monster
- spell. Returns SPELL_NO_SPELL on failure (no equiv).
- */
-unsigned char translate_spell(unsigned char spel)
-{
- switch (spel)
- {
- case SPELL_TELEPORT_SELF:
- return (MS_TELEPORT);
-
- case SPELL_MAGIC_DART:
- return (MS_MMISSILE);
- case SPELL_FIREBALL:
- case SPELL_DELAYED_FIREBALL:
- return (MS_FIREBALL);
- case SPELL_DIG:
- return (MS_DIG);
- case SPELL_BOLT_OF_FIRE:
- return (MS_FIRE_BOLT);
- case SPELL_BOLT_OF_COLD:
- return (MS_COLD_BOLT);
- case SPELL_LIGHTNING_BOLT:
- return (MS_LIGHTNING_BOLT);
- case SPELL_POLYMORPH_OTHER:
- return (MS_MUTATION);
- case SPELL_SLOW:
- return (MS_SLOW);
- case SPELL_HASTE:
- return (MS_HASTE);
- case SPELL_PARALYZE:
- return (MS_PARALYSIS);
- case SPELL_CONFUSE:
- return (MS_CONFUSE);
- case SPELL_INVISIBILITY:
- return (MS_INVIS);
- case SPELL_THROW_FLAME:
- return (MS_FLAME);
- case SPELL_THROW_FROST:
- return (MS_FROST);
- case SPELL_CONTROLLED_BLINK:
- return (MS_BLINK); /* approximate */
-/* case FREEZING_CLOUD: return ; no freezing/mephitic cloud yet
- case MEPHITIC_CLOUD: return ; */
- case SPELL_VENOM_BOLT:
- return (MS_VENOM_BOLT);
- case SPELL_POISON_ARROW:
- return (MS_POISON_ARROW);
- case SPELL_TELEPORT_OTHER:
- return (MS_TELEPORT_OTHER);
- case SPELL_SUMMON_SMALL_MAMMAL:
- return (MS_VAMPIRE_SUMMON); /* approximate */
- case SPELL_BOLT_OF_DRAINING:
- return (MS_NEGATIVE_BOLT);
- case SPELL_LEHUDIBS_CRYSTAL_SPEAR:
- return (MS_CRYSTAL_SPEAR);
- case SPELL_BLINK:
- return (MS_BLINK);
- case SPELL_ISKENDERUNS_MYSTIC_BLAST:
- return (MS_ORB_ENERGY);
- case SPELL_SUMMON_HORRIBLE_THINGS:
- return (MS_LEVEL_SUMMON); /* approximate */
- case SPELL_ANIMATE_DEAD:
- return (MS_ANIMATE_DEAD);
- case SPELL_PAIN:
- return (MS_PAIN);
- case SPELL_SUMMON_WRAITHS:
- return (MS_SUMMON_UNDEAD); /* approximate */
- case SPELL_STICKY_FLAME:
- return (MS_STICKY_FLAME);
- case SPELL_CALL_IMP:
- return (MS_SUMMON_DEMON_LESSER);
- case SPELL_BANISHMENT:
- return (MS_BANISHMENT);
- case SPELL_STING:
- return (MS_STING);
- case SPELL_SUMMON_DEMON:
- return (MS_SUMMON_DEMON);
- case SPELL_DEMONIC_HORDE:
- return (MS_SUMMON_DEMON_LESSER);
- case SPELL_SUMMON_GREATER_DEMON:
- return (MS_SUMMON_DEMON_GREATER);
- case SPELL_BOLT_OF_IRON:
- return (MS_IRON_BOLT);
- case SPELL_STONE_ARROW:
- return (MS_STONE_ARROW);
- case SPELL_DISINTEGRATE:
- return (MS_DISINTEGRATE);
- case SPELL_AGONY:
- /* Too powerful to give ghosts Torment for Agony? Nah. */
- return (MS_TORMENT);
- case SPELL_SYMBOL_OF_TORMENT:
- return (MS_TORMENT);
- default:
- break;
- }
-
- return (MS_NO_SPELL);
-}
-
-void generate_random_demon(void)
-{
- int rdem = 0;
- int i = 0;
-
- for (rdem = 0; rdem < MAX_MONSTERS + 1; rdem++)
- {
- if (rdem == MAX_MONSTERS)
- return;
-
- if (menv[rdem].type == MONS_PANDEMONIUM_DEMON)
- break;
- }
-
- char st_p[ITEMNAME_SIZE];
-
- make_name(random_int(), false, st_p);
- strcpy(ghost.name, st_p);
-
- // hp - could be defined below (as could ev, AC etc). Oh well, too late:
- ghost.values[ GVAL_MAX_HP ] = 100 + roll_dice( 3, 50 );
-
- ghost.values[ GVAL_EV ] = 5 + random2(20);
- ghost.values[ GVAL_AC ] = 5 + random2(20);
-
- ghost.values[ GVAL_SEE_INVIS ] = (one_chance_in(10) ? 0 : 1);
-
- if (!one_chance_in(3))
- ghost.values[ GVAL_RES_FIRE ] = (coinflip() ? 2 : 3);
- else
- {
- ghost.values[ GVAL_RES_FIRE ] = 0; /* res_fire */
-
- if (one_chance_in(10))
- ghost.values[ GVAL_RES_FIRE ] = -1;
- }
-
- if (!one_chance_in(3))
- ghost.values[ GVAL_RES_COLD ] = 2;
- else
- {
- ghost.values[ GVAL_RES_COLD ] = 0; /* res_cold */
-
- if (one_chance_in(10))
- ghost.values[ GVAL_RES_COLD ] = -1;
- }
-
- // demons, like ghosts, automatically get poison res. and life prot.
-
- // resist electricity:
- ghost.values[ GVAL_RES_ELEC ] = (!one_chance_in(3) ? 1 : 0);
-
- // HTH damage:
- ghost.values[ GVAL_DAMAGE ] = 20 + roll_dice( 2, 20 );
-
- // special attack type (uses weapon brand code):
- ghost.values[ GVAL_BRAND ] = SPWPN_NORMAL;
-
- if (!one_chance_in(3))
- {
- ghost.values[ GVAL_BRAND ] = random2(17);
-
- /* some brands inappropriate (eg holy wrath) */
- if (ghost.values[ GVAL_BRAND ] == SPWPN_HOLY_WRATH
- || ghost.values[ GVAL_BRAND ] == SPWPN_ORC_SLAYING
- || ghost.values[ GVAL_BRAND ] == SPWPN_PROTECTION
- || ghost.values[ GVAL_BRAND ] == SPWPN_FLAME
- || ghost.values[ GVAL_BRAND ] == SPWPN_FROST
- || ghost.values[ GVAL_BRAND ] == SPWPN_DISRUPTION)
- {
- ghost.values[ GVAL_BRAND ] = SPWPN_SPEED;
- }
- }
-
- // is demon a spellcaster?
- // upped from one_chance_in(3)... spellcasters are more interesting
- // and I expect named demons to typically have a trick or two -- bwr
- ghost.values[GVAL_DEMONLORD_SPELLCASTER] = (one_chance_in(10) ? 0 : 1);
-
- // does demon fly? (0 = no, 1 = fly, 2 = levitate)
- ghost.values[GVAL_DEMONLORD_FLY] = (one_chance_in(3) ? 0 :
- one_chance_in(5) ? 2 : 1);
-
- // vacant <ghost best skill level>:
- ghost.values[GVAL_DEMONLORD_UNUSED] = 0;
-
- // hit dice:
- ghost.values[GVAL_DEMONLORD_HIT_DICE] = 10 + roll_dice(2, 10);
-
- // does demon cycle colours?
- ghost.values[GVAL_DEMONLORD_CYCLE_COLOUR] = (one_chance_in(10) ? 1 : 0);
-
- menv[rdem].hit_dice = ghost.values[ GVAL_DEMONLORD_HIT_DICE ];
- menv[rdem].hit_points = ghost.values[ GVAL_MAX_HP ];
- menv[rdem].max_hit_points = ghost.values[ GVAL_MAX_HP ];
- menv[rdem].armour_class = ghost.values[ GVAL_AC ];
- menv[rdem].evasion = ghost.values[ GVAL_EV ];
- menv[rdem].speed = (one_chance_in(3) ? 10 : 6 + roll_dice(2, 9));
- menv[rdem].speed_increment = 70;
- menv[rdem].number = random_colour(); // demon's colour
-
- for (i = GVAL_SPELL_1; i <= GVAL_SPELL_6; i++)
- ghost.values[i] = SPELL_NO_SPELL;
-
- /* This bit uses the list of player spells to find appropriate spells
- for the demon, then converts those spells to the monster spell indices.
- Some special monster-only spells are at the end. */
- if (ghost.values[ GVAL_DEMONLORD_SPELLCASTER ] == 1)
- {
- if (coinflip())
- {
- for (;;)
- {
- if (one_chance_in(3))
- break;
-
- ghost.values[ GVAL_SPELL_1 ] = search_order_conj[i];
- i++;
-
- if (search_order_conj[i] == SPELL_NO_SPELL)
- break;
- }
- }
-
- if (coinflip())
- {
- for (;;)
- {
- if (one_chance_in(3))
- break;
-
- ghost.values[ GVAL_SPELL_2 ] = search_order_conj[i];
-
- if (search_order_conj[i] == SPELL_NO_SPELL)
- break;
- }
- }
-
- if (!one_chance_in(4))
- {
- for (;;)
- {
- if (one_chance_in(3))
- break;
-
- ghost.values[ GVAL_SPELL_3 ] = search_order_third[i];
- i++;
-
- if (search_order_third[i] == SPELL_NO_SPELL)
- break;
- }
- }
-
- if (coinflip())
- {
- for (;;)
- {
- if (one_chance_in(3))
- break;
-
- ghost.values[ GVAL_SPELL_4 ] = search_order_misc[i];
- i++;
-
- if (search_order_misc[i] == SPELL_NO_SPELL)
- break;
- }
- }
-
- if (coinflip())
- {
- for(;;)
- {
- if (one_chance_in(3))
- break;
-
- ghost.values[ GVAL_SPELL_5 ] = search_order_misc[i];
- i++;
-
- if (search_order_misc[i] == SPELL_NO_SPELL)
- break;
- }
- }
-
- if (coinflip())
- ghost.values[ GVAL_SPELL_6 ] = SPELL_BLINK;
- if (coinflip())
- ghost.values[ GVAL_SPELL_6 ] = SPELL_TELEPORT_SELF;
-
- /* Converts the player spell indices to monster spell ones */
- for (i = GVAL_SPELL_1; i <= GVAL_SPELL_6; i++)
- ghost.values[i] = translate_spell( ghost.values[i] );
-
- /* give demon a chance for some monster-only spells: */
- /* and demon-summoning should be fairly common: */
- if (one_chance_in(25))
- ghost.values[GVAL_SPELL_1] = MS_HELLFIRE_BURST;
- if (one_chance_in(25))
- ghost.values[GVAL_SPELL_1] = MS_METAL_SPLINTERS;
- if (one_chance_in(25))
- ghost.values[GVAL_SPELL_1] = MS_ENERGY_BOLT; /* eye of devas */
-
- if (one_chance_in(25))
- ghost.values[GVAL_SPELL_2] = MS_STEAM_BALL;
- if (one_chance_in(25))
- ghost.values[GVAL_SPELL_2] = MS_PURPLE_BLAST;
- if (one_chance_in(25))
- ghost.values[GVAL_SPELL_2] = MS_HELLFIRE;
-
- if (one_chance_in(25))
- ghost.values[GVAL_SPELL_3] = MS_SMITE;
- if (one_chance_in(25))
- ghost.values[GVAL_SPELL_3] = MS_HELLFIRE_BURST;
- if (one_chance_in(12))
- ghost.values[GVAL_SPELL_3] = MS_SUMMON_DEMON_GREATER;
- if (one_chance_in(12))
- ghost.values[GVAL_SPELL_3] = MS_SUMMON_DEMON;
-
- if (one_chance_in(20))
- ghost.values[GVAL_SPELL_4] = MS_SUMMON_DEMON_GREATER;
- if (one_chance_in(20))
- ghost.values[GVAL_SPELL_4] = MS_SUMMON_DEMON;
-
- /* at least they can summon demons */
- if (ghost.values[17] == SPELL_NO_SPELL)
- ghost.values[GVAL_SPELL_4] = MS_SUMMON_DEMON;
-
- if (one_chance_in(15))
- ghost.values[GVAL_SPELL_5] = MS_DIG;
- }
-} // end generate_random_demon()
-
-// Largest string we'll save
-#define STR_CAP 1000
-
-using std::string;
-
-void writeShort(FILE *file, short s)
-{
- char data[2];
- // High byte first - network order
- data[0] = (char)((s >> 8) & 0xFF);
- data[1] = (char)(s & 0xFF);
-
- write2(file, data, sizeof(data));
-}
-
-short readShort(FILE *file)
-{
- unsigned char data[2];
- read2(file, (char *) data, 2);
-
- // High byte first
- return (((short) data[0]) << 8) | (short) data[1];
-}
-
-void writeByte(FILE *file, unsigned char byte)
-{
- write2(file, (char *) &byte, sizeof byte);
-}
-
-unsigned char readByte(FILE *file)
-{
- unsigned char byte;
- read2(file, (char *) &byte, sizeof byte);
- return byte;
-}
-
-void writeString(FILE* file, const string &s)
-{
- int length = s.length();
- if (length > STR_CAP) length = STR_CAP;
- writeShort(file, length);
- write2(file, s.c_str(), length);
-}
-
-string readString(FILE *file)
-{
- char buf[STR_CAP + 1];
- short length = readShort(file);
- if (length)
- read2(file, buf, length);
- buf[length] = '\0';
- return string(buf);
-}
-
-void writeLong(FILE* file, long num)
-{
- // High word first, network order
- writeShort(file, (short) ((num >> 16) & 0xFFFFL));
- writeShort(file, (short) (num & 0xFFFFL));
-}
-
-long readLong(FILE *file)
-{
- // We need the unsigned short cast even for the high word because we
- // might be on a system where long is more than 4 bytes, and we don't want
- // to sign extend the high short.
- return ((long) (unsigned short) readShort(file)) << 16 |
- (long) (unsigned short) readShort(file);
-}
diff --git a/stone_soup/crawl-ref/source/files.h b/stone_soup/crawl-ref/source/files.h
deleted file mode 100644
index a2d357cac8..0000000000
--- a/stone_soup/crawl-ref/source/files.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * File: files.cc
- * Summary: Functions used to save and load levels/games.
- * Written by: Linley Henzell and Alexey Guzeev
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef FILES_H
-#define FILES_H
-
-#include "FixAry.h"
-#include <stdio.h>
-#include <string>
-
-// referenced in files - newgame - ouch - overmap:
-#define MAX_LEVELS 50
-// referenced in files - newgame - ouch - overmap:
-#define MAX_BRANCHES 30 // there must be a way this can be extracted from other data
-
-
-// referenced in files - newgame - ouch:
-extern FixedArray<bool, MAX_LEVELS, MAX_BRANCHES> tmp_file_pairs;
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - misc
- * *********************************************************************** */
-#if 0
-void load( unsigned char stair_taken, bool moving_level,
- bool was_a_labyrinth, char old_level, bool want_followers,
- bool is_new_game, char where_were_you2 );
-#endif
-
-bool travel_load_map( char branch, int absdepth );
-
-std::string get_savedir_filename(const char *pre, const char *suf,
- const char *ext);
-
-std::string get_prefs_filename();
-
-void load( unsigned char stair_taken, int load_mode, bool was_a_labyrinth,
- char old_level, char where_were_you2 );
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - libmac - misc
- * *********************************************************************** */
-void save_game(bool leave_game);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void restore_game(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: ouch
- * *********************************************************************** */
-void save_ghost( bool force = false );
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: files hiscores
- * *********************************************************************** */
-void make_filename( char *buf, const char *prefix, int level, int where,
- bool isLabyrinth, bool isGhost );
-
-
-void writeShort(FILE *file, short s);
-
-short readShort(FILE *file);
-
-void writeByte(FILE *file, unsigned char byte);
-
-unsigned char readByte(FILE *file);
-
-void writeString(FILE* file, const std::string &s);
-
-std::string readString(FILE *file);
-
-void writeLong(FILE* file, long num);
-
-long readLong(FILE *file);
-
-#endif
diff --git a/stone_soup/crawl-ref/source/food.cc b/stone_soup/crawl-ref/source/food.cc
deleted file mode 100644
index eee0cd6a78..0000000000
--- a/stone_soup/crawl-ref/source/food.cc
+++ /dev/null
@@ -1,1379 +0,0 @@
-/*
- * File: food.cc
- * Summary: Functions for eating and butchering.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <2> 5/20/99 BWR Added CRAWL_PIZZA.
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "food.h"
-
-#include <string.h>
-// required for abs() {dlb}:
-#include <stdlib.h>
-#include <stdio.h>
-#include <ctype.h>
-
-#ifdef DOS
-#include <conio.h>
-#endif
-
-#include "externs.h"
-
-#include "clua.h"
-#include "debug.h"
-#include "delay.h"
-#include "invent.h"
-#include "items.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "item_use.h"
-#include "it_use2.h"
-#include "macro.h"
-#include "misc.h"
-#include "mon-util.h"
-#include "mutation.h"
-#include "player.h"
-#include "religion.h"
-#include "skills2.h"
-#include "spells2.h"
-#include "stuff.h"
-#include "wpn-misc.h"
-
-static int determine_chunk_effect(int which_chunk_type, bool rotten_chunk);
-static void eat_chunk( int chunk_effect );
-static void eating(unsigned char item_class, int item_type);
-static void ghoul_eat_flesh( int chunk_effect );
-static void describe_food_change(int hunger_increment);
-static bool food_change(bool suppress_message);
-
-/*
- **************************************************
- * *
- * BEGIN PUBLIC FUNCTIONS *
- * *
- **************************************************
-*/
-
-void make_hungry( int hunger_amount, bool suppress_msg )
-{
- if (you.is_undead == US_UNDEAD)
- return;
-
-#if DEBUG_DIAGNOSTICS
- set_redraw_status( REDRAW_HUNGER );
-#endif
-
- you.hunger -= hunger_amount;
-
- if (you.hunger < 0)
- you.hunger = 0;
-
- // so we don't get two messages, ever.
- bool state_message = food_change(false);
-
- if (!suppress_msg && !state_message)
- describe_food_change( -hunger_amount );
-} // end make_hungry()
-
-void lessen_hunger( int satiated_amount, bool suppress_msg )
-{
- if (you.is_undead == US_UNDEAD)
- return;
-
- you.hunger += satiated_amount;
-
- if (you.hunger > 12000)
- you.hunger = 12000;
-
- // so we don't get two messages, ever
- bool state_message = food_change(false);
-
- if (!suppress_msg && !state_message)
- describe_food_change(satiated_amount);
-} // end lessen_hunger()
-
-void set_hunger( int new_hunger_level, bool suppress_msg )
-{
- if (you.is_undead == US_UNDEAD)
- return;
-
- int hunger_difference = (new_hunger_level - you.hunger);
-
- if (hunger_difference < 0)
- make_hungry( abs(hunger_difference), suppress_msg );
- else if (hunger_difference > 0)
- lessen_hunger( hunger_difference, suppress_msg );
-} // end set_hunger()
-
-// more of a "weapon_switch back from butchering" function, switching
-// to a weapon is done using the wield_weapon code.
-// special cases like staves of power or other special weps are taken
-// care of by calling wield_effects() {gdl}
-
-void weapon_switch( int targ )
-{
- if (targ == -1)
- {
- mpr( "You switch back to your bare hands." );
- }
- else
- {
- char buff[80];
- in_name( targ, DESC_NOCAP_A, buff );
-
- char let = index_to_letter( targ );
-
- snprintf( info, INFO_SIZE, "Switching back to %c - %s.", let, buff );
- mpr( info );
- }
-
- // unwield the old weapon and wield the new.
- // XXX This is a pretty dangerous hack; I don't like it.--GDL
- //
- // Well yeah, but that's because interacting with the wielding
- // code is a mess... this whole function's purpose was to
- // isolate this hack until there's a proper way to do things. -- bwr
- if (you.equip[EQ_WEAPON] != -1)
- unwield_item(you.equip[EQ_WEAPON]);
-
- you.equip[EQ_WEAPON] = targ;
-
- // special checks: staves of power, etc
- if (targ != -1)
- wield_effects( targ, false );
-}
-
-bool butchery(void)
-{
- char str_pass[ ITEMNAME_SIZE ];
- int items_here = 0;
- int o = igrd[you.x_pos][you.y_pos];
- int k = 0;
- int item_got;
- unsigned char keyin;
-
- bool can_butcher = false;
- bool wpn_switch = false;
- bool new_cursed = false;
- int old_weapon = you.equip[EQ_WEAPON];
-
- bool barehand_butcher = (you.equip[ EQ_GLOVES ] == -1)
- && (you.species == SP_TROLL
- || you.species == SP_GHOUL
- || you.attribute[ATTR_TRANSFORMATION] == TRAN_BLADE_HANDS
- || you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON
- || you.mutation[MUT_CLAWS]);
-
-
- if (igrd[you.x_pos][you.y_pos] == NON_ITEM)
- {
- mpr("There isn't anything here!");
- return (false);
- }
-
- if (player_is_levitating() && !wearing_amulet(AMU_CONTROLLED_FLIGHT))
- {
- mpr("You can't reach the floor from up here.");
- return (false);
- }
-
- if (barehand_butcher)
- can_butcher = true;
- else
- {
- if (you.equip[EQ_WEAPON] != -1)
- {
- can_butcher = can_cut_meat( you.inv[you.equip[EQ_WEAPON]].base_type,
- you.inv[you.equip[EQ_WEAPON]].sub_type );
- }
-
- // Should probably check for cursed-weapons, bare hands and
- // non-weapons in hand here, but wield_weapon will be used for
- // this swap and it will do all that (although the player might
- // be annoyed with the excess prompt).
- if (Options.easy_butcher && !can_butcher)
- {
- //mv: check for berserk first
- if (you.berserker)
- {
- mpr ("You are too berserk to search for a butchering knife!");
- return (false);
- }
-
- // We'll now proceed to look through the entire inventory for
- // choppers/slicers. We'll skip special weapons because
- // wielding/unwielding a foo of distortion would be disastrous.
- for (int i = 0; i < ENDOFPACK; ++i)
- {
- if (is_valid_item( you.inv[i] )
- && can_cut_meat( you.inv[i].base_type,
- you.inv[i].sub_type )
- && you.inv[i].base_type == OBJ_WEAPONS
- && item_known_uncursed(you.inv[i])
- && item_ident( you.inv[i], ISFLAG_KNOW_TYPE )
- && get_weapon_brand(you.inv[i])
- != SPWPN_DISTORTION
- && can_wield( you.inv[i] ))
- {
- mpr("Switching to a butchering implement.");
- wpn_switch = true;
- wield_weapon( true, i, false );
- break;
- }
- }
-
- // if we didn't swap above, then we still can't cut... let's
- // call wield_weapon() in the "prompt the user" way...
- if (!wpn_switch)
- {
- // prompt for new weapon
- mpr( "What would you like to use?", MSGCH_PROMPT );
- wield_weapon( false );
-
- // let's see if the user did something...
- if (you.equip[EQ_WEAPON] != old_weapon)
- wpn_switch = true;
- }
- }
-
- // weapon might have changed (to bare hands as well), we'll
- // update the can_butcher status accordingly (note: if we could
- // butcher with our bare hands we wouldn't be here) -- bwr
- if (wpn_switch && you.equip[EQ_WEAPON] != -1)
- {
- can_butcher = can_cut_meat( you.inv[you.equip[EQ_WEAPON]].base_type,
- you.inv[you.equip[EQ_WEAPON]].sub_type );
- }
- }
-
- // Account for the weapon switch above if it happened... we're
- // doing this here since the above switch may reveal information
- // about the weapon (curse status, ego type). So even if the
- // character fails to or decides not to butcher past this point,
- // they have achieved something and there should be a cost.
- if (wpn_switch)
- start_delay( DELAY_UNINTERUPTABLE, 1, old_weapon );
-
- // check to see if the new implement is cursed - if so, set a
- // flag indicating this. If a player actually butchers anything,
- // this flag can be checked before switching back.
- int wpn = you.equip[EQ_WEAPON];
-
- if (wpn != -1
- && you.inv[wpn].base_type == OBJ_WEAPONS
- && item_cursed( you.inv[wpn] ))
- {
- new_cursed = true;
- }
-
- // Final checks and clue-giving...
- if (!barehand_butcher && you.equip[EQ_WEAPON] == -1)
- {
- if (you.equip[ EQ_GLOVES ] == -1)
- mpr("What, with your bare hands?");
- else
- mpr("You can't use your claws with your gloves on!");
-
- // Switching back to avoid possible bug where player can use
- // this to switch weapons in zero time.
- if (wpn_switch)
- weapon_switch( old_weapon );
-
- return (false);
- }
- else if (!can_butcher)
- {
- mpr("Maybe you should try using a sharper implement.");
-
- // Switching back to avoid possible bug where player can use
- // this to switch weapons in zero time.
- if (wpn_switch && !new_cursed)
- weapon_switch( old_weapon );
-
- return (false);
- }
-
- // No turning back at this point, we better be qualified.
- ASSERT( can_butcher );
-
- int last_item = NON_ITEM;
-
- int objl = igrd[you.x_pos][you.y_pos];
- int hrg = 0;
- int counter = 0;
-
- while (objl != NON_ITEM)
- {
- counter++;
-
- last_item = objl;
-
- hrg = mitm[objl].link;
- objl = hrg;
- items_here++;
-
- if (counter > 1000)
- {
- error_message_to_player();
-
- if (wpn_switch && !new_cursed)
- weapon_switch( old_weapon );
-
- return (false);
- }
- }
-
- if (items_here == 1
- && (mitm[igrd[you.x_pos][you.y_pos]].base_type == OBJ_CORPSES &&
- mitm[igrd[you.x_pos][you.y_pos]].sub_type == CORPSE_BODY))
- {
- strcpy(info, "Butcher ");
- it_name(igrd[you.x_pos][you.y_pos], DESC_NOCAP_A, str_pass);
- strcat(info, str_pass);
- strcat(info, "\?");
- mpr(info, MSGCH_PROMPT);
-
- unsigned char keyin = getch();
-
- if (keyin == 0)
- {
- getch();
- keyin = 0;
- }
-
- if (keyin != 'y' && keyin != 'Y')
- {
- if (wpn_switch && !new_cursed)
- weapon_switch( old_weapon );
-
- return (false);
- }
-
- int item_got = igrd[you.x_pos][you.y_pos];
-
- last_item = NON_ITEM;
-
- if (barehand_butcher)
- mpr("You start tearing the corpse apart.");
- else
- mpr("You start hacking away.");
-
- if (you.duration[DUR_PRAYER]
- && (you.religion == GOD_OKAWARU
- || you.religion == GOD_MAKHLEB || you.religion == GOD_TROG))
- {
- offer_corpse(item_got);
- destroy_item(item_got);
- // XXX: need an extra turn here for weapon swapping?
- }
- else
- {
- int work_req = 3 - mitm[item_got].plus2;
- if (work_req < 0)
- work_req = 0;
-
- start_delay( DELAY_BUTCHER, work_req, item_got );
- }
-
- // cue up switching weapon back
- if (wpn_switch && !new_cursed)
- start_delay( DELAY_WEAPON_SWAP, 1, old_weapon );
-
- you.turn_is_over = 1;
-
- return (true);
-
- } // end "if items_here == 1"
- else if (items_here > 1)
- {
- last_item = NON_ITEM;
- o = igrd[you.x_pos][you.y_pos];
-
- for (k = 0; k < items_here; k++)
- {
- if (mitm[o].base_type != OBJ_CORPSES
- || mitm[o].sub_type != CORPSE_BODY)
- {
- goto out_of_eating;
- }
-
- strcpy(info, "Butcher ");
- it_name(o, DESC_NOCAP_A, str_pass);
- strcat(info, str_pass);
- strcat(info, "\?");
- mpr(info, MSGCH_PROMPT);
-
- keyin = getch();
- if (keyin == 0)
- {
- getch();
- keyin = 0;
- }
-
- if (keyin == 'q')
- {
- if (wpn_switch && !new_cursed)
- weapon_switch( old_weapon );
-
- return (false);
- }
-
- if (keyin == 'y')
- {
- item_got = o;
-
- if (barehand_butcher)
- mpr("You start tearing the corpse apart.");
- else
- mpr("You start hacking away.");
-
- if (you.duration[DUR_PRAYER]
- && (you.religion == GOD_OKAWARU
- || you.religion == GOD_MAKHLEB
- || you.religion == GOD_TROG))
- {
- offer_corpse(item_got);
- destroy_item(item_got);
- // XXX: need an extra turn here for weapon swapping?
- }
- else
- {
- int work_req = 3 - mitm[item_got].plus2;
- if (work_req < 0)
- work_req = 0;
-
- start_delay( DELAY_BUTCHER, work_req, item_got );
- }
-
- if (wpn_switch && !new_cursed)
- {
- // weapon_switch( old_weapon );
- // need to count the swap delay in this case
- start_delay( DELAY_WEAPON_SWAP, 1, old_weapon );
- }
-
- you.turn_is_over = 1;
- return (true);
- }
-
- out_of_eating:
-
- if (is_valid_item( mitm[o] ))
- last_item = o;
-
- hrg = mitm[o].link;
- o = hrg;
-
- if (o == NON_ITEM)
- break;
-
- if (items_here == 0)
- break;
- } // end "for k" loop
- }
-
- mpr("There isn't anything to dissect here.");
-
- if (wpn_switch && !new_cursed)
- weapon_switch( old_weapon );
-
- return (false);
-} // end butchery()
-
-#ifdef CLUA_BINDINGS
-void lua_push_items(lua_State *ls, int link)
-{
- lua_newtable(ls);
- int index = 0;
- for ( ; link != NON_ITEM; link = mitm[link].link)
- {
- lua_pushlightuserdata(ls, &mitm[link]);
- lua_rawseti(ls, -2, ++index);
- }
-}
-
-void lua_push_floor_items(lua_State *ls)
-{
- lua_push_items(ls, igrd[you.x_pos][you.y_pos]);
-}
-
-void lua_push_inv_items(lua_State *ls = NULL)
-{
- if (!ls)
- ls = clua.state();
- lua_newtable(ls);
- int index = 0;
- for (unsigned slot = 0; slot < ENDOFPACK; ++slot)
- {
- if (is_valid_item(you.inv[slot]))
- {
- lua_pushlightuserdata(ls, &you.inv[slot]);
- lua_rawseti(ls, -2, ++index);
- }
- }
-}
-#endif
-
-static bool userdef_eat_food()
-{
-#ifdef CLUA_BINDINGS
- lua_push_floor_items(clua.state());
- lua_push_inv_items();
- bool ret = clua.callfn("c_eat", 2, 0);
- if (!ret && clua.error.length())
- mpr(clua.error.c_str());
- return ret;
-#else
- return false;
-#endif
-}
-
-bool prompt_eat_from_inventory(void)
-{
- if (inv_count() < 1)
- {
- canned_msg(MSG_NOTHING_CARRIED);
- return (false);
- }
-
- int which_inventory_slot =
- prompt_invent_item( "Eat which item?", OBJ_FOOD );
- if (which_inventory_slot == PROMPT_ABORT)
- {
- canned_msg( MSG_OK );
- return (false);
- }
-
- // this conditional can later be merged into food::can_ingest() when
- // expanded to handle more than just OBJ_FOOD 16mar200 {dlb}
- if (you.inv[which_inventory_slot].base_type != OBJ_FOOD)
- {
- mpr("You can't eat that!");
- return (false);
- }
-
- if (!can_ingest( you.inv[which_inventory_slot].base_type,
- you.inv[which_inventory_slot].sub_type, false ))
- {
- return (false);
- }
-
- eat_from_inventory(which_inventory_slot);
-
- burden_change();
- you.turn_is_over = 1;
-
- return (true);
-}
-
-// [ds] Returns true if something was eaten
-bool eat_food(bool run_hook)
-{
- if (you.is_undead == US_UNDEAD)
- {
- mpr("You can't eat.");
- return (false);
- }
-
- if (you.hunger >= 11000)
- {
- mpr("You're too full to eat anything.");
- return (false);
- }
-
- // If user hook ran, we don't know whether something
- // was eaten or not...
- if (run_hook && userdef_eat_food())
- return (false);
-
- if (igrd[you.x_pos][you.y_pos] != NON_ITEM)
- {
- if (eat_from_floor())
- {
- burden_change(); // ghouls regain strength from rotten food
- return (true);
- }
- }
-
- return (prompt_eat_from_inventory());
-} // end eat_food()
-
-/*
- **************************************************
- * *
- * END PUBLIC FUNCTIONS *
- * *
- **************************************************
-*/
-
-static bool food_change(bool suppress_message)
-{
- char newstate = HS_ENGORGED;
- bool state_changed = false;
-
- // this case shouldn't actually happen:
- if (you.is_undead == US_UNDEAD)
- you.hunger = 6000;
-
- // take care of ghouls - they can never be 'full'
- if (you.species == SP_GHOUL && you.hunger > 6999)
- you.hunger = 6999;
-
- // get new hunger state
- if (you.hunger <= 1000)
- newstate = HS_STARVING;
- else if (you.hunger <= 2600)
- newstate = HS_HUNGRY;
- else if (you.hunger < 7000)
- newstate = HS_SATIATED;
- else if (you.hunger < 11000)
- newstate = HS_FULL;
-
- if (newstate != you.hunger_state)
- {
- state_changed = true;
- you.hunger_state = newstate;
- set_redraw_status( REDRAW_HUNGER );
-
- // Stop the travel command, if it's in progress and we just got hungry
- if (newstate < HS_SATIATED)
- interrupt_activity( AI_HUNGRY );
-
- if (suppress_message == false)
- {
- switch (you.hunger_state)
- {
- case HS_STARVING:
- mpr("You are starving!", MSGCH_FOOD);
- break;
- case HS_HUNGRY:
- mpr("You are feeling hungry.", MSGCH_FOOD);
- break;
- default:
- break;
- }
- }
- }
-
- return (state_changed);
-} // end food_change()
-
-
-// food_increment is positive for eating, negative for hungering
-static void describe_food_change(int food_increment)
-{
- int magnitude = (food_increment > 0)?food_increment:(-food_increment);
-
- if (magnitude == 0)
- return;
-
- strcpy(info, (magnitude <= 100) ? "You feel slightly " :
- (magnitude <= 350) ? "You feel somewhat " :
- (magnitude <= 800) ? "You feel a quite a bit "
- : "You feel a lot ");
-
- if ((you.hunger_state > HS_SATIATED) ^ (food_increment < 0))
- strcat(info, "more ");
- else
- strcat(info, "less ");
-
- strcat(info, (you.hunger_state > HS_SATIATED) ? "full."
- : "hungry.");
- mpr(info);
-} // end describe_food_change()
-
-void eat_from_inventory(int which_inventory_slot)
-{
- if (you.inv[which_inventory_slot].sub_type == FOOD_CHUNK)
- {
- // this is a bit easier to read... most compilers should
- // handle this the same -- bwr
- const int mons_type = you.inv[ which_inventory_slot ].plus;
- const int chunk_type = mons_corpse_effect( mons_type );
- const bool rotten = (you.inv[which_inventory_slot].special < 100);
-
- eat_chunk( determine_chunk_effect( chunk_type, rotten ) );
- }
- else
- {
- eating( you.inv[which_inventory_slot].base_type,
- you.inv[which_inventory_slot].sub_type );
- }
-
- dec_inv_item_quantity( which_inventory_slot, 1 );
-} // end eat_from_inventory()
-
-void eat_floor_item(int item_link)
-{
- if (mitm[item_link].sub_type == FOOD_CHUNK)
- {
- const int chunk_type = mons_corpse_effect( mitm[item_link].plus );
- const bool rotten = (mitm[item_link].special < 100);
-
- eat_chunk( determine_chunk_effect( chunk_type, rotten ) );
- }
- else
- {
- eating( mitm[item_link].base_type, mitm[item_link].sub_type );
- }
-
- you.turn_is_over = 1;
-
- dec_mitm_item_quantity( item_link, 1 );
-}
-
-bool eat_from_floor(void)
-{
- char str_pass[ ITEMNAME_SIZE ];
-
- if (player_is_levitating() && !wearing_amulet(AMU_CONTROLLED_FLIGHT))
- return (false);
-
- for (int o = igrd[you.x_pos][you.y_pos]; o != NON_ITEM; o = mitm[o].link)
- {
- if (mitm[o].base_type != OBJ_FOOD)
- continue;
-
- it_name( o, DESC_NOCAP_A, str_pass );
- snprintf( info, INFO_SIZE, "Eat %s%s?", (mitm[o].quantity > 1) ? "one of " : "",
- str_pass );
- mpr( info, MSGCH_PROMPT );
-
- unsigned char keyin = tolower( getch() );
-
- if (keyin == 0)
- {
- getch();
- keyin = 0;
- }
-
- if (keyin == 'q')
- return (false);
-
- if (keyin == 'y')
- {
- if (!can_ingest( mitm[o].base_type, mitm[o].sub_type, false ))
- return (false);
-
- eat_floor_item(o);
- return (true);
- }
- }
-
- return (false);
-}
-
-
-// never called directly - chunk_effect values must pass
-// through food::determine_chunk_effect() first {dlb}:
-static void eat_chunk( int chunk_effect )
-{
-
- bool likes_chunks = (you.species == SP_KOBOLD || you.species == SP_OGRE
- || you.species == SP_TROLL
- || you.mutation[MUT_CARNIVOROUS] > 0);
-
- if (you.species == SP_GHOUL)
- {
- ghoul_eat_flesh( chunk_effect );
- start_delay( DELAY_EAT, 2 );
- lessen_hunger( 1000, true );
- }
- else
- {
- switch (chunk_effect)
- {
- case CE_MUTAGEN_RANDOM:
- mpr("This meat tastes really weird.");
- mutate(100);
- break;
-
- case CE_MUTAGEN_BAD:
- mpr("This meat tastes *really* weird.");
- give_bad_mutation();
- break;
-
- case CE_HCL:
- rot_player( 10 + random2(10) );
- disease_player( 50 + random2(100) );
- break;
-
- case CE_POISONOUS:
- mpr("Yeeuch - this meat is poisonous!");
- poison_player( 3 + random2(4) );
- break;
-
- case CE_ROTTEN:
- case CE_CONTAMINATED:
- mpr("There is something wrong with this meat.");
- disease_player( 50 + random2(100) );
- break;
-
- // note that this is the only case that takes time and forces redraw
- case CE_CLEAN:
- strcpy(info, "This raw flesh ");
-
- strcat(info, (likes_chunks) ? "tastes good."
- : "is not very appetising.");
- mpr(info);
-
- start_delay( DELAY_EAT, 2 );
- lessen_hunger( 1000, true );
- break;
- }
- }
-
- return;
-} // end eat_chunk()
-
-static void ghoul_eat_flesh( int chunk_effect )
-{
- bool healed = false;
-
- if (chunk_effect != CE_ROTTEN && chunk_effect != CE_CONTAMINATED)
- {
- mpr("This raw flesh tastes good.");
-
- if (!one_chance_in(5))
- healed = true;
-
- if (player_rotted() && !one_chance_in(3))
- {
- mpr("You feel more resilient.");
- unrot_hp(1);
- }
- }
- else
- {
- if (chunk_effect == CE_ROTTEN)
- mpr( "This rotting flesh tastes delicious!" );
- else // CE_CONTAMINATED
- mpr( "This flesh tastes delicious!" );
-
- healed = true;
-
- if (player_rotted() && !one_chance_in(4))
- {
- mpr("You feel more resilient.");
- unrot_hp(1);
- }
- }
-
- if (you.strength < you.max_strength && one_chance_in(5))
- {
- mpr("You feel your strength returning.");
- you.strength++;
- you.redraw_strength = 1;
- }
-
- if (healed && you.hp < you.hp_max)
- inc_hp(1 + random2(5) + random2(1 + you.experience_level), false);
-
- calc_hp();
-
- return;
-} // end ghoul_eat_flesh()
-
-static void eating(unsigned char item_class, int item_type)
-{
- int temp_rand; // probability determination {dlb}
- int food_value = 0;
- int how_herbivorous = you.mutation[MUT_HERBIVOROUS];
- int how_carnivorous = you.mutation[MUT_CARNIVOROUS];
- int carnivore_modifier = 0;
- int herbivore_modifier = 0;
-
- switch (item_class)
- {
- case OBJ_FOOD:
- // apply base sustenance {dlb}:
- switch (item_type)
- {
- case FOOD_MEAT_RATION:
- case FOOD_ROYAL_JELLY:
- food_value = 5000;
- break;
- case FOOD_BREAD_RATION:
- food_value = 4400;
- break;
- case FOOD_HONEYCOMB:
- food_value = 2000;
- break;
- case FOOD_SNOZZCUMBER: // maybe a nasty side-effect from RD's book?
- case FOOD_PIZZA:
- case FOOD_BEEF_JERKY:
- food_value = 1500;
- break;
- case FOOD_CHEESE:
- case FOOD_SAUSAGE:
- food_value = 1200;
- break;
- case FOOD_ORANGE:
- case FOOD_BANANA:
- case FOOD_LEMON:
- food_value = 1000;
- break;
- case FOOD_PEAR:
- case FOOD_APPLE:
- case FOOD_APRICOT:
- food_value = 700;
- break;
- case FOOD_CHOKO:
- case FOOD_RAMBUTAN:
- case FOOD_LYCHEE:
- food_value = 600;
- break;
- case FOOD_STRAWBERRY:
- food_value = 200;
- break;
- case FOOD_GRAPE:
- food_value = 100;
- break;
- case FOOD_SULTANA:
- food_value = 70; // will not save you from starvation
- break;
- default:
- break;
- } // end base sustenance listing {dlb}
-
- // next, sustenance modifier for carnivores/herbivores {dlb}:
- // for some reason, sausages do not penalize herbivores {dlb}:
- switch (item_type)
- {
- case FOOD_MEAT_RATION:
- carnivore_modifier = 500;
- herbivore_modifier = -1500;
- break;
- case FOOD_BEEF_JERKY:
- carnivore_modifier = 200;
- herbivore_modifier = -200;
- break;
- case FOOD_BREAD_RATION:
- carnivore_modifier = -1000;
- herbivore_modifier = 500;
- break;
- case FOOD_BANANA:
- case FOOD_ORANGE:
- case FOOD_LEMON:
- carnivore_modifier = -300;
- herbivore_modifier = 300;
- break;
- case FOOD_PEAR:
- case FOOD_APPLE:
- case FOOD_APRICOT:
- case FOOD_CHOKO:
- case FOOD_SNOZZCUMBER:
- case FOOD_RAMBUTAN:
- case FOOD_LYCHEE:
- carnivore_modifier = -200;
- herbivore_modifier = 200;
- break;
- case FOOD_STRAWBERRY:
- carnivore_modifier = -50;
- herbivore_modifier = 50;
- break;
- case FOOD_GRAPE:
- case FOOD_SULTANA:
- carnivore_modifier = -20;
- herbivore_modifier = 20;
- break;
- default:
- carnivore_modifier = 0;
- herbivore_modifier = 0;
- break;
- } // end carnivore/herbivore modifier listing {dlb}
-
- // next, let's take care of messaging {dlb}:
- if (how_carnivorous > 0 && carnivore_modifier < 0)
- mpr("Blech - you need meat!");
- else if (how_herbivorous > 0 && herbivore_modifier < 0)
- mpr("Blech - you need greens!");
-
- if (how_herbivorous < 1)
- {
- switch (item_type)
- {
- case FOOD_MEAT_RATION:
- mpr("That meat ration really hit the spot!");
- break;
- case FOOD_BEEF_JERKY:
- strcpy(info, "That beef jerky was ");
- strcat(info, (one_chance_in(4)) ? "jerk-a-riffic"
- : "delicious");
- strcat(info, "!");
- mpr(info);
- break;
- default:
- break;
- }
- }
-
- if (how_carnivorous < 1)
- {
- switch (item_type)
- {
- case FOOD_BREAD_RATION:
- mpr("That bread ration really hit the spot!");
- break;
- case FOOD_PEAR:
- case FOOD_APPLE:
- case FOOD_APRICOT:
- strcpy(info, "Mmmm... Yummy ");
- strcat(info, (item_type == FOOD_APPLE) ? "apple." :
- (item_type == FOOD_PEAR) ? "pear." :
- (item_type == FOOD_APRICOT) ? "apricot."
- : "fruit.");
- mpr(info);
- break;
- case FOOD_CHOKO:
- mpr("That choko was very bland.");
- break;
- case FOOD_SNOZZCUMBER:
- mpr("That snozzcumber tasted truly putrid!");
- break;
- case FOOD_ORANGE:
- strcpy(info, "That orange was delicious!");
- if (one_chance_in(8))
- strcat(info, " Even the peel tasted good!");
- mpr(info);
- break;
- case FOOD_BANANA:
- strcpy(info, "That banana was delicious!");
- if (one_chance_in(8))
- strcat(info, " Even the peel tasted good!");
- mpr(info);
- break;
- case FOOD_STRAWBERRY:
- mpr("That strawberry was delicious!");
- break;
- case FOOD_RAMBUTAN:
- mpr("That rambutan was delicious!");
- break;
- case FOOD_LEMON:
- mpr("That lemon was rather sour... But delicious nonetheless!");
- break;
- case FOOD_GRAPE:
- mpr("That grape was delicious!");
- break;
- case FOOD_SULTANA:
- mpr("That sultana was delicious! (but very small)");
- break;
- case FOOD_LYCHEE:
- mpr("That lychee was delicious!");
- break;
- default:
- break;
- }
- }
-
- switch (item_type)
- {
- case FOOD_HONEYCOMB:
- mpr("That honeycomb was delicious.");
- break;
- case FOOD_ROYAL_JELLY:
- mpr("That royal jelly was delicious!");
- restore_stat(STAT_ALL, false);
- break;
- case FOOD_PIZZA:
- if (SysEnv.crawl_pizza && !one_chance_in(3))
- snprintf(info, INFO_SIZE, "Mmm... %s", SysEnv.crawl_pizza);
- else
- {
- temp_rand = random2(9);
-
- snprintf(info, INFO_SIZE, "Mmm... %s",
- (temp_rand == 0) ? "Ham and pineapple." :
- (temp_rand == 2) ? "Vegetable." :
- (temp_rand == 3) ? "Pepperoni." :
- (temp_rand == 4) ? "Yeuchh - Anchovies!" :
- (temp_rand == 5) ? "Cheesy." :
- (temp_rand == 6) ? "Supreme." :
- (temp_rand == 7) ? "Super Supreme!"
- : "Chicken.");
- }
- mpr(info);
- break;
- case FOOD_CHEESE:
- strcpy(info, "Mmm... ");
- temp_rand = random2(9);
-
- strcat(info, (temp_rand == 0) ? "Cheddar" :
- (temp_rand == 1) ? "Edam" :
- (temp_rand == 2) ? "Wensleydale" :
- (temp_rand == 3) ? "Camembert" :
- (temp_rand == 4) ? "Goat cheese" :
- (temp_rand == 5) ? "Fruit cheese" :
- (temp_rand == 6) ? "Mozzarella" :
- (temp_rand == 7) ? "Sheep cheese"
- : "Yak cheese");
-
- strcat(info, ".");
- mpr(info);
- break;
- case FOOD_SAUSAGE:
- mpr("That sausage was delicious!");
- break;
- default:
- break;
- }
-
- // finally, modify player's hunger level {dlb}:
- if (carnivore_modifier && how_carnivorous > 0)
- food_value += (carnivore_modifier * how_carnivorous);
-
- if (herbivore_modifier && how_herbivorous > 0)
- food_value += (herbivore_modifier * how_herbivorous);
-
- if (food_value > 0)
- {
- if (item_type == FOOD_MEAT_RATION || item_type == FOOD_BREAD_RATION)
- start_delay( DELAY_EAT, 3 );
- else
- start_delay( DELAY_EAT, 1 );
-
- lessen_hunger( food_value, true );
- }
- break;
-
- default:
- break;
- }
-
- return;
-} // end eating()
-
-bool can_ingest(int what_isit, int kindof_thing, bool suppress_msg, bool reqid,
- bool check_hunger)
-{
- bool survey_says = false;
-
- // [ds] These redundant checks are now necessary - Lua might be calling us.
- if (you.is_undead == US_UNDEAD)
- {
- if (!suppress_msg)
- mpr("You can't eat.");
- return (false);
- }
-
- if (check_hunger && you.hunger >= 11000)
- {
- if (!suppress_msg)
- mpr("You're too full to eat anything.");
- return (false);
- }
-
-
- bool ur_carnivorous = (you.species == SP_GHOUL
- || you.species == SP_KOBOLD
- || you.mutation[MUT_CARNIVOROUS] == 3);
-
- bool ur_herbivorous = (you.mutation[MUT_HERBIVOROUS] > 1);
-
- // ur_chunkslover not defined in terms of ur_carnivorous because
- // a player could be one and not the other IMHO - 13mar2000 {dlb}
- bool ur_chunkslover = (
- (check_hunger? you.hunger_state <= HS_HUNGRY : true)
- || wearing_amulet(AMU_THE_GOURMAND, !reqid)
- || you.species == SP_KOBOLD
- || you.species == SP_OGRE
- || you.species == SP_TROLL
- || you.species == SP_GHOUL
- || you.mutation[MUT_CARNIVOROUS]);
-
- switch (what_isit)
- {
- case OBJ_FOOD:
- switch (kindof_thing)
- {
- case FOOD_BREAD_RATION:
- case FOOD_PEAR:
- case FOOD_APPLE:
- case FOOD_CHOKO:
- case FOOD_SNOZZCUMBER:
- case FOOD_PIZZA:
- case FOOD_APRICOT:
- case FOOD_ORANGE:
- case FOOD_BANANA:
- case FOOD_STRAWBERRY:
- case FOOD_RAMBUTAN:
- case FOOD_LEMON:
- case FOOD_GRAPE:
- case FOOD_SULTANA:
- case FOOD_LYCHEE:
- if (ur_carnivorous)
- {
- survey_says = false;
- if (!suppress_msg)
- mpr("Sorry, you're a carnivore.");
- }
- else
- survey_says = true;
- break;
-
- case FOOD_CHUNK:
- if (ur_herbivorous)
- {
- survey_says = false;
- if (!suppress_msg)
- mpr("You can't eat raw meat!");
- }
- else if (!ur_chunkslover)
- {
- survey_says = false;
- if (!suppress_msg)
- mpr("You aren't quite hungry enough to eat that!");
- }
- else
- survey_says = true;
- break;
-
- default:
- return (true);
- }
- break;
-
- // other object types are set to return false for now until
- // someone wants to recode the eating code to permit consumption
- // of things other than just food -- corpses first, then more
- // exotic stuff later would be good to explore - 13mar2000 {dlb}
- case OBJ_CORPSES:
- default:
- return (false);
- }
-
- return (survey_says);
-} // end can_ingest()
-
-// see if you can follow along here -- except for the Amulet of the Gourmand
-// addition (long missing and requested), what follows is an expansion of how
-// chunks were handled in the codebase up to this date -- I have never really
-// understood why liches are hungry and not true undead beings ... {dlb}:
-static int determine_chunk_effect(int which_chunk_type, bool rotten_chunk)
-{
- int poison_resistance_level = player_res_poison();
- int this_chunk_effect = which_chunk_type;
-
- // determine the initial effect of eating a particular chunk {dlb}:
- switch (this_chunk_effect)
- {
- case CE_HCL:
- case CE_MUTAGEN_RANDOM:
- if (you.species == SP_GHOUL
- || you.attribute[ATTR_TRANSFORMATION] == TRAN_LICH)
- {
- this_chunk_effect = CE_CLEAN;
- }
- break;
-
- case CE_POISONOUS:
- if (you.species == SP_GHOUL
- || you.attribute[ATTR_TRANSFORMATION] == TRAN_LICH
- || poison_resistance_level > 0)
- {
- this_chunk_effect = CE_CLEAN;
- }
- break;
-
- case CE_CONTAMINATED:
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_LICH)
- this_chunk_effect = CE_CLEAN;
- else
- {
- switch (you.species)
- {
- case SP_GHOUL:
- // Doing this here causes a odd message later. -- bwr
- // this_chunk_effect = CE_ROTTEN;
- break;
-
- case SP_KOBOLD:
- case SP_TROLL:
- if (!one_chance_in(45))
- this_chunk_effect = CE_CLEAN;
- break;
-
- case SP_HILL_ORC:
- case SP_OGRE:
- if (!one_chance_in(15))
- this_chunk_effect = CE_CLEAN;
- break;
-
- default:
- if (!one_chance_in(3))
- this_chunk_effect = CE_CLEAN;
- break;
- }
- }
- break;
-
- default:
- break;
- }
-
- // determine effects of rotting on base chunk effect {dlb}:
- if (rotten_chunk)
- {
- switch (this_chunk_effect)
- {
- case CE_CLEAN:
- case CE_CONTAMINATED:
- this_chunk_effect = CE_ROTTEN;
- break;
- case CE_MUTAGEN_RANDOM:
- this_chunk_effect = CE_MUTAGEN_BAD;
- break;
- default:
- break;
- }
- }
-
- // one last chance for some species to safely eat rotten food {dlb}:
- if (this_chunk_effect == CE_ROTTEN)
- {
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_LICH)
- this_chunk_effect = CE_CLEAN;
- else
- {
- switch (you.species)
- {
- case SP_KOBOLD:
- case SP_TROLL:
- if (!one_chance_in(15))
- this_chunk_effect = CE_CLEAN;
- break;
- case SP_HILL_ORC:
- case SP_OGRE:
- if (!one_chance_in(5))
- this_chunk_effect = CE_CLEAN;
- break;
- default:
- break;
- }
- }
- }
-
- // the amulet of the gourmad will permit consumption of rotting meat as
- // though it were "clean" meat - ghouls can expect the reverse, as they
- // prize rotten meat ... yum! {dlb}:
- if (wearing_amulet(AMU_THE_GOURMAND))
- {
- if (you.species == SP_GHOUL)
- {
- if (this_chunk_effect == CE_CLEAN)
- this_chunk_effect = CE_ROTTEN;
- }
- else
- {
- if (this_chunk_effect == CE_ROTTEN)
- this_chunk_effect = CE_CLEAN;
- }
- }
-
- return (this_chunk_effect);
-} // end determine_chunk_effect()
diff --git a/stone_soup/crawl-ref/source/food.h b/stone_soup/crawl-ref/source/food.h
deleted file mode 100644
index 1c8e5f5a74..0000000000
--- a/stone_soup/crawl-ref/source/food.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * File: food.cc
- * Summary: Functions for eating and butchering.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef FOOD_H
-#define FOOD_H
-
-
-// last updated 19jun2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-bool butchery(void);
-
-
-// last updated 19jun2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-bool eat_food(bool run_hook = true);
-
-
-// last updated 19jun2000 {dlb}
-/* ***********************************************************************
- * called from: abl-show - acr - fight - food - spell
- * *********************************************************************** */
-void make_hungry(int hunger_amount, bool suppress_msg);
-
-
-// last updated 19jun2000 {dlb}
-/* ***********************************************************************
- * called from: acr - fight - food - it_use2 - item_use
- * *********************************************************************** */
-void lessen_hunger(int statiated_amount, bool suppress_msg);
-
-
-// last updated 19jun2000 {dlb}
-/* ***********************************************************************
- * called from: acr - decks - food - religion
- * *********************************************************************** */
-void set_hunger(int new_hunger_level, bool suppress_msg);
-
-
-// last updated 10sept2000 {bwr}
-/* ***********************************************************************
- * called from: delay.cc
- * *********************************************************************** */
-void weapon_switch( int targ );
-
-bool can_ingest(int what_isit, int kindof_thing, bool suppress_msg,
- bool reqid = false, bool check_hunger = true);
-
-void eat_floor_item(int item_link);
-
-bool eat_from_floor(void);
-
-void eat_from_inventory(int which_inventory_slot);
-
-bool prompt_eat_from_inventory(void);
-
-#endif
diff --git a/stone_soup/crawl-ref/source/hiscores.cc b/stone_soup/crawl-ref/source/hiscores.cc
deleted file mode 100644
index f3aba604d1..0000000000
--- a/stone_soup/crawl-ref/source/hiscores.cc
+++ /dev/null
@@ -1,1846 +0,0 @@
-/*
- * File: highscore.cc
- * Summary: deal with reading and writing of highscore file
- * Written by: Gordon Lipford
- *
- * Change History (most recent first):
- *
- * <1> 16feb2001 gdl Created
- */
-
-/*
- * ----------- MODIFYING THE PRINTED SCORE FORMAT ---------------------
- * Do this at your leisure. Change hiscores_format_single() as much
- * as you like.
- *
- *
- * ----------- IF YOU MODIFY THE INTERNAL SCOREFILE FORMAT ------------
- * .. as defined by the struct 'scorefile_entry' ..
- * You MUST change hs_copy(), hs_parse_numeric(), hs_parse_string(),
- * and hs_write(). It's also a really good idea to change the
- * version numbers assigned in ouch() so that Crawl can tell the
- * difference between your new entry and previous versions.
- *
- *
- *
- */
-
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <ctype.h>
-
-#include "AppHdr.h"
-#include "externs.h"
-
-#include "hiscores.h"
-#include "itemname.h"
-#include "mon-util.h"
-#include "player.h"
-#include "religion.h"
-#include "stuff.h"
-#include "tags.h"
-#include "view.h"
-
-#include "skills2.h"
-
-#ifdef MULTIUSER
- // includes to get passwd file access:
- #include <pwd.h>
- #include <sys/types.h>
-#endif
-
-// enough memory allocated to snarf in the scorefile entries
-static struct scorefile_entry hs_list[SCORE_FILE_ENTRIES];
-
-// hackish: scorefile position of newest entry. Will be highlit during
-// highscore printing (always -1 when run from command line).
-static int newest_entry = -1;
-
-static FILE *hs_open(const char *mode);
-static void hs_close(FILE *handle, const char *mode);
-static bool hs_read(FILE *scores, struct scorefile_entry &dest);
-static void hs_parse_numeric(char *inbuf, struct scorefile_entry &dest);
-static void hs_parse_string(char *inbuf, struct scorefile_entry &dest);
-static void hs_copy(struct scorefile_entry &dest, struct scorefile_entry &src);
-static void hs_write(FILE *scores, struct scorefile_entry &entry);
-static void hs_nextstring(char *&inbuf, char *dest);
-static int hs_nextint(char *&inbuf);
-static long hs_nextlong(char *&inbuf);
-
-// functions dealing with old scorefile entries
-static void hs_parse_generic_1(char *&inbuf, char *outbuf, const char *stopvalues);
-static void hs_parse_generic_2(char *&inbuf, char *outbuf, const char *continuevalues);
-static void hs_stripblanks(char *buf);
-static void hs_search_death(char *inbuf, struct scorefile_entry &se);
-static void hs_search_where(char *inbuf, struct scorefile_entry &se);
-
-// file locking stuff
-#ifdef USE_FILE_LOCKING
-static bool lock_file_handle( FILE *handle, int type );
-static bool unlock_file_handle( FILE *handle );
-#endif // USE_FILE_LOCKING
-
-void hiscores_new_entry( struct scorefile_entry &ne )
-{
- FILE *scores;
- int i, total_entries;
- bool inserted = false;
-
- // open highscore file (reading) -- note that NULL is not fatal!
- scores = hs_open("r");
-
- // read highscore file, inserting new entry at appropriate point,
- for (i = 0; i < SCORE_FILE_ENTRIES; i++)
- {
- if (hs_read(scores, hs_list[i]) == false)
- break;
-
- // compare points..
- if (ne.points >= hs_list[i].points && inserted == false)
- {
- newest_entry = i; // for later printing
- inserted = true;
- // copy read entry to i+1th position
- // Fixed a nasty overflow bug here -- Sharp
- if (i+1 < SCORE_FILE_ENTRIES)
- {
- hs_copy(hs_list[i+1], hs_list[i]);
- hs_copy(hs_list[i], ne);
- i++;
- } else {
- // copy new entry to current position
- hs_copy(hs_list[i], ne);
- }
- }
- }
-
- // special case: lowest score, with room
- if (!inserted && i < SCORE_FILE_ENTRIES)
- {
- newest_entry = i;
- inserted = true;
- // copy new entry
- hs_copy(hs_list[i], ne);
- i++;
- }
-
- total_entries = i;
-
- // close so we can re-open for writing
- hs_close(scores,"r");
-
- // open highscore file (writing) -- NULL *is* fatal here.
- scores = hs_open("w");
- if (scores == NULL)
- {
- perror("Entry not added - failure opening score file for writing.");
- return;
- }
-
- // write scorefile entries.
- for (i = 0; i < total_entries; i++)
- {
- hs_write(scores, hs_list[i]);
- }
-
- // close scorefile.
- hs_close(scores, "w");
-}
-
-void hiscores_print_list( int display_count, int format )
-{
- FILE *scores;
- int i, total_entries;
- bool use_printf = (Options.sc_entries > 0);
-
- if (display_count <= 0)
- display_count = SCORE_FILE_ENTRIES;
-
- // open highscore file (reading)
- scores = hs_open("r");
- if (scores == NULL)
- {
- // will only happen from command line
- puts( "No high scores." );
- return;
- }
-
- // read highscore file
- for (i = 0; i < SCORE_FILE_ENTRIES; i++)
- {
- if (hs_read( scores, hs_list[i] ) == false)
- break;
- }
- total_entries = i;
-
- // close off
- hs_close( scores, "r" );
-
- if (!use_printf)
- textcolor(LIGHTGREY);
-
- int start = (newest_entry > 10) ? newest_entry - 10: 0;
-
- if (start + display_count > total_entries)
- start = total_entries - display_count;
-
- if (start < 0)
- start = 0;
-
- const int finish = start + display_count;
-
- for (i = start; i < finish && i < total_entries; i++)
- {
- // check for recently added entry
- if (i == newest_entry && !use_printf)
- textcolor(YELLOW);
-
- // print position (tracked implicitly by order score file)
- snprintf( info, INFO_SIZE, "%3d.", i + 1 );
- if (use_printf)
- printf(info);
- else
- cprintf(info);
-
- // format the entry
- if (format == SCORE_TERSE)
- {
- hiscores_format_single( info, hs_list[i] );
- // truncate if we want short format
- info[75] = '\0';
- }
- else
- {
- hiscores_format_single_long( info, hs_list[i],
- (format == SCORE_VERBOSE) );
- }
-
- // print entry
- strcat(info, EOL);
- if(use_printf)
- printf(info);
- else
- cprintf(info);
-
- if (i == newest_entry && !use_printf)
- textcolor(LIGHTGREY);
- }
-}
-
-// Trying to supply an appropriate verb for the attack type. -- bwr
-static const char *const range_type_verb( const char *const aux )
-{
- if (strncmp( aux, "Shot ", 5 ) == 0) // launched
- return ("shot");
- else if (aux[0] == '\0' // unknown
- || strncmp( aux, "Hit ", 4 ) == 0 // thrown
- || strncmp( aux, "volley ", 7 ) == 0) // manticore spikes
- {
- return ("hit from afar");
- }
-
- return ("blasted"); // spells, wands
-}
-
-void hiscores_format_single(char *buf, struct scorefile_entry &se)
-{
- char scratch[100];
-
- // Now that we have a long format, I'm starting to make this
- // more terse, in hopes that it will better fit. -- bwr
-
- // race_class_name overrides race & class
- if (se.race_class_name[0] == '\0')
- {
- snprintf( scratch, sizeof(scratch), "%s%s",
- get_species_abbrev( se.race ), get_class_abbrev( se.cls ) );
- }
- else
- {
- strcpy( scratch, se.race_class_name );
- }
-
- se.name[10]='\0';
- sprintf( buf, "%8ld %-10s %s-%02d%s", se.points, se.name,
- scratch, se.lvl, (se.wiz_mode == 1) ? "W" : "" );
-
- // get monster type & number, if applicable
- int mon_type = se.death_source;
- int mon_number = se.mon_num;
-
- // remember -- we have 36 characters (not including initial space):
- switch (se.death_type)
- {
- case KILLED_BY_MONSTER:
- strcat( buf, " slain by " );
-
- // if death_source_name is non-null, override lookup (names might have
- // changed!)
- if (se.death_source_name[0] != '\0')
- strcat( buf, se.death_source_name );
- else
- strcat( buf, monam( mon_number, mon_type, true, DESC_PLAIN ) );
-
- break;
-
- case KILLED_BY_POISON:
- //if (dam == -9999) strcat(buf, "an overload of ");
- strcat( buf, " succumbed to poison" );
- break;
-
- case KILLED_BY_CLOUD:
- if (se.auxkilldata[0] == '\0')
- strcat( buf, " engulfed by a cloud" );
- else
- {
- const int len = strlen( se.auxkilldata );
-
- // Squeeze out "a cloud of" if required. -- bwr
- snprintf( scratch, sizeof(scratch), " engulfed by %s%s",
- (len < 15) ? "a cloud of " : "",
- se.auxkilldata );
-
- strcat( buf, scratch );
- }
- break;
-
- case KILLED_BY_BEAM:
- // keeping this short to leave room for the deep elf spellcasters:
- snprintf( scratch, sizeof(scratch), " %s by ",
- range_type_verb( se.auxkilldata ) );
- strcat( buf, scratch );
-
- // if death_source_name is non-null, override this
- if (se.death_source_name[0] != '\0')
- strcat( buf, se.death_source_name );
- else
- strcat( buf, monam( mon_number, mon_type, true, DESC_PLAIN ) );
- break;
-
-/*
- case KILLED_BY_DEATHS_DOOR:
- // death's door running out - NOTE: This is no longer fatal
- strcat(buf, " ran out of time");
- break;
-*/
-
- case KILLED_BY_CURARE:
- strcat( buf, " asphyxiated");
- break;
-
- case KILLED_BY_LAVA:
- if (se.race == SP_MUMMY)
- strcat( buf, " turned to ash by lava" );
- else
- strcat( buf, " took a swim in lava" );
- break;
-
- case KILLED_BY_WATER:
- if (se.race == SP_MUMMY)
- strcat( buf, " soaked and fell apart" );
- else
- strcat( buf, " drowned" );
- break;
-
- // these three are probably only possible if you wear a ring
- // of >= +3 ability, get drained to 3, then take it off, or have a very
- // low abil and wear a -ve ring. or, as of 2.7x, mutations can cause this
- // Don't forget decks of cards (they have some nasty code for this) -- bwr
- case KILLED_BY_STUPIDITY:
- strcat( buf, " died of stupidity" );
- break;
-
- case KILLED_BY_WEAKNESS:
- strcat( buf, " became too weak to continue" );
- break;
-
- case KILLED_BY_CLUMSINESS:
- strcat( buf, " slipped on a banana peel" );
- break;
-
- case KILLED_BY_TRAP:
- snprintf( scratch, sizeof(scratch), " triggered a%s trap",
- (se.auxkilldata[0] != '\0') ? se.auxkilldata : "" );
- strcat( buf, scratch );
- break;
-
- case KILLED_BY_LEAVING:
- strcat( buf, " got out of the dungeon alive" );
- break;
-
- case KILLED_BY_WINNING:
- strcat( buf, " escaped with the Orb!" );
- break;
-
- case KILLED_BY_QUITTING:
- strcat( buf, " quit the game" );
- break;
-
- case KILLED_BY_DRAINING:
- strcat( buf, " drained of all life" );
- break;
-
- case KILLED_BY_STARVATION:
- strcat( buf, " starved to death" );
- break;
-
- case KILLED_BY_FREEZING:
- strcat( buf, " froze to death" );
- break;
-
- case KILLED_BY_BURNING: // only sticky flame
- strcat( buf, " burnt to a crisp" );
- break;
-
- case KILLED_BY_WILD_MAGIC:
- if (se.auxkilldata[0] == '\0')
- strcat( buf, " killed by wild magic" );
- else
- {
- const bool need_by = (strncmp( se.auxkilldata, "by ", 3 ) == 0);
- const int len = strlen( se.auxkilldata );
-
- // Squeeze out "killed" if we're getting a bit long. -- bwr
- snprintf( scratch, sizeof(scratch), " %s%s%s",
- (len + 3 * (need_by) < 30) ? "killed" : "",
- (need_by) ? "by " : "",
- se.auxkilldata );
-
- strcat( buf, scratch );
- }
- break;
-
- case KILLED_BY_XOM: // only used for old Xom kills
- strcat( buf, " killed for Xom's enjoyment" );
- break;
-
- case KILLED_BY_STATUE:
- strcat( buf, " killed by a statue" );
- break;
-
- case KILLED_BY_ROTTING:
- strcat( buf, " rotted away" );
- break;
-
- case KILLED_BY_TARGETTING:
- strcat( buf, " killed by bad targeting" );
- break;
-
- case KILLED_BY_SPORE:
- strcat( buf, " killed by an exploding spore" );
- break;
-
- case KILLED_BY_TSO_SMITING:
- strcat( buf, " smote by The Shining One" );
- break;
-
- case KILLED_BY_PETRIFICATION:
- strcat( buf, " turned to stone" );
- break;
-
- case KILLED_BY_MELTING:
- strcat( buf, " melted into a puddle" );
- break;
-
- case KILLED_BY_BLEEDING:
- strcat( buf, " bled to death" );
- break;
-
- case KILLED_BY_SOMETHING:
- strcat( buf, " died" );
- break;
-
- case KILLED_BY_FALLING_DOWN_STAIRS:
- strcat( buf, " fell down a flight of stairs" );
- break;
-
- case KILLED_BY_ACID:
- strcat( buf, " splashed by acid" );
- break;
-
- default:
- strcat( buf, " nibbled to death by software bugs" );
- break;
- } // end switch
-
- if (se.death_type != KILLED_BY_LEAVING && se.death_type != KILLED_BY_WINNING)
- {
- if (se.level_type == LEVEL_ABYSS)
- {
- strcat(buf, " (Abyss)");
- return;
- }
- else if (se.level_type == LEVEL_PANDEMONIUM)
- {
- strcat(buf, " (Pan)");
- return;
- }
- else if (se.level_type == LEVEL_LABYRINTH)
- {
- strcat(buf, " (Lab)");
- return;
- }
- else if (se.branch == BRANCH_VESTIBULE_OF_HELL)
- {
- strcat(buf, " (Hell)"); // Gate? Vest?
- return;
- }
- else if (se.branch == BRANCH_HALL_OF_BLADES)
- {
- strcat(buf, " (Blade)");
- return;
- }
- else if (se.branch == BRANCH_ECUMENICAL_TEMPLE)
- {
- strcat(buf, " (Temple)");
- return;
- }
-
- snprintf( scratch, sizeof(scratch), " (%s%d)",
- (se.branch == BRANCH_DIS) ? "Dis " :
- (se.branch == BRANCH_GEHENNA) ? "Geh " :
- (se.branch == BRANCH_COCYTUS) ? "Coc " :
- (se.branch == BRANCH_TARTARUS) ? "Tar " :
- (se.branch == BRANCH_ORCISH_MINES) ? "Orc " :
- (se.branch == BRANCH_HIVE) ? "Hive " :
- (se.branch == BRANCH_LAIR) ? "Lair " :
- (se.branch == BRANCH_SLIME_PITS) ? "Slime " :
- (se.branch == BRANCH_VAULTS) ? "Vault " :
- (se.branch == BRANCH_CRYPT) ? "Crypt " :
- (se.branch == BRANCH_HALL_OF_ZOT) ? "Zot " :
- (se.branch == BRANCH_SNAKE_PIT) ? "Snake " :
- (se.branch == BRANCH_ELVEN_HALLS) ? "Elf " :
- (se.branch == BRANCH_TOMB) ? "Tomb " :
- (se.branch == BRANCH_SWAMP) ? "Swamp " : "DLv ",
- se.dlvl );
-
- strcat( buf, scratch );
- } // endif - killed by winning
-
- return;
-}
-
-static bool hiscore_same_day( time_t t1, time_t t2 )
-{
- struct tm *d1 = localtime( &t1 );
- const int year = d1->tm_year;
- const int mon = d1->tm_mon;
- const int day = d1->tm_mday;
-
- struct tm *d2 = localtime( &t2 );
-
- return (d2->tm_mday == day && d2->tm_mon == mon && d2->tm_year == year);
-}
-
-static void hiscore_date_string( time_t time, char buff[INFO_SIZE] )
-{
- struct tm *date = localtime( &time );
-
- const char *mons[12] = { "Jan", "Feb", "Mar", "Apr", "May", "June",
- "July", "Aug", "Sept", "Oct", "Nov", "Dec" };
-
- snprintf( buff, INFO_SIZE, "%s %d, %d", mons[date->tm_mon],
- date->tm_mday, date->tm_year + 1900 );
-}
-
-static void hiscore_newline( char *buf, int &line_count )
-{
- strncat( buf, EOL " ", HIGHSCORE_SIZE );
- line_count++;
-}
-
-int hiscores_format_single_long( char *buf, struct scorefile_entry &se,
- bool verbose )
-{
- char scratch[INFO_SIZE];
- int line_count = 1;
-
- // race_class_name could/used to override race & class
- // strcpy(scratch, se.race_class_name);
-
- // Please excuse the following bit of mess in the name of flavour ;)
- if (verbose)
- {
- strncpy( scratch, skill_title( se.best_skill, se.best_skill_lvl,
- se.race, se.str, se.dex, se.god ),
- INFO_SIZE );
-
- snprintf( buf, HIGHSCORE_SIZE, "%8ld %s the %s (level %d",
- se.points, se.name, scratch, se.lvl );
-
- }
- else
- {
- snprintf( buf, HIGHSCORE_SIZE, "%8ld %s the %s %s (level %d",
- se.points, se.name, species_name(se.race, se.lvl),
- get_class_name(se.cls), se.lvl );
- }
-
- if (se.final_max_max_hp > 0) // as the other two may be negative
- {
- snprintf( scratch, INFO_SIZE, ", %d/%d", se.final_hp, se.final_max_hp );
- strncat( buf, scratch, HIGHSCORE_SIZE );
-
- if (se.final_max_hp < se.final_max_max_hp)
- {
- snprintf( scratch, INFO_SIZE, " (%d)", se.final_max_max_hp );
- strncat( buf, scratch, HIGHSCORE_SIZE );
- }
-
- strncat( buf, " HPs", HIGHSCORE_SIZE );
- }
-
- strncat( buf, ((se.wiz_mode) ? ") *WIZ*" : ")"), HIGHSCORE_SIZE );
- hiscore_newline( buf, line_count );
-
- if (verbose)
- {
- const char *const race = species_name( se.race, se.lvl );
-
- snprintf( scratch, INFO_SIZE, "Began as a%s %s %s",
- is_vowel(race[0]) ? "n" : "", race, get_class_name(se.cls) );
- strncat( buf, scratch, HIGHSCORE_SIZE );
-
- if (se.birth_time > 0)
- {
- strncat( buf, " on ", HIGHSCORE_SIZE );
- hiscore_date_string( se.birth_time, scratch );
- strncat( buf, scratch, HIGHSCORE_SIZE );
- }
-
- strncat( buf, "." , HIGHSCORE_SIZE );
- hiscore_newline( buf, line_count );
-
- if (se.race != SP_DEMIGOD && se.god != -1)
- {
- if (se.god == GOD_XOM)
- {
- snprintf( scratch, INFO_SIZE, "Was a %sPlaything of Xom.",
- (se.lvl >= 20) ? "Favourite " : "" );
-
- strncat( buf, scratch, HIGHSCORE_SIZE );
- hiscore_newline( buf, line_count );
- }
- else if (se.god != GOD_NO_GOD)
- {
- // Not exactly the same as the religon screen, but
- // good enough to fill this slot for now.
- snprintf( scratch, INFO_SIZE, "Was %s of %s%s",
- (se.piety > 160) ? "the Champion" :
- (se.piety >= 120) ? "a High Priest" :
- (se.piety >= 100) ? "an Elder" :
- (se.piety >= 75) ? "a Priest" :
- (se.piety >= 50) ? "a Believer" :
- (se.piety >= 30) ? "a Follower"
- : "an Initiate",
- god_name( se.god ),
- (se.penance > 0) ? " (penitent)." : "." );
-
- strncat( buf, scratch, HIGHSCORE_SIZE );
- hiscore_newline( buf, line_count );
- }
- }
- }
-
- // get monster type & number, if applicable
- int mon_type = se.death_source;
- int mon_number = se.mon_num;
-
- bool needs_beam_cause_line = false;
- bool needs_called_by_monster_line = false;
- bool needs_damage = false;
-
- switch (se.death_type)
- {
- case KILLED_BY_MONSTER:
- // GDL: here's an example of using final_hp. Verbiage could be better.
- // bwr: changed "blasted" since this is for melee
- snprintf( scratch, INFO_SIZE, "%s %s",
- (se.final_hp > -6) ? "Slain by" :
- (se.final_hp > -14) ? "Mangled by" :
- (se.final_hp > -22) ? "Demolished by"
- : "Annihilated by",
-
- (se.death_source_name[0] != '\0')
- ? se.death_source_name
- : monam( mon_number, mon_type, true, DESC_PLAIN ) );
-
- strncat( buf, scratch, HIGHSCORE_SIZE );
-
- // put the damage on the weapon line if there is one
- if (se.auxkilldata[0] == '\0')
- needs_damage = true;
- break;
-
- case KILLED_BY_POISON:
- //if (dam == -9999) strcat(buf, "an overload of ");
- strcat( buf, "Succumbed to poison" );
- break;
-
- case KILLED_BY_CLOUD:
- if (se.auxkilldata[0] == '\0')
- strcat( buf, "Engulfed by a cloud" );
- else
- {
- snprintf( scratch, sizeof(scratch), "Engulfed by a cloud of %s",
- se.auxkilldata );
- strcat( buf, scratch );
- }
- needs_damage = true;
- break;
-
- case KILLED_BY_BEAM:
- if (isupper( se.auxkilldata[0] )) // already made (ie shot arrows)
- {
- strcat( buf, se.auxkilldata );
- needs_damage = true;
- }
- else if (verbose && strncmp( se.auxkilldata, "by ", 3 ) == 0)
- {
- // "by" is used for priest attacks where the effect is indirect
- // in verbose format we have another line for the monster
- needs_called_by_monster_line = true;
- snprintf( scratch, sizeof(scratch), "Killed %s", se.auxkilldata );
- strncat( buf, scratch, HIGHSCORE_SIZE );
- }
- else
- {
- // Note: This is also used for the "by" cases in non-verbose
- // mode since listing the monster is more imporatant.
- strcat( buf, "Killed from afar by " );
-
- // if death_source_name is non-null, override this
- if (se.death_source_name[0] != '\0')
- strcat(buf, se.death_source_name);
- else
- strcat(buf, monam( mon_number, mon_type, true, DESC_PLAIN ));
-
- if (se.auxkilldata[0] != '\0')
- needs_beam_cause_line = true;
- }
- break;
-
- case KILLED_BY_CURARE:
- strcat(buf, "Asphyxiated");
- break;
-
- case KILLED_BY_LAVA:
- if (se.race == SP_MUMMY)
- strcat( buf, "Turned to ash by lava" );
- else
- strcat( buf, "Took a swim in molten lava" );
- break;
-
- case KILLED_BY_WATER:
- if (se.race == SP_MUMMY)
- strcat( buf, "Soaked and fell apart" );
- else
- strcat( buf, "Drowned" );
- break;
-
- case KILLED_BY_STUPIDITY:
- strcat( buf, "Forgot to breathe" );
- break;
-
- case KILLED_BY_WEAKNESS:
- strcat( buf, "Collapsed under their own weight" );
- break;
-
- case KILLED_BY_CLUMSINESS:
- strcat( buf, "Slipped on a banana peel" );
- break;
-
- case KILLED_BY_TRAP:
- snprintf( scratch, sizeof(scratch), "Killed by triggering a%s trap",
- (se.auxkilldata[0] != '\0') ? se.auxkilldata : "" );
- strcat( buf, scratch );
- needs_damage = true;
- break;
-
- case KILLED_BY_LEAVING:
- if (se.num_runes > 0)
- strcat( buf, "Got out of the dungeon" );
- else
- strcat( buf, "Got out of the dungeon alive!" );
- break;
-
- case KILLED_BY_WINNING:
- strcat( buf, "Escaped with the Orb" );
- if (se.num_runes < 1)
- strcat( buf, "!" );
- break;
-
- case KILLED_BY_QUITTING:
- strcat( buf, "Quit the game" );
- break;
-
- case KILLED_BY_DRAINING:
- strcat( buf, "Was drained of all life" );
- break;
-
- case KILLED_BY_STARVATION:
- strcat( buf, "Starved to death" );
- break;
-
- case KILLED_BY_FREEZING: // refrigeration spell
- strcat( buf, "Froze to death" );
- needs_damage = true;
- break;
-
- case KILLED_BY_BURNING: // sticky flame
- strcat( buf, "Burnt to a crisp" );
- needs_damage = true;
- break;
-
- case KILLED_BY_WILD_MAGIC:
- if (se.auxkilldata[0] == '\0')
- strcat( buf, "Killed by wild magic" );
- else
- {
- // A lot of sources for this case... some have "by" already.
- snprintf( scratch, sizeof(scratch), "Killed %s%s",
- (strncmp( se.auxkilldata, "by ", 3 ) != 0) ? "by " : "",
- se.auxkilldata );
-
- strcat( buf, scratch );
- }
-
- needs_damage = true;
- break;
-
- case KILLED_BY_XOM: // only used for old Xom kills
- strcat( buf, "It was good that Xom killed them" );
- needs_damage = true;
- break;
-
- case KILLED_BY_STATUE:
- strcat( buf, "Killed by a statue" );
- needs_damage = true;
- break;
-
- case KILLED_BY_ROTTING:
- strcat( buf, "Rotted away" );
- break;
-
- case KILLED_BY_TARGETTING:
- strcat( buf, "Killed themselves with bad targeting" );
- needs_damage = true;
- break;
-
- case KILLED_BY_SPORE:
- strcat( buf, "Killed by an exploding spore" );
- needs_damage = true;
- break;
-
- case KILLED_BY_TSO_SMITING:
- strcat( buf, "Smote by The Shining One" );
- needs_damage = true;
- break;
-
- case KILLED_BY_PETRIFICATION:
- strcat( buf, "Turned to stone" );
- break;
-
- case KILLED_BY_MELTING:
- strcat( buf, " melted into a puddle" );
- break;
-
- case KILLED_BY_BLEEDING:
- strcat( buf, " bled to death" );
- break;
-
- case KILLED_BY_SOMETHING:
- strcat( buf, "Died" );
- break;
-
- case KILLED_BY_FALLING_DOWN_STAIRS:
- strcat( buf, "Fell down a flight of stairs" );
- needs_damage = true;
- break;
-
- case KILLED_BY_ACID:
- strcat( buf, "Splashed by acid" );
- needs_damage = true;
- break;
-
- default:
- strcat( buf, "Nibbled to death by software bugs" );
- break;
- } // end switch
-
- // TODO: Eventually, get rid of "..." for cases where the text fits.
- if (verbose)
- {
- bool done_damage = false; // paranoia
-
- if (needs_damage && se.damage > 0)
- {
- snprintf( scratch, INFO_SIZE, " (%d damage)", se.damage );
- strncat( buf, scratch, HIGHSCORE_SIZE );
- needs_damage = false;
- done_damage = true;
- }
-
- if ((se.death_type == KILLED_BY_LEAVING
- || se.death_type == KILLED_BY_WINNING)
- && se.num_runes > 0)
- {
- hiscore_newline( buf, line_count );
-
- snprintf( scratch, INFO_SIZE, "... %s %d rune%s",
- (se.death_type == KILLED_BY_WINNING) ? "and" : "with",
- se.num_runes, (se.num_runes > 1) ? "s" : "" );
- strncat( buf, scratch, HIGHSCORE_SIZE );
-
- if (se.num_diff_runes > 1)
- {
- snprintf( scratch, INFO_SIZE, " (of %d types)",
- se.num_diff_runes );
- strncat( buf, scratch, HIGHSCORE_SIZE );
- }
-
- if (se.death_time > 0
- && !hiscore_same_day( se.birth_time, se.death_time ))
- {
- strcat( buf, " on " );
- hiscore_date_string( se.death_time, scratch );
- strcat( buf, scratch );
- }
-
- strcat( buf, "!" );
- hiscore_newline( buf, line_count );
- }
- else if (se.death_type != KILLED_BY_QUITTING)
- {
- hiscore_newline( buf, line_count );
-
- if (se.death_type == KILLED_BY_MONSTER && se.auxkilldata[0])
- {
- snprintf(scratch, INFO_SIZE, "... wielding %s", se.auxkilldata);
- strncat(buf, scratch, HIGHSCORE_SIZE);
- needs_damage = true;
- }
- else if (needs_beam_cause_line)
- {
- strcat( buf, (is_vowel( se.auxkilldata[0] )) ? "... with an "
- : "... with a " );
- strcat( buf, se.auxkilldata );
- needs_damage = true;
- }
- else if (needs_called_by_monster_line)
- {
- snprintf( scratch, sizeof(scratch), "... called down by %s",
- se.death_source_name );
- strncat( buf, scratch, HIGHSCORE_SIZE );
- needs_damage = true;
- }
-
- if (needs_damage && !done_damage)
- {
- if (se.damage > 0)
- {
- snprintf( scratch, INFO_SIZE, " (%d damage)", se.damage );
- strncat( buf, scratch, HIGHSCORE_SIZE );
- hiscore_newline( buf, line_count );
- }
- }
- }
- }
-
- if (se.death_type == KILLED_BY_LEAVING
- || se.death_type == KILLED_BY_WINNING)
- {
- // TODO: strcat "after reaching level %d"; for LEAVING
- if (!verbose)
- {
- if (se.num_runes > 0)
- strcat( buf, "!" );
-
- hiscore_newline( buf, line_count );
- }
- }
- else
- {
- if (verbose && se.death_type != KILLED_BY_QUITTING)
- strcat( buf, "..." );
-
- if (se.level_type == LEVEL_ABYSS)
- strcat( buf, " in the Abyss" );
- else if (se.level_type == LEVEL_PANDEMONIUM)
- strcat( buf, " in Pandemonium" );
- else if (se.level_type == LEVEL_LABYRINTH)
- strcat( buf, " in a labyrinth" );
- else
- {
- switch (se.branch)
- {
- case BRANCH_ECUMENICAL_TEMPLE:
- strcat( buf, " in the Ecumenical Temple" );
- break;
- case BRANCH_HALL_OF_BLADES:
- strcat( buf, " in the Hall of Blades" );
- break;
- case BRANCH_VESTIBULE_OF_HELL:
- strcat( buf, " in the Vestibule" );
- break;
-
- case BRANCH_DIS:
- strcat( buf, " on Dis" );
- break;
- case BRANCH_GEHENNA:
- strcat( buf, " on Gehenna" );
- break;
- case BRANCH_COCYTUS:
- strcat( buf, " on Cocytus" );
- break;
- case BRANCH_TARTARUS:
- strcat( buf, " on Tartarus" );
- break;
- case BRANCH_ORCISH_MINES:
- strcat( buf, " on Orcish Mines" );
- break;
- case BRANCH_HIVE:
- strcat( buf, " on Hive" );
- break;
- case BRANCH_LAIR:
- strcat( buf, " on Lair" );
- break;
- case BRANCH_SLIME_PITS:
- strcat( buf, " on Slime Pits" );
- break;
- case BRANCH_VAULTS:
- strcat( buf, " on Vault" );
- break;
- case BRANCH_CRYPT:
- strcat( buf, " on Crypt" );
- break;
- case BRANCH_HALL_OF_ZOT:
- strcat( buf, " on Hall of Zot" );
- break;
- case BRANCH_SNAKE_PIT:
- strcat( buf, " on Snake Pit" );
- break;
- case BRANCH_ELVEN_HALLS:
- strcat( buf, " on Elven Halls" );
- break;
- case BRANCH_TOMB:
- strcat( buf, " on Tomb" );
- break;
- case BRANCH_SWAMP:
- strcat( buf, " on Swamp" );
- break;
- case BRANCH_MAIN_DUNGEON:
- strcat( buf, " on Dungeon" );
- break;
- }
-
- if (se.branch != BRANCH_VESTIBULE_OF_HELL
- && se.branch != BRANCH_ECUMENICAL_TEMPLE
- && se.branch != BRANCH_HALL_OF_BLADES)
- {
- snprintf( scratch, sizeof(scratch), " Level %d", se.dlvl );
- strcat( buf, scratch );
- }
- }
-
- if (verbose && se.death_time
- && !hiscore_same_day( se.birth_time, se.death_time ))
- {
- strcat( buf, " on " );
- hiscore_date_string( se.death_time, scratch );
- strcat( buf, scratch );
- }
-
- strcat( buf, "." );
- hiscore_newline( buf, line_count );
- } // endif - killed by winning
-
- if (verbose)
- {
- if (se.real_time > 0)
- {
- char username[80] = "The";
- char tmp[80];
-
-#ifdef MULTIUSER
- if (se.uid > 0)
- {
- struct passwd *pw_entry = getpwuid( se.uid );
- strncpy( username, pw_entry->pw_name, sizeof(username) );
- strncat( username, "'s", sizeof(username) );
- username[0] = toupper( username[0] );
- }
-#endif
-
- make_time_string( se.real_time, tmp, sizeof(tmp) );
-
- snprintf( scratch, INFO_SIZE, "%s game lasted %s (%ld turns).",
- username, tmp, se.num_turns );
-
- strncat( buf, scratch, HIGHSCORE_SIZE );
- hiscore_newline( buf, line_count );
- }
- }
-
- return (line_count);
-}
-
-// --------------------------------------------------------------------------
-// BEGIN private functions
-// --------------------------------------------------------------------------
-
-// first, some file locking stuff for multiuser crawl
-#ifdef USE_FILE_LOCKING
-
-static bool lock_file_handle( FILE *handle, int type )
-{
- struct flock lock;
- int status;
-
- lock.l_whence = SEEK_SET;
- lock.l_start = 0;
- lock.l_len = 0;
- lock.l_type = type;
-
-#ifdef USE_BLOCKING_LOCK
-
- status = fcntl( fileno( handle ), F_SETLKW, &lock );
-
-#else
-
- for (int i = 0; i < 30; i++)
- {
- status = fcntl( fileno( handle ), F_SETLK, &lock );
-
- // success
- if (status == 0)
- break;
-
- // known failure
- if (status == -1 && (errno != EACCES && errno != EAGAIN))
- break;
-
- perror( "Problems locking file... retrying..." );
- delay( 1000 );
- }
-
-#endif
-
- return (status == 0);
-}
-
-static bool unlock_file_handle( FILE *handle )
-{
- struct flock lock;
- int status;
-
- lock.l_whence = SEEK_SET;
- lock.l_start = 0;
- lock.l_len = 0;
- lock.l_type = F_UNLCK;
-
-#ifdef USE_BLOCKING_LOCK
-
- status = fcntl( fileno( handle ), F_SETLKW, &lock );
-
-#else
-
- for (int i = 0; i < 30; i++)
- {
- status = fcntl( fileno( handle ), F_SETLK, &lock );
-
- // success
- if (status == 0)
- break;
-
- // known failure
- if (status == -1 && (errno != EACCES && errno != EAGAIN))
- break;
-
- perror( "Problems unlocking file... retrying..." );
- delay( 1000 );
- }
-
-#endif
-
- return (status == 0);
-}
-
-#endif
-
-
-
-FILE *hs_open( const char *mode )
-{
-#ifdef SAVE_DIR_PATH
- FILE *handle = fopen(SAVE_DIR_PATH "scores", mode);
-#ifdef SHARED_FILES_CHMOD_PUBLIC
- chmod(SAVE_DIR_PATH "scores", SHARED_FILES_CHMOD_PUBLIC);
-#endif
-#else
- FILE *handle = fopen("scores", mode);
-#endif
-
-#ifdef USE_FILE_LOCKING
- int locktype = F_RDLCK;
- if (stricmp(mode, "w") == 0)
- locktype = F_WRLCK;
-
- if (handle && !lock_file_handle( handle, locktype ))
- {
- perror( "Could not lock scorefile... " );
- fclose( handle );
- handle = NULL;
- }
-#endif
- return handle;
-}
-
-void hs_close( FILE *handle, const char *mode )
-{
- UNUSED( mode );
-
- if (handle == NULL)
- return;
-
-#ifdef USE_FILE_LOCKING
- unlock_file_handle( handle );
-#endif
-
- // actually close
- fclose(handle);
-
-#ifdef SHARED_FILES_CHMOD_PUBLIC
- if (stricmp(mode, "w") == 0)
- {
- #ifdef SAVE_DIR_PATH
- chmod(SAVE_DIR_PATH "scores", SHARED_FILES_CHMOD_PUBLIC);
- #else
- chmod("scores", SHARED_FILES_CHMOD_PUBLIC);
- #endif
- }
-#endif
-}
-
-static void hs_init( struct scorefile_entry &dest )
-{
- // simple init
- dest.version = 0;
- dest.release = 0;
- dest.points = -1;
- dest.name[0] = '\0';
- dest.uid = 0;
- dest.race = 0;
- dest.cls = 0;
- dest.lvl = 0;
- dest.race_class_name[0] = '\0';
- dest.best_skill = 0;
- dest.best_skill_lvl = 0;
- dest.death_type = KILLED_BY_SOMETHING;
- dest.death_source = 0;
- dest.mon_num = 0;
- dest.death_source_name[0] = '\0';
- dest.auxkilldata[0] = '\0';
- dest.dlvl = 0;
- dest.level_type = 0;
- dest.branch = 0;
- dest.final_hp = -1;
- dest.final_max_hp = -1;
- dest.final_max_max_hp = -1;
- dest.str = -1;
- dest.intel = -1;
- dest.dex = -1;
- dest.damage = -1;
- dest.god = -1;
- dest.piety = -1;
- dest.penance = -1;
- dest.wiz_mode = 0;
- dest.birth_time = 0;
- dest.death_time = 0;
- dest.real_time = -1;
- dest.num_turns = -1;
- dest.num_diff_runes = 0;
- dest.num_runes = 0;
-}
-
-void hs_copy(struct scorefile_entry &dest, struct scorefile_entry &src)
-{
- // simple field copy -- assume src is well constructed.
-
- dest.version = src.version;
- dest.release = src.release;
- dest.points = src.points;
- strcpy(dest.name, src.name);
- dest.uid = src.uid;
- dest.race = src.race;
- dest.cls = src.cls;
- dest.lvl = src.lvl;
- strcpy(dest.race_class_name, src.race_class_name);
- dest.best_skill = src.best_skill;
- dest.best_skill_lvl = src.best_skill_lvl;
- dest.death_type = src.death_type;
- dest.death_source = src.death_source;
- dest.mon_num = src.mon_num;
- strcpy( dest.death_source_name, src.death_source_name );
- strcpy( dest.auxkilldata, src.auxkilldata );
- dest.dlvl = src.dlvl;
- dest.level_type = src.level_type;
- dest.branch = src.branch;
- dest.final_hp = src.final_hp;
- dest.final_max_hp = src.final_max_hp;
- dest.final_max_max_hp = src.final_max_max_hp;
- dest.str = src.str;
- dest.intel = src.intel;
- dest.dex = src.dex;
- dest.damage = src.damage;
- dest.god = src.god;
- dest.piety = src.piety;
- dest.penance = src.penance;
- dest.wiz_mode = src.wiz_mode;
- dest.birth_time = src.birth_time;
- dest.death_time = src.death_time;
- dest.real_time = src.real_time;
- dest.num_turns = src.num_turns;
- dest.num_diff_runes = src.num_diff_runes;
- dest.num_runes = src.num_runes;
-}
-
-bool hs_read( FILE *scores, struct scorefile_entry &dest )
-{
- char inbuf[200];
- int c = EOF;
-
- hs_init( dest );
-
- // get a character..
- if (scores != NULL)
- c = fgetc(scores);
-
- // check for NULL scores file or EOF
- if (scores == NULL || c == EOF)
- return false;
-
- // get a line - this is tricky. "Lines" come in three flavors:
- // 1) old-style lines which were 80 character blocks
- // 2) 4.0 pr1 through pr7 versions which were newline terminated
- // 3) 4.0 pr8 and onwards which are 'current' ASCII format, and
- // may exceed 80 characters!
-
- // put 'c' in first spot
- inbuf[0] = c;
-
- if (fgets(&inbuf[1], (c==':') ? (sizeof(inbuf) - 2) : 81, scores) == NULL)
- return false;
-
- // check type; lines starting with a colon are new-style scores.
- if (c == ':')
- hs_parse_numeric(inbuf, dest);
- else
- hs_parse_string(inbuf, dest);
-
- return true;
-}
-
-static void hs_nextstring(char *&inbuf, char *dest)
-{
- char *p = dest;
-
- if (*inbuf == '\0')
- {
- *p = '\0';
- return;
- }
-
- // assume we're on a ':'
- inbuf ++;
- while(*inbuf != ':' && *inbuf != '\0')
- *p++ = *inbuf++;
-
- *p = '\0';
-}
-
-static int hs_nextint(char *&inbuf)
-{
- char num[20];
- hs_nextstring(inbuf, num);
-
- return (num[0] == '\0' ? 0 : atoi(num));
-}
-
-static long hs_nextlong(char *&inbuf)
-{
- char num[20];
- hs_nextstring(inbuf, num);
-
- return (num[0] == '\0' ? 0 : atol(num));
-}
-
-static int val_char( char digit )
-{
- return (digit - '0');
-}
-
-static time_t hs_nextdate(char *&inbuf)
-{
- char buff[20];
- struct tm date;
-
- hs_nextstring( inbuf, buff );
-
- if (strlen( buff ) < 15)
- return (static_cast<time_t>(0));
-
- date.tm_year = val_char( buff[0] ) * 1000 + val_char( buff[1] ) * 100
- + val_char( buff[2] ) * 10 + val_char( buff[3] ) - 1900;
-
- date.tm_mon = val_char( buff[4] ) * 10 + val_char( buff[5] );
- date.tm_mday = val_char( buff[6] ) * 10 + val_char( buff[7] );
- date.tm_hour = val_char( buff[8] ) * 10 + val_char( buff[9] );
- date.tm_min = val_char( buff[10] ) * 10 + val_char( buff[11] );
- date.tm_sec = val_char( buff[12] ) * 10 + val_char( buff[13] );
- date.tm_isdst = (buff[14] == 'D');
-
- return (mktime( &date ));
-}
-
-static void hs_parse_numeric(char *inbuf, struct scorefile_entry &se)
-{
- se.version = hs_nextint(inbuf);
- se.release = hs_nextint(inbuf);
-
- // this would be a good point to check for version numbers and branch
- // appropriately
-
- // acceptable versions are 0 (converted from old hiscore format) and 4
- if (se.version != 0 && se.version != 4)
- return;
-
- se.points = hs_nextlong(inbuf);
-
- hs_nextstring(inbuf, se.name);
-
- se.uid = hs_nextlong(inbuf);
- se.race = hs_nextint(inbuf);
- se.cls = hs_nextint(inbuf);
-
- hs_nextstring(inbuf, se.race_class_name);
-
- se.lvl = hs_nextint(inbuf);
- se.best_skill = hs_nextint(inbuf);
- se.best_skill_lvl = hs_nextint(inbuf);
- se.death_type = hs_nextint(inbuf);
- se.death_source = hs_nextint(inbuf);
- se.mon_num = hs_nextint(inbuf);
-
- hs_nextstring(inbuf, se.death_source_name);
-
- // To try and keep the scorefile backwards compatible,
- // we'll branch on version > 4.0 to read the auxkilldata
- // text field.
- if (se.version == 4 && se.release >= 1)
- hs_nextstring( inbuf, se.auxkilldata );
- else
- se.auxkilldata[0] = '\0';
-
- se.dlvl = hs_nextint(inbuf);
- se.level_type = hs_nextint(inbuf);
- se.branch = hs_nextint(inbuf);
-
- // Trying to fix some bugs that have been around since at
- // least pr19, if not longer. From now on, dlvl should
- // be calculated on death and need no further modification.
- if (se.version < 4 || se.release < 2)
- {
- if (se.level_type == LEVEL_DUNGEON)
- {
- if (se.branch == BRANCH_MAIN_DUNGEON)
- se.dlvl += 1;
- else if (se.branch < BRANCH_ORCISH_MINES) // ie the hells
- se.dlvl -= 1;
- }
- }
-
- se.final_hp = hs_nextint(inbuf);
- if (se.version == 4 && se.release >= 2)
- {
- se.final_max_hp = hs_nextint(inbuf);
- se.final_max_max_hp = hs_nextint(inbuf);
- se.damage = hs_nextint(inbuf);
- se.str = hs_nextint(inbuf);
- se.intel = hs_nextint(inbuf);
- se.dex = hs_nextint(inbuf);
- se.god = hs_nextint(inbuf);
- se.piety = hs_nextint(inbuf);
- se.penance = hs_nextint(inbuf);
- }
- else
- {
- se.final_max_hp = -1;
- se.final_max_max_hp = -1;
- se.damage = -1;
- se.str = -1;
- se.intel = -1;
- se.dex = -1;
- se.god = -1;
- se.piety = -1;
- se.penance = -1;
- }
-
- se.wiz_mode = hs_nextint(inbuf);
-
- se.birth_time = hs_nextdate(inbuf);
- se.death_time = hs_nextdate(inbuf);
-
- if (se.version == 4 && se.release >= 2)
- {
- se.real_time = hs_nextint(inbuf);
- se.num_turns = hs_nextint(inbuf);
- }
- else
- {
- se.real_time = -1;
- se.num_turns = -1;
- }
-
- se.num_diff_runes = hs_nextint(inbuf);
- se.num_runes = hs_nextint(inbuf);
-}
-
-static void hs_write( FILE *scores, struct scorefile_entry &se )
-{
- char buff[80]; // should be more than enough for date stamps
-
- se.version = 4;
- se.release = 2;
-
- fprintf( scores, ":%d:%d:%ld:%s:%ld:%d:%d:%s:%d:%d:%d",
- se.version, se.release, se.points, se.name,
- se.uid, se.race, se.cls, se.race_class_name, se.lvl,
- se.best_skill, se.best_skill_lvl );
-
- // XXX: need damage
- fprintf( scores, ":%d:%d:%d:%s:%s:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
- se.death_type, se.death_source, se.mon_num,
- se.death_source_name, se.auxkilldata,
- se.dlvl, se.level_type, se.branch,
- se.final_hp, se.final_max_hp, se.final_max_max_hp, se.damage,
- se.str, se.intel, se.dex,
- se.god, se.piety, se.penance, se.wiz_mode );
-
- make_date_string( se.birth_time, buff );
- fprintf( scores, ":%s", buff );
-
- make_date_string( se.death_time, buff );
- fprintf( scores, ":%s", buff );
-
- fprintf( scores, ":%ld:%ld:%d:%d:\n",
- se.real_time, se.num_turns, se.num_diff_runes, se.num_runes );
-}
-// -------------------------------------------------------------------------
-// functions dealing with old-style scorefile entries.
-// -------------------------------------------------------------------------
-
-static void hs_parse_string(char *inbuf, struct scorefile_entry &se)
-{
- /* old entries are of the following format (Brent introduced some
- spacing at one point, we have to take this into account):
-
- // Actually, I believe it might have been Brian who added the spaces,
- // I was quite happy with the condensed version, given the 80 column
- // restriction. -- bwr
-
-6263 BoBo - DSD10 Wiz, killed by an acid blob on L1 of the Slime Pits.
-5877 Aldus-DGM10, killed by a lethal dose of poison on L10.
-5419 Yarf - Koa10, killed by a warg on L1 of the Mines.
-
- 1. All numerics up to the first non-numeric are the score
- 2. All non '-' characters are the name. Strip spaces.
- 3. All alphabetics up to the first numeric are race/class
- 4. All numerics up to the comma are the clevel
- 5. From the comma, search for known fixed substrings and
- translate to death_type. Leave death source = 0 for old
- scores, and just copy in the monster name.
- 6. Look for the branch type (again, substring search for
- fixed strings) and level.
-
- Very ugly and time consuming.
-
- */
-
- char scratch[80];
-
- // 1. get score
- hs_parse_generic_2(inbuf, scratch, "0123456789");
-
- se.version = 0; // version # of converted score
- se.release = 0;
- se.points = atoi(scratch);
-
- // 2. get name
- hs_parse_generic_1(inbuf, scratch, "-");
- hs_stripblanks(scratch);
- strcpy(se.name, scratch);
-
- // 3. get race, class
- inbuf++; // skip '-'
- hs_parse_generic_1(inbuf, scratch, "0123456789");
- hs_stripblanks(scratch);
- strcpy(se.race_class_name, scratch);
- se.race = 0;
- se.cls = 0;
-
- // 4. get clevel
- hs_parse_generic_2(inbuf, scratch, "0123456789");
- se.lvl = atoi(scratch);
-
- // 4a. get wizard mode
- hs_parse_generic_1(inbuf, scratch, ",");
- if (strstr(scratch, "Wiz") != NULL)
- se.wiz_mode = 1;
- else
- se.wiz_mode = 0;
-
- // 5. get death type
- inbuf++; // skip comma
- hs_search_death(inbuf, se);
-
- // 6. get branch, level
- hs_search_where(inbuf, se);
-
- // set things that can't be picked out of old scorefile entries
- se.uid = 0;
- se.best_skill = 0;
- se.best_skill_lvl = 0;
- se.final_hp = 0;
- se.final_max_hp = -1;
- se.final_max_max_hp = -1;
- se.damage = -1;
- se.str = -1;
- se.intel = -1;
- se.dex = -1;
- se.god = -1;
- se.piety = -1;
- se.penance = -1;
- se.birth_time = 0;
- se.death_time = 0;
- se.real_time = -1;
- se.num_turns = -1;
- se.num_runes = 0;
- se.num_diff_runes = 0;
- se.auxkilldata[0] = '\0';
-}
-
-static void hs_parse_generic_1(char *&inbuf, char *outbuf, const char *stopvalues)
-{
- char *p = outbuf;
-
- while(strchr(stopvalues, *inbuf) == NULL && *inbuf != '\0')
- *p++ = *inbuf++;
-
- *p = '\0';
-}
-
-static void hs_parse_generic_2(char *&inbuf, char *outbuf, const char *continuevalues)
-{
- char *p = outbuf;
-
- while(strchr(continuevalues, *inbuf) != NULL && *inbuf != '\0')
- *p++ = *inbuf++;
-
- *p = '\0';
-}
-
-static void hs_stripblanks(char *buf)
-{
- char *p = buf;
- char *q = buf;
-
- // strip leading
- while(*p == ' ')
- p++;
- while(*p != '\0')
- *q++ = *p++;
-
- *q-- = '\0';
- // strip trailing
- while(*q == ' ')
- {
- *q = '\0';
- q--;
- }
-}
-
-static void hs_search_death(char *inbuf, struct scorefile_entry &se)
-{
- // assume killed by monster
- se.death_type = KILLED_BY_MONSTER;
-
- // sigh..
- if (strstr(inbuf, "killed by a lethal dose of poison") != NULL)
- se.death_type = KILLED_BY_POISON;
- else if (strstr(inbuf, "killed by a cloud") != NULL)
- se.death_type = KILLED_BY_CLOUD;
- else if (strstr(inbuf, "killed from afar by") != NULL)
- se.death_type = KILLED_BY_BEAM;
- else if (strstr(inbuf, "took a swim in molten lava") != NULL)
- se.death_type = KILLED_BY_LAVA;
- else if (strstr(inbuf, "asphyxiated"))
- se.death_type = KILLED_BY_CURARE;
- else if (strstr(inbuf, "soaked and fell apart") != NULL)
- {
- se.death_type = KILLED_BY_WATER;
- se.race = SP_MUMMY;
- }
- else if (strstr(inbuf, "drowned") != NULL)
- se.death_type = KILLED_BY_WATER;
- else if (strstr(inbuf, "died of stupidity") != NULL)
- se.death_type = KILLED_BY_STUPIDITY;
- else if (strstr(inbuf, "too weak to continue adventuring") != NULL)
- se.death_type = KILLED_BY_WEAKNESS;
- else if (strstr(inbuf, "slipped on a banana peel") != NULL)
- se.death_type = KILLED_BY_CLUMSINESS;
- else if (strstr(inbuf, "killed by a trap") != NULL)
- se.death_type = KILLED_BY_TRAP;
- else if (strstr(inbuf, "got out of the dungeon alive") != NULL)
- se.death_type = KILLED_BY_LEAVING;
- else if (strstr(inbuf, "escaped with the Orb") != NULL)
- se.death_type = KILLED_BY_WINNING;
- else if (strstr(inbuf, "quit") != NULL)
- se.death_type = KILLED_BY_QUITTING;
- else if (strstr(inbuf, "was drained of all life") != NULL)
- se.death_type = KILLED_BY_DRAINING;
- else if (strstr(inbuf, "starved to death") != NULL)
- se.death_type = KILLED_BY_STARVATION;
- else if (strstr(inbuf, "froze to death") != NULL)
- se.death_type = KILLED_BY_FREEZING;
- else if (strstr(inbuf, "burnt to a crisp") != NULL)
- se.death_type = KILLED_BY_BURNING;
- else if (strstr(inbuf, "killed by wild magic") != NULL)
- se.death_type = KILLED_BY_WILD_MAGIC;
- else if (strstr(inbuf, "killed by Xom") != NULL)
- se.death_type = KILLED_BY_XOM;
- else if (strstr(inbuf, "killed by a statue") != NULL)
- se.death_type = KILLED_BY_STATUE;
- else if (strstr(inbuf, "rotted away") != NULL)
- se.death_type = KILLED_BY_ROTTING;
- else if (strstr(inbuf, "killed by bad target") != NULL)
- se.death_type = KILLED_BY_TARGETTING;
- else if (strstr(inbuf, "killed by an exploding spore") != NULL)
- se.death_type = KILLED_BY_SPORE;
- else if (strstr(inbuf, "smote by The Shining One") != NULL)
- se.death_type = KILLED_BY_TSO_SMITING;
- else if (strstr(inbuf, "turned to stone") != NULL)
- se.death_type = KILLED_BY_PETRIFICATION;
- else if (strstr(inbuf, "melted into a puddle") != NULL)
- se.death_type = KILLED_BY_MELTING;
- else if (strstr(inbuf, "bled to death") != NULL)
- se.death_type = KILLED_BY_BLEEDING;
-
- // whew!
-
- // now, if we're still KILLED_BY_MONSTER, make sure that there is
- // a "killed by" somewhere, or else we're setting it to UNKNOWN.
- if (se.death_type == KILLED_BY_MONSTER)
- {
- if (strstr(inbuf, "killed by") == NULL)
- se.death_type = KILLED_BY_SOMETHING;
- }
-
- // set some fields
- se.death_source = 0;
- se.mon_num = 0;
- strcpy(se.death_source_name, "");
-
- // now try to pull the monster out.
- if (se.death_type == KILLED_BY_MONSTER || se.death_type == KILLED_BY_BEAM)
- {
- char *p = strstr(inbuf, " by ");
- p += 4;
- char *q = strstr(inbuf, " on ");
- if (q == NULL)
- q = strstr(inbuf, " in ");
- char *d = se.death_source_name;
- while(p != q)
- *d++ = *p++;
-
- *d = '\0';
- }
-}
-
-static void hs_search_where(char *inbuf, struct scorefile_entry &se)
-{
- char scratch[6];
-
- se.level_type = LEVEL_DUNGEON;
- se.branch = BRANCH_MAIN_DUNGEON;
- se.dlvl = 0;
-
- // early out
- if (se.death_type == KILLED_BY_LEAVING || se.death_type == KILLED_BY_WINNING)
- return;
-
- // here we go again.
- if (strstr(inbuf, "in the Abyss") != NULL)
- se.level_type = LEVEL_ABYSS;
- else if (strstr(inbuf, "in Pandemonium") != NULL)
- se.level_type = LEVEL_PANDEMONIUM;
- else if (strstr(inbuf, "in a labyrinth") != NULL)
- se.level_type = LEVEL_LABYRINTH;
-
- // early out for special level types
- if (se.level_type != LEVEL_DUNGEON)
- return;
-
- // check for vestible
- if (strstr(inbuf, "in the Vestibule") != NULL)
- {
- se.branch = BRANCH_VESTIBULE_OF_HELL;
- return;
- }
-
- // from here, we have branch and level.
- char *p = strstr(inbuf, "on L");
- if (p != NULL)
- {
- p += 4;
- hs_parse_generic_2(p, scratch, "0123456789");
- se.dlvl = atoi( scratch );
- }
-
- // get branch.
- if (strstr(inbuf, "of Dis") != NULL)
- se.branch = BRANCH_DIS;
- else if (strstr(inbuf, "of Gehenna") != NULL)
- se.branch = BRANCH_GEHENNA;
- else if (strstr(inbuf, "of Cocytus") != NULL)
- se.branch = BRANCH_COCYTUS;
- else if (strstr(inbuf, "of Tartarus") != NULL)
- se.branch = BRANCH_TARTARUS;
- else if (strstr(inbuf, "of the Mines") != NULL)
- se.branch = BRANCH_ORCISH_MINES;
- else if (strstr(inbuf, "of the Hive") != NULL)
- se.branch = BRANCH_HIVE;
- else if (strstr(inbuf, "of the Lair") != NULL)
- se.branch = BRANCH_LAIR;
- else if (strstr(inbuf, "of the Slime Pits") != NULL)
- se.branch = BRANCH_SLIME_PITS;
- else if (strstr(inbuf, "of the Vaults") != NULL)
- se.branch = BRANCH_VAULTS;
- else if (strstr(inbuf, "of the Crypt") != NULL)
- se.branch = BRANCH_CRYPT;
- else if (strstr(inbuf, "of the Hall") != NULL)
- se.branch = BRANCH_HALL_OF_BLADES;
- else if (strstr(inbuf, "of Zot's Hall") != NULL)
- se.branch = BRANCH_HALL_OF_ZOT;
- else if (strstr(inbuf, "of the Temple") != NULL)
- se.branch = BRANCH_ECUMENICAL_TEMPLE;
- else if (strstr(inbuf, "of the Snake Pit") != NULL)
- se.branch = BRANCH_SNAKE_PIT;
- else if (strstr(inbuf, "of the Elf Hall") != NULL)
- se.branch = BRANCH_ELVEN_HALLS;
- else if (strstr(inbuf, "of the Tomb") != NULL)
- se.branch = BRANCH_TOMB;
- else if (strstr(inbuf, "of the Swamp") != NULL)
- se.branch = BRANCH_SWAMP;
-}
diff --git a/stone_soup/crawl-ref/source/hiscores.h b/stone_soup/crawl-ref/source/hiscores.h
deleted file mode 100644
index 2cb5f4786f..0000000000
--- a/stone_soup/crawl-ref/source/hiscores.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * File: hiscores.h
- * Summary: Scorefile manipulation functions
- * Written by: Gordon Lipford
- *
- * Change History (most recent first):
- *
- * <1> 16feb2001 GDL Created
- */
-
-
-#ifndef HISCORES_H
-#define HISCORES_H
-
-// last updated 16feb2001 {gdl}
-/* ***********************************************************************
- * called from: ouch
- * *********************************************************************** */
-void hiscores_new_entry( struct scorefile_entry &se );
-
-// last updated 16feb2001 {gdl}
-/* ***********************************************************************
- * called from: acr ouch
- * *********************************************************************** */
-void hiscores_print_list( int display_count = -1, int format = SCORE_TERSE );
-
-// last updated 16feb2001 {gdl}
-/* ***********************************************************************
- * called from: ouch hiscores
- * *********************************************************************** */
-void hiscores_format_single( char *buffer, struct scorefile_entry &se );
-int hiscores_format_single_long( char *buffer, struct scorefile_entry &se,
- bool verbose = false );
-
-#endif // HISCORES_H
diff --git a/stone_soup/crawl-ref/source/initfile.cc b/stone_soup/crawl-ref/source/initfile.cc
deleted file mode 100644
index f4e4a7331b..0000000000
--- a/stone_soup/crawl-ref/source/initfile.cc
+++ /dev/null
@@ -1,1790 +0,0 @@
-/*
- * File: initfile.cc
- * Summary: Simple reading of an init file and system variables
- * Written by: David Loewenstern
- *
- * Modified for Crawl Reference by $Author$ on $Date$
- *
- * Change History (most recent first):
- *
- * <3> 5 May 2000 GDL Add field stripping for 'name'
- * <2> 6/12/99 BWR Added get_system_environment
- * <1> 6/9/99 DML Created
- */
-
-#include "AppHdr.h"
-#include "initfile.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string>
-#include <ctype.h>
-
-#include "clua.h"
-#include "Kills.h"
-#include "files.h"
-#include "externs.h"
-#include "defines.h"
-#include "libutil.h"
-#include "player.h"
-#include "stash.h"
-#include "stuff.h"
-#include "travel.h"
-#include "items.h"
-#include "view.h"
-
-game_options Options;
-
-extern void (*viewwindow) (char, bool);
-extern unsigned char (*mapch) (unsigned char);
-extern unsigned char (*mapch2) (unsigned char);
-extern unsigned char mapchar3(unsigned char ldfk);
-extern unsigned char mapchar4(unsigned char ldfk);
-
-#ifdef UNIX
-extern int character_set; // unices only
-#endif
-
-static std::string & tolower_string( std::string &str );
-
-const static char *obj_syms = ")([/%.?=!.+\\0}X$";
-const static int obj_syms_len = 16;
-
-static void read_startup_prefs();
-static void read_options(InitLineInput &il, bool runscript);
-
-template<class A, class B> void append_vector(
- std::vector<A> &dest, const std::vector<B> &src)
-{
- dest.insert( dest.end(), src.begin(), src.end() );
-}
-
-// returns -1 if unmatched else returns 0-15
-static short str_to_colour( const std::string &str )
-{
- int ret;
-
- const std::string cols[16] =
- {
- "black", "blue", "green", "cyan", "red", "magenta", "brown",
- "lightgrey", "darkgrey", "lightblue", "lightgreen", "lightcyan",
- "lightred", "lightmagenta", "yellow", "white"
- };
-
- for (ret = 0; ret < 16; ret++)
- {
- if (str == cols[ret])
- break;
- }
-
- // check for alternate spellings
- if (ret == 16)
- {
- if (str == "lightgray")
- ret = 7;
- else if (str == "darkgray")
- ret = 8;
- }
-
- if (ret == 16)
- {
- // Check if we have a direct colour index
- const char *s = str.c_str();
- char *es = NULL;
- int ci = (int) strtol(s, &es, 10);
- if (s != (const char *) es && es && ci >= 0 && ci < 16)
- ret = ci;
- }
-
- return ((ret == 16) ? -1 : ret);
-}
-
-// returns -1 if unmatched else returns 0-15
-static int str_to_channel_colour( const std::string &str )
-{
- int ret = str_to_colour( str );
-
- if (ret == -1)
- {
- if (str == "mute")
- ret = MSGCOL_MUTED;
- else if (str == "plain" || str == "off")
- ret = MSGCOL_PLAIN;
- else if (str == "default" || str == "on")
- ret = MSGCOL_DEFAULT;
- else if (str == "alternate")
- ret = MSGCOL_ALTERNATE;
- }
-
- return (ret);
-}
-
-static const std::string message_channel_names[ NUM_MESSAGE_CHANNELS ] =
-{
- "plain", "prompt", "god", "duration", "danger", "warning", "food",
- "recovery", "sound", "talk", "intrinsic_gain", "mutation", "monster_spell",
- "monster_enchant", "monster_damage", "rotten_meat", "equipment",
- "diagnostic",
-};
-
-// returns -1 if unmatched else returns 0-15
-int str_to_channel( const std::string &str )
-{
- short ret;
-
- for (ret = 0; ret < NUM_MESSAGE_CHANNELS; ret++)
- {
- if (str == message_channel_names[ret])
- break;
- }
-
- return (ret == NUM_MESSAGE_CHANNELS ? -1 : ret);
-}
-
-std::string channel_to_str( int channel )
-{
- if (channel < 0 || channel >= NUM_MESSAGE_CHANNELS)
- return "";
-
- return message_channel_names[channel];
-}
-
-static int str_to_weapon( const std::string &str )
-{
- if (str == "shortsword" || str == "short sword")
- return (WPN_SHORT_SWORD);
- else if (str == "mace")
- return (WPN_MACE);
- else if (str == "spear")
- return (WPN_SPEAR);
- else if (str == "trident")
- return (WPN_TRIDENT);
- else if (str == "hand axe" || str == "handaxe")
- return (WPN_HAND_AXE);
- else if (str == "random")
- return (WPN_RANDOM);
-
- return (WPN_UNKNOWN);
-}
-
-static std::string weapon_to_str( int weapon )
-{
- switch (weapon)
- {
- case WPN_SHORT_SWORD:
- return "short sword";
- case WPN_MACE:
- return "mace";
- case WPN_SPEAR:
- return "spear";
- case WPN_TRIDENT:
- return "trident";
- case WPN_HAND_AXE:
- return "hand axe";
- case WPN_RANDOM:
- return "random";
- default:
- return "random";
- }
-}
-
-static unsigned int str_to_fire_types( const std::string &str )
-{
- if (str == "launcher")
- return (FIRE_LAUNCHER);
- else if (str == "dart")
- return (FIRE_DART);
- else if (str == "stone")
- return (FIRE_STONE);
- else if (str == "dagger")
- return (FIRE_DAGGER);
- else if (str == "spear")
- return (FIRE_SPEAR);
- else if (str == "hand axe" || str == "handaxe")
- return (FIRE_HAND_AXE);
- else if (str == "club")
- return (FIRE_CLUB);
-
- return (FIRE_NONE);
-}
-
-static void str_to_fire_order( const std::string &str,
- FixedVector< int, NUM_FIRE_TYPES > &list )
-{
- int i;
- size_t pos = 0;
- std::string item = "";
-
- for (i = 0; i < NUM_FIRE_TYPES; i++)
- {
- // get next item from comma delimited list
- const size_t end = str.find( ',', pos );
- item = str.substr( pos, end - pos );
- trim_string( item );
-
- list[i] = str_to_fire_types( item );
-
- if (end == std::string::npos)
- break;
- else
- pos = end + 1;
- }
-}
-
-static char str_to_race( const std::string &str )
-{
- int index = -1;
-
- if (str.length() == 1) // old system of using menu letter
- return (str[0]);
- else if (str.length() == 2) // scan abbreviations
- index = get_species_index_by_abbrev( str.c_str() );
-
- // if we don't have a match, scan the full names
- if (index == -1)
- index = get_species_index_by_name( str.c_str() );
-
- // skip over the extra draconians here
- if (index > SP_RED_DRACONIAN)
- index -= (SP_CENTAUR - SP_RED_DRACONIAN - 1);
-
- // SP_HUMAN is at 1, therefore we must subtract one.
- return ((index != -1) ? index_to_letter( index - 1 ) : '\0');
-}
-
-static char str_to_class( const std::string &str )
-{
- int index = -1;
-
- if (str.length() == 1) // old system of using menu letter
- return (str[0]);
- else if (str.length() == 2) // scan abbreviations
- index = get_class_index_by_abbrev( str.c_str() );
-
- // if we don't have a match, scan the full names
- if (index == -1)
- index = get_class_index_by_name( str.c_str() );
-
- return ((index != -1) ? index_to_letter( index ) : '\0');
-}
-
-static std::string & tolower_string( std::string &str )
-{
- if (str.length())
- {
- for (std::string::iterator cp = str.begin(); cp != str.end(); cp++)
- {
- *cp = tolower( *cp );
- }
- }
-
- return (str);
-}
-
-static bool read_bool( const std::string &field, bool def_value )
-{
- bool ret = def_value;
-
- if (field == "true" || field == "1")
- ret = true;
-
- if (field == "false" || field == "0")
- ret = false;
-
- return (ret);
-}
-
-static unsigned curses_attribute(const std::string &field)
-{
- if (field == "standout") // probably reverses
- return CHATTR_STANDOUT;
- else if (field == "bold") // probably brightens fg
- return CHATTR_BOLD;
- else if (field == "blink") // probably brightens bg
- return CHATTR_BLINK;
- else if (field == "underline")
- return CHATTR_UNDERLINE;
- else if (field == "reverse")
- return CHATTR_REVERSE;
- else if (field == "dim")
- return CHATTR_DIM;
- else if (field.find("hi:") == 0 || field.find("hilite:") == 0 ||
- field.find("highlight:") == 0)
- {
- int col = field.find(":");
- int colour = str_to_colour(field.substr(col + 1));
- if (colour == -1)
- fprintf(stderr, "Bad highlight string -- %s\n", field.c_str());
- else
- return CHATTR_HILITE | (colour << 8);
- }
- else
- fprintf( stderr, "Bad colour -- %s\n", field.c_str() );
- return CHATTR_NORMAL;
-}
-
-
-static void reset_startup_options(bool clear_name = true)
-{
- if (clear_name)
- you.your_name[0] = '\0';
- Options.race = '\0';
- Options.cls = '\0';
- Options.weapon = WPN_UNKNOWN;
- Options.random_pick = false;
- Options.chaos_knight = GOD_NO_GOD;
- Options.death_knight = DK_NO_SELECTION;
- Options.priest = GOD_NO_GOD;
-}
-
-void reset_options(bool clear_name)
-{
- // Option initialization
- Options.activity_interrupts[ ACT_MULTIDROP ] =
- AI_HP_LOSS | AI_STAT_CHANGE | AI_TELEPORT;
- Options.activity_interrupts[ ACT_RUNNING ] =
- 0xFFFF ^ AI_SEE_MONSTER;
- Options.activity_interrupts[ ACT_TRAVELING ] =
- 0xFFFF ^ (AI_MESSAGE | AI_SEE_MONSTER);
-
- reset_startup_options(clear_name);
- Options.prev_race = 0;
- Options.prev_cls = 0;
- Options.prev_ck = GOD_NO_GOD;
- Options.prev_dk = DK_NO_SELECTION;
- Options.prev_pr = GOD_NO_GOD;
- Options.prev_weapon = WPN_UNKNOWN;
- Options.prev_randpick = false;
- Options.remember_name = false;
-
-#ifdef USE_ASCII_CHARACTERS
- Options.ascii_display = true;
-#else
- Options.ascii_display = false;
-#endif
-
- Options.autopickups = 0x0000;
- Options.verbose_dump = false;
- Options.detailed_stat_dump = true;
- Options.colour_map = false;
- Options.clean_map = false;
- Options.show_uncursed = true;
- Options.always_greet = false;
- Options.easy_open = true;
- Options.easy_armour = true;
- Options.easy_butcher = false;
- Options.easy_confirm = CONFIRM_SAFE_EASY;
- Options.easy_quit_item_prompts = false;
- Options.hp_warning = 10;
- Options.hp_attention = 25;
- Options.terse_hand = true;
- Options.auto_list = false;
- Options.delay_message_clear = false;
- Options.pickup_dropped = true;
- Options.travel_colour = true;
- Options.travel_delay = -1;
- Options.travel_stair_cost = 500;
- Options.travel_exclude_radius2 = 68;
- Options.show_waypoints = true;
- Options.item_colour = false;
-
- Options.detected_item_colour = DARKGREY;
- Options.detected_monster_colour= DARKGREY;
- Options.remembered_monster_colour = 0;
-
- Options.easy_exit_menu = true;
- Options.dos_use_background_intensity = false;
- Options.assign_item_slot = SS_FORWARD;
-
- Options.macro_meta_entry = true;
-
- // 10 was the cursor step default on Linux.
- Options.level_map_cursor_step = 10;
-
-#ifdef STASH_TRACKING
- Options.stash_tracking = STM_NONE;
-#endif
- Options.explore_stop = ES_ITEM | ES_STAIR | ES_SHOP | ES_ALTAR;
- Options.target_zero_exp = true;
- Options.target_wrap = false;
- Options.target_oos = true;
- Options.target_los_first = true;
- Options.dump_kill_places = KDO_ONE_PLACE;
- Options.dump_message_count = 4;
- Options.dump_item_origins = IODS_ARTIFACTS | IODS_RODS;
- Options.dump_item_origin_price = -1;
-
- Options.drop_mode = DM_SINGLE;
-
- Options.flush_input[ FLUSH_ON_FAILURE ] = true;
- Options.flush_input[ FLUSH_BEFORE_COMMAND ] = false;
- Options.flush_input[ FLUSH_ON_MESSAGE ] = false;
- Options.flush_input[ FLUSH_LUA ] = true;
-
- Options.lowercase_invocations = false;
-
- // Note: These fire options currently match the old behaviour. -- bwr
- Options.fire_items_start = 0; // start at slot 'a'
-
- Options.fire_order[0] = FIRE_LAUNCHER; // fire first from bow...
- Options.fire_order[1] = FIRE_DART; // then only consider darts
-
- // clear the rest of the list
- for (int i = 2; i < NUM_FIRE_TYPES; i++)
- Options.fire_order[i] = FIRE_NONE;
-
- Options.fsim_rounds = 40000L;
- Options.fsim_mons = "worm";
- Options.fsim_str = Options.fsim_int = Options.fsim_dex = 15;
- Options.fsim_xl = 10;
- Options.fsim_kit.clear();
-
- // These are only used internally, and only from the commandline:
- // XXX: These need a better place.
- Options.sc_entries = 0;
- Options.sc_format = SCORE_REGULAR;
-
-//#ifdef USE_COLOUR_OPTS
- Options.friend_brand = CHATTR_NORMAL;
- Options.heap_brand = CHATTR_NORMAL;
- Options.stab_brand = CHATTR_NORMAL;
- Options.may_stab_brand = CHATTR_NORMAL;
- Options.no_dark_brand = 0;
-//#endif
-
-#ifdef WIZARD
- Options.wiz_mode = WIZ_NO;
-#endif
-
- // map each colour to itself as default
-#ifdef USE_8_COLOUR_TERM_MAP
- for (int i = 0; i < 16; i++)
- Options.colour[i] = i % 8;
-
- Options.colour[ DARKGREY ] = COL_TO_REPLACE_DARKGREY;
-#else
- for (int i = 0; i < 16; i++)
- Options.colour[i] = i;
-#endif
-
- // map each channel to plain (well, default for now since I'm testing)
- for (int i = 0; i < NUM_MESSAGE_CHANNELS; i++)
- Options.channels[i] = MSGCOL_DEFAULT;
-
- // Clear vector options.
- Options.banned_objects.clear();
- Options.stop_travel.clear();
- Options.sound_mappings.clear();
- Options.menu_colour_mappings.clear();
- Options.drop_filter.clear();
-
- Options.named_options.clear();
-
- // Map each category to itself. The user can override in init.txt
- Options.kill_map[KC_YOU] = KC_YOU;
- Options.kill_map[KC_FRIENDLY] = KC_FRIENDLY;
- Options.kill_map[KC_OTHER] = KC_OTHER;
-
- // Setup travel information. What's a better place to do this?
- initialise_travel();
-}
-
-void read_init_file(bool runscript)
-{
- FILE *f;
- char name_buff[kPathLen];
-
- reset_options(!runscript);
-
- if (!runscript)
- you.your_name[0] = '\0';
-
- if (SysEnv.crawl_rc)
- {
- f = fopen(SysEnv.crawl_rc, "r");
- }
- else if (SysEnv.crawl_dir)
- {
- strncpy(name_buff, SysEnv.crawl_dir, kPathLen);
- name_buff[ kPathLen - 1 ] = '\0';
- strncat(name_buff, "init.txt", kPathLen);
- name_buff[ kPathLen - 1 ] = '\0';
-
- f = fopen(name_buff, "r");
- }
-#ifdef MULTIUSER
- else if (SysEnv.home)
- {
- // init.txt isn't such a good choice if we're looking in
- // the user's home directory, we'll use Un*x standard
- strncpy(name_buff, SysEnv.home, kPathLen);
- name_buff[ kPathLen - 1 ] = '\0';
-
- // likely not to have a closing slash so we'll insert one...
- strncat(name_buff, "/.crawlrc", kPathLen);
- name_buff[ kPathLen - 1 ] = '\0';
-
- f = fopen(name_buff, "r");
- }
-#endif
- else
- {
- f = fopen("init.txt", "r");
- }
-
- if (f == NULL)
- return;
-
- if (!runscript)
- read_startup_prefs();
-
- read_options(f, runscript);
- fclose(f);
-} // end read_init_file()
-
-static void read_startup_prefs()
-{
- std::string fn = get_prefs_filename();
- FILE *f = fopen(fn.c_str(), "r");
- if (!f)
- return;
- read_options(f);
- fclose(f);
-
- Options.prev_randpick = Options.random_pick;
- Options.prev_weapon = Options.weapon;
- Options.prev_pr = Options.priest;
- Options.prev_dk = Options.death_knight;
- Options.prev_ck = Options.chaos_knight;
- Options.prev_cls = Options.cls;
- Options.prev_race = Options.race;
- Options.prev_name = you.your_name;
-
- reset_startup_options();
-}
-
-static void write_newgame_options(FILE *f)
-{
- // Write current player name
- fprintf(f, "name = %s\n", you.your_name);
-
- if (Options.prev_randpick)
- Options.prev_race = Options.prev_cls = '?';
-
- // Race selection
- if (Options.prev_race)
- fprintf(f, "race = %c\n", Options.prev_race);
- if (Options.prev_cls)
- fprintf(f, "class = %c\n", Options.prev_cls);
-
- if (Options.prev_weapon != WPN_UNKNOWN)
- fprintf(f, "weapon = %s\n", weapon_to_str(Options.prev_weapon).c_str());
-
- 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");
- }
- 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");
- }
- if (Options.prev_pr != GOD_NO_GOD)
- {
- fprintf(f, "priest = %s\n",
- Options.prev_pr == GOD_ZIN? "zin" :
- Options.prev_pr == GOD_YREDELEMNUL? "yredelemnul" :
- "random");
- }
-}
-
-void write_newgame_options_file()
-{
- std::string fn = get_prefs_filename();
- FILE *f = fopen(fn.c_str(), "w");
- if (!f)
- return;
- write_newgame_options(f);
- fclose(f);
-}
-
-void save_player_name()
-{
- if (!Options.remember_name)
- return ;
-
- std::string playername = you.your_name;
-
- // Read other preferences
- read_startup_prefs();
-
- // Put back your name
- strncpy(you.your_name, playername.c_str(), kNameLen);
- you.your_name[kNameLen - 1] = 0;
-
- // And save
- write_newgame_options_file();
-}
-
-void read_options(FILE *f, bool runscript)
-{
- FileLineInput fl(f);
- read_options(fl, runscript);
-}
-
-void read_options(const std::string &s, bool runscript)
-{
- StringLineInput st(s);
- read_options(st, runscript);
-}
-
-extern void (*viewwindow) (char, bool);
-/* these are all defined in view.cc: */
-extern unsigned char (*mapch) (unsigned char);
-extern unsigned char (*mapch2) (unsigned char);
-unsigned char mapchar(unsigned char ldfk);
-unsigned char mapchar2(unsigned char ldfk);
-unsigned char mapchar3(unsigned char ldfk);
-unsigned char mapchar4(unsigned char ldfk);
-void apply_ascii_display(bool ascii)
-{
- if (ascii)
- {
- // Default to the non-ibm set when it makes sense.
- viewwindow = &viewwindow3;
- mapch = &mapchar3;
- mapch2 = &mapchar4;
- }
- else
- {
- // Use the standard ibm default
- viewwindow = &viewwindow2;
- mapch = &mapchar;
- mapch2 = &mapchar2;
- }
-}
-
-static void read_options(InitLineInput &il, bool runscript)
-{
- unsigned int line = 0;
-
- bool inscriptblock = false;
- bool inscriptcond = false;
- bool isconditional = false;
-
- bool l_init = false;
-
- std::string luacond;
- std::string luacode;
- while (!il.eof())
- {
- std::string s = il.getline();
- std::string str = s;
- line++;
-
- trim_string( str );
-
- // This is to make some efficient comments
- if ((str.empty() || str[0] == '#') && !inscriptcond && !inscriptblock)
- continue;
-
- if (!inscriptcond && (str.find("L<") == 0 || str.find("<") == 0))
- {
- // The init file is now forced into isconditional mode.
- isconditional = true;
- inscriptcond = true;
-
- str = str.substr( str.find("L<") == 0? 2 : 1 );
- // Is this a one-liner?
- if (!str.empty() && str[ str.length() - 1 ] == '>') {
- inscriptcond = false;
- str = str.substr(0, str.length() - 1);
- }
-
- if (!str.empty() && runscript)
- {
- // If we're in the middle of an option block, close it.
- if (luacond.length() && l_init)
- {
- luacond += "]] )\n";
- l_init = false;
- }
- luacond += str + "\n";
- }
- continue;
- }
- else if (inscriptcond &&
- (str.find(">") == str.length() - 1 || str == ">L"))
- {
- inscriptcond = false;
- str = str.substr(0, str.length() - 1);
- if (!str.empty() && runscript)
- luacond += str + "\n";
- continue;
- }
- else if (inscriptcond)
- {
- if (runscript)
- luacond += s + "\n";
- continue;
- }
-
- // Handle blocks of Lua
- if (!inscriptblock && (str.find("Lua{") == 0 || str.find("{") == 0))
- {
- inscriptblock = true;
- luacode.clear();
-
- // Strip leading Lua[
- str = str.substr( str.find("Lua{") == 0? 4 : 1 );
-
- if (!str.empty() && str.find("}") == str.length() - 1)
- {
- str = str.substr(0, str.length() - 1);
- inscriptblock = false;
- }
-
- if (!str.empty())
- luacode += str + "\n";
-
- if (!inscriptblock && runscript)
- {
-#ifdef CLUA_BINDINGS
- clua.execstring(luacode.c_str());
- if (clua.error.length())
- fprintf(stderr, "Lua error: %s\n", clua.error.c_str());
- luacode.clear();
-#endif
- }
-
- continue;
- }
- else if (inscriptblock && (str == "}Lua" || str == "}"))
- {
- inscriptblock = false;
-#ifdef CLUA_BINDINGS
- if (runscript)
- {
- clua.execstring(luacode.c_str());
- if (clua.error.length())
- fprintf(stderr, "Lua error: %s\n",
- clua.error.c_str());
- }
-#endif
- luacode.clear();
- continue;
- }
- else if (inscriptblock)
- {
- luacode += s + "\n";
- continue;
- }
-
- if (isconditional && runscript)
- {
- if (!l_init)
- {
- luacond += "crawl.setopt( [[\n";
- l_init = true;
- }
-
- luacond += s + "\n";
- continue;
- }
-
- parse_option_line(str, runscript);
- }
-
-#ifdef CLUA_BINDINGS
- if (runscript && !luacond.empty())
- {
- if (l_init)
- luacond += "]] )\n";
- clua.execstring(luacond.c_str());
- if (clua.error.length())
- {
- mpr( ("Lua error: " + clua.error).c_str() );
- }
- }
-#endif
-
- apply_ascii_display(Options.ascii_display);
-}
-
-static int str_to_killcategory(const std::string &s)
-{
- static const char *kc[] = {
- "you",
- "friend",
- "other",
- };
-
- for (unsigned i = 0; i < sizeof(kc) / sizeof(*kc); ++i) {
- if (s == kc[i])
- return i;
- }
- return -1;
-}
-
-static void do_kill_map(const std::string &from, const std::string &to)
-{
- int ifrom = str_to_killcategory(from),
- ito = str_to_killcategory(to);
- if (ifrom != -1 && ito != -1)
- Options.kill_map[ifrom] = ito;
-}
-
-void parse_option_line(const std::string &str, bool runscript)
-{
- std::string key = "";
- std::string subkey = "";
- std::string field = "";
-
- int first_equals = str.find('=');
- int first_dot = str.find('.');
-
- // all lines with no equal-signs we ignore
- if (first_equals < 0)
- return;
-
- if (first_dot > 0 && first_dot < first_equals)
- {
- key = str.substr( 0, first_dot );
- subkey = str.substr( first_dot + 1, first_equals - first_dot - 1 );
- field = str.substr( first_equals + 1 );
- }
- else
- {
- // no subkey (dots are okay in value field)
- key = str.substr( 0, first_equals );
- subkey = "";
- field = str.substr( first_equals + 1 );
- }
-
- // Clean up our data...
- tolower_string( trim_string( key ) );
- tolower_string( trim_string( subkey ) );
-
- // some fields want capitals... none care about external spaces
- trim_string( field );
-
- // Keep unlowercased field around
- std::string orig_field = field;
-
- if (key != "name" && key != "crawl_dir"
- && key != "race" && key != "class" && key != "ban_pickup"
- && key != "stop_travel" && key != "sound"
- && key != "drop_filter" && key != "lua_file")
- {
- tolower_string( field );
- }
-
- // everything not a valid line is treated as a comment
- if (key == "autopickup")
- {
- for (size_t i = 0; i < field.length(); i++)
- {
- char type = field[i];
-
- // Make the amulet symbol equiv to ring -- bwross
- switch (type)
- {
- case '"':
- // also represents jewellery
- type = '=';
- break;
-
- case '|':
- // also represents staves
- type = '\\';
- break;
-
- case ':':
- // also represents books
- type = '+';
- break;
-
- case 'x':
- // also corpses
- type = 'X';
- break;
- }
-
- int j;
- for (j = 0; j < obj_syms_len && type != obj_syms[j]; j++)
- ;
-
- if (j < obj_syms_len)
- Options.autopickups |= (1L << j);
- else
- {
- fprintf( stderr, "Bad object type '%c' for autopickup.\n",
- type );
- }
- }
- }
- else if (key == "name")
- {
- // field is already cleaned up from trim_string()
- strncpy(you.your_name, field.c_str(), kNameLen);
- you.your_name[ kNameLen - 1 ] = '\0';
- }
- else if (key == "verbose_dump")
- {
- // gives verbose info in char dumps
- Options.verbose_dump = read_bool( field, Options.verbose_dump );
- }
- else if (key == "ascii_display")
- {
- Options.ascii_display = read_bool( field, Options.ascii_display );
- }
- else if (key == "detailed_stat_dump")
- {
- Options.detailed_stat_dump =
- read_bool( field, Options.detailed_stat_dump );
- }
- else if (key == "clean_map")
- {
- // removes monsters/clouds from map
- Options.clean_map = read_bool( field, Options.clean_map );
- }
- else if (key == "colour_map" || key == "color_map")
- {
- // colour-codes play-screen map
- Options.colour_map = read_bool( field, Options.colour_map );
- }
- else if (key == "easy_confirm")
- {
- // allows both 'Y'/'N' and 'y'/'n' on yesno() prompts
- if (field == "none")
- Options.easy_confirm = CONFIRM_NONE_EASY;
- else if (field == "safe")
- Options.easy_confirm = CONFIRM_SAFE_EASY;
- else if (field == "all")
- Options.easy_confirm = CONFIRM_ALL_EASY;
- }
- else if (key == "easy_quit_item_lists")
- {
- // allow aborting of item lists with space
- Options.easy_quit_item_prompts = read_bool( field,
- Options.easy_quit_item_prompts );
- }
- else if (key == "easy_open")
- {
- // automatic door opening with movement
- Options.easy_open = read_bool( field, Options.easy_open );
- }
- else if (key == "easy_armour" || key == "easy_armour")
- {
- // automatic removal of armour when dropping
- Options.easy_armour = read_bool( field, Options.easy_armour );
- }
- else if (key == "easy_butcher")
- {
- // automatic knife switching
- Options.easy_butcher = read_bool( field, Options.easy_butcher );
- }
- else if (key == "lua_file" && runscript)
- {
-#ifdef CLUA_BINDINGS
- clua.execfile(field.c_str());
- if (clua.error.length())
- fprintf(stderr, "Lua error: %s\n",
- clua.error.c_str());
-#endif
- }
- else if (key == "colour" || key == "color")
- {
- const int orig_col = str_to_colour( subkey );
- const int result_col = str_to_colour( field );
-
- if (orig_col != -1 && result_col != -1)
- Options.colour[orig_col] = result_col;
- else
- {
- fprintf( stderr, "Bad colour -- %s=%d or %s=%d\n",
- subkey.c_str(), orig_col, field.c_str(), result_col );
- }
- }
- else if (key == "channel")
- {
- const int chnl = str_to_channel( subkey );
- const int col = str_to_channel_colour( field );
-
- if (chnl != -1 && col != -1)
- Options.channels[chnl] = col;
- else if (chnl == -1)
- fprintf( stderr, "Bad channel -- %s\n", subkey.c_str() );
- else if (col == -1)
- fprintf( stderr, "Bad colour -- %s\n", field.c_str() );
- }
- else if (key == "background")
- {
- // change background colour
- // Experimental! This may look really bad!
- const int col = str_to_colour( field );
-
- if (col != -1)
- Options.background = col;
- else
- fprintf( stderr, "Bad colour -- %s\n", field.c_str() );
-
- }
- else if (key == "detected_item_colour")
- {
- const int col = str_to_colour( field );
- if (col != -1)
- Options.detected_item_colour = col;
- else
- fprintf( stderr, "Bad detected_item_colour -- %s\n",
- field.c_str());
- }
- else if (key == "detected_monster_colour")
- {
- const int col = str_to_colour( field );
- if (col != -1)
- Options.detected_monster_colour = col;
- else
- fprintf( stderr, "Bad detected_monster_colour -- %s\n",
- field.c_str());
- }
- else if (key == "remembered_monster_colour")
- {
- if (field == "real")
- Options.remembered_monster_colour = 0xFFFFU;
- else if (field == "auto")
- Options.remembered_monster_colour = 0;
- else {
- const int col = str_to_colour( field );
- if (col != -1)
- Options.remembered_monster_colour = col;
- else
- fprintf( stderr, "Bad remembered_monster_colour -- %s\n",
- field.c_str());
- }
- }
- else if (key == "friend_brand")
- {
- // Use curses attributes to mark friend
- // Some may look bad on some terminals.
- // As a suggestion, try "rxvt -rv -fn 10x20" under Un*xes
- Options.friend_brand = curses_attribute(field);
- }
- else if (key == "stab_brand")
- {
- Options.stab_brand = curses_attribute(field);
- }
- else if (key == "may_stab_brand")
- {
- Options.may_stab_brand = curses_attribute(field);
- }
- else if (key == "no_dark_brand")
- {
- // This is useful for terms where dark grey does
- // not have standout modes (since it's black on black).
- // This option will use light-grey instead in these cases.
- Options.no_dark_brand = read_bool( field, Options.no_dark_brand );
- }
- else if (key == "heap_brand")
- {
- // See friend_brand option upstairs. no_dark_brand applies
- // here as well.
- Options.heap_brand = curses_attribute(field);
- }
- else if (key == "show_uncursed")
- {
- // label known uncursed items as "uncursed"
- Options.show_uncursed = read_bool( field, Options.show_uncursed );
- }
- else if (key == "always_greet")
- {
- // show greeting when reloading game
- Options.always_greet = read_bool( field, Options.always_greet );
- }
- else if (key == "weapon")
- {
- // choose this weapon for classes that get choice
- Options.weapon = str_to_weapon( field );
- }
- else if (key == "chaos_knight")
- {
- // choose god for Chaos Knights
- if (field == "xom")
- Options.chaos_knight = GOD_XOM;
- else if (field == "makhleb")
- Options.chaos_knight = GOD_MAKHLEB;
- else if (field == "random")
- Options.chaos_knight = GOD_RANDOM;
- }
- else if (key == "death_knight")
- {
- if (field == "necromancy")
- Options.death_knight = DK_NECROMANCY;
- else if (field == "yredelemnul")
- Options.death_knight = DK_YREDELEMNUL;
- else if (field == "random")
- Options.death_knight = DK_RANDOM;
- }
- else if (key == "priest")
- {
- // choose this weapon for classes that get choice
- if (field == "zin")
- Options.priest = GOD_ZIN;
- else if (field == "yredelemnul")
- Options.priest = GOD_YREDELEMNUL;
- else if (field == "random")
- Options.priest = GOD_RANDOM;
- }
- else if (key == "fire_items_start")
- {
- if (isalpha( field[0] ))
- Options.fire_items_start = letter_to_index( field[0] );
- else
- {
- fprintf( stderr, "Bad fire item start index -- %s\n",
- field.c_str() );
- }
- }
- else if (key == "assign_item_slot")
- {
- if (field == "forward")
- Options.assign_item_slot = SS_FORWARD;
- else if (field == "backward")
- Options.assign_item_slot = SS_BACKWARD;
- }
- else if (key == "fire_order")
- {
- str_to_fire_order( field, Options.fire_order );
- }
- else if (key == "random_pick")
- {
- // randomly generate character
- Options.random_pick = read_bool( field, Options.random_pick );
- }
- else if (key == "remember_name")
- {
- Options.remember_name = read_bool( field, Options.remember_name );
- }
- else if (key == "hp_warning")
- {
- Options.hp_warning = atoi( field.c_str() );
- if (Options.hp_warning < 0 || Options.hp_warning > 100)
- {
- Options.hp_warning = 0;
- fprintf( stderr, "Bad HP warning percentage -- %s\n",
- field.c_str() );
- }
- }
- else if (key == "hp_attention")
- {
- Options.hp_attention = atoi( field.c_str() );
- if (Options.hp_attention < 0 || Options.hp_attention > 100)
- {
- Options.hp_attention = 0;
- fprintf( stderr, "Bad HP attention percentage -- %s\n",
- field.c_str() );
- }
- }
- else if (key == "crawl_dir")
- {
- // We shouldn't bother to allocate this a second time
- // if the user puts two crawl_dir lines in the init file.
- if (!SysEnv.crawl_dir)
- SysEnv.crawl_dir = (char *) calloc(kPathLen, sizeof(char));
-
- if (SysEnv.crawl_dir)
- {
- strncpy(SysEnv.crawl_dir, field.c_str(), kNameLen - 1);
- SysEnv.crawl_dir[ kNameLen - 1 ] = '\0';
- }
- }
- else if (key == "race")
- {
- Options.race = str_to_race( field );
-
- if (Options.race == '\0')
- fprintf( stderr, "Unknown race choice: %s\n", field.c_str() );
- }
- else if (key == "class")
- {
- Options.cls = str_to_class( field );
-
- if (Options.cls == '\0')
- fprintf( stderr, "Unknown class choice: %s\n", field.c_str() );
- }
- else if (key == "auto_list")
- {
- Options.auto_list = read_bool( field, Options.auto_list );
- }
- else if (key == "delay_message_clear")
- {
- Options.delay_message_clear = read_bool( field, Options.delay_message_clear );
- }
- else if (key == "terse_hand")
- {
- Options.terse_hand = read_bool( field, Options.terse_hand );
- }
- else if (key == "flush")
- {
- if (subkey == "failure")
- {
- Options.flush_input[FLUSH_ON_FAILURE]
- = read_bool(field, Options.flush_input[FLUSH_ON_FAILURE]);
- }
- else if (subkey == "command")
- {
- Options.flush_input[FLUSH_BEFORE_COMMAND]
- = read_bool(field, Options.flush_input[FLUSH_BEFORE_COMMAND]);
- }
- else if (subkey == "message")
- {
- Options.flush_input[FLUSH_ON_MESSAGE]
- = read_bool(field, Options.flush_input[FLUSH_ON_MESSAGE]);
- }
- else if (subkey == "lua")
- {
- Options.flush_input[FLUSH_LUA]
- = read_bool(field, Options.flush_input[FLUSH_LUA]);
- }
- }
- else if (key == "lowercase_invocations")
- {
- Options.lowercase_invocations
- = read_bool(field, Options.lowercase_invocations);
- }
- else if (key == "wiz_mode")
- {
- // wiz_mode is recognized as a legal key in all compiles -- bwr
-#ifdef WIZARD
- if (field == "never")
- Options.wiz_mode = WIZ_NEVER;
- else if (field == "no")
- Options.wiz_mode = WIZ_NO;
- else if (field == "yes")
- Options.wiz_mode = WIZ_YES;
- else
- fprintf(stderr, "Unknown wiz_mode option: %s\n", field.c_str());
-#endif
- }
- else if (key == "ban_pickup")
- {
- append_vector(Options.banned_objects, split_string(",", field));
- }
- else if (key == "pickup_thrown")
- {
- Options.pickup_thrown = read_bool(field, Options.pickup_thrown);
- }
- else if (key == "pickup_dropped")
- {
- Options.pickup_dropped = read_bool(field, Options.pickup_dropped);
- }
- else if (key == "show_waypoints")
- {
- Options.show_waypoints = read_bool(field, Options.show_waypoints);
- }
- else if (key == "fsim_kit")
- {
- append_vector(Options.fsim_kit, split_string(",", field));
- }
- else if (key == "fsim_rounds")
- {
- Options.fsim_rounds = atol(field.c_str());
- if (Options.fsim_rounds < 1000)
- Options.fsim_rounds = 1000;
- if (Options.fsim_rounds > 500000L)
- Options.fsim_rounds = 500000L;
- }
- else if (key == "fsim_mons")
- {
- Options.fsim_mons = field;
- }
- else if (key == "fsim_str")
- {
- Options.fsim_str = atoi(field.c_str());
- }
- else if (key == "fsim_int")
- {
- Options.fsim_int = atoi(field.c_str());
- }
- else if (key == "fsim_dex")
- {
- Options.fsim_dex = atoi(field.c_str());
- }
- else if (key == "fsim_xl")
- {
- Options.fsim_xl = atoi(field.c_str());
- }
- else if (key == "travel_delay")
- {
- // Read travel delay in milliseconds.
- Options.travel_delay = atoi( field.c_str() );
- if (Options.travel_delay < -1)
- Options.travel_delay = -1;
- if (Options.travel_delay > 2000)
- Options.travel_delay = 2000;
- }
- else if (key == "level_map_cursor_step")
- {
- Options.level_map_cursor_step = atoi( field.c_str() );
- if (Options.level_map_cursor_step < 1)
- Options.level_map_cursor_step = 1;
- if (Options.level_map_cursor_step > 50)
- Options.level_map_cursor_step = 50;
- }
- else if (key == "macro_meta_entry")
- {
- Options.macro_meta_entry = read_bool(field, Options.macro_meta_entry);
- }
- else if (key == "travel_stair_cost")
- {
- Options.travel_stair_cost = atoi( field.c_str() );
- if (Options.travel_stair_cost < 1)
- Options.travel_stair_cost = 1;
- else if (Options.travel_stair_cost > 1000)
- Options.travel_stair_cost = 1000;
- }
- else if (key == "travel_exclude_radius2")
- {
- Options.travel_exclude_radius2 = atoi( field.c_str() );
- if (Options.travel_exclude_radius2 < 0)
- Options.travel_exclude_radius2 = 0;
- else if (Options.travel_exclude_radius2 > 400)
- Options.travel_exclude_radius2 = 400;
- }
- else if (key == "stop_travel")
- {
- std::vector<std::string> fragments = split_string(",", field);
- for (int i = 0, count = fragments.size(); i < count; ++i)
- {
- if (fragments[i].length() == 0)
- continue;
-
- std::string::size_type pos = fragments[i].find(":");
- if (pos && pos != std::string::npos)
- {
- std::string prefix = fragments[i].substr(0, pos);
- int channel = str_to_channel( prefix );
- if (channel != -1 || prefix == "any")
- {
- std::string s = fragments[i].substr( pos + 1 );
- trim_string( s );
- Options.stop_travel.push_back(
- message_filter( channel, s ) );
- continue;
- }
- }
-
- Options.stop_travel.push_back(
- message_filter( fragments[i] ) );
- }
- }
- else if (key == "drop_filter")
- {
- append_vector(Options.drop_filter, split_string(",", field));
- }
- else if (key == "travel_avoid_terrain")
- {
- std::vector<std::string> seg = split_string(",", field);
- for (int i = 0, count = seg.size(); i < count; ++i)
- prevent_travel_to( seg[i] );
- }
- else if (key == "travel_colour")
- {
- Options.travel_colour = read_bool(field, Options.travel_colour);
- }
- else if (key == "item_colour")
- {
- Options.item_colour = read_bool(field, Options.item_colour);
- }
- else if (key == "easy_exit_menu")
- {
- Options.easy_exit_menu = read_bool(field, Options.easy_exit_menu);
- }
- else if (key == "dos_use_background_intensity")
- {
- Options.dos_use_background_intensity =
- read_bool(field, Options.dos_use_background_intensity);
- }
- else if (key == "explore_stop")
- {
- Options.explore_stop = ES_NONE;
- std::vector<std::string> stops = split_string(",", field);
- for (int i = 0, count = stops.size(); i < count; ++i)
- {
- const std::string &c = stops[i];
- if (c == "item" || c == "items")
- Options.explore_stop |= ES_ITEM;
- else if (c == "shop" || c == "shops")
- Options.explore_stop |= ES_SHOP;
- else if (c == "stair" || c == "stairs")
- Options.explore_stop |= ES_STAIR;
- else if (c == "altar" || c == "altars")
- Options.explore_stop |= ES_ALTAR;
- }
- }
-#ifdef STASH_TRACKING
- else if (key == "stash_tracking")
- {
- Options.stash_tracking =
- field == "explicit"? STM_EXPLICIT :
- field == "dropped" ? STM_DROPPED :
- field == "all" ? STM_ALL :
- STM_NONE;
- }
- else if (key == "stash_filter")
- {
- std::vector<std::string> seg = split_string(",", field);
- for (int i = 0, count = seg.size(); i < count; ++i)
- Stash::filter( seg[i] );
- }
-#endif
- else if (key == "sound")
- {
- std::vector<std::string> seg = split_string(",", field);
- for (int i = 0, count = seg.size(); i < count; ++i) {
- const std::string &sub = seg[i];
- std::string::size_type cpos = sub.find(":", 0);
- if (cpos != std::string::npos) {
- sound_mapping mapping;
- mapping.pattern = sub.substr(0, cpos);
- mapping.soundfile = sub.substr(cpos + 1);
- Options.sound_mappings.push_back(mapping);
- }
- }
- }
- else if (key == "menu_colour" || key == "menu_color")
- {
- std::vector<std::string> seg = split_string(",", field);
- for (int i = 0, count = seg.size(); i < count; ++i) {
- const std::string &sub = seg[i];
- std::string::size_type cpos = sub.find(":", 0);
- if (cpos != std::string::npos) {
- colour_mapping mapping;
- mapping.pattern = sub.substr(cpos + 1);
- mapping.colour = str_to_colour(sub.substr(0, cpos));
- if (mapping.colour != -1)
- Options.menu_colour_mappings.push_back(mapping);
- }
- }
- }
- else if (key == "dump_kill_places")
- {
- Options.dump_kill_places =
- field == "none"? KDO_NO_PLACES :
- field == "all" ? KDO_ALL_PLACES :
- KDO_ONE_PLACE;
- }
- else if (key == "kill_map")
- {
- std::vector<std::string> seg = split_string(",", field);
- for (int i = 0, count = seg.size(); i < count; ++i)
- {
- const std::string &s = seg[i];
- std::string::size_type cpos = s.find(":", 0);
- if (cpos != std::string::npos) {
- std::string from = s.substr(0, cpos);
- std::string to = s.substr(cpos + 1);
- do_kill_map(from, to);
- }
- }
- }
- else if (key == "dump_message_count")
- {
- // Capping is implicit
- Options.dump_message_count = atoi( field.c_str() );
- }
- else if (key == "dump_item_origins")
- {
- Options.dump_item_origins = IODS_PRICE;
- std::vector<std::string> choices = split_string(",", field);
- for (int i = 0, count = choices.size(); i < count; ++i)
- {
- const std::string &ch = choices[i];
- if (ch == "artifacts")
- Options.dump_item_origins |= IODS_ARTIFACTS;
- else if (ch == "ego_arm" || ch == "ego armour"
- || ch == "ego_armour")
- Options.dump_item_origins |= IODS_EGO_ARMOUR;
- else if (ch == "ego_weap" || ch == "ego weapon"
- || ch == "ego_weapon" || ch == "ego weapons"
- || ch == "ego_weapons")
- Options.dump_item_origins |= IODS_EGO_WEAPON;
- else if (ch == "jewellery" || ch == "jewelry")
- Options.dump_item_origins |= IODS_JEWELLERY;
- else if (ch == "runes")
- Options.dump_item_origins |= IODS_RUNES;
- else if (ch == "rods")
- Options.dump_item_origins |= IODS_RODS;
- else if (ch == "staves")
- Options.dump_item_origins |= IODS_STAVES;
- else if (ch == "books")
- Options.dump_item_origins |= IODS_BOOKS;
- else if (ch == "all" || ch == "everything")
- Options.dump_item_origins = IODS_EVERYTHING;
- }
- }
- else if (key == "dump_item_origin_price")
- {
- Options.dump_item_origin_price = atoi( field.c_str() );
- if (Options.dump_item_origin_price < -1)
- Options.dump_item_origin_price = -1;
- }
- else if (key == "target_zero_exp")
- {
- Options.target_zero_exp = read_bool(field, Options.target_zero_exp);
- }
- else if (key == "target_wrap")
- {
- Options.target_wrap = read_bool(field, Options.target_wrap);
- }
- else if (key == "target_oos")
- {
- Options.target_oos = read_bool(field, Options.target_oos);
- }
- else if (key == "target_los_first")
- {
- Options.target_los_first = read_bool(field, Options.target_los_first);
- }
- else if (key == "drop_mode")
- {
- if (field.find("multi") != std::string::npos)
- Options.drop_mode = DM_MULTI;
- else
- Options.drop_mode = DM_SINGLE;
- }
- // Catch-all else, copies option into map
- else
- {
-#ifdef CLUA_BINDINGS
- if (!clua.callbooleanfn(false, "c_process_lua_option", "ss",
- key.c_str(), orig_field.c_str()))
-#endif
- {
-#ifdef CLUA_BINDINGS
- if (clua.error.length())
- mpr(clua.error.c_str());
-#endif
- Options.named_options[key] = orig_field;
- }
- }
-}
-
-void get_system_environment(void)
-{
- // The player's name
- SysEnv.crawl_name = getenv("CRAWL_NAME");
-
- // The player's pizza
- SysEnv.crawl_pizza = getenv("CRAWL_PIZZA");
-
- // The directory which contians init.txt, macro.txt, morgue.txt
- // This should end with the appropriate path delimiter.
- SysEnv.crawl_dir = getenv("CRAWL_DIR");
-
- // The full path to the init file -- this over-rides CRAWL_DIR
- SysEnv.crawl_rc = getenv("CRAWL_RC");
-
- // rename giant and giant spiked clubs
- SysEnv.board_with_nail = (getenv("BOARD_WITH_NAIL") != NULL);
-
-#ifdef MULTIUSER
- // The user's home directory (used to look for ~/.crawlrc file)
- SysEnv.home = getenv("HOME");
-#endif
-} // end get_system_environment()
-
-
-// parse args, filling in Options and game environment as we go.
-// returns true if no unknown or malformed arguments were found.
-
-static const char *cmd_ops[] = { "scores", "name", "race", "class",
- "pizza", "plain", "dir", "rc", "tscores",
- "vscores" };
-
-const int num_cmd_ops = 10;
-bool arg_seen[num_cmd_ops];
-
-bool parse_args( int argc, char **argv, bool rc_only )
-{
- if (argc < 2) // no args!
- return (true);
-
- char *arg, *next_arg;
- int current = 1;
- bool nextUsed = false;
- int ecount;
-
- // initialize
- for(int i=0; i<num_cmd_ops; i++)
- arg_seen[i] = false;
-
- while(current < argc)
- {
- // get argument
- arg = argv[current];
-
- // next argument (if there is one)
- if (current+1 < argc)
- next_arg = argv[current+1];
- else
- next_arg = NULL;
-
- nextUsed = false;
-
- // arg MUST begin with '-' or '/'
- char c = arg[0];
- if (c != '-' && c != '/')
- return (false);
-
- // look for match (now we also except --scores)
- if (arg[1] == '-')
- arg = &arg[2];
- else
- arg = &arg[1];
-
- int o;
- for(o = 0; o < num_cmd_ops; o++)
- {
- if (stricmp(cmd_ops[o], arg) == 0)
- break;
- }
-
- if (o == num_cmd_ops)
- return (false);
-
- // disallow options specified more than once.
- if (arg_seen[o] == true)
- return (false);
-
- // set arg to 'seen'
- arg_seen[o] = true;
-
- // partially parse next argument
- bool next_is_param = false;
- if (next_arg != NULL)
- {
- if (next_arg[0] != '-' && next_arg[0] != '/')
- next_is_param = true;
- }
-
- //.take action according to the cmd chosen
- switch(o)
- {
- case 0: // scores
- case 8: // tscores
- case 9: // vscores
- if (!next_is_param)
- ecount = SCORE_FILE_ENTRIES; // default
- else // optional number given
- {
- ecount = atoi(next_arg);
- if (ecount < 1)
- ecount = 1;
-
- if (ecount > SCORE_FILE_ENTRIES)
- ecount = SCORE_FILE_ENTRIES;
-
- nextUsed = true;
- }
-
- if (!rc_only)
- {
- Options.sc_entries = ecount;
-
- if (o == 8)
- Options.sc_format = SCORE_TERSE;
- else if (o == 9)
- Options.sc_format = SCORE_VERBOSE;
-
- }
- break;
-
- case 1: // name
- if (!next_is_param)
- return (false);
-
- if (!rc_only)
- {
- strncpy(you.your_name, next_arg, kNameLen);
- you.your_name[ kNameLen - 1 ] = '\0';
- }
-
- nextUsed = true;
- break;
-
- case 2: // race
- case 3: // class
- if (!next_is_param)
- return (false);
-
- // if (strlen(next_arg) != 1)
- // return (false);
-
- if (!rc_only)
- {
- if (o == 2)
- Options.race = str_to_race( std::string( next_arg ) );
-
- if (o == 3)
- Options.cls = str_to_class( std::string( next_arg ) );
- }
- nextUsed = true;
- break;
-
- case 4: // pizza
- if (!next_is_param)
- return (false);
-
- if (!rc_only)
- SysEnv.crawl_pizza = next_arg;
-
- nextUsed = true;
- break;
-
- case 5: // plain
- if (next_is_param)
- return (false);
-
- if (!rc_only)
- {
- viewwindow = &viewwindow3;
- mapch = &mapchar3;
- mapch2 = &mapchar4;
-#ifdef UNIX
- character_set = 0;
-#endif
- }
- break;
-
- case 6: // dir
- // ALWAYS PARSE
- if (!next_is_param)
- return (false);
-
- SysEnv.crawl_dir = next_arg;
- nextUsed = true;
- break;
-
- case 7:
- // ALWAYS PARSE
- if (!next_is_param)
- return (false);
-
- SysEnv.crawl_rc = next_arg;
- nextUsed = true;
- break;
- } // end switch -- which option?
-
- // update position
- current++;
- if (nextUsed)
- current++;
- }
-
- return (true);
-}
diff --git a/stone_soup/crawl-ref/source/initfile.h b/stone_soup/crawl-ref/source/initfile.h
deleted file mode 100644
index 8be4ffad19..0000000000
--- a/stone_soup/crawl-ref/source/initfile.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * File: initfile.h
- * Summary: Simple reading of init file.
- * Written by: David Loewenstern
- *
- * Change History (most recent first):
- *
- * <1> 6/9/99 DML Created
- */
-
-
-#ifndef INITFILE_H
-#define INITFILE_H
-
-#include <string>
-#include <cstdio>
-
-std::string & trim_string( std::string &str );
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void read_init_file(bool runscript = false);
-
-void read_options(FILE *f, bool runscript = false);
-
-void read_options(const std::string &s, bool runscript = false);
-
-void parse_option_line(const std::string &line, bool runscript = false);
-
-void apply_ascii_display(bool ascii);
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void get_system_environment(void);
-
-
-// last updated 16feb2001 {gdl}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-bool parse_args(int argc, char **argv, bool rc_only);
-
-void write_newgame_options_file(void);
-
-void save_player_name(void);
-
-std::string channel_to_str(int ch);
-
-int str_to_channel(const std::string &);
-
-class InitLineInput {
-public:
- virtual ~InitLineInput() { }
- virtual bool eof() = 0;
- virtual std::string getline() = 0;
-};
-
-class FileLineInput : public InitLineInput {
-public:
- FileLineInput(FILE *f) : file(f) { }
-
- bool eof() {
- return !file || feof(file);
- }
-
- std::string getline() {
- char s[256] = "";
- if (!eof())
- fgets(s, sizeof s, file);
- return (s);
- }
-private:
- FILE *file;
-};
-
-class StringLineInput : public InitLineInput {
-public:
- StringLineInput(const std::string &s) : str(s), pos(0) { }
-
- bool eof() {
- return pos >= str.length();
- }
-
- std::string getline() {
- if (eof())
- return "";
- std::string::size_type newl = str.find("\n", pos);
- if (newl == std::string::npos)
- newl = str.length();
- std::string line = str.substr(pos, newl - pos);
- pos = newl + 1;
- return line;
- }
-private:
- const std::string &str;
- std::string::size_type pos;
-};
-
-#endif
diff --git a/stone_soup/crawl-ref/source/insult.cc b/stone_soup/crawl-ref/source/insult.cc
deleted file mode 100644
index 1e8c629ab9..0000000000
--- a/stone_soup/crawl-ref/source/insult.cc
+++ /dev/null
@@ -1,672 +0,0 @@
-// insult generator
-// Josh Fishman (c) 2001, All Rights Reserved
-// This file is released under the GNU GPL, but special permission is granted
-// to link with Linley Henzel's Dungeon Crawl (or Crawl) without change to
-// Crawl's license.
-//
-// The goal of this stuff is catachronistic feel.
-
-#include "AppHdr.h"
-
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-
-#include "externs.h"
-#include "insult.h"
-#include "mon-util.h"
-#include "stuff.h"
-
-static const char* insults1(void);
-static const char* insults2(void);
-static const char* insults3(void);
-static const char* run_away(void);
-static const char* give_up(void);
-static const char* meal(void);
-static const char* whilst_thou_can(void);
-static const char* important_body_part(void);
-static const char* important_spiritual_part(void);
-
-static void init_cap(char *);
-
-void init_cap(char * str)
-{
- if (str != NULL)
- str[0] = toupper( str[0] );
-}
-
-void imp_taunt( struct monsters *mons )
-{
- char buff[80];
- const char *mon_name = ptr_monam( mons, DESC_CAP_THE );
-
- snprintf( buff, sizeof(buff),
- "%s, thou %s!",
- random2(7) ? run_away() : give_up(),
- generic_insult() );
-
- init_cap( buff );
-
- // XXX: Not pretty, but stops truncation...
- if (strlen( mon_name ) + 11 + strlen( buff ) >= 79)
- {
- snprintf( info, INFO_SIZE, "%s shouts:", mon_name );
- mpr( info, MSGCH_TALK );
-
- mpr( buff, MSGCH_TALK );
- }
- else
- {
- snprintf( info, INFO_SIZE, "%s shouts, \"%s\"", mon_name, buff );
- mpr( info, MSGCH_TALK );
- }
-}
-
-void demon_taunt( struct monsters *mons )
-{
- static const char * sound_list[] =
- {
- "says", // actually S_SILENT
- "shouts",
- "barks",
- "shouts",
- "roars",
- "screams",
- "bellows",
- "screeches",
- "buzzes",
- "moans",
- "whines",
- "croaks",
- "growls",
- };
-
- char buff[80];
- const char *mon_name = ptr_monam( mons, DESC_CAP_THE );
- const char *voice = sound_list[ mons_shouts(mons->type) ];
-
- if (coinflip())
- {
- snprintf( buff, sizeof(buff),
- "%s, thou %s!",
- random2(3) ? give_up() : run_away(),
- generic_insult() );
- }
- else
- {
- switch( random2( 4 ) )
- {
- case 0:
- snprintf( buff, sizeof(buff),
- "Thy %s shall be my %s!",
- random2(4) ? important_body_part()
- : important_spiritual_part(), meal() );
- break;
- case 1:
- snprintf( buff, sizeof(buff),
- "%s, thou tasty %s!", give_up(), meal() );
- break;
- case 2:
- snprintf( buff, sizeof(buff),
- "%s %s!", run_away(), whilst_thou_can() );
- break;
- case 3:
- snprintf( buff, sizeof(buff),
- "I %s %s thy %s!",
- coinflip() ? "will" : "shall",
- coinflip() ? "feast upon" : "devour",
- random2(4) ? important_body_part()
- : important_spiritual_part() );
- break;
- default:
- snprintf( buff, sizeof(buff), "Thou %s!", generic_insult() );
- break;
- }
- }
-
- init_cap( buff );
-
- // XXX: Not pretty, but stops truncation...
- if (strlen(mon_name) + strlen(voice) + strlen(buff) + 5 >= 79)
- {
- snprintf( info, INFO_SIZE, "%s %s:", mon_name, voice );
- mpr( info, MSGCH_TALK );
-
- mpr( buff, MSGCH_TALK );
- }
- else
- {
- snprintf( info, INFO_SIZE, "%s %s, \"%s\"", mon_name, voice, buff );
- mpr( info, MSGCH_TALK );
- }
-}
-
-const char * generic_insult(void)
-{
- static char buffer[80]; //FIXME: use string objects or whatnot
-
- strcpy(buffer, insults1());
- strcat(buffer, " ");
- strcat(buffer, insults2());
- strcat(buffer, " ");
- strcat(buffer, insults3());
-
- return (buffer);
-}
-
-static const char * important_body_part(void)
-{
- static const char * part_list[] = {
- "head",
- "brain",
- "heart",
- "viscera",
- "eyes",
- "lungs",
- "liver",
- "throat",
- "neck",
- "skull",
- "spine",
- };
-
- return (part_list[random2(sizeof(part_list) / sizeof(char *))]);
-}
-
-static const char * important_spiritual_part(void)
-{
- static const char * part_list[] = {
- "soul",
- "spirit",
- "inner light",
- "hope",
- "faith",
- "will",
- "heart",
- "mind",
- "sanity",
- "fortitude",
- "life force",
- };
-
- return (part_list[random2(sizeof(part_list) / sizeof(char *))]);
-}
-
-static const char * meal(void)
-{
- static const char * meal_list[] = {
- "meal",
- "breakfast",
- "lunch",
- "dinner",
- "supper",
- "repast",
- "snack",
- "victuals",
- "refection",
- "junket",
- "luncheon",
- "snackling",
- "curdle",
- "snacklet",
- "mouthful",
- };
-
- return (meal_list[random2(sizeof(meal_list) / sizeof(char *))]);
-}
-
-static const char * run_away(void)
-{
- static const char * run_away_list[] = {
- "give up",
- "quit",
- "run away",
- "escape",
- "flee",
- "fly",
- "take thy face hence",
- "remove thy stench",
- "go and return not",
- "get thee hence",
- "back with thee",
- "away with thee",
- "turn tail",
- "leave",
- "return whence thou came",
- "begone",
- "get thee gone",
- "get thee hence",
- "slither away",
- "slither home",
- "slither hence",
- "crawl home",
- "scamper home",
- "scamper hence",
- "scamper away",
- "bolt",
- "decamp",
- };
-
- return (run_away_list[random2(sizeof(run_away_list) / sizeof(char *))]);
-}
-
-static const char * give_up(void)
-{
- static const char * give_up_list[] = {
- "give up",
- "give in",
- "quit",
- "surrender",
- "kneel",
- "beg for mercy",
- "despair",
- "submit",
- "succumb",
- "quail",
- "embrace thy failure",
- "embrace thy fall",
- "embrace thy doom",
- "embrace thy dedition",
- "embrace submission",
- "accept thy failure",
- "accept thy fall",
- "accept thy doom",
- "capitulate",
- "tremble",
- "relinquish hope",
- "taste defeat",
- "despond",
- "disclaim thyself",
- "abandon hope",
- "face thy requiem",
- "face thy fugue",
- "admit defeat",
- "flounder",
- };
-
- return (give_up_list[random2(sizeof(give_up_list) / sizeof(char *))]);
-}
-
-static const char * whilst_thou_can(void)
-{
- static const char * threat_list[] = {
- "whilst thou can",
- "whilst thou may",
- "whilst thou are able",
- "if wit thou hast",
- "whilst thy luck holds",
- "before doom catcheth thee",
- "lest death find thee",
- "whilst thou art whole",
- "whilst life thou hast", //jmf: hmm. screen vs. this for undead?
- };
-
- return (threat_list[random2(sizeof(threat_list) / sizeof(char *))]);
-}
-
-static const char * insults1(void)
-{
- static const char * insults1_list[] = {
- "artless",
- "baffled",
- "bawdy",
- "beslubbering",
- "bootless",
- "bumbling",
- "canting",
- "churlish",
- "cockered",
- "clouted",
- "craven",
- "currish",
- "dankish",
- "dissembling",
- "droning",
- "ducking",
- "errant",
- "fawning",
- "feckless",
- "feeble",
- "fobbing",
- "foppish",
- "froward",
- "frothy",
- "fulsome",
- "gleeking",
- "goatish",
- "gorbellied",
- "grime-gilt",
- "horrid",
- "hateful",
- "impertinent",
- "infectious",
- "jarring",
- "loggerheaded",
- "lumpish",
- "mammering",
- "mangled",
- "mewling",
- "odious",
- "paunchy",
- "pribbling",
- "puking",
- "puny",
- "qualling",
- "quaking",
- "rank",
- "pandering",
- "pecksniffian",
- "plume-plucked",
- "pottle-deep",
- "pox-marked",
- "reeling-ripe",
- "rough-hewn",
- "simpering",
- "spongy",
- "surly",
- "tottering",
- "twisted",
- "unctious",
- "unhinged",
- "unmuzzled",
- "vain",
- "venomed",
- "villainous",
- "warped",
- "wayward",
- "weedy",
- "worthless",
- "yeasty",
- };
-
- return (insults1_list[random2(sizeof(insults1_list) / sizeof(char*))]);
-}
-
-static const char * insults2(void)
-{
- static const char * insults2_list[] = {
- "base-court",
- "bat-fowling",
- "beef-witted",
- "beetle-headed",
- "boil-brained",
- "clapper-clawed",
- "clay-brained",
- "common-kissing",
- "crook-pated",
- "dismal-dreaming",
- "ditch-delivered",
- "dizzy-eyed",
- "doghearted",
- "dread-bolted",
- "earth-vexing",
- "elf-skinned",
- "fat-kidneyed",
- "fen-sucked",
- "flap-mouthed",
- "fly-bitten",
- "folly-fallen",
- "fool-born",
- "full-gorged",
- "guts-griping",
- "half-faced",
- "hasty-witted",
- "hedge-born",
- "hell-hated",
- "idle-headed",
- "ill-breeding",
- "ill-nurtured",
- "kobold-kissing",
- "knotty-pated",
- "limp-willed",
- "milk-livered",
- "moon-mazed",
- "motley-minded",
- "onion-eyed",
- "miscreant",
- "roguish",
- "moldwarp",
- "ruttish",
- "mumble-news",
- "saucy",
- "nut-hook",
- "spleeny",
- "pigeon-egg",
- "rude-growing",
- "rump-fed",
- "shard-borne",
- "sheep-biting",
- "sow-suckled",
- "spur-galled",
- "swag-bellied",
- "tardy-gaited",
- "tickle-brained",
- "toad-spotted",
- "toenail-biting",
- "unchin-snouted",
- "weather-bitten",
- "weevil-witted",
- };
-
- return (insults2_list[random2(sizeof(insults2_list) / sizeof(char*))]);
-}
-
-static const char * insults3(void)
-{
- static const char * insults3_list[] = {
- "apple-john",
- "baggage",
- "bandersnitch",
- "barnacle",
- "beggar",
- "bladder",
- "boar-pig",
- "bounder",
- "bugbear",
- "bum-bailey",
- "canker-blossom",
- "clack-dish",
- "clam",
- "clotpole",
- "coxcomb",
- "codpiece",
- "death-token",
- "dewberry",
- "dingleberry",
- "flap-bat",
- "flax-wench",
- "flirt-gill",
- "foot-licker",
- "fustilarian",
- "giglet",
- "gnoll-tail",
- "gudgeon",
- "guttersnipe",
- "haggard",
- "harpy",
- "hedge-pig",
- "horn-beast",
- "hugger-mugger",
- "joithead",
- "lewdster",
- "lout",
- "maggot-pie",
- "malt-worm",
- "mammet",
- "measle",
- "mendicant",
- "minnow reeky",
- "mule",
- "nightsoil",
- "nobody",
- "nothing",
- "pigeon-egg",
- "pignut",
- "pimple",
- "pustule",
- "puttock",
- "pumpion",
- "ratsbane",
- "scavenger",
- "scut",
- "serf",
- "simpleton",
- "skainsmate",
- "slime mold",
- "snaffler",
- "snake-molt",
- "strumpet",
- "surfacer",
- "tinkerer",
- "tiddler",
- "urchin",
- "varlet",
- "vassal",
- "vulture",
- "wastrel",
- "wagtail",
- "whey-face",
- "wormtrail",
- "yak-dropping",
- "zombie-fodder",
- };
-
- return (insults3_list[random2(sizeof(insults3_list) / sizeof(char*))]);
-}
-
-// currently unused:
-#if 0
-const char * racial_insult(void)
-{
- static const char * food3[] = {
- "snackling",
- "crunchlet",
- "half-meal",
- "supper-setting",
- "snacklet",
- "noshlet",
- "morsel",
- "mug-up",
- "bite-bait",
- "crunch-chow",
- "snack-pap",
- "grub",
- };
-
- static const char * elf1[] = {
- "weakly",
- "sickly",
- "frail",
- "delicate",
- "fragile",
- "brittle",
- "tender",
- "mooning",
- "painted",
- "lily-hearted",
- "dandy",
- "featherweight",
- "flimsy",
- "rootless",
- "spindly",
- "puny",
- "shaky",
- "prissy",
- };
-
- static const char * halfling3[] = {
- "half-pint",
- "footstool",
- "munchkin",
- "side-stool",
- "pudgelet",
- "groundling",
- "burrow-snipe",
- "hole-bolter",
- "low-roller",
- "runt",
- "peewee",
- "mimicus",
- "manikin",
- "hop-o-thumb",
- "knee-biter",
- "burrow-botch",
- "hole-pimple",
- "hovel-pustule",
- };
-
- static const char * spriggan3[] = {
- "rat-rider",
- "mouthfull",
- "quarter-pint",
- "nissette",
- "fizzle-flop",
- "spell-botch",
- "feeblet",
- "weakling",
- "pinchbeck-pixie",
- "ankle-biter",
- "bootstain",
- "nano-nebbish",
- "sopling",
- "shrunken violet",
- "sissy-prig",
- "pussyfoot",
- "creepsneak",
- };
-
- static const char * dwarf2[] = {
- "dirt-grubbing",
- "grit-sucking",
- "muck-plodding",
- "stone-broke",
- "pelf-dandling",
- "fault-botching",
- "gravel-groveling",
- "boodle-bothering",
- "cabbage-coddling",
- "rhino-raveling",
- "thigh-biting",
- "dirt-delving",
- };
-
- static const char * kenku2[] = {
- "hollow-boned",
- "feather-brained",
- "beak-witted",
- "hen-pecked",
- "lightweight",
- "frail-limbed",
- "bird-brained",
- "featherweight",
- "pigeon-toed",
- "crow-beaked",
- "magpie-eyed",
- "mallardish",
- };
-
- static const char * minotaur3[] = {
- "bull-brain",
- "cud-chewer",
- "calf-wit",
- "bovine",
- //"mooer", // of Venice
- "cow",
- "cattle",
- "meatloaf",
- "veal",
- "meatball",
- "rump-roast",
- "briscut",
- "cretin",
- "walking sirloin",
- };
-
- switch (you.species)
- {
- default:
- break;
- }
-}
-#endif
diff --git a/stone_soup/crawl-ref/source/insult.h b/stone_soup/crawl-ref/source/insult.h
deleted file mode 100644
index 143d0ecae3..0000000000
--- a/stone_soup/crawl-ref/source/insult.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef INSULT_H
-#define INSULT_H
-
-#include "externs.h"
-
-void imp_taunt( struct monsters *mons );
-void demon_taunt( struct monsters *mons );
-const char * generic_insult(void);
-const char * racial_insult(void);
-
-#endif
diff --git a/stone_soup/crawl-ref/source/invent.cc b/stone_soup/crawl-ref/source/invent.cc
deleted file mode 100644
index 2145f80f72..0000000000
--- a/stone_soup/crawl-ref/source/invent.cc
+++ /dev/null
@@ -1,1027 +0,0 @@
-/*
- * File: invent.cc
- * Summary: Functions for inventory related commands.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <5> 10/9/99 BCR Added wizard help screen
- * <4> 10/1/99 BCR Clarified help screen
- * <3> 6/9/99 DML Autopickup
- * <2> 5/20/99 BWR Extended screen lines support
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "invent.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#ifdef DOS
-#include <conio.h>
-#endif
-
-#include "externs.h"
-
-#include "clua.h"
-#include "itemname.h"
-#include "items.h"
-#include "macro.h"
-#include "player.h"
-#include "shopping.h"
-#include "stuff.h"
-#include "view.h"
-#include "menu.h"
-
-const char *command_string( int i );
-const char *wizard_string( int i );
-
-struct InvTitle : public MenuEntry
-{
- Menu *m;
- std::string (*titlefn)( int menuflags, const std::string &oldt );
-
- InvTitle( Menu *mn, const char *title,
- std::string (*tfn)( int menuflags, const std::string &oldt ) )
- : MenuEntry( title )
- {
- m = mn;
- titlefn = tfn;
- }
-
- std::string get_text() const
- {
- return titlefn? titlefn( m->get_flags(), MenuEntry::get_text() ) :
- MenuEntry::get_text();
- }
-};
-
-class InvShowPrices;
-class InvEntry : public MenuEntry
-{
-private:
- static bool show_prices;
- static char temp_id[4][50];
- static void set_show_prices(bool doshow);
-
- friend class InvShowPrices;
-public:
- const item_def *item;
-
- InvEntry( const item_def &i ) : MenuEntry( "", MEL_ITEM ), item( &i )
- {
- data = const_cast<item_def *>( item );
-
- char buf[ITEMNAME_SIZE];
- if (i.base_type == OBJ_GOLD)
- snprintf(buf, sizeof buf, "%d gold piece%s", i.quantity,
- (i.quantity > 1? "s" : ""));
- else
- item_name(i,
- in_inventory(i)?
- DESC_INVENTORY_EQUIP : DESC_NOCAP_A, buf, false);
- text = buf;
-
- if (i.base_type != OBJ_GOLD)
- {
- if (in_inventory(i))
- {
- text = text.substr( 4 ); // Skip the inventory letter.
- add_hotkey(index_to_letter( i.link ));
- }
- else
- add_hotkey(' '); // Dummy hotkey
- }
- else
- {
- // Dummy hotkey for gold.
- add_hotkey(' ');
- }
- add_class_hotkeys(i);
-
- quantity = i.quantity;
- }
-
- std::string get_text() const
- {
- char buf[ITEMNAME_SIZE];
- char suffix[ITEMNAME_SIZE] = "";
-
- if (InvEntry::show_prices)
- {
- int value = item_value(*item, temp_id, true);
- if (value > 0)
- snprintf(suffix, sizeof suffix,
- " (%d gold)", value);
- }
- snprintf( buf, sizeof buf,
- "%c %c %s%s",
- hotkeys[0],
- (!selected_qty? '-' : selected_qty < quantity? '#' : '+'),
- text.c_str(),
- suffix );
- return (buf);
- }
-private:
- void add_class_hotkeys(const item_def &i)
- {
- switch (i.base_type)
- {
- case OBJ_GOLD:
- add_hotkey('$');
- break;
- case OBJ_MISSILES:
- add_hotkey('(');
- break;
- case OBJ_WEAPONS:
- add_hotkey(')');
- break;
- case OBJ_ARMOUR:
- add_hotkey('[');
- break;
- case OBJ_WANDS:
- add_hotkey('/');
- break;
- case OBJ_FOOD:
- add_hotkey('%');
- break;
- case OBJ_BOOKS:
- add_hotkey('+');
- add_hotkey(':');
- break;
- case OBJ_SCROLLS:
- add_hotkey('?');
- break;
- case OBJ_JEWELLERY:
- add_hotkey(i.sub_type >= AMU_RAGE? '"' : '=');
- break;
- case OBJ_POTIONS:
- add_hotkey('!');
- break;
- case OBJ_STAVES:
- add_hotkey('\\');
- add_hotkey('|');
- break;
- case OBJ_MISCELLANY:
- add_hotkey('}');
- break;
- case OBJ_CORPSES:
- add_hotkey('&');
- break;
- default:
- break;
- }
- }
-};
-
-bool InvEntry::show_prices = false;
-char InvEntry::temp_id[4][50];
-
-void InvEntry::set_show_prices(bool doshow)
-{
- if ((show_prices = doshow))
- {
- memset(temp_id, 1, sizeof temp_id);
- }
-}
-
-class InvShowPrices {
-public:
- InvShowPrices(bool doshow = true)
- {
- InvEntry::set_show_prices(doshow);
- }
- ~InvShowPrices()
- {
- InvEntry::set_show_prices(false);
- }
-};
-
-class InvMenu : public Menu
-{
-public:
- InvMenu(int flags = MF_MULTISELECT) : Menu(flags) { }
-protected:
- bool process_key(int key);
-};
-
-bool InvMenu::process_key( int key )
-{
- if (items.size() && (key == CONTROL('D') || key == '@'))
- {
- int newflag =
- is_set(MF_MULTISELECT)?
- MF_SINGLESELECT | MF_EASY_EXIT | MF_ANYPRINTABLE
- : MF_MULTISELECT;
-
- flags &= ~(MF_SINGLESELECT | MF_MULTISELECT |
- MF_EASY_EXIT | MF_ANYPRINTABLE);
- flags |= newflag;
-
- deselect_all();
- sel->clear();
- draw_select_count(0);
- return true;
- }
- return Menu::process_key( key );
-}
-
-bool in_inventory( const item_def &i )
-{
- return i.x == -1 && i.y == -1;
-}
-
-unsigned char get_invent( int invent_type )
-{
- unsigned char nothing = invent_select( invent_type );
-
- redraw_screen();
-
- return (nothing);
-} // end get_invent()
-
-std::string item_class_name( int type, bool terse )
-{
- if (terse)
- {
- switch (type)
- {
- case OBJ_GOLD: return ("gold");
- case OBJ_WEAPONS: return ("weapon");
- case OBJ_MISSILES: return ("missile");
- case OBJ_ARMOUR: return ("armour");
- case OBJ_WANDS: return ("wand");
- case OBJ_FOOD: return ("food");
- case OBJ_UNKNOWN_I: return ("book");
- case OBJ_SCROLLS: return ("scroll");
- case OBJ_JEWELLERY: return ("jewelry");
- case OBJ_POTIONS: return ("potion");
- case OBJ_UNKNOWN_II: return ("gem");
- case OBJ_BOOKS: return ("book");
- case OBJ_STAVES: return ("stave");
- case OBJ_ORBS: return ("orb");
- case OBJ_MISCELLANY: return ("misc");
- case OBJ_CORPSES: return ("carrion");
- }
- }
- else
- {
- switch (type)
- {
- case OBJ_GOLD: return ("Gold");
- case OBJ_WEAPONS: return ("Hand Weapons");
- case OBJ_MISSILES: return ("Missiles");
- case OBJ_ARMOUR: return ("Armour");
- case OBJ_WANDS: return ("Magical Devices");
- case OBJ_FOOD: return ("Comestibles");
- case OBJ_UNKNOWN_I: return ("Books");
- case OBJ_SCROLLS: return ("Scrolls");
- case OBJ_JEWELLERY: return ("Jewellery");
- case OBJ_POTIONS: return ("Potions");
- case OBJ_UNKNOWN_II: return ("Gems");
- case OBJ_BOOKS: return ("Books");
- case OBJ_STAVES: return ("Magical Staves and Rods");
- case OBJ_ORBS: return ("Orbs of Power");
- case OBJ_MISCELLANY: return ("Miscellaneous");
- case OBJ_CORPSES: return ("Carrion");
- }
- }
- return ("");
-}
-
-void populate_item_menu( Menu *menu, const std::vector<item_def> &items,
- void (*callback)(MenuEntry *me) )
-{
- FixedVector< int, NUM_OBJECT_CLASSES > inv_class;
- for (int i = 0; i < NUM_OBJECT_CLASSES; ++i)
- inv_class[i] = 0;
- for (int i = 0, count = items.size(); i < count; ++i)
- inv_class[ items[i].base_type ]++;
-
- menu_letter ckey;
- for (int i = 0; i < NUM_OBJECT_CLASSES; ++i)
- {
- if (!inv_class[i]) continue;
-
- menu->add_entry( new MenuEntry( item_class_name(i), MEL_SUBTITLE ) );
-
- for (int j = 0, count = items.size(); j < count; ++j)
- {
- if (items[j].base_type != i) continue;
-
- InvEntry *ie = new InvEntry( items[j] );
- ie->hotkeys[0] = ckey++;
- callback(ie);
-
- menu->add_entry( ie );
- }
- }
-}
-
-std::vector<SelItem> select_items( std::vector<item_def*> &items,
- const char *title )
-{
- std::vector<SelItem> selected;
-
- if (items.empty())
- return selected;
-
- FixedVector< int, NUM_OBJECT_CLASSES > inv_class;
- for (int i = 0; i < NUM_OBJECT_CLASSES; ++i)
- inv_class[i] = 0;
- for (int i = 0, count = items.size(); i < count; ++i)
- inv_class[ items[i]->base_type ]++;
-
- Menu menu;
- menu.set_title( new MenuEntry(title) );
-
- char ckey = 'a';
- for (int i = 0; i < NUM_OBJECT_CLASSES; ++i)
- {
- if (!inv_class[i]) continue;
-
- menu.add_entry( new MenuEntry( item_class_name(i), MEL_SUBTITLE ) );
-
- for (int j = 0, count = items.size(); j < count; ++j)
- {
- if (items[j]->base_type != i) continue;
-
- InvEntry *ie = new InvEntry( *items[j] );
- ie->hotkeys[0] = ckey;
-
- menu.add_entry( ie );
-
- ckey = ckey == 'z'? 'A' :
- ckey == 'Z'? 'a' :
- ckey + 1;
- }
- }
- menu.set_flags( MF_MULTISELECT | MF_SELECT_ANY_PAGE );
- std::vector< MenuEntry * > sel = menu.show();
- for (int i = 0, count = sel.size(); i < count; ++i)
- {
- InvEntry *inv = (InvEntry *) sel[i];
- selected.push_back( SelItem( inv->hotkeys[0],
- inv->selected_qty,
- inv->item ) );
- }
-
- return selected;
-}
-
-static bool item_class_selected(const item_def &i, int selector)
-{
- const int itype = i.base_type;
- if (selector == OSEL_ANY || selector == itype)
- return (true);
-
- switch (selector)
- {
- case OBJ_MISSILES:
- return (itype == OBJ_MISSILES || itype == OBJ_WEAPONS);
- case OBJ_WEAPONS:
- case OSEL_WIELD:
- return (itype == OBJ_WEAPONS || itype == OBJ_STAVES
- || itype == OBJ_MISCELLANY);
- case OBJ_SCROLLS:
- return (itype == OBJ_SCROLLS || itype == OBJ_BOOKS);
- default:
- return (false);
- }
-}
-
-static bool userdef_item_selected(const item_def &i, int selector)
-{
-#if defined(CLUA_BINDINGS)
- const char *luafn = selector == OSEL_WIELD? "ch_item_wieldable" :
- NULL;
- return (luafn && clua.callbooleanfn(false, luafn, "u", &i));
-#else
- return (false);
-#endif
-}
-
-static bool is_item_selected(const item_def &i, int selector)
-{
- return item_class_selected(i, selector)
- || userdef_item_selected(i, selector);
-}
-
-static void get_inv_items_to_show(std::vector<item_def*> &v, int selector)
-{
- for (int i = 0; i < ENDOFPACK; i++)
- {
- if (is_valid_item(you.inv[i]) && is_item_selected(you.inv[i], selector))
- v.push_back( &you.inv[i] );
- }
-}
-
-static void set_vectitem_classes(const std::vector<item_def*> &v,
- FixedVector<int, NUM_OBJECT_CLASSES> &fv)
-{
- for (int i = 0; i < NUM_OBJECT_CLASSES; i++)
- fv[i] = 0;
-
- for (int i = 0, size = v.size(); i < size; i++)
- fv[ v[i]->base_type ]++;
-}
-
-unsigned char invent_select(
- int item_selector,
- int flags,
- std::string (*titlefn)( int menuflags,
- const std::string &oldt ),
- std::vector<SelItem> *items,
- std::vector<text_pattern> *filter,
- Menu::selitem_tfn selitemfn )
-{
- InvMenu menu;
-
- menu.selitem_text = selitemfn;
- if (filter)
- menu.set_select_filter( *filter );
-
- FixedVector< int, NUM_OBJECT_CLASSES > inv_class2;
- for (int i = 0; i < NUM_OBJECT_CLASSES; i++)
- inv_class2[i] = 0;
-
- int inv_count = 0;
-
- for (int i = 0; i < ENDOFPACK; i++)
- {
- if (you.inv[i].quantity)
- {
- inv_class2[ you.inv[i].base_type ]++;
- inv_count++;
- }
- }
-
- if (!inv_count)
- {
- menu.set_title( new MenuEntry( "You aren't carrying anything." ) );
- menu.show();
- return 0;
- }
-
- std::vector<item_def*> tobeshown;
- get_inv_items_to_show( tobeshown, item_selector );
- set_vectitem_classes( tobeshown, inv_class2 );
-
- if (tobeshown.size())
- {
- const int cap = carrying_capacity();
-
- char title_buf[200];
- snprintf( title_buf, sizeof title_buf,
- "Inventory: %d.%d/%d.%d aum (%d%%, %d/52 slots)",
- you.burden / 10, you.burden % 10,
- cap / 10, cap % 10,
- (you.burden * 100) / cap,
- inv_count );
- menu.set_title( new InvTitle( &menu, title_buf, titlefn ) );
-
- for (int i = 0; i < 15; i++)
- {
- if (inv_class2[i] != 0)
- {
- std::string s = item_class_name(i);
- menu.add_entry( new MenuEntry( s, MEL_SUBTITLE ) );
-
- for (int j = 0, size = tobeshown.size(); j < size; ++j)
- {
- if (tobeshown[j]->base_type == i)
- {
- menu.add_entry( new InvEntry( *tobeshown[j] ) );
- }
- } // end of j loop
- } // end of if inv_class2
- } // end of i loop.
- }
- else
- {
- std::string s;
- if (item_selector == -1)
- s = "You aren't carrying anything.";
- else
- {
- if (item_selector == OBJ_WEAPONS || item_selector == OSEL_WIELD)
- s = "You aren't carrying any weapons.";
- else if (item_selector == OBJ_MISSILES)
- s = "You aren't carrying any ammunition.";
- else
- s = "You aren't carrying any such object.";
- }
- menu.set_title( new MenuEntry( s ) );
- }
-
- menu.set_flags( flags );
- std::vector< MenuEntry * > sel = menu.show();
- if (items)
- {
- for (int i = 0, count = sel.size(); i < count; ++i)
- items->push_back( SelItem( sel[i]->hotkeys[0],
- sel[i]->selected_qty ) );
- }
-
- unsigned char mkey = menu.getkey();
- if (!isalnum(mkey) && mkey != '$' && mkey != '-' && mkey != '?'
- && mkey != '*')
- mkey = ' ';
- return mkey;
-}
-
-unsigned char invent( int item_class_inv, bool show_price )
-{
- InvShowPrices show_item_prices(show_price);
- return (invent_select(item_class_inv));
-} // end invent()
-
-
-// Reads in digits for a count and apprends then to val, the
-// return value is the character that stopped the reading.
-static unsigned char get_invent_quant( unsigned char keyin, int &quant )
-{
- quant = keyin - '0';
-
- for(;;)
- {
- keyin = get_ch();
-
- if (!isdigit( keyin ))
- break;
-
- quant *= 10;
- quant += (keyin - '0');
-
- if (quant > 9999999)
- {
- quant = 9999999;
- keyin = '\0';
- break;
- }
- }
-
- return (keyin);
-}
-
-// This function prompts the user for an item, handles the '?' and '*'
-// listings, and returns the inventory slot to the caller (which if
-// must_exist is true (the default) will be an assigned item, with
-// a positive quantity.
-//
-// It returns PROMPT_ABORT if the player hits escape.
-// It returns PROMPT_GOT_SPECIAL if the player hits the "other_valid_char".
-//
-// Note: This function never checks if the item is appropriate.
-std::vector<SelItem> prompt_invent_items(
- const char *prompt,
- int type_expect,
- std::string (*titlefn)( int menuflags,
- const std::string &oldt ),
- bool allow_auto_list,
- bool allow_easy_quit,
- const char other_valid_char,
- std::vector<text_pattern> *select_filter,
- Menu::selitem_tfn fn )
-{
- unsigned char keyin = 0;
- int ret = -1;
-
- bool need_redraw = false;
- bool need_prompt = true;
- bool need_getch = true;
-
- if (Options.auto_list && allow_auto_list)
- {
- need_getch = false;
- need_redraw = false;
- need_prompt = false;
- keyin = '?';
- }
-
- std::vector< SelItem > items;
- int count = -1;
- for (;;)
- {
- if (need_redraw)
- {
- redraw_screen();
- mesclr( true );
- }
-
- if (need_prompt)
- mpr( prompt, MSGCH_PROMPT );
-
- if (need_getch)
- keyin = get_ch();
-
- need_redraw = false;
- need_prompt = true;
- need_getch = true;
-
- // Note: We handle any "special" character first, so that
- // it can be used to override the others.
- if (other_valid_char != '\0' && keyin == other_valid_char)
- {
- ret = PROMPT_GOT_SPECIAL;
- break;
- }
- else if (keyin == '?' || keyin == '*' || keyin == ',')
- {
- int selmode = Options.drop_mode == DM_SINGLE?
- MF_SINGLESELECT | MF_EASY_EXIT | MF_ANYPRINTABLE :
- MF_MULTISELECT;
- // The "view inventory listing" mode.
- int ch = invent_select(
- keyin == '*'? -1 : type_expect,
- selmode | MF_SELECT_ANY_PAGE,
- titlefn, &items, select_filter, fn );
-
- if (selmode & MF_SINGLESELECT)
- {
- keyin = ch;
- need_getch = false;
- }
- else
- {
- keyin = 0;
- need_getch = true;
- }
-
- if (items.size())
- {
- redraw_screen();
- mesclr( true );
-
- for (int i = 0, count = items.size(); i < count; ++i)
- items[i].slot = letter_to_index( items[i].slot );
- return items;
- }
-
- need_redraw = !(keyin == '?' || keyin == '*'
- || keyin == ',' || keyin == '+');
- need_prompt = need_redraw;
- }
- else if (isdigit( keyin ))
- {
- // The "read in quantity" mode
- keyin = get_invent_quant( keyin, count );
-
- need_prompt = false;
- need_getch = false;
- }
- else if (keyin == ESCAPE
- || (Options.easy_quit_item_prompts
- && allow_easy_quit
- && keyin == ' '))
- {
- ret = PROMPT_ABORT;
- break;
- }
- else if (isalpha( keyin ))
- {
- ret = letter_to_index( keyin );
-
- if (!is_valid_item( you.inv[ret] ))
- mpr( "You do not have any such object." );
- else
- break;
- }
- else if (!isspace( keyin ))
- {
- // we've got a character we don't understand...
- canned_msg( MSG_HUH );
- }
- }
-
- if (ret != PROMPT_ABORT)
- items.push_back( SelItem( ret, count ) );
- return items;
-}
-
-// This function prompts the user for an item, handles the '?' and '*'
-// listings, and returns the inventory slot to the caller (which if
-// must_exist is true (the default) will be an assigned item, with
-// a positive quantity.
-//
-// It returns PROMPT_ABORT if the player hits escape.
-// It returns PROMPT_GOT_SPECIAL if the player hits the "other_valid_char".
-//
-// Note: This function never checks if the item is appropriate.
-int prompt_invent_item( const char *prompt, int type_expect,
- bool must_exist, bool allow_auto_list,
- bool allow_easy_quit,
- const char other_valid_char,
- int *const count )
-{
- unsigned char keyin = 0;
- int ret = -1;
-
- bool need_redraw = false;
- bool need_prompt = true;
- bool need_getch = true;
-
- if (Options.auto_list && allow_auto_list)
- {
- std::vector< SelItem > items;
-
- // pretend the player has hit '?' and setup state.
- keyin = invent_select( type_expect,
- MF_SINGLESELECT | MF_ANYPRINTABLE
- | MF_EASY_EXIT,
- NULL, &items );
-
- if (items.size())
- {
- if (count)
- *count = items[0].quantity;
- redraw_screen();
- mesclr( true );
- return letter_to_index( keyin );
- }
-
- need_getch = false;
-
- // Don't redraw if we're just going to display another listing
- need_redraw = (keyin != '?' && keyin != '*');
-
- // A prompt is nice for when we're moving to "count" mode.
- need_prompt = (count != NULL && isdigit( keyin ));
- }
-
- for (;;)
- {
- if (need_redraw)
- {
- redraw_screen();
- mesclr( true );
- }
-
- if (need_prompt)
- mpr( prompt, MSGCH_PROMPT );
-
- if (need_getch)
- keyin = get_ch();
-
- need_redraw = false;
- need_prompt = true;
- need_getch = true;
-
- // Note: We handle any "special" character first, so that
- // it can be used to override the others.
- if (other_valid_char != '\0' && keyin == other_valid_char)
- {
- ret = PROMPT_GOT_SPECIAL;
- break;
- }
- else if (keyin == '?' || keyin == '*')
- {
- // The "view inventory listing" mode.
- std::vector< SelItem > items;
- keyin = invent_select( keyin == '*'? OSEL_ANY : type_expect,
- MF_SINGLESELECT | MF_ANYPRINTABLE
- | MF_EASY_EXIT,
- NULL,
- &items );
-
- if (items.size())
- {
- if (count)
- *count = items[0].quantity;
- redraw_screen();
- mesclr( true );
- return letter_to_index( keyin );
- }
-
- need_getch = false;
-
- // Don't redraw if we're just going to display another listing
- need_redraw = (keyin != '?' && keyin != '*');
-
- // A prompt is nice for when we're moving to "count" mode.
- need_prompt = (count != NULL && isdigit( keyin ));
- }
- else if (count != NULL && isdigit( keyin ))
- {
- // The "read in quantity" mode
- keyin = get_invent_quant( keyin, *count );
-
- need_prompt = false;
- need_getch = false;
- }
- else if (keyin == ESCAPE
- || (Options.easy_quit_item_prompts
- && allow_easy_quit
- && keyin == ' '))
- {
- ret = PROMPT_ABORT;
- break;
- }
- else if (isalpha( keyin ))
- {
- ret = letter_to_index( keyin );
-
- if (must_exist && !is_valid_item( you.inv[ret] ))
- mpr( "You do not have any such object." );
- else
- break;
- }
- else if (!isspace( keyin ))
- {
- // we've got a character we don't understand...
- canned_msg( MSG_HUH );
- }
- }
-
- return (ret);
-}
-
-void list_commands(bool wizard)
-{
- const char *line;
- int j = 0;
-
-#ifdef DOS_TERM
- char buffer[4800];
-
- window(1, 1, 80, 25);
- gettext(1, 1, 80, 25, buffer);
-#endif
-
- clrscr();
-
- // BCR - Set to screen length - 1 to display the "more" string
- int moreLength = (get_number_of_lines() - 1) * 2;
-
- for (int i = 0; i < 500; i++)
- {
- if (wizard)
- line = wizard_string( i );
- else
- line = command_string( i );
-
- if (strlen( line ) != 0)
- {
- // BCR - If we've reached the end of the screen, clear
- if (j == moreLength)
- {
- gotoxy(2, j / 2 + 1);
- cprintf("More...");
- getch();
- clrscr();
- j = 0;
- }
-
- gotoxy( ((j % 2) ? 40 : 2), ((j / 2) + 1) );
- cprintf( line );
-
- j++;
- }
- }
-
- getch();
-
-#ifdef DOS_TERM
- puttext(1, 1, 80, 25, buffer);
-#endif
-
- return;
-} // end list_commands()
-
-const char *wizard_string( int i )
-{
- UNUSED( i );
-
-#ifdef WIZARD
- return((i == 10) ? "a : acquirement" :
- (i == 13) ? "A : set all skills to level" :
- (i == 15) ? "b : controlled blink" :
- (i == 20) ? "B : banish yourself to the Abyss" :
- (i == 30) ? "g : add a skill" :
- (i == 35) ? "G : remove all monsters" :
- (i == 40) ? "h/H : heal yourself (super-Heal)" :
- (i == 50) ? "i/I : identify/unidentify inventory":
- (i == 70) ? "l : make entrance to labyrinth" :
- (i == 80) ? "m/M : create monster by number/name":
- (i == 90) ? "o/%% : create an object" :
- (i == 100) ? "p : make entrance to pandemonium" :
- (i == 110) ? "x : gain an experience level" :
- (i == 115) ? "r : change character's species" :
- (i == 120) ? "s : gain 20000 skill points" :
- (i == 130) ? "S : set skill to level" :
- (i == 140) ? "t : tweak object properties" :
- (i == 150) ? "X : Receive a gift from Xom" :
- (i == 160) ? "z/Z : cast any spell by number/name":
- (i == 200) ? "$ : get 1000 gold" :
- (i == 210) ? "</> : create up/down staircase" :
- (i == 220) ? "u/d : shift up/down one level" :
- (i == 230) ? "~/\" : goto a level" :
- (i == 240) ? "( : create a feature" :
- (i == 250) ? "] : get a mutation" :
- (i == 260) ? "[ : get a demonspawn mutation" :
- (i == 270) ? ": : find branch" :
- (i == 280) ? "{ : magic mapping" :
- (i == 290) ? "^ : gain piety" :
- (i == 300) ? "_ : gain religion" :
- (i == 310) ? "\' : list items" :
- (i == 320) ? "? : list wizard commands" :
- (i == 330) ? "| : acquire all unrand artefacts" :
- (i == 340) ? "+ : turn item into random artefact" :
- (i == 350) ? "= : sum skill points"
- : "");
-
-#else
- return ("");
-#endif
-} // end wizard_string()
-
-const char *command_string( int i )
-{
- /*
- * BCR - Command printing, case statement
- * Note: The numbers in this case indicate the order in which the
- * commands will be printed out. Make sure none of these
- * numbers is greater than 500, because that is the limit.
- *
- * Arranged alpha lower, alpha upper, punctuation, ctrl.
- *
- */
-
- return((i == 10) ? "a : use special ability" :
- (i == 20) ? "d(#) : drop (exact quantity of) items" :
- (i == 30) ? "e : eat food" :
- (i == 40) ? "f : fire first available missile" :
- (i == 50) ? "i : inventory listing" :
- (i == 55) ? "m : check skills" :
- (i == 60) ? "o/c : open / close a door" :
- (i == 65) ? "p : pray" :
- (i == 70) ? "q : quaff a potion" :
- (i == 80) ? "r : read a scroll or book" :
- (i == 90) ? "s : search adjacent tiles" :
- (i == 100) ? "t : throw/shoot an item" :
- (i == 110) ? "v : view item description" :
- (i == 120) ? "w : wield an item" :
- (i == 130) ? "x : examine visible surroundings" :
- (i == 135) ? "z : zap a wand" :
- (i == 140) ? "A : list abilities/mutations" :
- (i == 141) ? "C : check experience" :
- (i == 142) ? "D : dissect a corpse" :
- (i == 145) ? "E : evoke power of wielded item" :
- (i == 150) ? "M : memorise a spell" :
- (i == 155) ? "O : overview of the dungeon" :
- (i == 160) ? "P/R : put on / remove jewellery" :
- (i == 165) ? "Q : quit without saving" :
- (i == 168) ? "S : save game and exit" :
- (i == 179) ? "V : version information" :
- (i == 200) ? "W/T : wear / take off armour" :
- (i == 210) ? "X : examine level map" :
- (i == 220) ? "Z : cast a spell" :
- (i == 240) ? ",/g : pick up items" :
- (i == 242) ? "./del: rest one turn" :
- (i == 250) ? "</> : ascend / descend a staircase" :
- (i == 270) ? "; : examine occupied tile" :
- (i == 280) ? "\\ : check item knowledge" :
-#ifdef WIZARD
- (i == 290) ? "& : invoke your Wizardly powers" :
-#endif
- (i == 300) ? "+/- : scroll up/down [level map only]" :
- (i == 310) ? "! : shout or command allies" :
- (i == 325) ? "^ : describe religion" :
- (i == 337) ? "@ : status" :
- (i == 340) ? "# : dump character to file" :
- (i == 350) ? "= : reassign inventory/spell letters" :
- (i == 360) ? "\' : wield item a, or switch to b" :
-#ifdef USE_MACROS
- (i == 380) ? "` : add macro" :
- (i == 390) ? "~ : save macros" :
-#endif
- (i == 400) ? "] : display worn armour" :
- (i == 410) ? "\" : display worn jewellery" :
- (i == 420) ? "Ctrl-P : see old messages" :
-#ifdef PLAIN_TERM
- (i == 430) ? "Ctrl-R : Redraw screen" :
-#endif
- (i == 440) ? "Ctrl-A : toggle autopickup" :
- (i == 450) ? "Ctrl-X : Save game without query" :
-
-#ifdef ALLOW_DESTROY_ITEM_COMMAND
- (i == 451) ? "Ctrl-D : Destroy inventory item" :
-#endif
- (i == 453) ? "Ctrl-G : interlevel travel" :
- (i == 455) ? "Ctrl-O : explore" :
-
-#ifdef STASH_TRACKING
- (i == 456) ? "Ctrl-S : mark stash" :
- (i == 457) ? "Ctrl-E : forget stash" :
- (i == 458) ? "Ctrl-F : search stashes" :
-#endif
-
- (i == 460) ? "Shift & DIR : long walk" :
- (i == 465) ? "/ DIR : long walk" :
- (i == 470) ? "Ctrl & DIR : door; untrap; attack" :
- (i == 475) ? "* DIR : door; untrap; attack" :
- (i == 478) ? "Shift & 5 on keypad : rest 100 turns"
- : "");
-} // end command_string()
diff --git a/stone_soup/crawl-ref/source/invent.h b/stone_soup/crawl-ref/source/invent.h
deleted file mode 100644
index 624e603fc1..0000000000
--- a/stone_soup/crawl-ref/source/invent.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * File: invent.cc
- * Summary: Functions for inventory related commands.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef INVENT_H
-#define INVENT_H
-
-#include <stddef.h>
-#include <vector>
-#include "menu.h"
-
-#define PROMPT_ABORT -1
-#define PROMPT_GOT_SPECIAL -2
-
-struct SelItem
-{
- int slot;
- int quantity;
- const item_def *item;
-
- SelItem() : slot(0), quantity(0), item(NULL) { }
- SelItem( int s, int q, const item_def *it = NULL )
- : slot(s), quantity(q), item(it)
- {
- }
-};
-
-
-int prompt_invent_item( const char *prompt, int type_expect,
- bool must_exist = true,
- bool allow_auto_list = true,
- bool allow_easy_quit = true,
- const char other_valid_char = '\0',
- int *const count = NULL );
-
-std::vector<SelItem> select_items( std::vector<item_def*> &items,
- const char *title );
-
-std::vector<SelItem> prompt_invent_items(
- const char *prompt,
- int type_expect,
- std::string (*titlefn)( int menuflags,
- const std::string &oldt )
- = NULL,
- bool allow_auto_list = true,
- bool allow_easy_quit = true,
- const char other_valid_char = '\0',
- std::vector<text_pattern> *filter = NULL,
- Menu::selitem_tfn fn = NULL );
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: invent - ouch - shopping
- * *********************************************************************** */
-unsigned char invent( int item_class_inv, bool show_price );
-
-unsigned char invent_select(int item_class_inv,
- int select_flags = MF_NOSELECT,
- std::string (*titlefn)( int menuflags,
- const std::string &oldt )
- = NULL,
- std::vector<SelItem> *sels = NULL,
- std::vector<text_pattern> *filter = NULL,
- Menu::selitem_tfn fn = NULL );
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - command - food - item_use - items - spl-book - spells1
- * *********************************************************************** */
-unsigned char get_invent(int invent_type);
-
-bool in_inventory(const item_def &i);
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void list_commands(bool wizard);
-
-std::string item_class_name(int type, bool terse = false);
-
-void populate_item_menu( Menu *menu, const std::vector<item_def> &items,
- void (*callback)(MenuEntry *me) );
-
-#endif
diff --git a/stone_soup/crawl-ref/source/it_use2.cc b/stone_soup/crawl-ref/source/it_use2.cc
deleted file mode 100644
index d03abea16e..0000000000
--- a/stone_soup/crawl-ref/source/it_use2.cc
+++ /dev/null
@@ -1,523 +0,0 @@
-/*
- * File: it_use2.cc
- * Summary: Functions for using wands, potions, and weapon/armour removal.4\3
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * 26jun2000 jmf added ZAP_MAGMA
- * <4> 19mar2000 jmf Added ZAP_BACKLIGHT and ZAP_SLEEP
- * <3> 10/1/99 BCR Changed messages for speed and
- * made amulet resist slow up speed
- * <2> 5/20/99 BWR Fixed bug with RAP_METABOLISM
- * and RAP_NOISES artefacts/
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "it_use2.h"
-
-#include <stdio.h>
-#include <string.h>
-
-#include "externs.h"
-
-#include "beam.h"
-#include "effects.h"
-#include "food.h"
-#include "itemname.h"
-#include "misc.h"
-#include "mutation.h"
-#include "player.h"
-#include "randart.h"
-#include "religion.h"
-#include "skills2.h"
-#include "spells2.h"
-#include "spl-cast.h"
-#include "stuff.h"
-#include "view.h"
-
-// From an actual potion, pow == 40 -- bwr
-bool potion_effect( char pot_eff, int pow )
-{
- bool effect = true; // current behaviour is all potions id on quaffing
-
- int new_value = 0;
- unsigned char i;
-
- if (pow > 150)
- pow = 150;
-
- switch (pot_eff)
- {
- case POT_HEALING:
- mpr("You feel better.");
- inc_hp(5 + random2(7), false);
-
- // only fix rot when healed to full
- if (you.hp == you.hp_max)
- {
- unrot_hp(1);
- set_hp(you.hp_max, false);
- }
-
- you.poison = 0;
- you.rotting = 0;
- you.disease = 0;
- you.conf = 0;
- break;
-
- case POT_HEAL_WOUNDS:
- mpr("You feel much better.");
- inc_hp(10 + random2avg(28, 3), false);
-
- // only fix rot when healed to full
- if (you.hp == you.hp_max)
- {
- unrot_hp( 2 + random2avg(5, 2) );
- set_hp(you.hp_max, false);
- }
- break;
-
- case POT_SPEED:
- haste_player( 40 + random2(pow) );
- break;
-
- case POT_MIGHT:
- {
- bool were_mighty = (you.might > 0);
-
- if (!were_mighty)
- mpr( "You feel very mighty all of a sudden." );
- else
- {
- mpr( "You still feel pretty mighty." );
- contaminate_player(1);
- }
-
- // conceivable max gain of +184 {dlb}
- you.might += 35 + random2(pow);
-
- if (!were_mighty)
- modify_stat(STAT_STRENGTH, 5, true);
-
- // files.cc permits values up to 215, but ... {dlb}
- if (you.might > 80)
- you.might = 80;
-
- did_god_conduct( DID_STIMULANTS, 4 + random2(4) );
- }
- break;
-
- case POT_GAIN_STRENGTH:
- mutate(MUT_STRONG);
- break;
-
- case POT_GAIN_DEXTERITY:
- mutate(MUT_AGILE);
- break;
-
- case POT_GAIN_INTELLIGENCE:
- mutate(MUT_CLEVER);
- break;
-
- case POT_LEVITATION:
- strcpy(info, "You feel");
- strcat(info, (!player_is_levitating()) ? " very" : " more");
- strcat(info, " buoyant.");
- mpr(info);
-
- if (!player_is_levitating())
- mpr("You gently float upwards from the floor.");
-
- you.levitation += 25 + random2(pow);
-
- if (you.levitation > 100)
- you.levitation = 100;
-
- burden_change();
- break;
-
- case POT_POISON:
- case POT_STRONG_POISON:
- if (player_res_poison())
- {
- snprintf( info, INFO_SIZE, "You feel %s nauseous.",
- (pot_eff == POT_POISON) ? "slightly" : "quite" );
-
- mpr(info);
- }
- else
- {
- snprintf( info, INFO_SIZE, "That liquid tasted %s nasty...",
- (pot_eff == POT_POISON) ? "very" : "extremely" );
-
- mpr(info);
-
- poison_player( ((pot_eff == POT_POISON) ? 1 + random2avg(5, 2)
- : 3 + random2avg(13, 2)) );
- }
- break;
-
- case POT_SLOWING:
- slow_player( 10 + random2(pow) );
- break;
-
- case POT_PARALYSIS:
- snprintf( info, INFO_SIZE, "You %s the ability to move!",
- (you.paralysis) ? "still haven't" : "suddenly lose" );
-
- mpr( info, MSGCH_WARN );
-
- new_value = 2 + random2( 6 + you.paralysis );
-
- if (new_value > you.paralysis)
- you.paralysis = new_value;
-
- if (you.paralysis > 13)
- you.paralysis = 13;
- break;
-
- case POT_CONFUSION:
- confuse_player( 3 + random2(8) );
- break;
-
- case POT_INVISIBILITY:
- mpr( (!you.invis) ? "You fade into invisibility!"
- : "You feel safely hidden away." );
-
- // now multiple invisiblity casts aren't as good -- bwr
- if (!you.invis)
- you.invis = 15 + random2(pow);
- else
- you.invis += random2(pow);
-
- if (you.invis > 100)
- you.invis = 100;
- break;
-
- // carnivore check here? {dlb}
- case POT_PORRIDGE: // oatmeal - always gluggy white/grey?
- mpr("That potion was really gluggy!");
- lessen_hunger(6000, true);
- break;
-
- case POT_DEGENERATION:
- mpr("There was something very wrong with that liquid!");
- lose_stat(STAT_RANDOM, 1 + random2avg(4, 2));
- break;
-
- // Don't generate randomly - should be rare and interesting
- case POT_DECAY:
- if (you.is_undead)
- mpr( "You feel terrible." );
- else
- rot_player( 10 + random2(10) );
- break;
-
- case POT_WATER:
- mpr("This tastes like water.");
- // we should really separate thirst from hunger {dlb}
- // Thirst would just be annoying for the player, the
- // 20 points here doesn't represesent real food anyways -- bwr
- lessen_hunger(20, true);
- break;
-
- case POT_EXPERIENCE:
- if (you.experience_level < 27)
- {
- mpr("You feel more experienced!");
-
- you.experience = 1 + exp_needed( 2 + you.experience_level );
- level_change();
- }
- else
- mpr("A flood of memories washes over you.");
- break; // I'll let this slip past robe of archmagi
-
- case POT_MAGIC:
- mpr( "You feel magical!" );
- new_value = 5 + random2avg(19, 2);
-
- // increase intrinsic MP points
- if (you.magic_points + new_value > you.max_magic_points)
- {
- new_value = (you.max_magic_points - you.magic_points)
- + (you.magic_points + new_value - you.max_magic_points) / 4 + 1;
- }
-
- inc_mp( new_value, true );
- break;
-
- case POT_RESTORE_ABILITIES:
- // messaging taken care of within function {dlb}
- // not quite true... if no stat's are restore = no message, and
- // that's just confusing when trying out random potions (this one
- // still auto-identifies so we know what the effect is, but it
- // shouldn't require bringing up the descovery screen to do that -- bwr
- if (restore_stat(STAT_ALL, false) == false)
- mpr( "You feel refreshed." );
- break;
-
- case POT_BERSERK_RAGE:
- go_berserk(true);
- break;
-
- case POT_CURE_MUTATION:
- mpr("It has a very clean taste.");
- for (i = 0; i < 7; i++)
- {
- if (random2(10) > i)
- delete_mutation(100);
- }
- break;
-
- case POT_MUTATION:
- mpr("You feel extremely strange.");
- for (i = 0; i < 3; i++)
- {
- mutate(100, false);
- }
-
- did_god_conduct(DID_STIMULANTS, 4 + random2(4));
- break;
- }
-
- return (effect);
-} // end potion_effect()
-
-void unwield_item(char unw)
-{
- you.special_wield = SPWLD_NONE;
- you.wield_change = true;
-
- if (you.inv[unw].base_type == OBJ_WEAPONS)
- {
- if (is_fixed_artefact( you.inv[unw] ))
- {
- switch (you.inv[unw].special)
- {
- case SPWPN_SINGING_SWORD:
- mpr("The Singing Sword sighs.");
- break;
- case SPWPN_WRATH_OF_TROG:
- mpr("You feel less violent.");
- break;
- case SPWPN_SCYTHE_OF_CURSES:
- case SPWPN_STAFF_OF_OLGREB:
- you.inv[unw].plus = 0;
- you.inv[unw].plus2 = 0;
- break;
- case SPWPN_STAFF_OF_WUCAD_MU:
- you.inv[unw].plus = 0;
- you.inv[unw].plus2 = 0;
- miscast_effect( SPTYP_DIVINATION, 9, 90, 100, "the Staff of Wucad Mu" );
- break;
- default:
- break;
- }
-
- return;
- }
-
- int brand = get_weapon_brand( you.inv[unw] );
-
- if (is_random_artefact( you.inv[unw] ))
- unuse_randart(unw);
-
- if (brand != SPWPN_NORMAL)
- {
- char str_pass[ ITEMNAME_SIZE ];
- in_name(unw, DESC_CAP_YOUR, str_pass);
- strcpy(info, str_pass);
-
- switch (brand)
- {
- case SPWPN_SWORD_OF_CEREBOV:
- case SPWPN_FLAMING:
- strcat(info, " stops flaming.");
- mpr(info);
- break;
-
- case SPWPN_FREEZING:
- case SPWPN_HOLY_WRATH:
- strcat(info, " stops glowing.");
- mpr(info);
- break;
-
- case SPWPN_ELECTROCUTION:
- strcat(info, " stops crackling.");
- mpr(info);
- break;
-
- case SPWPN_VENOM:
- strcat(info, " stops dripping with poison.");
- mpr(info);
- break;
-
- case SPWPN_PROTECTION:
- mpr("You feel less protected.");
- you.redraw_armour_class = 1;
- break;
-
- case SPWPN_VAMPIRICISM:
- mpr("You feel the strange hunger wane.");
- break;
-
- /* case 8: draining
- case 9: speed, 10 slicing etc */
-
- case SPWPN_DISTORTION:
- // Removing the translocations skill reduction of effect,
- // it might seem sensible, but this brand is supposted
- // to be dangerous because it does large bonus damage,
- // as well as free teleport other side effects, and
- // even with the miscast effects you can rely on the
- // occasional spatial bonus to mow down some opponents.
- // It's far too powerful without a real risk, especially
- // if it's to be allowed as a player spell. -- bwr
-
- // int effect = 9 - random2avg( you.skills[SK_TRANSLOCATIONS] * 2, 2 );
- miscast_effect( SPTYP_TRANSLOCATION, 9, 90, 100, "a distortion effect" );
- break;
-
- // when more are added here, *must* duplicate unwielding
- // effect in vorpalise weapon scroll effect in read_scoll
- } // end switch
-
-
- if (you.duration[DUR_WEAPON_BRAND])
- {
- you.duration[DUR_WEAPON_BRAND] = 0;
- set_item_ego_type( you.inv[unw], OBJ_WEAPONS, SPWPN_NORMAL );
- mpr("Your branding evaporates.");
- }
- } // end if
- }
-
- if (player_equip( EQ_STAFF, STAFF_POWER ))
- {
- // XXX: Ugly hack so that thhis currently works (don't want to
- // mess with the fact that currently this function doesn't
- // actually unwield the item, but we need it out of the player's
- // hand for this to work. -- bwr
- int tmp = you.equip[ EQ_WEAPON ];
-
- you.equip[ EQ_WEAPON ] = -1;
- calc_mp();
- you.equip[ EQ_WEAPON ] = tmp;
- }
-
- return;
-} // end unwield_item()
-
-// This does *not* call ev_mod!
-void unwear_armour(char unw)
-{
- you.redraw_armour_class = 1;
- you.redraw_evasion = 1;
-
- switch (get_armour_ego_type( you.inv[unw] ))
- {
- case SPARM_RUNNING:
- mpr("You feel rather sluggish.");
- break;
-
- case SPARM_FIRE_RESISTANCE:
- mpr("\"Was it this warm in here before?\"");
- break;
-
- case SPARM_COLD_RESISTANCE:
- mpr("You catch a bit of a chill.");
- break;
-
- case SPARM_POISON_RESISTANCE:
- if (!player_res_poison())
- mpr("You feel less healthy.");
- break;
-
- case SPARM_SEE_INVISIBLE:
- if (!player_see_invis())
- mpr("You feel less perceptive.");
- break;
-
- case SPARM_DARKNESS: // I do not understand this {dlb}
- if (you.invis)
- you.invis = 1;
- break;
-
- case SPARM_STRENGTH:
- modify_stat(STAT_STRENGTH, -3, false);
- break;
-
- case SPARM_DEXTERITY:
- modify_stat(STAT_DEXTERITY, -3, false);
- break;
-
- case SPARM_INTELLIGENCE:
- modify_stat(STAT_INTELLIGENCE, -3, false);
- break;
-
- case SPARM_PONDEROUSNESS:
- mpr("That put a bit of spring back into your step.");
- // you.speed -= 2;
- break;
-
- case SPARM_LEVITATION:
- //you.levitation++;
- if (you.levitation)
- you.levitation = 1;
- break;
-
- case SPARM_MAGIC_RESISTANCE:
- mpr("You feel less resistant to magic.");
- break;
-
- case SPARM_PROTECTION:
- mpr("You feel less protected.");
- break;
-
- case SPARM_STEALTH:
- mpr("You feel less stealthy.");
- break;
-
- case SPARM_RESISTANCE:
- mpr("You feel hot and cold all over.");
- break;
-
- case SPARM_POSITIVE_ENERGY:
- mpr("You feel vulnerable.");
- break;
-
- case SPARM_ARCHMAGI:
- mpr("You feel strangely numb.");
- break;
- }
-
- if (is_random_artefact( you.inv[unw] ))
- unuse_randart(unw);
-
- return;
-} // end unwear_armour()
-
-void unuse_randart(unsigned char unw)
-{
- ASSERT( is_random_artefact( you.inv[unw] ) );
-
- FixedVector< char, RA_PROPERTIES > proprt;
- randart_wpn_properties( you.inv[unw], proprt );
-
- if (proprt[RAP_AC])
- you.redraw_armour_class = 1;
-
- if (proprt[RAP_EVASION])
- you.redraw_evasion = 1;
-
- // modify ability scores
- modify_stat( STAT_STRENGTH, -proprt[RAP_STRENGTH], true );
- modify_stat( STAT_INTELLIGENCE, -proprt[RAP_INTELLIGENCE], true );
- modify_stat( STAT_DEXTERITY, -proprt[RAP_DEXTERITY], true );
-
- if (proprt[RAP_NOISES] != 0)
- you.special_wield = SPWLD_NONE;
-} // end unuse_randart()
diff --git a/stone_soup/crawl-ref/source/it_use2.h b/stone_soup/crawl-ref/source/it_use2.h
deleted file mode 100644
index 2177b4083b..0000000000
--- a/stone_soup/crawl-ref/source/it_use2.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * File: it_use2.cc
- * Summary: Functions for using wands, potions, and weapon/armour removal.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef IT_USE2_H
-#define IT_USE2_H
-
-
-#include "externs.h"
-
-
-/* ***********************************************************************
- * called from: ability - beam - decks - item_use - misc - religion -
- * spell - spells - spells1
- * *********************************************************************** */
-bool potion_effect(char pot_eff, int pow);
-
-
-/* ***********************************************************************
- * called from: item_use
- * *********************************************************************** */
-void unuse_randart(unsigned char unw);
-
-
-/* ***********************************************************************
- * called from: item_use - transfor
- * *********************************************************************** */
-void unwear_armour(char unw);
-
-
-/* ***********************************************************************
- * called from: decks - it_use3 - item_use - items - spells3 - transfor
- * *********************************************************************** */
-void unwield_item(char unw);
-
-#endif
diff --git a/stone_soup/crawl-ref/source/it_use3.cc b/stone_soup/crawl-ref/source/it_use3.cc
deleted file mode 100644
index 272cf8ba2b..0000000000
--- a/stone_soup/crawl-ref/source/it_use3.cc
+++ /dev/null
@@ -1,1067 +0,0 @@
-/*
- * File: it_use3.cc
- * Summary: Functions for using some of the wackier inventory items.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <4> 6/13/99 BWR Auto ID Channel staff
- * <3> 5/22/99 BWR SPWLD_POWER is now HP/13 - 3
- * <2> 5/20/99 BWR Capped SPWLD_POWER to +20
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "it_use3.h"
-
-#include <string.h>
-
-#include "externs.h"
-
-#include "beam.h"
-#include "decks.h"
-#include "direct.h"
-#include "effects.h"
-#include "fight.h"
-#include "food.h"
-#include "items.h"
-#include "it_use2.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "misc.h"
-#include "monplace.h"
-#include "monstuff.h"
-#include "player.h"
-#include "randart.h"
-#include "religion.h"
-#include "skills.h"
-#include "skills2.h"
-#include "spells1.h"
-#include "spells2.h"
-#include "spl-book.h"
-#include "spl-cast.h"
-#include "spl-util.h"
-#include "stuff.h"
-#include "view.h"
-#include "wpn-misc.h"
-
-static bool ball_of_energy(void);
-static bool ball_of_fixation(void);
-static bool ball_of_seeing(void);
-static bool box_of_beasts(void);
-static bool disc_of_storms(void);
-static bool efreet_flask(void);
-
-void special_wielded(void)
-{
- const int wpn = you.equip[EQ_WEAPON];
- const int old_plus = you.inv[wpn].plus;
- const int old_plus2 = you.inv[wpn].plus2;
- const char old_colour = you.inv[wpn].colour;
-
- char str_pass[ ITEMNAME_SIZE ];
- int temp_rand = 0; // for probability determination {dlb}
- bool makes_noise = (one_chance_in(20) && !silenced(you.x_pos, you.y_pos));
-
- switch (you.special_wield)
- {
- case SPWLD_SING:
- if (makes_noise)
- {
- strcpy(info, "The Singing Sword ");
- temp_rand = random2(32);
- strcat(info,
- (temp_rand == 0) ? "hums a little tune." :
- (temp_rand == 1) ? "breaks into glorious song!" :
- (temp_rand == 2) ? "sings." :
- (temp_rand == 3) ? "sings loudly." :
- (temp_rand == 4) ? "chimes melodiously." :
- (temp_rand == 5) ? "makes a horrible noise." :
- (temp_rand == 6) ? "sings off-key." :
- (temp_rand == 7) ? "sings 'tra-la-la'." :
- (temp_rand == 8) ? "burbles away merrily." :
- (temp_rand == 9) ? "gurgles." :
- (temp_rand == 10) ? "suddenly shrieks!" :
- (temp_rand == 11) ? "cackles." :
- (temp_rand == 12) ? "warbles." :
- (temp_rand == 13) ? "chimes harmoniously." :
- (temp_rand == 14) ? "makes beautiful music." :
- (temp_rand == 15) ? "produces a loud orchestral chord." :
- (temp_rand == 16) ? "whines plaintively." :
- (temp_rand == 17) ? "tinkles." :
- (temp_rand == 18) ? "rings like a bell." :
- (temp_rand == 19) ? "wails mournfully." :
- (temp_rand == 20) ? "practices its scales." :
- (temp_rand == 21) ? "lilts tunefully." :
- (temp_rand == 22) ? "hums tunelessly." :
- (temp_rand == 23) ? "sighs." :
- (temp_rand == 24) ? "makes a deep moaning sound." :
- (temp_rand == 25) ? "makes a popping sound." :
- (temp_rand == 26) ? "sings a sudden staccato note." :
- (temp_rand == 27) ? "says 'Hi! I'm the Singing Sword!'." :
- (temp_rand == 28) ? "whispers something." :
- (temp_rand == 29) ? "speaks gibberish." :
- (temp_rand == 30) ? "raves incoherently."
- : "yells in some weird language.");
- mpr(info, MSGCH_SOUND);
- }
- break;
-
- case SPWLD_CURSE:
- makes_noise = false;
-
- if (one_chance_in(30))
- curse_an_item(0, 0);
- break;
-
- case SPWLD_VARIABLE:
- makes_noise = false;
-
- do_uncurse_item( you.inv[wpn] );
-
- if (random2(5) < 2) // 40% chance {dlb}
- you.inv[wpn].plus += (coinflip() ? +1 : -1);
-
- if (random2(5) < 2) // 40% chance {dlb}
- you.inv[wpn].plus2 += (coinflip() ? +1 : -1);
-
- if (you.inv[wpn].plus < -4)
- you.inv[wpn].plus = -4;
- else if (you.inv[wpn].plus > 16)
- you.inv[wpn].plus = 16;
-
- if (you.inv[wpn].plus2 < -4)
- you.inv[wpn].plus2 = -4;
- else if (you.inv[wpn].plus2 > 16)
- you.inv[wpn].plus2 = 16;
-
- you.inv[wpn].colour = random_colour();
- break;
-
- case SPWLD_TORMENT:
- makes_noise = false;
-
- if (one_chance_in(200))
- {
- torment( you.x_pos, you.y_pos );
- did_god_conduct( DID_UNHOLY, 1 );
- }
- break;
-
- case SPWLD_ZONGULDROK:
- makes_noise = false;
-
- if (one_chance_in(5))
- {
- animate_dead( 1 + random2(3), BEH_HOSTILE, MHITYOU, 1 );
- did_god_conduct( DID_NECROMANCY, 1 );
- }
- break;
-
- case SPWLD_POWER:
- makes_noise = false;
-
- you.inv[wpn].plus = stepdown_value( -4 + (you.hp / 5), 4, 4, 4, 20 );
- you.inv[wpn].plus2 = you.inv[wpn].plus;
- break;
-
- case SPWLD_OLGREB:
- makes_noise = false;
-
- // Giving Olgreb's staff a little lift since staves of poison have
- // been made better. -- bwr
- you.inv[wpn].plus = you.skills[SK_POISON_MAGIC] / 3;
- you.inv[wpn].plus2 = you.inv[wpn].plus;
- break;
-
- case SPWLD_WUCAD_MU:
- makes_noise = false;
-
- you.inv[wpn].plus = ((you.intel > 25) ? 22 : you.intel - 3);
- you.inv[wpn].plus2 = ((you.intel > 25) ? 13 : you.intel / 2);
- break;
-
- case SPWLD_SHADOW:
- makes_noise = false;
-
- if (random2(8) <= player_spec_death())
- {
- did_god_conduct( DID_NECROMANCY, 1 );
- create_monster( MONS_SHADOW, ENCH_ABJ_II, BEH_FRIENDLY,
- you.x_pos, you.y_pos, you.pet_target, 250 );
- }
-
- show_green = DARKGREY;
- break;
-
- case SPWLD_HUM:
- if (makes_noise)
- {
- in_name(wpn, DESC_CAP_YOUR, str_pass);
- strcpy(info, str_pass);
- strcat(info, " lets out a weird humming sound.");
- mpr(info, MSGCH_SOUND);
- }
- break; // to noisy() call at foot 2apr2000 {dlb}
-
- case SPWLD_CHIME:
- if (makes_noise)
- {
- in_name(wpn, DESC_CAP_YOUR, str_pass);
- strcpy(info, str_pass);
- strcat(info, " chimes like a gong.");
- mpr(info, MSGCH_SOUND);
- }
- break;
-
- case SPWLD_BECKON:
- if (makes_noise)
- mpr("You hear a voice call your name.", MSGCH_SOUND);
- break;
-
- case SPWLD_SHOUT:
- if (makes_noise)
- mpr("You hear a shout.", MSGCH_SOUND);
- break;
-
- //case SPWLD_PRUNE:
- default:
- return;
- }
-
- if (makes_noise)
- noisy( 25, you.x_pos, you.y_pos );
-
- if (old_plus != you.inv[wpn].plus
- || old_plus2 != you.inv[wpn].plus2
- || old_colour != you.inv[wpn].colour)
- {
- you.wield_change = true;
- }
-
- return;
-} // end special_wielded()
-
-static void reaching_weapon_attack(void)
-{
- struct dist beam;
- int x_distance, y_distance;
- int x_middle, y_middle;
- int skill;
-
- mpr("Attack whom?", MSGCH_PROMPT);
-
- direction( beam, DIR_TARGET, TARG_ENEMY );
- if (!beam.isValid)
- return;
-
- if (beam.isMe)
- {
- canned_msg(MSG_UNTHINKING_ACT);
- return;
- }
-
- x_distance = abs(beam.tx - you.x_pos);
- y_distance = abs(beam.ty - you.y_pos);
-
- if (x_distance > 2 || y_distance > 2)
- mpr("Your weapon cannot reach that far!");
- else if (mgrd[beam.tx][beam.ty] == NON_MONSTER)
- {
- mpr("You attack empty space.");
- }
- else
- {
- /* BCR - Added a check for monsters in the way. Only checks cardinal
- * directions. Knight moves are ignored. Assume the weapon
- * slips between the squares.
- */
-
- // if we're attacking more than a space away
- if ((x_distance > 1) || (y_distance > 1))
- {
-
-#define MAX(x,y) (((x) > (y)) ? (x) : (y))
- x_middle = MAX(beam.tx, you.x_pos) - (x_distance / 2);
- y_middle = MAX(beam.ty, you.y_pos) - (y_distance / 2);
-#undef MAX
-
- // if either the x or the y is the same, we should check for
- // a monster:
- if (((beam.tx == you.x_pos) || (beam.ty == you.y_pos))
- && (mgrd[x_middle][y_middle] != NON_MONSTER))
- {
- skill = weapon_skill( you.inv[you.equip[EQ_WEAPON]].base_type,
- you.inv[you.equip[EQ_WEAPON]].sub_type );
-
- if ((5 + (3 * skill)) > random2(100))
- {
- mpr("You reach to attack!");
- you_attack(mgrd[beam.tx][beam.ty], false);
- }
- else
- {
- mpr("You could not reach far enough!");
- you_attack(mgrd[x_middle][y_middle], false);
- }
- }
- else
- {
- mpr("You reach to attack!");
- you_attack(mgrd[beam.tx][beam.ty], false);
- }
- }
- else
- {
- you_attack(mgrd[beam.tx][beam.ty], false);
- }
- }
-
- return;
-} // end reaching_weapon_attack()
-
-// returns true if item successfully evoked.
-bool evoke_wielded( void )
-{
- char opened_gates = 0;
- unsigned char spell_casted = random2(21);
- int count_x, count_y;
- int temp_rand = 0; // for probability determination {dlb}
- int power = 0;
-
- int pract = 0;
- bool did_work = false; // used for default "nothing happens" message
-
- char str_pass[ ITEMNAME_SIZE ];
-
- int wield = you.equip[EQ_WEAPON];
-
- if (you.berserker)
- {
- canned_msg( MSG_TOO_BERSERK );
- return (false);
- }
- else if (wield == -1)
- {
- mpr("You aren't wielding anything!");
- return (false);
- }
-
- switch (you.inv[wield].base_type)
- {
- case OBJ_WEAPONS:
- if (get_weapon_brand( you.inv[wield] ) == SPWPN_REACHING
- && enough_mp(1, false))
- {
- // needed a cost to prevent evocation training abuse -- bwr
- dec_mp(1);
- make_hungry( 50, false );
- reaching_weapon_attack();
- pract = (one_chance_in(5) ? 1 : 0);
- did_work = true;
- }
- else if (is_fixed_artefact( you.inv[wield] ))
- {
- switch (you.inv[wield].special)
- {
- case SPWPN_STAFF_OF_DISPATER:
- if (you.deaths_door || !enough_hp(11, true)
- || !enough_mp(5, true))
- {
- break;
- }
-
- mpr("You feel the staff feeding on your energy!");
-
- dec_hp( 5 + random2avg(19, 2), false );
- dec_mp( 2 + random2avg(5, 2) );
- make_hungry( 100, false );
-
- power = you.skills[SK_EVOCATIONS] * 8;
- your_spells( SPELL_HELLFIRE, power, false );
- pract = (coinflip() ? 2 : 1);
- did_work = true;
- break;
-
- // let me count the number of ways spell_casted is
- // used here ... one .. two .. three ... >CRUNCH<
- // three licks to get to the center of a ... {dlb}
- case SPWPN_SCEPTRE_OF_ASMODEUS:
- spell_casted = random2(21);
-
- if (spell_casted == 0)
- break;
-
- make_hungry( 200, false );
- pract = 1;
-
- if (spell_casted < 2) // summon devils, maybe a Fiend
- {
-
- spell_casted = (one_chance_in(4) ? MONS_FIEND
- : MONS_HELLION + random2(10));
-
- bool good_summon = (create_monster( spell_casted,
- ENCH_ABJ_VI, BEH_HOSTILE,
- you.x_pos, you.y_pos,
- MHITYOU, 250) != -1);
-
- if (good_summon)
- {
- if (spell_casted == MONS_FIEND)
- mpr("\"Your arrogance condemns you, mortal!\"");
- else
- mpr("The Sceptre summons one of its servants.");
- }
-
- did_work = true;
- break;
- }
-
- temp_rand = random2(240);
-
- if (temp_rand > 125)
- spell_casted = SPELL_BOLT_OF_FIRE; // 114 in 240
- else if (temp_rand > 68)
- spell_casted = SPELL_LIGHTNING_BOLT; // 57 in 240
- else if (temp_rand > 11)
- spell_casted = SPELL_BOLT_OF_DRAINING; // 57 in 240
- else
- spell_casted = SPELL_HELLFIRE; // 12 in 240
-
- power = you.skills[SK_EVOCATIONS] * 8;
- your_spells( spell_casted, power, false );
- did_work = true;
- break;
-
- case SPWPN_STAFF_OF_OLGREB:
- if (!enough_mp( 4, true )
- || you.skills[SK_EVOCATIONS] < random2(6))
- {
- break;
- }
-
- dec_mp(4);
- make_hungry( 50, false );
- pract = 1;
- did_work = true;
-
- power = 10 + you.skills[SK_EVOCATIONS] * 8;
-
- your_spells( SPELL_OLGREBS_TOXIC_RADIANCE, power, false );
-
- if (you.skills[SK_EVOCATIONS] >= random2(10))
- your_spells( SPELL_VENOM_BOLT, power, false );
- break;
-
- case SPWPN_STAFF_OF_WUCAD_MU:
- if (you.magic_points == you.max_magic_points
- || you.skills[SK_EVOCATIONS] < random2(25))
- {
- break;
- }
-
- mpr("Magical energy flows into your mind!");
-
- inc_mp( 3 + random2(5) + you.skills[SK_EVOCATIONS] / 3, false );
- make_hungry( 50, false );
- pract = 1;
- did_work = true;
-
- if (one_chance_in(3))
- {
- miscast_effect( SPTYP_DIVINATION, random2(9),
- random2(70), 100, "the Staff of Wucad Mu" );
- }
- break;
-
- default:
- break;
- }
- }
- break;
-
- case OBJ_STAVES:
- if (item_is_rod( you.inv[wield] ))
- {
- pract = staff_spell( wield );
- did_work = true; // staff_spell() will handle messages
- }
- else if (you.inv[wield].sub_type == STAFF_CHANNELING)
- {
- if (you.magic_points < you.max_magic_points
- && you.skills[SK_EVOCATIONS] >= random2(30))
- {
- mpr("You channel some magical energy.");
- inc_mp( 1 + random2(3), false );
- make_hungry( 50, false );
- pract = (one_chance_in(5) ? 1 : 0);
- did_work = true;
-
- if (!item_ident( you.inv[you.equip[EQ_WEAPON]],
- ISFLAG_KNOW_TYPE ))
- {
- set_ident_flags( you.inv[you.equip[EQ_WEAPON]],
- ISFLAG_KNOW_TYPE );
-
- strcpy( info, "You are wielding " );
- in_name( you.equip[EQ_WEAPON], DESC_NOCAP_A, str_pass );
- strcat( info, str_pass );
- strcat( info, "." );
-
- mpr( info );
- more();
-
- you.wield_change = true;
- }
- }
- }
- break;
-
- case OBJ_MISCELLANY:
- did_work = true; // easier to do it this way for misc items
- switch (you.inv[wield].sub_type)
- {
- case MISC_BOTTLED_EFREET:
- if (efreet_flask())
- pract = 2;
- break;
-
- case MISC_CRYSTAL_BALL_OF_SEEING:
- if (ball_of_seeing())
- pract = 1;
- break;
-
- case MISC_AIR_ELEMENTAL_FAN:
- if (you.skills[SK_EVOCATIONS] <= random2(30))
- canned_msg(MSG_NOTHING_HAPPENS);
- else
- {
- summon_elemental(100, MONS_AIR_ELEMENTAL, 4);
- pract = (one_chance_in(5) ? 1 : 0);
- }
- break;
-
- case MISC_LAMP_OF_FIRE:
- if (you.skills[SK_EVOCATIONS] <= random2(30))
- canned_msg(MSG_NOTHING_HAPPENS);
- else
- {
- summon_elemental(100, MONS_FIRE_ELEMENTAL, 4);
- pract = (one_chance_in(5) ? 1 : 0);
- }
- break;
-
- case MISC_STONE_OF_EARTH_ELEMENTALS:
- if (you.skills[SK_EVOCATIONS] <= random2(30))
- canned_msg(MSG_NOTHING_HAPPENS);
- else
- {
- summon_elemental(100, MONS_EARTH_ELEMENTAL, 4);
- pract = (one_chance_in(5) ? 1 : 0);
- }
- break;
-
- case MISC_HORN_OF_GERYON:
- // Note: This assumes that the Vestibule has not been changed.
- if (player_in_branch( BRANCH_VESTIBULE_OF_HELL ))
- {
- mpr("You produce a weird and mournful sound.");
-
- for (count_x = 0; count_x < GXM; count_x++)
- {
- for (count_y = 0; count_y < GYM; count_y++)
- {
- if (grd[count_x][count_y] == DNGN_STONE_ARCH)
- {
- opened_gates++;
-
- // this may generate faulty [][] values {dlb}
- switch (grd[count_x + 2][count_y])
- {
- case DNGN_FLOOR:
- grd[count_x][count_y] = DNGN_ENTER_DIS;
- break;
- case DNGN_LAVA:
- grd[count_x][count_y] = DNGN_ENTER_GEHENNA;
- break;
- case DNGN_ROCK_WALL:
- grd[count_x][count_y] = DNGN_ENTER_TARTARUS;
- break;
- case DNGN_DEEP_WATER:
- grd[count_x][count_y] = DNGN_ENTER_COCYTUS;
- break;
- }
- }
- }
- }
-
- if (opened_gates)
- {
- mpr("Your way has been unbarred.");
- pract = 1;
- }
- }
- else
- {
- mpr("You produce a hideous howling noise!");
- pract = (one_chance_in(3) ? 1 : 0);
- create_monster( MONS_BEAST, ENCH_ABJ_IV, BEH_HOSTILE,
- you.x_pos, you.y_pos, MHITYOU, 250 );
- }
- break;
-
- case MISC_DECK_OF_WONDERS:
- deck_of_cards(DECK_OF_WONDERS);
- pract = 1;
- break;
-
- case MISC_DECK_OF_SUMMONINGS:
- deck_of_cards(DECK_OF_SUMMONING);
- pract = 1;
- break;
-
- case MISC_DECK_OF_TRICKS:
- deck_of_cards(DECK_OF_TRICKS);
- pract = 1;
- break;
-
- case MISC_DECK_OF_POWER:
- deck_of_cards(DECK_OF_POWER);
- pract = 1;
- break;
-
- case MISC_BOX_OF_BEASTS:
- if (box_of_beasts())
- pract = 1;
- break;
-
- case MISC_CRYSTAL_BALL_OF_ENERGY:
- if (ball_of_energy())
- pract = 1;
- break;
-
- case MISC_CRYSTAL_BALL_OF_FIXATION:
- if (ball_of_fixation())
- pract = 1;
- break;
-
- case MISC_DISC_OF_STORMS:
- if (disc_of_storms())
- pract = (coinflip() ? 2 : 1);
- break;
-
- case MISC_PORTABLE_ALTAR_OF_NEMELEX:
- if (player_in_branch( BRANCH_ECUMENICAL_TEMPLE ))
- {
- mpr( "Don't you think this level already has more than "
- "enough altars?" );
- }
- else if (grd[you.x_pos][you.y_pos] != DNGN_FLOOR)
- mpr("You need a clear area to place this item.");
- else
- {
- mpr("You unfold the altar and place it on the floor.");
- grd[you.x_pos][you.y_pos] = DNGN_ALTAR_NEMELEX_XOBEH;
- dec_inv_item_quantity( you.equip[EQ_WEAPON], 1 );
- }
- break;
-
- default:
- did_work = false;
- break;
- }
- break;
-
- default:
- break;
- }
-
- if (!did_work)
- canned_msg(MSG_NOTHING_HAPPENS);
- else if (pract > 0)
- exercise( SK_EVOCATIONS, pract );
-
- you.turn_is_over = 1;
-
- return (did_work);
-} // end evoke_wielded()
-
-static bool efreet_flask(void)
-{
- const int behaviour = ((you.skills[SK_EVOCATIONS] > random2(20))
- ? BEH_FRIENDLY : BEH_HOSTILE);
-
- mpr("You open the flask...");
-
- dec_inv_item_quantity( you.equip[EQ_WEAPON], 1 );
-
- if (create_monster( MONS_EFREET, ENCH_ABJ_V, behaviour,
- you.x_pos, you.y_pos, MHITYOU, 250 ) != -1)
- {
- mpr( "...and a huge efreet comes out." );
-
- mpr( (behaviour == BEH_FRIENDLY) ? "\"Thank you for releasing me!\""
- : "It howls insanely!" );
- }
- else
- canned_msg(MSG_NOTHING_HAPPENS);
-
- return (true);
-} // end efreet_flask()
-
-static bool ball_of_seeing(void)
-{
- int use = 0;
- bool ret = false;
-
- mpr("You gaze into the crystal ball.");
-
- use = ((!you.conf) ? random2(you.skills[SK_EVOCATIONS] * 6) : random2(5));
-
- if (use < 2)
- {
- lose_stat( STAT_INTELLIGENCE, 1 );
- }
- else if (use < 5 && enough_mp(1, true))
- {
- mpr("You feel power drain from you!");
- set_mp(0, false);
- }
- else if (use < 10)
- {
- confuse_player( 10 + random2(10), false );
- }
- else if (use < 15
- || you.level_type == LEVEL_LABYRINTH
- || you.level_type == LEVEL_ABYSS || coinflip())
- {
- mpr("You see nothing.");
- }
- else
- {
- mpr("You see a map of your surroundings!");
- magic_mapping( 15, 50 + random2( you.skills[SK_EVOCATIONS] ) );
- ret = true;
- }
-
- return (ret);
-} // end ball_of_seeing()
-
-static bool disc_of_storms(void)
-{
- int temp_rand = 0; // probability determination {dlb}
- struct bolt beam;
- int disc_count = 0;
- unsigned char which_zap = 0;
-
- const int fail_rate = (30 - you.skills[SK_EVOCATIONS]);
- bool ret = false;
-
- if (player_res_electricity() || (random2(100) < fail_rate))
- canned_msg(MSG_NOTHING_HAPPENS);
- else if (random2(100) < fail_rate)
- mpr("The disc glows for a moment, then fades.");
- else if (random2(100) < fail_rate)
- mpr("Little bolts of electricity crackle over the disc.");
- else
- {
- mpr("The disc erupts in an explosion of electricity!");
-
- disc_count = roll_dice( 2, 1 + you.skills[SK_EVOCATIONS] / 7 );
-
- while (disc_count)
- {
- temp_rand = random2(3);
-
- which_zap = ((temp_rand > 1) ? ZAP_LIGHTNING :
- (temp_rand > 0) ? ZAP_ELECTRICITY
- : ZAP_ORB_OF_ELECTRICITY);
-
- beam.source_x = you.x_pos;
- beam.source_y = you.y_pos;
- beam.target_x = you.x_pos + random2(13) - 6;
- beam.target_y = you.y_pos + random2(13) - 6;
-
- zapping( which_zap, 30 + you.skills[SK_EVOCATIONS] * 2, beam );
-
- disc_count--;
- }
-
- ret = true;
- }
-
- return (ret);
-} // end disc_of_storms()
-
-void tome_of_power(char sc_read_2)
-{
- int temp_rand = 0; // probability determination {dlb}
-
- int powc = 5 + you.skills[SK_EVOCATIONS]
- + roll_dice( 5, you.skills[SK_EVOCATIONS] );
-
- int spell_casted = 0;
- struct bolt beam;
-
- strcpy(info, "The book opens to a page covered in ");
-
- char wc[30];
- weird_writing( wc );
- strcat( info, wc );
- strcat( info, "." );
- mpr( info );
-
- you.turn_is_over = 1;
-
- if (!yesno("Read it?"))
- return;
-
- set_ident_flags( you.inv[sc_read_2], ISFLAG_IDENT_MASK );
-
- if (you.mutation[MUT_BLURRY_VISION] > 0
- && random2(4) < you.mutation[MUT_BLURRY_VISION])
- {
- mpr("The page is too blurry for you to read.");
- return;
- }
-
- mpr("You find yourself reciting the magical words!");
- exercise( SK_EVOCATIONS, 1 );
-
- temp_rand = random2(50) + random2( you.skills[SK_EVOCATIONS] / 3 );
-
- switch (random2(50))
- {
- case 0:
- case 3:
- case 4:
- case 6:
- case 7:
- case 8:
- case 9:
- mpr("A cloud of weird smoke pours from the book's pages!");
- big_cloud( CLOUD_GREY_SMOKE + random2(3), you.x_pos, you.y_pos, 20,
- 10 + random2(8) );
- return;
- case 1:
- case 14:
- mpr("A cloud of choking fumes pours from the book's pages!");
- big_cloud(CLOUD_POISON, you.x_pos, you.y_pos, 20, 7 + random2(5));
- return;
-
- case 2:
- case 13:
- mpr("A cloud of freezing gas pours from the book's pages!");
- big_cloud(CLOUD_COLD, you.x_pos, you.y_pos, 20, 8 + random2(5));
- return;
-
- case 5:
- case 11:
- case 12:
- if (one_chance_in(5))
- {
- mpr("The book disappears in a mighty explosion!");
- dec_inv_item_quantity( sc_read_2, 1 );
- }
-
- beam.type = SYM_BURST;
- beam.damage = dice_def( 3, 15 );
- // unsure about this // BEAM_EXPLOSION instead? [dlb]
- beam.flavour = BEAM_FIRE;
- beam.target_x = you.x_pos;
- beam.target_y = you.y_pos;
- strcpy( beam.beam_name, "fiery explosion" );
- beam.colour = RED;
- // your explosion, (not someone else's explosion)
- beam.beam_source = NON_MONSTER;
- beam.thrower = KILL_YOU;
- beam.aux_source = "an exploding Tome of Power";
- beam.ex_size = 2;
- beam.is_tracer = false;
- beam.is_explosion = true;
-
- explosion(beam);
- return;
-
-
- case 10:
- if (create_monster( MONS_ABOMINATION_SMALL, ENCH_ABJ_VI, BEH_HOSTILE,
- you.x_pos, you.y_pos, MHITYOU, 250 ) != -1)
- {
- mpr("A horrible Thing appears!");
- mpr("It doesn't look too friendly.");
- }
- return;
- }
-
- viewwindow(1, false);
-
- temp_rand = random2(23) + random2( you.skills[SK_EVOCATIONS] / 3 );
-
- if (temp_rand > 25)
- temp_rand = 25;
-
- spell_casted = ((temp_rand > 19) ? SPELL_FIREBALL :
- (temp_rand > 16) ? SPELL_BOLT_OF_FIRE :
- (temp_rand > 13) ? SPELL_BOLT_OF_COLD :
- (temp_rand > 11) ? SPELL_LIGHTNING_BOLT :
- (temp_rand > 10) ? SPELL_LEHUDIBS_CRYSTAL_SPEAR :
- (temp_rand > 9) ? SPELL_VENOM_BOLT :
- (temp_rand > 8) ? SPELL_BOLT_OF_DRAINING :
- (temp_rand > 7) ? SPELL_BOLT_OF_INACCURACY :
- (temp_rand > 6) ? SPELL_STICKY_FLAME :
- (temp_rand > 5) ? SPELL_TELEPORT_SELF :
- (temp_rand > 4) ? SPELL_CIGOTUVIS_DEGENERATION :
- (temp_rand > 3) ? SPELL_POLYMORPH_OTHER :
- (temp_rand > 2) ? SPELL_MEPHITIC_CLOUD :
- (temp_rand > 1) ? SPELL_THROW_FLAME :
- (temp_rand > 0) ? SPELL_THROW_FROST
- : SPELL_MAGIC_DART);
-
- your_spells( spell_casted, powc, false );
-} // end tome_of_power()
-
-void skill_manual(char sc_read_2)
-{
- char skname[30];
-
- set_ident_flags( you.inv[sc_read_2], ISFLAG_IDENT_MASK );
-
- strcpy(skname, skill_name(you.inv[sc_read_2].plus));
-
- strcpy(info, "This is a manual of ");
- strcat(info, skname);
- strcat(info, "!");
- mpr(info);
-
- you.turn_is_over = 1;
-
- if (!yesno("Read it?"))
- return;
-
- strcpy(info, "You read about ");
- strcat(info, strlwr(skname));
- strcat(info, ".");
- mpr(info);
-
- exercise( you.inv[sc_read_2].plus, 500 );
-
- if (one_chance_in(10))
- {
- mpr("The book crumbles into dust.");
- dec_inv_item_quantity( sc_read_2, 1 );
- }
- else
- {
- mpr("The book looks somewhat more worn.");
- }
-} // end skill_manual()
-
-static bool box_of_beasts(void)
-{
- int beasty = MONS_PROGRAM_BUG; // error trapping {dlb}
- int temp_rand = 0; // probability determination {dlb}
-
- int ret = false;
-
- mpr("You open the lid...");
-
- if (random2(100) < 60 + you.skills[SK_EVOCATIONS])
- {
- temp_rand = random2(11);
-
- beasty = ((temp_rand == 0) ? MONS_GIANT_BAT :
- (temp_rand == 1) ? MONS_HOUND :
- (temp_rand == 2) ? MONS_JACKAL :
- (temp_rand == 3) ? MONS_RAT :
- (temp_rand == 4) ? MONS_ICE_BEAST :
- (temp_rand == 5) ? MONS_SNAKE :
- (temp_rand == 6) ? MONS_YAK :
- (temp_rand == 7) ? MONS_BUTTERFLY :
- (temp_rand == 8) ? MONS_HELL_HOUND :
- (temp_rand == 9) ? MONS_BROWN_SNAKE
- : MONS_GIANT_LIZARD);
-
- int beh = (one_chance_in(you.skills[SK_EVOCATIONS] + 5) ? BEH_HOSTILE
- : BEH_FRIENDLY);
-
- if (create_monster( beasty, ENCH_ABJ_II + random2(4), beh,
- you.x_pos, you.y_pos, MHITYOU, 250 ) != -1)
- {
- mpr("...and something leaps out!");
- ret = true;
- }
- }
- else
- {
- if (!one_chance_in(6))
- mpr("...but nothing happens.");
- else
- {
- mpr("...but the box appears empty.");
- you.inv[you.equip[EQ_WEAPON]].sub_type = MISC_EMPTY_EBONY_CASKET;
- }
- }
-
- return (ret);
-} // end box_of_beasts()
-
-static bool ball_of_energy(void)
-{
- int use = 0;
- int proportional = 0;
-
- bool ret = false;
-
- mpr("You gaze into the crystal ball.");
-
- use = ((!you.conf) ? random2(you.skills[SK_EVOCATIONS] * 6) : random2(6));
-
- if (use < 2 || you.max_magic_points == 0)
- {
- lose_stat(STAT_INTELLIGENCE, 1);
- }
- else if ((use < 4 && enough_mp(1, true))
- || you.magic_points == you.max_magic_points)
- {
- mpr( "You feel your power drain away!" );
- set_mp( 0, false );
- }
- else if (use < 6)
- {
- confuse_player( 10 + random2(10), false );
- }
- else
- {
- proportional = you.magic_points * 100;
- proportional /= you.max_magic_points;
-
- if (random2avg(77 - you.skills[SK_EVOCATIONS] * 2, 4) > proportional
- || one_chance_in(25))
- {
- mpr( "You feel your power drain away!" );
- set_mp( 0, false );
- }
- else
- {
- mpr( "You are suffused with power!" );
- inc_mp( 6 + roll_dice( 2, you.skills[SK_EVOCATIONS] ), false );
-
- ret = true;
- }
- }
-
- return (ret);
-} // end ball_of_energy()
-
-static bool ball_of_fixation(void)
-{
- mpr("You gaze into the crystal ball.");
- mpr("You are mesmerised by a rainbow of scintillating colours!");
-
- you.paralysis = 100;
- you.slow = 100;
-
- return (true);
-} // end ball_of_fixation()
diff --git a/stone_soup/crawl-ref/source/it_use3.h b/stone_soup/crawl-ref/source/it_use3.h
deleted file mode 100644
index 2e5efae7c3..0000000000
--- a/stone_soup/crawl-ref/source/it_use3.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * File: it_use3.cc
- * Summary: Functions for using some of the wackier inventory items.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef IT_USE3_H
-#define IT_USE3_H
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: item_use
- * *********************************************************************** */
-void skill_manual(char sc_read_2);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: item_use - spl-book
- * *********************************************************************** */
-void tome_of_power(char sc_read_2);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-bool evoke_wielded(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void special_wielded(void);
-
-
-#endif
diff --git a/stone_soup/crawl-ref/source/item_use.cc b/stone_soup/crawl-ref/source/item_use.cc
deleted file mode 100644
index c1b37124ab..0000000000
--- a/stone_soup/crawl-ref/source/item_use.cc
+++ /dev/null
@@ -1,3289 +0,0 @@
-/*
- * File: item_use.cc
- * Summary: Functions for making use of inventory items.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <8> 28July2000 GDL Revised player throwing
- * <7> 11/23/99 LRH Horned characters can wear hats/caps
- * <6> 7/13/99 BWR Lowered learning rates for
- * throwing skills, and other
- * balance tweaks
- * <5> 5/28/99 JDJ Changed wear_armour to allow Spriggans to
- * wear bucklers.
- * <4> 5/26/99 JDJ body armour can be removed and worn if an
- * uncursed cloak is being worn.
- * Removed lots of unnessary mpr string copying.
- * Added missing ponderous message.
- * <3> 5/20/99 BWR Fixed staff of air bug, output of trial
- * identified items, a few you.wield_changes so
- * that the weapon gets updated.
- * <2> 5/08/99 JDJ Added armour_prompt.
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "item_use.h"
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "externs.h"
-
-#include "beam.h"
-#include "debug.h"
-#include "delay.h"
-#include "describe.h"
-#include "direct.h"
-#include "effects.h"
-#include "fight.h"
-#include "food.h"
-#include "invent.h"
-#include "it_use2.h"
-#include "it_use3.h"
-#include "items.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "misc.h"
-#include "monplace.h"
-#include "monstuff.h"
-#include "mstuff2.h"
-#include "mon-util.h"
-#include "ouch.h"
-#include "player.h"
-#include "randart.h"
-#include "religion.h"
-#include "skills.h"
-#include "skills2.h"
-#include "spells1.h"
-#include "spells2.h"
-#include "spells3.h"
-#include "spl-book.h"
-#include "spl-cast.h"
-#include "stuff.h"
-#include "transfor.h"
-#include "view.h"
-#include "wpn-misc.h"
-
-bool drink_fountain(void);
-void use_randart(unsigned char item_wield_2);
-static bool enchant_armour( void );
-
-// Rather messy - we've gathered all the can't-wield logic from wield_weapon()
-// here.
-bool can_wield(const item_def& weapon)
-{
- if (you.berserker) return false;
- if (you.attribute[ATTR_TRANSFORMATION] != TRAN_NONE
- && !can_equip( EQ_WEAPON ))
- return false;
-
- if (you.equip[EQ_WEAPON] != -1
- && you.inv[you.equip[EQ_WEAPON]].base_type == OBJ_WEAPONS
- && item_cursed( you.inv[you.equip[EQ_WEAPON]] ))
- return false;
-
- if (weapon.base_type != OBJ_WEAPONS && weapon.base_type == OBJ_STAVES
- && you.equip[EQ_SHIELD] != -1)
- return false;
-
- if ((you.species < SP_OGRE || you.species > SP_OGRE_MAGE)
- && item_mass( weapon ) >= 500)
- return false;
-
- if ((you.species == SP_HALFLING || you.species == SP_GNOME
- || you.species == SP_KOBOLD || you.species == SP_SPRIGGAN)
- && (weapon.sub_type == WPN_GREAT_SWORD
- || weapon.sub_type == WPN_TRIPLE_SWORD
- || weapon.sub_type == WPN_GREAT_MACE
- || weapon.sub_type == WPN_DIRE_FLAIL
- || weapon.sub_type == WPN_BATTLEAXE
- || weapon.sub_type == WPN_EXECUTIONERS_AXE
- || weapon.sub_type == WPN_LOCHABER_AXE
- || weapon.sub_type == WPN_HALBERD
- || weapon.sub_type == WPN_GLAIVE
- || weapon.sub_type == WPN_GIANT_CLUB
- || weapon.sub_type == WPN_GIANT_SPIKED_CLUB
- || weapon.sub_type == WPN_LONGBOW
- || weapon.sub_type == WPN_SCYTHE))
- return false;
-
- if (hands_reqd_for_weapon( weapon.base_type,
- weapon.sub_type ) == HANDS_TWO
- && you.equip[EQ_SHIELD] != -1)
- return false;
-
- int weap_brand = get_weapon_brand( weapon );
- if ((you.is_undead || you.species == SP_DEMONSPAWN)
- && (!is_fixed_artefact( weapon )
- && (weap_brand == SPWPN_HOLY_WRATH
- || weap_brand == SPWPN_DISRUPTION
- || (weapon.base_type == OBJ_WEAPONS
- && weapon.sub_type == WPN_BLESSED_BLADE))))
- return false;
-
- // We can wield this weapon. Phew!
- return true;
-}
-
-bool wield_weapon(bool auto_wield, int slot, bool show_weff_messages)
-{
- int item_slot = 0;
- char str_pass[ ITEMNAME_SIZE ];
-
- if (inv_count() < 1)
- {
- canned_msg(MSG_NOTHING_CARRIED);
- return (false);
- }
-
- if (you.berserker)
- {
- canned_msg(MSG_TOO_BERSERK);
- return (false);
- }
-
- if (you.attribute[ATTR_TRANSFORMATION] != TRAN_NONE)
- {
- if (!can_equip( EQ_WEAPON ))
- {
- mpr("You can't wield anything in your present form.");
- return (false);
- }
- }
-
- if (you.equip[EQ_WEAPON] != -1
- && you.inv[you.equip[EQ_WEAPON]].base_type == OBJ_WEAPONS
- && item_cursed( you.inv[you.equip[EQ_WEAPON]] ))
- {
- mpr("You can't unwield your weapon to draw a new one!");
- return (false);
- }
-
- if (you.sure_blade)
- {
- mpr("The bond with your blade fades away.");
- you.sure_blade = 0;
- }
-
- if (auto_wield)
- {
- if (you.equip[EQ_WEAPON] == 0) // ie. weapon is currently 'a'
- item_slot = 1;
- else
- item_slot = 0;
- if (slot != -1) item_slot = slot;
- }
-
- bool force_unwield =
- you.inv[item_slot].base_type != OBJ_WEAPONS
- && you.inv[item_slot].base_type != OBJ_MISSILES
- && you.inv[item_slot].base_type != OBJ_STAVES;
-
- // Prompt if not using the auto swap command,
- // or if the swap slot is empty.
- if (!auto_wield || !is_valid_item(you.inv[item_slot]) || force_unwield)
- {
- if (!auto_wield)
- item_slot = prompt_invent_item( "Wield which item (- for none)?",
- OSEL_WIELD, true, true, true, '-' );
- else
- item_slot = PROMPT_GOT_SPECIAL;
-
- if (item_slot == PROMPT_ABORT)
- {
- canned_msg( MSG_OK );
- return (false);
- }
- else if (item_slot == PROMPT_GOT_SPECIAL) // '-' or bare hands
- {
- if (you.equip[EQ_WEAPON] != -1)
- {
- unwield_item(you.equip[EQ_WEAPON]);
- you.turn_is_over = 1;
-
- you.equip[EQ_WEAPON] = -1;
- canned_msg( MSG_EMPTY_HANDED );
- you.time_taken *= 3;
- you.time_taken /= 10;
- }
- else
- {
- mpr( "You are already empty-handed." );
- }
- return (true);
- }
- }
-
- if (item_slot == you.equip[EQ_WEAPON])
- {
- mpr("You are already wielding that!");
- return (true);
- }
-
- for (int i = EQ_CLOAK; i <= EQ_AMULET; i++)
- {
- if (item_slot == you.equip[i])
- {
- mpr("You are wearing that object!");
- return (false);
- }
- }
-
- if (you.inv[item_slot].base_type != OBJ_WEAPONS)
- {
- if (you.inv[item_slot].base_type == OBJ_STAVES
- && you.equip[EQ_SHIELD] != -1)
- {
- mpr("You can't wield that with a shield.");
- return (false);
- }
-
- if (you.equip[EQ_WEAPON] != -1)
- unwield_item(you.equip[EQ_WEAPON]);
-
- you.equip[EQ_WEAPON] = item_slot;
- }
- else
- {
- if ((you.species < SP_OGRE || you.species > SP_OGRE_MAGE)
- && item_mass( you.inv[item_slot] ) >= 500)
- {
- mpr("That's too large and heavy for you to wield.");
- return (false);
- }
-
- if ((you.species == SP_HALFLING || you.species == SP_GNOME
- || you.species == SP_KOBOLD || you.species == SP_SPRIGGAN)
-
- && (you.inv[item_slot].sub_type == WPN_GREAT_SWORD
- || you.inv[item_slot].sub_type == WPN_TRIPLE_SWORD
- || you.inv[item_slot].sub_type == WPN_GREAT_MACE
- || you.inv[item_slot].sub_type == WPN_DIRE_FLAIL
- || you.inv[item_slot].sub_type == WPN_BATTLEAXE
- || you.inv[item_slot].sub_type == WPN_EXECUTIONERS_AXE
- || you.inv[item_slot].sub_type == WPN_LOCHABER_AXE
- || you.inv[item_slot].sub_type == WPN_HALBERD
- || you.inv[item_slot].sub_type == WPN_GLAIVE
- || you.inv[item_slot].sub_type == WPN_GIANT_CLUB
- || you.inv[item_slot].sub_type == WPN_GIANT_SPIKED_CLUB
- || you.inv[item_slot].sub_type == WPN_LONGBOW
- || you.inv[item_slot].sub_type == WPN_SCYTHE))
- {
- mpr("That's too large for you to wield.");
- return (false);
-
- }
-
- if (hands_reqd_for_weapon( you.inv[item_slot].base_type,
- you.inv[item_slot].sub_type ) == HANDS_TWO
- && you.equip[EQ_SHIELD] != -1)
- {
- mpr("You can't wield that with a shield.");
- return (false);
- }
-
- int weap_brand = get_weapon_brand( you.inv[item_slot] );
-
- if ((you.is_undead || you.species == SP_DEMONSPAWN)
- && (!is_fixed_artefact( you.inv[item_slot] )
- && (weap_brand == SPWPN_HOLY_WRATH
- || weap_brand == SPWPN_DISRUPTION
- || (you.inv[item_slot].base_type == OBJ_WEAPONS
- && you.inv[item_slot].sub_type == WPN_BLESSED_BLADE))))
- {
- mpr("This weapon will not allow you to wield it.");
- you.turn_is_over = 1;
- return (false);
- }
-
- if (you.equip[EQ_WEAPON] != -1)
- unwield_item(you.equip[EQ_WEAPON]);
-
- you.equip[EQ_WEAPON] = item_slot;
- }
-
- // any oddness on wielding taken care of here
- wield_effects(item_slot, show_weff_messages);
-
- in_name( item_slot, DESC_INVENTORY_EQUIP, str_pass );
- mpr( str_pass );
-
- // warn player about low str/dex or throwing skill
- wield_warning();
-
- // time calculations
- you.time_taken *= 5;
- you.time_taken /= 10;
-
- you.wield_change = true;
- you.turn_is_over = 1;
-
- return (true);
-}
-
-// provide a function for handling initial wielding of 'special'
-// weapons, or those whose function is annoying to reproduce in
-// other places *cough* auto-butchering *cough* {gdl}
-
-void wield_effects(int item_wield_2, bool showMsgs)
-{
- unsigned char i_dam = 0;
-
- // and here we finally get to the special effects of wielding {dlb}
- if (you.inv[item_wield_2].base_type == OBJ_MISCELLANY)
- {
- if (you.inv[item_wield_2].sub_type == MISC_LANTERN_OF_SHADOWS)
- {
- if (showMsgs)
- mpr("The area is filled with flickering shadows.");
-
- you.special_wield = SPWLD_SHADOW;
- }
- }
-
- if (you.inv[item_wield_2].base_type == OBJ_STAVES)
- {
- if (you.inv[item_wield_2].sub_type == STAFF_POWER)
- {
- // inc_max_mp(13);
- calc_mp();
- set_ident_flags( you.inv[item_wield_2], ISFLAG_EQ_WEAPON_MASK );
- }
- else
- {
- // Most staves only give curse status when wielded and
- // right now that's always "uncursed". -- bwr
- set_ident_flags( you.inv[item_wield_2], ISFLAG_KNOW_CURSE );
- }
- }
-
- if (you.inv[item_wield_2].base_type == OBJ_WEAPONS)
- {
- if (is_demonic(you.inv[item_wield_2].sub_type)
- && (you.religion == GOD_ZIN || you.religion == GOD_SHINING_ONE
- || you.religion == GOD_ELYVILON))
- {
- if (showMsgs)
- mpr("You really shouldn't be using a nasty item like this.");
- }
-
- set_ident_flags( you.inv[item_wield_2], ISFLAG_EQ_WEAPON_MASK );
-
- if (is_random_artefact( you.inv[item_wield_2] ))
- {
- i_dam = randart_wpn_property(you.inv[item_wield_2], RAP_BRAND);
- use_randart(item_wield_2);
- }
- else
- {
- i_dam = you.inv[item_wield_2].special;
- }
-
- if (i_dam != SPWPN_NORMAL)
- {
- // message first
- if (showMsgs)
- {
- switch (i_dam)
- {
- case SPWPN_SWORD_OF_CEREBOV:
- case SPWPN_FLAMING:
- mpr("It bursts into flame!");
- break;
-
- case SPWPN_FREEZING:
- mpr("It glows with a cold blue light!");
- break;
-
- case SPWPN_HOLY_WRATH:
- mpr("It softly glows with a divine radiance!");
- break;
-
- case SPWPN_ELECTROCUTION:
- mpr("You hear the crackle of electricity.");
- break;
-
- case SPWPN_ORC_SLAYING:
- mpr((you.species == SP_HILL_ORC)
- ? "You feel a sudden desire to commit suicide."
- : "You feel a sudden desire to kill orcs!");
- break;
-
- case SPWPN_VENOM:
- mpr("It begins to drip with poison!");
- break;
-
- case SPWPN_PROTECTION:
- mpr("You feel protected!");
- break;
-
- case SPWPN_DRAINING:
- mpr("You sense an unholy aura.");
- break;
-
- case SPWPN_SPEED:
- mpr("Your hands tingle!");
- break;
-
- case SPWPN_FLAME:
- mpr("It glows red for a moment.");
- break;
-
- case SPWPN_FROST:
- mpr("It is covered in frost.");
- break;
-
- case SPWPN_VAMPIRICISM:
- if (!you.is_undead)
- mpr("You feel a strange hunger.");
- else
- mpr("You feel strangely empty.");
- break;
-
- case SPWPN_DISRUPTION:
- mpr("You sense a holy aura.");
- break;
-
- case SPWPN_PAIN:
- mpr("A searing pain shoots up your arm!");
- break;
-
- case SPWPN_SINGING_SWORD:
- mpr("The Singing Sword hums in delight!");
- break;
-
- case SPWPN_WRATH_OF_TROG:
- mpr("You feel bloodthirsty!");
- break;
-
- case SPWPN_SCYTHE_OF_CURSES:
- mpr("A shiver runs down your spine.");
- break;
-
- case SPWPN_GLAIVE_OF_PRUNE:
- mpr("You feel pruney.");
- break;
-
- case SPWPN_SCEPTRE_OF_TORMENT:
- mpr("A terribly searing pain shoots up your arm!");
- break;
-
- case SPWPN_SWORD_OF_ZONGULDROK:
- mpr("You sense an extremely unholy aura.");
- break;
-
- case SPWPN_SWORD_OF_POWER:
- mpr("You sense an aura of extreme power.");
- break;
-
- case SPWPN_STAFF_OF_OLGREB:
- // mummies cannot smell
- if (you.species != SP_MUMMY)
- mpr("You smell chlorine.");
- else
- mpr("The staff glows slightly green.");
- break;
-
- case SPWPN_VAMPIRES_TOOTH:
- // mummies cannot smell, and do not hunger {dlb}
- if (!you.is_undead)
- mpr("You feel a strange hunger, and smell blood on the air...");
- else
- mpr("You feel strangely empty.");
- break;
-
- default:
- break;
- }
- }
-
- // effect second
- switch (i_dam)
- {
- case SPWPN_PROTECTION:
- you.redraw_armour_class = 1;
- break;
-
- case SPWPN_DISTORTION:
- miscast_effect( SPTYP_TRANSLOCATION, 9, 90, 100, "a distortion effect" );
- break;
-
- case SPWPN_SINGING_SWORD:
- you.special_wield = SPWLD_SING;
- break;
-
- case SPWPN_WRATH_OF_TROG:
- you.special_wield = SPWLD_TROG;
- break;
-
- case SPWPN_SCYTHE_OF_CURSES:
- you.special_wield = SPWLD_CURSE;
- if (one_chance_in(5))
- do_curse_item( you.inv[item_wield_2] );
- break;
-
- case SPWPN_MACE_OF_VARIABILITY:
- you.special_wield = SPWLD_VARIABLE;
- break;
-
- case SPWPN_GLAIVE_OF_PRUNE:
- you.special_wield = SPWLD_NONE;
- break;
-
- case SPWPN_SCEPTRE_OF_TORMENT:
- you.special_wield = SPWLD_TORMENT;
- break;
-
- case SPWPN_SWORD_OF_ZONGULDROK:
- you.special_wield = SPWLD_ZONGULDROK;
- break;
-
- case SPWPN_SWORD_OF_POWER:
- you.special_wield = SPWLD_POWER;
- break;
-
- case SPWPN_STAFF_OF_OLGREB:
- // josh declares mummies cannot smell {dlb}
- you.special_wield = SPWLD_OLGREB;
- break;
-
- case SPWPN_STAFF_OF_WUCAD_MU:
- miscast_effect( SPTYP_DIVINATION, 9, 90, 100, "the Staff of Wucad Mu" );
- you.special_wield = SPWLD_WUCAD_MU;
- break;
- }
- }
-
- if (item_cursed( you.inv[item_wield_2] ))
- mpr("It sticks to your hand!");
- }
-} // end wield_weapon()
-
-//---------------------------------------------------------------
-//
-// armour_prompt
-//
-// Prompt the user for some armour. Returns true if the user picked
-// something legit.
-//
-//---------------------------------------------------------------
-bool armour_prompt( const std::string & mesg, int *index )
-{
- ASSERT(index != NULL);
-
- bool succeeded = false;
- int slot;
-
- if (inv_count() < 1)
- canned_msg(MSG_NOTHING_CARRIED);
- else if (you.berserker)
- canned_msg(MSG_TOO_BERSERK);
- else
- {
- slot = prompt_invent_item( mesg.c_str(), OBJ_ARMOUR );
-
- if (slot != PROMPT_ABORT)
- {
- *index = slot;
- succeeded = true;
- }
- }
-
- return (succeeded);
-} // end armour_prompt()
-
-static bool cloak_is_being_removed( void )
-{
- if (current_delay_action() != DELAY_ARMOUR_OFF)
- return (false);
-
- if (you.delay_queue.front().parm1 != you.equip[ EQ_CLOAK ])
- return (false);
-
- return (true);
-}
-
-//---------------------------------------------------------------
-//
-// wear_armour
-//
-//---------------------------------------------------------------
-void wear_armour(void)
-{
- int armour_wear_2;
-
- if (!armour_prompt("Wear which item?", &armour_wear_2))
- return;
-
- do_wear_armour( armour_wear_2, false );
-}
-
-bool do_wear_armour( int item, bool quiet )
-{
- if (!is_valid_item( you.inv[item] ))
- {
- if (!quiet)
- mpr("You don't have any such object.");
-
- return (false);
- }
-
- const int base_type = you.inv[item].base_type;
- if (base_type != OBJ_ARMOUR)
- {
- if (!quiet)
- mpr("You can't wear that.");
-
- return (false);
- }
-
- const int sub_type = you.inv[item].sub_type;
- const item_def &invitem = you.inv[item];
- const equipment_type slot = get_armour_slot(invitem);
-
- if (item == you.equip[EQ_WEAPON])
- {
- if (!quiet)
- mpr("You are wielding that object!");
-
- return (false);
- }
-
- for (int loopy = EQ_CLOAK; loopy <= EQ_BODY_ARMOUR; loopy++)
- {
- if (item == you.equip[loopy])
- {
- if (!quiet)
- mpr("You are already wearing that!");
-
- return (false);
- }
- }
-
- // if you're wielding something,
- if (you.equip[EQ_WEAPON] != -1
- // attempting to wear a shield,
- && (you.inv[item].sub_type == ARM_SHIELD
- || you.inv[item].sub_type == ARM_BUCKLER
- || you.inv[item].sub_type == ARM_LARGE_SHIELD)
- // weapon is two-handed
- && hands_reqd_for_weapon(you.inv[you.equip[EQ_WEAPON]].base_type,
- you.inv[you.equip[EQ_WEAPON]].sub_type) == HANDS_TWO)
- {
- if (!quiet)
- mpr("You'd need three hands to do that!");
-
- return (false);
- }
-
- bool can_wear = true;
- if (sub_type == ARM_NAGA_BARDING)
- can_wear = (you.species == SP_NAGA);
-
- if (sub_type == ARM_CENTAUR_BARDING)
- can_wear = (you.species == SP_CENTAUR);
-
- if (!can_wear)
- {
- if (!quiet)
- mpr("You can't wear that!");
- return (false);
- }
-
- if (you.inv[item].sub_type == ARM_BOOTS)
- {
- if (you.species == SP_NAGA || you.species == SP_CENTAUR)
- {
- if (!quiet)
- mpr("You can't wear that!");
- return (false);
- }
-
- if (player_is_swimming() && you.species == SP_MERFOLK)
- {
- if (!quiet)
- mpr("You don't currently have feet!");
-
- return (false);
- }
- }
-
- if (you.species == SP_NAGA && sub_type == ARM_NAGA_BARDING
- && !player_is_shapechanged())
- {
- // it fits
- }
- else if (you.species == SP_CENTAUR
- && sub_type == ARM_CENTAUR_BARDING
- && !player_is_shapechanged())
- {
- // it fits
- }
- else if (sub_type == ARM_HELMET
- && (get_helmet_type(invitem) == THELM_CAP
- || get_helmet_type(invitem) == THELM_WIZARD_HAT))
- {
- // caps & wiz hats always fit, unless your head's too big (ogres &c)
- }
- else if (!can_equip( slot ))
- {
- if (!quiet)
- mpr("You can't wear that in your present form.");
-
- return (false);
- }
-
- // Cannot swim in heavy armour
- if (player_is_swimming()
- && slot == EQ_BODY_ARMOUR
- && !is_light_armour( invitem ))
- {
- if (!quiet)
- mpr("You can't swim in that!");
-
- return (false);
- }
-
- // Giant races
- if ((you.species >= SP_OGRE && you.species <= SP_OGRE_MAGE)
- || player_genus(GENPC_DRACONIAN))
- {
- if ((sub_type >= ARM_LEATHER_ARMOUR
- && sub_type <= ARM_PLATE_MAIL)
- || (sub_type >= ARM_GLOVES
- && sub_type <= ARM_BUCKLER)
- || sub_type == ARM_CRYSTAL_PLATE_MAIL
- || (sub_type == ARM_HELMET
- && (get_helmet_type(invitem) == THELM_HELM
- || get_helmet_type(invitem) == THELM_HELMET)))
- {
- if (!quiet)
- mpr("This armour doesn't fit on your body.");
-
- return (false);
- }
- }
-
- // Tiny races
- if (you.species == SP_SPRIGGAN)
- {
- if ((sub_type >= ARM_LEATHER_ARMOUR
- && sub_type <= ARM_PLATE_MAIL)
- || sub_type == ARM_GLOVES
- || sub_type == ARM_BOOTS
- || sub_type == ARM_SHIELD
- || sub_type == ARM_LARGE_SHIELD
- || sub_type == ARM_CRYSTAL_PLATE_MAIL
- || (sub_type == ARM_HELMET
- && (get_helmet_type(invitem) == THELM_HELM
- || get_helmet_type(invitem) == THELM_HELMET)))
- {
- if (!quiet)
- mpr("This armour doesn't fit on your body.");
-
- return (false);
- }
- }
-
- bool removedCloak = false;
- int cloak = -1;
-
- if (slot == EQ_BODY_ARMOUR
- && you.equip[EQ_CLOAK] != -1 && !cloak_is_being_removed())
- {
- if (!item_cursed( you.inv[you.equip[EQ_CLOAK]] ))
- {
- cloak = you.equip[ EQ_CLOAK ];
- if (!takeoff_armour(you.equip[EQ_CLOAK]))
- return (false);
-
- removedCloak = true;
- }
- else
- {
- if (!quiet)
- mpr("Your cloak prevents you from wearing the armour.");
-
- return (false);
- }
- }
-
- if (slot == EQ_CLOAK && you.equip[EQ_CLOAK] != -1)
- {
- if (!takeoff_armour(you.equip[EQ_CLOAK]))
- return (false);
- }
-
- if (slot == EQ_HELMET && you.equip[EQ_HELMET] != -1)
- {
- if (!takeoff_armour(you.equip[EQ_HELMET]))
- return (false);
- }
-
- if (slot == EQ_GLOVES && you.equip[EQ_GLOVES] != -1)
- {
- if (!takeoff_armour(you.equip[EQ_GLOVES]))
- return (false);
- }
-
- if (slot == EQ_BOOTS && you.equip[EQ_BOOTS] != -1)
- {
- if (!takeoff_armour(you.equip[EQ_BOOTS]))
- return (false);
- }
-
- if (slot == EQ_SHIELD && you.equip[EQ_SHIELD] != -1)
- {
- if (!takeoff_armour(you.equip[EQ_SHIELD]))
- return (false);
- }
-
- if (slot == EQ_BODY_ARMOUR && you.equip[EQ_BODY_ARMOUR] != -1)
- {
- if (!takeoff_armour(you.equip[EQ_BODY_ARMOUR]))
- return (false);
- }
-
- you.turn_is_over = 1;
-
- int delay = property( you.inv[item], PARM_AC );
-
- if (delay < 1)
- delay = 1;
-
- if (delay)
- start_delay( DELAY_ARMOUR_ON, delay, item );
-
- if (removedCloak)
- start_delay( DELAY_ARMOUR_ON, 1, cloak );
-
- return (true);
-} // do_end wear_armour()
-
-bool takeoff_armour(int item)
-{
- if (you.inv[item].base_type != OBJ_ARMOUR)
- {
- mpr("You aren't wearing that!");
- return false;
- }
-
- if (item_cursed( you.inv[item] ))
- {
- for (int loopy = EQ_CLOAK; loopy <= EQ_BODY_ARMOUR; loopy++)
- {
- if (item == you.equip[loopy])
- {
- in_name(item, DESC_CAP_YOUR, info);
- strcat(info, " is stuck to your body!");
- mpr(info);
- return false;
- }
- }
- }
-
- bool removedCloak = false;
- int cloak = -1;
- const equipment_type slot = get_armour_slot(you.inv[item]);
-
- if (slot == EQ_BODY_ARMOUR)
- {
- if (you.equip[EQ_CLOAK] != -1 && !cloak_is_being_removed())
- {
- if (!item_cursed( you.inv[you.equip[EQ_CLOAK]] ))
- {
- cloak = you.equip[ EQ_CLOAK ];
- if (!takeoff_armour(you.equip[EQ_CLOAK]))
- return (false);
-
- removedCloak = true;
- }
- else
- {
- mpr("Your cloak prevents you from removing the armour.");
- return false;
- }
- }
-
- if (item != you.equip[EQ_BODY_ARMOUR])
- {
- mpr("You aren't wearing that!");
- return false;
- }
-
- // you.equip[EQ_BODY_ARMOUR] = -1;
- }
- else
- {
- switch (slot)
- {
- case EQ_SHIELD:
- if (item != you.equip[EQ_SHIELD])
- {
- mpr("You aren't wearing that!");
- return false;
- }
- break;
-
- case EQ_CLOAK:
- if (item != you.equip[EQ_CLOAK])
- {
- mpr("You aren't wearing that!");
- return false;
- }
- break;
-
- case EQ_HELMET:
- if (item != you.equip[EQ_HELMET])
- {
- mpr("You aren't wearing that!");
- return false;
- }
- break;
-
- case EQ_GLOVES:
- if (item != you.equip[EQ_GLOVES])
- {
- mpr("You aren't wearing that!");
- return false;
- }
- break;
-
- case EQ_BOOTS:
- if (item != you.equip[EQ_BOOTS])
- {
- mpr("You aren't wearing that!");
- return false;
- }
- break;
-
- default:
- break;
- }
- }
-
- you.turn_is_over = 1;
-
- int delay = property( you.inv[item], PARM_AC );
-
- if (delay < 1)
- delay = 1;
-
- start_delay( DELAY_ARMOUR_OFF, delay, item );
-
- if (removedCloak)
- start_delay( DELAY_ARMOUR_ON, 1, cloak );
-
- return true;
-} // end takeoff_armour()
-
-void throw_anything(void)
-{
- struct bolt beam;
- int throw_slot;
-
- if (you.berserker)
- {
- canned_msg(MSG_TOO_BERSERK);
- return;
- }
- else if (inv_count() < 1)
- {
- canned_msg(MSG_NOTHING_CARRIED);
- return;
- }
-
- throw_slot = prompt_invent_item( "Throw which item?", OBJ_MISSILES );
- if (throw_slot == PROMPT_ABORT)
- {
- canned_msg( MSG_OK );
- return;
- }
-
- if (throw_slot == you.equip[EQ_WEAPON]
- && (item_cursed( you.inv[you.equip[EQ_WEAPON]] )))
- {
- mpr("That thing is stuck to your hand!");
- return;
- }
- else
- {
- for (int loopy = EQ_CLOAK; loopy <= EQ_AMULET; loopy++)
- {
- if (throw_slot == you.equip[loopy])
- {
- mpr("You are wearing that object!");
- return;
- }
- }
- }
-
- throw_it(beam, throw_slot);
-} // end throw_anything()
-
-// Return index of first valid balanced throwing weapon or ENDOFPACK
-static int try_finding_throwing_weapon( int sub_type )
-{
- int i;
-
- for (i = Options.fire_items_start; i < ENDOFPACK; i++)
- {
- // skip invalid objects, wielded object
- if (!is_valid_item( you.inv[i] ) || you.equip[EQ_WEAPON] == i)
- continue;
-
- // consider melee weapons that can also be thrown
- if (you.inv[i].base_type == OBJ_WEAPONS
- && you.inv[i].sub_type == sub_type)
- {
- break;
- }
- }
-
- return (i);
-}
-
-// Return index of first missile of sub_type or ENDOFPACK
-static int try_finding_missile( int sub_type )
-{
- int i;
-
- for (i = Options.fire_items_start; i < ENDOFPACK; i++)
- {
- // skip invalid objects
- if (!is_valid_item( you.inv[i] ))
- continue;
-
- // consider melee weapons that can also be thrown
- if (you.inv[i].base_type == OBJ_MISSILES
- && you.inv[i].sub_type == sub_type)
- {
- break;
- }
- }
-
- return (i);
-}
-
-// Note: This is a simple implementation, not an efficient one. -- bwr
-//
-// Returns item index or ENDOFPACK if no item found for auto-firing
-int get_fire_item_index( void )
-{
- int item = ENDOFPACK;
- const int weapon = you.equip[ EQ_WEAPON ];
-
- for (int i = 0; i < NUM_FIRE_TYPES; i++)
- {
- // look for next type on list... if found item is set != ENDOFPACK
- switch (Options.fire_order[i])
- {
- case FIRE_LAUNCHER:
- // check if we have ammo for a wielded launcher:
- if (weapon != -1
- && you.inv[ weapon ].base_type == OBJ_WEAPONS
- && launches_things( you.inv[ weapon ].sub_type ))
- {
- int type_wanted = launched_by( you.inv[ weapon ].sub_type );
- item = try_finding_missile( type_wanted );
- }
- break;
-
- case FIRE_DART:
- item = try_finding_missile( MI_DART );
- break;
-
- case FIRE_STONE:
- item = try_finding_missile( MI_STONE );
- break;
-
- case FIRE_DAGGER:
- item = try_finding_throwing_weapon( WPN_DAGGER );
- break;
-
- case FIRE_SPEAR:
- item = try_finding_throwing_weapon( WPN_SPEAR );
- break;
-
- case FIRE_HAND_AXE:
- item = try_finding_throwing_weapon( WPN_HAND_AXE );
- break;
-
- case FIRE_CLUB:
- item = try_finding_throwing_weapon( WPN_CLUB );
- break;
-
- case FIRE_NONE:
- default:
- break;
- }
-
- // if successful break
- if (item != ENDOFPACK)
- break;
- }
-
- // either item was found or is still ENDOFPACK for no item
- return (item);
-}
-
-void shoot_thing(void)
-{
- struct bolt beam; // passed in by reference, but never used here
- char str_pass[ ITEMNAME_SIZE ];
-
- if (you.berserker)
- {
- canned_msg(MSG_TOO_BERSERK);
- return;
- }
-
- const int item = get_fire_item_index();
-
- if (item == ENDOFPACK)
- {
- mpr("No suitable missiles.");
- return;
- }
-
- in_name( item, DESC_INVENTORY_EQUIP, str_pass );
- snprintf( info, INFO_SIZE, "Firing: %s", str_pass );
- mpr( info );
-
- throw_it( beam, item );
-} // end shoot_thing()
-
-// throw_it - currently handles player throwing only. Monster
-// throwing is handled in mstuff2:mons_throw()
-// Note: If dummy_target is non-NULL, throw_it fakes a bolt and calls
-// affect() on the monster's square.
-//
-// Return value is only relevant if dummy_target is non-NULL, and returns
-// true if dummy_target is hit.
-bool throw_it(struct bolt &pbolt, int throw_2, monsters *dummy_target)
-{
- struct dist thr;
- char shoot_skill = 0;
-
- char wepClass, wepType; // ammo class and type
- char lnchClass, lnchType; // launcher class and type
-
- int baseHit = 0, baseDam = 0; // from thrown or ammo
- int ammoHitBonus = 0, ammoDamBonus = 0; // from thrown or ammo
- int lnchHitBonus = 0, lnchDamBonus = 0; // special add from launcher
- int exHitBonus = 0, exDamBonus = 0; // 'extra' bonus from skill/dex/str
- int effSkill = 0; // effective launcher skill
- int dice_mult = 100;
- bool launched = false; // item is launched
- bool thrown = false; // item is sensible thrown item
- int slayDam = 0;
-
- if (dummy_target)
- {
- thr.isValid = true;
- thr.isCancel = false;
- thr.tx = dummy_target->x;
- thr.ty = dummy_target->y;
- }
- else
- {
- mpr( STD_DIRECTION_PROMPT, MSGCH_PROMPT );
- message_current_target();
- direction( thr, DIR_NONE, TARG_ENEMY );
- }
-
- if (!thr.isValid)
- {
- if (thr.isCancel)
- canned_msg(MSG_OK);
-
- return (false);
- }
-
- // Must unwield before fire_beam() makes a copy in order to remove things
- // like temporary branding. -- bwr
- if (throw_2 == you.equip[EQ_WEAPON] && you.inv[throw_2].quantity == 1)
- {
- unwield_item( throw_2 );
- you.equip[EQ_WEAPON] = -1;
- canned_msg( MSG_EMPTY_HANDED );
- }
-
- // Making a copy of the item: changed only for venom launchers
- item_def item = you.inv[throw_2];
- item.quantity = 1;
- item.slot = index_to_letter(item.link);
- origin_set_unknown(item);
-
- char str_pass[ ITEMNAME_SIZE ];
-
- if (you.conf)
- {
- thr.isTarget = true;
- thr.tx = you.x_pos + random2(13) - 6;
- thr.ty = you.y_pos + random2(13) - 6;
- }
-
- // even though direction is allowed, we're throwing so we
- // want to use tx, ty to make the missile fly to map edge.
- pbolt.target_x = thr.tx;
- pbolt.target_y = thr.ty;
-
- pbolt.flavour = BEAM_MISSILE;
- // pbolt.range is set below
-
- switch (item.base_type)
- {
- case OBJ_WEAPONS: pbolt.type = SYM_WEAPON; break;
- case OBJ_MISSILES: pbolt.type = SYM_MISSILE; break;
- case OBJ_ARMOUR: pbolt.type = SYM_ARMOUR; break;
- case OBJ_WANDS: pbolt.type = SYM_STICK; break;
- case OBJ_FOOD: pbolt.type = SYM_CHUNK; break;
- case OBJ_UNKNOWN_I: pbolt.type = SYM_BURST; break;
- case OBJ_SCROLLS: pbolt.type = SYM_SCROLL; break;
- case OBJ_JEWELLERY: pbolt.type = SYM_TRINKET; break;
- case OBJ_POTIONS: pbolt.type = SYM_FLASK; break;
- case OBJ_UNKNOWN_II: pbolt.type = SYM_ZAP; break;
- case OBJ_BOOKS: pbolt.type = SYM_OBJECT; break;
- // this does not seem right, but value was 11 {dlb}
- // notice how the .type does not match the class -- hmmm... {dlb}
- case OBJ_STAVES: pbolt.type = SYM_CHUNK; break;
- }
-
- pbolt.source_x = you.x_pos;
- pbolt.source_y = you.y_pos;
- pbolt.colour = item.colour;
-
- item_name( item, DESC_PLAIN, str_pass );
- strcpy( pbolt.beam_name, str_pass );
-
- pbolt.thrower = KILL_YOU_MISSILE;
- pbolt.aux_source = NULL;
-
- // get the ammo/weapon type. Convenience.
- wepClass = item.base_type;
- wepType = item.sub_type;
-
- // get the launcher class,type. Convenience.
- if (you.equip[EQ_WEAPON] < 0)
- {
- lnchClass = -1;
- // set lnchType to 0 so the 'figure out if launched'
- // code doesn't break
- lnchType = 0;
- }
- else
- {
- lnchClass = you.inv[you.equip[EQ_WEAPON]].base_type;
- lnchType = you.inv[you.equip[EQ_WEAPON]].sub_type;
- }
-
- // baseHit and damage for generic objects
- baseHit = you.strength - item_mass(item) / 10;
- if (baseHit > 0)
- baseHit = 0;
-
- baseDam = item_mass(item) / 100;
-
- // special: might be throwing generic weapon;
- // use base wep. damage, w/ penalty
- if (wepClass == OBJ_WEAPONS)
- {
- baseDam = property( item, PWPN_DAMAGE ) - 4;
- if (baseDam < 0)
- baseDam = 0;
- }
-
- // figure out if we're thrown or launched
- throw_type(lnchClass, lnchType, wepClass, wepType, launched, thrown);
-
- // extract launcher bonuses due to magic
- if (launched)
- {
- lnchHitBonus = you.inv[you.equip[EQ_WEAPON]].plus;
- lnchDamBonus = you.inv[you.equip[EQ_WEAPON]].plus2;
- }
-
- // extract weapon/ammo bonuses due to magic
- ammoHitBonus = item.plus;
- ammoDamBonus = item.plus2;
-
- // CALCULATIONS FOR LAUNCHED WEAPONS
- if (launched)
- {
- const item_def &launcher = you.inv[you.equip[EQ_WEAPON]];
- const int bow_brand = get_weapon_brand( launcher );
- const int ammo_brand = get_ammo_brand( item );
- const bool two_handed = (you.equip[EQ_SHIELD] == -1);
- bool poisoned = (ammo_brand == SPMSL_POISONED
- || ammo_brand == SPMSL_POISONED_II);
- const int rc_skill = you.skills[SK_RANGED_COMBAT];
-
- const int item_base_dam = property( item, PWPN_DAMAGE );
- const int lnch_base_dam = property( launcher, PWPN_DAMAGE );
-
- const skill_type launcher_skill = range_skill( launcher );
- const int str_weight = weapon_str_weight( launcher );
- const int dex_weight = 10 - str_weight;
-
- int speed_base = 10 * property( launcher, PWPN_SPEED );
- int speed_min = 70;
- int speed_stat = str_weight * you.strength + dex_weight * you.dex;
- int speed = 100;
-
- baseHit = property( launcher, PWPN_HIT );
- baseDam = lnch_base_dam + random2(1 + item_base_dam);
-
- // Slings are terribly weakened otherwise
- if (lnch_base_dam == 0)
- baseDam = item_base_dam;
-
- if (launcher_skill == SK_BOWS)
- speed_min = 60;
-
-#ifdef DEBUG_DIAGNOSTICS
- mprf(MSGCH_DIAGNOSTICS,
- "Base hit == %d; Base damage == %d "
- "(item %d + launcher %d)",
- baseHit, baseDam,
- item_base_dam, lnch_base_dam);
-#endif
-
- // fix ammo damage bonus, since missiles only use inv_plus
- ammoDamBonus = ammoHitBonus;
-
- // check for matches; dwarven,elven,orcish
- if (!get_equip_race(you.inv[you.equip[EQ_WEAPON]]) == 0)
- {
- if (get_equip_race( you.inv[you.equip[EQ_WEAPON]] )
- == get_equip_race( item ))
- {
- baseHit += 1;
- baseDam += 1;
-
- // elves with elven bows
- if (get_equip_race(you.inv[you.equip[EQ_WEAPON]])
- == ISFLAG_ELVEN
- && player_genus(GENPC_ELVEN))
- {
- baseHit += 1;
- }
- }
- }
-
- // for all launched weapons, maximum effective specific skill
- // is twice throwing skill. This models the fact that no matter
- // how 'good' you are with a bow, if you know nothing about
- // trajectories you're going to be a damn poor bowman. Ditto
- // for crossbows and slings.
-
- // [dshaligram] Throwing now two parts launcher skill, one part
- // ranged combat. Removed the old model which is... silly.
-
- shoot_skill = you.skills[launcher_skill];
- effSkill = (shoot_skill * 2 + rc_skill) / 3;
-
- // FIXME: Use actual body size
- if (!two_handed && hands_reqd(launcher, SIZE_MEDIUM) == HANDS_HALF)
- {
- speed_base = (speed_base * 3 + 1) / 2;
- speed_min = (speed_min * 3 + 1) / 2;
- }
-
- speed = speed_base - 4 * shoot_skill * speed_stat / 250;
- if (speed < speed_min)
- speed = speed_min;
-
- if (bow_brand == SPWPN_SPEED)
- {
- // Speed nerf as per 4.1
- speed = 2 * speed / 3;
- }
-#ifdef DEBUG_DIAGNOSTICS
- mprf(MSGCH_DIAGNOSTICS, "Final launcher speed: %d", speed);
-#endif
-
- you.time_taken = speed * you.time_taken / 100;
-
- // effSkill = you.skills[SK_RANGED_COMBAT] * 2 + 1;
- // effSkill = (shoot_skill > effSkill) ? effSkill : shoot_skill;
-
- // [dshaligram] Improving missile weapons:
- // - Remove the strength/enchantment cap where you need to be strong
- // to exploit a launcher bonus.
- // - Add on launcher and missile pluses to extra damage.
-
- // [dshaligram] This can get large...
- exDamBonus = lnchDamBonus + random2(1 + ammoDamBonus);
- exDamBonus = exDamBonus > 0? random2(exDamBonus + 1)
- : -random2(-exDamBonus + 1);
- exHitBonus = lnchHitBonus > 0? random2(lnchHitBonus + 1)
- : -random2(-lnchHitBonus + 1);
-
- // removed 2 random2(2)s from each of the learning curves, but
- // left slings because they're hard enough to develop without
- // a good source of shot in the dungeon.
- switch (launcher_skill)
- {
- case SK_SLINGS:
- {
- // Slings are really easy to learn because they're not
- // really all that good, and its harder to get ammo anyways.
- exercise(SK_SLINGS, 1 + random2avg(3, 2));
- baseHit += 0;
- exHitBonus += (effSkill * 3) / 2;
-
- // strength is good if you're using a nice sling.
- int strbonus = (10 * (you.strength - 10)) / 9;
- strbonus = (strbonus * (2 * baseDam + ammoDamBonus)) / 20;
-
- // cap
- if (strbonus > lnchDamBonus + 1)
- strbonus = lnchDamBonus + 1;
-
- exDamBonus += strbonus;
- // add skill for slings.. helps to find those vulnerable spots
- dice_mult = dice_mult * (14 + random2(1 + effSkill)) / 14;
-
- // now kill the launcher damage bonus
- if (lnchDamBonus > 0)
- lnchDamBonus = 0;
- break;
- }
- // blowguns take a _very_ steady hand; a lot of the bonus
- // comes from dexterity. (Dex bonus here as well as below)
- case SK_DARTS:
- baseHit -= 2;
- exercise(SK_DARTS, (coinflip()? 2 : 1));
- exHitBonus += (effSkill * 3) / 2 + you.dex / 2;
-
- // no extra damage for blowguns
- // exDamBonus = 0;
-
- // now kill the launcher damage and ammo bonuses
- if (lnchDamBonus > 0)
- lnchDamBonus = 0;
- if (ammoDamBonus > 0)
- ammoDamBonus = 0;
- break;
-
- case SK_BOWS:
- {
- baseHit -= 3;
- exercise(SK_BOWS, (coinflip()? 2 : 1));
- exHitBonus += (effSkill * 2);
-
- // strength is good if you're using a nice bow
- int strbonus = (10 * (you.strength - 10)) / 4;
- strbonus = (strbonus * (2 * baseDam + ammoDamBonus)) / 20;
-
- // cap; reduced this cap, because we don't want to allow
- // the extremely-strong to quadruple the enchantment bonus.
- if (strbonus > lnchDamBonus + 1)
- strbonus = lnchDamBonus + 1;
-
- exDamBonus += strbonus;
-
- // add in skill for bows.. help you to find those vulnerable spots.
- // exDamBonus += effSkill;
-
- dice_mult = dice_mult * (17 + random2(1 + effSkill)) / 17;
-
- // now kill the launcher damage bonus
- if (lnchDamBonus > 0)
- lnchDamBonus = 0;
- break;
- }
- // Crossbows are easy for unskilled people.
-
- case SK_CROSSBOWS:
- exercise(SK_CROSSBOWS, (coinflip()? 2 : 1));
- baseHit++;
- exHitBonus += (3 * effSkill) / 2 + 6;
- // exDamBonus += effSkill * 2 / 3 + 4;
-
- dice_mult = dice_mult * (22 + random2(1 + effSkill)) / 22;
-
- if (lnchType == WPN_HAND_CROSSBOW)
- {
- exHitBonus -= 2;
- dice_mult = dice_mult * 26 / 30;
- }
- break;
-
- default:
- break;
- }
-
- // all launched weapons have a slight chance of improving
- // throwing skill
- if (coinflip())
- exercise(SK_RANGED_COMBAT, 1);
-
- // all launched weapons get a minor tohit boost from throwing skill.
- exHitBonus += you.skills[SK_RANGED_COMBAT] / 5;
-
- if (bow_brand == SPWPN_VORPAL)
- {
- // Vorpal brand adds 25% damage bonus.
- dice_mult = dice_mult * 125 / 100;
- }
-
- // special cases for flame, frost, poison, etc.
- // check for venom brand (usually only available for blowguns)
- if (bow_brand == SPWPN_VENOM && ammo_brand == SPMSL_NORMAL)
- {
- // poison brand the ammo
- set_item_ego_type( item, OBJ_MISSILES, SPMSL_POISONED );
- item_name( item, DESC_PLAIN, str_pass );
- strcpy( pbolt.beam_name, str_pass );
- }
-
- // Note that bow_brand is known since the bow is equiped.
- if ((bow_brand == SPWPN_FLAME || ammo_brand == SPMSL_FLAME)
- && ammo_brand != SPMSL_ICE && bow_brand != SPWPN_FROST)
- {
- // [dshaligram] Branded arrows are much stronger.
- dice_mult = dice_mult * 150 / 100;
-
- pbolt.flavour = BEAM_FIRE;
- strcpy(pbolt.beam_name, "bolt of ");
-
- if (poisoned)
- strcat(pbolt.beam_name, "poison ");
-
- strcat(pbolt.beam_name, "flame");
- pbolt.colour = RED;
- pbolt.type = SYM_BOLT;
- pbolt.thrower = KILL_YOU_MISSILE;
- pbolt.aux_source = NULL;
-
- // ammo known if we can't attribute it to the bow
- if (bow_brand != SPWPN_FLAME)
- {
- set_ident_flags( item, ISFLAG_KNOW_TYPE );
- set_ident_flags( you.inv[throw_2], ISFLAG_KNOW_TYPE );
- }
- }
-
- if ((bow_brand == SPWPN_FROST || ammo_brand == SPMSL_ICE)
- && ammo_brand != SPMSL_FLAME && bow_brand != SPWPN_FLAME)
- {
- // [dshaligram] Branded arrows are much stronger.
- dice_mult = dice_mult * 150 / 100;
-
- pbolt.flavour = BEAM_COLD;
- strcpy(pbolt.beam_name, "bolt of ");
-
- if (poisoned)
- strcat(pbolt.beam_name, "poison ");
-
- strcat(pbolt.beam_name, "frost");
- pbolt.colour = WHITE;
- pbolt.type = SYM_BOLT;
- pbolt.thrower = KILL_YOU_MISSILE;
- pbolt.aux_source = NULL;
-
- // ammo known if we can't attribute it to the bow
- if (bow_brand != SPWPN_FROST)
- {
- set_ident_flags( item, ISFLAG_KNOW_TYPE );
- set_ident_flags( you.inv[throw_2], ISFLAG_KNOW_TYPE );
- }
- }
-
- // ammo known if it cancels the effect of the bow
- if ((bow_brand == SPWPN_FLAME && ammo_brand == SPMSL_ICE)
- || (bow_brand == SPWPN_FROST && ammo_brand == SPMSL_FLAME))
- {
- set_ident_flags( item, ISFLAG_KNOW_TYPE );
- set_ident_flags( you.inv[throw_2], ISFLAG_KNOW_TYPE );
- }
-
- /* the chief advantage here is the extra damage this does
- * against susceptible creatures */
-
- /* Note: weapons & ammo of eg fire are not cumulative
- * ammo of fire and weapons of frost don't work together,
- * and vice versa */
-
- // ID check
- if (!item_ident( you.inv[you.equip[EQ_WEAPON]], ISFLAG_KNOW_PLUSES )
- && random2(100) < shoot_skill)
- {
- set_ident_flags(you.inv[you.equip[EQ_WEAPON]], ISFLAG_KNOW_PLUSES);
-
- strcpy(info, "You are wielding ");
- in_name(you.equip[EQ_WEAPON], DESC_NOCAP_A, str_pass);
- strcat(info, str_pass);
- strcat(info, ".");
- mpr(info);
-
- more();
- you.wield_change = true;
- }
- }
-
- // CALCULATIONS FOR THROWN WEAPONS
- if (thrown)
- {
- baseHit = 0;
-
- // since darts/rocks are missiles, they only use inv_plus
- if (wepClass == OBJ_MISSILES)
- ammoDamBonus = ammoHitBonus;
-
- // all weapons that use 'throwing' go here..
- if (wepClass == OBJ_WEAPONS
- || (wepClass == OBJ_MISSILES && wepType == MI_STONE))
- {
- // elves with elven weapons
- if (get_equip_race(item) == ISFLAG_ELVEN
- && player_genus(GENPC_ELVEN))
- baseHit += 1;
-
- // give an appropriate 'tohit' -
- // hand axes and clubs are -5
- // daggers are +1
- // spears are -1
- // rocks are 0
- if (wepClass == OBJ_WEAPONS)
- {
- switch (wepType)
- {
- case WPN_DAGGER:
- baseHit += 1;
- break;
- case WPN_SPEAR:
- baseHit -= 1;
- break;
- default:
- baseHit -= 5;
- break;
- }
- }
-
- exHitBonus = you.skills[SK_RANGED_COMBAT] * 2;
-
- baseDam = property( item, PWPN_DAMAGE );
- exDamBonus =
- (10 * (you.skills[SK_RANGED_COMBAT] / 2 + you.strength - 10)) / 12;
-
- // now, exDamBonus is a multiplier. The full multiplier
- // is applied to base damage, but only a third is applied
- // to the magical modifier.
- exDamBonus = (exDamBonus * (3 * baseDam + ammoDamBonus)) / 30;
- }
-
- if (wepClass == OBJ_MISSILES && wepType == MI_DART)
- {
- // give an appropriate 'tohit' & damage
- baseHit = 2;
- baseDam = property( item, PWPN_DAMAGE );
-
- exHitBonus = you.skills[SK_DARTS] * 2;
- exHitBonus += (you.skills[SK_RANGED_COMBAT] * 2) / 3;
- exDamBonus = you.skills[SK_DARTS] / 3;
- exDamBonus += you.skills[SK_RANGED_COMBAT] / 5;
-
- // exercise skills
- exercise(SK_DARTS, 1 + random2avg(3, 2));
- }
-
- if (wepClass == OBJ_MISSILES && wepType == MI_NEEDLE)
- {
- // Throwing needles is now seriously frowned upon; it's difficult
- // to grip a fiddly little needle, and not penalising it cheapens
- // blowguns.
- exHitBonus -= (30 - you.skills[SK_DARTS]) / 3;
- baseHit -= (30 - you.skills[SK_DARTS]) / 4;
-#ifdef DEBUG_DIAGNOSTICS
- mprf(MSGCH_DIAGNOSTICS, "Needle base hit = %d, exHitBonus = %d",
- baseHit, exHitBonus);
-#endif
- }
-
- // exercise skill
- if (coinflip())
- exercise(SK_RANGED_COMBAT, 1);
- }
-
- // range, dexterity bonus, possible skill increase for silly throwing
- if (thrown || launched)
- {
- if (wepType == MI_LARGE_ROCK)
- {
- pbolt.range = 1 + random2( you.strength / 5 );
- if (pbolt.range > 9)
- pbolt.range = 9;
-
- pbolt.rangeMax = pbolt.range;
- }
- else
- {
- pbolt.range = 9;
- pbolt.rangeMax = 9;
-
- exHitBonus += you.dex / 2;
-
- // slaying bonuses
- if (!(launched && wepType == MI_NEEDLE))
- {
- slayDam = slaying_bonus(PWPN_DAMAGE);
- slayDam = slayDam < 0? -random2(1 - slayDam)
- : random2(1 + slayDam);
- }
-
- exHitBonus += slaying_bonus(PWPN_HIT);
- }
- }
- else
- {
- // range based on mass & strength, between 1 and 9
- pbolt.range = you.strength - item_mass(item) / 10 + 3;
- if (pbolt.range < 1)
- pbolt.range = 1;
-
- if (pbolt.range > 9)
- pbolt.range = 9;
-
- // set max range equal to range for this
- pbolt.rangeMax = pbolt.range;
-
- if (one_chance_in(20))
- exercise(SK_RANGED_COMBAT, 1);
-
- exHitBonus = you.dex / 4;
- }
-
- // FINALIZE tohit and damage
- if (exHitBonus >= 0)
- pbolt.hit = baseHit + random2avg(exHitBonus + 1, 2);
- else
- pbolt.hit = baseHit - random2avg(0 - (exHitBonus - 1), 2);
-
- if (exDamBonus >= 0)
- pbolt.damage = dice_def( 1, baseDam + random2(exDamBonus + 1) );
- else
- pbolt.damage = dice_def( 1, baseDam - random2(0 - (exDamBonus - 1)) );
-
- pbolt.damage.size = dice_mult * pbolt.damage.size / 100;
- pbolt.damage.size += slayDam;
-
- scale_dice( pbolt.damage );
-
- // only add bonuses if we're throwing something sensible
- if (thrown || launched || wepClass == OBJ_WEAPONS)
- {
- pbolt.hit += ammoHitBonus + lnchHitBonus;
- pbolt.damage.size += ammoDamBonus + lnchDamBonus;
- }
-
-#if DEBUG_DIAGNOSTICS
- mprf( MSGCH_DIAGNOSTICS,
- "H:%d+%d;a%dl%d. D:%d+%d;a%dl%d -> %d,%dd%d",
- baseHit, exHitBonus, ammoHitBonus, lnchHitBonus,
- baseDam, exDamBonus, ammoDamBonus, lnchDamBonus,
- pbolt.hit, pbolt.damage.num, pbolt.damage.size );
-#endif
-
- // create message
- if (launched)
- strcpy(info, "You shoot ");
- else
- strcpy(info, "You throw ");
-
- item_name( item, DESC_NOCAP_A, str_pass );
-
- strcat(info, str_pass);
- strcat(info, ".");
- mpr(info);
-
- // ensure we're firing a 'missile'-type beam
- pbolt.is_beam = false;
- pbolt.is_tracer = false;
-
- // mark this item as thrown if it's a missile, so that we'll pick it up
- // when we walk over it.
- if (wepClass == OBJ_MISSILES || wepClass == OBJ_WEAPONS)
- item.flags |= ISFLAG_THROWN;
-
- bool hit = false;
- // using copy, since the launched item might be differect (venom blowgun)
- if (dummy_target)
- hit = (affect( pbolt, dummy_target->x, dummy_target->y ) != 0);
- else
- {
- fire_beam( pbolt, &item );
- dec_inv_item_quantity( throw_2, 1 );
- }
-
- // throwing and blowguns are silent
- if (launched && lnchType != WPN_BLOWGUN)
- noisy( 6, you.x_pos, you.y_pos );
-
- // but any monster nearby can see that something has been thrown:
- alert_nearby_monsters();
-
- you.turn_is_over = 1;
-
- return (hit);
-} // end throw_it()
-
-bool puton_item(int item_slot, bool prompt_finger)
-{
- if (item_slot == you.equip[EQ_LEFT_RING]
- || item_slot == you.equip[EQ_RIGHT_RING]
- || item_slot == you.equip[EQ_AMULET])
- {
- mpr("You've already put that on!");
- return (true);
- }
-
- if (item_slot == you.equip[EQ_WEAPON])
- {
- mpr("You are wielding that object.");
- return (false);
- }
-
- if (you.inv[item_slot].base_type != OBJ_JEWELLERY)
- {
- //jmf: let's not take our inferiority complex out on players, eh? :-p
- //mpr("You're sadly mistaken if you consider that jewellery.")
- mpr("You can only put on jewellery.");
- return (false);
- }
-
- bool is_amulet = (you.inv[item_slot].sub_type >= AMU_RAGE);
-
- if (!is_amulet) // ie it's a ring
- {
- if (you.equip[EQ_GLOVES] != -1
- && item_cursed( you.inv[you.equip[EQ_GLOVES]] ))
- {
- mpr("You can't take your gloves off to put on a ring!");
- return (false);
- }
-
- if (you.inv[item_slot].base_type == OBJ_JEWELLERY
- && you.equip[EQ_LEFT_RING] != -1
- && you.equip[EQ_RIGHT_RING] != -1)
- {
- // and you are trying to wear body you.equip.
- mpr("You've already put a ring on each hand.");
- return (false);
- }
- }
- else if (you.equip[EQ_AMULET] != -1)
- {
- strcpy(info, "You are already wearing an amulet.");
-
- if (one_chance_in(20))
- {
- strcat(info, " And I must say it looks quite fetching.");
- }
-
- mpr(info);
- return (false);
- }
-
- int hand_used = 0;
-
- if (you.equip[EQ_LEFT_RING] != -1)
- hand_used = 1;
-
- if (you.equip[EQ_RIGHT_RING] != -1)
- hand_used = 0;
-
- if (is_amulet)
- hand_used = 2;
- else if (you.equip[EQ_LEFT_RING] == -1 && you.equip[EQ_RIGHT_RING] == -1)
- {
- if (prompt_finger)
- {
- mpr("Put on which hand (l or r)?", MSGCH_PROMPT);
-
- int keyin = get_ch();
-
- if (keyin == 'l')
- hand_used = 0;
- else if (keyin == 'r')
- hand_used = 1;
- else if (keyin == ESCAPE)
- return (false);
- else
- {
- mpr("You don't have such a hand!");
- return (false);
- }
- }
- else
- {
- // First ring goes on left hand if we're choosing automatically.
- hand_used = 0;
- }
- }
-
- you.equip[ EQ_LEFT_RING + hand_used ] = item_slot;
-
- int ident = ID_TRIED_TYPE;
-
- switch (you.inv[item_slot].sub_type)
- {
- case RING_FIRE:
- case RING_HUNGER:
- case RING_ICE:
- case RING_LIFE_PROTECTION:
- case RING_POISON_RESISTANCE:
- case RING_PROTECTION_FROM_COLD:
- case RING_PROTECTION_FROM_FIRE:
- case RING_PROTECTION_FROM_MAGIC:
- case RING_SUSTAIN_ABILITIES:
- case RING_SUSTENANCE:
- case RING_SLAYING:
- case RING_SEE_INVISIBLE:
- case RING_TELEPORTATION:
- case RING_WIZARDRY:
- case RING_REGENERATION:
- break;
-
- case RING_PROTECTION:
- you.redraw_armour_class = 1;
- if (you.inv[item_slot].plus != 0)
- ident = ID_KNOWN_TYPE;
- break;
-
- case RING_INVISIBILITY:
- if (!you.invis)
- {
- mpr("You become transparent for a moment.");
- ident = ID_KNOWN_TYPE;
- }
- break;
-
- case RING_EVASION:
- you.redraw_evasion = 1;
- if (you.inv[item_slot].plus != 0)
- ident = ID_KNOWN_TYPE;
- break;
-
- case RING_STRENGTH:
- modify_stat(STAT_STRENGTH, you.inv[item_slot].plus, true);
- if (you.inv[item_slot].plus != 0)
- ident = ID_KNOWN_TYPE;
- break;
-
- case RING_DEXTERITY:
- modify_stat(STAT_DEXTERITY, you.inv[item_slot].plus, true);
- if (you.inv[item_slot].plus != 0)
- ident = ID_KNOWN_TYPE;
- break;
-
- case RING_INTELLIGENCE:
- modify_stat(STAT_INTELLIGENCE, you.inv[item_slot].plus, true);
- if (you.inv[item_slot].plus != 0)
- ident = ID_KNOWN_TYPE;
- break;
-
- case RING_MAGICAL_POWER:
- calc_mp();
- ident = ID_KNOWN_TYPE;
- break;
-
- case RING_LEVITATION:
- mpr("You feel buoyant.");
- ident = ID_KNOWN_TYPE;
- break;
-
- case RING_TELEPORT_CONTROL:
- // XXX: is this safe or should we make it a function -- bwr
- you.attribute[ATTR_CONTROL_TELEPORT]++;
- break;
-
- case AMU_RAGE:
- mpr("You feel a brief urge to hack something to bits.");
- ident = ID_KNOWN_TYPE;
- break;
- }
-
- you.turn_is_over = 1;
-
- // Artefacts have completely different appearance than base types
- // so we don't allow them to make the base types known
- if (is_random_artefact( you.inv[item_slot] ))
- use_randart(item_slot);
- else
- {
- set_ident_type( you.inv[item_slot].base_type,
- you.inv[item_slot].sub_type, ident );
- }
-
- if (ident == ID_KNOWN_TYPE)
- set_ident_flags( you.inv[item_slot], ISFLAG_EQ_JEWELLERY_MASK );
-
- if (item_cursed( you.inv[item_slot] ))
- {
- snprintf( info, INFO_SIZE,
- "Oops, that %s feels deathly cold.", (is_amulet) ? "amulet"
- : "ring" );
- mpr(info);
- }
-
- // cursed or not, we know that since we've put the ring on
- set_ident_flags( you.inv[item_slot], ISFLAG_KNOW_CURSE );
-
- char str_pass[ ITEMNAME_SIZE ];
- in_name( item_slot, DESC_INVENTORY_EQUIP, str_pass );
- mpr( str_pass );
-
- return (true);
-}
-
-bool puton_ring(int slot, bool prompt_finger)
-{
- int item_slot;
-
- if (inv_count() < 1)
- {
- canned_msg(MSG_NOTHING_CARRIED);
- return (false);
- }
-
- if (you.berserker)
- {
- canned_msg(MSG_TOO_BERSERK);
- return (false);
- }
-
- if (slot != -1)
- item_slot = slot;
- else
- item_slot = prompt_invent_item( "Put on which piece of jewellery?",
- OBJ_JEWELLERY );
-
- if (item_slot == PROMPT_ABORT)
- {
- canned_msg( MSG_OK );
- return (false);
- }
-
- return puton_item(item_slot, prompt_finger);
-} // end puton_ring()
-
-bool remove_ring(int slot)
-{
- int hand_used = 10;
- int ring_wear_2;
- char str_pass[ ITEMNAME_SIZE ];
-
- if (you.equip[EQ_LEFT_RING] == -1 && you.equip[EQ_RIGHT_RING] == -1
- && you.equip[EQ_AMULET] == -1)
- {
- mpr("You aren't wearing any rings or amulets.");
- return (false);
- }
-
- if (you.berserker)
- {
- canned_msg(MSG_TOO_BERSERK);
- return (false);
- }
-
- if (you.equip[EQ_GLOVES] != -1
- && item_cursed( you.inv[you.equip[EQ_GLOVES]] )
- && you.equip[EQ_AMULET] == -1)
- {
- mpr("You can't take your gloves off to remove any rings!");
- return (false);
- }
-
- if (you.equip[EQ_LEFT_RING] != -1 && you.equip[EQ_RIGHT_RING] == -1
- && you.equip[EQ_AMULET] == -1)
- {
- hand_used = 0;
- }
-
- if (you.equip[EQ_LEFT_RING] == -1 && you.equip[EQ_RIGHT_RING] != -1
- && you.equip[EQ_AMULET] == -1)
- {
- hand_used = 1;
- }
-
- if (you.equip[EQ_LEFT_RING] == -1 && you.equip[EQ_RIGHT_RING] == -1
- && you.equip[EQ_AMULET] != -1)
- {
- hand_used = 2;
- }
-
- if (hand_used == 10)
- {
- int equipn =
- slot == -1? prompt_invent_item( "Remove which piece of jewellery?",
- OBJ_JEWELLERY )
- : slot;
-
- if (equipn == PROMPT_ABORT)
- {
- canned_msg( MSG_OK );
- return (false);
- }
-
- if (you.inv[equipn].base_type != OBJ_JEWELLERY)
- {
- mpr("That isn't a piece of jewellery.");
- return (false);
- }
-
- if (you.equip[EQ_LEFT_RING] == equipn)
- hand_used = 0;
- else if (you.equip[EQ_RIGHT_RING] == equipn)
- hand_used = 1;
- else if (you.equip[EQ_AMULET] == equipn)
- hand_used = 2;
- else
- {
- mpr("You aren't wearing that.");
- return (false);
- }
- }
-
- if (you.equip[EQ_GLOVES] != -1
- && item_cursed( you.inv[you.equip[EQ_GLOVES]] )
- && (hand_used == 0 || hand_used == 1))
- {
- mpr("You can't take your gloves off to remove any rings!");
- return (false);
- }
-
- if (you.equip[hand_used + 7] == -1)
- {
- mpr("I don't think you really meant that.");
- return (false);
- }
-
- if (item_cursed( you.inv[you.equip[hand_used + 7]] ))
- {
- mpr("It's stuck to you!");
-
- set_ident_flags( you.inv[you.equip[hand_used + 7]], ISFLAG_KNOW_CURSE );
- return (false);
- }
-
- strcpy(info, "You remove ");
- in_name(you.equip[hand_used + 7], DESC_NOCAP_YOUR, str_pass);
-
- strcat(info, str_pass);
- strcat(info, ".");
- mpr(info);
-
- // I'll still use ring_wear_2 here.
- ring_wear_2 = you.equip[hand_used + 7];
-
- switch (you.inv[ring_wear_2].sub_type)
- {
- case RING_FIRE:
- case RING_HUNGER:
- case RING_ICE:
- case RING_LIFE_PROTECTION:
- case RING_POISON_RESISTANCE:
- case RING_PROTECTION_FROM_COLD:
- case RING_PROTECTION_FROM_FIRE:
- case RING_PROTECTION_FROM_MAGIC:
- case RING_REGENERATION:
- case RING_SEE_INVISIBLE:
- case RING_SLAYING:
- case RING_SUSTAIN_ABILITIES:
- case RING_SUSTENANCE:
- case RING_TELEPORTATION:
- case RING_WIZARDRY:
- break;
-
- case RING_PROTECTION:
- you.redraw_armour_class = 1;
- break;
-
- case RING_EVASION:
- you.redraw_evasion = 1;
- break;
-
- case RING_STRENGTH:
- modify_stat(STAT_STRENGTH, -you.inv[ring_wear_2].plus, true);
- break;
-
- case RING_DEXTERITY:
- modify_stat(STAT_DEXTERITY, -you.inv[ring_wear_2].plus, true);
- break;
-
- case RING_INTELLIGENCE:
- modify_stat(STAT_INTELLIGENCE, -you.inv[ring_wear_2].plus, true);
- break;
-
- case RING_INVISIBILITY:
- // removing this ring effectively cancels all invisibility {dlb}
- if (you.invis)
- you.invis = 1;
- break;
-
- case RING_LEVITATION:
- // removing this ring effectively cancels all levitation {dlb}
- if (you.levitation)
- you.levitation = 1;
- break;
-
- case RING_MAGICAL_POWER:
- // dec_max_mp(9);
- break;
-
- case RING_TELEPORT_CONTROL:
- you.attribute[ATTR_CONTROL_TELEPORT]--;
- break;
- }
-
- if (is_random_artefact( you.inv[ring_wear_2] ))
- unuse_randart(ring_wear_2);
-
- you.equip[hand_used + 7] = -1;
-
- // must occur after ring is removed -- bwr
- calc_mp();
-
- you.turn_is_over = 1;
-
- return (true);
-} // end remove_ring()
-
-void zap_wand(void)
-{
- struct bolt beam;
- struct dist zap_wand;
- int item_slot;
- char str_pass[ ITEMNAME_SIZE ];
-
- // Unless the character knows the type of the wand, the targeting
- // system will default to cycling through all monsters. -- bwr
- int targ_mode = TARG_ANY;
-
- beam.obvious_effect = false;
-
- if (inv_count() < 1)
- {
- canned_msg(MSG_NOTHING_CARRIED);
- return;
- }
-
- if (you.berserker)
- {
- canned_msg(MSG_TOO_BERSERK);
- return;
- }
-
- item_slot = prompt_invent_item( "Zap which item?", OBJ_WANDS );
- if (item_slot == PROMPT_ABORT)
- {
- canned_msg( MSG_OK );
- return;
- }
-
- if (you.inv[item_slot].base_type != OBJ_WANDS
- || you.inv[item_slot].plus < 1)
- {
- canned_msg(MSG_NOTHING_HAPPENS);
- you.turn_is_over = 1;
- return;
- }
-
- if (item_ident( you.inv[item_slot], ISFLAG_KNOW_TYPE ))
- {
- if (you.inv[item_slot].sub_type == WAND_HASTING
- || you.inv[item_slot].sub_type == WAND_HEALING
- || you.inv[item_slot].sub_type == WAND_INVISIBILITY)
- {
- targ_mode = TARG_FRIEND;
- }
- else
- {
- targ_mode = TARG_ENEMY;
- }
- }
-
- mpr( STD_DIRECTION_PROMPT, MSGCH_PROMPT );
- message_current_target();
-
- direction( zap_wand, DIR_NONE, targ_mode );
-
- if (!zap_wand.isValid)
- {
- if (zap_wand.isCancel)
- canned_msg(MSG_OK);
- return;
- }
-
- if (you.conf)
- {
- zap_wand.tx = you.x_pos + random2(13) - 6;
- zap_wand.ty = you.y_pos + random2(13) - 6;
- }
-
- // blargh! blech! this is just begging to be a problem ...
- // not to mention work-around after work-around as wands are
- // added, removed, or altered {dlb}:
- char type_zapped = you.inv[item_slot].sub_type;
-
- if (type_zapped == WAND_ENSLAVEMENT)
- type_zapped = ZAP_ENSLAVEMENT;
-
- if (type_zapped == WAND_DRAINING)
- type_zapped = ZAP_NEGATIVE_ENERGY;
-
- if (type_zapped == WAND_DISINTEGRATION)
- type_zapped = ZAP_DISINTEGRATION;
-
- if (type_zapped == WAND_RANDOM_EFFECTS)
- {
- type_zapped = random2(16);
- if (one_chance_in(20))
- type_zapped = ZAP_NEGATIVE_ENERGY;
- if (one_chance_in(17))
- type_zapped = ZAP_ENSLAVEMENT;
- }
-
- beam.source_x = you.x_pos;
- beam.source_y = you.y_pos;
- beam.target_x = zap_wand.tx;
- beam.target_y = zap_wand.ty;
-
- zapping( type_zapped, 30 + roll_dice(2, you.skills[SK_EVOCATIONS]), beam );
-
- if (beam.obvious_effect == 1 || you.inv[item_slot].sub_type == WAND_FIREBALL)
- {
- if (get_ident_type( you.inv[item_slot].base_type,
- you.inv[item_slot].sub_type ) != ID_KNOWN_TYPE)
- {
- set_ident_type( you.inv[item_slot].base_type,
- you.inv[item_slot].sub_type, ID_KNOWN_TYPE );
-
- in_name(item_slot, DESC_INVENTORY_EQUIP, str_pass);
- mpr( str_pass );
-
- // update if wielding
- if (you.equip[EQ_WEAPON] == item_slot)
- you.wield_change = true;
- }
- }
- else
- {
- set_ident_type( you.inv[item_slot].base_type,
- you.inv[item_slot].sub_type, ID_TRIED_TYPE );
- }
-
- you.inv[item_slot].plus--;
-
- if (get_ident_type( you.inv[item_slot].base_type,
- you.inv[item_slot].sub_type ) == ID_KNOWN_TYPE
- && (item_ident( you.inv[item_slot], ISFLAG_KNOW_PLUSES )
- || you.skills[SK_EVOCATIONS] > 5 + random2(15)))
- {
- if (!item_ident( you.inv[item_slot], ISFLAG_KNOW_PLUSES ))
- {
- mpr("Your skill with magical items lets you calculate the power of this device...");
- }
-
- snprintf( info, INFO_SIZE, "This wand has %d charge%s left.",
- you.inv[item_slot].plus,
- (you.inv[item_slot].plus == 1) ? "" : "s" );
-
- mpr(info);
- set_ident_flags( you.inv[item_slot], ISFLAG_KNOW_PLUSES );
- }
-
- exercise( SK_EVOCATIONS, 1 );
- alert_nearby_monsters();
-
- you.turn_is_over = 1;
-} // end zap_wand()
-
-void drink(void)
-{
- int item_slot;
-
- if (you.is_undead == US_UNDEAD)
- {
- mpr("You can't drink.");
- return;
- }
-
- if (grd[you.x_pos][you.y_pos] == DNGN_BLUE_FOUNTAIN
- || grd[you.x_pos][you.y_pos] == DNGN_SPARKLING_FOUNTAIN)
- {
- if (drink_fountain())
- return;
- }
-
- if (inv_count() < 1)
- {
- canned_msg(MSG_NOTHING_CARRIED);
- return;
- }
-
- if (you.berserker)
- {
- canned_msg(MSG_TOO_BERSERK);
- return;
- }
-
- item_slot = prompt_invent_item( "Drink which item?", OBJ_POTIONS );
- if (item_slot == PROMPT_ABORT)
- {
- canned_msg( MSG_OK );
- return;
- }
-
- if (you.inv[item_slot].base_type != OBJ_POTIONS)
- {
- mpr("You can't drink that!");
- return;
- }
-
- if (potion_effect( you.inv[item_slot].sub_type, 40 ))
- {
- set_ident_flags( you.inv[item_slot], ISFLAG_IDENT_MASK );
-
- set_ident_type( you.inv[item_slot].base_type,
- you.inv[item_slot].sub_type, ID_KNOWN_TYPE );
- }
- else
- {
- set_ident_type( you.inv[item_slot].base_type,
- you.inv[item_slot].sub_type, ID_TRIED_TYPE );
- }
-
- dec_inv_item_quantity( item_slot, 1 );
- you.turn_is_over = 1;
-
- lessen_hunger(40, true);
-} // end drink()
-
-bool drink_fountain(void)
-{
- bool gone_dry = false;
- int temp_rand; // for probability determinations {dlb}
- int fountain_effect = POT_WATER; // for fountain effects {dlb}
-
- switch (grd[you.x_pos][you.y_pos])
- {
- case DNGN_BLUE_FOUNTAIN:
- if (!yesno("Drink from the fountain?"))
- return false;
-
- mpr("You drink the pure, clear water.");
- break;
-
- case DNGN_SPARKLING_FOUNTAIN:
- if (!yesno("Drink from the sparkling fountain?"))
- return false;
-
- mpr("You drink the sparkling water.");
- break;
- }
-
- if (grd[you.x_pos][you.y_pos] == DNGN_SPARKLING_FOUNTAIN)
- {
- temp_rand = random2(4500);
-
- fountain_effect = ((temp_rand > 2399) ? POT_WATER : // 46.7%
- (temp_rand > 2183) ? POT_DECAY : // 4.8%
- (temp_rand > 2003) ? POT_MUTATION : // 4.0%
- (temp_rand > 1823) ? POT_HEALING : // 4.0%
- (temp_rand > 1643) ? POT_HEAL_WOUNDS :// 4.0%
- (temp_rand > 1463) ? POT_SPEED : // 4.0%
- (temp_rand > 1283) ? POT_MIGHT : // 4.0%
- (temp_rand > 1139) ? POT_DEGENERATION ://3.2%
- (temp_rand > 1019) ? POT_LEVITATION :// 2.7%
- (temp_rand > 899) ? POT_POISON : // 2.7%
- (temp_rand > 779) ? POT_SLOWING : // 2.7%
- (temp_rand > 659) ? POT_PARALYSIS : // 2.7%
- (temp_rand > 539) ? POT_CONFUSION : // 2.7%
- (temp_rand > 419) ? POT_INVISIBILITY :// 2.7%
- (temp_rand > 329) ? POT_MAGIC : // 2.0%
- (temp_rand > 239) ? POT_RESTORE_ABILITIES :// 2.0%
- (temp_rand > 149) ? POT_STRONG_POISON ://2.0%
- (temp_rand > 59) ? POT_BERSERK_RAGE : //2.0%
- (temp_rand > 39) ? POT_GAIN_STRENGTH : //0.4%
- (temp_rand > 19) ? POT_GAIN_DEXTERITY //0.4%
- : POT_GAIN_INTELLIGENCE);//0.4%
- }
-
- potion_effect(fountain_effect, 100);
-
- switch (grd[you.x_pos][you.y_pos])
- {
- case DNGN_BLUE_FOUNTAIN:
- if (one_chance_in(20))
- gone_dry = true;
- break;
-
- case DNGN_SPARKLING_FOUNTAIN:
- if (one_chance_in(10))
- {
- gone_dry = true;
- break;
- }
- else
- {
- temp_rand = random2(50);
-
- // you won't know it (yet)
- if (temp_rand > 40) // 18% probability
- grd[you.x_pos][you.y_pos] = DNGN_BLUE_FOUNTAIN;
- }
- break;
- }
-
- if (gone_dry)
- {
- mpr("The fountain dries up!");
- if (grd[you.x_pos][you.y_pos] == DNGN_BLUE_FOUNTAIN)
- grd[you.x_pos][you.y_pos] = DNGN_DRY_FOUNTAIN_I;
- else if (grd[you.x_pos][you.y_pos] == DNGN_SPARKLING_FOUNTAIN)
- grd[you.x_pos][you.y_pos] = DNGN_DRY_FOUNTAIN_II;
- }
-
- you.turn_is_over = 1;
- return true;
-} // end drink_fountain()
-
-static bool affix_weapon_enchantment( void )
-{
- const int wpn = you.equip[ EQ_WEAPON ];
- bool success = true;
-
- struct bolt beam;
-
- if (wpn == -1 || !you.duration[ DUR_WEAPON_BRAND ])
- return (false);
-
- switch (get_weapon_brand( you.inv[wpn] ))
- {
- case SPWPN_VORPAL:
- if (get_vorpal_type( you.inv[wpn] ) != DVORP_CRUSHING)
- {
- strcat(info, "'s sharpness seems more permanent.");
- }
- else
- {
- strcat(info, "'s heaviness feels very stable.");
- }
- mpr(info);
- break;
-
- case SPWPN_FLAMING:
- strcat(info," is engulfed in an explosion of flames!");
- mpr(info);
-
- beam.type = SYM_BURST;
- beam.damage = dice_def( 3, 10 );
- beam.flavour = 2;
- beam.target_x = you.x_pos;
- beam.target_y = you.y_pos;
- strcpy(beam.beam_name, "fiery explosion");
- beam.colour = RED;
- beam.thrower = KILL_YOU;
- beam.aux_source = "a fiery explosion";
- beam.ex_size = 2;
- beam.is_tracer = false;
- beam.is_explosion = true;
-
- explosion(beam);
- break;
-
- case SPWPN_FREEZING:
- strcat(info," glows brilliantly blue for a moment.");
- mpr(info);
- cast_refrigeration(60);
- break;
-
- case SPWPN_DRAINING:
- strcat(info," thirsts for the lives of mortals!");
- mpr(info);
- drain_exp();
- break;
-
- case SPWPN_VENOM:
- strcat(info, " seems more permanently poisoned.");
- mpr(info);
- cast_toxic_radiance();
- break;
-
- case SPWPN_DISTORTION:
- // [dshaligram] Attempting to fix a distortion brand gets you a free
- // distortion effect, and no permabranding. Sorry, them's the breaks.
- strcat(info, " twongs alarmingly.");
- mpr(info);
-
- // from unwield_item
- miscast_effect( SPTYP_TRANSLOCATION, 9, 90, 100,
- "a distortion effect" );
- success = false;
- break;
-
- default:
- success = false;
- break;
- }
-
- if (success)
- you.duration[DUR_WEAPON_BRAND] = 0;
-
- return (success);
-}
-
-bool enchant_weapon( int which_stat, bool quiet )
-{
- const int wpn = you.equip[ EQ_WEAPON ];
- bool affected = true;
- int enchant_level;
- char str_pass[ ITEMNAME_SIZE ];
-
- if (wpn == -1
- || (you.inv[ wpn ].base_type != OBJ_WEAPONS
- && you.inv[ wpn ].base_type != OBJ_MISSILES))
- {
- if (!quiet)
- canned_msg(MSG_NOTHING_HAPPENS);
-
- return (false);
- }
-
- you.wield_change = true;
-
- // missiles only have one stat
- if (you.inv[ wpn ].base_type == OBJ_MISSILES)
- which_stat = ENCHANT_TO_HIT;
-
- if (which_stat == ENCHANT_TO_HIT)
- enchant_level = you.inv[ wpn ].plus;
- else
- enchant_level = you.inv[ wpn ].plus2;
-
- // artefacts can't be enchanted, but scrolls still remove curses
- if (you.inv[ wpn ].base_type == OBJ_WEAPONS
- && (is_fixed_artefact( you.inv[wpn] )
- || is_random_artefact( you.inv[wpn] )))
- {
- affected = false;
- }
-
- if (enchant_level >= 4 && random2(9) < enchant_level)
- {
- affected = false;
- }
-
- // if it isn't affected by the enchantment, it will still
- // be uncursed:
- if (!affected)
- {
- if (item_cursed( you.inv[you.equip[EQ_WEAPON]] ))
- {
- if (!quiet)
- {
- in_name(you.equip[EQ_WEAPON], DESC_CAP_YOUR, str_pass);
- strcpy(info, str_pass);
- strcat(info, " glows silver for a moment.");
- mpr(info);
- }
-
- do_uncurse_item( you.inv[you.equip[EQ_WEAPON]] );
-
- return (true);
- }
- else
- {
- if (!quiet)
- canned_msg(MSG_NOTHING_HAPPENS);
-
- return (false);
- }
- }
-
- // vVvVv This is *here* (as opposed to lower down) for a reason!
- in_name( wpn, DESC_CAP_YOUR, str_pass );
- strcpy( info, str_pass );
-
- do_uncurse_item( you.inv[ wpn ] );
-
- if (you.inv[ wpn ].base_type == OBJ_WEAPONS)
- {
- if (which_stat == ENCHANT_TO_DAM)
- {
- you.inv[ wpn ].plus2++;
-
- if (!quiet)
- {
- strcat(info, " glows red for a moment.");
- mpr(info);
- }
- }
- else if (which_stat == ENCHANT_TO_HIT)
- {
- you.inv[ wpn ].plus++;
-
- if (!quiet)
- {
- strcat(info, " glows green for a moment.");
- mpr(info);
- }
- }
- }
- else if (you.inv[ wpn ].base_type == OBJ_MISSILES)
- {
- strcat( info, (you.inv[ wpn ].quantity > 1) ? " glow"
- : " glows" );
-
- strcat(info, " red for a moment.");
-
- you.inv[ wpn ].plus++;
- }
-
- return (true);
-}
-
-static bool enchant_armour( void )
-{
- // NOTE: It is assumed that armour which changes in this way does
- // not change into a form of armour with a different evasion modifier.
- char str_pass[ ITEMNAME_SIZE ];
- int nthing = you.equip[EQ_BODY_ARMOUR];
-
- if (nthing != -1
- && (you.inv[nthing].sub_type == ARM_DRAGON_HIDE
- || you.inv[nthing].sub_type == ARM_ICE_DRAGON_HIDE
- || you.inv[nthing].sub_type == ARM_STEAM_DRAGON_HIDE
- || you.inv[nthing].sub_type == ARM_MOTTLED_DRAGON_HIDE
- || you.inv[nthing].sub_type == ARM_STORM_DRAGON_HIDE
- || you.inv[nthing].sub_type == ARM_GOLD_DRAGON_HIDE
- || you.inv[nthing].sub_type == ARM_SWAMP_DRAGON_HIDE
- || you.inv[nthing].sub_type == ARM_TROLL_HIDE))
- {
- in_name( you.equip[EQ_BODY_ARMOUR], DESC_CAP_YOUR, str_pass );
- strcpy(info, str_pass);
- strcat(info, " glows purple and changes!");
- mpr(info);
-
- you.redraw_armour_class = 1;
-
- hide2armour(you.inv[nthing]);
- return (true);
- }
-
- // pick random piece of armour
- int count = 0;
- int affected_slot = EQ_WEAPON;
-
- for (int i = EQ_CLOAK; i <= EQ_BODY_ARMOUR; i++)
- {
- if (you.equip[i] != -1)
- {
- count++;
- if (one_chance_in( count ))
- affected_slot = i;
- }
- }
-
- // no armour == no enchantment
- if (affected_slot == EQ_WEAPON)
- {
- canned_msg(MSG_NOTHING_HAPPENS);
- return (false);
- }
-
- bool affected = true;
- item_def &item = you.inv[you.equip[ affected_slot ]];
-
- if (is_random_artefact( item )
- || ((item.sub_type >= ARM_CLOAK && item.sub_type <= ARM_BOOTS)
- && item.plus >= 2)
- || ((item.sub_type == ARM_SHIELD
- || item.sub_type == ARM_BUCKLER
- || item.sub_type == ARM_LARGE_SHIELD)
- && item.plus >= 2)
- || (item.plus >= 3 && random2(8) < item.plus))
- {
- affected = false;
- }
-
- // even if not affected, it may be uncursed.
- if (!affected)
- {
- if (item_cursed( item ))
- {
- item_name(item, DESC_CAP_YOUR, str_pass);
- strcpy(info, str_pass);
- strcat(info, " glows silver for a moment.");
- mpr(info);
-
- do_uncurse_item( item );
- return (true);
- }
- else
- {
- canned_msg( MSG_NOTHING_HAPPENS );
- return (false);
- }
- }
-
- // vVvVv This is *here* for a reason!
- item_name(item, DESC_CAP_YOUR, str_pass);
- strcpy(info, str_pass);
- strcat(info, " glows green for a moment.");
- mpr(info);
-
- item.plus++;
-
- do_uncurse_item( item );
- you.redraw_armour_class = 1;
- return (true);
-}
-
-static void handle_read_book( int item_slot )
-{
- int spell, spell_index, nthing;
-
- if (you.inv[item_slot].sub_type == BOOK_DESTRUCTION)
- {
- if (silenced(you.x_pos, you.y_pos))
- {
- mpr("This book does not work if you cannot read it aloud!");
- return;
- }
-
- tome_of_power(item_slot);
- return;
- }
- else if (you.inv[item_slot].sub_type == BOOK_MANUAL)
- {
- skill_manual(item_slot);
- return;
- }
- else
- {
- // Spellbook
- spell = read_book( you.inv[item_slot], RBOOK_READ_SPELL );
- }
-
- if (spell < 'a' || spell > 'h') //jmf: was 'g', but 8=h
- {
- mesclr( true );
- return;
- }
-
- spell_index = letter_to_index( spell );
-
- nthing = which_spell_in_book(you.inv[item_slot].sub_type, spell_index);
- if (nthing == SPELL_NO_SPELL)
- {
- mesclr( true );
- return;
- }
-
- describe_spell( nthing );
- redraw_screen();
-
- mesclr( true );
- return;
-}
-
-void read_scroll(void)
-{
- int affected = 0;
- int i;
- int count;
- int nthing;
- struct bolt beam;
- char str_pass[ ITEMNAME_SIZE ];
-
- // added: scroll effects are never tracers.
- beam.is_tracer = false;
-
- if (you.berserker)
- {
- canned_msg(MSG_TOO_BERSERK);
- return;
- }
-
- if (inv_count() < 1)
- {
- canned_msg(MSG_NOTHING_CARRIED);
- return;
- }
-
- int item_slot = prompt_invent_item( "Read which item?", OBJ_SCROLLS );
- if (item_slot == PROMPT_ABORT)
- {
- canned_msg( MSG_OK );
- return;
- }
-
- if (you.inv[item_slot].base_type != OBJ_BOOKS
- && you.inv[item_slot].base_type != OBJ_SCROLLS)
- {
- mpr("You can't read that!");
- return;
- }
-
- // here we try to read a book {dlb}:
- if (you.inv[item_slot].base_type == OBJ_BOOKS)
- {
- handle_read_book( item_slot );
- return;
- }
-
- if (silenced(you.x_pos, you.y_pos))
- {
- mpr("Magic scrolls do not work when you're silenced!");
- return;
- }
-
- // ok - now we FINALLY get to read a scroll !!! {dlb}
- you.turn_is_over = 1;
-
- // imperfect vision prevents players from reading actual content {dlb}:
- if (you.mutation[MUT_BLURRY_VISION]
- && random2(5) < you.mutation[MUT_BLURRY_VISION])
- {
- mpr((you.mutation[MUT_BLURRY_VISION] == 3 && one_chance_in(3))
- ? "This scroll appears to be blank."
- : "The writing blurs in front of your eyes.");
- return;
- }
-
- // decrement and handle inventory if any scroll other than paper {dlb}:
- const int scroll_type = you.inv[item_slot].sub_type;
- if (scroll_type != SCR_PAPER)
- {
- mpr("As you read the scroll, it crumbles to dust.");
- // Actual removal of scroll done afterwards. -- bwr
- }
-
- // scrolls of paper are also exempted from this handling {dlb}:
- if (scroll_type != SCR_PAPER)
- {
- if (you.conf)
- {
- random_uselessness(random2(9), item_slot);
- dec_inv_item_quantity( item_slot, 1 );
- return;
- }
-
- if (!you.skills[SK_SPELLCASTING])
- exercise(SK_SPELLCASTING, (coinflip()? 2 : 1));
- }
-
- bool id_the_scroll = true; // to prevent unnecessary repetition
-
- // it is the exception, not the rule, that
- // the scroll will not be identified {dlb}:
- switch (scroll_type)
- {
- case SCR_PAPER:
- // remember paper scrolls handled as special case above, too:
- mpr("This scroll appears to be blank.");
- break;
-
- case SCR_RANDOM_USELESSNESS:
- random_uselessness(random2(9), item_slot);
- id_the_scroll = false;
- break;
-
- case SCR_BLINKING:
- blink();
- break;
-
- case SCR_TELEPORTATION:
- you_teleport();
- break;
-
- case SCR_REMOVE_CURSE:
- if (!remove_curse(false))
- id_the_scroll = false;
- break;
-
- case SCR_DETECT_CURSE:
- if (!detect_curse(false))
- id_the_scroll = false;
- break;
-
- case SCR_ACQUIREMENT:
- acquirement(OBJ_RANDOM, AQ_SCROLL);
- break;
-
- case SCR_FEAR:
- if (!mass_enchantment(ENCH_FEAR, 1000, MHITYOU))
- id_the_scroll = false;
- break;
-
- case SCR_NOISE:
- mpr("You hear a loud clanging noise!");
- noisy( 25, you.x_pos, you.y_pos );
- break;
-
- case SCR_SUMMONING:
- if (create_monster( MONS_ABOMINATION_SMALL, ENCH_ABJ_VI, BEH_FRIENDLY,
- you.x_pos, you.y_pos, you.pet_target, 250 ) != -1)
- {
- mpr("A horrible Thing appears!");
- }
- break;
-
- case SCR_FORGETFULNESS:
- mpr("You feel momentarily disoriented.");
- if (!wearing_amulet(AMU_CLARITY))
- forget_map(50 + random2(50));
- break;
-
- case SCR_MAGIC_MAPPING:
- if (you.level_type == LEVEL_LABYRINTH
- || you.level_type == LEVEL_ABYSS)
- {
- mpr("You feel momentarily disoriented.");
- id_the_scroll = false;
- }
- else
- {
- mpr("You feel aware of your surroundings.");
- magic_mapping(50, 90 + random2(11));
- }
- break;
-
- case SCR_TORMENT:
- torment( you.x_pos, you.y_pos );
-
- // is only naughty if you know you're doing it
- if (get_ident_type( OBJ_SCROLLS, SCR_TORMENT ) == ID_KNOWN_TYPE)
- {
- did_god_conduct(DID_UNHOLY, 10);
- }
- break;
-
- case SCR_IMMOLATION:
- mpr("The scroll explodes in your hands!");
-
- beam.type = SYM_BURST;
- beam.damage = dice_def( 3, 10 );
- // unsure about this // BEAM_EXPLOSION instead? {dlb}
- beam.flavour = BEAM_FIRE;
- beam.target_x = you.x_pos;
- beam.target_y = you.y_pos;
- strcpy(beam.beam_name, "fiery explosion");
- beam.colour = RED;
- // your explosion, (not someone else's explosion)
- beam.thrower = KILL_YOU;
- beam.aux_source = "reading a scroll of immolation";
- beam.ex_size = 2;
- beam.is_explosion = true;
-
- explosion(beam);
- break;
-
- case SCR_IDENTIFY:
- set_ident_flags( you.inv[item_slot], ISFLAG_IDENT_MASK );
-
- // important {dlb}
- set_ident_type( OBJ_SCROLLS, SCR_IDENTIFY, ID_KNOWN_TYPE );
-
- identify(-1);
- you.wield_change = true;
- break;
-
- case SCR_CURSE_WEAPON:
- nthing = you.equip[EQ_WEAPON];
-
- if (nthing == -1
- || you.inv[nthing].base_type != OBJ_WEAPONS
- || item_cursed( you.inv[nthing] ))
- {
- canned_msg(MSG_NOTHING_HAPPENS);
- id_the_scroll = false;
- }
- else
- {
- in_name( nthing, DESC_CAP_YOUR, str_pass );
- strcpy(info, str_pass);
- strcat(info, " glows black for a moment.");
- mpr(info);
-
- do_curse_item( you.inv[nthing] );
- you.wield_change = true;
- }
- break;
-
- // everything [in the switch] below this line is a nightmare {dlb}:
- case SCR_ENCHANT_WEAPON_I:
- id_the_scroll = enchant_weapon( ENCHANT_TO_HIT );
- break;
-
- case SCR_ENCHANT_WEAPON_II:
- id_the_scroll = enchant_weapon( ENCHANT_TO_DAM );
- break;
-
- case SCR_ENCHANT_WEAPON_III:
- if (you.equip[ EQ_WEAPON ] != -1)
- {
- if (!affix_weapon_enchantment())
- {
- in_name( you.equip[EQ_WEAPON], DESC_CAP_YOUR, str_pass );
- strcpy( info, str_pass );
- strcat( info, " glows bright yellow for a while." );
- mpr( info );
-
- enchant_weapon( ENCHANT_TO_HIT, true );
-
- if (coinflip())
- enchant_weapon( ENCHANT_TO_HIT, true );
-
- enchant_weapon( ENCHANT_TO_DAM, true );
-
- if (coinflip())
- enchant_weapon( ENCHANT_TO_DAM, true );
-
- do_uncurse_item( you.inv[you.equip[EQ_WEAPON]] );
- }
- }
- else
- {
- canned_msg(MSG_NOTHING_HAPPENS);
- id_the_scroll = false;
- }
- break;
-
- case SCR_VORPALISE_WEAPON:
- nthing = you.equip[EQ_WEAPON];
- if (nthing == -1
- || you.inv[ nthing ].base_type != OBJ_WEAPONS
- || (you.inv[ nthing ].base_type == OBJ_WEAPONS
- && (is_fixed_artefact( you.inv[ nthing ] )
- || is_random_artefact( you.inv[ nthing ] )
- || you.inv[nthing].sub_type == WPN_BLOWGUN)))
- {
- canned_msg(MSG_NOTHING_HAPPENS);
- break;
- }
-
- in_name(nthing, DESC_CAP_YOUR, str_pass);
-
- strcpy(info, str_pass);
- strcat(info, " emits a brilliant flash of light!");
- mpr(info);
-
- alert_nearby_monsters();
-
- if (get_weapon_brand( you.inv[nthing] ) != SPWPN_NORMAL)
- {
- mpr("You feel strangely frustrated.");
- break;
- }
-
- you.wield_change = true;
- set_item_ego_type( you.inv[nthing], OBJ_WEAPONS, SPWPN_VORPAL );
- break;
-
- case SCR_RECHARGING:
- nthing = you.equip[EQ_WEAPON];
-
- if (nthing != -1
- && !is_random_artefact( you.inv[nthing] )
- && !is_fixed_artefact( you.inv[nthing] )
- && get_weapon_brand( you.inv[nthing] ) == SPWPN_ELECTROCUTION)
- {
- id_the_scroll = !enchant_weapon( ENCHANT_TO_DAM );
- break;
- }
-
- if (!recharge_wand())
- {
- canned_msg(MSG_NOTHING_HAPPENS);
- id_the_scroll = false;
- }
- break;
-
- case SCR_ENCHANT_ARMOUR:
- id_the_scroll = enchant_armour();
- break;
-
- case SCR_CURSE_ARMOUR:
- // make sure there's something to curse first
- count = 0;
- affected = EQ_WEAPON;
- for (i = EQ_CLOAK; i <= EQ_BODY_ARMOUR; i++)
- {
- if (you.equip[i] != -1 && !item_cursed( you.inv[you.equip[i]] ))
- {
- count++;
- if (one_chance_in( count ))
- affected = i;
- }
- }
-
- if (affected == EQ_WEAPON)
- {
- canned_msg(MSG_NOTHING_HAPPENS);
- id_the_scroll = false;
- break;
- }
-
- // make the name _before_ we curse it
- in_name( you.equip[affected], DESC_CAP_YOUR, str_pass );
- do_curse_item( you.inv[you.equip[affected]] );
-
- strcpy(info, str_pass);
- strcat(info, " glows black for a moment.");
- mpr(info);
- break;
- } // end switch
-
- // finally, destroy and identify the scroll
- if (scroll_type != SCR_PAPER)
- {
- dec_inv_item_quantity( item_slot, 1 );
- }
-
- set_ident_type( OBJ_SCROLLS, scroll_type,
- (id_the_scroll) ? ID_KNOWN_TYPE : ID_TRIED_TYPE );
-} // end read_scroll()
-
-void original_name(void)
-{
- int item_slot = prompt_invent_item( "Examine which item?", -1 );
- if (item_slot == PROMPT_ABORT)
- {
- canned_msg( MSG_OK );
- return;
- }
-
- describe_item( you.inv[item_slot] );
- redraw_screen();
-} // end original_name()
-
-void use_randart(unsigned char item_wield_2)
-{
- ASSERT( is_random_artefact( you.inv[ item_wield_2 ] ) );
-
- FixedVector< char, RA_PROPERTIES > proprt;
- randart_wpn_properties( you.inv[item_wield_2], proprt );
-
- if (proprt[RAP_AC])
- you.redraw_armour_class = 1;
-
- if (proprt[RAP_EVASION])
- you.redraw_evasion = 1;
-
- // modify ability scores
- modify_stat( STAT_STRENGTH, proprt[RAP_STRENGTH], true );
- modify_stat( STAT_INTELLIGENCE, proprt[RAP_INTELLIGENCE], true );
- modify_stat( STAT_DEXTERITY, proprt[RAP_DEXTERITY], true );
-
- if (proprt[RAP_NOISES])
- you.special_wield = 50 + proprt[RAP_NOISES];
-}
diff --git a/stone_soup/crawl-ref/source/item_use.h b/stone_soup/crawl-ref/source/item_use.h
deleted file mode 100644
index 93d3ec3098..0000000000
--- a/stone_soup/crawl-ref/source/item_use.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * File: item_use.cc
- * Summary: Functions for making use of inventory items.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <2> 5/26/99 JDJ Exposed armour_prompt. takeoff_armour takes an index argument.
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef ITEM_USE_H
-#define ITEM_USE_H
-
-
-#include <string>
-#include "externs.h"
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - item_use
- * *********************************************************************** */
-bool armour_prompt(const std::string & mesg, int *index);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - item_use - items
- * *********************************************************************** */
-bool takeoff_armour(int index);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void drink(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void original_name(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-bool puton_ring(int slot = -1, bool prompt_finger = true);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void read_scroll(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-bool remove_ring(int slot = -1);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-int get_fire_item_index(void);
-void shoot_thing(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void throw_anything(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void wear_armour( void );
-
-// last updated 10Sept2001 {bwr}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-bool do_wear_armour( int item, bool quiet );
-
-struct item_def;
-// last updated 30May2003 {ds}
-/* ***********************************************************************
- * called from: food
- * *********************************************************************** */
-bool can_wield(const item_def& weapon);
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-bool wield_weapon(bool auto_wield, int slot = -1, bool show_we_messages = true);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void zap_wand(void);
-
-
-// last updated 15jan2001 {gdl}
-/* ***********************************************************************
- * called from: item_use food
- * *********************************************************************** */
-void wield_effects(int item_wield_2, bool showMsgs);
-
-// last updated 10sept2001 {bwr}
-/* ***********************************************************************
- * called from: delay.cc item_use.cc it_use2.cc
- * *********************************************************************** */
-void use_randart( unsigned char item_wield_2 );
-
-bool puton_item(int slot, bool prompt_finger = true);
-
-bool enchant_weapon( int which_stat, bool quiet = false );
-
-bool throw_it(struct bolt &pbolt, int throw_2, monsters *dummy_target = NULL);
-
-#endif
diff --git a/stone_soup/crawl-ref/source/itemname.cc b/stone_soup/crawl-ref/source/itemname.cc
deleted file mode 100644
index 89c7441b45..0000000000
--- a/stone_soup/crawl-ref/source/itemname.cc
+++ /dev/null
@@ -1,2421 +0,0 @@
-/*
- * File: itemname.cc
- * Summary: Misc functions.
- * Written by: Linley Henzell
- *
- * Modified for Crawl Reference by $Author$ on $Date$
- *
- * Change History (most recent first):
- *
- * <4> 9/09/99 BWR Added hands_required function
- * <3> 6/13/99 BWR Upped the base AC for heavy armour
- * <2> 5/20/99 BWR Extended screen lines support
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "itemname.h"
-
-#include <ctype.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#ifdef DOS
-#include <conio.h>
-#endif
-
-#include "externs.h"
-
-#include "invent.h"
-#include "itemprop.h"
-#include "macro.h"
-#include "mon-util.h"
-#include "randart.h"
-#include "skills2.h"
-#include "stuff.h"
-#include "wpn-misc.h"
-#include "view.h"
-
-
-char id[NUM_IDTYPE][MAX_SUBTYPES];
-
-static bool is_random_name_space( char let );
-static bool is_random_name_vowel( char let);
-static char item_name_2( const item_def &item, char buff[ ITEMNAME_SIZE ], bool terse );
-
-static char retvow(int sed);
-static char retlet(int sed );
-
-bool is_vowel( const char chr )
-{
- const char low = tolower( chr );
-
- return (low == 'a' || low == 'e' || low == 'i' || low == 'o' || low == 'u');
-}
-
-bool item_type_known( const item_def &item )
-{
- return item_ident(item, ISFLAG_KNOW_TYPE)
- || (item.base_type == OBJ_JEWELLERY
- && id[IDTYPE_JEWELLERY][item.sub_type] == ID_KNOWN_TYPE);
-}
-
-// it_name() and in_name() are now somewhat obsolete now that itemname
-// takes item_def, so consider them depricated.
-void it_name( int itn, char des, char buff[ ITEMNAME_SIZE ], bool terse )
-{
- item_name( mitm[itn], des, buff, terse );
-} // end it_name()
-
-
-void in_name( int inn, char des, char buff[ ITEMNAME_SIZE ], bool terse )
-{
- item_name( you.inv[inn], des, buff, terse );
-} // end in_name()
-
-// quant_name is usful since it prints out a different number of items
-// than the item actually contains.
-void quant_name( const item_def &item, int quant, char des,
- char buff[ ITEMNAME_SIZE ], bool terse )
-{
- // item_name now requires a "real" item, so we'll mangle a tmp
- item_def tmp = item;
- tmp.quantity = quant;
-
- item_name( tmp, des, buff, terse );
-} // end quant_name()
-
-char item_name( const item_def &item, char descrip, char buff[ ITEMNAME_SIZE ],
- bool terse )
-{
- const int item_clas = item.base_type;
- const int item_typ = item.sub_type;
- const int it_quant = item.quantity;
-
- char tmp_quant[20];
- char itm_name[ ITEMNAME_SIZE ] = "";
-
- item_name_2( item, itm_name, terse );
-
- buff[0] = '\0';
-
- if (descrip == DESC_INVENTORY_EQUIP || descrip == DESC_INVENTORY)
- {
- if (in_inventory(item)) // actually in inventory
- snprintf( buff, ITEMNAME_SIZE, (terse) ? "%c) " : "%c - ",
- index_to_letter( item.link ) );
- else
- descrip = DESC_CAP_A;
- }
-
- if (terse)
- descrip = DESC_PLAIN;
-
- if (item_clas == OBJ_ORBS
- || (item_ident( item, ISFLAG_KNOW_TYPE )
- && ((item_clas == OBJ_MISCELLANY
- && item_typ == MISC_HORN_OF_GERYON)
- || (is_fixed_artefact( item )
- || (is_random_artefact( item ))))))
- {
- // artefacts always get "the" unless we just want the plain name
- switch (descrip)
- {
- case DESC_CAP_A:
- case DESC_CAP_YOUR:
- case DESC_CAP_THE:
- strncat(buff, "The ", ITEMNAME_SIZE );
- break;
- case DESC_NOCAP_A:
- case DESC_NOCAP_YOUR:
- case DESC_NOCAP_THE:
- case DESC_NOCAP_ITS:
- case DESC_INVENTORY_EQUIP:
- case DESC_INVENTORY:
- strncat(buff, "the ", ITEMNAME_SIZE );
- break;
- default:
- case DESC_PLAIN:
- break;
- }
- }
- else if (it_quant > 1)
- {
- switch (descrip)
- {
- case DESC_CAP_THE:
- strncat(buff, "The ", ITEMNAME_SIZE );
- break;
- case DESC_NOCAP_THE:
- strncat(buff, "the ", ITEMNAME_SIZE );
- break;
- case DESC_CAP_A:
- case DESC_NOCAP_A:
- case DESC_INVENTORY_EQUIP:
- case DESC_INVENTORY:
- break;
- case DESC_CAP_YOUR:
- strncat(buff, "Your ", ITEMNAME_SIZE );
- break;
- case DESC_NOCAP_YOUR:
- strncat(buff, "your ", ITEMNAME_SIZE );
- break;
- case DESC_NOCAP_ITS:
- strncat(buff, "its ", ITEMNAME_SIZE );
- break;
- case DESC_PLAIN:
- default:
- break;
- }
-
- itoa(it_quant, tmp_quant, 10);
- strncat(buff, tmp_quant, ITEMNAME_SIZE );
- strncat(buff, " ", ITEMNAME_SIZE );
- }
- else
- {
- switch (descrip)
- {
- case DESC_CAP_THE:
- strncat(buff, "The ", ITEMNAME_SIZE );
- break;
- case DESC_NOCAP_THE:
- strncat(buff, "the ", ITEMNAME_SIZE );
- break;
- case DESC_CAP_A:
- strncat(buff, "A", ITEMNAME_SIZE );
-
- if (itm_name[0] == 'a' || itm_name[0] == 'e' || itm_name[0] == 'i'
- || itm_name[0] == 'o' || itm_name[0] == 'u')
- {
- strncat(buff, "n", ITEMNAME_SIZE );
- }
-
- strncat(buff, " ", ITEMNAME_SIZE );
- break; // A/An
-
- case DESC_NOCAP_A:
- case DESC_INVENTORY_EQUIP:
- case DESC_INVENTORY:
- strncat(buff, "a", ITEMNAME_SIZE );
-
- if (itm_name[0] == 'a' || itm_name[0] == 'e' || itm_name[0] == 'i'
- || itm_name[0] == 'o' || itm_name[0] == 'u')
- {
- strncat(buff, "n", ITEMNAME_SIZE );
- }
-
- strncat(buff, " ", ITEMNAME_SIZE );
- break; // a/an
-
- case DESC_CAP_YOUR:
- strncat(buff, "Your ", ITEMNAME_SIZE );
- break;
- case DESC_NOCAP_YOUR:
- strncat(buff, "your ", ITEMNAME_SIZE );
- break;
- case DESC_NOCAP_ITS:
- strncat(buff, "its ", ITEMNAME_SIZE );
- break;
- case DESC_PLAIN:
- default:
- break;
- }
- } // end of else
-
- strncat(buff, itm_name, ITEMNAME_SIZE );
-
- if (descrip == DESC_INVENTORY_EQUIP && item.x == -1 && item.y == -1)
- {
- ASSERT( item.link != -1 );
-
- if (item.link == you.equip[EQ_WEAPON])
- {
- if (you.inv[ you.equip[EQ_WEAPON] ].base_type == OBJ_WEAPONS
- || item_is_staff( you.inv[ you.equip[EQ_WEAPON] ] ))
- {
- strncat( buff, " (weapon)", ITEMNAME_SIZE );
- }
- else
- {
- strncat( buff, " (in hand)", ITEMNAME_SIZE );
- }
- }
- else if (item.link == you.equip[EQ_CLOAK]
- || item.link == you.equip[EQ_HELMET]
- || item.link == you.equip[EQ_GLOVES]
- || item.link == you.equip[EQ_BOOTS]
- || item.link == you.equip[EQ_SHIELD]
- || item.link == you.equip[EQ_BODY_ARMOUR])
- {
- strncat( buff, " (worn)", ITEMNAME_SIZE );
- }
- else if (item.link == you.equip[EQ_LEFT_RING])
- {
- strncat( buff, " (left hand)", ITEMNAME_SIZE );
- }
- else if (item.link == you.equip[EQ_RIGHT_RING])
- {
- strncat( buff, " (right hand)", ITEMNAME_SIZE );
- }
- else if (item.link == you.equip[EQ_AMULET])
- {
- strncat( buff, " (around neck)", ITEMNAME_SIZE );
- }
- }
-
- return (1);
-} // end item_name()
-
-
-// Note that "terse" is only currently used for the "in hand" listing on
-// the game screen.
-static char item_name_2( const item_def &item, char buff[ITEMNAME_SIZE],
- bool terse )
-{
- const int item_clas = item.base_type;
- const int item_typ = item.sub_type;
- const int it_plus = item.plus;
- const int item_plus2 = item.plus2;
- const int it_quant = item.quantity;
-
- char tmp_quant[20];
- char tmp_buff[ITEMNAME_SIZE];
- int brand;
- unsigned char sparm;
-
- buff[0] = '\0';
-
- switch (item_clas)
- {
- case OBJ_WEAPONS:
- if (item_ident( item, ISFLAG_KNOW_CURSE ) && !terse)
- {
- // We don't bother printing "uncursed" if the item is identified
- // for pluses (it's state should be obvious), this is so that
- // the weapon name is kept short (there isn't a lot of room
- // for the name on the main screen). If you're going to change
- // this behaviour, *please* make it so that there is an option
- // that maintains this behaviour. -- bwr
- if (item_cursed( item ))
- strncat(buff, "cursed ", ITEMNAME_SIZE );
- else if (Options.show_uncursed
- && !item_ident( item, ISFLAG_KNOW_PLUSES ))
- {
- strncat(buff, "uncursed ", ITEMNAME_SIZE );
- }
- }
-
- if (item_ident( item, ISFLAG_KNOW_PLUSES ))
- {
- if (it_plus == 0 && item_plus2 == 0)
- strncat(buff, "+0 ", ITEMNAME_SIZE );
- else
- {
- if (it_plus >= 0)
- strncat( buff, "+" , ITEMNAME_SIZE );
-
- itoa( it_plus, tmp_quant, 10 );
- strncat( buff, tmp_quant , ITEMNAME_SIZE );
-
- if (it_plus != item_plus2 || !terse)
- {
- strncat( buff, "," , ITEMNAME_SIZE );
-
- if (item_plus2 >= 0)
- strncat(buff, "+", ITEMNAME_SIZE );
-
- itoa( item_plus2, tmp_quant, 10 );
- strncat( buff, tmp_quant , ITEMNAME_SIZE );
- }
-
- strncat( buff, " " , ITEMNAME_SIZE );
- }
- }
-
- if (is_random_artefact( item ))
- {
- strncat( buff, randart_name(item), ITEMNAME_SIZE );
- break;
- }
-
- if (is_fixed_artefact( item ))
- {
- if (item_ident( item, ISFLAG_KNOW_TYPE ))
- {
- strncat(buff,
- (item.special == SPWPN_SINGING_SWORD) ? "Singing Sword" :
- (item.special == SPWPN_WRATH_OF_TROG) ? "Wrath of Trog" :
- (item.special == SPWPN_SCYTHE_OF_CURSES) ? "Scythe of Curses" :
- (item.special == SPWPN_MACE_OF_VARIABILITY) ? "Mace of Variability" :
- (item.special == SPWPN_GLAIVE_OF_PRUNE) ? "Glaive of Prune" :
- (item.special == SPWPN_SCEPTRE_OF_TORMENT) ? "Sceptre of Torment" :
- (item.special == SPWPN_SWORD_OF_ZONGULDROK) ? "Sword of Zonguldrok" :
- (item.special == SPWPN_SWORD_OF_CEREBOV) ? "Sword of Cerebov" :
- (item.special == SPWPN_STAFF_OF_DISPATER) ? "Staff of Dispater" :
- (item.special == SPWPN_SCEPTRE_OF_ASMODEUS) ? "Sceptre of Asmodeus" :
- (item.special == SPWPN_SWORD_OF_POWER) ? "Sword of Power" :
- (item.special == SPWPN_KNIFE_OF_ACCURACY) ? "Knife of Accuracy" :
- (item.special == SPWPN_STAFF_OF_OLGREB) ? "Staff of Olgreb" :
- (item.special == SPWPN_VAMPIRES_TOOTH) ? "Vampire's Tooth" :
- (item.special == SPWPN_STAFF_OF_WUCAD_MU) ? "Staff of Wucad Mu"
- : "Brodale's Buggy Bola",
- ITEMNAME_SIZE );
- }
- else
- {
- strncat(buff,
- (item.special == SPWPN_SINGING_SWORD) ? "golden long sword" :
- (item.special == SPWPN_WRATH_OF_TROG) ? "bloodstained battleaxe" :
- (item.special == SPWPN_SCYTHE_OF_CURSES) ? "warped scythe" :
- (item.special == SPWPN_MACE_OF_VARIABILITY) ? "shimmering mace" :
- (item.special == SPWPN_GLAIVE_OF_PRUNE) ? "purple glaive" :
- (item.special == SPWPN_SCEPTRE_OF_TORMENT) ? "jeweled golden mace" :
- (item.special == SPWPN_SWORD_OF_ZONGULDROK) ? "bone long sword" :
- (item.special == SPWPN_SWORD_OF_CEREBOV) ? "great serpentine sword" :
- (item.special == SPWPN_STAFF_OF_DISPATER) ? "golden staff" :
- (item.special == SPWPN_SCEPTRE_OF_ASMODEUS) ? "ruby sceptre" :
- (item.special == SPWPN_SWORD_OF_POWER) ? "chunky great sword" :
- (item.special == SPWPN_KNIFE_OF_ACCURACY) ? "thin dagger" :
- (item.special == SPWPN_STAFF_OF_OLGREB) ? "green glowing staff" :
- (item.special == SPWPN_VAMPIRES_TOOTH) ? "ivory dagger" :
- (item.special == SPWPN_STAFF_OF_WUCAD_MU) ? "ephemeral quarterstaff"
- : "buggy bola",
- ITEMNAME_SIZE );
- }
- break;
- }
-
- // Now that we can have "glowing elven" weapons, it's
- // probably a good idea to cut out the descriptive
- // term once it's become obsolete. -- bwr
- if (!item_ident( item, ISFLAG_KNOW_PLUSES ) && !terse)
- {
- switch (get_equip_desc( item ))
- {
- case ISFLAG_RUNED:
- strncat(buff, "runed ", ITEMNAME_SIZE );
- break;
- case ISFLAG_GLOWING:
- strncat(buff, "glowing ", ITEMNAME_SIZE );
- break;
- }
- }
-
- // always give racial type (it does have game effects)
-
- switch (get_equip_race( item ))
- {
- case ISFLAG_ORCISH:
- strncat( buff, (terse) ? "orc " : "orcish ", ITEMNAME_SIZE );
- break;
- case ISFLAG_ELVEN:
- strncat( buff, (terse) ? "elf " : "elven ", ITEMNAME_SIZE );
- break;
- case ISFLAG_DWARVEN:
- strncat( buff, (terse) ? "dwarf " : "dwarven ", ITEMNAME_SIZE );
- break;
- }
-
- brand = get_weapon_brand( item );
-
- if (item_ident( item, ISFLAG_KNOW_TYPE ) && !terse)
- {
- if (brand == SPWPN_VAMPIRICISM)
- strncat(buff, "vampiric ", ITEMNAME_SIZE );
- } // end if
-
- standard_name_weap( item_typ, tmp_buff );
- strncat( buff, tmp_buff, ITEMNAME_SIZE );
-
- if (item_ident( item, ISFLAG_KNOW_TYPE ))
- {
- switch (brand)
- {
- case SPWPN_NORMAL:
- break;
- case SPWPN_FLAMING:
- strncat(buff, (terse) ? " (flame)" : " of flaming", ITEMNAME_SIZE );
- break;
- case SPWPN_FREEZING:
- strncat(buff, (terse) ? " (freeze)" : " of freezing", ITEMNAME_SIZE );
- break;
- case SPWPN_HOLY_WRATH:
- strncat(buff, (terse) ? " (holy)" : " of holy wrath", ITEMNAME_SIZE );
- break;
- case SPWPN_ELECTROCUTION:
- strncat(buff, (terse) ? " (elec)" : " of electrocution", ITEMNAME_SIZE );
- break;
- case SPWPN_ORC_SLAYING:
- strncat(buff, (terse) ? " (slay orc)" : " of orc slaying", ITEMNAME_SIZE );
- break;
- case SPWPN_VENOM:
- strncat(buff, (terse) ? " (venom)" : " of venom", ITEMNAME_SIZE );
- break;
- case SPWPN_PROTECTION:
- strncat(buff, (terse) ? " (protect)" : " of protection", ITEMNAME_SIZE );
- break;
- case SPWPN_DRAINING:
- strncat(buff, (terse) ? " (drain)" : " of draining", ITEMNAME_SIZE );
- break;
- case SPWPN_SPEED:
- strncat(buff, (terse) ? " (speed)" : " of speed", ITEMNAME_SIZE );
- break;
- case SPWPN_VORPAL:
- if (is_range_weapon( item ))
- {
- strncat(buff, (terse) ? " (velocity)" : " of velocity",
- ITEMNAME_SIZE );
- break;
- }
-
- switch (get_vorpal_type(item))
- {
- case DVORP_CRUSHING:
- strncat(buff, (terse) ? " (crush)" : " of crushing", ITEMNAME_SIZE );
- break;
- case DVORP_SLICING:
- strncat(buff, (terse) ? " (slice)" : " of slicing", ITEMNAME_SIZE );
- break;
- case DVORP_PIERCING:
- strncat(buff, (terse) ? " (pierce)" : " of piercing", ITEMNAME_SIZE );
- break;
- case DVORP_CHOPPING:
- strncat(buff, (terse) ? " (chop)" : " of chopping", ITEMNAME_SIZE );
- break;
- case DVORP_SLASHING:
- strncat(buff, (terse) ? " (slash)" : " of slashing", ITEMNAME_SIZE );
- break;
- case DVORP_STABBING:
- strncat(buff, (terse) ? " (stab)" : " of stabbing", ITEMNAME_SIZE );
- break;
- }
- break;
-
- case SPWPN_FLAME:
- strncat(buff, (terse) ? " (flame)" : " of flame", ITEMNAME_SIZE );
- break; // bows/xbows
-
- case SPWPN_FROST:
- strncat(buff, (terse) ? " (frost)" : " of frost", ITEMNAME_SIZE );
- break; // bows/xbows
-
- case SPWPN_VAMPIRICISM:
- if (terse)
- strncat( buff, " (vamp)", ITEMNAME_SIZE );
- break;
-
- case SPWPN_DISRUPTION:
- strncat(buff, (terse) ? " (disrupt)" : " of disruption", ITEMNAME_SIZE );
- break;
- case SPWPN_PAIN:
- strncat(buff, (terse) ? " (pain)" : " of pain", ITEMNAME_SIZE );
- break;
- case SPWPN_DISTORTION:
- strncat(buff, (terse) ? " (distort)" : " of distortion", ITEMNAME_SIZE );
- break;
-
- case SPWPN_REACHING:
- strncat(buff, (terse) ? " (reach)" : " of reaching", ITEMNAME_SIZE );
- break;
-
- /* 25 - 29 are randarts */
- }
- }
-
- if (item_ident(item, ISFLAG_KNOW_CURSE) && item_cursed(item) && terse)
- strncat( buff, " (curse)", ITEMNAME_SIZE );
- break;
-
- case OBJ_MISSILES:
- brand = get_ammo_brand( item );
-
- if (brand == SPMSL_POISONED || brand == SPMSL_POISONED_II)
- {
- strncat( buff, (terse) ? "poison " : "poisoned ", ITEMNAME_SIZE );
- }
-
- if (brand == SPMSL_CURARE)
- {
- strncat( buff, (terse) ? "curare " : "curare-tipped ", ITEMNAME_SIZE);
- }
-
- if (item_ident( item, ISFLAG_KNOW_PLUSES ))
- {
- if (it_plus >= 0)
- strncat(buff, "+", ITEMNAME_SIZE );
-
- itoa( it_plus, tmp_quant, 10 );
-
- strncat(buff, tmp_quant, ITEMNAME_SIZE );
- strncat(buff, " ", ITEMNAME_SIZE );
- }
-
- if (get_equip_race( item ))
- {
- int dwpn = get_equip_race( item );
-
- strncat(buff,
- (dwpn == ISFLAG_ORCISH) ? ((terse) ? "orc " : "orcish ") :
- (dwpn == ISFLAG_ELVEN) ? ((terse) ? "elf " : "elven ") :
- (dwpn == ISFLAG_DWARVEN) ? ((terse) ? "dwarf " : "dwarven ")
- : "buggy ",
- ITEMNAME_SIZE);
- }
-
- strncat(buff, (item_typ == MI_STONE) ? "stone" :
- (item_typ == MI_ARROW) ? "arrow" :
- (item_typ == MI_BOLT) ? "bolt" :
- (item_typ == MI_DART) ? "dart" :
- (item_typ == MI_NEEDLE) ? "needle" :
- (item_typ == MI_LARGE_ROCK) ? "large rock" :
- "hysterical raisin", ITEMNAME_SIZE);
- // this should probably be "" {dlb}
-
- if (it_quant > 1)
- strncat(buff, "s", ITEMNAME_SIZE );
-
- if (item_ident( item, ISFLAG_KNOW_TYPE ))
- {
- strncat( buff,
- (brand == SPMSL_FLAME) ? ((terse) ? " (flame)" : " of flame") :
- (brand == SPMSL_ICE) ? ((terse) ? " (ice)" : " of ice") :
- (brand == SPMSL_NORMAL) ? "" :
- (brand == SPMSL_POISONED) ? "" :
- (brand == SPMSL_POISONED_II) ? "" :
- (brand == SPMSL_CURARE) ? "" :
- " (buggy)", ITEMNAME_SIZE );
- }
- break;
-
- case OBJ_ARMOUR:
- if (item_ident( item, ISFLAG_KNOW_CURSE ) && !terse)
- {
- if (item_cursed( item ))
- strncat(buff, "cursed ", ITEMNAME_SIZE );
- else if (Options.show_uncursed
- && !item_ident( item, ISFLAG_KNOW_PLUSES ))
- {
- strncat(buff, "uncursed ", ITEMNAME_SIZE );
- }
- }
-
- if (item_ident( item, ISFLAG_KNOW_PLUSES ))
- {
- if (it_plus >= 0)
- strncat(buff, "+", ITEMNAME_SIZE );
-
- itoa( it_plus, tmp_quant, 10 );
-
- strncat(buff, tmp_quant, ITEMNAME_SIZE );
- strncat(buff, " ", ITEMNAME_SIZE );
- }
-
- if (item_typ == ARM_GLOVES || item_typ == ARM_BOOTS)
- {
- strncat( buff, "pair of ", ITEMNAME_SIZE );
- }
-
- if (is_random_artefact( item ))
- {
- strncat(buff, randart_armour_name(item), ITEMNAME_SIZE);
- break;
- }
-
- // Now that we can have "glowing elven" armour, it's
- // probably a good idea to cut out the descriptive
- // term once it's become obsolete. -- bwr
- if (!item_ident( item, ISFLAG_KNOW_PLUSES ) && !terse)
- {
- switch (get_equip_desc( item ))
- {
- case ISFLAG_EMBROIDERED_SHINY:
- if (item_typ == ARM_ROBE || item_typ == ARM_CLOAK
- || item_typ == ARM_GLOVES || item_typ == ARM_BOOTS)
- {
- strncat(buff, "embroidered ", ITEMNAME_SIZE );
- }
- else if (item_typ != ARM_LEATHER_ARMOUR
- && item_typ != ARM_ANIMAL_SKIN)
- {
- strncat(buff, "shiny ", ITEMNAME_SIZE );
- }
- break;
-
- case ISFLAG_RUNED:
- strncat(buff, "runed ", ITEMNAME_SIZE );
- break;
-
- case ISFLAG_GLOWING:
- strncat(buff, "glowing ", ITEMNAME_SIZE );
- break;
- }
- }
-
- // always give racial description (has game effects)
- switch (get_equip_race( item ))
- {
- case ISFLAG_ELVEN:
- strncat(buff, (terse) ? "elf " :"elven ", ITEMNAME_SIZE );
- break;
- case ISFLAG_DWARVEN:
- strncat(buff, (terse) ? "dwarf " : "dwarven ", ITEMNAME_SIZE );
- break;
- case ISFLAG_ORCISH:
- strncat(buff, (terse) ? "orc " : "orcish ", ITEMNAME_SIZE );
- break;
- } // end switch
-
- standard_name_armour( item, tmp_buff ); // in randart.cc
- strncat( buff, tmp_buff, ITEMNAME_SIZE );
-
- sparm = get_armour_ego_type( item );
-
- if (item_ident( item, ISFLAG_KNOW_TYPE ) && sparm != SPARM_NORMAL)
- {
- if (!terse)
- {
- strncat(buff, " of ", ITEMNAME_SIZE );
-
- strncat(buff, (sparm == SPARM_RUNNING) ? "running" :
- (sparm == SPARM_FIRE_RESISTANCE) ? "fire resistance" :
- (sparm == SPARM_COLD_RESISTANCE) ? "cold resistance" :
- (sparm == SPARM_POISON_RESISTANCE) ? "poison resistance" :
- (sparm == SPARM_SEE_INVISIBLE) ? "see invisible" :
- (sparm == SPARM_DARKNESS) ? "darkness" :
- (sparm == SPARM_STRENGTH) ? "strength" :
- (sparm == SPARM_DEXTERITY) ? "dexterity" :
- (sparm == SPARM_INTELLIGENCE) ? "intelligence" :
- (sparm == SPARM_PONDEROUSNESS) ? "ponderousness" :
- (sparm == SPARM_LEVITATION) ? "levitation" :
- (sparm == SPARM_MAGIC_RESISTANCE) ? "magic resistance" :
- (sparm == SPARM_PROTECTION) ? "protection" :
- (sparm == SPARM_STEALTH) ? "stealth" :
- (sparm == SPARM_RESISTANCE) ? "resistance" :
- (sparm == SPARM_POSITIVE_ENERGY) ? "positive energy" :
- (sparm == SPARM_ARCHMAGI) ? "the Archmagi" :
- (sparm == SPARM_PRESERVATION) ? "preservation"
- : "bugginess",
- ITEMNAME_SIZE);
- }
- else
- {
- strncat(buff, (sparm == SPARM_RUNNING) ? " (run)" :
- (sparm == SPARM_FIRE_RESISTANCE) ? " (R-fire)" :
- (sparm == SPARM_COLD_RESISTANCE) ? " (R-cold)" :
- (sparm == SPARM_POISON_RESISTANCE) ? " (R-poison)" :
- (sparm == SPARM_SEE_INVISIBLE) ? " (see invis)" :
- (sparm == SPARM_DARKNESS) ? " (darkness)" :
- (sparm == SPARM_STRENGTH) ? " (str)" :
- (sparm == SPARM_DEXTERITY) ? " (dex)" :
- (sparm == SPARM_INTELLIGENCE) ? " (int)" :
- (sparm == SPARM_PONDEROUSNESS) ? " (ponderous)" :
- (sparm == SPARM_LEVITATION) ? " (levitate)" :
- (sparm == SPARM_MAGIC_RESISTANCE) ? " (R-magic)" :
- (sparm == SPARM_PROTECTION) ? " (protect)" :
- (sparm == SPARM_STEALTH) ? " (stealth)" :
- (sparm == SPARM_RESISTANCE) ? " (resist)" :
- (sparm == SPARM_POSITIVE_ENERGY) ? " (R-neg)" : // ha ha
- (sparm == SPARM_ARCHMAGI) ? " (Archmagi)" :
- (sparm == SPARM_PRESERVATION) ? " (preserve)"
- : " (buggy)",
- ITEMNAME_SIZE);
- }
- }
-
- if (item_ident(item, ISFLAG_KNOW_CURSE) && item_cursed(item) && terse)
- strncat( buff, " (curse)", ITEMNAME_SIZE );
- break;
-
- // compacted 15 Apr 2000 {dlb}:
- case OBJ_WANDS:
- if (id[ IDTYPE_WANDS ][item_typ] == ID_KNOWN_TYPE
- || item_ident( item, ISFLAG_KNOW_TYPE ))
- {
- strncat(buff, "wand of ", ITEMNAME_SIZE );
- strncat(buff, (item_typ == WAND_FLAME) ? "flame" :
- (item_typ == WAND_FROST) ? "frost" :
- (item_typ == WAND_SLOWING) ? "slowing" :
- (item_typ == WAND_HASTING) ? "hasting" :
- (item_typ == WAND_MAGIC_DARTS) ? "magic darts" :
- (item_typ == WAND_HEALING) ? "healing" :
- (item_typ == WAND_PARALYSIS) ? "paralysis" :
- (item_typ == WAND_FIRE) ? "fire" :
- (item_typ == WAND_COLD) ? "cold" :
- (item_typ == WAND_CONFUSION) ? "confusion" :
- (item_typ == WAND_INVISIBILITY) ? "invisibility" :
- (item_typ == WAND_DIGGING) ? "digging" :
- (item_typ == WAND_FIREBALL) ? "fireball" :
- (item_typ == WAND_TELEPORTATION) ? "teleportation" :
- (item_typ == WAND_LIGHTNING) ? "lightning" :
- (item_typ == WAND_POLYMORPH_OTHER) ? "polymorph other" :
- (item_typ == WAND_ENSLAVEMENT) ? "enslavement" :
- (item_typ == WAND_DRAINING) ? "draining" :
- (item_typ == WAND_RANDOM_EFFECTS) ? "random effects" :
- (item_typ == WAND_DISINTEGRATION) ? "disintegration"
- : "bugginess",
- ITEMNAME_SIZE );
- }
- else
- {
- char primary = (item.special % 12);
- char secondary = (item.special / 12);
-
- strncat(buff,(secondary == 0) ? "" : // hope this works {dlb}
- (secondary == 1) ? "jeweled" :
- (secondary == 2) ? "curved" :
- (secondary == 3) ? "long" :
- (secondary == 4) ? "short" :
- (secondary == 5) ? "twisted" :
- (secondary == 6) ? "crooked" :
- (secondary == 7) ? "forked" :
- (secondary == 8) ? "shiny" :
- (secondary == 9) ? "blackened" :
- (secondary == 10) ? "tapered" :
- (secondary == 11) ? "glowing" :
- (secondary == 12) ? "worn" :
- (secondary == 13) ? "encrusted" :
- (secondary == 14) ? "runed" :
- (secondary == 15) ? "sharpened" : "buggily", ITEMNAME_SIZE);
-
- if (secondary != 0)
- strncat(buff, " ", ITEMNAME_SIZE );
-
- strncat(buff, (primary == 0) ? "iron" :
- (primary == 1) ? "brass" :
- (primary == 2) ? "bone" :
- (primary == 3) ? "wooden" :
- (primary == 4) ? "copper" :
- (primary == 5) ? "gold" :
- (primary == 6) ? "silver" :
- (primary == 7) ? "bronze" :
- (primary == 8) ? "ivory" :
- (primary == 9) ? "glass" :
- (primary == 10) ? "lead" :
- (primary == 11) ? "plastic" : "buggy", ITEMNAME_SIZE);
-
- strncat(buff, " wand", ITEMNAME_SIZE );
-
- if (id[ IDTYPE_WANDS ][item_typ] == ID_TRIED_TYPE)
- {
- strncat( buff, " {tried}" , ITEMNAME_SIZE );
- }
- }
-
- if (item_ident( item, ISFLAG_KNOW_PLUSES ))
- {
- strncat(buff, " (", ITEMNAME_SIZE );
- itoa( it_plus, tmp_quant, 10 );
- strncat(buff, tmp_quant, ITEMNAME_SIZE );
- strncat(buff, ")", ITEMNAME_SIZE);
- }
- break;
-
- // NB: potions, food, and scrolls stack on the basis of class and
- // type ONLY !!!
-
- // compacted 15 Apr 2000 {dlb}:
- case OBJ_POTIONS:
- if (id[ IDTYPE_POTIONS ][item_typ] == ID_KNOWN_TYPE
- || item_ident( item, ISFLAG_KNOW_TYPE ))
- {
- strncat(buff, "potion", ITEMNAME_SIZE );
- strncat(buff, (it_quant == 1) ? " " : "s ", ITEMNAME_SIZE);
- strncat(buff, "of ", ITEMNAME_SIZE );
- strncat(buff, (item_typ == POT_HEALING) ? "healing" :
- (item_typ == POT_HEAL_WOUNDS) ? "heal wounds" :
- (item_typ == POT_SPEED) ? "speed" :
- (item_typ == POT_MIGHT) ? "might" :
- (item_typ == POT_GAIN_STRENGTH) ? "gain strength" :
- (item_typ == POT_GAIN_DEXTERITY) ? "gain dexterity" :
- (item_typ == POT_GAIN_INTELLIGENCE) ? "gain intelligence" :
- (item_typ == POT_LEVITATION) ? "levitation" :
- (item_typ == POT_POISON) ? "poison" :
- (item_typ == POT_SLOWING) ? "slowing" :
- (item_typ == POT_PARALYSIS) ? "paralysis" :
- (item_typ == POT_CONFUSION) ? "confusion" :
- (item_typ == POT_INVISIBILITY) ? "invisibility" :
- (item_typ == POT_PORRIDGE) ? "porridge" :
- (item_typ == POT_DEGENERATION) ? "degeneration" :
- (item_typ == POT_DECAY) ? "decay" :
- (item_typ == POT_WATER) ? "water" :
- (item_typ == POT_EXPERIENCE) ? "experience" :
- (item_typ == POT_MAGIC) ? "magic" :
- (item_typ == POT_RESTORE_ABILITIES) ? "restore abilities" :
- (item_typ == POT_STRONG_POISON) ? "strong poison" :
- (item_typ == POT_BERSERK_RAGE) ? "berserk rage" :
- (item_typ == POT_CURE_MUTATION) ? "cure mutation" :
- (item_typ == POT_MUTATION) ? "mutation" : "bugginess",
- ITEMNAME_SIZE);
- }
- else
- {
- char primary = item.special / 14;
- char secondary = item.special % 14;
-
- strncat(buff,
- (primary == 0) ? "" :
- (primary == 1) ? "bubbling " :
- (primary == 2) ? "lumpy " :
- (primary == 3) ? "fuming " :
- (primary == 4) ? "smoky " :
- (primary == 5) ? "fizzy " :
- (primary == 6) ? "glowing " :
- (primary == 7) ? "sedimented " :
- (primary == 8) ? "metallic " :
- (primary == 9) ? "murky " :
- (primary == 10) ? "gluggy " :
- (primary == 11) ? "viscous " :
- (primary == 12) ? "oily " :
- (primary == 13) ? "slimy " :
- (primary == 14) ? "emulsified " : "buggy ", ITEMNAME_SIZE);
-
- strncat(buff,
- (secondary == 0) ? "clear" :
- (secondary == 1) ? "blue" :
- (secondary == 2) ? "black" :
- (secondary == 3) ? "silvery" :
- (secondary == 4) ? "cyan" :
- (secondary == 5) ? "purple" :
- (secondary == 6) ? "orange" :
- (secondary == 7) ? "inky" :
- (secondary == 8) ? "red" :
- (secondary == 9) ? "yellow" :
- (secondary == 10) ? "green" :
- (secondary == 11) ? "brown" :
- (secondary == 12) ? "pink" :
- (secondary == 13) ? "white" : "buggy", ITEMNAME_SIZE);
-
- strncat(buff, " potion", ITEMNAME_SIZE );
-
- if (it_quant > 1)
- strncat(buff, "s", ITEMNAME_SIZE );
-
- if (id[ IDTYPE_POTIONS ][item_typ] == ID_TRIED_TYPE)
- {
- strncat( buff, " {tried}" , ITEMNAME_SIZE );
- }
- }
- break;
-
- // NB: adding another food type == must set for carnivorous chars
- // (Kobolds and mutants)
- case OBJ_FOOD:
- switch (item_typ)
- {
- case FOOD_MEAT_RATION:
- strncat(buff, "meat ration", ITEMNAME_SIZE );
- break;
- case FOOD_BREAD_RATION:
- strncat(buff, "bread ration", ITEMNAME_SIZE );
- break;
- case FOOD_PEAR:
- strncat(buff, "pear", ITEMNAME_SIZE );
- break;
- case FOOD_APPLE: // make this less common
- strncat(buff, "apple", ITEMNAME_SIZE );
- break;
- case FOOD_CHOKO:
- strncat(buff, "choko", ITEMNAME_SIZE );
- break;
- case FOOD_HONEYCOMB:
- strncat(buff, "honeycomb", ITEMNAME_SIZE );
- break;
- case FOOD_ROYAL_JELLY:
- strncat(buff, "royal jell", ITEMNAME_SIZE );
- break;
- case FOOD_SNOZZCUMBER:
- strncat(buff, "snozzcumber", ITEMNAME_SIZE );
- break;
- case FOOD_PIZZA:
- strncat(buff, "slice of pizza", ITEMNAME_SIZE );
- break;
- case FOOD_APRICOT:
- strncat(buff, "apricot", ITEMNAME_SIZE );
- break;
- case FOOD_ORANGE:
- strncat(buff, "orange", ITEMNAME_SIZE );
- break;
- case FOOD_BANANA:
- strncat(buff, "banana", ITEMNAME_SIZE );
- break;
- case FOOD_STRAWBERRY:
- strncat(buff, "strawberr", ITEMNAME_SIZE );
- break;
- case FOOD_RAMBUTAN:
- strncat(buff, "rambutan", ITEMNAME_SIZE );
- break;
- case FOOD_LEMON:
- strncat(buff, "lemon", ITEMNAME_SIZE );
- break;
- case FOOD_GRAPE:
- strncat(buff, "grape", ITEMNAME_SIZE );
- break;
- case FOOD_SULTANA:
- strncat(buff, "sultana", ITEMNAME_SIZE );
- break;
- case FOOD_LYCHEE:
- strncat(buff, "lychee", ITEMNAME_SIZE );
- break;
- case FOOD_BEEF_JERKY:
- strncat(buff, "beef jerk", ITEMNAME_SIZE );
- break;
- case FOOD_CHEESE:
- strncat(buff, "cheese", ITEMNAME_SIZE );
- break;
- case FOOD_SAUSAGE:
- strncat(buff, "sausage", ITEMNAME_SIZE );
- break;
- case FOOD_CHUNK:
- moname( it_plus, true, DESC_PLAIN, tmp_buff );
-
- if (item.special < 100)
- strncat(buff, "rotting ", ITEMNAME_SIZE );
-
- strncat(buff, "chunk", ITEMNAME_SIZE );
-
- if (it_quant > 1)
- strncat(buff, "s", ITEMNAME_SIZE );
-
- strncat(buff, " of ", ITEMNAME_SIZE );
- strncat(buff, tmp_buff, ITEMNAME_SIZE );
- strncat(buff, " flesh", ITEMNAME_SIZE );
- break;
-
- }
-
- if (item_typ == FOOD_ROYAL_JELLY || item_typ == FOOD_STRAWBERRY
- || item_typ == FOOD_BEEF_JERKY)
- strncat(buff, (it_quant > 1) ? "ie" : "y", ITEMNAME_SIZE );
- break;
-
- // compacted 15 Apr 2000 {dlb}:
- case OBJ_SCROLLS:
- strncat(buff, "scroll", ITEMNAME_SIZE );
- strncat(buff, (it_quant == 1) ? " " : "s ", ITEMNAME_SIZE);
-
- if (id[ IDTYPE_SCROLLS ][item_typ] == ID_KNOWN_TYPE
- || item_ident( item, ISFLAG_KNOW_TYPE ))
- {
- strncat(buff, "of ", ITEMNAME_SIZE );
- strncat(buff, (item_typ == SCR_IDENTIFY) ? "identify" :
- (item_typ == SCR_TELEPORTATION) ? "teleportation" :
- (item_typ == SCR_FEAR) ? "fear" :
- (item_typ == SCR_NOISE) ? "noise" :
- (item_typ == SCR_REMOVE_CURSE) ? "remove curse" :
- (item_typ == SCR_DETECT_CURSE) ? "detect curse" :
- (item_typ == SCR_SUMMONING) ? "summoning" :
- (item_typ == SCR_ENCHANT_WEAPON_I) ? "enchant weapon I" :
- (item_typ == SCR_ENCHANT_ARMOUR) ? "enchant armour" :
- (item_typ == SCR_TORMENT) ? "torment" :
- (item_typ == SCR_RANDOM_USELESSNESS) ? "random uselessness" :
- (item_typ == SCR_CURSE_WEAPON) ? "curse weapon" :
- (item_typ == SCR_CURSE_ARMOUR) ? "curse armour" :
- (item_typ == SCR_IMMOLATION) ? "immolation" :
- (item_typ == SCR_BLINKING) ? "blinking" :
- (item_typ == SCR_PAPER) ? "paper" :
- (item_typ == SCR_MAGIC_MAPPING) ? "magic mapping" :
- (item_typ == SCR_FORGETFULNESS) ? "forgetfulness" :
- (item_typ == SCR_ACQUIREMENT) ? "acquirement" :
- (item_typ == SCR_ENCHANT_WEAPON_II) ? "enchant weapon II" :
- (item_typ == SCR_VORPALISE_WEAPON) ? "vorpalise weapon" :
- (item_typ == SCR_RECHARGING) ? "recharging" :
- //(item_typ == 23) ? "portal travel" :
- (item_typ == SCR_ENCHANT_WEAPON_III) ? "enchant weapon III"
- : "bugginess",
- ITEMNAME_SIZE);
- }
- else
- {
- strncat(buff, "labeled ", ITEMNAME_SIZE );
- char buff3[ ITEMNAME_SIZE ];
-
- const unsigned long sseed =
- item.special
- + static_cast<unsigned long>(it_plus)
- + (static_cast<unsigned long>(item_clas) << 16);
- make_name( sseed, true, buff3 );
- strncat( buff, buff3 , ITEMNAME_SIZE );
-
- if (id[ IDTYPE_SCROLLS ][item_typ] == ID_TRIED_TYPE)
- {
- strncat( buff, " {tried}" , ITEMNAME_SIZE );
- }
- }
- break;
-
- // compacted 15 Apr 2000 {dlb}: -- on hold ... what a mess!
- case OBJ_JEWELLERY:
- // not using {tried} here because there are some confusing
- // issues to work out with how we want to handle jewellery
- // artefacts and base type id. -- bwr
- if (item_ident( item, ISFLAG_KNOW_CURSE ))
- {
- if (item_cursed( item ))
- strncat(buff, "cursed ", ITEMNAME_SIZE );
- else if (Options.show_uncursed
- && !item_ident( item, ISFLAG_KNOW_PLUSES ))
- {
- strncat(buff, "uncursed ", ITEMNAME_SIZE );
- }
- }
-
- if (is_random_artefact( item ))
- {
- strncat(buff, randart_ring_name(item), ITEMNAME_SIZE);
- break;
- }
-
- if (id[ IDTYPE_JEWELLERY ][item_typ] == ID_KNOWN_TYPE
- || item_ident( item, ISFLAG_KNOW_TYPE ))
- {
-
- if (item_ident( item, ISFLAG_KNOW_PLUSES )
- && (item_typ == RING_PROTECTION || item_typ == RING_STRENGTH
- || item_typ == RING_SLAYING || item_typ == RING_EVASION
- || item_typ == RING_DEXTERITY
- || item_typ == RING_INTELLIGENCE))
- {
- char gokh = it_plus;
-
- if (gokh >= 0)
- strncat( buff, "+" , ITEMNAME_SIZE );
-
- itoa( gokh, tmp_quant, 10 );
- strncat( buff, tmp_quant , ITEMNAME_SIZE );
-
- if (item_typ == RING_SLAYING)
- {
- strncat( buff, "," , ITEMNAME_SIZE );
-
- if (item_plus2 >= 0)
- strncat(buff, "+", ITEMNAME_SIZE );
-
- itoa( item_plus2, tmp_quant, 10 );
- strncat( buff, tmp_quant , ITEMNAME_SIZE );
- }
-
- strncat(buff, " ", ITEMNAME_SIZE );
- }
-
- switch (item_typ)
- {
- case RING_REGENERATION:
- strncat(buff, "ring of regeneration", ITEMNAME_SIZE );
- break;
- case RING_PROTECTION:
- strncat(buff, "ring of protection", ITEMNAME_SIZE );
- break;
- case RING_PROTECTION_FROM_FIRE:
- strncat(buff, "ring of protection from fire", ITEMNAME_SIZE );
- break;
- case RING_POISON_RESISTANCE:
- strncat(buff, "ring of poison resistance", ITEMNAME_SIZE );
- break;
- case RING_PROTECTION_FROM_COLD:
- strncat(buff, "ring of protection from cold", ITEMNAME_SIZE );
- break;
- case RING_STRENGTH:
- strncat(buff, "ring of strength", ITEMNAME_SIZE );
- break;
- case RING_SLAYING:
- strncat(buff, "ring of slaying", ITEMNAME_SIZE );
- break;
- case RING_SEE_INVISIBLE:
- strncat(buff, "ring of see invisible", ITEMNAME_SIZE );
- break;
- case RING_INVISIBILITY:
- strncat(buff, "ring of invisibility", ITEMNAME_SIZE );
- break;
- case RING_HUNGER:
- strncat(buff, "ring of hunger", ITEMNAME_SIZE );
- break;
- case RING_TELEPORTATION:
- strncat(buff, "ring of teleportation", ITEMNAME_SIZE );
- break;
- case RING_EVASION:
- strncat(buff, "ring of evasion", ITEMNAME_SIZE );
- break;
- case RING_SUSTAIN_ABILITIES:
- strncat(buff, "ring of sustain abilities", ITEMNAME_SIZE );
- break;
- case RING_SUSTENANCE:
- strncat(buff, "ring of sustenance", ITEMNAME_SIZE );
- break;
- case RING_DEXTERITY:
- strncat(buff, "ring of dexterity", ITEMNAME_SIZE );
- break;
- case RING_INTELLIGENCE:
- strncat(buff, "ring of intelligence", ITEMNAME_SIZE );
- break;
- case RING_WIZARDRY:
- strncat(buff, "ring of wizardry", ITEMNAME_SIZE );
- break;
- case RING_MAGICAL_POWER:
- strncat(buff, "ring of magical power", ITEMNAME_SIZE );
- break;
- case RING_LEVITATION:
- strncat(buff, "ring of levitation", ITEMNAME_SIZE );
- break;
- case RING_LIFE_PROTECTION:
- strncat(buff, "ring of life protection", ITEMNAME_SIZE );
- break;
- case RING_PROTECTION_FROM_MAGIC:
- strncat(buff, "ring of protection from magic", ITEMNAME_SIZE );
- break;
- case RING_FIRE:
- strncat(buff, "ring of fire", ITEMNAME_SIZE );
- break;
- case RING_ICE:
- strncat(buff, "ring of ice", ITEMNAME_SIZE );
- break;
- case RING_TELEPORT_CONTROL:
- strncat(buff, "ring of teleport control", ITEMNAME_SIZE );
- break;
- case AMU_RAGE:
- strncat(buff, "amulet of rage", ITEMNAME_SIZE );
- break;
- case AMU_RESIST_SLOW:
- strncat(buff, "amulet of resist slowing", ITEMNAME_SIZE );
- break;
- case AMU_CLARITY:
- strncat(buff, "amulet of clarity", ITEMNAME_SIZE );
- break;
- case AMU_WARDING:
- strncat(buff, "amulet of warding", ITEMNAME_SIZE );
- break;
- case AMU_RESIST_CORROSION:
- strncat(buff, "amulet of resist corrosion", ITEMNAME_SIZE );
- break;
- case AMU_THE_GOURMAND:
- strncat(buff, "amulet of the gourmand", ITEMNAME_SIZE );
- break;
- case AMU_CONSERVATION:
- strncat(buff, "amulet of conservation", ITEMNAME_SIZE );
- break;
- case AMU_CONTROLLED_FLIGHT:
- strncat(buff, "amulet of controlled flight", ITEMNAME_SIZE );
- break;
- case AMU_INACCURACY:
- strncat(buff, "amulet of inaccuracy", ITEMNAME_SIZE );
- break;
- case AMU_RESIST_MUTATION:
- strncat(buff, "amulet of resist mutation", ITEMNAME_SIZE );
- break;
- }
- /* ? of imputed learning - 100% exp from tames/summoned kills */
- break;
- }
-
- if (item_typ < AMU_RAGE) // rings
- {
- if (is_random_artefact( item ))
- {
- strncat(buff, randart_ring_name(item), ITEMNAME_SIZE);
- break;
- }
-
- switch (item.special / 13) // secondary characteristic of ring
- {
- case 1:
- strncat(buff, "encrusted ", ITEMNAME_SIZE );
- break;
- case 2:
- strncat(buff, "glowing ", ITEMNAME_SIZE );
- break;
- case 3:
- strncat(buff, "tubular ", ITEMNAME_SIZE );
- break;
- case 4:
- strncat(buff, "runed ", ITEMNAME_SIZE );
- break;
- case 5:
- strncat(buff, "blackened ", ITEMNAME_SIZE );
- break;
- case 6:
- strncat(buff, "scratched ", ITEMNAME_SIZE );
- break;
- case 7:
- strncat(buff, "small ", ITEMNAME_SIZE );
- break;
- case 8:
- strncat(buff, "large ", ITEMNAME_SIZE );
- break;
- case 9:
- strncat(buff, "twisted ", ITEMNAME_SIZE );
- break;
- case 10:
- strncat(buff, "shiny ", ITEMNAME_SIZE );
- break;
- case 11:
- strncat(buff, "notched ", ITEMNAME_SIZE );
- break;
- case 12:
- strncat(buff, "knobbly ", ITEMNAME_SIZE );
- break;
- }
-
- switch (item.special % 13)
- {
- case 0:
- strncat(buff, "wooden ring", ITEMNAME_SIZE );
- break;
- case 1:
- strncat(buff, "silver ring", ITEMNAME_SIZE );
- break;
- case 2:
- strncat(buff, "golden ring", ITEMNAME_SIZE );
- break;
- case 3:
- strncat(buff, "iron ring", ITEMNAME_SIZE );
- break;
- case 4:
- strncat(buff, "steel ring", ITEMNAME_SIZE );
- break;
- case 5:
- strncat(buff, "bronze ring", ITEMNAME_SIZE );
- break;
- case 6:
- strncat(buff, "brass ring", ITEMNAME_SIZE );
- break;
- case 7:
- strncat(buff, "copper ring", ITEMNAME_SIZE );
- break;
- case 8:
- strncat(buff, "granite ring", ITEMNAME_SIZE );
- break;
- case 9:
- strncat(buff, "ivory ring", ITEMNAME_SIZE );
- break;
- case 10:
- strncat(buff, "bone ring", ITEMNAME_SIZE );
- break;
- case 11:
- strncat(buff, "marble ring", ITEMNAME_SIZE );
- break;
- case 12:
- strncat(buff, "jade ring", ITEMNAME_SIZE );
- break;
- case 13:
- strncat(buff, "glass ring", ITEMNAME_SIZE );
- break;
- }
- } // end of rings
- else // ie is an amulet
- {
- if (is_random_artefact( item ))
- {
- strncat(buff, randart_ring_name(item), ITEMNAME_SIZE);
- break;
- }
-
- if (item.special > 13)
- {
- switch (item.special / 13) // secondary characteristic of amulet
- {
- case 0:
- strncat(buff, "dented ", ITEMNAME_SIZE );
- break;
- case 1:
- strncat(buff, "square ", ITEMNAME_SIZE );
- break;
- case 2:
- strncat(buff, "thick ", ITEMNAME_SIZE );
- break;
- case 3:
- strncat(buff, "thin ", ITEMNAME_SIZE );
- break;
- case 4:
- strncat(buff, "runed ", ITEMNAME_SIZE );
- break;
- case 5:
- strncat(buff, "blackened ", ITEMNAME_SIZE );
- break;
- case 6:
- strncat(buff, "glowing ", ITEMNAME_SIZE );
- break;
- case 7:
- strncat(buff, "small ", ITEMNAME_SIZE );
- break;
- case 8:
- strncat(buff, "large ", ITEMNAME_SIZE );
- break;
- case 9:
- strncat(buff, "twisted ", ITEMNAME_SIZE );
- break;
- case 10:
- strncat(buff, "tiny ", ITEMNAME_SIZE );
- break;
- case 11:
- strncat(buff, "triangular ", ITEMNAME_SIZE );
- break;
- case 12:
- strncat(buff, "lumpy ", ITEMNAME_SIZE );
- break;
- }
- }
-
- switch (item.special % 13)
- {
- case 0:
- strncat(buff, "zirconium amulet", ITEMNAME_SIZE );
- break;
- case 1:
- strncat(buff, "sapphire amulet", ITEMNAME_SIZE );
- break;
- case 2:
- strncat(buff, "golden amulet", ITEMNAME_SIZE );
- break;
- case 3:
- strncat(buff, "emerald amulet", ITEMNAME_SIZE );
- break;
- case 4:
- strncat(buff, "garnet amulet", ITEMNAME_SIZE );
- break;
- case 5:
- strncat(buff, "bronze amulet", ITEMNAME_SIZE );
- break;
- case 6:
- strncat(buff, "brass amulet", ITEMNAME_SIZE );
- break;
- case 7:
- strncat(buff, "copper amulet", ITEMNAME_SIZE );
- break;
- case 8:
- strncat(buff, "ruby amulet", ITEMNAME_SIZE );
- break;
- case 9:
- strncat(buff, "ivory amulet", ITEMNAME_SIZE );
- break;
- case 10:
- strncat(buff, "bone amulet", ITEMNAME_SIZE );
- break;
- case 11:
- strncat(buff, "platinum amulet", ITEMNAME_SIZE );
- break;
- case 12:
- strncat(buff, "jade amulet", ITEMNAME_SIZE );
- break;
- case 13:
- strncat(buff, "plastic amulet", ITEMNAME_SIZE );
- break;
- }
- } // end of amulets
- break;
-
- // compacted 15 Apr 2000 {dlb}:
- case OBJ_MISCELLANY:
- switch (item_typ)
- {
- case MISC_RUNE_OF_ZOT:
- strncat( buff, (it_plus == RUNE_DIS) ? "iron" :
- (it_plus == RUNE_GEHENNA) ? "obsidian" :
- (it_plus == RUNE_COCYTUS) ? "icy" :
- (it_plus == RUNE_TARTARUS) ? "bone" :
- (it_plus == RUNE_SLIME_PITS) ? "slimy" :
- (it_plus == RUNE_VAULTS) ? "silver" :
- (it_plus == RUNE_SNAKE_PIT) ? "serpentine" :
- (it_plus == RUNE_ELVEN_HALLS) ? "elven" :
- (it_plus == RUNE_TOMB) ? "golden" :
- (it_plus == RUNE_SWAMP) ? "decaying" :
-
- // pandemonium and abyss runes:
- (it_plus == RUNE_DEMONIC) ? "demonic" :
- (it_plus == RUNE_ABYSSAL) ? "abyssal" :
-
- // special pandemonium runes:
- (it_plus == RUNE_MNOLEG) ? "glowing" :
- (it_plus == RUNE_LOM_LOBON) ? "magical" :
- (it_plus == RUNE_CEREBOV) ? "fiery" :
- (it_plus == RUNE_GLOORX_VLOQ) ? "dark"
- : "buggy",
- ITEMNAME_SIZE);
-
- strncat(buff, " ", ITEMNAME_SIZE );
- strncat(buff, "rune", ITEMNAME_SIZE );
-
- if (it_quant > 1)
- strncat(buff, "s", ITEMNAME_SIZE );
-
- if (item_ident( item, ISFLAG_KNOW_TYPE ))
- strncat(buff, " of Zot", ITEMNAME_SIZE );
- break;
-
- case MISC_DECK_OF_POWER:
- case MISC_DECK_OF_SUMMONINGS:
- case MISC_DECK_OF_TRICKS:
- case MISC_DECK_OF_WONDERS:
- strncat(buff, "deck of ", ITEMNAME_SIZE );
- strncat(buff, !item_ident( item, ISFLAG_KNOW_TYPE ) ? "cards" :
- (item_typ == MISC_DECK_OF_WONDERS) ? "wonders" :
- (item_typ == MISC_DECK_OF_SUMMONINGS) ? "summonings" :
- (item_typ == MISC_DECK_OF_TRICKS) ? "tricks" :
- (item_typ == MISC_DECK_OF_POWER) ? "power"
- : "bugginess",
- ITEMNAME_SIZE);
- break;
-
- case MISC_CRYSTAL_BALL_OF_ENERGY:
- case MISC_CRYSTAL_BALL_OF_FIXATION:
- case MISC_CRYSTAL_BALL_OF_SEEING:
- strncat(buff, "crystal ball", ITEMNAME_SIZE );
- if (item_ident( item, ISFLAG_KNOW_TYPE ))
- {
- strncat(buff, " of ", ITEMNAME_SIZE );
- strncat(buff,
- (item_typ == MISC_CRYSTAL_BALL_OF_SEEING) ? "seeing" :
- (item_typ == MISC_CRYSTAL_BALL_OF_ENERGY) ? "energy" :
- (item_typ == MISC_CRYSTAL_BALL_OF_FIXATION) ? "fixation"
- : "bugginess",
- ITEMNAME_SIZE);
- }
- break;
-
- case MISC_BOX_OF_BEASTS:
- if (item_ident( item, ISFLAG_KNOW_TYPE ))
- strncat(buff, "box of beasts", ITEMNAME_SIZE );
- else
- strncat(buff, "small ebony casket", ITEMNAME_SIZE );
- break;
-
- case MISC_EMPTY_EBONY_CASKET:
- if (item_ident( item, ISFLAG_KNOW_TYPE ))
- strncat(buff, "empty ebony casket", ITEMNAME_SIZE );
- else
- strncat(buff, "small ebony casket", ITEMNAME_SIZE );
- break;
-
- case MISC_AIR_ELEMENTAL_FAN:
- if (item_ident( item, ISFLAG_KNOW_TYPE ))
- strncat(buff, "air elemental ", ITEMNAME_SIZE );
- strncat(buff, "fan", ITEMNAME_SIZE );
- break;
-
- case MISC_LAMP_OF_FIRE:
- strncat(buff, "lamp", ITEMNAME_SIZE );
- if (item_ident( item, ISFLAG_KNOW_TYPE ))
- strncat(buff, " of fire", ITEMNAME_SIZE );
- break;
-
- case MISC_LANTERN_OF_SHADOWS:
- if (!item_ident( item, ISFLAG_KNOW_TYPE ))
- strncat(buff, "bone ", ITEMNAME_SIZE );
- strncat(buff, "lantern", ITEMNAME_SIZE );
-
- if (item_ident( item, ISFLAG_KNOW_TYPE ))
- strncat(buff, " of shadows", ITEMNAME_SIZE );
- break;
-
- case MISC_HORN_OF_GERYON:
- if (!item_ident( item, ISFLAG_KNOW_TYPE ))
- strncat(buff, "silver ", ITEMNAME_SIZE );
- strncat(buff, "horn", ITEMNAME_SIZE );
-
- if (item_ident( item, ISFLAG_KNOW_TYPE ))
- strncat(buff, " of Geryon", ITEMNAME_SIZE );
- break;
-
- case MISC_DISC_OF_STORMS:
- if (!item_ident( item, ISFLAG_KNOW_TYPE ))
- strncat(buff, "grey ", ITEMNAME_SIZE );
- strncat(buff, "disc", ITEMNAME_SIZE );
-
- if (item_ident( item, ISFLAG_KNOW_TYPE ))
- strncat(buff, " of storms", ITEMNAME_SIZE );
- break;
-
- case MISC_STONE_OF_EARTH_ELEMENTALS:
- if (!item_ident( item, ISFLAG_KNOW_TYPE ))
- strncat(buff, "nondescript ", ITEMNAME_SIZE );
- strncat(buff, "stone", ITEMNAME_SIZE );
-
- if (item_ident( item, ISFLAG_KNOW_TYPE ))
- strncat(buff, " of earth elementals", ITEMNAME_SIZE );
- break;
-
- case MISC_BOTTLED_EFREET:
- strncat(buff, (!item_ident( item, ISFLAG_KNOW_TYPE ))
- ? "sealed bronze flask" : "bottled efreet",
- ITEMNAME_SIZE );
- break;
-
- case MISC_PORTABLE_ALTAR_OF_NEMELEX:
- strncat(buff, "portable altar of Nemelex", ITEMNAME_SIZE );
- break;
-
- default:
- strncat(buff, "buggy miscellaneous item", ITEMNAME_SIZE );
- break;
- }
- break;
-
- // compacted 15 Apr 2000 {dlb}:
- case OBJ_BOOKS:
- if (!item_ident( item, ISFLAG_KNOW_TYPE ))
- {
- char primary = (item.special / 10);
- char secondary = (item.special % 10);
-
- strncat(buff, (primary == 0) ? "" :
- (primary == 1) ? "chunky " :
- (primary == 2) ? "thick " :
- (primary == 3) ? "thin " :
- (primary == 4) ? "wide " :
- (primary == 5) ? "glowing " :
- (primary == 6) ? "dog-eared " :
- (primary == 7) ? "oblong " :
- (primary == 8) ? "runed " :
-
- // these last three were single spaces {dlb}
- (primary == 9) ? "" :
- (primary == 10) ? "" : (primary == 11) ? "" : "buggily ",
- ITEMNAME_SIZE);
-
- strncat(buff, (secondary == 0) ? "paperback " :
- (secondary == 1) ? "hardcover " :
- (secondary == 2) ? "leatherbound " :
- (secondary == 3) ? "metal-bound " :
- (secondary == 4) ? "papyrus " :
- // these two were single spaces, too {dlb}
- (secondary == 5) ? "" :
- (secondary == 6) ? "" : "buggy ", ITEMNAME_SIZE);
-
- strncat(buff, "book", ITEMNAME_SIZE );
- }
- else if (item_typ == BOOK_MANUAL)
- {
- strncat(buff, "manual of ", ITEMNAME_SIZE );
- strncat(buff, skill_name(it_plus), ITEMNAME_SIZE );
- }
- else if (item_typ == BOOK_NECRONOMICON)
- strncat(buff, "Necronomicon", ITEMNAME_SIZE );
- else if (item_typ == BOOK_DESTRUCTION)
- strncat(buff, "tome of Destruction", ITEMNAME_SIZE );
- else if (item_typ == BOOK_YOUNG_POISONERS)
- strncat(buff, "Young Poisoner's Handbook", ITEMNAME_SIZE );
- else if (item_typ == BOOK_BEASTS)
- strncat(buff, "Monster Manual", ITEMNAME_SIZE );
- else
- {
- strncat(buff, "book of ", ITEMNAME_SIZE );
- strncat(buff, (item_typ == BOOK_MINOR_MAGIC_I
- || item_typ == BOOK_MINOR_MAGIC_II
- || item_typ == BOOK_MINOR_MAGIC_III) ? "Minor Magic" :
- (item_typ == BOOK_CONJURATIONS_I
- || item_typ == BOOK_CONJURATIONS_II) ? "Conjurations" :
- (item_typ == BOOK_FLAMES) ? "Flames" :
- (item_typ == BOOK_FROST) ? "Frost" :
- (item_typ == BOOK_SUMMONINGS) ? "Summonings" :
- (item_typ == BOOK_FIRE) ? "Fire" :
- (item_typ == BOOK_ICE) ? "Ice" :
- (item_typ == BOOK_SURVEYANCES) ? "Surveyances" :
- (item_typ == BOOK_SPATIAL_TRANSLOCATIONS) ? "Spatial Translocations" :
- (item_typ == BOOK_ENCHANTMENTS) ? "Enchantments" :
- (item_typ == BOOK_TEMPESTS) ? "the Tempests" :
- (item_typ == BOOK_DEATH) ? "Death" :
- (item_typ == BOOK_HINDERANCE) ? "Hinderance" :
- (item_typ == BOOK_CHANGES) ? "Changes" :
- (item_typ == BOOK_TRANSFIGURATIONS) ? "Transfigurations" :
- (item_typ == BOOK_PRACTICAL_MAGIC) ? "Practical Magic" :
- (item_typ == BOOK_WAR_CHANTS) ? "War Chants" :
- (item_typ == BOOK_CLOUDS) ? "Clouds" :
- (item_typ == BOOK_HEALING) ? "Healing" :
- (item_typ == BOOK_NECROMANCY) ? "Necromancy" :
- (item_typ == BOOK_CALLINGS) ? "Callings" :
- (item_typ == BOOK_CHARMS) ? "Charms" :
- (item_typ == BOOK_DEMONOLOGY) ? "Demonology" :
- (item_typ == BOOK_AIR) ? "Air" :
- (item_typ == BOOK_SKY) ? "the Sky" :
- (item_typ == BOOK_DIVINATIONS) ? "Divinations" :
- (item_typ == BOOK_WARP) ? "the Warp" :
- (item_typ == BOOK_ENVENOMATIONS) ? "Envenomations" :
- (item_typ == BOOK_ANNIHILATIONS) ? "Annihilations" :
- (item_typ == BOOK_UNLIFE) ? "Unlife" :
- (item_typ == BOOK_CONTROL) ? "Control" :
- (item_typ == BOOK_MUTATIONS) ? "Morphology" :
- (item_typ == BOOK_TUKIMA) ? "Tukima" :
- (item_typ == BOOK_GEOMANCY) ? "Geomancy" :
- (item_typ == BOOK_EARTH) ? "the Earth" :
- (item_typ == BOOK_WIZARDRY) ? "Wizardry" :
- (item_typ == BOOK_POWER) ? "Power" :
- (item_typ == BOOK_CANTRIPS) ? "Cantrips" :
- (item_typ == BOOK_PARTY_TRICKS) ? "Party Tricks" :
- (item_typ == BOOK_STALKING) ? "Stalking"
- : "Bugginess",
- ITEMNAME_SIZE );
- }
- break;
-
- // compacted 15 Apr 2000 {dlb}:
- case OBJ_STAVES:
- if (!item_ident( item, ISFLAG_KNOW_TYPE ))
- {
- strncat(buff, (item.special == 0) ? "curved" :
- (item.special == 1) ? "glowing" :
- (item.special == 2) ? "thick" :
- (item.special == 3) ? "thin" :
- (item.special == 4) ? "long" :
- (item.special == 5) ? "twisted" :
- (item.special == 6) ? "jeweled" :
- (item.special == 7) ? "runed" :
- (item.special == 8) ? "smoking" :
- (item.special == 9) ? "gnarled" : // was "" {dlb}
- (item.special == 10) ? "" :
- (item.special == 11) ? "" :
- (item.special == 12) ? "" :
- (item.special == 13) ? "" :
- (item.special == 14) ? "" :
- (item.special == 15) ? "" :
- (item.special == 16) ? "" :
- (item.special == 17) ? "" :
- (item.special == 18) ? "" :
- (item.special == 19) ? "" :
- (item.special == 20) ? "" :
- (item.special == 21) ? "" :
- (item.special == 22) ? "" :
- (item.special == 23) ? "" :
- (item.special == 24) ? "" :
- (item.special == 25) ? "" :
- (item.special == 26) ? "" :
- (item.special == 27) ? "" :
- (item.special == 28) ? "" :
- (item.special == 29) ? "" : "buggy", ITEMNAME_SIZE);
- strncat(buff, " ", ITEMNAME_SIZE );
- }
-
- strncat( buff, (item_is_rod( item ) ? "rod" : "staff"), ITEMNAME_SIZE );
-
- if (item_ident( item, ISFLAG_KNOW_TYPE ))
- {
- strncat(buff, " of ", ITEMNAME_SIZE );
-
- strncat(buff, (item_typ == STAFF_WIZARDRY) ? "wizardry" :
- (item_typ == STAFF_POWER) ? "power" :
- (item_typ == STAFF_FIRE) ? "fire" :
- (item_typ == STAFF_COLD) ? "cold" :
- (item_typ == STAFF_POISON) ? "poison" :
- (item_typ == STAFF_ENERGY) ? "energy" :
- (item_typ == STAFF_DEATH) ? "death" :
- (item_typ == STAFF_CONJURATION) ? "conjuration" :
- (item_typ == STAFF_ENCHANTMENT) ? "enchantment" :
- (item_typ == STAFF_SMITING) ? "smiting" :
- (item_typ == STAFF_STRIKING) ? "striking" :
- (item_typ == STAFF_WARDING) ? "warding" :
- (item_typ == STAFF_DISCOVERY) ? "discovery" :
- (item_typ == STAFF_DEMONOLOGY) ? "demonology" :
- (item_typ == STAFF_AIR) ? "air" :
- (item_typ == STAFF_EARTH) ? "earth" :
- (item_typ == STAFF_SUMMONING
- || item_typ == STAFF_SPELL_SUMMONING) ? "summoning" :
- (item_typ == STAFF_DESTRUCTION_I
- || item_typ == STAFF_DESTRUCTION_II
- || item_typ == STAFF_DESTRUCTION_III
- || item_typ == STAFF_DESTRUCTION_IV) ? "destruction" :
- (item_typ == STAFF_CHANNELING) ? "channeling"
- : "bugginess", ITEMNAME_SIZE );
- }
-
- if (item_is_rod( item ) && item.sub_type != STAFF_STRIKING
- && item_ident( item, ISFLAG_KNOW_TYPE ))
- {
- strncat( buff, " (", ITEMNAME_SIZE );
- itoa( item.plus / ROD_CHARGE_MULT, tmp_quant, 10 );
- strncat( buff, tmp_quant, ITEMNAME_SIZE );
- strncat( buff, "/", ITEMNAME_SIZE );
- itoa( item.plus2 / ROD_CHARGE_MULT, tmp_quant, 10 );
- strncat( buff, tmp_quant, ITEMNAME_SIZE );
- strncat( buff, ")", ITEMNAME_SIZE );
- }
-
- break;
-
-
- // rearranged 15 Apr 2000 {dlb}:
- case OBJ_ORBS:
- strncpy( buff, "Orb of ", ITEMNAME_SIZE );
- strncat( buff, (item_typ == ORB_ZOT) ? "Zot" :
-/* ******************************************************************
- (item_typ == 1) ? "Zug" :
- (item_typ == 2) ? "Xob" :
- (item_typ == 3) ? "Ix" :
- (item_typ == 4) ? "Xug" :
- (item_typ == 5) ? "Zob" :
- (item_typ == 6) ? "Ik" :
- (item_typ == 7) ? "Grolp" :
- (item_typ == 8) ? "fo brO ehT" :
- (item_typ == 9) ? "Plob" :
- (item_typ == 10) ? "Zuggle-Glob" :
- (item_typ == 11) ? "Zin" :
- (item_typ == 12) ? "Qexigok" :
- (item_typ == 13) ? "Bujuk" :
- (item_typ == 14) ? "Uhen Tiquritu" :
- (item_typ == 15) ? "Idohoxom Sovuf" :
- (item_typ == 16) ? "Voc Vocilicoso" :
- (item_typ == 17) ? "Chanuaxydiviha" :
- (item_typ == 18) ? "Ihexodox" :
- (item_typ == 19) ? "Rynok Pol" :
- (item_typ == 20) ? "Nemelex" :
- (item_typ == 21) ? "Sif Muna" :
- (item_typ == 22) ? "Okawaru" :
- (item_typ == 23) ? "Kikubaaqudgha" :
-****************************************************************** */
- "Bugginess", ITEMNAME_SIZE ); // change back to "Zot" if source of problems cannot be found {dlb}
- break;
-
- case OBJ_GOLD:
- strncat(buff, "gold piece", ITEMNAME_SIZE );
- break;
-
- // still not implemented, yet:
- case OBJ_GEMSTONES:
- break;
-
- // rearranged 15 Apr 2000 {dlb}:
- case OBJ_CORPSES:
- if (item_typ == CORPSE_BODY && item.special < 100)
- strncat(buff, "rotting ", ITEMNAME_SIZE );
-
- moname( it_plus, true, DESC_PLAIN, tmp_buff );
-
- strncat(buff, tmp_buff, ITEMNAME_SIZE );
- strncat(buff, " ", ITEMNAME_SIZE );
- strncat(buff, (item_typ == CORPSE_BODY) ? "corpse" :
- (item_typ == CORPSE_SKELETON) ? "skeleton" : "corpse bug",
- ITEMNAME_SIZE );
- break;
-
- default:
- strncat(buff, "!", ITEMNAME_SIZE );
- } // end of switch?
-
- // Disambiguation
- if (!terse && item_ident(item, ISFLAG_KNOW_TYPE))
- {
-#define name_append(x) strncat(buff, x, ITEMNAME_SIZE)
- switch (item_clas)
- {
- case OBJ_STAVES:
- switch (item_typ)
- {
- case STAFF_DESTRUCTION_I:
- name_append(" [fire]");
- break;
- case STAFF_DESTRUCTION_II:
- name_append(" [ice]");
- break;
- case STAFF_DESTRUCTION_III:
- name_append(" [iron,fireball,lightning]");
- break;
- case STAFF_DESTRUCTION_IV:
- name_append(" [inacc,magma,cold]");
- break;
- }
- break;
- case OBJ_BOOKS:
- switch (item_typ)
- {
- case BOOK_MINOR_MAGIC_I:
- name_append(" [flame]");
- break;
- case BOOK_MINOR_MAGIC_II:
- name_append(" [frost]");
- break;
- case BOOK_MINOR_MAGIC_III:
- name_append(" [summ]");
- break;
- case BOOK_CONJURATIONS_I:
- name_append(" [fire]");
- break;
- case BOOK_CONJURATIONS_II:
- name_append(" [ice]");
- break;
- }
- }
-#undef name_append
- }
-
- // debugging output -- oops, I probably block it above ... dang! {dlb}
- if (strlen(buff) < 3)
- {
- char ugug[20];
-
- strncat(buff, "bad item (cl:", ITEMNAME_SIZE );
- itoa(item_clas, ugug, 10);
- strncat(buff, ugug, ITEMNAME_SIZE );
- strncat(buff, ",ty:", ITEMNAME_SIZE );
- itoa(item_typ, ugug, 10);
- strncat(buff, ugug, ITEMNAME_SIZE );
- strncat(buff, ",pl:", ITEMNAME_SIZE );
- itoa(it_plus, ugug, 10);
- strncat(buff, ugug, ITEMNAME_SIZE );
- strncat(buff, ",pl2:", ITEMNAME_SIZE );
- itoa(item_plus2, ugug, 10);
- strncat(buff, ugug, ITEMNAME_SIZE );
- strncat(buff, ",sp:", ITEMNAME_SIZE );
- itoa(item.special, ugug, 10);
- strncat(buff, ugug, ITEMNAME_SIZE );
- strncat(buff, ",qu:", ITEMNAME_SIZE );
- itoa(it_quant, ugug, 10);
- strncat(buff, ugug, ITEMNAME_SIZE );
- strncat(buff, ")", ITEMNAME_SIZE );
- }
-
- // hackish {dlb}
- if (it_quant > 1
- && item_clas != OBJ_MISSILES
- && item_clas != OBJ_SCROLLS
- && item_clas != OBJ_POTIONS
- && item_clas != OBJ_MISCELLANY
- && (item_clas != OBJ_FOOD || item_typ != FOOD_CHUNK))
- {
- strncat(buff, "s", ITEMNAME_SIZE );
- }
-
- return 1;
-} // end item_name_2()
-
-void save_id(char identy[4][50])
-{
- int x = 0, jx = 0;
-
- for (x = 0; x < 4; x++)
- {
- for (jx = 0; jx < 50; jx++)
- {
- identy[x][jx] = id[x][jx];
- }
- }
-} // end save_id()
-
-void clear_ids(void)
-{
-
- int i = 0, j = 0;
-
- for (i = 0; i < 4; i++)
- {
- for (j = 0; j < 50; j++)
- {
- id[i][j] = ID_UNKNOWN_TYPE;
- }
- }
-
-} // end clear_ids()
-
-
-void set_ident_type( char cla, int ty, char setting, bool force )
-{
- // Don't allow overwriting of known type with tried unless forced.
- if (!force
- && setting == ID_TRIED_TYPE
- && get_ident_type( cla, ty ) == ID_KNOWN_TYPE)
- {
- return;
- }
-
- switch (cla)
- {
- case OBJ_WANDS:
- id[ IDTYPE_WANDS ][ty] = setting;
- break;
-
- case OBJ_SCROLLS:
- id[ IDTYPE_SCROLLS ][ty] = setting;
- break;
-
- case OBJ_JEWELLERY:
- id[ IDTYPE_JEWELLERY ][ty] = setting;
- break;
-
- case OBJ_POTIONS:
- id[ IDTYPE_POTIONS ][ty] = setting;
- break;
-
- default:
- break;
- }
-} // end set_ident_type()
-
-char get_ident_type(char cla, int ty)
-{
- switch (cla)
- {
- case OBJ_WANDS:
- return id[ IDTYPE_WANDS ][ty];
-
- case OBJ_SCROLLS:
- return id[ IDTYPE_SCROLLS ][ty];
-
- case OBJ_JEWELLERY:
- return id[ IDTYPE_JEWELLERY ][ty];
-
- case OBJ_POTIONS:
- return id[ IDTYPE_POTIONS ][ty];
-
- default:
- return (ID_UNKNOWN_TYPE);
- }
-} // end get_ident_type()
-
-unsigned char check_item_knowledge(void)
-{
- char st_pass[ITEMNAME_SIZE] = "";
- int i, j;
- char lines = 0;
- unsigned char anything = 0;
- int ft = 0;
- int max = 0;
- int yps = 0;
- int inv_count = 0;
- unsigned char ki = 0;
-
- const int num_lines = get_number_of_lines();
-
-#ifdef DOS_TERM
- char buffer[2400];
-
- gettext(35, 1, 80, 25, buffer);
-#endif
-
-#ifdef DOS_TERM
- window(35, 1, 80, 25);
-#endif
-
- clrscr();
-
- for (i = 0; i < 4; i++)
- {
- for (j = 0; j < 30; j++)
- {
- if (id[i][j] == ID_KNOWN_TYPE)
- inv_count++;
- }
- }
-
- if (inv_count == 0)
- {
- cprintf("You don't recognise anything yet!");
- if (getch() == 0)
- getch();
- goto putty;
- }
-
- textcolor(BLUE);
- cprintf(" You recognise:");
- textcolor(LIGHTGREY);
- lines++;
-
- for (i = 0; i < 4; i++)
- {
- switch (i)
- {
- case IDTYPE_WANDS:
- ft = OBJ_WANDS;
- max = NUM_WANDS;
- break;
- case IDTYPE_SCROLLS:
- ft = OBJ_SCROLLS;
- max = NUM_SCROLLS;
- break;
- case IDTYPE_JEWELLERY:
- ft = OBJ_JEWELLERY;
- max = NUM_JEWELLERY;
- break;
- case IDTYPE_POTIONS:
- ft = OBJ_POTIONS;
- max = NUM_POTIONS;
- break;
- }
-
- for (j = 0; j < max; j++)
- {
- if (lines > num_lines - 2 && inv_count > 0)
- {
- gotoxy(1, num_lines);
- cprintf("-more-");
-
- ki = getch();
-
- if (ki == ESCAPE)
- {
-#ifdef DOS_TERM
- puttext(35, 1, 80, 25, buffer);
-#endif
- return ESCAPE;
- }
- if (ki >= 'A' && ki <= 'z')
- {
-#ifdef DOS_TERM
- puttext(35, 1, 80, 25, buffer);
-#endif
- return ki;
- }
-
- if (ki == 0)
- ki = getch();
-
- lines = 0;
- clrscr();
- gotoxy(1, 1);
- anything = 0;
- }
-
- int ident_level = get_ident_type( ft, j );
-
- if (ident_level == ID_KNOWN_TYPE)
- {
- anything++;
-
- if (lines > 0)
- cprintf(EOL);
- lines++;
- cprintf(" ");
-
- yps = wherey();
-
- // item_name now requires a "real" item, so we'll create a tmp
- item_def tmp;// = { ft, j, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 };
- tmp.base_type = ft;
- tmp.sub_type = j;
- tmp.colour = 1;
-
- item_name( tmp, DESC_PLAIN, st_pass );
-
- cprintf(st_pass);
-
- inv_count--;
-
- if (wherey() != yps)
- lines++;
- }
- } // end of j loop
- }
-
- if (anything > 0)
- {
- ki = getch();
- //ki = getch();
- //ki = anything;
-
- if (ki >= 'A' && ki <= 'z')
- {
-#ifdef DOS_TERM
- puttext(35, 1, 80, 25, buffer);
-#endif
- return ki;
- }
-
- if (ki == 0)
- ki = getch();
-#ifdef DOS_TERM
- puttext(35, 1, 80, 25, buffer);
-#endif
- return anything;
- }
-
- putty:
-#ifdef DOS_TERM
- puttext(35, 1, 80, 25, buffer);
-#endif
-
- return ki;
-} // end check_item_knowledge()
-
-
-// Used for: Pandemonium demonlords, shopkeepers, scrolls, random artefacts
-int make_name( unsigned long seed, bool all_cap, char buff[ ITEMNAME_SIZE ] )
-{
- char name[ITEMNAME_SIZE];
- int numb[17];
-
- int i = 0;
- bool want_vowel = false;
- bool has_space = false;
-
- for (i = 0; i < ITEMNAME_SIZE; i++)
- name[i] = '\0';
-
- const int var1 = (seed & 0xFF);
- const int var2 = ((seed >> 8) & 0xFF);
- const int var3 = ((seed >> 16) & 0xFF);
- const int var4 = ((seed >> 24) & 0xFF);
-
- numb[0] = 373 * var1 + 409 * var2 + 281 * var3;
- numb[1] = 163 * var4 + 277 * var2 + 317 * var3;
- numb[2] = 257 * var1 + 179 * var4 + 83 * var3;
- numb[3] = 61 * var1 + 229 * var2 + 241 * var4;
- numb[4] = 79 * var1 + 263 * var2 + 149 * var3;
- numb[5] = 233 * var4 + 383 * var2 + 311 * var3;
- numb[6] = 199 * var1 + 211 * var4 + 103 * var3;
- numb[7] = 139 * var1 + 109 * var2 + 349 * var4;
- numb[8] = 43 * var1 + 389 * var2 + 359 * var3;
- numb[9] = 367 * var4 + 101 * var2 + 251 * var3;
- numb[10] = 293 * var1 + 59 * var4 + 151 * var3;
- numb[11] = 331 * var1 + 107 * var2 + 307 * var4;
- numb[12] = 73 * var1 + 157 * var2 + 347 * var3;
- numb[13] = 379 * var4 + 353 * var2 + 227 * var3;
- numb[14] = 181 * var1 + 173 * var4 + 193 * var3;
- numb[15] = 131 * var1 + 167 * var2 + 53 * var4;
- numb[16] = 313 * var1 + 127 * var2 + 401 * var3 + 337 * var4;
-
- int len = 3 + numb[0] % 5 + ((numb[1] % 5 == 0) ? numb[2] % 6 : 1);
-
- if (all_cap)
- len += 6;
-
- int j = numb[3] % 17;
- const int k = numb[4] % 17;
- int count = 0;
-
- for (i = 0; i < len; i++)
- {
- j = (j + 1) % 17;
- if (j == 0)
- {
- count++;
- if (count > 9)
- break;
- }
-
- if (!has_space && i > 5 && i < len - 4
- && (numb[(k + 10 * j) % 17] % 5) != 3)
- {
- want_vowel = true;
- name[i] = ' ';
- }
- else if (i > 0
- && (want_vowel
- || (i > 1
- && is_random_name_vowel( name[i - 1] )
- && !is_random_name_vowel( name[i - 2] )
- && (numb[(k + 4 * j) % 17] % 5) <= 1 )))
- {
- want_vowel = true;
- name[i] = retvow( numb[(k + 7 * j) % 17] );
-
- if (is_random_name_space( name[i] ))
- {
- if (i == 0)
- {
- want_vowel = false;
- name[i] = retlet( numb[(k + 14 * j) % 17] );
- }
- else if (len < 7
- || i <= 2 || i >= len - 3
- || is_random_name_space( name[i - 1] )
- || (i > 1 && is_random_name_space( name[i - 2] ))
- || (i > 2
- && !is_random_name_vowel( name[i - 1] )
- && !is_random_name_vowel( name[i - 2] )))
- {
- i--;
- continue;
- }
- }
- else if (i > 1
- && name[i] == name[i - 1]
- && (name[i] == 'y' || name[i] == 'i'
- || (numb[(k + 12 * j) % 17] % 5) <= 1))
- {
- i--;
- continue;
- }
- }
- else
- {
- if ((len > 3 || i != 0)
- && (numb[(k + 13 * j) % 17] % 7) <= 1
- && (i < len - 2 || (i > 0 && !is_random_name_space(name[i - 1]))))
- {
- const bool beg = ((i < 1) || is_random_name_space(name[i - 1]));
- const bool end = (i >= len - 2);
-
- const int first = (beg ? 0 : (end ? 14 : 0));
- const int last = (beg ? 27 : (end ? 56 : 67));
-
- const int num = last - first;
-
- i++;
-
- switch (numb[(k + 11 * j) % 17] % num + first)
- {
- // start, middle
- case 0: strcat(name, "kl"); break;
- case 1: strcat(name, "gr"); break;
- case 2: strcat(name, "cl"); break;
- case 3: strcat(name, "cr"); break;
- case 4: strcat(name, "fr"); break;
- case 5: strcat(name, "pr"); break;
- case 6: strcat(name, "tr"); break;
- case 7: strcat(name, "tw"); break;
- case 8: strcat(name, "br"); break;
- case 9: strcat(name, "pl"); break;
- case 10: strcat(name, "bl"); break;
- case 11: strcat(name, "str"); i++; len++; break;
- case 12: strcat(name, "shr"); i++; len++; break;
- case 13: strcat(name, "thr"); i++; len++; break;
- // start, middle, end
- case 14: strcat(name, "sm"); break;
- case 15: strcat(name, "sh"); break;
- case 16: strcat(name, "ch"); break;
- case 17: strcat(name, "th"); break;
- case 18: strcat(name, "ph"); break;
- case 19: strcat(name, "pn"); break;
- case 20: strcat(name, "kh"); break;
- case 21: strcat(name, "gh"); break;
- case 22: strcat(name, "mn"); break;
- case 23: strcat(name, "ps"); break;
- case 24: strcat(name, "st"); break;
- case 25: strcat(name, "sk"); break;
- case 26: strcat(name, "sch"); i++; len++; break;
- // middle, end
- case 27: strcat(name, "ts"); break;
- case 28: strcat(name, "cs"); break;
- case 29: strcat(name, "xt"); break;
- case 30: strcat(name, "nt"); break;
- case 31: strcat(name, "ll"); break;
- case 32: strcat(name, "rr"); break;
- case 33: strcat(name, "ss"); break;
- case 34: strcat(name, "wk"); break;
- case 35: strcat(name, "wn"); break;
- case 36: strcat(name, "ng"); break;
- case 37: strcat(name, "cw"); break;
- case 38: strcat(name, "mp"); break;
- case 39: strcat(name, "ck"); break;
- case 40: strcat(name, "nk"); break;
- case 41: strcat(name, "dd"); break;
- case 42: strcat(name, "tt"); break;
- case 43: strcat(name, "bb"); break;
- case 44: strcat(name, "pp"); break;
- case 45: strcat(name, "nn"); break;
- case 46: strcat(name, "mm"); break;
- case 47: strcat(name, "kk"); break;
- case 48: strcat(name, "gg"); break;
- case 49: strcat(name, "ff"); break;
- case 50: strcat(name, "pt"); break;
- case 51: strcat(name, "tz"); break;
- case 52: strcat(name, "dgh"); i++; len++; break;
- case 53: strcat(name, "rgh"); i++; len++; break;
- case 54: strcat(name, "rph"); i++; len++; break;
- case 55: strcat(name, "rch"); i++; len++; break;
- // middle only
- case 56: strcat(name, "cz"); break;
- case 57: strcat(name, "xk"); break;
- case 58: strcat(name, "zx"); break;
- case 59: strcat(name, "xz"); break;
- case 60: strcat(name, "cv"); break;
- case 61: strcat(name, "vv"); break;
- case 62: strcat(name, "nl"); break;
- case 63: strcat(name, "rh"); break;
- case 64: strcat(name, "dw"); break;
- case 65: strcat(name, "nw"); break;
- case 66: strcat(name, "khl"); i++; len++; break;
- default:
- i--;
- break;
- }
- }
- else
- {
- if (i == 0)
- {
- name[i] = 'a' + (numb[(k + 8 * j) % 17] % 26);
- want_vowel = is_random_name_vowel( name[i] );
- }
- else
- {
- name[i] = retlet( numb[(k + 3 * j) % 17] );
- }
- }
- }
-
- if (name[i] == '\0')
- {
- i--;
- continue;
- }
-
- if (want_vowel && !is_random_name_vowel( name[i] )
- || (!want_vowel && is_random_name_vowel( name[i] )))
- {
- i--;
- continue;
- }
-
- if (is_random_name_space( name[i] ))
- has_space = true;
-
- if (!is_random_name_vowel( name[i] ))
- want_vowel = true;
- else
- want_vowel = false;
- }
-
- // catch break and try to give a final letter
- if (i > 0
- && !is_random_name_space( name[i - 1] )
- && name[i - 1] != 'y'
- && is_random_name_vowel( name[i - 1] )
- && (count > 9 || (i < 8 && numb[16] % 3)))
- {
- name[i] = retlet( numb[j] );
- }
-
- len = strlen( name );
-
- if (len)
- {
- for (i = len - 1; i > 0; i--)
- {
- if (!isspace( name[i] ))
- break;
- else
- {
- name[i] = '\0';
- len--;
- }
- }
- }
-
- if (len >= 3)
- strncpy( buff, name, ITEMNAME_SIZE );
- else
- {
- strncpy( buff, "plog", ITEMNAME_SIZE );
- len = 4;
- }
-
- buff[ ITEMNAME_SIZE - 1 ] = '\0';
-
- for (i = 0; i < len; i++)
- {
- if (all_cap || i == 0 || buff[i - 1] == ' ')
- buff[i] = toupper( buff[i] );
- }
-
- return (len);
-} // end make_name()
-
-bool is_random_name_space(char let)
-{
- return (let == ' ');
-}
-
-static bool is_random_name_vowel( char let )
-{
- return (let == 'a' || let == 'e' || let == 'i' || let == 'o' || let == 'u'
- || let == 'y' || let == ' ');
-} // end is_random_name_vowel()
-
-static char retvow( int sed )
-{
- static const char vowels[] = "aeiouaeiouaeiouy ";
- return (vowels[ sed % (sizeof(vowels) - 1) ]);
-} // end retvow()
-
-static char retlet( int sed )
-{
- static const char consonants[] = "bcdfghjklmnpqrstvwxzcdfghlmnrstlmnrst";
- return (consonants[ sed % (sizeof(consonants) - 1) ]);
-}
diff --git a/stone_soup/crawl-ref/source/itemname.h b/stone_soup/crawl-ref/source/itemname.h
deleted file mode 100644
index 5e7cc49bfe..0000000000
--- a/stone_soup/crawl-ref/source/itemname.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * File: itemname.cc
- * Summary: Misc functions.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef ITEMNAME_H
-#define ITEMNAME_H
-
-#include "externs.h"
-
-bool is_vowel( const char chr );
-
-/* ***********************************************************************
- * called from: describe - effects - item_use - shopping
- * *********************************************************************** */
-char get_ident_type(char cla, int ty);
-
-
-/* ***********************************************************************
- * called from: acr - chardump - direct - effects - fight - invent -
- * it_use2 - item_use - items - monstuff - mstuff2 - ouch -
- * shopping - spells1 - spells2 - spells3
- * *********************************************************************** */
-char item_name( const item_def &item, char descrip, char buff[ITEMNAME_SIZE],
- bool terse = false );
-
-
-/* ***********************************************************************
- * called from: debug - describe - dungeon - fight - files - item_use -
- * monstuff - mstuff2 - players - spells0
- * *********************************************************************** */
-int property( const item_def &item, int prop_type );
-
-
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-unsigned char check_item_knowledge(void);
-
-
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void clear_ids(void);
-
-
-/* ***********************************************************************
- * called from: direct - fight - food - items - monstuff - religion -
- * shopping
- * *********************************************************************** */
-void it_name(int itn, char des, char buff[ITEMNAME_SIZE], bool terse = false);
-
-/* ***********************************************************************
- * called from: acr - chardump - command - effects - fight - invent -
- * it_use2 - it_use3 - item_use - items - ouch - output -
- * spell - spells1 - spells2 - spells3 - spells4 - transfor
- * *********************************************************************** */
-void in_name(int inn, char des, char buff[ITEMNAME_SIZE], bool terse = false);
-
-/* ***********************************************************************
- * called from: itemname.cc items.cc item_use.cc mstuff2.cc
- * *********************************************************************** */
-void quant_name( const item_def &item, int quant, char des,
- char buff[ITEMNAME_SIZE], bool terse = false );
-
-/* ***********************************************************************
- * bit operations called from a large number of files
- * *********************************************************************** */
-bool item_cursed( const item_def &item );
-bool item_known_cursed( const item_def &item );
-bool item_known_uncursed( const item_def &item );
-// bool fully_indentified( const item_def &item );
-
-bool item_type_known( const item_def &item );
-
-bool set_item_ego_type( item_def &item, int item_type, int ego_type );
-
-int get_weapon_brand( const item_def &item );
-int get_ammo_brand( const item_def &item );
-int get_armour_ego_type( const item_def &item );
-
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void init_properties(void);
-
-int make_name( unsigned long seed, bool all_caps, char buff[ ITEMNAME_SIZE ] );
-
-/* ***********************************************************************
- * called from: files - shopping
- * *********************************************************************** */
-void save_id(char identy[4][50]);
-
-
-/* ***********************************************************************
- * called from: files - item_use - newgame - ouch - shopping - spells1
- * *********************************************************************** */
-void set_ident_type( char cla, int ty, char setting, bool force = false );
-
-
-/* ***********************************************************************
- * called from: dungeon - item_use
- * *********************************************************************** */
-bool hide2armour( unsigned char *which_subtype );
-
-
-#endif
diff --git a/stone_soup/crawl-ref/source/itemprop.cc b/stone_soup/crawl-ref/source/itemprop.cc
deleted file mode 100644
index 0a48f6c00f..0000000000
--- a/stone_soup/crawl-ref/source/itemprop.cc
+++ /dev/null
@@ -1,2032 +0,0 @@
-/*
- * File: itemprop.cc
- * Summary: Misc functions.
- * Written by: Brent Ross
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- BWR Created
- */
-
-#include "AppHdr.h"
-#include "itemname.h"
-
-#include <ctype.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#ifdef DOS
-#include <conio.h>
-#endif
-
-#include "externs.h"
-
-#include "items.h"
-#include "itemprop.h"
-#include "macro.h"
-#include "mon-util.h"
-#include "player.h"
-#include "randart.h"
-#include "skills2.h"
-#include "stuff.h"
-#include "transfor.h"
-#include "view.h"
-
-
-// XXX: name strings in most of the following are currently unused!
-struct armour_def
-{
- armour_type id;
- const char *name;
- int ac;
- int ev;
- int mass;
-
- bool light;
- equipment_type slot;
- size_type fit_min;
- size_type fit_max;
-};
-
-// Note: the Little-Giant range is used to make armours which are very
-// flexible and adjustable and can be worn by any player character...
-// providing they also pass the shape test, of course.
-static int Armour_index[NUM_ARMOURS];
-static armour_def Armour_prop[NUM_ARMOURS] =
-{
- { ARM_ANIMAL_SKIN, "animal skin", 2, 0, 100,
- true, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT },
- { ARM_ROBE, "robe", 2, 0, 60,
- true, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_BIG },
- { ARM_LEATHER_ARMOUR, "leather armour", 3, -1, 150,
- true, EQ_BODY_ARMOUR, SIZE_SMALL, SIZE_MEDIUM },
- { ARM_STUDDED_LEATHER_ARMOUR,"studded leather armour",4, -1, 180,
- true, EQ_BODY_ARMOUR, SIZE_SMALL, SIZE_MEDIUM },
-
- { ARM_RING_MAIL, "ring mail", 4, -2, 250,
- false, EQ_BODY_ARMOUR, SIZE_SMALL, SIZE_MEDIUM },
- { ARM_SCALE_MAIL, "scale mail", 5, -3, 350,
- false, EQ_BODY_ARMOUR, SIZE_SMALL, SIZE_MEDIUM },
- { ARM_CHAIN_MAIL, "chain mail", 6, -4, 400,
- false, EQ_BODY_ARMOUR, SIZE_SMALL, SIZE_MEDIUM },
- { ARM_BANDED_MAIL, "banded mail", 7, -5, 500,
- false, EQ_BODY_ARMOUR, SIZE_MEDIUM, SIZE_MEDIUM },
- { ARM_SPLINT_MAIL, "splint mail", 8, -5, 550,
- false, EQ_BODY_ARMOUR, SIZE_MEDIUM, SIZE_MEDIUM },
- { ARM_PLATE_MAIL, "plate mail", 10, -6, 650,
- false, EQ_BODY_ARMOUR, SIZE_MEDIUM, SIZE_MEDIUM },
- { ARM_CRYSTAL_PLATE_MAIL, "crystal plate mail", 14, -8, 1200,
- false, EQ_BODY_ARMOUR, SIZE_MEDIUM, SIZE_MEDIUM },
-
- { ARM_TROLL_HIDE, "troll hide", 2, -1, 220,
- true, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT },
- { ARM_TROLL_LEATHER_ARMOUR, "troll leather armour", 4, -1, 220,
- true, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT },
- { ARM_STEAM_DRAGON_HIDE, "steam dragon hide", 2, 0, 120,
- true, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT },
- { ARM_STEAM_DRAGON_ARMOUR, "steam dragon armour", 4, 0, 120,
- true, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT },
- { ARM_MOTTLED_DRAGON_HIDE, "mottled dragon hide", 2, -1, 150,
- true, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT },
- { ARM_MOTTLED_DRAGON_ARMOUR,"mottled dragon armour", 5, -1, 150,
- true, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT },
-
- { ARM_SWAMP_DRAGON_HIDE, "swamp dragon hide", 3, -2, 200,
- false, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT },
- { ARM_SWAMP_DRAGON_ARMOUR, "swamp dragon armour", 5, -2, 200,
- false, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT },
- { ARM_DRAGON_HIDE, "dragon hide", 3, -3, 350,
- false, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT },
- { ARM_DRAGON_ARMOUR, "dragon armour", 6, -3, 350,
- false, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT },
- { ARM_ICE_DRAGON_HIDE, "ice dragon hide", 3, -3, 350,
- false, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT },
- { ARM_ICE_DRAGON_ARMOUR, "ice dragon armour", 6, -3, 350,
- false, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT },
- { ARM_STORM_DRAGON_HIDE, "storm dragon hide", 4, -5, 600,
- false, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT },
- { ARM_STORM_DRAGON_ARMOUR, "storm dragon armour", 8, -5, 600,
- false, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT },
- { ARM_GOLD_DRAGON_HIDE, "gold dragon hide", 5, -8, 1100,
- false, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT },
- { ARM_GOLD_DRAGON_ARMOUR, "gold dragaon armour", 10, -8, 1100,
- false, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT },
-
- { ARM_CLOAK, "cloak", 1, 0, 40,
- true, EQ_CLOAK, SIZE_LITTLE, SIZE_BIG },
- { ARM_GLOVES, "gloves", 1, 0, 20,
- true, EQ_GLOVES, SIZE_SMALL, SIZE_MEDIUM },
-
- { ARM_HELMET, "helmet", 1, 0, 80,
- false, EQ_HELMET, SIZE_SMALL, SIZE_MEDIUM },
- { ARM_CAP, "cap", 0, 0, 40,
- true, EQ_HELMET, SIZE_LITTLE, SIZE_LARGE },
-
- // Note that barding size is compared against torso so it currently
- // needs to fit medium, but that doesn't matter as much as race
- // and shapeshift status.
- { ARM_BOOTS, "boots", 1, 0, 30,
- true, EQ_BOOTS, SIZE_SMALL, SIZE_MEDIUM },
- { ARM_CENTAUR_BARDING, "centaur barding", 4, -2, 100,
- true, EQ_BOOTS, SIZE_MEDIUM, SIZE_MEDIUM },
- { ARM_NAGA_BARDING, "naga barding", 4, -2, 100,
- true, EQ_BOOTS, SIZE_MEDIUM, SIZE_MEDIUM },
-
- // Note: shields use ac-value as sh-value, EV pen is used for heavy_shield
- { ARM_BUCKLER, "buckler", 3, 0, 90,
- true, EQ_SHIELD, SIZE_LITTLE, SIZE_MEDIUM },
- { ARM_SHIELD, "shield", 5, -1, 150,
- false, EQ_SHIELD, SIZE_SMALL, SIZE_BIG },
- { ARM_LARGE_SHIELD, "large shield", 7, -2, 230,
- false, EQ_SHIELD, SIZE_MEDIUM, SIZE_GIANT },
-};
-
-struct weapon_def
-{
- int id;
- const char *name;
- int dam;
- int hit;
- int speed;
- int mass;
- int str_weight;
-
- skill_type skill;
- hands_reqd_type hands;
- size_type fit_size; // actual size is one size smaller
- missile_type ammo; // MI_NONE for non-launchers
- bool throwable;
-
- int dam_type;
-};
-
-static int Weapon_index[NUM_WEAPONS];
-static weapon_def Weapon_prop[NUM_WEAPONS] =
-{
- // Maces & Flails
- { WPN_WHIP, "whip", 4, 2, 13, 30, 2,
- SK_MACES_FLAILS, HANDS_ONE, SIZE_MEDIUM, MI_NONE, false,
- DAMV_SLASHING },
- { WPN_CLUB, "club", 5, 3, 13, 50, 7,
- SK_MACES_FLAILS, HANDS_ONE, SIZE_SMALL, MI_NONE, true,
- DAMV_CRUSHING },
- { WPN_HAMMER, "hammer", 7, 3, 13, 90, 7,
- SK_MACES_FLAILS, HANDS_ONE, SIZE_SMALL, MI_NONE, false,
- DAMV_CRUSHING },
- { WPN_MACE, "mace", 8, 3, 14, 120, 8,
- SK_MACES_FLAILS, HANDS_ONE, SIZE_SMALL, MI_NONE, false,
- DAMV_CRUSHING },
- { WPN_FLAIL, "flail", 9, 2, 15, 130, 8,
- SK_MACES_FLAILS, HANDS_ONE, SIZE_SMALL, MI_NONE, false,
- DAMV_CRUSHING },
- { WPN_ANCUS, "ancus", 9, 2, 14, 120, 8,
- SK_MACES_FLAILS, HANDS_ONE, SIZE_MEDIUM, MI_NONE, false,
- DAMV_CRUSHING },
- { WPN_MORNINGSTAR, "morningstar", 10, -2, 15, 140, 8,
- SK_MACES_FLAILS, HANDS_ONE, SIZE_MEDIUM, MI_NONE, false,
- DAMV_PIERCING | DAM_BLUDGEON },
- { WPN_DEMON_WHIP, "demon whip", 10, 2, 13, 30, 2,
- SK_MACES_FLAILS, HANDS_ONE, SIZE_MEDIUM, MI_NONE, false,
- DAMV_SLASHING },
- { WPN_SPIKED_FLAIL, "spiked flail", 12, -3, 16, 190, 8,
- SK_MACES_FLAILS, HANDS_ONE, SIZE_MEDIUM, MI_NONE, false,
- DAMV_PIERCING | DAM_BLUDGEON },
- { WPN_EVENINGSTAR, "eveningstar", 12, -2, 15, 180, 8,
- SK_MACES_FLAILS, HANDS_ONE, SIZE_MEDIUM, MI_NONE, false,
- DAMV_PIERCING | DAM_BLUDGEON },
- { WPN_DIRE_FLAIL, "dire flail", 13, -6, 14, 240, 9,
- SK_MACES_FLAILS, HANDS_DOUBLE, SIZE_MEDIUM, MI_NONE, false,
- DAMV_PIERCING | DAM_BLUDGEON },
- { WPN_GREAT_MACE, "great mace", 18, -5, 19, 270, 9,
- SK_MACES_FLAILS, HANDS_TWO, SIZE_LARGE, MI_NONE, false,
- DAMV_CRUSHING },
- { WPN_GIANT_CLUB, "giant club", 19, -8, 20, 330, 10,
- SK_MACES_FLAILS, HANDS_TWO, SIZE_BIG, MI_NONE, false,
- DAMV_CRUSHING },
- { WPN_GIANT_SPIKED_CLUB, "giant spiked club", 20, -9, 21, 350, 10,
- SK_MACES_FLAILS, HANDS_TWO, SIZE_BIG, MI_NONE, false,
- DAMV_PIERCING | DAM_BLUDGEON },
-
- // Short blades
- { WPN_KNIFE, "knife", 3, 5, 10, 10, 1,
- SK_SHORT_BLADES, HANDS_ONE, SIZE_LITTLE, MI_NONE, false,
- DAMV_STABBING | DAM_SLICE },
- { WPN_DAGGER, "dagger", 4, 6, 10, 20, 1,
- SK_SHORT_BLADES, HANDS_ONE, SIZE_LITTLE, MI_NONE, true,
- DAMV_STABBING | DAM_SLICE },
- { WPN_QUICK_BLADE, "quick blade", 5, 6, 8, 50, 0,
- SK_SHORT_BLADES, HANDS_ONE, SIZE_LITTLE, MI_NONE, false,
- DAMV_STABBING | DAM_SLICE },
- { WPN_SHORT_SWORD, "short sword", 6, 4, 11, 80, 2,
- SK_SHORT_BLADES, HANDS_ONE, SIZE_SMALL, MI_NONE, false,
- DAMV_SLICING | DAM_PIERCE },
- { WPN_SABRE, "sabre", 7, 4, 11, 90, 2,
- SK_SHORT_BLADES, HANDS_ONE, SIZE_SMALL, MI_NONE, false,
- DAMV_SLICING | DAM_PIERCE },
-
- // Long swords
- { WPN_FALCHION, "falchion", 8, 2, 13, 170, 4,
- SK_LONG_SWORDS, HANDS_ONE, SIZE_MEDIUM, MI_NONE, false,
- DAMV_SLICING }, // or perhaps DAMV_CHOPPING is more apt?
- { WPN_LONG_SWORD, "long sword", 10, -2, 14, 160, 3,
- SK_LONG_SWORDS, HANDS_ONE, SIZE_MEDIUM, MI_NONE, false,
- DAMV_SLICING },
- { WPN_SCIMITAR, "scimitar", 11, -2, 14, 170, 3,
- SK_LONG_SWORDS, HANDS_ONE, SIZE_MEDIUM, MI_NONE, false,
- DAMV_SLICING },
- { WPN_KATANA, "katana", 13, -1, 13, 160, 3,
- SK_LONG_SWORDS, HANDS_HALF, SIZE_MEDIUM, MI_NONE, false,
- DAMV_SLICING },
- { WPN_DEMON_BLADE, "demon blade", 13, -3, 15, 200, 4,
- SK_LONG_SWORDS, HANDS_ONE, SIZE_MEDIUM, MI_NONE, false,
- DAMV_SLICING },
- { WPN_BLESSED_BLADE, "blessed blade", 14, -3, 14, 200, 4,
- SK_LONG_SWORDS, HANDS_ONE, SIZE_MEDIUM, MI_NONE, false,
- DAMV_SLICING },
- { WPN_DOUBLE_SWORD, "double sword", 15, -5, 16, 220, 5,
- SK_LONG_SWORDS, HANDS_HALF, SIZE_MEDIUM, MI_NONE, false,
- DAMV_SLICING },
- { WPN_GREAT_SWORD, "great sword", 16, -5, 17, 250, 6,
- SK_LONG_SWORDS, HANDS_TWO, SIZE_LARGE, MI_NONE, false,
- DAMV_SLICING },
- { WPN_TRIPLE_SWORD, "triple sword", 17, -5, 17, 260, 6,
- SK_LONG_SWORDS, HANDS_TWO, SIZE_LARGE, MI_NONE, false,
- DAMV_SLICING },
-
- // Axes
- { WPN_HAND_AXE, "hand axe", 7, 3, 13, 80, 6,
- SK_AXES, HANDS_ONE, SIZE_SMALL, MI_NONE, true,
- DAMV_CHOPPING },
- { WPN_WAR_AXE, "war axe", 11, -3, 16, 180, 7,
- SK_AXES, HANDS_ONE, SIZE_MEDIUM, MI_NONE, false,
- DAMV_CHOPPING },
- { WPN_BROAD_AXE, "broad axe", 14, -6, 17, 230, 8,
- SK_AXES, HANDS_HALF, SIZE_MEDIUM, MI_NONE, false,
- DAMV_CHOPPING },
- { WPN_BATTLEAXE, "battleaxe", 16, -7, 18, 250, 8,
- SK_AXES, HANDS_TWO, SIZE_LARGE, MI_NONE, false,
- DAMV_CHOPPING },
- { WPN_EXECUTIONERS_AXE, "executioner\'s axe", 18, -8, 18, 280, 9,
- SK_AXES, HANDS_TWO, SIZE_LARGE, MI_NONE, false,
- DAMV_CHOPPING },
-
- // Polearms
- { WPN_SPEAR, "spear", 6, 3, 12, 50, 3,
- SK_POLEARMS, HANDS_HALF, SIZE_SMALL, MI_NONE, true,
- DAMV_PIERCING },
- { WPN_TRIDENT, "trident", 9, 2, 14, 160, 4,
- SK_POLEARMS, HANDS_HALF, SIZE_MEDIUM, MI_NONE, false,
- DAMV_PIERCING },
- { WPN_DEMON_TRIDENT, "demon trident", 13, 2, 14, 160, 4,
- SK_POLEARMS, HANDS_HALF, SIZE_MEDIUM, MI_NONE, false,
- DAMV_PIERCING },
- { WPN_HALBERD, "halberd", 13, -3, 16, 200, 5,
- SK_POLEARMS, HANDS_TWO, SIZE_LARGE, MI_NONE, false,
- DAMV_CHOPPING | DAM_PIERCE },
- { WPN_SCYTHE, "scythe", 14, -4, 20, 220, 7,
- SK_POLEARMS, HANDS_TWO, SIZE_LARGE, MI_NONE, false,
- DAMV_SLICING },
- { WPN_GLAIVE, "glaive", 15, -3, 18, 200, 6,
- SK_POLEARMS, HANDS_TWO, SIZE_LARGE, MI_NONE, false,
- DAMV_CHOPPING },
- { WPN_LOCHABER_AXE, "lochaber axe", 18, -6, 20, 200, 8,
- SK_POLEARMS, HANDS_TWO, SIZE_LARGE, MI_NONE, false,
- DAMV_CHOPPING },
-
- { WPN_QUARTERSTAFF, "quarterstaff", 9, 2, 12, 180, 7,
- SK_STAVES, HANDS_DOUBLE, SIZE_LARGE, MI_NONE, false,
- DAMV_CRUSHING },
- { WPN_LAJATANG, "lajatang", 14, -3, 14, 200, 3,
- SK_STAVES, HANDS_DOUBLE, SIZE_LARGE, MI_NONE, false,
- DAMV_SLICING },
-
- // Range weapons
- // Notes:
- // - HANDS_HALF means a reloading time penalty if using shield
- // - damage field is used for bonus strength damage (string tension)
- // - slings get a bonus from dex, not str (as tension is meaningless)
- // - str weight is used for speed and applying dex to skill
- { WPN_BLOWGUN, "blowgun", 0, 2, 10, 20, 0,
- SK_DARTS, HANDS_HALF, SIZE_LITTLE, MI_NEEDLE, false,
- DAMV_NON_MELEE },
- { WPN_SLING, "sling", 0, 2, 11, 20, 1,
- SK_SLINGS, HANDS_HALF, SIZE_LITTLE, MI_STONE, false,
- DAMV_NON_MELEE },
- { WPN_HAND_CROSSBOW, "hand crossbow", 3, 4, 15, 70, 5,
- SK_CROSSBOWS, HANDS_HALF, SIZE_SMALL, MI_DART, false,
- DAMV_NON_MELEE },
- { WPN_CROSSBOW, "crossbow", 5, 4, 15, 150, 8,
- SK_CROSSBOWS, HANDS_TWO, SIZE_MEDIUM, MI_BOLT, false,
- DAMV_NON_MELEE },
- { WPN_BOW, "bow", 4, 1, 11, 90, 2,
- SK_BOWS, HANDS_TWO, SIZE_MEDIUM, MI_ARROW, false,
- DAMV_NON_MELEE },
- { WPN_LONGBOW, "longbow", 5, 0, 12, 120, 3,
- SK_BOWS, HANDS_TWO, SIZE_LARGE, MI_ARROW, false,
- DAMV_NON_MELEE },
-};
-
-struct missile_def
-{
- int id;
- const char *name;
- int dam;
- int mass;
- bool throwable;
-};
-
-static int Missile_index[NUM_MISSILES];
-static missile_def Missile_prop[NUM_MISSILES] =
-{
- { MI_NEEDLE, "needle", 0, 1, false },
- { MI_STONE, "stone", 4, 2, true },
- { MI_DART, "dart", 5, 3, true },
- { MI_ARROW, "arrow", 6, 5, false },
- { MI_BOLT, "bolt", 8, 5, false },
- { MI_LARGE_ROCK, "large rock", 20, 1000, true },
-};
-
-struct food_def
-{
- int id;
- const char *name;
- int value;
- int carn_mod;
- int herb_mod;
- int mass;
- int turns;
-};
-
-// NOTE: Any food with special random messages or side effects
-// currently only takes one turn to eat (except ghouls and chunks)...
-// if this changes then those items will have to have special code
-// (like ghoul chunks) to guarantee that the special thing is only
-// done once. See the ghoul eating code over in food.cc.
-static int Food_index[NUM_FOODS];
-static food_def Food_prop[NUM_FOODS] =
-{
- { FOOD_MEAT_RATION, "meat ration", 5000, 500, -1500, 80, 4 },
- { FOOD_SAUSAGE, "sausage", 1500, 150, -400, 40, 1 },
- { FOOD_CHUNK, "chunk", 1000, 100, -500, 100, 3 },
- { FOOD_BEEF_JERKY, "beef jerky", 800, 100, -250, 20, 1 },
-
- { FOOD_BREAD_RATION, "bread ration", 4400, -1500, 750, 80, 4 },
- { FOOD_SNOZZCUMBER, "snozzcumber", 1500, -500, 500, 50, 1 },
- { FOOD_ORANGE, "orange", 1000, -350, 400, 20, 1 },
- { FOOD_BANANA, "banana", 1000, -350, 400, 20, 1 },
- { FOOD_LEMON, "lemon", 1000, -350, 400, 20, 1 },
- { FOOD_PEAR, "pear", 700, -250, 300, 20, 1 },
- { FOOD_APPLE, "apple", 700, -250, 300, 20, 1 },
- { FOOD_APRICOT, "apricot", 700, -250, 300, 15, 1 },
- { FOOD_CHOKO, "choko", 600, -200, 250, 30, 1 },
- { FOOD_RAMBUTAN, "rambutan", 600, -200, 250, 10, 1 },
- { FOOD_LYCHEE, "lychee", 600, -200, 250, 10, 1 },
- { FOOD_STRAWBERRY, "strawberry", 200, -80, 100, 5, 1 },
- { FOOD_GRAPE, "grape", 100, -40, 50, 2, 1 },
- { FOOD_SULTANA, "sultana", 70, -30, 30, 1, 1 },
-
- { FOOD_ROYAL_JELLY, "royal jelly", 4000, 0, 0, 55, 1 },
- { FOOD_HONEYCOMB, "honeycomb", 2000, 0, 0, 40, 1 },
- { FOOD_PIZZA, "pizza", 1500, 0, 0, 40, 1 },
- { FOOD_CHEESE, "cheese", 1200, 0, 0, 40, 1 },
-};
-
-// Must call this functions early on so that the above tables can
-// be accessed correctly.
-void init_properties(void)
-{
- int i;
-
- for (i = 0; i < NUM_ARMOURS; i++)
- Armour_index[ Armour_prop[i].id ] = i;
-
- for (i = 0; i < NUM_WEAPONS; i++)
- Weapon_index[ Weapon_prop[i].id ] = i;
-
- for (i = 0; i < NUM_MISSILES; i++)
- Missile_index[ Missile_prop[i].id ] = i;
-
- for (i = 0; i < NUM_FOODS; i++)
- Food_index[ Food_prop[i].id ] = i;
-}
-
-
-// Some convenient functions to hide the bit operations and create
-// an interface layer between the code and the data in case this
-// gets changed again. -- bwr
-
-//
-// Item cursed status functions:
-//
-bool item_cursed( const item_def &item )
-{
- return (item.flags & ISFLAG_CURSED);
-}
-
-bool item_known_cursed( const item_def &item )
-{
- return ((item.flags & ISFLAG_KNOW_CURSE) && (item.flags & ISFLAG_CURSED));
-}
-
-bool item_known_uncursed( const item_def &item )
-{
- return ((item.flags & ISFLAG_KNOW_CURSE) && !(item.flags & ISFLAG_CURSED));
-}
-
-void do_curse_item( item_def &item )
-{
- item.flags |= ISFLAG_CURSED;
-}
-
-void do_uncurse_item( item_def &item )
-{
- item.flags &= (~ISFLAG_CURSED);
-}
-
-//
-// Item identification status:
-//
-bool item_ident( const item_def &item, unsigned long flags )
-{
- return ((item.flags & flags) == flags);
-}
-
-void set_ident_flags( item_def &item, unsigned long flags )
-{
- item.flags |= flags;
-}
-
-void unset_ident_flags( item_def &item, unsigned long flags )
-{
- item.flags &= (~flags);
-}
-
-//
-// Equipment race and description:
-//
-unsigned long get_equip_race( const item_def &item )
-{
- return (item.flags & ISFLAG_RACIAL_MASK);
-}
-
-unsigned long get_equip_desc( const item_def &item )
-{
- return (item.flags & ISFLAG_COSMETIC_MASK);
-}
-
-void set_equip_race( item_def &item, unsigned long flags )
-{
- ASSERT( (flags & ~ISFLAG_RACIAL_MASK) == 0 );
-
- // first check for base-sub pairs that can't ever have racial types
- switch (item.base_type)
- {
- case OBJ_WEAPONS:
- if (item.sub_type == WPN_GIANT_CLUB
- || item.sub_type == WPN_GIANT_SPIKED_CLUB
- || item.sub_type == WPN_KATANA
- || item.sub_type == WPN_LAJATANG
- || item.sub_type == WPN_SLING
- || item.sub_type == WPN_KNIFE
- || item.sub_type == WPN_QUARTERSTAFF
- || item.sub_type == WPN_DEMON_BLADE
- || item.sub_type == WPN_DEMON_WHIP
- || item.sub_type == WPN_DEMON_TRIDENT)
- {
- return;
- }
- break;
-
- case OBJ_ARMOUR:
- // not hides, dragon armour, crystal plate, or barding
- if (item.sub_type >= ARM_DRAGON_HIDE
- && item.sub_type <= ARM_SWAMP_DRAGON_ARMOUR
- && item.sub_type != ARM_CENTAUR_BARDING
- && item.sub_type != ARM_NAGA_BARDING)
- {
- return;
- }
- break;
-
- case OBJ_MISSILES:
- if (item.sub_type == MI_STONE || item.sub_type == MI_LARGE_ROCK)
- return;
- break;
-
- default:
- return;
- }
-
- // check that item is appropriate for racial type
- switch (flags)
- {
- case ISFLAG_ELVEN:
- if (item.base_type == OBJ_ARMOUR
- && (item.sub_type == ARM_SPLINT_MAIL
- || item.sub_type == ARM_BANDED_MAIL
- || item.sub_type == ARM_PLATE_MAIL))
- {
- return;
- }
- break;
-
- case ISFLAG_DWARVEN:
- if (item.base_type == OBJ_ARMOUR
- && (item.sub_type == ARM_ROBE
- || item.sub_type == ARM_LEATHER_ARMOUR
- || item.sub_type == ARM_STUDDED_LEATHER_ARMOUR))
- {
- return;
- }
- break;
-
- case ISFLAG_ORCISH:
- default:
- break;
- }
-
- item.flags &= ~ISFLAG_RACIAL_MASK; // delete previous
- item.flags |= flags;
-}
-
-void set_equip_desc( item_def &item, unsigned long flags )
-{
- ASSERT( (flags & ~ISFLAG_COSMETIC_MASK) == 0 );
-
- item.flags &= ~ISFLAG_COSMETIC_MASK; // delete previous
- item.flags |= flags;
-}
-
-//
-// These functions handle the description and subtypes for helmets/caps
-//
-short get_helmet_type( const item_def &item )
-{
- ASSERT( item.base_type == OBJ_ARMOUR
- && get_armour_slot( item ) == EQ_HELMET );
-
- return (item.plus2 & THELM_TYPE_MASK);
-}
-
-short get_helmet_desc( const item_def &item )
-{
- ASSERT( item.base_type == OBJ_ARMOUR
- && get_armour_slot( item ) == EQ_HELMET );
-
- return (item.plus2 & THELM_DESC_MASK);
-}
-
-void set_helmet_type( item_def &item, short type )
-{
- ASSERT( (type & ~THELM_TYPE_MASK) == 0 );
- ASSERT( item.base_type == OBJ_ARMOUR
- && get_armour_slot( item ) == EQ_HELMET );
-
- // make sure we have the right sub_type (to get properties correctly)
- if (type == THELM_HELMET || type == THELM_HELM)
- item.sub_type = ARM_HELMET;
-
- // [dshaligram] FIXME: This is for when we import caps
- // else
- // item.sub_type = ARM_CAP;
-
- item.plus2 &= ~THELM_TYPE_MASK;
- item.plus2 |= type;
-}
-
-void set_helmet_desc( item_def &item, short type )
-{
- ASSERT( (type & ~THELM_DESC_MASK) == 0 );
- ASSERT( item.base_type == OBJ_ARMOUR
- && get_armour_slot( item ) == EQ_HELMET );
-
- const int helmtype = get_helmet_type(item);
- if ((helmtype == THELM_CAP || helmtype == THELM_WIZARD_HAT)
- && type > THELM_DESC_PLUMED)
- type = THELM_DESC_PLAIN;
-
- item.plus2 &= ~THELM_DESC_MASK;
- item.plus2 |= type;
-}
-
-bool is_hard_helmet(const item_def &item)
-{
- return (item.base_type == OBJ_ARMOUR
- && item.sub_type == ARM_HELMET
- && (get_helmet_type(item) == THELM_HELM
- || get_helmet_type(item) == THELM_HELMET));
-}
-
-void set_helmet_random_desc( item_def &item )
-{
- ASSERT( item.base_type == OBJ_ARMOUR
- && get_armour_slot( item ) == EQ_HELMET );
-
- item.plus2 &= ~THELM_DESC_MASK;
-
- if (is_hard_helmet(item))
- item.plus2 |= (random2(8) << 8);
- else
- item.plus2 |= (random2(5) << 8);
-
-}
-
-bool is_helmet_type( const item_def &item, short val )
-{
- if (item.base_type != OBJ_ARMOUR || get_armour_slot( item ) != EQ_HELMET)
- return (false);
-
- return (get_helmet_type( item ) == val);
-}
-
-//
-// Ego item functions:
-//
-bool set_item_ego_type( item_def &item, int item_type, int ego_type )
-{
- if (item.base_type == item_type
- && !is_random_artefact( item )
- && !is_fixed_artefact( item ))
- {
- item.special = ego_type;
- return (true);
- }
-
- return (false);
-}
-
-int get_weapon_brand( const item_def &item )
-{
- // Weapon ego types are "brands", so we do the randart lookup here.
-
- // Staves "brands" handled specially
- if (item.base_type != OBJ_WEAPONS)
- return (SPWPN_NORMAL);
-
- if (is_fixed_artefact( item ))
- {
- switch (item.special)
- {
- case SPWPN_SWORD_OF_CEREBOV:
- return (SPWPN_FLAMING);
-
- case SPWPN_STAFF_OF_OLGREB:
- return (SPWPN_VENOM);
-
- case SPWPN_VAMPIRES_TOOTH:
- return (SPWPN_VAMPIRICISM);
-
- default:
- return (SPWPN_NORMAL);
- }
- }
- else if (is_random_artefact( item ))
- {
- return (randart_wpn_property( item, RAP_BRAND ));
- }
-
- return (item.special);
-}
-
-int get_ammo_brand( const item_def &item )
-{
- // no artefact arrows yet -- bwr
- if (item.base_type != OBJ_MISSILES || is_random_artefact( item ))
- return (SPMSL_NORMAL);
-
- return (item.special);
-}
-
-int get_armour_ego_type( const item_def &item )
-{
- // artefact armours have no ego type, must look up powers separately
- if (item.base_type != OBJ_ARMOUR
- || (is_random_artefact( item ) && !is_unrandom_artefact( item )))
- {
- return (SPARM_NORMAL);
- }
-
- return (item.special);
-}
-
-//
-// Armour information and checking functions
-//
-bool hide2armour( item_def &item )
-{
- if (item.base_type != OBJ_ARMOUR)
- return (false);
-
- switch (item.sub_type)
- {
- default:
- return (false);
-
- case ARM_DRAGON_HIDE:
- item.sub_type = ARM_DRAGON_ARMOUR;
- break;
-
- case ARM_TROLL_HIDE:
- item.sub_type = ARM_TROLL_LEATHER_ARMOUR;
- break;
-
- case ARM_ICE_DRAGON_HIDE:
- item.sub_type = ARM_ICE_DRAGON_ARMOUR;
- break;
-
- case ARM_MOTTLED_DRAGON_HIDE:
- item.sub_type = ARM_MOTTLED_DRAGON_ARMOUR;
- break;
-
- case ARM_STORM_DRAGON_HIDE:
- item.sub_type = ARM_STORM_DRAGON_ARMOUR;
- break;
-
- case ARM_GOLD_DRAGON_HIDE:
- item.sub_type = ARM_GOLD_DRAGON_ARMOUR;
- break;
-
- case ARM_SWAMP_DRAGON_HIDE:
- item.sub_type = ARM_SWAMP_DRAGON_ARMOUR;
- break;
-
- case ARM_STEAM_DRAGON_HIDE:
- item.sub_type = ARM_STEAM_DRAGON_ARMOUR;
- break;
- }
-
- return (true);
-} // end hide2armour()
-
-// Return the enchantment limit of a piece of armour
-int armour_max_enchant( const item_def &item )
-{
- ASSERT( item.base_type == OBJ_ARMOUR );
-
- const int eq_slot = get_armour_slot( item );
-
- int max_plus = MAX_SEC_ENCHANT;
- if (eq_slot == EQ_BODY_ARMOUR || eq_slot == EQ_SHIELD)
- max_plus = MAX_ARM_ENCHANT;
-
- return (max_plus);
-}
-
-// doesn't include animal skin (only skins we can make and enchant)
-bool armour_is_hide( const item_def &item, bool inc_made )
-{
- ASSERT( item.base_type == OBJ_ARMOUR );
-
- switch (item.sub_type)
- {
- case ARM_TROLL_LEATHER_ARMOUR:
- case ARM_DRAGON_ARMOUR:
- case ARM_ICE_DRAGON_ARMOUR:
- case ARM_STEAM_DRAGON_ARMOUR:
- case ARM_MOTTLED_DRAGON_ARMOUR:
- case ARM_STORM_DRAGON_ARMOUR:
- case ARM_GOLD_DRAGON_ARMOUR:
- case ARM_SWAMP_DRAGON_ARMOUR:
- return (inc_made);
-
- case ARM_TROLL_HIDE:
- case ARM_DRAGON_HIDE:
- case ARM_ICE_DRAGON_HIDE:
- case ARM_STEAM_DRAGON_HIDE:
- case ARM_MOTTLED_DRAGON_HIDE:
- case ARM_STORM_DRAGON_HIDE:
- case ARM_GOLD_DRAGON_HIDE:
- case ARM_SWAMP_DRAGON_HIDE:
- return (true);
-
- default:
- break;
- }
-
- return (false);
-}
-
-// used to distinguish shiny and embroidered
-bool armour_not_shiny( const item_def &item )
-{
- ASSERT( item.base_type == OBJ_ARMOUR );
-
- switch (item.sub_type)
- {
- case ARM_ROBE:
- case ARM_CLOAK:
- case ARM_GLOVES:
- case ARM_BOOTS:
- case ARM_NAGA_BARDING:
- case ARM_CENTAUR_BARDING:
- case ARM_CAP:
- case ARM_LEATHER_ARMOUR:
- case ARM_STUDDED_LEATHER_ARMOUR:
- case ARM_ANIMAL_SKIN:
- case ARM_TROLL_HIDE:
- case ARM_TROLL_LEATHER_ARMOUR:
- return (true);
-
- case ARM_HELMET:
- {
- const int helmtype = get_helmet_type(item);
- return (helmtype == THELM_CAP || helmtype == THELM_WIZARD_HAT);
- }
- default:
- break;
- }
-
- return (false);
-}
-
-int armour_str_required( const item_def &arm )
-{
- ASSERT (arm.base_type == OBJ_ARMOUR );
-
- int ret = 0;
-
- const equipment_type slot = get_armour_slot( arm );
- const int mass = item_mass( arm );
-
- switch (slot)
- {
- case EQ_BODY_ARMOUR:
- ret = mass / 35;
- break;
-
- case EQ_SHIELD:
- ret = mass / 15;
- break;
-
- default:
- break;
- }
-
- return ((ret < STR_REQ_THRESHOLD) ? 0 : ret);
-}
-
-equipment_type get_armour_slot( const item_def &item )
-{
- ASSERT( item.base_type == OBJ_ARMOUR );
-
- return (Armour_prop[ Armour_index[item.sub_type] ].slot);
-}
-
-bool jewellery_is_amulet( const item_def &item )
-{
- ASSERT( item.base_type == OBJ_JEWELLERY );
-
- return (item.sub_type >= AMU_RAGE);
-}
-
-bool check_jewellery_size( const item_def &item, size_type size )
-{
- ASSERT( item.base_type == OBJ_JEWELLERY );
-
- // Currently assuming amulets are always wearable (only needs
- // to be held over head or heart... giants can strap it on with
- // a bit of binder twine). However, rings need to actually fit
- // around the ring finger to work, and so the big cannot use them.
- return (size <= SIZE_LARGE || jewellery_is_amulet( item ));
-}
-
-// Returns the basic light status of an armour, ignoring things like the
-// elven bonus... you probably want is_light_armour() most times.
-bool base_armour_is_light( const item_def &item )
-{
- ASSERT( item.base_type == OBJ_ARMOUR );
-
- return (Armour_prop[ Armour_index[item.sub_type] ].light);
-}
-
-// returns number of sizes off
-int fit_armour_size( const item_def &item, size_type size )
-{
- ASSERT( item.base_type == OBJ_ARMOUR );
-
- const size_type min = Armour_prop[ Armour_index[item.sub_type] ].fit_min;
- const size_type max = Armour_prop[ Armour_index[item.sub_type] ].fit_max;
-
- if (size < min)
- return (min - size); // -'ve means levels too small
- else if (size > max)
- return (max - size); // +'ve means levels too large
-
- return (0);
-}
-
-// returns true if armour fits size (shape needs additional verification)
-bool check_armour_size( const item_def &item, size_type size )
-{
- ASSERT( item.base_type == OBJ_ARMOUR );
-
- return (fit_armour_size( item, size ) == 0);
-}
-
-// Note that this function is used to check validity of equipment
-// coming out of transformations... so it shouldn't contain any
-// wield/unwield only checks like two-handed weapons and shield.
-bool check_armour_shape( const item_def &item, bool quiet )
-{
- ASSERT( item.base_type == OBJ_ARMOUR );
-
- const int slot = get_armour_slot( item );
-
- if (!player_is_shapechanged())
- {
- switch (slot)
- {
- case EQ_BOOTS:
- switch (you.species)
- {
- case SP_NAGA:
- if (item.sub_type != ARM_NAGA_BARDING)
- {
- if (!quiet)
- mpr( "You can't wear that!" );
-
- return (false);
- }
- break;
-
- case SP_CENTAUR:
- if (item.sub_type != ARM_CENTAUR_BARDING)
- {
- if (!quiet)
- mpr( "You can't wear that!" );
-
- return (false);
- }
- break;
-
- case SP_KENKU:
- if (!quiet)
- {
- if (item.sub_type == ARM_BOOTS)
- mpr( "Boots don't fit your feet!" );
- else
- mpr( "You can't wear barding!" );
- }
- return (false);
-
- case SP_MERFOLK:
- if (player_in_water() && item.sub_type == ARM_BOOTS)
- {
- if (!quiet)
- mpr( "You don't currently have feet!" );
-
- return (false);
- }
- // intentional fall-through
- default:
- if (item.sub_type == ARM_NAGA_BARDING
- || item.sub_type == ARM_CENTAUR_BARDING)
- {
- if (!quiet)
- mpr( "You can't wear barding!" );
-
- return (false);
- }
-
- if (you.mutation[MUT_HOOVES] >= 2)
- {
- if (!quiet)
- mpr( "You can't wear boots with hooves!" );
-
- return (false);
- }
- break;
- }
- break;
-
- case EQ_HELMET:
- if (item.sub_type == ARM_CAP
- || get_helmet_type(item) == THELM_CAP
- || get_helmet_type(item) == THELM_WIZARD_HAT)
- break;
-
- if (you.species == SP_KENKU)
- {
- if (!quiet)
- mpr( "That helmet does not fit your head!" );
-
- return (false);
- }
-
- if (you.species == SP_MINOTAUR || you.mutation[MUT_HORNS])
- {
- if (!quiet)
- mpr( "You can't wear that with your horns!" );
-
- return (false);
- }
- break;
-
- case EQ_GLOVES:
- if (you.mutation[MUT_CLAWS] >= 3)
- {
- if (!quiet)
- mpr( "You can't wear gloves with your huge claws!" );
-
- return (false);
- }
- break;
-
- case EQ_BODY_ARMOUR:
- // Cannot swim in heavy armour
- if (player_is_swimming() && !is_light_armour( item ))
- {
- if (!quiet)
- mpr("You can't swim in that!");
-
- return (false);
- }
-
- // Draconians are human-sized, but have wings that cause problems
- // with most body armours (only very flexible fit allowed).
- if (player_genus( GENPC_DRACONIAN )
- && !check_armour_size( item, SIZE_BIG ))
- {
- if (!quiet)
- mpr( "That armour doesn't fit your wings." );
-
- return (false);
- }
- break;
-
- default:
- break;
- }
- }
- else
- {
- // Note: some transformation include all of the above as well
- if (item.sub_type == ARM_NAGA_BARDING
- || item.sub_type == ARM_CENTAUR_BARDING)
- {
- if (!quiet)
- mpr( "You can't wear barding in your current form!" );
-
- return (false);
- }
- }
-
- // Note: This need to be checked after all the special cases
- // above, and in addition to shapechanged or not. This is
- // a simple check against the armour types that are forced off.
-
- // FIXME FIXME FIXME
- /*
- if (!transform_can_equip_type( slot ))
- {
- if (!quiet)
- mpr( "You can't wear that in your current form!" );
-
- return (false);
- }
- */
-
- return (true);
-}
-
-//
-// Weapon information and checking functions:
-//
-
-// Checks how rare a weapon is. Many of these have special routines for
-// placement, especially those with a rarity of zero. Chance is out of 10.
-int weapon_rarity( int w_type )
-{
- switch (w_type)
- {
- case WPN_CLUB:
- case WPN_DAGGER:
- return (10);
-
- case WPN_HAND_AXE:
- case WPN_MACE:
- case WPN_QUARTERSTAFF:
- return (9);
-
- case WPN_BOW:
- case WPN_FLAIL:
- case WPN_HAMMER:
- case WPN_SABRE:
- case WPN_SHORT_SWORD:
- case WPN_SLING:
- case WPN_SPEAR:
- return (8);
-
- case WPN_FALCHION:
- case WPN_LONG_SWORD:
- case WPN_MORNINGSTAR:
- case WPN_WAR_AXE:
- return (7);
-
- case WPN_BATTLEAXE:
- case WPN_CROSSBOW:
- case WPN_GREAT_SWORD:
- case WPN_SCIMITAR:
- case WPN_TRIDENT:
- return (6);
-
- case WPN_GLAIVE:
- case WPN_HALBERD:
- case WPN_BLOWGUN:
- return (5);
-
- case WPN_BROAD_AXE:
- case WPN_HAND_CROSSBOW:
- case WPN_SPIKED_FLAIL:
- case WPN_WHIP:
- return (4);
-
- case WPN_GREAT_MACE:
- return (3);
-
- case WPN_ANCUS:
- case WPN_DIRE_FLAIL:
- case WPN_SCYTHE:
- case WPN_LONGBOW:
- return (2);
-
- case WPN_GIANT_CLUB:
- case WPN_GIANT_SPIKED_CLUB:
- case WPN_LOCHABER_AXE:
- return (1);
-
- case WPN_DOUBLE_SWORD:
- case WPN_EVENINGSTAR:
- case WPN_EXECUTIONERS_AXE:
- case WPN_KATANA:
- case WPN_LAJATANG:
- case WPN_KNIFE:
- case WPN_QUICK_BLADE:
- case WPN_TRIPLE_SWORD:
- case WPN_DEMON_TRIDENT:
- case WPN_DEMON_WHIP:
- case WPN_DEMON_BLADE:
- case WPN_BLESSED_BLADE:
- // zero value weapons must be placed specially -- see make_item() {dlb}
- return (0);
-
- default:
- break;
- }
-
- return (0);
-} // end rare_weapon()
-
-int get_vorpal_type( const item_def &item )
-{
- int ret = DVORP_NONE;
-
- if (item.base_type == OBJ_WEAPONS)
- ret = (Weapon_prop[ Weapon_index[item.sub_type] ].dam_type & DAMV_MASK);
-
- return (ret);
-} // end vorpal_type()
-
-int get_damage_type( const item_def &item )
-{
- int ret = DAM_BASH;
-
- if (item.base_type == OBJ_WEAPONS)
- ret = (Weapon_prop[ Weapon_index[item.sub_type] ].dam_type & DAM_MASK);
-
- return (ret);
-} // end damage_type()
-
-bool does_damage_type( const item_def &item, int dam_type )
-{
- return (get_damage_type( item ) & dam_type);
-} // end does_damage_type()
-
-
-// give hands required to wield weapon for a torso of "size"
-hands_reqd_type hands_reqd( const item_def &item, size_type size )
-{
- int ret = HANDS_ONE;
- int fit;
- bool doub = false;
-
- switch (item.base_type)
- {
- case OBJ_STAVES:
- case OBJ_WEAPONS:
- // Merging staff with magical staves for consistancy... doing
- // as a special case because we want to be very flexible with
- // these useful objects (we want spriggans and ogre magi to
- // be able to use them).
- if (item.base_type == OBJ_STAVES || item.sub_type == WPN_QUARTERSTAFF)
- {
- if (size < SIZE_SMALL)
- ret = HANDS_TWO;
- else if (size > SIZE_LARGE)
- ret = HANDS_ONE;
- else
- ret = HANDS_HALF;
- break;
- }
-
- ret = Weapon_prop[ Weapon_index[item.sub_type] ].hands;
-
- // size is the level where we can use one hand for one end
- if (ret == HANDS_DOUBLE)
- {
- doub = true;
- ret = HANDS_HALF;
- }
-
- // adjust handedness for size only for non-whip melee weapons
- if (!is_range_weapon( item )
- && item.sub_type != WPN_WHIP
- && item.sub_type != WPN_DEMON_WHIP)
- {
- fit = cmp_weapon_size( item, size );
-
- // Adjust handedness for non-medium races:
- // (XX values don't matter, see fit_weapon_wieldable_size)
- //
- // Spriggan Kobold Human Ogre Big Giant
- // Little 0 0 0 XX XX XX
- // Small +1 0 0 -2 XX XX
- // Medium XX +1 0 -1 -2 XX
- // Large XX XX 0 0 -1 -2
- // Big XX XX XX 0 0 -1
- // Giant XX XX XX XX 0 0
-
- // Note the stretching of double weapons for larger characters
- // by one level since they tend to be larger weapons.
- if (size < SIZE_MEDIUM && fit > 0)
- ret += fit;
- else if (size > SIZE_MEDIUM && fit < 0)
- ret += (fit + doub);
- }
- break;
-
- case OBJ_CORPSES: // unwieldy
- ret = HANDS_TWO;
- break;
-
- case OBJ_ARMOUR: // barding and body armours are unwieldy
- if (item.sub_type == ARM_NAGA_BARDING
- || item.sub_type == ARM_CENTAUR_BARDING
- || get_armour_slot( item ) == EQ_BODY_ARMOUR)
- {
- ret = HANDS_TWO;
- }
- break;
-
- default:
- break;
- }
-
- if (ret > HANDS_TWO)
- ret = HANDS_TWO;
- else if (ret < HANDS_ONE)
- ret = HANDS_ONE;
-
- return (static_cast< hands_reqd_type >( ret ));
-}
-
-bool is_double_ended( const item_def &item )
-{
- if (item.base_type == OBJ_STAVES)
- return (true);
- else if (item.base_type != OBJ_WEAPONS)
- return (false);
-
- return (Weapon_prop[ Weapon_index[item.sub_type] ].hands == HANDS_DOUBLE);
-}
-
-int double_wpn_awkward_speed( const item_def &item )
-{
- ASSERT( is_double_ended( item ) );
-
- const int base = property( item, PWPN_SPEED );
-
- return ((base * 30 + 10) / 20 + 2);
-}
-
-
-bool is_demonic( const item_def &item )
-{
- if (item.base_type == OBJ_WEAPONS)
- {
- switch (item.sub_type)
- {
- case WPN_DEMON_BLADE:
- case WPN_DEMON_WHIP:
- case WPN_DEMON_TRIDENT:
- return (true);
-
- default:
- break;
- }
- }
-
- return (false);
-} // end is_demonic()
-
-int weapon_str_weight( const item_def &wpn )
-{
- ASSERT (wpn.base_type == OBJ_WEAPONS || wpn.base_type == OBJ_STAVES);
-
- if (wpn.base_type == OBJ_STAVES)
- return (Weapon_prop[ Weapon_index[WPN_QUARTERSTAFF] ].str_weight);
-
- return (Weapon_prop[ Weapon_index[wpn.sub_type] ].str_weight);
-}
-
-int weapon_dex_weight( const item_def &wpn )
-{
- return (10 - weapon_str_weight( wpn ));
-}
-
-int weapon_impact_mass( const item_def &wpn )
-{
- ASSERT (wpn.base_type == OBJ_WEAPONS || wpn.base_type == OBJ_STAVES);
-
- return ((weapon_str_weight( wpn ) * item_mass( wpn ) + 5) / 10);
-}
-
-int weapon_str_required( const item_def &wpn, bool hand_half )
-{
- ASSERT (wpn.base_type == OBJ_WEAPONS || wpn.base_type == OBJ_STAVES);
-
- const int req = weapon_impact_mass( wpn ) / ((hand_half) ? 11 : 10);
-
- return ((req < STR_REQ_THRESHOLD) ? 0 : req);
-}
-
-// returns melee skill of item
-skill_type weapon_skill( const item_def &item )
-{
- if (item.base_type == OBJ_WEAPONS && !is_range_weapon( item ))
- return (Weapon_prop[ Weapon_index[item.sub_type] ].skill);
- else if (item.base_type == OBJ_STAVES)
- return (SK_STAVES);
-
- // this is used to mark that only fighting applies.
- return (SK_FIGHTING);
-}
-
-// front function for the above when we don't have a physical item to check
-skill_type weapon_skill( int wclass, int wtype )
-{
- item_def wpn;
-
- wpn.base_type = wclass;
- wpn.sub_type = wtype;
-
- return (weapon_skill( wpn ));
-} // end weapon_skill()
-
-// returns range skill of the item
-skill_type range_skill( const item_def &item )
-{
- if (item.base_type == OBJ_WEAPONS && is_range_weapon( item ))
- return (Weapon_prop[ Weapon_index[item.sub_type] ].skill);
- else if (item.base_type == OBJ_MISSILES && item.sub_type == MI_DART)
- return (SK_DARTS);
-
- return (SK_RANGED_COMBAT);
-}
-
-// front function for the above when we don't have a physical item to check
-skill_type range_skill( int wclass, int wtype )
-{
- item_def wpn;
-
- wpn.base_type = wclass;
- wpn.sub_type = wtype;
-
- return (range_skill( wpn ));
-} // end weapon_skill()
-
-
-// Calculate the bonus to melee EV for using "wpn", with "skill" and "dex"
-// to protect a body of size "body".
-int weapon_ev_bonus( const item_def &wpn, int skill, size_type body, int dex,
- bool hide_hidden )
-{
- ASSERT( wpn.base_type == OBJ_WEAPONS || wpn.base_type == OBJ_STAVES );
-
- int ret = 0;
-
- // Note: ret currently measured in halves (see skill factor)
- if (wpn.sub_type == WPN_WHIP || wpn.sub_type == WPN_DEMON_WHIP)
- ret = 3 + (dex / 5);
- else if (weapon_skill( wpn ) == SK_POLEARMS)
- ret = 2 + (dex / 5);
-
- // weapons of reaching are naturally a bit longer/flexier
- if (!hide_hidden || item_ident( wpn, ISFLAG_KNOW_TYPE ))
- {
- if (get_weapon_brand( wpn ) == SPWPN_REACHING)
- ret += 1;
- }
-
- // only consider additional modifications if we have a positive base:
- if (ret > 0)
- {
- // Size factors:
- // - large characters can't cover their flanks as well
- // - note that not all weapons are available to small characters
- if (body > SIZE_LARGE)
- ret -= (4 * (body - SIZE_LARGE) - 2);
- else if (body < SIZE_MEDIUM)
- ret += 1;
-
- // apply skill (and dividing by 2)
- ret = (ret * (skill + 10)) / 20;
-
- // make sure things can't get too insane
- if (ret > 8)
- ret = 8 + (ret - 8) / 2;
- }
-
- // Note: this is always a bonus
- return ((ret > 0) ? ret : 0);
-}
-
-static size_type weapon_size( const item_def &item )
-{
- ASSERT (item.base_type == OBJ_WEAPONS || item.base_type == OBJ_STAVES);
-
- if (item.base_type == OBJ_STAVES)
- return (Weapon_prop[ Weapon_index[WPN_QUARTERSTAFF] ].fit_size);
-
- return (Weapon_prop[ Weapon_index[item.sub_type] ].fit_size);
-}
-
-// returns number of sizes off
-int cmp_weapon_size( const item_def &item, size_type size )
-{
- ASSERT( item.base_type == OBJ_WEAPONS || item.base_type == OBJ_STAVES );
-
- return (weapon_size( item ) - size);
-}
-
-// Returns number of sizes away from being a usable weapon
-int fit_weapon_wieldable_size( const item_def &item, size_type size )
-{
- ASSERT( item.base_type == OBJ_WEAPONS || item.base_type == OBJ_STAVES );
-
- const int fit = cmp_weapon_size( item, size );
-
- return ((fit < -2) ? fit + 2 : (fit > 1) ? fit - 1 : 0);
-}
-
-// Returns number of sizes away from being throwable... the window
-// is currently [size - 5, size - 1].
-int fit_item_throwable_size( const item_def &item, size_type size )
-{
- int ret = item_size( item ) - size;
-
- return ((ret >= 0) ? ret + 1 : (ret > -6) ? 0 : ret + 5);
-}
-
-// Returns true if weapon is usable as a tool
-// Note that we assume that tool usable >= wieldable
-bool check_weapon_tool_size( const item_def &item, size_type size )
-{
- ASSERT( item.base_type == OBJ_WEAPONS || item.base_type == OBJ_STAVES );
-
- // Staves are currently usable for everyone just to be nice.
- if (item.base_type == OBJ_STAVES || item.sub_type == WPN_QUARTERSTAFF)
- return (true);
-
- const int fit = cmp_weapon_size( item, size );
-
- return (fit >= -3 && fit <= 1);
-}
-
-// Returns true if weapon is uasable as a weapon
-bool check_weapon_wieldable_size( const item_def &item, size_type size )
-{
- ASSERT( item.base_type == OBJ_WEAPONS || item.base_type == OBJ_STAVES );
-
- return (fit_weapon_wieldable_size( item, size ) == 0);
-}
-
-// Note that this function is used to check validity of equipment
-// coming out of transformations... so it shouldn't contain any
-// wield/unwield only checks like two-handed weapons and shield.
-// check_id is only used for descriptions, where we don't want to
-// give away any information the player doesn't have yet.
-bool check_weapon_shape( const item_def &item, bool quiet, bool check_id )
-{
- const int brand = get_weapon_brand( item );
-
- if ((!check_id || item_ident( item, ISFLAG_KNOW_TYPE ))
- && ((item.base_type == OBJ_WEAPONS
- && item.sub_type == WPN_BLESSED_BLADE)
- || brand == SPWPN_HOLY_WRATH
- || brand == SPWPN_DISRUPTION)
- && (you.is_undead || you.species == SP_DEMONSPAWN))
- {
- if (!quiet)
- mpr( "This weapon will not allow you to wield it." );
-
- return (false);
- }
-
- // Note: this should always be done last, see check_armour_shape()
- // FIXME FIXME FIXME
- /*
- if (!transform_can_equip_type( EQ_WEAPON ))
- {
- if (!quiet)
- mpr( "You can't wield anything in your current form!" );
-
- return (false);
- }
- */
-
- return (true);
-}
-
-// Returns the you.inv[] index of our wielded weapon or -1 (no item, not wield)
-int get_inv_wielded( void )
-{
- return (player_weapon_wielded() ? you.equip[EQ_WEAPON] : -1);
-}
-
-// Returns the you.inv[] index of our hand tool or -1 (no item, not usable)
-// Note that we don't count armour and such as "tools" here because
-// this function is used to judge if the item will sticky curse to
-// our hands.
-int get_inv_hand_tool( void )
-{
- const int tool = you.equip[EQ_WEAPON];
-
- // FIXME
- /*
- if (tool == -1 || !is_tool( you.inv[tool] ))
- return (-1);
-
- if (you.inv[tool].base_type == OBJ_WEAPONS
- || you.inv[tool].base_type == OBJ_STAVES)
- {
- // assuring that bad "shape" weapons aren't in hand
- ASSERT( check_weapon_shape( you.inv[tool], false ) );
-
- if (!check_weapon_tool_size( you.inv[tool], player_size() ))
- return (-1);
- }
- */
-
- return (tool);
-}
-
-// Returns the you.inv[] index of the thing in our hand... this is provided
-// as a service to specify that both of the above are irrelevant.
-// Do not use this for low level functions dealing with wielding directly.
-int get_inv_in_hand( void )
-{
- return (you.equip[EQ_WEAPON]);
-}
-
-//
-// Launcher and ammo functions:
-//
-missile_type fires_ammo_type( const item_def &item )
-{
- if (item.base_type != OBJ_WEAPONS)
- return (MI_NONE);
-
- return (Weapon_prop[ Weapon_index[item.sub_type] ].ammo);
-}
-
-bool is_range_weapon( const item_def &item )
-{
- return (fires_ammo_type( item ) != MI_NONE);
-}
-
-bool is_range_weapon_type( weapon_type wtype )
-{
- item_def wpn;
-
- wpn.base_type = OBJ_WEAPONS;
- wpn.sub_type = wtype;
-
- return (is_range_weapon( wpn ));
-}
-
-const char * ammo_name( const item_def &bow )
-{
- ASSERT( is_range_weapon( bow ) );
-
- const int ammo = fires_ammo_type( bow );
-
- return (Missile_prop[ Missile_index[ammo] ].name);
-}
-
-// returns true if item can be reasonably thrown without a launcher
-bool is_throwable( const item_def &wpn )
-{
- if (wpn.base_type == OBJ_WEAPONS)
- return (Weapon_prop[ Weapon_index[wpn.sub_type] ].throwable);
- else if (wpn.base_type == OBJ_MISSILES)
- return (Missile_prop[ Missile_index[wpn.sub_type] ].throwable);
-
- return (false);
-}
-
-// FIXME
-#if 0
-// decide if "being" is launching or throwing "ammo"
-launch_retval is_launched( int being_id, const item_def &ammo, bool msg )
-{
- ASSERT( being_id != MHITNOT );
-
- launch_retval ret = LRET_FUMBLED;
-
- const item_def * lnch = 0;
- int fit = 0;
-
- if (being_id == MHITYOU)
- {
- const int wpn = get_inv_wielded();
- lnch = (wpn == -1) ? 0 : &you.inv[wpn];
- fit = fit_item_throwable_size( ammo, player_size() );
- }
- else // monster case
- {
- const int wpn = menv[being_id].inv[MSLOT_WEAPON];
- lnch = (wpn == NON_ITEM) ? 0 : &mitm[wpn];
- fit = fit_item_throwable_size( ammo, mons_size( menv[being_id].type ) );
- }
-
- if (lnch
- && lnch->base_type == OBJ_WEAPONS
- && is_range_weapon( *lnch )
- && ammo.base_type == OBJ_MISSILES
- && ammo.sub_type == fires_ammo_type( *lnch ))
- {
- ret = LRET_LAUNCHED;
- }
- else if (is_throwable( ammo ))
- {
- if (fit == 0)
- ret = LRET_THROWN;
- else
- {
- ret = LRET_FUMBLED;
-
- if (being_id == MHITYOU && msg)
- {
- mpr( MSGCH_WARN, "It's difficult to throw such a%s object.",
- (fit > 0) ? " large" : (fit < 0) ? " small" : "n awkward" );
- }
- }
- }
-
- return (ret);
-}
-#endif
-
-//
-// Staff/rod functions:
-//
-bool item_is_rod( const item_def &item )
-{
- return (item.base_type == OBJ_STAVES
- && item.sub_type >= STAFF_SMITING && item.sub_type < STAFF_AIR);
-}
-
-bool item_is_staff( const item_def &item )
-{
- // Isn't De Morgan's law wonderful. -- bwr
- return (item.base_type == OBJ_STAVES
- && (item.sub_type < STAFF_SMITING || item.sub_type >= STAFF_AIR));
-}
-
-//
-// Ring functions:
-//
-// Returns number of pluses on jewellery (always none for amulets yet).
-int ring_has_pluses( const item_def &item )
-{
- ASSERT (item.base_type == OBJ_JEWELLERY);
-
- switch (item.sub_type)
- {
- case RING_SLAYING:
- return (2);
-
- case RING_PROTECTION:
- case RING_EVASION:
- case RING_STRENGTH:
- case RING_INTELLIGENCE:
- case RING_DEXTERITY:
- return (1);
-
- default:
- break;
- }
-
- return (0);
-}
-
-//
-// Food functions:
-//
-bool food_is_meat( const item_def &item )
-{
- ASSERT( is_valid_item( item ) && item.base_type == OBJ_FOOD );
-
- return (Food_prop[ Food_index[item.sub_type] ].carn_mod > 0);
-}
-
-bool food_is_veg( const item_def &item )
-{
- ASSERT( is_valid_item( item ) && item.base_type == OBJ_FOOD );
-
- return (Food_prop[ Food_index[item.sub_type] ].herb_mod > 0);
-}
-
-// returns food value for one turn of eating
-int food_value( const item_def &item )
-{
- ASSERT( is_valid_item( item ) && item.base_type == OBJ_FOOD );
-
- const int herb = you.mutation[MUT_HERBIVOROUS];
-
- // XXX: this needs to be better merged with the mutation system
- const int carn = (you.species == SP_KOBOLD || you.species == SP_GHOUL) ? 3
- : you.mutation[MUT_CARNIVOROUS];
-
- const food_def &food = Food_prop[ Food_index[item.sub_type] ];
-
- int ret = food.value;
-
- ret += (carn * food.carn_mod);
- ret += (herb * food.herb_mod);
-
- return ((ret > 0) ? div_rand_round( ret, food.turns ) : 0);
-}
-
-int food_turns( const item_def &item )
-{
- ASSERT( is_valid_item( item ) && item.base_type == OBJ_FOOD );
-
- return (Food_prop[ Food_index[item.sub_type] ].turns);
-}
-
-bool can_cut_meat( const item_def &item )
-{
- return (does_damage_type( item, DAM_SLICE ));
-}
-
-// returns true if item counts as a tool for tool size comaparisons and msgs
-bool is_tool( const item_def &item )
-{
- // Currently using OBJ_WEAPONS instead of can_cut_meat() as almost
- // any weapon might be an evocable artefact.
- return (item.base_type == OBJ_WEAPONS
- || item.base_type == OBJ_STAVES
- || (item.base_type == OBJ_MISCELLANY
- && item.sub_type != MISC_RUNE_OF_ZOT));
-}
-
-
-//
-// Generic item functions:
-//
-int property( const item_def &item, int prop_type )
-{
- switch (item.base_type)
- {
- case OBJ_ARMOUR:
- if (prop_type == PARM_AC)
- return (Armour_prop[ Armour_index[item.sub_type] ].ac);
- else if (prop_type == PARM_EVASION)
- return (Armour_prop[ Armour_index[item.sub_type] ].ev);
- break;
-
- case OBJ_WEAPONS:
- if (prop_type == PWPN_DAMAGE)
- return (Weapon_prop[ Weapon_index[item.sub_type] ].dam);
- else if (prop_type == PWPN_HIT)
- return (Weapon_prop[ Weapon_index[item.sub_type] ].hit);
- else if (prop_type == PWPN_SPEED)
- return (Weapon_prop[ Weapon_index[item.sub_type] ].speed);
- break;
-
- case OBJ_MISSILES:
- if (prop_type == PWPN_DAMAGE)
- return (Missile_prop[ Missile_index[item.sub_type] ].dam);
- break;
-
- case OBJ_STAVES:
- if (prop_type == PWPN_DAMAGE)
- return (Weapon_prop[ Weapon_index[WPN_QUARTERSTAFF] ].dam);
- else if (prop_type == PWPN_HIT)
- return (Weapon_prop[ Weapon_index[WPN_QUARTERSTAFF] ].hit);
- else if (prop_type == PWPN_SPEED)
- return (Weapon_prop[ Weapon_index[WPN_QUARTERSTAFF] ].speed);
- break;
-
- default:
- break;
- }
-
- return (0);
-}
-
-int item_mass( const item_def &item )
-{
- int unit_mass = 0;
-
- switch (item.base_type)
- {
- case OBJ_WEAPONS:
- unit_mass = Weapon_prop[ Weapon_index[item.sub_type] ].mass;
- break;
-
- case OBJ_ARMOUR:
- unit_mass = Armour_prop[ Armour_index[item.sub_type] ].mass;
-
- if (get_equip_race( item ) == ISFLAG_ELVEN)
- {
- const int reduc = (unit_mass >= 25) ? unit_mass / 5 : 5;
-
- // truncate to the nearest 5 and reduce the item mass:
- unit_mass -= ((reduc / 5) * 5);
- unit_mass = MAXIMUM( unit_mass, 5 );
- }
- break;
-
- case OBJ_MISSILES:
- unit_mass = Missile_prop[ Missile_index[item.sub_type] ].mass;
- break;
-
- case OBJ_FOOD:
- unit_mass = Food_prop[ Food_index[item.sub_type] ].mass;
- break;
-
- case OBJ_WANDS:
- unit_mass = 100;
- break;
-
- case OBJ_UNKNOWN_I:
- unit_mass = 200; // labeled "books"
- break;
-
- case OBJ_SCROLLS:
- unit_mass = 20;
- break;
-
- case OBJ_JEWELLERY:
- unit_mass = 10;
- break;
-
- case OBJ_POTIONS:
- unit_mass = 40;
- break;
-
- case OBJ_UNKNOWN_II:
- unit_mass = 5; // labeled "gems"
- break;
-
- case OBJ_BOOKS:
- unit_mass = 70;
- break;
-
- case OBJ_STAVES:
- unit_mass = 130;
- break;
-
- case OBJ_ORBS:
- unit_mass = 300;
- break;
-
- case OBJ_MISCELLANY:
- switch (item.sub_type)
- {
- case MISC_BOTTLED_EFREET:
- case MISC_CRYSTAL_BALL_OF_SEEING:
- case MISC_CRYSTAL_BALL_OF_ENERGY:
- case MISC_CRYSTAL_BALL_OF_FIXATION:
- unit_mass = 150;
- break;
-
- default:
- unit_mass = 100;
- break;
- }
- break;
-
- case OBJ_CORPSES:
- unit_mass = mons_weight( item.plus );
-
- if (item.sub_type == CORPSE_SKELETON)
- unit_mass /= 10;
- break;
-
- default:
- case OBJ_GOLD:
- unit_mass = 0;
- break;
- }
-
- return ((unit_mass > 0) ? unit_mass : 0);
-}
-
-// Note that this function, an item sizes in general aren't quite on the
-// same scale as PCs and monsters.
-size_type item_size( const item_def &item )
-{
- int size = SIZE_TINY;
-
- switch (item.base_type)
- {
- case OBJ_WEAPONS:
- case OBJ_STAVES:
- size = Weapon_prop[ Weapon_index[item.sub_type] ].fit_size - 1;
- break;
-
- case OBJ_ARMOUR:
- size = SIZE_MEDIUM;
- switch (item.sub_type)
- {
- case ARM_GLOVES:
- case ARM_HELMET:
- case ARM_CAP:
- case ARM_BOOTS:
- case ARM_BUCKLER:
- // tiny armour
- break;
-
- case ARM_SHIELD:
- size = SIZE_LITTLE;
- break;
-
- case ARM_LARGE_SHIELD:
- size = SIZE_SMALL;
- break;
-
- default: // body armours and bardings
- size = SIZE_MEDIUM;
- break;
- }
- break;
-
- case OBJ_MISSILES:
- if (item.sub_type == MI_LARGE_ROCK)
- size = SIZE_SMALL;
- break;
-
- case OBJ_MISCELLANY:
- if (item.sub_type == MISC_PORTABLE_ALTAR_OF_NEMELEX)
- {
- size = SIZE_SMALL;
- }
- break;
-
- case OBJ_CORPSES:
- // FIXME
- // size = mons_size( item.plus, PSIZE_BODY );
- size = SIZE_SMALL;
- break;
-
- default: // sundry tiny items
- break;
- }
-
- if (size < SIZE_TINY)
- size = SIZE_TINY;
- else if (size > SIZE_HUGE)
- size = SIZE_HUGE;
-
- return (static_cast<size_type>( size ));
-}
-
-// returns true if we might be interested in dumping the colour
-bool is_colourful_item( const item_def &item )
-{
- bool ret = false;
-
- switch (item.base_type)
- {
- case OBJ_ARMOUR:
- if (item.sub_type == ARM_ROBE
- || item.sub_type == ARM_CLOAK
- || item.sub_type == ARM_CAP
- || item.sub_type == ARM_NAGA_BARDING
- || item.sub_type == ARM_CENTAUR_BARDING)
- {
- ret = true;
- }
- break;
-
- default:
- break;
- }
-
- return (ret);
-}
diff --git a/stone_soup/crawl-ref/source/itemprop.h b/stone_soup/crawl-ref/source/itemprop.h
deleted file mode 100644
index aa565a8ddf..0000000000
--- a/stone_soup/crawl-ref/source/itemprop.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * File: itemname.cc
- * Summary: Misc functions.
- * Written by: Brent Ross
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- BWR Created
- */
-
-
-#ifndef ITEMPROP_H
-#define ITEMPROP_H
-
-#include "externs.h"
-
-void init_properties(void);
-
-// cursed:
-bool item_cursed( const item_def &item );
-bool item_known_cursed( const item_def &item );
-bool item_known_uncursed( const item_def &item );
-void do_curse_item( item_def &item );
-void do_uncurse_item( item_def &item );
-
-// ident:
-bool item_ident( const item_def &item, unsigned long flags );
-void set_ident_flags( item_def &item, unsigned long flags );
-void unset_ident_flags( item_def &item, unsigned long flags );
-
-// racial item and item descriptions:
-void set_equip_race( item_def &item, unsigned long flags );
-void set_equip_desc( item_def &item, unsigned long flags );
-unsigned long get_equip_race( const item_def &item );
-unsigned long get_equip_desc( const item_def &item );
-
-// helmet functions:
-void set_helmet_type( item_def &item, short flags );
-void set_helmet_desc( item_def &item, short flags );
-void set_helmet_random_desc( item_def &item );
-
-short get_helmet_type( const item_def &item );
-short get_helmet_desc( const item_def &item );
-
-bool is_helmet_type( const item_def &item, short val );
-
-// ego items:
-bool set_item_ego_type( item_def &item, int item_type, int ego_type );
-int get_weapon_brand( const item_def &item );
-int get_armour_ego_type( const item_def &item );
-int get_ammo_brand( const item_def &item );
-
-// armour functions:
-int armour_max_enchant( const item_def &item );
-bool armour_is_hide( const item_def &item, bool inc_made = false );
-bool armour_not_shiny( const item_def &item );
-int armour_str_required( const item_def &arm );
-
-equipment_type get_armour_slot( const item_def &item );
-
-bool jewellery_is_amulet( const item_def &item );
-bool check_jewellery_size( const item_def &item, size_type size );
-
-bool hide2armour( item_def &item );
-
-bool base_armour_is_light( const item_def &item );
-int fit_armour_size( const item_def &item, size_type size );
-bool check_armour_size( const item_def &item, size_type size );
-bool check_armour_shape( const item_def &item, bool quiet );
-
-// weapon functions:
-int weapon_rarity( int w_type );
-
-int cmp_weapon_size( const item_def &item, size_type size );
-bool check_weapon_tool_size( const item_def &item, size_type size );
-int fit_weapon_wieldable_size( const item_def &item, size_type size );
-bool check_weapon_wieldable_size( const item_def &item, size_type size );
-
-int fit_item_throwable_size( const item_def &item, size_type size );
-
-bool check_weapon_shape( const item_def &item, bool quiet, bool check_id = false );
-
-int weapon_ev_bonus( const item_def &wpn, int skill, size_type body, int dex,
- bool hide_hidden = false );
-
-int get_inv_wielded( void );
-int get_inv_hand_tool( void );
-int get_inv_in_hand( void );
-
-hands_reqd_type hands_reqd( const item_def &item, size_type size );
-bool is_double_ended( const item_def &item );
-
-int double_wpn_awkward_speed( const item_def &item );
-
-bool is_demonic( const item_def &item );
-
-int get_vorpal_type( const item_def &item );
-int get_damage_type( const item_def &item );
-bool does_damage_type( const item_def &item, int dam_type );
-
-int weapon_str_weight( const item_def &wpn );
-int weapon_dex_weight( const item_def &wpn );
-int weapon_impact_mass( const item_def &wpn );
-int weapon_str_required( const item_def &wpn, bool half );
-
-skill_type weapon_skill( const item_def &item );
-skill_type weapon_skill( int wclass, int wtype );
-
-skill_type range_skill( const item_def &item );
-skill_type range_skill( int wclass, int wtype );
-
-// launcher and ammo functions:
-bool is_range_weapon( const item_def &item );
-bool is_range_weapon_type( weapon_type wtype );
-missile_type fires_ammo_type( const item_def &item );
-const char * ammo_name( const item_def &bow );
-bool is_throwable( const item_def &wpn );
-launch_retval is_launched( int being_id, const item_def &ammo, bool msg = false );
-
-// staff/rod functions:
-bool item_is_rod( const item_def &item );
-bool item_is_staff( const item_def &item );
-
-// ring functions:
-int ring_has_pluses( const item_def &item );
-
-// food functions:
-bool food_is_meat( const item_def &item );
-bool food_is_veg( const item_def &item );
-int food_value( const item_def &item );
-int food_turns( const item_def &item );
-bool can_cut_meat( const item_def &item );
-
-// generic item property functions:
-bool is_tool( const item_def &item );
-int property( const item_def &item, int prop_type );
-int item_mass( const item_def &item );
-size_type item_size( const item_def &item );
-
-bool is_colourful_item( const item_def &item );
-
-#endif
diff --git a/stone_soup/crawl-ref/source/items.cc b/stone_soup/crawl-ref/source/items.cc
deleted file mode 100644
index 7c7a822343..0000000000
--- a/stone_soup/crawl-ref/source/items.cc
+++ /dev/null
@@ -1,3070 +0,0 @@
-/*
- * File: items.cc
- * Summary: Misc (mostly) inventory related functions.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <9> 7/08/01 MV Added messages for chunks/corpses rotting
- * <8> 8/07/99 BWR Added Rune stacking
- * <7> 6/13/99 BWR Added auto staff detection
- * <6> 6/12/99 BWR Fixed time system.
- * <5> 6/9/99 DML Autopickup
- * <4> 5/26/99 JDJ Drop will attempt to take off armour.
- * <3> 5/21/99 BWR Upped armour skill learning slightly.
- * <2> 5/20/99 BWR Added assurance that against inventory count being wrong.
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "items.h"
-#include "clua.h"
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <ctype.h>
-
-#ifdef DOS
-#include <conio.h>
-#endif
-
-#include "externs.h"
-
-#include "beam.h"
-#include "cloud.h"
-#include "debug.h"
-#include "delay.h"
-#include "effects.h"
-#include "invent.h"
-#include "it_use2.h"
-#include "item_use.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "misc.h"
-#include "monplace.h"
-#include "monstuff.h"
-#include "mstuff2.h"
-#include "mon-util.h"
-#include "mutation.h"
-#include "player.h"
-#include "randart.h"
-#include "religion.h"
-#include "shopping.h"
-#include "skills.h"
-#include "spl-cast.h"
-#include "stuff.h"
-#include "stash.h"
-
-static void autopickup(void);
-static bool is_stackable_item( const item_def &item );
-
-// Used to be called "unlink_items", but all it really does is make
-// sure item coordinates are correct to the stack they're in. -- bwr
-void fix_item_coordinates(void)
-{
- int x,y,i;
-
- // nails all items to the ground (i.e. sets x,y)
- for (x = 0; x < GXM; x++)
- {
- for (y = 0; y < GYM; y++)
- {
- i = igrd[x][y];
-
- while (i != NON_ITEM)
- {
- mitm[i].x = x;
- mitm[i].y = y;
- i = mitm[i].link;
- }
- }
- }
-}
-
-// This function uses the items coordinates to relink all the igrd lists.
-void link_items(void)
-{
- int i,j;
-
- // first, initailize igrd array
- for (i = 0; i < GXM; i++)
- {
- for (j = 0; j < GYM; j++)
- igrd[i][j] = NON_ITEM;
- }
-
- // link all items on the grid, plus shop inventory,
- // DON'T link the huge pile of monster items at (0,0)
-
- for (i = 0; i < MAX_ITEMS; i++)
- {
- if (!is_valid_item(mitm[i]) || (mitm[i].x == 0 && mitm[i].y == 0))
- {
- // item is not assigned, or is monster item. ignore.
- mitm[i].link = NON_ITEM;
- continue;
- }
-
- // link to top
- mitm[i].link = igrd[ mitm[i].x ][ mitm[i].y ];
- igrd[ mitm[i].x ][ mitm[i].y ] = i;
- }
-} // end link_items()
-
-static bool item_ok_to_clean(int item)
-{
- // 5. never clean food or Orbs
- if (mitm[item].base_type == OBJ_FOOD || mitm[item].base_type == OBJ_ORBS)
- return false;
-
- // never clean runes
- if (mitm[item].base_type == OBJ_MISCELLANY
- && mitm[item].sub_type == MISC_RUNE_OF_ZOT)
- {
- return false;
- }
-
- return true;
-}
-
-// returns index number of first available space, or NON_ITEM for
-// unsuccessful cleanup (should be exceedingly rare!)
-int cull_items(void)
-{
- // XXX: Not the prettiest of messages, but the player
- // deserves to know whenever this kicks in. -- bwr
- mpr( "Too many items on level, removing some.", MSGCH_WARN );
-
- /* rules:
- 1. Don't cleanup anything nearby the player
- 2. Don't cleanup shops
- 3. Don't cleanup monster inventory
- 4. Clean 15% of items
- 5. never remove food, orbs, runes
- 7. uniques weapons are moved to the abyss
- 8. randarts are simply lost
- 9. unrandarts are 'destroyed', but may be generated again
- */
-
- int x,y, item, next;
- int first_cleaned = NON_ITEM;
-
- // 2. avoid shops by avoiding (0,5..9)
- // 3. avoid monster inventory by iterating over the dungeon grid
- for (x = 5; x < GXM; x++)
- {
- for (y = 5; y < GYM; y++)
- {
- // 1. not near player!
- if (x > you.x_pos - 9 && x < you.x_pos + 9
- && y > you.y_pos - 9 && y < you.y_pos + 9)
- {
- continue;
- }
-
- // iterate through the grids list of items:
- for (item = igrd[x][y]; item != NON_ITEM; item = next)
- {
- next = mitm[item].link; // in case we can't get it later.
-
- if (item_ok_to_clean(item) && random2(100) < 15)
- {
- if (is_fixed_artefact( mitm[item] ))
- {
- // 7. move uniques to abyss
- set_unique_item_status( OBJ_WEAPONS, mitm[item].special,
- UNIQ_LOST_IN_ABYSS );
- }
- else if (is_unrandom_artefact( mitm[item] ))
- {
- // 9. unmark unrandart
- int x = find_unrandart_index(item);
- if (x >= 0)
- set_unrandart_exist(x, 0);
- }
-
- // POOF!
- destroy_item( item );
- if (first_cleaned == NON_ITEM)
- first_cleaned = item;
- }
- } // end for item
-
- } // end y
- } // end x
-
- return (first_cleaned);
-}
-
-// Note: This function is to isolate all the checks to see if
-// an item is valid (often just checking the quantity).
-//
-// It shouldn't be used a a substitute for those cases
-// which actually want to check the quantity (as the
-// rules for unused objects might change).
-bool is_valid_item( const item_def &item )
-{
- return (item.base_type != OBJ_UNASSIGNED && item.quantity > 0);
-}
-
-// Reduce quantity of an inventory item, do cleanup if item goes away.
-//
-// Returns true if stack of items no longer exists.
-bool dec_inv_item_quantity( int obj, int amount )
-{
- bool ret = false;
-
- if (you.equip[EQ_WEAPON] == obj)
- you.wield_change = true;
-
- if (you.inv[obj].quantity <= amount)
- {
- for (int i = 0; i < NUM_EQUIP; i++)
- {
- if (you.equip[i] == obj)
- {
- you.equip[i] = -1;
- if (i == EQ_WEAPON)
- {
- unwield_item( obj );
- canned_msg( MSG_EMPTY_HANDED );
- }
- }
- }
-
- you.inv[obj].base_type = OBJ_UNASSIGNED;
- you.inv[obj].quantity = 0;
-
- ret = true;
- }
- else
- {
- you.inv[obj].quantity -= amount;
- }
-
- burden_change();
-
- return (ret);
-}
-
-// Reduce quantity of a monster/grid item, do cleanup if item goes away.
-//
-// Returns true if stack of items no longer exists.
-bool dec_mitm_item_quantity( int obj, int amount )
-{
- if (mitm[obj].quantity <= amount)
- {
- destroy_item( obj );
- return (true);
- }
-
- mitm[obj].quantity -= amount;
-
- return (false);
-}
-
-void inc_inv_item_quantity( int obj, int amount )
-{
- if (you.equip[EQ_WEAPON] == obj)
- you.wield_change = true;
-
- you.inv[obj].quantity += amount;
- burden_change();
-}
-
-void inc_mitm_item_quantity( int obj, int amount )
-{
- mitm[obj].quantity += amount;
-}
-
-void init_item( int item )
-{
- if (item == NON_ITEM)
- return;
-
- mitm[item].base_type = OBJ_UNASSIGNED;
- mitm[item].sub_type = 0;
- mitm[item].plus = 0;
- mitm[item].plus2 = 0;
- mitm[item].special = 0;
- mitm[item].quantity = 0;
- mitm[item].colour = 0;
- mitm[item].flags = 0;
-
- mitm[item].x = 0;
- mitm[item].y = 0;
- mitm[item].link = NON_ITEM;
-}
-
-// Returns an unused mitm slot, or NON_ITEM if none available.
-// The reserve is the number of item slots to not check.
-// Items may be culled if a reserve <= 10 is specified.
-int get_item_slot( int reserve )
-{
- ASSERT( reserve >= 0 );
-
- int item = NON_ITEM;
-
- for (item = 0; item < (MAX_ITEMS - reserve); item++)
- {
- if (!is_valid_item( mitm[item] ))
- break;
- }
-
- if (item >= MAX_ITEMS - reserve)
- {
- item = (reserve <= 10) ? cull_items() : NON_ITEM;
-
- if (item == NON_ITEM)
- return (NON_ITEM);
- }
-
- ASSERT( item != NON_ITEM );
-
- init_item( item );
-
- return (item);
-}
-
-void unlink_item( int dest )
-{
- int c = 0;
- int cy = 0;
-
- // Don't destroy non-items, may be called after an item has been
- // reduced to zero quantity however.
- if (dest == NON_ITEM || !is_valid_item( mitm[dest] ))
- return;
-
- if (mitm[dest].x == 0 && mitm[dest].y == 0)
- {
- // (0,0) is where the monster items are (and they're unlinked by igrd),
- // although it also contains items that are not linked in yet.
- //
- // Check if a monster has it:
- for (c = 0; c < MAX_MONSTERS; c++)
- {
- struct monsters *monster = &menv[c];
-
- if (monster->type == -1)
- continue;
-
- for (cy = 0; cy < NUM_MONSTER_SLOTS; cy++)
- {
- if (monster->inv[cy] == dest)
- {
- monster->inv[cy] = NON_ITEM;
-
- mitm[dest].x = 0;
- mitm[dest].y = 0;
- mitm[dest].link = NON_ITEM;
-
- // This causes problems when changing levels. -- bwr
- // if (monster->type == MONS_DANCING_WEAPON)
- // monster_die(monster, KILL_RESET, 0);
- return;
- }
- }
- }
-
- // Always return because this item might just be temporary.
- return;
- }
- else
- {
- // Linked item on map:
- //
- // Use the items (x,y) to access the list (igrd[x][y]) where
- // the item should be linked.
-
- // First check the top:
- if (igrd[ mitm[dest].x ][ mitm[dest].y ] == dest)
- {
- // link igrd to the second item
- igrd[ mitm[dest].x ][ mitm[dest].y ] = mitm[dest].link;
-
- mitm[dest].x = 0;
- mitm[dest].y = 0;
- mitm[dest].link = NON_ITEM;
- return;
- }
-
- // Okay, item is buried, find item that's on top of it:
- for (c = igrd[ mitm[dest].x ][ mitm[dest].y ]; c != NON_ITEM; c = mitm[c].link)
- {
- // find item linking to dest item
- if (is_valid_item( mitm[c] ) && mitm[c].link == dest)
- {
- // unlink dest
- mitm[c].link = mitm[dest].link;
-
- mitm[dest].x = 0;
- mitm[dest].y = 0;
- mitm[dest].link = NON_ITEM;
- return;
- }
- }
- }
-
-#if DEBUG
- // Okay, the sane ways are gone... let's warn the player:
- mpr( "BUG WARNING: Problems unlinking item!!!", MSGCH_DANGER );
-
- // Okay, first we scan all items to see if we have something
- // linked to this item. We're not going to return if we find
- // such a case... instead, since things are already out of
- // alignment, let's assume there might be multiple links as well.
- bool linked = false;
- int old_link = mitm[dest].link; // used to try linking the first
-
- // clean the relevant parts of the object:
- mitm[dest].base_type = OBJ_UNASSIGNED;
- mitm[dest].quantity = 0;
- mitm[dest].x = 0;
- mitm[dest].y = 0;
- mitm[dest].link = NON_ITEM;
-
- // Look through all items for links to this item.
- for (c = 0; c < MAX_ITEMS; c++)
- {
- if (is_valid_item( mitm[c] ) && mitm[c].link == dest)
- {
- // unlink item
- mitm[c].link = old_link;
-
- if (!linked)
- {
- old_link = NON_ITEM;
- linked = true;
- }
- }
- }
-
- // Now check the grids to see if it's linked as a list top.
- for (c = 2; c < (GXM - 1); c++)
- {
- for (cy = 2; cy < (GYM - 1); cy++)
- {
- if (igrd[c][cy] == dest)
- {
- igrd[c][cy] = old_link;
-
- if (!linked)
- {
- old_link = NON_ITEM; // cleaned after the first
- linked = true;
- }
- }
- }
- }
-
-
- // Okay, finally warn player if we didn't do anything.
- if (!linked)
- mpr("BUG WARNING: Item didn't seem to be linked at all.", MSGCH_DANGER);
-#endif
-} // end unlink_item()
-
-static void item_cleanup(item_def &item)
-{
- item.base_type = OBJ_UNASSIGNED;
- item.quantity = 0;
- item.orig_place = 0;
- item.orig_monnum = 0;
-}
-
-void destroy_item( int dest )
-{
- // Don't destroy non-items, but this function may be called upon
- // to remove items reduced to zero quantity, so we allow "invalid"
- // objects in.
- if (dest == NON_ITEM || !is_valid_item( mitm[dest] ))
- return;
-
- unlink_item( dest );
-
- item_cleanup(mitm[dest]);
-}
-
-void destroy_item_stack( int x, int y )
-{
- int o = igrd[x][y];
-
- igrd[x][y] = NON_ITEM;
-
- while (o != NON_ITEM)
- {
- int next = mitm[o].link;
-
- if (is_valid_item( mitm[o] ))
- {
- if (mitm[o].base_type == OBJ_ORBS)
- {
- set_unique_item_status( OBJ_ORBS, mitm[o].sub_type,
- UNIQ_LOST_IN_ABYSS );
- }
- else if (is_fixed_artefact( mitm[o] ))
- {
- set_unique_item_status( OBJ_WEAPONS, mitm[o].special,
- UNIQ_LOST_IN_ABYSS );
- }
-
- mitm[o].base_type = OBJ_UNASSIGNED;
- mitm[o].quantity = 0;
- }
-
- o = next;
- }
-}
-
-
-/*
- * Takes keyin as an argument because it will only display a long list of items
- * if ; is pressed.
- */
-void item_check(char keyin)
-{
- char item_show[50][50];
- char temp_quant[10];
-
- int counter = 0;
- int counter_max = 0;
-
- const int grid = grd[you.x_pos][you.y_pos];
-
- if (grid >= DNGN_ENTER_HELL && grid <= DNGN_PERMADRY_FOUNTAIN)
- {
- if (grid >= DNGN_STONE_STAIRS_DOWN_I && grid <= DNGN_ROCK_STAIRS_DOWN)
- {
- snprintf( info, INFO_SIZE, "There is a %s staircase leading down here.",
- (grid == DNGN_ROCK_STAIRS_DOWN) ? "rock" : "stone" );
-
- mpr(info);
- }
- else if (grid >= DNGN_STONE_STAIRS_UP_I && grid <= DNGN_ROCK_STAIRS_UP)
- {
- snprintf( info, INFO_SIZE, "There is a %s staircase leading upwards here.",
- (grid == DNGN_ROCK_STAIRS_UP) ? "rock" : "stone" );
-
- mpr(info);
- }
- else
- {
- switch (grid)
- {
- case DNGN_ENTER_HELL:
- mpr("There is a gateway to Hell here.");
- break;
- case DNGN_ENTER_GEHENNA:
- mpr("There is a gateway to Gehenna here.");
- break;
- case DNGN_ENTER_COCYTUS:
- mpr("There is a gateway to the frozen wastes of Cocytus here.");
- break;
- case DNGN_ENTER_TARTARUS:
- mpr("There is a gateway to Tartarus here.");
- break;
- case DNGN_ENTER_DIS:
- mpr("There is a gateway to the Iron City of Dis here.");
- break;
- case DNGN_ENTER_SHOP:
- snprintf( info, INFO_SIZE, "There is an entrance to %s here.", shop_name(you.x_pos, you.y_pos));
- mpr(info);
- break;
- case DNGN_ENTER_LABYRINTH:
- mpr("There is an entrance to a labyrinth here.");
- mpr("Beware, for starvation awaits!");
- break;
- case DNGN_ENTER_ABYSS:
- mpr("There is a one-way gate to the infinite horrors of the Abyss here.");
- break;
- case DNGN_STONE_ARCH:
- mpr("There is an empty stone archway here.");
- break;
- case DNGN_EXIT_ABYSS:
- mpr("There is a gateway leading out of the Abyss here.");
- break;
- case DNGN_ENTER_PANDEMONIUM:
- mpr("There is a gate leading to the halls of Pandemonium here.");
- break;
- case DNGN_EXIT_PANDEMONIUM:
- mpr("There is a gate leading out of Pandemonium here.");
- break;
- case DNGN_TRANSIT_PANDEMONIUM:
- mpr("There is a gate leading to another region of Pandemonium here.");
- break;
- case DNGN_ENTER_ORCISH_MINES:
- mpr("There is a staircase to the Orcish Mines here.");
- break;
- case DNGN_ENTER_HIVE:
- mpr("There is a staircase to the Hive here.");
- break;
- case DNGN_ENTER_LAIR:
- mpr("There is a staircase to the Lair here.");
- break;
- case DNGN_ENTER_SLIME_PITS:
- mpr("There is a staircase to the Slime Pits here.");
- break;
- case DNGN_ENTER_VAULTS:
- mpr("There is a staircase to the Vaults here.");
- break;
- case DNGN_ENTER_CRYPT:
- mpr("There is a staircase to the Crypt here.");
- break;
- case DNGN_ENTER_HALL_OF_BLADES:
- mpr("There is a staircase to the Hall of Blades here.");
- break;
- case DNGN_ENTER_ZOT:
- mpr("There is a gate to the Realm of Zot here.");
- break;
- case DNGN_ENTER_TEMPLE:
- mpr("There is a staircase to the Ecumenical Temple here.");
- break;
- case DNGN_ENTER_SNAKE_PIT:
- mpr("There is a staircase to the Snake Pit here.");
- break;
- case DNGN_ENTER_ELVEN_HALLS:
- mpr("There is a staircase to the Elven Halls here.");
- break;
- case DNGN_ENTER_TOMB:
- mpr("There is a staircase to the Tomb here.");
- break;
- case DNGN_ENTER_SWAMP:
- mpr("There is a staircase to the Swamp here.");
- break;
- case DNGN_RETURN_FROM_ORCISH_MINES:
- case DNGN_RETURN_FROM_HIVE:
- case DNGN_RETURN_FROM_LAIR:
- case DNGN_RETURN_FROM_VAULTS:
- case DNGN_RETURN_FROM_TEMPLE:
- mpr("There is a staircase back to the Dungeon here.");
- break;
- case DNGN_RETURN_FROM_SLIME_PITS:
- case DNGN_RETURN_FROM_SNAKE_PIT:
- case DNGN_RETURN_FROM_SWAMP:
- mpr("There is a staircase back to the Lair here.");
- break;
- case DNGN_RETURN_FROM_CRYPT:
- case DNGN_RETURN_FROM_HALL_OF_BLADES:
- mpr("There is a staircase back to the Vaults here.");
- break;
- case DNGN_RETURN_FROM_TOMB:
- mpr("There is a staircase back to the Crypt here.");
- break;
- case DNGN_RETURN_FROM_ELVEN_HALLS:
- mpr("There is a staircase back to the Mines here.");
- break;
- case DNGN_RETURN_FROM_ZOT:
- mpr("There is a gate leading back out of this place here.");
- break;
- case DNGN_ALTAR_ZIN:
- mpr("There is a glowing white marble altar of Zin here.");
- break;
- case DNGN_ALTAR_SHINING_ONE:
- mpr("There is a glowing golden altar of the Shining One here.");
- break;
- case DNGN_ALTAR_KIKUBAAQUDGHA:
- mpr("There is an ancient bone altar of Kikubaaqudgha here.");
- break;
- case DNGN_ALTAR_YREDELEMNUL:
- mpr("There is a basalt altar of Yredelemnul here.");
- break;
- case DNGN_ALTAR_XOM:
- mpr("There is a shimmering altar of Xom here.");
- break;
- case DNGN_ALTAR_VEHUMET:
- mpr("There is a shining altar of Vehumet here.");
- break;
- case DNGN_ALTAR_OKAWARU:
- mpr("There is an iron altar of Okawaru here.");
- break;
- case DNGN_ALTAR_MAKHLEB:
- mpr("There is a burning altar of Makhleb here.");
- break;
- case DNGN_ALTAR_SIF_MUNA:
- mpr("There is a deep blue altar of Sif Muna here.");
- break;
- case DNGN_ALTAR_TROG:
- mpr("There is a bloodstained altar of Trog here.");
- break;
- case DNGN_ALTAR_NEMELEX_XOBEH:
- mpr("There is a sparkling altar of Nemelex Xobeh here.");
- break;
- case DNGN_ALTAR_ELYVILON:
- mpr("There is a silver altar of Elyvilon here.");
- break;
- case DNGN_BLUE_FOUNTAIN:
- mpr("There is a fountain here (q to drink).");
- break;
- case DNGN_SPARKLING_FOUNTAIN:
- mpr("There is a sparkling fountain here (q to drink).");
- break;
- case DNGN_DRY_FOUNTAIN_I:
- case DNGN_DRY_FOUNTAIN_II:
- case DNGN_DRY_FOUNTAIN_IV:
- case DNGN_DRY_FOUNTAIN_VI:
- case DNGN_DRY_FOUNTAIN_VIII:
- case DNGN_PERMADRY_FOUNTAIN:
- mpr("There is a dry fountain here.");
- break;
- }
- }
- }
-
- if (igrd[you.x_pos][you.y_pos] == NON_ITEM && keyin == ';')
- {
- mpr("There are no items here.");
- return;
- }
-
- autopickup();
-
- origin_set(you.x_pos, you.y_pos);
-
- int objl = igrd[you.x_pos][you.y_pos];
-
- while (objl != NON_ITEM)
- {
- counter++;
-
- if (counter > 45)
- {
- strcpy(item_show[counter], "Too many items.");
- break;
- }
-
- if (mitm[objl].base_type == OBJ_GOLD)
- {
- itoa(mitm[objl].quantity, temp_quant, 10);
- strcpy(item_show[counter], temp_quant);
- strcat(item_show[counter], " gold piece");
- if (mitm[objl].quantity > 1)
- strcat(item_show[counter], "s");
-
- }
- else
- {
- char str_pass[ ITEMNAME_SIZE ];
- it_name(objl, DESC_NOCAP_A, str_pass);
- strcpy(item_show[counter], str_pass);
- }
-
- objl = mitm[objl].link;
- }
-
- counter_max = counter;
- counter = 0;
-
- if (counter_max == 1)
- {
- strcpy(info, "You see here "); // remember 'an'.
-
- strcat(info, item_show[counter_max]);
- strcat(info, ".");
- mpr(info);
-
- counter++;
- counter_max = 0; // to skip next part.
-
- }
-
- if ((counter_max > 0 && counter_max < 6)
- || (counter_max > 1 && keyin == ';'))
- {
- mpr("Things that are here:");
-
- while (counter < counter_max)
- {
- // this is before the strcpy because item_show start at 1, not 0.
- counter++;
- mpr(item_show[counter]);
- }
- }
-
- if (counter_max > 5 && keyin != ';')
- mpr("There are several objects here.");
-}
-
-
-void pickup_menu(int item_link)
-{
- std::vector<item_def*> items;
-
- for (int i = item_link; i != NON_ITEM; i = mitm[i].link)
- items.push_back( &mitm[i] );
-
- std::vector<SelItem> selected =
- select_items( items, "Select items to pick up" );
- redraw_screen();
-
- for (int i = 0, count = selected.size(); i < count; ++i) {
- for (int j = item_link; j != NON_ITEM; j = mitm[j].link) {
- if (&mitm[j] == selected[i].item) {
- if (j == item_link)
- item_link = mitm[j].link;
-
- unsigned long oldflags = mitm[j].flags;
- mitm[j].flags &= ~(ISFLAG_THROWN | ISFLAG_DROPPED);
- int result = move_item_to_player( j, selected[i].quantity );
-
- // If we cleared any flags on the items, but the pickup was
- // partial, reset the flags for the items that remain on the
- // floor.
- if (is_valid_item(mitm[j]))
- mitm[j].flags = oldflags;
-
- if (result == 0)
- {
- mpr("You can't carry that much weight.");
- return;
- }
- else if (result == -1)
- {
- mpr("You can't carry that many items.");
- return;
- }
- break;
- }
- }
- }
-}
-
-bool origin_known(const item_def &item)
-{
- return (item.orig_place != 0);
-}
-
-// We have no idea where the player found this item.
-void origin_set_unknown(item_def &item)
-{
- if (!origin_known(item))
- {
- item.orig_place = 0xFFFF;
- item.orig_monnum = 0;
- }
-}
-
-// This item is starting equipment.
-void origin_set_startequip(item_def &item)
-{
- if (!origin_known(item))
- {
- item.orig_place = 0xFFFF;
- item.orig_monnum = -1;
- }
-}
-
-void origin_set_monster(item_def &item, const monsters *monster)
-{
- if (!origin_known(item))
- {
- if (!item.orig_monnum)
- item.orig_monnum = monster->type + 1;
- item.orig_place = get_packed_place();
- }
-}
-
-void origin_purchased(item_def &item)
-{
- // We don't need to check origin_known if it's a shop purchase
- item.orig_place = get_packed_place();
- // Hackiness
- item.orig_monnum = -1;
-}
-
-void origin_acquired(item_def &item, int agent)
-{
- // We don't need to check origin_known if it's a divine gift
- item.orig_place = get_packed_place();
- // Hackiness
- item.orig_monnum = -2 - agent;
-}
-
-void origin_set_inventory(void (*oset)(item_def &item))
-{
- for (int i = 0; i < ENDOFPACK; ++i)
- {
- if (is_valid_item(you.inv[i]))
- oset(you.inv[i]);
- }
-}
-
-static int first_corpse_monnum(int x, int y)
-{
- // We could look for a corpse on this square and assume that the
- // items belonged to it, but that is unsatisfactory.
- return (0);
-}
-
-void origin_set(int x, int y)
-{
- int monnum = first_corpse_monnum(x, y);
- unsigned short pplace = get_packed_place();
- for (int link = igrd[x][y]; link != NON_ITEM; link = mitm[link].link)
- {
- item_def &item = mitm[link];
- if (origin_known(item))
- continue;
- if (!item.orig_monnum)
- item.orig_monnum = static_cast<short>( monnum );
- item.orig_place = pplace;
- }
-}
-
-void origin_set_monstercorpse(item_def &item, int x, int y)
-{
- item.orig_monnum = first_corpse_monnum(x, y);
-}
-
-void origin_freeze(item_def &item, int x, int y)
-{
- if (!origin_known(item))
- {
- if (!item.orig_monnum && x != -1 && y != -1)
- origin_set_monstercorpse(item, x, y);
- item.orig_place = get_packed_place();
- }
-}
-
-static std::string origin_monster_name(const item_def &item)
-{
- const int monnum = item.orig_monnum - 1;
- if (monnum == MONS_PLAYER_GHOST)
- return ("a player ghost");
- else if (monnum == MONS_PANDEMONIUM_DEMON)
- return ("a demon");
- char monnamebuf[ITEMNAME_SIZE]; // Le sigh.
- moname(monnum, true, DESC_NOCAP_A, monnamebuf);
- return (monnamebuf);
-}
-
-static std::string origin_monster_desc(const item_def &item)
-{
- return (origin_monster_name(item));
-}
-
-static std::string origin_place_desc(const item_def &item)
-{
- std::string place = branch_level_name(item.orig_place);
- if (place.length() && place != "Pandemonium")
- place[0] = tolower(place[0]);
- return (place.find("level") == 0?
- "on " + place
- : "in " + place);
-}
-
-bool is_rune(const item_def &item)
-{
- return (item.base_type == OBJ_MISCELLANY &&
- item.sub_type == MISC_RUNE_OF_ZOT);
-}
-
-bool origin_describable(const item_def &item)
-{
- return (origin_known(item)
- && (item.orig_place != 0xFFFFU || item.orig_monnum == -1)
- && (!is_stackable_item(item) || is_rune(item))
- && item.quantity == 1
- && item.base_type != OBJ_CORPSES
- && (item.base_type != OBJ_FOOD || item.sub_type != FOOD_CHUNK)
- // Portable altars cannot be tracked meaningfully with Crawl's
- // current handling for portable altars.
- && (item.base_type != OBJ_MISCELLANY ||
- item.sub_type != MISC_PORTABLE_ALTAR_OF_NEMELEX));
-}
-
-std::string article_it(const item_def &item)
-{
- /*
- bool them = false;
- if (item.quantity > 1)
- them = true;
- else if (item.base_type == OBJ_ARMOUR &&
- item.sub_type == ARM_BOOTS)
- {
- if (item.plus2 != TBOOT_NAGA_BARDING &&
- item.plus2 != TBOOT_CENTAUR_BARDING)
- them = true;
- }
- else if (item.base_type == OBJ_ARMOUR &&
- item.sub_type == ARM_GLOVES)
- {
- them = true;
- }
-
- return them? "them" : "it";
- */
- // "it" is always correct, since gloves and boots also come in pairs.
- return "it";
-}
-
-bool origin_is_original_equip(const item_def &item)
-{
- return (item.orig_place == 0xFFFFU && item.orig_monnum == -1);
-}
-
-std::string origin_desc(const item_def &item)
-{
- if (!origin_describable(item))
- return ("");
-
- if (origin_is_original_equip(item))
- return "Original Equipment";
-
- std::string desc;
- if (item.orig_monnum)
- {
- if (item.orig_monnum < 0)
- {
- int iorig = -item.orig_monnum - 2;
- switch (iorig)
- {
- case -1:
- desc += "You bought " + article_it(item) + " in a shop ";
- break;
- case AQ_SCROLL:
- desc += "You acquired " + article_it(item) + " ";
- break;
- case AQ_CARD_ACQUISITION:
- desc += "You drew \"Acquisition\" ";
- break;
- case AQ_CARD_VIOLENCE:
- desc += "You drew \"Violence\" ";
- break;
- case AQ_CARD_PROTECTION:
- desc += "You drew \"Protection\" ";
- break;
- case AQ_CARD_KNOWLEDGE:
- desc += "You drew \"Knowledge\" ";
- break;
- case AQ_WIZMODE:
- desc += "Your wizardly powers created "
- + article_it(item) + " ";
- break;
- default:
- if (iorig > GOD_NO_GOD && iorig < NUM_GODS)
- desc += std::string(god_name(iorig))
- + " gifted " + article_it(item) + " to you ";
- else
- // Bug really.
- desc += "You stumbled upon " + article_it(item) + " ";
- break;
- }
- }
- else if (item.orig_monnum - 1 == MONS_DANCING_WEAPON)
- desc += "You subdued it ";
- else
- desc += "You took " + article_it(item) + " off "
- + origin_monster_desc(item) + " ";
- }
- else
- desc += "You found " + article_it(item) + " ";
- desc += origin_place_desc(item);
- return (desc);
-}
-
-bool pickup_single_item(int link, int qty)
-{
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_AIR
- && you.duration[DUR_TRANSFORMATION] > 0)
- {
- mpr("You can't pick up anything in this form!");
- return (false);
- }
-
- if (player_is_levitating() && !wearing_amulet(AMU_CONTROLLED_FLIGHT))
- {
- mpr("You can't reach the floor from up here.");
- return (false);
- }
-
- if (qty < 1 || qty > mitm[link].quantity)
- qty = mitm[link].quantity;
-
- unsigned long oldflags = mitm[link].flags;
- mitm[link].flags &= ~(ISFLAG_THROWN | ISFLAG_DROPPED);
- int num = move_item_to_player( link, qty );
- if (is_valid_item(mitm[link]))
- mitm[link].flags = oldflags;
-
- if (num == -1)
- {
- mpr("You can't carry that many items.");
- return (false);
- }
- else if (num == 0)
- {
- mpr("You can't carry that much weight.");
- return (false);
- }
-
- return (true);
-}
-
-void pickup(void)
-{
- int o = 0;
- int m = 0;
- unsigned char keyin = 0;
- int next;
- char str_pass[ ITEMNAME_SIZE ];
-
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_AIR
- && you.duration[DUR_TRANSFORMATION] > 0)
- {
- mpr("You can't pick up anything in this form!");
- return;
- }
-
- if (player_is_levitating() && !wearing_amulet(AMU_CONTROLLED_FLIGHT))
- {
- mpr("You can't reach the floor from up here.");
- return;
- }
-
- // Fortunately, the player is prevented from testing their
- // portable altar in the Ecumenical Temple. -- bwr
- if (grd[you.x_pos][you.y_pos] == DNGN_ALTAR_NEMELEX_XOBEH
- && !player_in_branch( BRANCH_ECUMENICAL_TEMPLE ))
- {
- if (inv_count() >= ENDOFPACK)
- {
- mpr("There is a portable altar here, but you can't carry anything else.");
- return;
- }
-
- if (yesno("There is a portable altar here. Pick it up?"))
- {
- for (m = 0; m < ENDOFPACK; m++)
- {
- if (!is_valid_item( you.inv[m] ))
- {
- you.inv[m].base_type = OBJ_MISCELLANY;
- you.inv[m].sub_type = MISC_PORTABLE_ALTAR_OF_NEMELEX;
- you.inv[m].plus = 0;
- you.inv[m].plus2 = 0;
- you.inv[m].special = 0;
- you.inv[m].colour = LIGHTMAGENTA;
- you.inv[m].quantity = 1;
- set_ident_flags( you.inv[m], ISFLAG_IDENT_MASK );
-
- you.inv[m].x = -1;
- you.inv[m].y = -1;
- you.inv[m].link = m;
-
- burden_change();
-
- in_name( m, DESC_INVENTORY_EQUIP, str_pass );
- strcpy( info, str_pass );
- mpr( info );
- break;
- }
- }
-
- grd[you.x_pos][you.y_pos] = DNGN_FLOOR;
- }
- }
-
- o = igrd[you.x_pos][you.y_pos];
-
- if (o == NON_ITEM)
- {
- mpr("There are no items here.");
- }
- else if (mitm[o].link == NON_ITEM) // just one item?
- {
- pickup_single_item(o, mitm[o].quantity);
- } // end of if items_here
- else
- {
- mpr("There are several objects here.");
-
- while (o != NON_ITEM)
- {
- next = mitm[o].link;
-
- if (keyin != 'a')
- {
- strcpy(info, "Pick up ");
-
- if (mitm[o].base_type == OBJ_GOLD)
- {
- char st_prn[20];
- itoa(mitm[o].quantity, st_prn, 10);
- strcat(info, st_prn);
- strcat(info, " gold piece");
-
- if (mitm[o].quantity > 1)
- strcat(info, "s");
- }
- else
- {
- it_name(o, DESC_NOCAP_A, str_pass);
- strcat(info, str_pass);
- }
-
- strcat(info, "\? (y,n,a,*,q)");
- mpr( info, MSGCH_PROMPT );
-
- keyin = get_ch();
- }
-
- if (keyin == '*' || keyin == '?' || keyin == ',')
- {
- pickup_menu(o);
- break;
- }
-
- if (keyin == 'q')
- break;
-
- if (keyin == 'y' || keyin == 'a')
- {
- mitm[o].flags &= ~(ISFLAG_THROWN | ISFLAG_DROPPED);
- int result = move_item_to_player( o, mitm[o].quantity );
-
- if (result == 0)
- {
- mpr("You can't carry that much weight.");
- keyin = 'x'; // resets from 'a'
- }
- else if (result == -1)
- {
- mpr("You can't carry that many items.");
- break;
- }
- }
-
- o = next;
- }
- }
-} // end pickup()
-
-static bool is_stackable_item( const item_def &item )
-{
- if (!is_valid_item( item ))
- return (false);
-
- if (item.base_type == OBJ_MISSILES
- || (item.base_type == OBJ_FOOD && item.sub_type != FOOD_CHUNK)
- || item.base_type == OBJ_SCROLLS
- || item.base_type == OBJ_POTIONS
- || item.base_type == OBJ_UNKNOWN_II
- || (item.base_type == OBJ_MISCELLANY
- && item.sub_type == MISC_RUNE_OF_ZOT))
- {
- return (true);
- }
-
- return (false);
-}
-
-bool items_stack( const item_def &item1, const item_def &item2 )
-{
- // both items must be stackable
- if (!is_stackable_item( item1 ) || !is_stackable_item( item2 ))
- return (false);
-
- // base and sub-types must always be the same to stack
- if (item1.base_type != item2.base_type || item1.sub_type != item2.sub_type)
- return (false);
-
- // These classes also require pluses and special
- if (item1.base_type == OBJ_MISSILES
- || item1.base_type == OBJ_MISCELLANY) // only runes
- {
- if (item1.plus != item2.plus
- || item1.plus2 != item2.plus2
- || item1.special != item2.special)
- {
- return (false);
- }
- }
-
- // Check the flags, food/scrolls/potions don't care about the item's
- // ident status (scrolls and potions are known by identifying any
- // one of them, the individual status might not be the same).
- if (item1.base_type == OBJ_FOOD
- || item1.base_type == OBJ_SCROLLS
- || item1.base_type == OBJ_POTIONS)
- {
- if ((item1.flags & ~ISFLAG_IDENT_MASK)
- != (item2.flags & ~ISFLAG_IDENT_MASK))
- {
- return (false);
- }
-
- // Thanks to mummy cursing, we can have potions of decay
- // that don't look alike... so we don't stack potions
- // if either isn't identified and they look different. -- bwr
- if (item1.base_type == OBJ_POTIONS
- && item1.special != item2.special
- && (!item_ident( item1, ISFLAG_KNOW_TYPE )
- || !item_ident( item2, ISFLAG_KNOW_TYPE )))
- {
- return (false);
- }
- }
- else if (item1.flags != item2.flags)
- {
- return (false);
- }
-
- return (true);
-}
-
-static int userdef_find_free_slot(const item_def &i)
-{
-#ifdef CLUA_BINDINGS
- int slot = -1;
- if (!clua.callfn("c_assign_invletter", "u>d", &i, &slot))
- return (-1);
- return (slot);
-#else
- return -1;
-#endif
-}
-
-int find_free_slot(const item_def &i)
-{
-#define slotisfree(s) \
- ((s) >= 0 && (s) < ENDOFPACK && !is_valid_item(you.inv[s]))
-
- bool searchforward = false;
- // If we're doing Lua, see if there's a Lua function that can give
- // us a free slot.
- int slot = userdef_find_free_slot(i);
- if (slot == -2 || Options.assign_item_slot == SS_FORWARD)
- searchforward = true;
-
- if (slotisfree(slot))
- return slot;
-
- // See if the item remembers where it's been. Lua code can play with
- // this field so be extra careful.
- if ((i.slot >= 'a' && i.slot <= 'z') ||
- (i.slot >= 'A' && i.slot <= 'Z'))
- slot = letter_to_index(i.slot);
-
- if (slotisfree(slot))
- return slot;
-
- if (searchforward)
- {
- // Return first free slot
- for (slot = 0; slot < ENDOFPACK; ++slot) {
- if (!is_valid_item(you.inv[slot]))
- return slot;
- }
- }
- else
- {
- // This is the new default free slot search. We look for the last
- // available slot that does not leave a gap in the inventory.
- bool accept_empty = false;
- for (slot = ENDOFPACK - 1; slot >= 0; --slot)
- {
- if (is_valid_item(you.inv[slot]))
- {
- if (!accept_empty && slot + 1 < ENDOFPACK &&
- !is_valid_item(you.inv[slot + 1]))
- return (slot + 1);
-
- accept_empty = true;
- }
- else if (accept_empty)
- {
- return slot;
- }
- }
- }
- return (-1);
-#undef slotisfree
-}
-
-// Returns quantity of items moved into player's inventory and -1 if
-// the player's inventory is full.
-int move_item_to_player( int obj, int quant_got, bool quiet )
-{
- int imass = 0;
- int unit_mass = 0;
- int retval = quant_got;
- char brek = 0;
- bool partialPickup = false;
-
- int m = 0;
-
- // Gold has no mass, so we handle it first.
- if (mitm[obj].base_type == OBJ_GOLD)
- {
- you.gold += quant_got;
- dec_mitm_item_quantity( obj, quant_got );
- you.redraw_gold = 1;
-
- if (!quiet)
- {
- snprintf( info, INFO_SIZE, "You pick up %d gold piece%s.",
- quant_got, (quant_got > 1) ? "s" : "" );
-
- mpr(info);
- }
-
- you.turn_is_over = 1;
- return (retval);
- }
-
- unit_mass = item_mass( mitm[obj] );
- if (quant_got > mitm[obj].quantity || quant_got <= 0)
- quant_got = mitm[obj].quantity;
-
- imass = unit_mass * quant_got;
-
- brek = 0;
-
- // multiply both constants * 10
-
- if ((int) you.burden + imass > carrying_capacity())
- {
- // calculate quantity we can actually pick up
- int part = (carrying_capacity() - (int)you.burden) / unit_mass;
-
- if (part < 1)
- return (0);
-
- // only pickup 'part' items
- quant_got = part;
- partialPickup = true;
-
- retval = part;
- }
-
- if (is_stackable_item( mitm[obj] ))
- {
- for (m = 0; m < ENDOFPACK; m++)
- {
- if (items_stack( you.inv[m], mitm[obj] ))
- {
- if (!quiet && partialPickup)
- mpr("You can only carry some of what is here.");
-
- inc_inv_item_quantity( m, quant_got );
- dec_mitm_item_quantity( obj, quant_got );
- burden_change();
-
- if (!quiet)
- {
- in_name( m, DESC_INVENTORY, info );
- mpr(info);
- }
-
- you.turn_is_over = 1;
-
- return (retval);
- }
- } // end of for m loop.
- }
-
- // can't combine, check for slot space
- if (inv_count() >= ENDOFPACK)
- return (-1);
-
- if (!quiet && partialPickup)
- mpr("You can only carry some of what is here.");
-
- int freeslot = find_free_slot(mitm[obj]);
- if (freeslot < 0 || freeslot >= ENDOFPACK
- || is_valid_item(you.inv[freeslot]))
- {
- // Something is terribly wrong
- return (-1);
- }
-
- item_def &item = you.inv[freeslot];
- // copy item
- item = mitm[obj];
- item.x = -1;
- item.y = -1;
- item.link = freeslot;
-
- origin_freeze(item, you.x_pos, you.y_pos);
-
- item.quantity = quant_got;
- dec_mitm_item_quantity( obj, quant_got );
- burden_change();
-
- if (!quiet)
- {
- in_name( freeslot, DESC_INVENTORY, info );
- mpr(info);
- }
-
- if (item.base_type == OBJ_ORBS
- && you.char_direction == DIR_DESCENDING)
- {
- if (!quiet)
- mpr("Now all you have to do is get back out of the dungeon!");
- you.char_direction = DIR_ASCENDING;
- }
-
- you.turn_is_over = 1;
-
- return (retval);
-} // end move_item_to_player()
-
-
-// Moves mitm[obj] to (x,y)... will modify the value of obj to
-// be the index of the final object (possibly different).
-//
-// Done this way in the hopes that it will be obvious from
-// calling code that "obj" is possibly modified.
-void move_item_to_grid( int *const obj, int x, int y )
-{
- // must be a valid reference to a valid object
- if (*obj == NON_ITEM || !is_valid_item( mitm[*obj] ))
- return;
-
- // If it's a stackable type...
- if (is_stackable_item( mitm[*obj] ))
- {
- // Look for similar item to stack:
- for (int i = igrd[x][y]; i != NON_ITEM; i = mitm[i].link)
- {
- // check if item already linked here -- don't want to unlink it
- if (*obj == i)
- return;
-
- if (items_stack( mitm[*obj], mitm[i] ))
- {
- // Add quantity to item already here, and dispose
- // of obj, while returning the found item. -- bwr
- inc_mitm_item_quantity( i, mitm[*obj].quantity );
- destroy_item( *obj );
- *obj = i;
- return;
- }
- }
- }
-
- ASSERT( *obj != NON_ITEM );
-
- // Need to actually move object, so first unlink from old position.
- unlink_item( *obj );
-
- // move item to coord:
- mitm[*obj].x = x;
- mitm[*obj].y = y;
-
- // link item to top of list.
- mitm[*obj].link = igrd[x][y];
- igrd[x][y] = *obj;
-
- return;
-}
-
-void move_item_stack_to_grid( int x, int y, int targ_x, int targ_y )
-{
- // Tell all items in stack what the new coordinate is.
- for (int o = igrd[x][y]; o != NON_ITEM; o = mitm[o].link)
- {
- mitm[o].x = targ_x;
- mitm[o].y = targ_y;
- }
-
- igrd[targ_x][targ_y] = igrd[x][y];
- igrd[x][y] = NON_ITEM;
-}
-
-
-// returns quantity dropped
-bool copy_item_to_grid( const item_def &item, int x_plos, int y_plos,
- int quant_drop, bool mark_dropped )
-{
- if (quant_drop == 0)
- return (false);
-
- // default quant_drop == -1 => drop all
- if (quant_drop < 0)
- quant_drop = item.quantity;
-
- // loop through items at current location
- if (is_stackable_item( item ))
- {
- for (int i = igrd[x_plos][y_plos]; i != NON_ITEM; i = mitm[i].link)
- {
- if (items_stack( item, mitm[i] ))
- {
- inc_mitm_item_quantity( i, quant_drop );
-
- // If the items on the floor already have a nonzero slot,
- // leave it as such, otherwise set the slot.
- if (mark_dropped && !mitm[i].slot)
- mitm[i].slot = index_to_letter(item.link);
- return (true);
- }
- }
- }
-
- // item not found in current stack, add new item to top.
- int new_item = get_item_slot(10);
- if (new_item == NON_ITEM)
- return (false);
-
- // copy item
- mitm[new_item] = item;
-
- // set quantity, and set the item as unlinked
- mitm[new_item].quantity = quant_drop;
- mitm[new_item].x = 0;
- mitm[new_item].y = 0;
- mitm[new_item].link = NON_ITEM;
-
- if (mark_dropped)
- {
- mitm[new_item].slot = index_to_letter(item.link);
- mitm[new_item].flags |= ISFLAG_DROPPED;
- mitm[new_item].flags &= ~ISFLAG_THROWN;
- origin_set_unknown(mitm[new_item]);
- }
-
- move_item_to_grid( &new_item, x_plos, y_plos );
-
- return (true);
-} // end copy_item_to_grid()
-
-
-//---------------------------------------------------------------
-//
-// move_top_item -- moves the top item of a stack to a new
-// location.
-//
-//---------------------------------------------------------------
-bool move_top_item( int src_x, int src_y, int dest_x, int dest_y )
-{
- int item = igrd[ src_x ][ src_y ];
- if (item == NON_ITEM)
- return (false);
-
- // Now move the item to its new possition...
- move_item_to_grid( &item, dest_x, dest_y );
-
- return (true);
-}
-
-
-//---------------------------------------------------------------
-//
-// drop_gold
-//
-//---------------------------------------------------------------
-static void drop_gold(unsigned int amount)
-{
- if (you.gold > 0)
- {
- if (amount > you.gold)
- amount = you.gold;
-
- snprintf( info, INFO_SIZE, "You drop %d gold piece%s.",
- amount, (amount > 1) ? "s" : "" );
- mpr(info);
-
- // loop through items at grid location, look for gold
- int i = igrd[you.x_pos][you.y_pos];
-
- while(i != NON_ITEM)
- {
- if (mitm[i].base_type == OBJ_GOLD)
- {
- inc_mitm_item_quantity( i, amount );
- you.gold -= amount;
- you.redraw_gold = 1;
- you.turn_is_over = 1;
- return;
- }
-
- // follow link
- i = mitm[i].link;
- }
-
- // place on top.
- i = get_item_slot(10);
- if (i == NON_ITEM)
- {
- mpr( "Too many items on this level, not dropping the gold." );
- return;
- }
-
- mitm[i].base_type = OBJ_GOLD;
- mitm[i].quantity = amount;
- mitm[i].flags = 0;
-
- move_item_to_grid( &i, you.x_pos, you.y_pos );
-
- you.gold -= amount;
- you.redraw_gold = 1;
-
- you.turn_is_over = 1;
- }
- else
- {
- mpr("You don't have any money.");
- }
-} // end drop_gold()
-
-bool drop_item( int item_dropped, int quant_drop ) {
- if (item_dropped == PROMPT_GOT_SPECIAL) // ie '$' for gold
- {
- // drop gold
- if (quant_drop < 0 || quant_drop > static_cast< int >( you.gold ))
- quant_drop = you.gold;
-
- drop_gold( quant_drop );
- return (true);
- }
-
- if (quant_drop < 0 || quant_drop > you.inv[item_dropped].quantity)
- quant_drop = you.inv[item_dropped].quantity;
-
- if (item_dropped == you.equip[EQ_LEFT_RING]
- || item_dropped == you.equip[EQ_RIGHT_RING]
- || item_dropped == you.equip[EQ_AMULET])
- {
- mpr("You will have to take that off first.");
- return (false);
- }
-
- if (item_dropped == you.equip[EQ_WEAPON]
- && you.inv[item_dropped].base_type == OBJ_WEAPONS
- && item_cursed( you.inv[item_dropped] ))
- {
- mpr("That object is stuck to you!");
- return (false);
- }
-
- for (int i = EQ_CLOAK; i <= EQ_BODY_ARMOUR; i++)
- {
- if (item_dropped == you.equip[i] && you.equip[i] != -1)
- {
- if (!Options.easy_armour)
- {
- mpr("You will have to take that off first.");
- }
- else
- {
- // If we take off the item, cue up the item being dropped
- if (takeoff_armour( item_dropped ))
- {
- start_delay( DELAY_DROP_ITEM, 1, item_dropped, 1 );
- you.turn_is_over = 0; // turn happens later
- }
- }
-
- // Regardless, we want to return here because either we're
- // aborting the drop, or the drop is delayed until after
- // the armour is removed. -- bwr
- return (false);
- }
- }
-
- // Unwield needs to be done before copy in order to clear things
- // like temporary brands. -- bwr
- if (item_dropped == you.equip[EQ_WEAPON])
- {
- unwield_item(item_dropped);
- you.equip[EQ_WEAPON] = -1;
- canned_msg( MSG_EMPTY_HANDED );
- }
-
- if (!copy_item_to_grid( you.inv[item_dropped],
- you.x_pos, you.y_pos, quant_drop, true ))
- {
- mpr( "Too many items on this level, not dropping the item." );
- return (false);
- }
-
- char str_pass[ ITEMNAME_SIZE ];
- quant_name( you.inv[item_dropped], quant_drop, DESC_NOCAP_A, str_pass );
- snprintf( info, INFO_SIZE, "You drop %s.", str_pass );
- mpr(info);
-
- dec_inv_item_quantity( item_dropped, quant_drop );
- you.turn_is_over = 1;
-
- return (true);
-}
-
-
-static std::string drop_menu_title( int menuflags, const std::string &oldt ) {
- std::string res = oldt;
- res.erase(0, res.find_first_not_of(" \n\t"));
- if (menuflags & MF_MULTISELECT)
- res = "[Multidrop] " + res;
- return " " + res;
-}
-
-int get_equip_slot(const item_def *item)
-{
- int worn = -1;
- if (item && in_inventory(*item))
- {
- for (int i = 0; i < NUM_EQUIP; ++i)
- {
- if (you.equip[i] == item->link)
- {
- worn = i;
- break;
- }
- }
- }
- return worn;
-}
-
-static std::string drop_selitem_text( const std::vector<MenuEntry*> *s )
-{
- char buf[130];
- bool extraturns = false;
-
- if (!s->size())
- return "";
-
- for (int i = 0, size = s->size(); i < size; ++i)
- {
- const item_def *item = static_cast<item_def *>( (*s)[i]->data );
- int eq = get_equip_slot(item);
- if (eq > EQ_WEAPON && eq < NUM_EQUIP)
- {
- extraturns = true;
- break;
- }
- }
-
- snprintf( buf, sizeof buf, " (%lu%s turn%s)", (unsigned long) (s->size()),
- extraturns? "+" : "",
- s->size() > 1? "s" : "" );
- return buf;
-}
-
-//---------------------------------------------------------------
-//
-// drop
-//
-// Prompts the user for an item to drop
-//
-//---------------------------------------------------------------
-void drop(void)
-{
- if (inv_count() < 1 && you.gold == 0)
- {
- canned_msg(MSG_NOTHING_CARRIED);
- you.activity = ACT_NONE;
- return;
- }
-
- static std::vector<SelItem> selected;
-
- if (!you.activity || selected.empty())
- selected = prompt_invent_items( "Drop which item?", -1,
- drop_menu_title,
- true, true, '$',
- &Options.drop_filter,
- drop_selitem_text );
-
- if (selected.empty())
- {
- canned_msg( MSG_OK );
- you.activity = ACT_NONE;
- return;
- }
-
- // Throw away invalid items; items usually go invalid because
- // of chunks rotting away.
- while (!selected.empty()
- // Don't look for gold in inventory
- && selected[0].slot != PROMPT_GOT_SPECIAL
- && !is_valid_item(you.inv[ selected[0].slot ]))
- selected.erase( selected.begin() );
-
- // Did the defunct item filter above deprive us of a drop target?
- if (!selected.empty())
- {
- drop_item( selected[0].slot, selected[0].quantity );
- // Forget the item we just dropped
- selected.erase( selected.begin() );
- }
-
- // If we still have items that want to be dropped, start the multiturn
- // activity
- you.activity = selected.empty()? ACT_NONE : ACT_MULTIDROP;
-} // end drop()
-
-//---------------------------------------------------------------
-//
-// shift_monster
-//
-// Moves a monster to approximately (x,y) and returns true
-// if monster was moved.
-//
-//---------------------------------------------------------------
-static bool shift_monster( struct monsters *mon, int x, int y )
-{
- bool found_move = false;
-
- int i, j;
- int tx, ty;
- int nx = 0, ny = 0;
-
- int count = 0;
-
- if (x == 0 && y == 0)
- {
- // try and find a random floor space some distance away
- for (i = 0; i < 50; i++)
- {
- tx = 5 + random2( GXM - 10 );
- ty = 5 + random2( GYM - 10 );
-
- int dist = grid_distance(x, y, tx, ty);
- if (grd[tx][ty] == DNGN_FLOOR && dist > 10)
- break;
- }
-
- if (i == 50)
- return (false);
- }
-
- for (i = -1; i <= 1; i++)
- {
- for (j = -1; j <= 1; j++)
- {
- tx = x + i;
- ty = y + j;
-
- if (tx < 5 || tx > GXM - 5 || ty < 5 || ty > GXM - 5)
- continue;
-
- // won't drop on anything but vanilla floor right now
- if (grd[tx][ty] != DNGN_FLOOR)
- continue;
-
- if (mgrd[tx][ty] != NON_MONSTER)
- continue;
-
- if (tx == you.x_pos && ty == you.y_pos)
- continue;
-
- count++;
- if (one_chance_in(count))
- {
- nx = tx;
- ny = ty;
- found_move = true;
- }
- }
- }
-
- if (found_move)
- {
- const int mon_index = mgrd[mon->x][mon->y];
- mgrd[mon->x][mon->y] = NON_MONSTER;
- mgrd[nx][ny] = mon_index;
- mon->x = nx;
- mon->y = ny;
- }
-
- return (found_move);
-}
-
-//---------------------------------------------------------------
-//
-// update_corpses
-//
-// Update all of the corpses and food chunks on the floor. (The
-// elapsed time is a double because this is called when we re-
-// enter a level and a *long* time may have elapsed).
-//
-//---------------------------------------------------------------
-void update_corpses(double elapsedTime)
-{
- int cx, cy;
-
- if (elapsedTime <= 0.0)
- return;
-
- const long rot_time = (long) (elapsedTime / 20.0);
-
- for (int c = 0; c < MAX_ITEMS; c++)
- {
- if (mitm[c].quantity < 1)
- continue;
-
- if (mitm[c].base_type != OBJ_CORPSES && mitm[c].base_type != OBJ_FOOD)
- {
- continue;
- }
-
- if (mitm[c].base_type == OBJ_CORPSES
- && mitm[c].sub_type > CORPSE_SKELETON)
- {
- continue;
- }
-
- if (mitm[c].base_type == OBJ_FOOD && mitm[c].sub_type != FOOD_CHUNK)
- {
- continue;
- }
-
- if (rot_time >= mitm[c].special)
- {
- if (mitm[c].base_type == OBJ_FOOD)
- {
- destroy_item(c);
- }
- else
- {
- if (mitm[c].sub_type == CORPSE_SKELETON
- || !mons_skeleton( mitm[c].plus ))
- {
- destroy_item(c);
- }
- else
- {
- mitm[c].sub_type = CORPSE_SKELETON;
- mitm[c].special = 200;
- mitm[c].colour = LIGHTGREY;
- }
- }
- }
- else
- {
- ASSERT(rot_time < 256);
- mitm[c].special -= rot_time;
- }
- }
-
-
- int fountain_checks = (int)(elapsedTime / 1000.0);
- if (random2(1000) < (int)(elapsedTime) % 1000)
- fountain_checks += 1;
-
- // dry fountains may start flowing again
- if (fountain_checks > 0)
- {
- for (cx=0; cx<GXM; cx++)
- {
- for (cy=0; cy<GYM; cy++)
- {
- if (grd[cx][cy] > DNGN_SPARKLING_FOUNTAIN
- && grd[cx][cy] < DNGN_PERMADRY_FOUNTAIN)
- {
- for (int i=0; i<fountain_checks; i++)
- {
- if (one_chance_in(100))
- {
- if (grd[cx][cy] > DNGN_SPARKLING_FOUNTAIN)
- grd[cx][cy]--;
- }
- }
- }
- }
- }
- }
-}
-
-static bool remove_enchant_levels( struct monsters *mon, int slot, int min,
- int levels )
-{
- const int new_level = mon->enchantment[slot] - levels;
-
- if (new_level < min)
- {
- mons_del_ench( mon,
- mon->enchantment[slot], mon->enchantment[slot], true );
- return (true);
- }
- else
- {
- mon->enchantment[slot] = new_level;
- }
-
- return (false);
-}
-
-//---------------------------------------------------------------
-//
-// update_enchantments
-//
-// Update a monster's enchantments when the player returns
-// to the level.
-//
-// Management for enchantments... problems with this are the oddities
-// (monster dying from poison several thousands of turns later), and
-// game balance.
-//
-// Consider: Poison/Sticky Flame a monster at range and leave, monster
-// dies but can't leave level to get to player (implied game balance of
-// the delayed damage is that the monster could be a danger before
-// it dies). This could be fixed by keeping some monsters active
-// off level and allowing them to take stairs (a very serious change).
-//
-// Compare this to the current abuse where the player gets
-// effectively extended duration of these effects (although only
-// the actual effects only occur on level, the player can leave
-// and heal up without having the effect disappear).
-//
-// This is a simple compromise between the two... the enchantments
-// go away, but the effects don't happen off level. -- bwr
-//
-//---------------------------------------------------------------
-static void update_enchantments( struct monsters *mon, int levels )
-{
- int i;
-
- for (i = 0; i < NUM_MON_ENCHANTS; i++)
- {
- switch (mon->enchantment[i])
- {
- case ENCH_YOUR_POISON_I:
- case ENCH_YOUR_POISON_II:
- case ENCH_YOUR_POISON_III:
- case ENCH_YOUR_POISON_IV:
- remove_enchant_levels( mon, i, ENCH_YOUR_POISON_I, levels );
- break;
-
- case ENCH_YOUR_SHUGGOTH_I:
- case ENCH_YOUR_SHUGGOTH_II:
- case ENCH_YOUR_SHUGGOTH_III:
- case ENCH_YOUR_SHUGGOTH_IV:
- remove_enchant_levels( mon, i, ENCH_YOUR_SHUGGOTH_I, levels );
- break;
-
- case ENCH_YOUR_ROT_I:
- case ENCH_YOUR_ROT_II:
- case ENCH_YOUR_ROT_III:
- case ENCH_YOUR_ROT_IV:
- remove_enchant_levels( mon, i, ENCH_YOUR_ROT_I, levels );
- break;
-
- case ENCH_BACKLIGHT_I:
- case ENCH_BACKLIGHT_II:
- case ENCH_BACKLIGHT_III:
- case ENCH_BACKLIGHT_IV:
- remove_enchant_levels( mon, i, ENCH_BACKLIGHT_I, levels );
- break;
-
- case ENCH_YOUR_STICKY_FLAME_I:
- case ENCH_YOUR_STICKY_FLAME_II:
- case ENCH_YOUR_STICKY_FLAME_III:
- case ENCH_YOUR_STICKY_FLAME_IV:
- remove_enchant_levels( mon, i, ENCH_YOUR_STICKY_FLAME_I, levels );
- break;
-
- case ENCH_POISON_I:
- case ENCH_POISON_II:
- case ENCH_POISON_III:
- case ENCH_POISON_IV:
- remove_enchant_levels( mon, i, ENCH_POISON_I, levels );
- break;
-
- case ENCH_STICKY_FLAME_I:
- case ENCH_STICKY_FLAME_II:
- case ENCH_STICKY_FLAME_III:
- case ENCH_STICKY_FLAME_IV:
- remove_enchant_levels( mon, i, ENCH_STICKY_FLAME_I, levels );
- break;
-
- case ENCH_FRIEND_ABJ_I:
- case ENCH_FRIEND_ABJ_II:
- case ENCH_FRIEND_ABJ_III:
- case ENCH_FRIEND_ABJ_IV:
- case ENCH_FRIEND_ABJ_V:
- case ENCH_FRIEND_ABJ_VI:
- if (remove_enchant_levels( mon, i, ENCH_FRIEND_ABJ_I, levels ))
- {
- monster_die( mon, KILL_RESET, 0 );
- }
- break;
-
- case ENCH_ABJ_I:
- case ENCH_ABJ_II:
- case ENCH_ABJ_III:
- case ENCH_ABJ_IV:
- case ENCH_ABJ_V:
- case ENCH_ABJ_VI:
- if (remove_enchant_levels( mon, i, ENCH_ABJ_I, levels ))
- {
- monster_die( mon, KILL_RESET, 0 );
- }
- break;
-
-
- case ENCH_SHORT_LIVED:
- monster_die( mon, KILL_RESET, 0 );
- break;
-
- case ENCH_TP_I:
- case ENCH_TP_II:
- case ENCH_TP_III:
- case ENCH_TP_IV:
- monster_teleport( mon, true );
- break;
-
- case ENCH_CONFUSION:
- monster_blink( mon );
- break;
-
- case ENCH_GLOWING_SHAPESHIFTER:
- case ENCH_SHAPESHIFTER:
- case ENCH_CREATED_FRIENDLY:
- case ENCH_SUBMERGED:
- default:
- // don't touch these
- break;
-
- case ENCH_SLOW:
- case ENCH_HASTE:
- case ENCH_FEAR:
- case ENCH_INVIS:
- case ENCH_CHARM:
- case ENCH_SLEEP_WARY:
- // delete enchantment (using function to get this done cleanly)
- mons_del_ench(mon, mon->enchantment[i], mon->enchantment[i], true);
- break;
- }
- }
-}
-
-
-//---------------------------------------------------------------
-//
-// update_level
-//
-// Update the level when the player returns to it.
-//
-//---------------------------------------------------------------
-void update_level( double elapsedTime )
-{
- int m, i;
- int turns = (int) (elapsedTime / 10.0);
-
-#if DEBUG_DIAGNOSTICS
- int mons_total = 0;
-
- snprintf( info, INFO_SIZE, "turns: %d", turns );
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- update_corpses( elapsedTime );
-
- for (m = 0; m < MAX_MONSTERS; m++)
- {
- struct monsters *mon = &menv[m];
-
- if (mon->type == -1)
- continue;
-
-#if DEBUG_DIAGNOSTICS
- mons_total++;
-#endif
-
- // following monsters don't get movement
- if (mon->flags & MF_JUST_SUMMONED)
- continue;
-
- // XXX: Allow some spellcasting (like Healing and Teleport)? -- bwr
- // const bool healthy = (mon->hit_points * 2 > mon->max_hit_points);
-
- // This is the monster healing code, moved here from tag.cc:
- if (monster_descriptor( mon->type, MDSC_REGENERATES )
- || mon->type == MONS_PLAYER_GHOST)
- {
- heal_monster( mon, turns, false );
- }
- else
- {
- heal_monster( mon, (turns / 10), false );
- }
-
- if (turns >= 10)
- update_enchantments( mon, turns / 10 );
-
- // Don't move water or lava monsters around
- if (monster_habitat( mon->type ) != DNGN_FLOOR)
- continue;
-
- // Let sleeping monsters lie
- if (mon->behaviour == BEH_SLEEP)
- continue;
-
-
- const int range = (turns * mon->speed) / 10;
- const int moves = (range > 50) ? 50 : range;
-
- // const bool short_time = (range >= 5 + random2(10));
- const bool long_time = (range >= (500 + roll_dice( 2, 500 )));
-
- const bool ranged_attack = (mons_has_ranged_spell( mon )
- || mons_has_ranged_attack( mon ));
-
-#if DEBUG_DIAGNOSTICS
- // probably too annoying even for DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE,
- "mon #%d: range %d; long %d; pos (%d,%d); targ %d(%d,%d); flags %d",
- m, range, long_time, mon->x, mon->y,
- mon->foe, mon->target_x, mon->target_y, mon->flags );
-
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- if (range <= 0)
- continue;
-
- if (long_time
- && (mon->behaviour == BEH_FLEE
- || mon->behaviour == BEH_CORNERED
- || testbits( mon->flags, MF_BATTY )
- || ranged_attack
- || coinflip()))
- {
- if (mon->behaviour != BEH_WANDER)
- {
- mon->behaviour = BEH_WANDER;
- mon->foe = MHITNOT;
- mon->target_x = 10 + random2( GXM - 10 );
- mon->target_y = 10 + random2( GYM - 10 );
- }
- else
- {
- // monster will be sleeping after we move it
- mon->behaviour = BEH_SLEEP;
- }
- }
- else if (ranged_attack)
- {
- // if we're doing short time movement and the monster has a
- // ranged attack (missile or spell), then the monster will
- // flee to gain distance if its "too close", else it will
- // just shift its position rather than charge the player. -- bwr
- if (grid_distance(mon->x, mon->y, mon->target_x, mon->target_y) < 3)
- {
- mon->behaviour = BEH_FLEE;
-
- // if the monster is on the target square, fleeing won't work
- if (mon->x == mon->target_x && mon->y == mon->target_y)
- {
- if (you.x_pos != mon->x || you.y_pos != mon->y)
- {
- // flee from player's position if different
- mon->target_x = you.x_pos;
- mon->target_y = you.y_pos;
- }
- else
- {
- // randomize the target so we have a direction to flee
- mon->target_x += (random2(3) - 1);
- mon->target_y += (random2(3) - 1);
- }
- }
-
-#if DEBUG_DIAGNOSTICS
- mpr( "backing off...", MSGCH_DIAGNOSTICS );
-#endif
- }
- else
- {
- shift_monster( mon, mon->x, mon->y );
-
-#if DEBUG_DIAGNOSTICS
- snprintf(info, INFO_SIZE, "shifted to (%d,%d)", mon->x, mon->y);
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
- continue;
- }
- }
-
- int pos_x = mon->x, pos_y = mon->y;
-
- // dirt simple movement:
- for (i = 0; i < moves; i++)
- {
- int mx = (pos_x > mon->target_x) ? -1 :
- (pos_x < mon->target_x) ? 1
- : 0;
-
- int my = (pos_y > mon->target_y) ? -1 :
- (pos_y < mon->target_y) ? 1
- : 0;
-
- if (mon->behaviour == BEH_FLEE)
- {
- mx *= -1;
- my *= -1;
- }
-
- if (pos_x + mx < 0 || pos_x + mx >= GXM)
- mx = 0;
-
- if (pos_y + my < 0 || pos_y + my >= GXM)
- my = 0;
-
- if (mx == 0 && my == 0)
- break;
-
- if (grd[pos_x + mx][pos_y + my] < DNGN_FLOOR)
- break;
-
- pos_x += mx;
- pos_y += my;
- }
-
- if (!shift_monster( mon, pos_x, pos_y ))
- shift_monster( mon, mon->x, mon->y );
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "moved to (%d,%d)", mon->x, mon->y );
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
- }
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "total monsters on level = %d", mons_total );
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- for (i = 0; i < MAX_CLOUDS; i++)
- delete_cloud( i );
-}
-
-
-//---------------------------------------------------------------
-//
-// handle_time
-//
-// Do various time related actions...
-// This function is called about every 20 turns.
-//
-//---------------------------------------------------------------
-void handle_time( long time_delta )
-{
- int temp_rand; // probability determination {dlb}
-
- // so as not to reduplicate f(x) calls {dlb}
- unsigned int which_miscast = SPTYP_RANDOM;
-
- bool summon_instead; // for branching within a single switch {dlb}
- int which_beastie = MONS_PROGRAM_BUG; // error trapping {dlb}
- unsigned char i; // loop variable {dlb}
- bool new_rotting_item = false; //mv: becomes true when some new item becomes rotting
-
- // BEGIN - Nasty things happen to people who spend too long in Hell:
- if (player_in_hell() && coinflip())
- {
- temp_rand = random2(17);
-
- mpr((temp_rand == 0) ? "\"You will not leave this place.\"" :
- (temp_rand == 1) ? "\"Die, mortal!\"" :
- (temp_rand == 2) ? "\"We do not forgive those who trespass against us!\"" :
- (temp_rand == 3) ? "\"Trespassers are not welcome here!\"" :
- (temp_rand == 4) ? "\"You do not belong in this place!\"" :
- (temp_rand == 5) ? "\"Leave now, before it is too late!\"" :
- (temp_rand == 6) ? "\"We have you now!\"" :
- (temp_rand == 7) ? "You feel a terrible foreboding..." :
- (temp_rand == 8) ? "You hear words spoken in a strange and terrible language..." :
-
- (temp_rand == 9) ? ((you.species != SP_MUMMY)
- ? "You smell brimstone." : "Brimstone rains from above.") :
-
- (temp_rand == 10) ? "Something frightening happens." :
- (temp_rand == 11) ? "You sense an ancient evil watching you..." :
- (temp_rand == 12) ? "You feel lost and a long, long way from home..." :
- (temp_rand == 13) ? "You suddenly feel all small and vulnerable." :
- (temp_rand == 14) ? "A gut-wrenching scream fills the air!" :
- (temp_rand == 15) ? "You shiver with fear." :
- (temp_rand == 16) ? "You sense a hostile presence."
- : "You hear diabolical laughter!", MSGCH_TALK);
-
- temp_rand = random2(27);
-
- if (temp_rand > 17) // 9 in 27 odds {dlb}
- {
- temp_rand = random2(8);
-
- if (temp_rand > 3) // 4 in 8 odds {dlb}
- which_miscast = SPTYP_NECROMANCY;
- else if (temp_rand > 1) // 2 in 8 odds {dlb}
- which_miscast = SPTYP_SUMMONING;
- else if (temp_rand > 0) // 1 in 8 odds {dlb}
- which_miscast = SPTYP_CONJURATION;
- else // 1 in 8 odds {dlb}
- which_miscast = SPTYP_ENCHANTMENT;
-
- miscast_effect( which_miscast, 4 + random2(6), random2avg(97, 3),
- 100, "the effects of Hell" );
- }
- else if (temp_rand > 7) // 10 in 27 odds {dlb}
- {
- // 60:40 miscast:summon split {dlb}
- summon_instead = (random2(5) > 2);
-
- switch (you.where_are_you)
- {
- case BRANCH_DIS:
- if (summon_instead)
- which_beastie = summon_any_demon(DEMON_GREATER);
- else
- which_miscast = SPTYP_EARTH;
- break;
- case BRANCH_GEHENNA:
- if (summon_instead)
- which_beastie = MONS_FIEND;
- else
- which_miscast = SPTYP_FIRE;
- break;
- case BRANCH_COCYTUS:
- if (summon_instead)
- which_beastie = MONS_ICE_FIEND;
- else
- which_miscast = SPTYP_ICE;
- break;
- case BRANCH_TARTARUS:
- if (summon_instead)
- which_beastie = MONS_SHADOW_FIEND;
- else
- which_miscast = SPTYP_NECROMANCY;
- break;
- default: // this is to silence gcc compiler warnings {dlb}
- if (summon_instead)
- which_beastie = MONS_FIEND;
- else
- which_miscast = SPTYP_NECROMANCY;
- break;
- }
-
- if (summon_instead)
- {
- create_monster( which_beastie, 0, BEH_HOSTILE, you.x_pos,
- you.y_pos, MHITYOU, 250 );
- }
- else
- {
- miscast_effect( which_miscast, 4 + random2(6),
- random2avg(97, 3), 100, "the effects of Hell" );
- }
- }
-
- // NB: no "else" - 8 in 27 odds that nothing happens through
- // first chain {dlb}
- // also note that the following is distinct from and in
- // addition to the above chain:
-
- // try to summon at least one and up to five random monsters {dlb}
- if (one_chance_in(3))
- {
- create_monster( RANDOM_MONSTER, 0, BEH_HOSTILE,
- you.x_pos, you.y_pos, MHITYOU, 250 );
-
- for (i = 0; i < 4; i++)
- {
- if (one_chance_in(3))
- {
- create_monster( RANDOM_MONSTER, 0, BEH_HOSTILE,
- you.x_pos, you.y_pos, MHITYOU, 250 );
- }
- }
- }
- }
- // END - special Hellish things...
-
- // Adjust the player's stats if s/he's diseased (or recovering).
- if (!you.disease)
- {
- if (you.strength < you.max_strength && one_chance_in(100))
- {
- mpr("You feel your strength returning.", MSGCH_RECOVERY);
- you.strength++;
- you.redraw_strength = 1;
- }
-
- if (you.dex < you.max_dex && one_chance_in(100))
- {
- mpr("You feel your dexterity returning.", MSGCH_RECOVERY);
- you.dex++;
- you.redraw_dexterity = 1;
- }
-
- if (you.intel < you.max_intel && one_chance_in(100))
- {
- mpr("You feel your intelligence returning.", MSGCH_RECOVERY);
- you.intel++;
- you.redraw_intelligence = 1;
- }
- }
- else
- {
- if (one_chance_in(30))
- {
- mpr("Your disease is taking its toll.", MSGCH_WARN);
- lose_stat(STAT_RANDOM, 1);
- }
- }
-
- // Adjust the player's stats if s/he has the deterioration mutation
- if (you.mutation[MUT_DETERIORATION]
- && random2(200) <= you.mutation[MUT_DETERIORATION] * 5 - 2)
- {
- lose_stat(STAT_RANDOM, 1);
- }
-
- int added_contamination = 0;
-
- // Account for mutagenic radiation. Invis and haste will give the
- // player about .1 points per turn, mutagenic randarts will give
- // about 1.5 points on average, so they can corrupt the player
- // quite quickly. Wielding one for a short battle is OK, which is
- // as things should be. -- GDL
- if (you.invis && random2(10) < 6)
- added_contamination++;
-
- if (you.haste && !you.berserker && random2(10) < 6)
- added_contamination++;
-
- // randarts are usually about 20x worse than running around invisible
- // or hasted.. this seems OK.
- added_contamination += random2(1 + scan_randarts(RAP_MUTAGENIC));
-
- // we take off about .5 points per turn
- if (!you.invis && !you.haste && coinflip())
- added_contamination -= 1;
-
- contaminate_player( added_contamination );
-
- // only check for badness once every other turn
- if (coinflip())
- {
- if (you.magic_contamination >= 5
- /* && random2(150) <= you.magic_contamination */)
- {
- mpr("Your body shudders with the violent release of wild energies!", MSGCH_WARN);
-
- // for particularly violent releases, make a little boom
- if (you.magic_contamination > 25 && one_chance_in(3))
- {
- struct bolt boom;
- boom.type = SYM_BURST;
- boom.colour = BLACK;
- boom.flavour = BEAM_RANDOM;
- boom.target_x = you.x_pos;
- boom.target_y = you.y_pos;
- boom.damage = dice_def( 3, (you.magic_contamination / 2) );
- boom.thrower = KILL_MISC;
- boom.aux_source = "a magical explosion";
- boom.beam_source = NON_MONSTER;
- boom.is_beam = false;
- boom.is_tracer = false;
- boom.is_explosion = true;
- strcpy(boom.beam_name, "magical storm");
-
- boom.ench_power = (you.magic_contamination * 5);
- boom.ex_size = (you.magic_contamination / 15);
- if (boom.ex_size > 9)
- boom.ex_size = 9;
-
- explosion(boom);
- }
-
- // we want to warp the player, not do good stuff!
- if (one_chance_in(5))
- mutate(100);
- else
- give_bad_mutation(coinflip());
-
- // we're meaner now, what with explosions and whatnot, but
- // we dial down the contamination a little faster if its actually
- // mutating you. -- GDL
- contaminate_player( -(random2(you.magic_contamination / 4) + 1) );
- }
- }
-
- // Random chance to identify staff in hand based off of Spellcasting
- // and an appropriate other spell skill... is 1/20 too fast?
- if (you.equip[EQ_WEAPON] != -1
- && you.inv[you.equip[EQ_WEAPON]].base_type == OBJ_STAVES
- && !item_ident( you.inv[you.equip[EQ_WEAPON]], ISFLAG_KNOW_TYPE )
- && one_chance_in(20))
- {
- int total_skill = you.skills[SK_SPELLCASTING];
-
- switch (you.inv[you.equip[EQ_WEAPON]].sub_type)
- {
- case STAFF_WIZARDRY:
- case STAFF_ENERGY:
- total_skill += you.skills[SK_SPELLCASTING];
- break;
- case STAFF_FIRE:
- if (you.skills[SK_FIRE_MAGIC] > you.skills[SK_ICE_MAGIC])
- total_skill += you.skills[SK_FIRE_MAGIC];
- else
- total_skill += you.skills[SK_ICE_MAGIC];
- break;
- case STAFF_COLD:
- if (you.skills[SK_ICE_MAGIC] > you.skills[SK_FIRE_MAGIC])
- total_skill += you.skills[SK_ICE_MAGIC];
- else
- total_skill += you.skills[SK_FIRE_MAGIC];
- break;
- case STAFF_AIR:
- if (you.skills[SK_AIR_MAGIC] > you.skills[SK_EARTH_MAGIC])
- total_skill += you.skills[SK_AIR_MAGIC];
- else
- total_skill += you.skills[SK_EARTH_MAGIC];
- break;
- case STAFF_EARTH:
- if (you.skills[SK_EARTH_MAGIC] > you.skills[SK_AIR_MAGIC])
- total_skill += you.skills[SK_EARTH_MAGIC];
- else
- total_skill += you.skills[SK_AIR_MAGIC];
- break;
- case STAFF_POISON:
- total_skill += you.skills[SK_POISON_MAGIC];
- break;
- case STAFF_DEATH:
- total_skill += you.skills[SK_NECROMANCY];
- break;
- case STAFF_CONJURATION:
- total_skill += you.skills[SK_CONJURATIONS];
- break;
- case STAFF_ENCHANTMENT:
- total_skill += you.skills[SK_ENCHANTMENTS];
- break;
- case STAFF_SUMMONING:
- total_skill += you.skills[SK_SUMMONINGS];
- break;
- }
-
- if (random2(100) < total_skill)
- {
- set_ident_flags( you.inv[you.equip[EQ_WEAPON]], ISFLAG_IDENT_MASK );
-
- char str_pass[ ITEMNAME_SIZE ];
- in_name(you.equip[EQ_WEAPON], DESC_NOCAP_A, str_pass);
- snprintf( info, INFO_SIZE, "You are wielding %s.", str_pass );
- mpr(info);
- more();
-
- you.wield_change = true;
- }
- }
-
- // Check to see if an upset god wants to do something to the player
- // jmf: moved huge thing to religion.cc
- handle_god_time();
-
- // If the player has the lost mutation forget portions of the map
- if (you.mutation[MUT_LOST])
- {
- if (random2(100) <= you.mutation[MUT_LOST] * 5)
- forget_map(5 + random2(you.mutation[MUT_LOST] * 10));
- }
-
- // Update all of the corpses and food chunks on the floor
- update_corpses(time_delta);
-
- // Update all of the corpses and food chunks in the player's
- // inventory {should be moved elsewhere - dlb}
-
-
- for (i = 0; i < ENDOFPACK; i++)
- {
- if (you.inv[i].quantity < 1)
- continue;
-
- if (you.inv[i].base_type != OBJ_CORPSES && you.inv[i].base_type != OBJ_FOOD)
- continue;
-
- if (you.inv[i].base_type == OBJ_CORPSES
- && you.inv[i].sub_type > CORPSE_SKELETON)
- {
- continue;
- }
-
- if (you.inv[i].base_type == OBJ_FOOD && you.inv[i].sub_type != FOOD_CHUNK)
- continue;
-
- if ((time_delta / 20) >= you.inv[i].special)
- {
- if (you.inv[i].base_type == OBJ_FOOD)
- {
- if (you.equip[EQ_WEAPON] == i)
- {
- unwield_item(you.equip[EQ_WEAPON]);
- you.equip[EQ_WEAPON] = -1;
- you.wield_change = true;
- }
-
- mpr( "Your equipment suddenly weighs less.", MSGCH_ROTTEN_MEAT );
- you.inv[i].quantity = 0;
- burden_change();
- continue;
- }
-
- if (you.inv[i].sub_type == CORPSE_SKELETON)
- continue; // carried skeletons are not destroyed
-
- if (!mons_skeleton( you.inv[i].plus ))
- {
- if (you.equip[EQ_WEAPON] == i)
- {
- unwield_item(you.equip[EQ_WEAPON]);
- you.equip[EQ_WEAPON] = -1;
- }
-
- you.inv[i].quantity = 0;
- burden_change();
- continue;
- }
-
- you.inv[i].sub_type = 1;
- you.inv[i].special = 0;
- you.inv[i].colour = LIGHTGREY;
- you.wield_change = true;
- continue;
- }
-
- you.inv[i].special -= (time_delta / 20);
-
- if (you.inv[i].special < 100 && (you.inv[i].special + (time_delta / 20)>=100))
- {
- new_rotting_item = true;
- }
- }
-
- //mv: messages when chunks/corpses become rotten
- if (new_rotting_item)
- {
- switch (you.species)
- {
- // XXX: should probably still notice?
- case SP_MUMMY: // no smell
- case SP_TROLL: // stupid, living in mess - doesn't care about it
- break;
-
- case SP_GHOUL: //likes it
- temp_rand = random2(8);
- mpr( ((temp_rand < 5) ? "You smell something rotten." :
- (temp_rand == 5) ? "Smell of rotting flesh makes you more hungry." :
- (temp_rand == 6) ? "You smell decay. Yum-yum."
- : "Wow! There is something tasty in your inventory."),
- MSGCH_ROTTEN_MEAT );
- break;
-
- case SP_KOBOLD: //mv: IMO these race aren't so "touchy"
- case SP_OGRE:
- case SP_MINOTAUR:
- case SP_HILL_ORC:
- temp_rand = random2(8);
- mpr( ((temp_rand < 5) ? "You smell something rotten." :
- (temp_rand == 5) ? "You smell rotting flesh." :
- (temp_rand == 6) ? "You smell decay."
- : "There is something rotten in your inventory."),
- MSGCH_ROTTEN_MEAT );
- break;
-
- default:
- temp_rand = random2(8);
- mpr( ((temp_rand < 5) ? "You smell something rotten." :
- (temp_rand == 5) ? "Smell of rotting flesh makes you sick." :
- (temp_rand == 6) ? "You smell decay. Yuk..."
- : "Ugh! There is something really disgusting in your inventory."),
- MSGCH_ROTTEN_MEAT );
- break;
- }
- }
-
- // exercise armour *xor* stealth skill: {dlb}
- if (!player_light_armour())
- {
- if (random2(1000) <= item_mass( you.inv[you.equip[EQ_BODY_ARMOUR]] ))
- {
- return;
- }
-
- if (one_chance_in(6)) // lowered random roll from 7 to 6 -- bwross
- exercise(SK_ARMOUR, 1);
- }
- else // exercise stealth skill:
- {
- if (you.burden_state != BS_UNENCUMBERED || you.berserker)
- return;
-
- if (you.special_wield == SPWLD_SHADOW)
- return;
-
- if (you.equip[EQ_BODY_ARMOUR] != -1
- && random2( item_mass( you.inv[you.equip[EQ_BODY_ARMOUR]] )) >= 100)
- {
- return;
- }
-
- if (one_chance_in(18))
- exercise(SK_STEALTH, 1);
- }
-
- return;
-} // end handle_time()
-
-int autopickup_on = 1;
-
-static bool is_banned(const item_def &item) {
- static char name[ITEMNAME_SIZE];
- item_name(item, DESC_INVENTORY, name, false);
-
- std::string iname = name;
- for (unsigned i = 0; i < Options.banned_objects.size(); ++i) {
- if (Options.banned_objects[i].matches(iname))
- return true;
- }
- return false;
-}
-
-static void autopickup(void)
-{
- //David Loewenstern 6/99
- int result, o, next;
- bool did_pickup = false;
-
- if (autopickup_on == 0 || Options.autopickups == 0L)
- return;
-
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_AIR
- && you.duration[DUR_TRANSFORMATION] > 0)
- {
- return;
- }
-
- if (player_is_levitating() && !wearing_amulet(AMU_CONTROLLED_FLIGHT))
- return;
-
- o = igrd[you.x_pos][you.y_pos];
-
- while (o != NON_ITEM)
- {
- next = mitm[o].link;
-
- if ( ((mitm[o].flags & ISFLAG_THROWN) && Options.pickup_thrown) ||
- ( (Options.autopickups & (1L << mitm[o].base_type)
-#ifdef CLUA_BINDINGS
- || clua.callbooleanfn(false, "ch_autopickup", "u", &mitm[o])
-#endif
- )
- && (Options.pickup_dropped || !(mitm[o].flags & ISFLAG_DROPPED))
- && !is_banned(mitm[o])))
- {
- mitm[o].flags &= ~(ISFLAG_THROWN | ISFLAG_DROPPED);
-
- result = move_item_to_player( o, mitm[o].quantity);
-
- if (result == 0)
- {
- mpr("You can't carry any more.");
- break;
- }
- else if (result == -1)
- {
- mpr("Your pack is full.");
- break;
- }
-
- did_pickup = true;
- }
-
- o = next;
- }
-
- // move_item_to_player should leave things linked. -- bwr
- // relink_cell(you.x_pos, you.y_pos);
-
- if (did_pickup)
- {
- you.turn_is_over = 1;
- start_delay( DELAY_AUTOPICKUP, 1 );
- }
-}
-
-int inv_count(void)
-{
- int count=0;
-
- for(int i=0; i< ENDOFPACK; i++)
- {
- if (is_valid_item( you.inv[i] ))
- count += 1;
- }
-
- return count;
-}
-
-#ifdef ALLOW_DESTROY_ITEM_COMMAND
-// Started with code from AX-crawl, although its modified to fix some
-// serious problems. -- bwr
-//
-// Issues to watch for here:
-// - no destroying things from the ground since that includes corpses
-// which might be animated by monsters (butchering takes a few turns).
-// This code provides a quicker way to get rid of a corpse, but
-// the player has to be able to lift it first... something that was
-// a valid preventative method before (although this allow the player
-// to get rid of the mass on the next action).
-//
-// - artefacts can be destroyed
-//
-// - equipment cannot be destroyed... not only is this the more accurate
-// than testing for curse status (to prevent easy removal of cursed items),
-// but the original code would leave all the equiped items properties
-// (including weight) which would cause a bit of a mess to state.
-//
-// - no item does anything for just carrying it... if that changes then
-// this code will have to deal with that.
-//
-// - Do we want the player to be able to remove items from the game?
-// This would make things considerably easier to keep weapons (esp
-// those of distortion) from falling into the hands of monsters.
-// Right now the player has to carry them to a safe area, or otherwise
-// ingeniously dispose of them... do we care about this gameplay aspect?
-//
-// - Prompt for number to destroy?
-//
-void cmd_destroy_item( void )
-{
- int i;
- char str_pass[ ITEMNAME_SIZE ];
-
- // ask the item to destroy
- int item = prompt_invent_item( "Destroy which item? ", -1, true, false );
- if (item == PROMPT_ABORT)
- return;
-
- // Used to check for cursed... but that's not the real problem -- bwr
- for (i = 0; i < NUM_EQUIP; i++)
- {
- if (you.equip[i] == item)
- {
- mesclr( true );
- mpr( "You cannot destroy equipped items!" );
- return;
- }
- }
-
- // ask confirmation
- // quant_name(you.inv[item], you.inv[item].quantity, DESC_NOCAP_A, str_pass );
- item_name( you.inv[item], DESC_NOCAP_THE, str_pass );
- snprintf( info, INFO_SIZE, "Destroy %s? ", str_pass );
-
- if (yesno( info, true ))
- {
- //destroy it!!
- snprintf( info, INFO_SIZE, "You destroy %s.", str_pass );
- mpr( info );
- dec_inv_item_quantity( item, you.inv[item].quantity );
- burden_change();
- }
-}
-#endif
diff --git a/stone_soup/crawl-ref/source/items.h b/stone_soup/crawl-ref/source/items.h
deleted file mode 100644
index c4bca72527..0000000000
--- a/stone_soup/crawl-ref/source/items.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * File: items.cc
- * Summary: Misc (mostly) inventory related functions.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <2> 6/9/99 DML Autopickup
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef ITEMS_H
-#define ITEMS_H
-
-#include "externs.h"
-
-// used in acr.cc {dlb}:
-extern int autopickup_on;
-
-// used in initfile.cc {dlb}:
-extern long autopickups;
-
-bool is_valid_item( const item_def &item );
-
-bool dec_inv_item_quantity( int obj, int amount );
-bool dec_mitm_item_quantity( int obj, int amount );
-
-void inc_inv_item_quantity( int obj, int amount );
-void inc_mitm_item_quantity( int obj, int amount );
-
-void move_item_to_grid( int *const obj, int x, int y );
-void move_item_stack_to_grid( int x, int y, int targ_x, int targ_y );
-int move_item_to_player( int obj, int quant_got, bool quiet = false );
-bool items_stack( const item_def &item1, const item_def &item2 );
-
-void init_item( int item );
-
-// last updated 13mar2001 {gdl}
-/* ***********************************************************************
- * called from: dungeon files
- * *********************************************************************** */
-void link_items(void);
-
-// last updated 13mar2001 {gdl}
-/* ***********************************************************************
- * called from: files
- * *********************************************************************** */
-void fix_item_coordinates(void);
-
-// last updated: 19apr2001 {gdl}
-/* ***********************************************************************
- * called from: dungeon
- * *********************************************************************** */
-int cull_items(void);
-
-// last updated: 16oct2001 -- bwr
-int get_item_slot( int reserve = 50 );
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: beam - fight - files - food - items - misc - monstuff -
- * religion - spells2 - spells3 - spells4
- * *********************************************************************** */
-void unlink_item(int dest);
-void destroy_item(int dest);
-void destroy_item_stack( int x, int y );
-
-// last updated: 08jun2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void item_check(char keyin);
-
-
-// last updated: 08jun2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void pickup(void);
-
-
-// last updated 08jun2000 {dlb}
-/* ***********************************************************************
- * called from: beam - items - transfor
- * *********************************************************************** */
-bool copy_item_to_grid( const item_def &item, int x_plos, int y_plos,
- int quant_drop = -1, // item.quantity by default
- bool mark_dropped = false);
-
-// last updated Oct 15, 2000 -- bwr
-/* ***********************************************************************
- * called from: spells4.cc
- * *********************************************************************** */
-bool move_top_item( int src_x, int src_y, int dest_x, int dest_y );
-
-// last updated: 08jun2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void drop(void);
-
-
-// last updated: 08jun2000 {dlb}
-/* ***********************************************************************
- * called from: files - items
- * *********************************************************************** */
-void update_corpses(double elapsedTime);
-void update_level(double elapsedTime);
-
-
-// last updated: 08jun2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void handle_time( long time_delta );
-
-// last updated: 08jun2000 {dlb}
-/* ***********************************************************************
- * called from: command food item_use shopping spl-book transfor
- * *********************************************************************** */
-int inv_count(void);
-
-void cmd_destroy_item( void );
-
-bool pickup_single_item(int link, int qty);
-
-bool drop_item( int item_dropped, int quant_drop );
-
-int get_equip_slot(const item_def *item);
-
-void origin_set(int x, int y);
-void origin_set_monster(item_def &item, const monsters *monster);
-void origin_freeze(item_def &item, int x, int y);
-bool origin_known(const item_def &item);
-bool origin_describable(const item_def &item);
-std::string origin_desc(const item_def &item);
-void origin_purchased(item_def &item);
-void origin_acquired(item_def &item, int agent);
-void origin_set_startequip(item_def &item);
-void origin_set_unknown(item_def &item);
-void origin_set_inventory( void (*oset)(item_def &item) );
-
-#endif
diff --git a/stone_soup/crawl-ref/source/lev-pand.cc b/stone_soup/crawl-ref/source/lev-pand.cc
deleted file mode 100644
index a2fadad876..0000000000
--- a/stone_soup/crawl-ref/source/lev-pand.cc
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * File: lev-pand.cc
- * Summary: Functions used in Pandemonium.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "lev-pand.h"
-
-#include "externs.h"
-
-#include "monplace.h"
-#include "mon-pick.h"
-#include "stuff.h"
-
-void init_pandemonium(void)
-{
- int pc = 0;
- struct monsters *monster = 0; // NULL
-
- for (pc = 0; pc < MAX_MONSTERS; pc++)
- {
- monster = &menv[pc];
-
- // Looks for unique demons and sets appropriate lists of demons.
- // NB - also sets the level colours.
- if (monster->type == MONS_MNOLEG)
- {
- env.mons_alloc[0] = MONS_ABOMINATION_SMALL;
- env.mons_alloc[1] = MONS_ABOMINATION_SMALL;
- env.mons_alloc[2] = MONS_ABOMINATION_SMALL;
- env.mons_alloc[3] = MONS_ABOMINATION_LARGE;
- env.mons_alloc[4] = MONS_NEQOXEC;
- env.mons_alloc[5] = MONS_MIDGE;
- env.mons_alloc[6] = MONS_NEQOXEC;
- env.mons_alloc[7] = MONS_BLUE_DEATH;
- env.mons_alloc[8] = MONS_BALRUG;
- env.mons_alloc[9] = MONS_LEMURE;
- return;
- }
-
- if (monster->type == MONS_LOM_LOBON)
- {
- env.mons_alloc[0] = MONS_HELLWING;
- env.mons_alloc[1] = MONS_SMOKE_DEMON;
- env.mons_alloc[2] = MONS_SMOKE_DEMON;
- env.mons_alloc[3] = MONS_YNOXINUL;
- env.mons_alloc[4] = MONS_GREEN_DEATH;
- env.mons_alloc[5] = MONS_BLUE_DEATH;
- env.mons_alloc[6] = MONS_SMOKE_DEMON;
- env.mons_alloc[7] = MONS_HELLWING;
- env.mons_alloc[8] = MONS_WHITE_IMP;
- env.mons_alloc[9] = MONS_HELLWING;
- return;
- }
-
- if (monster->type == MONS_CEREBOV)
- {
- env.mons_alloc[0] = MONS_EFREET;
- env.mons_alloc[1] = MONS_ABOMINATION_SMALL;
- env.mons_alloc[2] = MONS_ORANGE_DEMON;
- env.mons_alloc[3] = MONS_ORANGE_DEMON;
- env.mons_alloc[4] = MONS_NEQOXEC;
- env.mons_alloc[5] = MONS_LEMURE;
- env.mons_alloc[6] = MONS_ORANGE_DEMON;
- env.mons_alloc[7] = MONS_YNOXINUL;
- env.mons_alloc[8] = MONS_BALRUG;
- env.mons_alloc[9] = MONS_BALRUG;
- return;
- }
-
- if (monster->type == MONS_GLOORX_VLOQ)
- {
- env.mons_alloc[0] = MONS_SKELETON_SMALL;
- env.mons_alloc[1] = MONS_SKELETON_SMALL;
- env.mons_alloc[2] = MONS_SKELETON_LARGE;
- env.mons_alloc[3] = MONS_WHITE_IMP;
- env.mons_alloc[4] = MONS_CACODEMON;
- env.mons_alloc[5] = MONS_HELLWING;
- env.mons_alloc[6] = MONS_SMOKE_DEMON;
- env.mons_alloc[7] = MONS_EXECUTIONER;
- env.mons_alloc[8] = MONS_EXECUTIONER;
- env.mons_alloc[9] = MONS_EXECUTIONER;
- return;
- }
- }
-
-// colour of monster 9 is colour of floor, 8 is colour of rock
-// IIRC, BLACK is set to LIGHTGRAY
-
- for (pc = 0; pc < 10; pc++)
- {
- switch (random2(17))
- {
- case 0: case 10: env.mons_alloc[pc] = MONS_WHITE_IMP; break;
- case 1: case 11: env.mons_alloc[pc] = MONS_LEMURE; break;
- case 2: case 12: env.mons_alloc[pc] = MONS_UFETUBUS; break;
- case 3: case 13: env.mons_alloc[pc] = MONS_MANES; break;
- case 4: case 14: env.mons_alloc[pc] = MONS_MIDGE; break;
- case 5: env.mons_alloc[pc] = MONS_NEQOXEC; break;
- case 6: env.mons_alloc[pc] = MONS_ORANGE_DEMON; break;
- case 7: env.mons_alloc[pc] = MONS_HELLWING; break;
- case 8: env.mons_alloc[pc] = MONS_SMOKE_DEMON; break;
- case 9: env.mons_alloc[pc] = MONS_YNOXINUL; break;
- case 15: env.mons_alloc[pc] = MONS_ABOMINATION_SMALL; break;
- case 16: env.mons_alloc[pc] = MONS_ABOMINATION_LARGE; break;
- }
-
- if (one_chance_in(10))
- env.mons_alloc[pc] = MONS_HELLION + random2(10);
-
- if (one_chance_in(30))
- env.mons_alloc[pc] = MONS_RED_DEVIL;
-
- if (one_chance_in(30))
- env.mons_alloc[pc] = MONS_IMP;
-
- if (one_chance_in(20))
- env.mons_alloc[pc] = MONS_DEMONIC_CRAWLER + random2(5);
- }
-
- if (one_chance_in(8))
- env.mons_alloc[7] = MONS_EXECUTIONER + random2(5);
-
- if (one_chance_in(5))
- env.mons_alloc[8] = MONS_EXECUTIONER + random2(5);
-
- if (one_chance_in(3))
- env.mons_alloc[9] = MONS_EXECUTIONER + random2(5);
-
- if (one_chance_in(10))
- env.mons_alloc[7 + random2(3)] = MONS_FIEND;
-
- if (one_chance_in(10))
- env.mons_alloc[7 + random2(3)] = MONS_ICE_FIEND;
-
- if (one_chance_in(10))
- env.mons_alloc[7 + random2(3)] = MONS_SHADOW_FIEND;
-
- if (one_chance_in(10))
- env.mons_alloc[7 + random2(3)] = MONS_PIT_FIEND;
-
- // set at least some specific monsters for the special levels - this
- // can also be used to set some colours
-} // end init_pandemonium()
-
-void pandemonium_mons(void)
-{
- // must leave allowance for monsters rare on pandemonium (eg wizards etc)
- int pan_mons = env.mons_alloc[random2(10)];
-
- if (one_chance_in(40))
- {
- do
- {
- pan_mons = random2(NUM_MONSTERS); // was random2(400) {dlb}
- }
- while (!mons_pan(pan_mons));
- }
- mons_place(pan_mons, BEH_HOSTILE, MHITNOT, false, 50,50,
- LEVEL_PANDEMONIUM);
-} // end pandemonium_mons()
diff --git a/stone_soup/crawl-ref/source/lev-pand.h b/stone_soup/crawl-ref/source/lev-pand.h
deleted file mode 100644
index 6868ad4bf1..0000000000
--- a/stone_soup/crawl-ref/source/lev-pand.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * File: lev-pand.h
- * Summary: Functions used in Pandemonium.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef LEVPAND_H
-#define LEVPAND_H
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: abyss - misc
- * *********************************************************************** */
-void init_pandemonium(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - misc
- * *********************************************************************** */
-void pandemonium_mons(void);
-
-
-#endif
diff --git a/stone_soup/crawl-ref/source/libemx.cc b/stone_soup/crawl-ref/source/libemx.cc
deleted file mode 100644
index 5634adbef8..0000000000
--- a/stone_soup/crawl-ref/source/libemx.cc
+++ /dev/null
@@ -1,233 +0,0 @@
-#include <stdio.h>
-#include <stdarg.h>
-#include <emx/syscalls.h>
-#include <sys/video.h>
-
-#include "libemx.h"
-
-
-static int cursor_start = 0, cursor_end = 0;
-static int gx = 0, gy = 0, gxx = 79, gyy = 24;
-static char buf[4096];
-
-
-
-
-void init_emx()
-{
- v_init();
- v_getctype(&cursor_start, &cursor_end);
-}
-
-
-
-
-void deinit_emx()
-{
- // nothing to do
-}
-
-
-
-
-void _setcursortype(int curstype)
-{
- if ( curstype == _NOCURSOR )
- v_hidecursor();
- else
- v_ctype(cursor_start, cursor_end);
-}
-
-
-
-
-void clrscr()
-{
- if ( (gx == 0) && (gy == 0) && (gxx == 79) && (gyy == 24) )
- {
- v_clear();
- v_gotoxy(0, 0);
- }
- else
- {
- for (int i = gy; i <= gyy; ++i)
- {
- v_gotoxy(gx, i);
- v_putn(' ', gxx - gx + 1);
- }
- v_gotoxy(gx, gy);
- }
-}
-
-
-
-
-void gotoxy(int x, int y)
-{
- v_gotoxy(x - 1 + gx, y - 1 + gy);
-}
-
-
-
-
-void textcolor(int c)
-{
- v_attrib(c);
-}
-
-
-
-
-static void cprintf_aux(const char *s)
-{
- char *ptr = buf;
-
- while (*s)
- {
- if ( *s == '\n' )
- {
- *ptr = 0;
- v_puts(buf);
- int x, y;
-
- v_getxy(&x, &y);
- if ( y != 24 )
- v_gotoxy(gx, y + 1);
- else
- v_putc('\n');
-
- ptr = buf;
- }
- else if ( *s != '\r' )
- *ptr++ = *s;
-
- ++s;
- }
-
- *ptr = 0;
- v_puts(buf);
-
-}
-
-void cprintf(const char *format, ...)
-{
- va_list argp;
- char buffer[4096]; // one could hope it's enough
-
- va_start( argp, format );
-
- vsprintf(buffer, format, argp);
- cprintf_aux(buffer);
-
- va_end(argp);
-}
-
-void puttext(int x, int y, int lx, int ly, unsigned const char *buf)
-{
- puttext(x, y, lx, ly, (const char *) buf);
-}
-
-
-
-
-void puttext(int x, int y, int lx, int ly, const char *buf)
-{
- int count = (lx - x + 1);
-
- for (int i = y - 1; i < ly; ++i)
- {
- v_putline(buf + 2 * count * i, x - 1, i, count);
- }
-}
-
-
-
-
-void gettext(int x, int y, int lx, int ly, unsigned char *buf)
-{
- gettext(x, y, lx, ly, (char *) buf);
-}
-
-
-
-
-void gettext(int x, int y, int lx, int ly, char *buf)
-{
- int count = (lx - x + 1);
-
- for (int i = y - 1; i < ly; ++i)
- {
- v_getline(buf + 2 * count * i, x - 1, i, count);
- }
-}
-
-
-
-
-void window(int x, int y, int lx, int ly)
-{
- gx = x - 1;
- gy = y - 1;
- gxx = lx - 1;
- gyy = ly - 1;
-}
-
-
-
-
-int wherex()
-{
- int x, y;
-
- v_getxy(&x, &y);
-
- return x + 1 - gx;
-}
-
-
-
-
-int wherey()
-{
- int x, y;
-
- v_getxy(&x, &y);
-
- return y + 1 - gy;
-}
-
-
-
-
-void putch(char c)
-{
- v_putc(c);
-}
-
-
-
-
-int kbhit()
-{
- return 0;
-}
-
-
-
-
-void delay(int ms)
-{
- __sleep2(ms);
-}
-
-
-
-
-void textbackground(int c)
-{
- if ( c != 0 )
- {
- fprintf(stderr, "bad background=%d", c);
- exit(1);
- }
-}
diff --git a/stone_soup/crawl-ref/source/libemx.h b/stone_soup/crawl-ref/source/libemx.h
deleted file mode 100644
index ac33612284..0000000000
--- a/stone_soup/crawl-ref/source/libemx.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef LIBEMX_H
-#define LIBEMX_H
-#ifndef __LIBEMX_C__
-
-
-#include <stdlib.h>
-#include <conio.h>
-
-#define itoa _itoa
-
-
-#define _NORMALCURSOR 1
-#define _NOCURSOR 0
-
-
-void init_emx();
-void deinit_emx();
-void _setcursortype(int curstype);
-void clrscr();
-void gotoxy(int x, int y);
-void textcolor(int c);
-void cprintf (const char *format, ...);
-
-void puttext(int x, int y, int lx, int ly, const char *buf);
-void puttext(int x, int y, int lx, int ly, unsigned const char *buf);
-void gettext(int x, int y, int lx, int ly, char *buf);
-void gettext(int x, int y, int lx, int ly, unsigned char *buf);
-void window(int x, int y, int lx, int ly);
-int wherex();
-int wherey();
-void putch(char c);
-int kbhit();
-void delay(int ms);
-void textbackground(int c);
-
-
-#endif // __LIBEMX_C__
-#endif
diff --git a/stone_soup/crawl-ref/source/libmac.cc b/stone_soup/crawl-ref/source/libmac.cc
deleted file mode 100644
index 35e2055344..0000000000
--- a/stone_soup/crawl-ref/source/libmac.cc
+++ /dev/null
@@ -1,2116 +0,0 @@
-/*
- * File: libmac.cc
- * Summary: Mac specific routines used by Crawl.
- * Written by: Jesse Jones (jesjones@mindspring.com)
- *
- * Modified for Crawl Reference by $Author$ on $Date$
- *
- * Change History (most recent first):
- *
- * <5> 5/25/02 JDJ Rewrote to use Carbon Events and Mach-O.
- * <4> 9/25/99 CDL linuxlib -> liblinux
- *
- * <3> 5/30/99 JDJ Quit only pops up save changes dialog if game_has_started is true.
- * <2> 4/24/99 JDJ HandleMenu calls save_game instead of returning a 'S'
- * character ('S' now prompts). kTermHeight is now initialized
- * to NUMBER_OF_LINES.
- * <2> 4/24/99 JDJ getstr only adds printable characters to the buffer.
- * <1> 3/23/99 JDJ Created
- */
-
-#include "AppHdr.h"
-#include "libmac.h"
-
-#if macintosh
-
-#include <cstdarg>
-#include <ctype.h>
-#include <string.h>
-#include <vector.h>
-
-#include <CarbonCore/StringCompare.h>
-#include <HIToolbox/CarbonEvents.h>
-#include <HIToolbox/Dialogs.h>
-
-#include "debug.h"
-#include "defines.h"
-#include "files.h"
-#include "MacString.h"
-#include "version.h"
-
-
-//-----------------------------------
-// Forward References
-//
-class CApplication;
-
-
-//-----------------------------------
-// Constants
-//
-const int kTermWidth = 80;
-const int kTermHeight = MAC_NUMBER_OF_LINES;
-
-const int kLeftArrowKey = 0x7B;
-const int kUpArrowKey = 0x7E;
-const int kRightArrowKey = 0x7C;
-const int kDownArrowKey = 0x7D;
-
-const int kNumPad0Key = 0x52;
-const int kNumPad1Key = 0x53;
-const int kNumPad2Key = 0x54;
-const int kNumPad3Key = 0x55;
-const int kNumPad4Key = 0x56;
-const int kNumPad5Key = 0x57;
-const int kNumPad6Key = 0x58;
-const int kNumPad7Key = 0x59;
-const int kNumPad8Key = 0x5B;
-const int kNumPad9Key = 0x5C;
-
-const int kNumPadMultKey = 0x43;
-const int kNumPadAddKey = 0x45;
-const int kNumPadSubKey = 0x4E;
-const int kNumPadDecimalKey = 0x41;
-const int kNumPadDivideKey = 0x4B;
-
-const char kEnterChar = 0x03;
-const short kEscapeKey = 0x35;
-const char kCheckMarkChar = 0x12;
-const char kNoMarkChar = 0x00;
-
-const short kSaveBtn = 1;
-const short kCancelBtn = 2;
-const short kDontSaveBtn = 3;
-
-const Rect kBigRect = {0, 0, 32000, 32000};
-
-const RGBColor kBlack = {0, 0, 0};
-const RGBColor kWhite = {65535, 65535, 65535};
-
-enum EAskSaveResult
-{
- kSaveChanges = 1,
- kCancelSave = 2,
- kDontSave = 3
-};
-
-
-//-----------------------------------
-// Variables
-//
-static CApplication* sApp = NULL;
-static CTabHandle sColors = NULL;
-
-static bool sInDialog = false;
-
-extern bool game_has_started;
-
-
-// ========================================================================
-// Internal Functions
-// ========================================================================
-
-//---------------------------------------------------------------
-//
-// CreateSpec
-//
-//---------------------------------------------------------------
-static EventTypeSpec CreateSpec(UInt32 c, UInt32 k)
-{
- EventTypeSpec spec;
-
- spec.eventClass = c;
- spec.eventKind = k;
-
- return spec;
-}
-
-
-//---------------------------------------------------------------
-//
-// DrawChar
-//
-//---------------------------------------------------------------
-inline void DrawChar(short x, short y, char ch)
-{
- MoveTo(x, y);
- DrawText(&ch, 0, 1);
-}
-
-
-//---------------------------------------------------------------
-//
-// ThrowIf
-//
-//---------------------------------------------------------------
-static void ThrowIf(bool predicate, const std::string& text)
-{
- if (predicate)
- throw std::runtime_error(text);
-}
-
-
-//---------------------------------------------------------------
-//
-// ThrowIfOSErr
-//
-//---------------------------------------------------------------
-static void ThrowIfOSErr(OSErr err, const std::string& text)
-{
- if (err != noErr)
- {
- char buffer[256];
- sprintf(buffer, "%s (%d)", text.c_str(), err);
-
- throw std::runtime_error(buffer);
- }
-}
-
-
-//---------------------------------------------------------------
-//
-// FlashButton
-//
-//---------------------------------------------------------------
-static void FlashButton(DialogPtr dialog, short item)
-{
- ASSERT(dialog != nil);
- ASSERT(item >= 1 && item <= CountDITL(dialog));
-
- ControlRef control;
- (void) GetDialogItemAsControl(dialog, item, &control);
-
- HiliteControl(control, 1);
-// QDAddRectToDirtyRegion(GetDialogPort(dialog), &kBigRect);
- QDFlushPortBuffer(GetDialogPort(dialog), NULL);
-
- unsigned long ticks;
- Delay(8, &ticks);
-
- HiliteControl(control, 0);
-// QDAddRectToDirtyRegion(GetDialogPort(dialog), &kBigRect);
- QDFlushPortBuffer(GetDialogPort(dialog), NULL);
-}
-
-
-//---------------------------------------------------------------
-//
-// WarnUser
-//
-// Pops up an error dialog.
-//
-//---------------------------------------------------------------
-static void WarnUser(const char* message)
-{
- int len = strlen(message);
- if (len > 250)
- len = 250;
-
- Str255 text;
- for (int i = 0; i < len; i++)
- text[i + 1] = message[i];
- text[0] = len;
-
- AlertStdAlertParamRec params;
- params.movable = true;
- params.helpButton = false;
- params.filterProc = NULL;
- params.defaultText = (StringPtr) -1L; // use default (ie "OK")
- params.cancelText = NULL;
- params.otherText = NULL;
- params.defaultButton = 1;
- params.cancelButton = 0;
- params.position = kWindowAlertPositionParentWindowScreen;
-
- short item;
- sInDialog = true;
- OSErr err = StandardAlert(kAlertCautionAlert, text, "\p", &params, &item);
- ASSERT(err == noErr); // seems kind of pointless to throw
- sInDialog = false;
-}
-
-
-//---------------------------------------------------------------
-//
-// SaveChangesFilter
-//
-//---------------------------------------------------------------
-static pascal Boolean SaveChangesFilter(DialogPtr dptr, EventRecord* event, short* item)
-{
- bool handled = false;
-
- if (event->what == keyDown)
- {
- char ch = (char) toupper((char) (event->message & charCodeMask));
- short key = (short) ((event->message & keyCodeMask) >> 8);
-
- if (ch == 'S')
- {
- *item = 1;
- handled = true;
- }
- else if (ch == 'D')
- {
- *item = 3;
- handled = true;
- }
- else if (ch == '\r' || ch == kEnterChar)
- {
- *item = 1;
- handled = true;
- }
- else if (key == kEscapeKey)
- {
- *item = 2;
- handled = true;
- }
-
- if (handled)
- FlashButton(dptr, *item);
- }
-
- return handled;
-}
-
-
-//---------------------------------------------------------------
-//
-// AskSaveChanges
-//
-//---------------------------------------------------------------
-static EAskSaveResult AskSaveChanges()
-{
-#if 1
- static ModalFilterUPP filterProc = NewModalFilterUPP(SaveChangesFilter);
-
- AlertStdAlertParamRec params;
- params.movable = true;
- params.helpButton = false;
- params.filterProc = filterProc;
- params.defaultText = "\pSave";
- params.cancelText = "\pCancel";
- params.otherText = "\pDon't Save";
- params.defaultButton = kSaveBtn;
- params.cancelButton = kCancelBtn;
- params.position = kWindowAlertPositionParentWindowScreen;
-
- short item = kSaveBtn;
- sInDialog = true;
- OSErr err = StandardAlert(kAlertStopAlert, "\pDo you want to save your game before quitting?", "\p", &params, &item);
- ASSERT(err == noErr); // seems kind of pointless to throw
- sInDialog = false;
-
- EAskSaveResult result;
- if (item == kSaveBtn)
- result = kSaveChanges;
- else if (item == kDontSaveBtn)
- result = kDontSave;
- else
- result = kCancelSave;
-
- return result;
-
-#else
- NavDialogOptions options;
- OSStatus err = NavGetDefaultDialogOptions(&options);
- ASSERT(err == noErr); // seems kind of pointless to throw
-
- NavAskSaveChangesResult reply = kSaveChanges;
- if (err == noErr)
- {
- std::string name = "foobar";
- UInt32 length = std::min(name.size(), sizeof(options.savedFileName) - 1);
- BlockMoveData(name.c_str(), options.savedFileName + 1, length);
- options.savedFileName[0] = length;
-
- err = NavAskSaveChanges(&options,
- action,
- &reply,
- NULL,
- 0UL);
- ASSERT(err == noErr); // seems kind of pointless to throw
- }
-
- return (EAskSaveResult) reply;
-#endif
-}
-
-
-//---------------------------------------------------------------
-//
-// ConvertColor
-//
-//---------------------------------------------------------------
-static RGBColor ConvertColor(int c)
-{
- ASSERT(c >= 0);
- ASSERT(c < 16);
-
- RGBColor color;
-
- if (c == BLACK)
- color = (**sColors).ctTable[15].rgb; // QD likes black and white swapped from DOS indices
-
- else if (c == WHITE)
- color = (**sColors).ctTable[0].rgb;
- else
- color = (**sColors).ctTable[c].rgb;
-
- return color;
-}
-
-#if __MWERKS__
-#pragma mark -
-#endif
-
-// ============================================================================
-// class CApplication
-// ============================================================================
-class CApplication {
-
-//-----------------------------------
-// Initialization/Destruction
-//
-public:
- ~CApplication();
- CApplication();
-
-//-----------------------------------
-// API
-//
-public:
- void Quit();
-
- char GetChar();
- // Block until a key is pressed.
-
- bool PeekChar();
- // Return true if a key event is on the event queue.
-
- void Clear();
- void SetCursor(int x, int y);
- Point GetCursor() const {return mCursor;}
- void SetChar(unsigned char ch);
- void Print(const char* buffer);
- void ShowCursor(bool show) {mShowCursor = show;}
-
- void SetForeColor(const RGBColor& color);
- void SetBackColor(const RGBColor& color);
-
- void SetFont(const unsigned char *name) {this->DoSetFont(name, mPointSize);}
- void SetFontSize(int size) {this->DoSetFont(mFontName, size);}
-
-//-----------------------------------
-// Internal Types
-//
-private:
- struct SCell {
- unsigned char ch;
- RGBColor color;
-
- SCell()
- {
- ch = ' ';
- color.red = color.green = color.blue = 65535;
- }
- };
-
- typedef vector<SCell> Line;
-
-//-----------------------------------
-// Internal API
-//
-private:
- void DoAbout();
- void DoClearToEOL();
- void DoDrawCell(const Rect& area, const SCell& cell);
- OSStatus DoEnableCommand(MenuRef menuH, MenuCommand command, MenuItemIndex index);
- OSStatus DoHandleCommand(MenuCommand command);
- void DoInitMenus();
- void DoInitWindows();
- char DoMungeChar(char inChar, UInt32 inKey, UInt32 modifiers) const;
- OSStatus DoOpenMenu(MenuRef menuH);
- void DoReadPrefs();
- void DoRender();
- void DoScroll();
- void DoSetChar(unsigned char ch);
- void DoSetFont(const unsigned char* name, int size);
- void DoWritePrefs();
-
- static pascal OSStatus DoKeyDown(EventHandlerCallRef handler, EventRef event, void* refCon);
- static pascal OSStatus DoMenuEvent(EventHandlerCallRef handler, EventRef event, void* refCon);
- static pascal OSErr DoQuit(const AppleEvent* event, AppleEvent* reply, SInt32 refCon);
- static pascal OSStatus DoWindowEvent(EventHandlerCallRef handler, EventRef event, void* refCon);
-
-//-----------------------------------
-// Member Data
-//
-private:
- WindowRef mWindow;
- vector<Line> mLines;
- char mChar;
-
- Point mCursor;
- bool mShowCursor;
-
- RGBColor mForeColor;
- RGBColor mBackColor;
-
- Str255 mFontName;
- int mPointSize;
- UInt32 mNumFonts;
- MenuRef mFontMenu;
-
- short mFontNum;
- int mAscent;
- int mCellHeight;
- int mCellWidth;
-};
-
-//---------------------------------------------------------------
-//
-// CApplication::~CApplication
-//
-//---------------------------------------------------------------
-CApplication::~CApplication()
-{
- this->DoWritePrefs();
-
- DisposeWindow(mWindow);
-}
-
-
-//---------------------------------------------------------------
-//
-// CApplication::CApplication
-//
-//---------------------------------------------------------------
-CApplication::CApplication()
-{
- InitCursor();
-
- mCursor.h = 0;
- mCursor.v = 0;
- mShowCursor = false;
- mChar = 0;
-
- mNumFonts = 0;
- mFontName[0] = '\0';
- mFontNum = -2;
- mPointSize = 0;
- mAscent = 0;
- mCellHeight = 0;
- mCellWidth = 0;
- mFontMenu = NULL;
-
- mForeColor = kWhite;
- mBackColor = kBlack;
-
- try
- {
- // install a handler for the quit apple event
- OSStatus err = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP(DoQuit), 0, false);
- ThrowIfOSErr(err, "Couldn't install the quit handler!");
-
- // install a custom key handler
- std::vector<EventTypeSpec> specs;
- specs.push_back(CreateSpec(kEventClassKeyboard, kEventRawKeyDown));
- specs.push_back(CreateSpec(kEventClassKeyboard, kEventRawKeyRepeat));
-
- err = InstallApplicationEventHandler(NewEventHandlerUPP(DoKeyDown), specs.size(), &specs[0], this, NULL);
- ThrowIfOSErr(err, "Couldn't install the key handler!");
-
- // create the window
- this->DoInitWindows();
-
- // init the menus
- this->DoInitMenus();
-
- // update some state
- this->DoReadPrefs();
-
- this->Clear();
-
- // show the window
- ShowWindow(mWindow);
- }
- catch (const std::exception& e)
- {
- WarnUser(e.what());
- ExitToShell();
- }
- catch (...)
- {
- WarnUser("Couldn't initialize the application.");
- ExitToShell();
- }
-}
-
-
-//---------------------------------------------------------------
-//
-// CApplication::Quit
-//
-//---------------------------------------------------------------
-void CApplication::Quit()
-{
- if (game_has_started)
- {
- EAskSaveResult answer = AskSaveChanges();
-
- if (answer == kSaveChanges)
- {
- save_game(true);
- }
- else if (answer == kDontSave)
- {
- deinit_mac();
- ExitToShell();
- }
- }
- else
- {
- deinit_mac();
- ExitToShell();
- }
-}
-
-
-//---------------------------------------------------------------
-//
-// CApplication::Clear
-//
-//---------------------------------------------------------------
-void CApplication::Clear()
-{
- mLines.resize(kTermHeight);
-
- for (int y = 0; y < mLines.size(); ++y)
- {
- Line& line = mLines[y];
- line.resize(kTermWidth);
-
- for (int x = 0; x < line.size(); ++x)
- {
- SCell& cell = line[x];
-
- cell.ch = ' ';
- cell.color = kWhite;
- }
- }
-
- mCursor.h = 0;
- mCursor.v = 0;
-
- (void) InvalWindowRect(mWindow, &kBigRect);
-}
-
-
-//---------------------------------------------------------------
-//
-// CApplication::SetCursor
-//
-//---------------------------------------------------------------
-void CApplication::SetCursor(int x, int y)
-{
- ASSERT(x >= 0);
- ASSERT(x < kTermWidth);
- ASSERT(y >= 0);
- ASSERT(y < kTermHeight);
-
- if (x != mCursor.h || y != mCursor.v)
- {
- if (mShowCursor)
- {
- Rect area;
- area.top = mCursor.v * mCellHeight;
- area.bottom = area.top + mCellHeight;
- area.left = mCursor.h * mCellWidth;
- area.right = area.left + mCellWidth;
-
- (void) InvalWindowRect(mWindow, &area);
- }
-
- mCursor.h = x;
- mCursor.v = y;
-
- if (mShowCursor)
- {
- Rect area;
- area.top = mCursor.v * mCellHeight;
- area.bottom = area.top + mCellHeight;
- area.left = mCursor.h * mCellWidth;
- area.right = area.left + mCellWidth;
-
- (void) InvalWindowRect(mWindow, &area);
- }
- }
-}
-
-
-//---------------------------------------------------------------
-//
-// CApplication::SetChar
-//
-//---------------------------------------------------------------
-void CApplication::SetChar(unsigned char ch)
-{
- ASSERT(ch != '\t');
- ASSERT(mLines.size() == kTermHeight);
-
- const int TABSIZE = 8;
-
- int x = mCursor.h; // this is from the ncurses source
- int y = mCursor.v;
-
- switch (ch) {
- case '\t':
- x += (TABSIZE - (x % TABSIZE));
-
- // Space-fill the tab on the bottom line so that we'll get the
- // "correct" cursor position.
- if (x < kTermWidth)
- {
- char blank = ' ';
-
- while (mCursor.h < x)
- this->DoSetChar(blank);
- break;
-
- }
- else
- {
- this->DoClearToEOL();
- if (++y >= kTermHeight)
- {
- x = kTermWidth - 1;
- y--;
- this->DoScroll();
- x = 0;
- }
- else
- x = 0;
- }
- break;
-
-#if 1
- case '\n':
- case '\r':
- this->DoClearToEOL();
- if (++y >= kTermHeight)
- {
- y--;
- this->DoScroll();
- }
- x = 0;
- break;
-
-#else
- case '\n':
- this->DoClearToEOL();
- if (++y >= kTermHeight)
- {
- y--;
- this->DoScroll();
- }
- /* FALLTHRU */
-
- case '\r':
- x = 0;
- break;
-#endif
-
- case '\b':
- if (x == 0)
- return;
- mCursor.h--;
- this->DoSetChar(' ');
- x--;
- break;
-
- case 159:
- case 176:
- case 177:
- case 220:
- case 239:
- case 240:
- case 247:
- case 249:
- case 250:
- case 206:
- case 254:
- this->DoSetChar(ch);
- return;
- break;
-
- default:
- if (ch == '\0')
- ch = ' ';
-
-// ASSERT(ch >= ' ');
-// ASSERT(ch <= '~');
-
- if (ch >= ' ' && ch <= '~')
- this->DoSetChar(ch);
- else
- this->DoSetChar('À');
- return;
- }
-
- mCursor.h = x;
- mCursor.v = y;
-}
-
-
-//---------------------------------------------------------------
-//
-// CApplication::Print
-//
-//---------------------------------------------------------------
-void CApplication::Print(const char* buffer)
-{
- ASSERT(buffer != NULL);
-
- const char* p = buffer;
-
- while (*p != '\0')
- {
- char ch = *p++;
-
- this->SetChar(ch);
- }
-}
-
-
-//---------------------------------------------------------------
-//
-// CApplication::SetForeColor
-//
-//---------------------------------------------------------------
-void CApplication::SetForeColor(const RGBColor & color)
-{
- if (color.red != mForeColor.red || color.green != mForeColor.green || color.blue != mForeColor.blue)
- {
- mForeColor = color;
-
- (void) InvalWindowRect(mWindow, &kBigRect);
- }
-}
-
-
-//---------------------------------------------------------------
-//
-// CApplication::SetBackColor
-//
-//---------------------------------------------------------------
-void CApplication::SetBackColor(const RGBColor & color)
-{
- if (color.red != mBackColor.red || color.green != mBackColor.green || color.blue != mBackColor.blue)
- {
- mBackColor = color;
-
- (void) InvalWindowRect(mWindow, &kBigRect);
- }
-}
-
-
-//---------------------------------------------------------------
-//
-// CApplication::GetChar
-//
-//---------------------------------------------------------------
-char CApplication::GetChar()
-{
- mChar = 0;
- RunApplicationEventLoop();
-
- (void) InvalWindowRect(mWindow, &kBigRect);
-
- return mChar;
-}
-
-
-//---------------------------------------------------------------
-//
-// CApplication::PeekChar
-//
-//---------------------------------------------------------------
-bool CApplication::PeekChar()
-{
- EventTypeSpec specs[2];
- specs[0] = CreateSpec(kEventClassKeyboard, kEventRawKeyDown);
- specs[1] = CreateSpec(kEventClassKeyboard, kEventRawKeyRepeat);
-
- EventRef event = NULL;
- OSStatus err = ReceiveNextEvent(2, specs, kEventDurationNoWait, false, &event);
-
- return err == noErr;
-}
-
-#if __MWERKS__
-#pragma mark ~
-#endif
-
-//---------------------------------------------------------------
-//
-// CApplication::DoAbout
-//
-//---------------------------------------------------------------
-void CApplication::DoAbout()
-{
- AlertStdAlertParamRec params;
- params.movable = true;
- params.helpButton = false;
- params.filterProc = NULL;
- params.defaultText = (StringPtr) -1L; // use default (ie "OK") VERSION
- params.cancelText = NULL;
- params.otherText = NULL;
- params.defaultButton = 1;
- params.cancelButton = 0;
- params.position = kWindowAlertPositionParentWindowScreen;
-
- short item;
- sInDialog = true;
- OSErr err = StandardAlert(kAlertNoteAlert, "\p Crawl " VERSION, "\p© 1997-2002 by Linley Henzell\nMac Port by Jesse Jones", &params, &item);
- ASSERT(err == noErr); // seems kind of pointless to throw
- sInDialog = false;
-}
-
-
-//---------------------------------------------------------------
-//
-// CApplication::DoClearToEOL
-//
-//---------------------------------------------------------------
-void CApplication::DoClearToEOL()
-{
- ASSERT(mCursor.h < kTermWidth);
- ASSERT(mCursor.v < kTermHeight);
-
- Line& line = mLines[mCursor.v];
- for (int x = mCursor.h; x < kTermWidth; ++x)
- {
- SCell& cell = line[x];
- cell.ch = ' ';
- }
-
- Rect area;
- area.top = mCursor.v * mCellHeight;
- area.bottom = area.top + mCellHeight;
- area.left = mCursor.h * mCellWidth;
- area.right = 16000;
-
- (void) InvalWindowRect(mWindow, &kBigRect);
-}
-
-
-//---------------------------------------------------------------
-//
-// CApplication::DoDrawCell
-//
-//---------------------------------------------------------------
-void CApplication::DoDrawCell(const Rect& area, const SCell& cell)
-{
- RGBForeColor(&cell.color);
-
- switch (cell.ch) {
- case 159: // fountain
- DrawChar(area.left, area.top + mAscent, '´');
- break;
-
- case 177: // wall
- case 176:
- PaintRect(&area);
- break;
-
- case 247: // water/lava
- PaintRect(&area);
- break;
-
- case 249: // floor
- case 250: // undiscovered trap?
-// FillRect(&area, &qd.gray);
- DrawChar(area.left, area.top + mAscent, '.');
- break;
-
- case 206:
- case 254: // door
- {
- Rect temp = area;
- InsetRect(&temp, 2, 2);
- PaintRect(&temp);
- }
- break;
-
- case 220: // altar
- DrawChar(area.left, area.top + mAscent, 'Æ');
- break;
-
- case 239: // staircase to hell
- case 240: // branch staircase
- DrawChar(area.left, area.top + mAscent, '²');
- break;
-
- default:
- DrawChar(area.left, area.top + mAscent, cell.ch);
- }
-}
-
-
-//---------------------------------------------------------------
-//
-// CApplication::DoEnableCommand
-//
-//---------------------------------------------------------------
-OSStatus CApplication::DoEnableCommand(MenuRef menuH, MenuCommand command, MenuItemIndex index)
-{
- OSStatus err = noErr;
-
- if (command == 'Abut')
- {
- EnableMenuItem(menuH, index);
- }
- else if (command == 'Save')
- {
- if (game_has_started)
- EnableMenuItem(menuH, index);
- else
- DisableMenuItem(menuH, index);
- }
- else if (command >= 'Size' && command <= 'Size'+128)
- {
- if (mPointSize == command - 'Size')
- SetItemMark(menuH, index, kCheckMarkChar);
- else
- SetItemMark(menuH, index, kNoMarkChar);
- }
- else if (command >= 'Font' && command <= 'Font'+128)
- {
- Str255 name;
- GetMenuItemText(menuH, index, name);
-
- if (EqualString(mFontName, name, true, true))
- SetItemMark(menuH, index, kCheckMarkChar);
- else
- SetItemMark(menuH, index, noMark);
- }
- else
- err = eventNotHandledErr;
-
- return err;
-}
-
-
-//---------------------------------------------------------------
-//
-// CApplication::DoHandleCommand
-//
-//---------------------------------------------------------------
-OSStatus CApplication::DoHandleCommand(MenuCommand command)
-{
- OSStatus err = noErr;
-
- if (command == 'Abut')
- {
- this->DoAbout();
- }
- else if (command == 'Save')
- {
- save_game(false);
- }
- else if (command >= 'Size' && command <= 'Size'+128)
- {
- int size = command - 'Size';
-
- this->SetFontSize(size);
- }
- else if (command >= 'Font' && command <= 'Font'+128)
- {
- int index = command - 'Font';
-
- Str255 name;
- GetMenuItemText(mFontMenu, index, name);
-
- this->SetFont(name);
- }
- else if (command == kHICommandQuit)
- {
- this->Quit();
- }
- else
- err = eventNotHandledErr;
-
- return err;
-}
-
-
-//---------------------------------------------------------------
-//
-// CApplication::DoInitMenus
-//
-//---------------------------------------------------------------
-void CApplication::DoInitMenus()
-{
- const int kFileMenu = 257;
- const int kFontMenu = 258;
- const int kSizeMenu = 259;
-
- // add the About menu item
- MenuRef menuH = NewMenu(0, "\pð");
-
- OSStatus err = InsertMenuItemTextWithCFString(menuH, MacString("About Crawl"), 0, kMenuItemAttrIgnoreMeta, 'Abut');
- ThrowIfOSErr(err, "Couldn't add the about menu item!");
-
- InsertMenu(menuH, 0);
-
- // create the File menu
- err = CreateNewMenu(kFileMenu, kMenuAttrAutoDisable, &menuH);
- ThrowIfOSErr(err, "Couldn't create the file menu!");
-
- err = SetMenuTitleWithCFString(menuH, MacString("File"));
- ThrowIfOSErr(err, "Couldn't set the file menu name!");
-
- InsertMenu(menuH, 0);
-
- // add the File menu items
- err = AppendMenuItemTextWithCFString(menuH, MacString("Save"), kMenuItemAttrIgnoreMeta, 'Save', NULL);
- ThrowIfOSErr(err, "Couldn't add the save menu item!");
-
- err = SetMenuItemCommandKey(menuH, 1, false, 'S');
- ThrowIfOSErr(err, "Couldn't set the save menu item's command key!");
-
- // create the Font menu
- err = CreateNewMenu(kFontMenu, kMenuAttrAutoDisable, &mFontMenu);
- ThrowIfOSErr(err, "Couldn't create the font menu!");
-
- err = CreateStandardFontMenu(mFontMenu, 0, 0, kNilOptions, &mNumFonts);
- ThrowIfOSErr(err, "Couldn't initialize the font menu!");
-
- err = SetMenuTitleWithCFString(mFontMenu, MacString("Font"));
- ThrowIfOSErr(err, "Couldn't set the font menu name!");
-
- UInt16 numItems = CountMenuItems(mFontMenu);
- for (UInt16 index = 1; index <= numItems; ++index)
- {
- // set the font for each menu item so we're WYSIWYG
- Str255 fontName;
- GetMenuItemText(mFontMenu, index, fontName);
-
- short fontNum;
- GetFNum(fontName, &fontNum);
-
- SetMenuItemFontID(mFontMenu, index, fontNum);
-
- // set the command id so we can process the items (CreateStandardFontMenu
- // leaves all of these at 0)
- err = SetMenuItemCommandID(mFontMenu, index, 'Font' + index);
- ThrowIfOSErr(err, "Couldn't set the font menu item's command ids!");
- }
-
- InsertMenu(mFontMenu, 0);
-
- // create the Size menu
- err = CreateNewMenu(kSizeMenu, kMenuAttrAutoDisable, &menuH);
- ThrowIfOSErr(err, "Couldn't create the size menu!");
-
- err = SetMenuTitleWithCFString(menuH, MacString("Size"));
- ThrowIfOSErr(err, "Couldn't set the size menu name!");
-
- InsertMenu(menuH, 0);
-
- // add the Size menu items
- const char* items[] = {"9", "10", "12", "16", "18", "20", "32", "48", "64", NULL};
- int sizes[] = {9, 10, 12, 16, 18, 20, 32, 48, 64};
- for (int i = 0; items[i] != NULL; ++i)
- {
- err = AppendMenuItemTextWithCFString(menuH, MacString(items[i]), kMenuItemAttrIgnoreMeta, 'Size' + sizes[i], NULL);
- ThrowIfOSErr(err, "Couldn't add a size menu item!");
- }
-
- // install a custom menu handler
- std::vector<EventTypeSpec> specs;
- specs.push_back(CreateSpec(kEventClassCommand, kEventCommandProcess));
- specs.push_back(CreateSpec(kEventClassCommand, kEventCommandUpdateStatus));
- specs.push_back(CreateSpec(kEventClassMenu, kEventMenuOpening));
-
- err = InstallApplicationEventHandler(NewEventHandlerUPP(DoMenuEvent), specs.size(), &specs[0], this, NULL);
- ThrowIfOSErr(err, "Couldn't install the menu handlers!");
-
- // draw the new menubar
- DrawMenuBar();
-}
-
-
-//---------------------------------------------------------------
-//
-// CApplication::DoInitWindows
-//
-//---------------------------------------------------------------
-void CApplication::DoInitWindows()
-{
- // create the window
- Rect bounds = {32, 32, 64, 64}; // we position properly later
-
- WindowAttributes attrs = kWindowCollapseBoxAttribute | kWindowStandardHandlerAttribute;
- OSStatus err = CreateNewWindow(kDocumentWindowClass, attrs, &bounds, &mWindow);
- ThrowIfOSErr(err, "Couldn't create the window!");
-
- // install a custom window handler
- std::vector<EventTypeSpec> specs;
- specs.push_back(CreateSpec(kEventClassWindow, kEventWindowDrawContent));
-
- err = InstallWindowEventHandler(mWindow, NewEventHandlerUPP(DoWindowEvent), specs.size(), &specs[0], this, NULL);
- ThrowIfOSErr(err, "Couldn't install the window event handler!");
-}
-
-
-//---------------------------------------------------------------
-//
-// CApplication::DoKeyDown [static]
-//
-//---------------------------------------------------------------
-pascal OSStatus CApplication::DoKeyDown(EventHandlerCallRef handler, EventRef event, void* refCon)
-{
- OSStatus err = eventNotHandledErr;
-
- if (!sInDialog)
- {
- CApplication* thisPtr = static_cast<CApplication*>(refCon);
-
- try
- {
- char ch;
- (void) GetEventParameter(event, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(ch), NULL, &ch);
-
- UInt32 key;
- (void) GetEventParameter(event, kEventParamKeyCode, typeUInt32, NULL, sizeof(key), NULL, &key);
-
- UInt32 modifiers;
- (void) GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(modifiers), NULL, &modifiers);
-
- if ((modifiers & cmdKey) == 0)
- thisPtr->mChar = thisPtr->DoMungeChar(ch, key, modifiers);
-
- if (thisPtr->mChar != 0)
- QuitApplicationEventLoop();
-
- err = noErr;
- }
- catch (const std::exception& e)
- {
- DEBUGSTR((std::string("Couldn't complete the operation (") + e.what() + ").").c_str());
- err = eventNotHandledErr;
- }
- catch (...)
- {
- DEBUGSTR("Couldn't complete the operation.");
- err = eventNotHandledErr;
- }
- }
-
- return err;
-}
-
-
-//---------------------------------------------------------------
-//
-// CApplication::DoMenuEvent [static]
-//
-//---------------------------------------------------------------
-pascal OSStatus CApplication::DoMenuEvent(EventHandlerCallRef handler, EventRef event, void* refCon)
-{
- OSStatus err = noErr;
- CApplication* thisPtr = static_cast<CApplication*>(refCon);
-
- UInt32 kind = GetEventKind(event);
- try
- {
- HICommand command;
-
- if (kind == kEventCommandUpdateStatus)
- {
- err = GetEventParameter(event, kEventParamDirectObject, typeHICommand, NULL, sizeof(command), NULL, &command);
- ThrowIfOSErr(err, "Couldn't get the direct object in DoMenuEvent");
-
- err = thisPtr->DoEnableCommand(command.menu.menuRef, command.commandID, command.menu.menuItemIndex);
- }
- else if (kind == kEventCommandProcess)
- {
- err = GetEventParameter(event, kEventParamDirectObject, typeHICommand, NULL, sizeof(command), NULL, &command);
- ThrowIfOSErr(err, "Couldn't get the direct object in DoMenuEvent");
-
- err = thisPtr->DoHandleCommand(command.commandID);
- }
- else if (kind == kEventMenuOpening)
- {
- Boolean firstTime;
- err = GetEventParameter(event, kEventParamMenuFirstOpen, typeBoolean, NULL, sizeof(firstTime), NULL, &firstTime);
- ThrowIfOSErr(err, "Couldn't get the first open flag in DoMenuEvent");
-
- if (firstTime) // only call the callbacks the first time we open the menu (during this drag)
- {
- MenuRef menuH;
- err = GetEventParameter(event, kEventParamDirectObject, typeMenuRef, NULL, sizeof(MenuRef), NULL, &menuH);
- ThrowIfOSErr(err, "Couldn't get the direct object in DoMenuEvent");
-
- err = thisPtr->DoOpenMenu(menuH);
- }
- }
- else
- err = eventNotHandledErr;
- }
- catch (const std::exception& e)
- {
- DEBUGSTR((std::string("Couldn't complete the operation (") + e.what() + ").").c_str());
- err = eventNotHandledErr;
- }
- catch (...)
- {
- DEBUGSTR("Couldn't complete the operation.");
- err = eventNotHandledErr;
- }
-
- if (kind == kEventCommandProcess)
- HiliteMenu(0);
-
- return err;
-}
-
-
-//---------------------------------------------------------------
-//
-// CApplication::DoMungeChar
-//
-//---------------------------------------------------------------
-char CApplication::DoMungeChar(char ch, UInt32 key, UInt32 modifiers) const
-{
- switch (key) {
- case kNumPad1Key:
- if (modifiers & shiftKey)
- ch = 'B';
- else if (modifiers & controlKey)
- ch = 2;
- else
- ch = 'b';
- break;
-
- case kNumPad2Key:
- case kDownArrowKey:
- if (modifiers & shiftKey)
- ch = 'J';
- else if (modifiers & controlKey)
- ch = 10;
- else
- ch = 'j';
- break;
-
- case kNumPad3Key:
- if (modifiers & shiftKey)
- ch = 'N';
- else if (modifiers & controlKey)
- ch = 14;
- else
- ch = 'n';
- break;
-
- case kNumPad4Key:
- case kLeftArrowKey:
- if (modifiers & shiftKey)
- ch = 'H';
- else if (modifiers & controlKey)
- ch = 8;
- else
- ch = 'h';
- break;
-
- case kNumPad5Key:
- if (modifiers & shiftKey)
- ch = '5';
- else
- ch = '.';
- break;
-
- case kNumPad6Key:
- case kRightArrowKey:
- if (modifiers & shiftKey)
- ch = 'L';
- else if (modifiers & controlKey)
- ch = 12;
- else
- ch = 'l';
- break;
-
- case kNumPad7Key:
- if (modifiers & shiftKey)
- ch = 'Y';
- else if (modifiers & controlKey)
- ch = 25;
- else
- ch = 'y';
- break;
-
- case kNumPad8Key:
- case kUpArrowKey:
- if (modifiers & shiftKey)
- ch = 'K';
- else if (modifiers & controlKey)
- ch = 11;
- else
- ch = 'k';
- break;
-
- case kNumPad9Key:
- if (modifiers & shiftKey)
- ch = 'U';
- else if (modifiers & controlKey)
- ch = 21;
- else
- ch = 'u';
- break;
- }
-
- return ch;
-}
-
-
-//---------------------------------------------------------------
-//
-// CApplication::DoOpenMenu
-//
-//---------------------------------------------------------------
-OSStatus CApplication::DoOpenMenu(MenuRef menuH)
-{
- // select the curret font
-
- return noErr;
-}
-
-
-//---------------------------------------------------------------
-//
-// CApplication::DoQuit [static]
-//
-//---------------------------------------------------------------
-pascal OSErr CApplication::DoQuit(const AppleEvent* event, AppleEvent* reply, SInt32 refCon)
-{
- CApplication* thisPtr = reinterpret_cast<CApplication*>(refCon);
- thisPtr->Quit();
-
- return noErr;
-}
-
-
-//---------------------------------------------------------------
-//
-// CApplication::DoReadPrefs
-//
-//---------------------------------------------------------------
-void CApplication::DoReadPrefs()
-{
- MacString appID("Crawl4");
-
- // window location
- Rect bounds;
-
- MacString name("window_x");
- Boolean existsX = false;
- bounds.left = CFPreferencesGetAppIntegerValue(name, appID, &existsX);
-
- name = MacString("window_y");
- Boolean existsY = false;
- bounds.top = CFPreferencesGetAppIntegerValue(name, appID, &existsY);
-
- if (existsX && existsY)
- {
- bounds.right = bounds.left + 32; // DoSetFont will reset the window dimensions
- bounds.bottom = bounds.top + 32;
-
- OSStatus err = SetWindowBounds(mWindow, kWindowStructureRgn, &bounds);
- ASSERT(err == noErr);
- }
- else
- {
- OSStatus err = RepositionWindow(mWindow, NULL, kWindowCenterOnMainScreen);
- ASSERT(err == noErr);
- }
-
- // mFontName
- name = MacString("font_name");
-
- CFTypeRef dataRef = CFPreferencesCopyAppValue(name, appID);
- if (dataRef != NULL && CFGetTypeID(dataRef) == CFStringGetTypeID())
- {
- MacString data(static_cast<CFStringRef>(dataRef));
-
- Str255 fontName;
- data.CopyTo(fontName, sizeof(fontName));
- CFRelease(dataRef);
-
- // mPointSize
- name = MacString("font_size");
- CFIndex fontSize = CFPreferencesGetAppIntegerValue(name, appID, NULL);
- if (fontSize > 0)
- this->DoSetFont(fontName, fontSize);
- else
- this->DoSetFont(fontName, 12);
- }
- else
- this->DoSetFont("\pMonaco", 12);
-
- // make sure the window isn't off-screen
- Rect area;
- OSStatus err = GetWindowGreatestAreaDevice(mWindow, kWindowStructureRgn, NULL, &area);
- if (err == noErr)
- {
- err = GetWindowBounds(mWindow, kWindowDragRgn, &bounds);
- if (err == noErr)
- {
- SectRect(&area, &bounds, &bounds);
-
- int pixels = (bounds.right - bounds.left)*(bounds.bottom - bounds.top);
- if (pixels < 64) // only move the window if there are fewer than 64 draggable pixels
- {
- err = ConstrainWindowToScreen(mWindow, kWindowStructureRgn, kWindowConstrainStandardOptions, NULL, NULL);
- ASSERT(err == noErr);
- }
- }
- }
-}
-
-
-//---------------------------------------------------------------
-//
-// CApplication::DoRender
-//
-//---------------------------------------------------------------
-void CApplication::DoRender()
-{
- ASSERT(mLines.size() == kTermHeight);
-
- SetPortWindowPort(mWindow);
-
- TextFont(mFontNum);
- TextSize(mPointSize);
-
- RGBBackColor(&mBackColor);
- EraseRect(&kBigRect);
-
- Rect area;
- for (int y = 0; y < mLines.size(); ++y)
- {
- area.top = y*mCellHeight;
- area.bottom = area.top + mCellHeight;
- area.left = 0;
- area.right = area.left + mCellWidth;
-
- const Line& line = mLines[y];
- ASSERT(line.size() == kTermWidth);
-
- for (int x = 0; x < line.size(); ++x)
- {
- const SCell& cell = line[x];
-
- this->DoDrawCell(area, cell);
-
- if (x == mCursor.h && y == mCursor.v && mShowCursor)
- {
- ::RGBForeColor(&kWhite);
- ::MoveTo(area.left + 1, area.top + mAscent);
- ::Line(area.right - area.left - 2, 0);
- }
-
- area.left += mCellWidth;
- area.right += mCellWidth;
- }
- }
-}
-
-
-//---------------------------------------------------------------
-//
-// CApplication::DoSetChar
-//
-//---------------------------------------------------------------
-void CApplication::DoSetChar(unsigned char ch)
-{
- ASSERT(mCursor.h < kTermWidth);
- ASSERT(mCursor.v < kTermHeight);
- ASSERT(mCursor.h >= 0);
- ASSERT(mCursor.v >= 0);
-
- int x = mCursor.h;
-
- Line& line = mLines[mCursor.v];
- ASSERT(line.size() == kTermWidth);
-
- SCell& cell = line[x++];
- cell.ch = ch;
- cell.color = mForeColor;
-
- Rect area;
- area.top = mCursor.v * mCellHeight;
- area.bottom = area.top + mCellHeight;
- area.left = mCursor.h * mCellWidth;
- area.right = area.left + mCellWidth;
-
- (void) InvalWindowRect(mWindow, &kBigRect);
-
- if (x >= kTermWidth)
- {
- if (++mCursor.v >= kTermHeight)
- {
- mCursor.v = kTermHeight - 1;
- mCursor.h = kTermWidth - 1;
- this->DoScroll();
- }
- x = 0;
- }
-
- mCursor.h = x;
-}
-
-
-//---------------------------------------------------------------
-//
-// CApplication::DoScroll
-//
-//---------------------------------------------------------------
-void CApplication::DoScroll()
-{
- mLines.erase(mLines.begin());
-
- mLines.push_back(Line());
- mLines.back().resize(kTermWidth);
-
- (void) InvalWindowRect(mWindow, &kBigRect);
-}
-
-
-//---------------------------------------------------------------
-//
-// CApplication::DoSetFont
-//
-//---------------------------------------------------------------
-void CApplication::DoSetFont(const unsigned char* name, int size)
-{
- ASSERT(name != NULL);
- ASSERT(size > 0);
-
- short fontNum;
- GetFNum(name, &fontNum);
-
- if (fontNum != mFontNum || size != mPointSize)
- {
- BlockMoveData(name, mFontName, name[0] + 1);
-
- mFontNum = fontNum;
- mPointSize = size;
-
- SetPortWindowPort(mWindow);
- TextFont(mFontNum);
- TextSize(mPointSize);
-
- FontInfo info;
- GetFontInfo(&info);
-
- mCellHeight = info.ascent + info.descent;
- mAscent = info.ascent;
-
- short width = StringWidth("\pMMMMM"); // widMax is usually much too wide so we'll compute this ourselves...
- mCellWidth = width/5 + 1;
-
- Rect bounds;
- bounds.top = 0;
- bounds.left = 0;
- bounds.bottom = mCellHeight * kTermHeight;
- bounds.right = mCellWidth * kTermWidth;
- SizeWindow(mWindow, bounds.right, bounds.bottom, false);
-
- (void) InvalWindowRect(mWindow, &kBigRect);
- }
-}
-
-
-//---------------------------------------------------------------
-//
-// CApplication::DoWindowEvent [static]
-//
-//---------------------------------------------------------------
-pascal OSStatus CApplication::DoWindowEvent(EventHandlerCallRef handler, EventRef event, void* refCon)
-{
- OSStatus err = noErr;
- CApplication* thisPtr = static_cast<CApplication*>(refCon);
-
- try
- {
- WindowRef window = NULL;
- (void) GetEventParameter(event, kEventParamDirectObject, typeWindowRef, NULL, sizeof(window), NULL, &window);
- ASSERT(window == thisPtr->mWindow);
-
- UInt32 kind = GetEventKind(event);
- switch (kind) {
-// case kEventWindowBoundsChanging:
-// thisPtr->DoConstrainWindow(event);
-// break;
-
- case kEventWindowDrawContent:
- thisPtr->DoRender();
- break;
-
-// case kEventWindowGetIdealSize:
-// case kEventWindowGetMaximumSize:
-// {
-// ::Point maxSize = thisPtr->OnGetMaxSize();
-// SetEventParameter(event, kEventParamDimensions, &maxSize);
-// }
-// break;
-
-// case kEventWindowGetMinimumSize:
-// {
-// ::Point minSize = thisPtr->OnGetMinSize();
-// SetEventParameter(event, kEventParamDimensions, &minSize);
-// }
-// break;
-
- default:
- err = eventNotHandledErr;
- }
- }
- catch (const std::exception& e)
- {
- DEBUGSTR((std::string("Couldn't complete the operation (") + e.what() + ").").c_str());
- err = eventNotHandledErr;
- }
- catch (...)
- {
- DEBUGSTR("Couldn't complete the operation.");
- err = eventNotHandledErr;
- }
-
- return err;
-}
-
-
-//---------------------------------------------------------------
-//
-// CApplication::DoWritePrefs , , mWindow->location
-//
-//---------------------------------------------------------------
-void CApplication::DoWritePrefs()
-{
- MacString appID("Crawl4");
-
- // mFontName
- MacString name("font_name");
- MacString data(mFontName);
- CFPreferencesSetAppValue(name, data, appID);
-
- // mPointSize
- name = MacString("font_size");
- data = MacString(mPointSize);
- CFPreferencesSetAppValue(name, data, appID);
-
- // window location
- Rect bounds;
- OSStatus err = GetWindowBounds(mWindow, kWindowStructureRgn, &bounds);
- if (err == noErr)
- {
- name = MacString("window_x");
- data = MacString(bounds.left);
- CFPreferencesSetAppValue(name, data, appID);
-
- name = MacString("window_y");
- data = MacString(bounds.top);
- CFPreferencesSetAppValue(name, data, appID);
- }
-
- // flush
- VERIFY(CFPreferencesAppSynchronize(appID));
-}
-
-#if __MWERKS__
-#pragma mark -
-#endif
-
-// ========================================================================
-// Non-ANSI Functions
-// ========================================================================
-
-//---------------------------------------------------------------
-//
-// stricmp
-//
-// Case insensitive string comparison (code is from MSL which
-// is why it looks so dorky).
-//
-//---------------------------------------------------------------
-int stricmp(const char* lhs, const char* rhs)
-{
- ASSERT(lhs != NULL);
- ASSERT(rhs != NULL);
-
- const unsigned char* p1 = (unsigned char*) lhs - 1;
- const unsigned char* p2 = (unsigned char*) rhs - 1;
- unsigned long c1, c2;
-
- while ((c1 = tolower(*++p1)) == (c2 = tolower(*++p2)))
- if (c1 == '\0')
- return (0);
-
- return c1 - c2;
-}
-
-
-//---------------------------------------------------------------
-//
-// strlwr
-//
-// In place conversion to lower case.
-//
-//---------------------------------------------------------------
-char* strlwr(char* str)
-{
- ASSERT(str != NULL);
-
- for (int i = 0; i < strlen(str); ++i)
- str[i] = tolower(str[i]);
-
- return str;
-}
-
-
-//---------------------------------------------------------------
-//
-// itoa
-//
-// Converts an integer to a string (after libunix.cc).
-//
-//---------------------------------------------------------------
-void itoa(int value, char* buffer, int radix)
-{
- ASSERT(buffer != NULL);
- ASSERT(radix == 10 || radix == 2);
-
- if (radix == 10)
- sprintf(buffer, "%i", value);
-
- if (radix == 2)
- { /* int to "binary string" */
- unsigned int bitmask = 32768;
- int ctr = 0;
- int startflag = 0;
-
- while (bitmask)
- {
- if (value & bitmask)
- {
- startflag = 1;
- sprintf(buffer + ctr, "1");
-
- }
- else
- {
- if (startflag)
- sprintf(buffer + ctr, "0");
- }
-
- bitmask = bitmask >> 1;
- if (startflag)
- ctr++;
- }
-
- if (!startflag) /* Special case if value == 0 */
- sprintf((buffer + ctr++), "0");
- buffer[ctr] = (char) NULL;
- }
-}
-
-#if __MWERKS__
-#pragma mark -
-#endif
-
-// ========================================================================
-// Curses(?) Functions
-// ========================================================================
-
-//---------------------------------------------------------------
-//
-// window
-//
-//---------------------------------------------------------------
-void window(int x, int y, int lx, int ly)
-{
- ASSERT(lx == kTermWidth); // window size is hard-coded
- ASSERT(ly == kTermHeight);
-
- gotoxy(x, y);
-}
-
-
-//---------------------------------------------------------------
-//
-// clrscr
-//
-//---------------------------------------------------------------
-void clrscr()
-{
- ASSERT(sApp != NULL);
-
- sApp->Clear();
-}
-
-
-//---------------------------------------------------------------
-//
-// textcolor
-//
-//---------------------------------------------------------------
-void textcolor(int c)
-{
- ASSERT(c >= 0);
- ASSERT(c < 16);
- ASSERT(sApp != NULL);
-
- RGBColor color = ConvertColor(c);
- sApp->SetForeColor(color);
-}
-
-
-//---------------------------------------------------------------
-//
-// textbackground
-//
-//---------------------------------------------------------------
-void textbackground(int c)
-{
- ASSERT(c >= 0);
- ASSERT(c < 16);
- ASSERT(sApp != NULL);
-
- RGBColor color = ConvertColor(c);
- sApp->SetBackColor(color);
-}
-
-
-//---------------------------------------------------------------
-//
-// gotoxy
-//
-//---------------------------------------------------------------
-void gotoxy(int x, int y)
-{
- ASSERT(x >= 1);
- ASSERT(y >= 1);
- ASSERT(sApp != NULL);
-
- sApp->SetCursor(x - 1, y - 1);
-}
-
-
-//---------------------------------------------------------------
-//
-// wherex
-//
-//---------------------------------------------------------------
-int wherex()
-{
- ASSERT(sApp != NULL);
-
- Point pos = sApp->GetCursor();
-
- return pos.h + 1;
-}
-
-
-//---------------------------------------------------------------
-//
-// wherey
-//
-//---------------------------------------------------------------
-int wherey()
-{
- ASSERT(sApp != NULL);
-
- Point pos = sApp->GetCursor();
-
- return pos.v + 1;
-}
-
-
-//---------------------------------------------------------------
-//
-// putch
-//
-//---------------------------------------------------------------
-void putch(char ch)
-{
- ASSERT(sApp != NULL);
-
- char buffer[2];
-
- buffer[0] = ch;
- buffer[1] = '\0';
-
- sApp->SetChar(ch);
-// sApp->Print(buffer);
-}
-
-
-//---------------------------------------------------------------
-//
-// cprintf
-//
-//---------------------------------------------------------------
-void cprintf(const char* format,...)
-{
- ASSERT(sApp != NULL);
-
- char buffer[2048];
-
- va_list argp;
-
- va_start(argp, format);
- vsprintf(buffer, format, argp);
- va_end(argp);
-
- sApp->Print(buffer);
-}
-
-
-//---------------------------------------------------------------
-//
-// kbhit
-//
-//---------------------------------------------------------------
-int kbhit()
-{
- return sApp->PeekChar();
-}
-
-
-//---------------------------------------------------------------
-//
-// getche
-//
-//---------------------------------------------------------------
-char getche()
-{
- char ch = getch();
-
- if (ch != '\r')
- putch(ch);
-
- return ch;
-}
-
-
-//---------------------------------------------------------------
-//
-// getstr
-//
-//---------------------------------------------------------------
-void getstr(char* buffer, int bufferSize)
-{
- ASSERT(buffer != NULL);
- ASSERT(bufferSize > 1);
-
- int index = 0;
-
- while (index < bufferSize - 1)
- {
- char ch = getche();
-
- if (ch == '\r')
- break;
- else if (ch == '\b' && index > 0)
- --index;
- else if (isprint(ch))
- buffer[index++] = ch;
- }
-
- buffer[index] = '\0';
-}
-
-
-//---------------------------------------------------------------
-//
-// _setcursortype
-//
-//---------------------------------------------------------------
-void _setcursortype(int curstype)
-{
- ASSERT(curstype == _NORMALCURSOR || curstype == _NOCURSOR);
- ASSERT(sApp != NULL);
-
- sApp->ShowCursor(curstype == _NORMALCURSOR);
-}
-
-
-//---------------------------------------------------------------
-//
-// getch
-//
-//---------------------------------------------------------------
-int getch()
-{
- ASSERT(sApp != NULL);
-
- return sApp->GetChar();
-}
-
-#if __MWERKS__
-#pragma mark -
-#endif
-
-// ========================================================================
-// Misc Functions
-// ========================================================================
-
-//---------------------------------------------------------------
-//
-// delay
-//
-//---------------------------------------------------------------
-void delay(int ms)
-{
- ASSERT(ms >= 0);
-
- usleep(1000*ms);
-}
-
-
-//---------------------------------------------------------------
-//
-// init_mac
-//
-//---------------------------------------------------------------
-void init_mac()
-{
- ASSERT(sApp == NULL);
-
- // Read in the color table
- sColors = GetCTable(256);
- if (sColors == NULL)
- {
- WarnUser("Couldn't load the colour table!");
- ExitToShell();
- }
-
- // Create the application object
- sApp = new CApplication;
-}
-
-
-//---------------------------------------------------------------
-//
-// deinit_mac
-//
-//---------------------------------------------------------------
-void deinit_mac()
-{
- delete sApp;
- sApp = NULL;
-}
-
-
-#endif // macintosh
diff --git a/stone_soup/crawl-ref/source/libmac.h b/stone_soup/crawl-ref/source/libmac.h
deleted file mode 100644
index 8b7e3903d6..0000000000
--- a/stone_soup/crawl-ref/source/libmac.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * File: libmac.h
- * Summary: Mac specific routines used by Crawl.
- * Written by: Jesse Jones
- *
- * Change History (most recent first):
- *
- * <2> 5/25/02 JDJ Updated for Mach-O targets
- * <1> 3/23/99 JDJ Created
- */
-
-#ifndef LIBMAC_H
-#define LIBMAC_H
-
-#if macintosh
-
-#ifdef _BSD_SIZE_T_ // $$$ is there a better way to test for OS X?
- #define OSX 1
-#else
- #define OS9 1
-#endif
-
-#include <fcntl.h>
-#include <stdlib.h>
-#include <string.h>
-
-#if OSX
- #include <unistd.h>
-#endif
-
-#define MAC_NUMBER_OF_LINES 30
-
-// constants
-const int _NORMALCURSOR = 1;
-const int _NOCURSOR = 0;
-
-
-// non-ANSI functions
-int stricmp(const char* lhs, const char* rhs);
-char* strlwr(char* str);
-void itoa(int n, char* buffer, int radix);
-
-#if !OSX
- inline void srandom(unsigned int seed)
- {
- srand(seed);
- }
-
- int open(const char* path, int openFlags, int permissions);
- int open(const char* path, int openFlags, int permissions, int mysteryFlags);
- int close(int desc);
- int read(int desc, void *buffer, unsigned int bytes);
- int write(int desc, const void *buffer, unsigned int bytes);
- int unlink(const char* path);
-#endif
-
-
-// curses(?) functions
-void clrscr();
-void gotoxy(int x, int y);
-void textcolor(int c);
-void cprintf(const char* format,...);
-
-void window(int x, int y, int lx, int ly);
-int wherex();
-int wherey();
-void putch(char c);
-int kbhit();
-
-char getche();
-int getch();
-void getstr(char* buffer, int bufferSize);
-
-void textbackground(int c);
-void _setcursortype(int curstype);
-
-
-// misc functions
-void delay(int ms);
-
-void init_mac();
-void deinit_mac();
-
-
-#endif // macintosh
-#endif // LIBMAC_H
diff --git a/stone_soup/crawl-ref/source/libunix.cc b/stone_soup/crawl-ref/source/libunix.cc
deleted file mode 100644
index 72441dfd3d..0000000000
--- a/stone_soup/crawl-ref/source/libunix.cc
+++ /dev/null
@@ -1,778 +0,0 @@
-/*
- * File: libunix.cc
- * Summary: Functions for unix and curses support
- * Written by: ?
- *
- * Modified for Crawl Reference by $Author$ on $Date$
- *
- * Change History (most recent first):
- *
- * <6> 10/11/99 BCR Swapped 'v' and 'V' commands, fixed
- * & for debug command.
- * <5> 9/25/99 CDL linuxlib -> liblinux
- * changes to fix "macro problem"
- * keypad -> command lookup
- * <4> 99/07/13 BWR added translate_keypad(), to try and
- * translate keypad escape sequences into
- * numeric char values.
- * <3> 99/06/18 BCR moved CHARACTER_SET #define to AppHdr.h
- * <2> 99/05/12 BWR Tchars, signals, solaris support
- *
- * <1> -/--/-- ? Created
- *
- */
-
-/* Some replacement routines missing in gcc
- Some of these are inspired by/stolen from the Linux-conio package
- by Mental EXPlotion. Hope you guys don't mind.
- The colour exchange system is perhaps a little overkill, but I wanted
- it to be general to support future changes.. The only thing not
- supported properly is black on black (used by curses for "normal" mode)
- and white on white (used by me for "bright black" (darkgray) on black
-
- Jan 1998 Svante Gerhard <svante@algonet.se> */
-
-#include "AppHdr.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdarg.h>
-#include <ctype.h>
-#define _LIBUNIX_IMPLEMENTATION
-#include "libunix.h"
-#include "defines.h"
-
-#include "enum.h"
-#include "externs.h"
-
-#include <termios.h>
-
-static struct termios def_term;
-static struct termios game_term;
-
-#ifdef USE_UNIX_SIGNALS
-#include <signal.h>
-#endif
-
-// Its best if curses comes at the end (name conflicts with Solaris). -- bwr
-#ifndef CURSES_INCLUDE_FILE
- #include <curses.h>
-#else
- #include CURSES_INCLUDE_FILE
-#endif
-
-// Character set variable
-int character_set = CHARACTER_SET;
-
-// Globals holding current text/backg. colors
-short FG_COL = WHITE;
-short BG_COL = BLACK;
-
-// a lookup table to convert keypresses to command enums
-static int key_to_command_table[KEY_MAX];
-
-static unsigned int convert_to_curses_attr( int chattr )
-{
- switch (chattr & CHATTR_ATTRMASK)
- {
- case CHATTR_STANDOUT: return (A_STANDOUT);
- case CHATTR_BOLD: return (A_BOLD);
- case CHATTR_BLINK: return (A_BLINK);
- case CHATTR_UNDERLINE: return (A_UNDERLINE);
- case CHATTR_REVERSE: return (A_REVERSE);
- case CHATTR_DIM: return (A_DIM);
- default: return (A_NORMAL);
- }
-}
-
-static inline short macro_colour( short col )
-{
- return (Options.colour[ col ]);
-}
-
-// Translate DOS colors to curses.
-static short translate_colour( short col )
-{
- switch (col)
- {
- case BLACK:
- return COLOR_BLACK;
- break;
- case BLUE:
- return COLOR_BLUE;
- break;
- case GREEN:
- return COLOR_GREEN;
- break;
- case CYAN:
- return COLOR_CYAN;
- break;
- case RED:
- return COLOR_RED;
- break;
- case MAGENTA:
- return COLOR_MAGENTA;
- break;
- case BROWN:
- return COLOR_YELLOW;
- break;
- case LIGHTGREY:
- return COLOR_WHITE;
- break;
- case DARKGREY:
- return COLOR_BLACK + COLFLAG_CURSES_BRIGHTEN;
- break;
- case LIGHTBLUE:
- return COLOR_BLUE + COLFLAG_CURSES_BRIGHTEN;
- break;
- case LIGHTGREEN:
- return COLOR_GREEN + COLFLAG_CURSES_BRIGHTEN;
- break;
- case LIGHTCYAN:
- return COLOR_CYAN + COLFLAG_CURSES_BRIGHTEN;
- break;
- case LIGHTRED:
- return COLOR_RED + COLFLAG_CURSES_BRIGHTEN;
- break;
- case LIGHTMAGENTA:
- return COLOR_MAGENTA + COLFLAG_CURSES_BRIGHTEN;
- break;
- case YELLOW:
- return COLOR_YELLOW + COLFLAG_CURSES_BRIGHTEN;
- break;
- case WHITE:
- return COLOR_WHITE + COLFLAG_CURSES_BRIGHTEN;
- break;
- default:
- return COLOR_GREEN;
- break; //mainly for debugging
- }
-}
-
-
-static void setup_colour_pairs( void )
-{
-
- short i, j;
-
- for (i = 0; i < 8; i++)
- {
- for (j = 0; j < 8; j++)
- {
- if (( i > 0 ) || ( j > 0 ))
- init_pair(i * 8 + j, j, i);
- }
- }
-
- init_pair(63, COLOR_BLACK, Options.background);
-} // end setup_colour_pairs()
-
-
-static void termio_init()
-{
- tcgetattr(0, &def_term);
- memcpy(&game_term, &def_term, sizeof(struct termios));
-
- def_term.c_cc[VINTR] = (char) 3; // ctrl-C
- game_term.c_cc[VINTR] = (char) 3; // ctrl-C
-
- // Lets recover some control sequences
- game_term.c_cc[VSTART] = (char) -1; // ctrl-Q
- game_term.c_cc[VSTOP] = (char) -1; // ctrl-S
- game_term.c_cc[VSUSP] = (char) -1; // ctrl-Y
-#ifdef VDSUSP
- game_term.c_cc[VDSUSP] = (char) -1; // ctrl-Y
-#endif
-
- tcsetattr(0, TCSAFLUSH, &game_term);
-}
-
-
-int getch_ck() {
- int c = getch();
- switch (c) {
- case KEY_BACKSPACE: return CK_BKSP;
- case KEY_DC: return CK_DELETE;
- case KEY_HOME: return CK_HOME;
- case KEY_PPAGE: return CK_PGUP;
- case KEY_END: return CK_END;
- case KEY_NPAGE: return CK_PGDN;
- case KEY_UP: return CK_UP;
- case KEY_DOWN: return CK_DOWN;
- case KEY_LEFT: return CK_LEFT;
- case KEY_RIGHT: return CK_RIGHT;
- default: return c;
- }
-}
-
-void init_key_to_command()
-{
- int i;
-
- // initialize to "do nothing"
- for (i = 0; i < KEY_MAX; i++)
- {
- key_to_command_table[i] = CMD_NO_CMD;
- }
-
- // lower case
- key_to_command_table[(int) 'a'] = CMD_USE_ABILITY;
- key_to_command_table[(int) 'b'] = CMD_MOVE_DOWN_LEFT;
- key_to_command_table[(int) 'c'] = CMD_CLOSE_DOOR;
- key_to_command_table[(int) 'd'] = CMD_DROP;
- key_to_command_table[(int) 'e'] = CMD_EAT;
- key_to_command_table[(int) 'f'] = CMD_FIRE;
- key_to_command_table[(int) 'g'] = CMD_PICKUP;
- key_to_command_table[(int) 'h'] = CMD_MOVE_LEFT;
- key_to_command_table[(int) 'i'] = CMD_DISPLAY_INVENTORY;
- key_to_command_table[(int) 'j'] = CMD_MOVE_DOWN;
- key_to_command_table[(int) 'k'] = CMD_MOVE_UP;
- key_to_command_table[(int) 'l'] = CMD_MOVE_RIGHT;
- key_to_command_table[(int) 'm'] = CMD_DISPLAY_SKILLS;
- key_to_command_table[(int) 'n'] = CMD_MOVE_DOWN_RIGHT;
- key_to_command_table[(int) 'o'] = CMD_OPEN_DOOR;
- key_to_command_table[(int) 'p'] = CMD_PRAY;
- key_to_command_table[(int) 'q'] = CMD_QUAFF;
- key_to_command_table[(int) 'r'] = CMD_READ;
- key_to_command_table[(int) 's'] = CMD_SEARCH;
- key_to_command_table[(int) 't'] = CMD_THROW;
- key_to_command_table[(int) 'u'] = CMD_MOVE_UP_RIGHT;
- key_to_command_table[(int) 'v'] = CMD_EXAMINE_OBJECT;
- key_to_command_table[(int) 'w'] = CMD_WIELD_WEAPON;
- key_to_command_table[(int) 'x'] = CMD_LOOK_AROUND;
- key_to_command_table[(int) 'y'] = CMD_MOVE_UP_LEFT;
- key_to_command_table[(int) 'z'] = CMD_ZAP_WAND;
-
- // upper case
- key_to_command_table[(int) 'A'] = CMD_DISPLAY_MUTATIONS;
- key_to_command_table[(int) 'B'] = CMD_RUN_DOWN_LEFT;
- key_to_command_table[(int) 'C'] = CMD_EXPERIENCE_CHECK;
- key_to_command_table[(int) 'D'] = CMD_BUTCHER;
- key_to_command_table[(int) 'E'] = CMD_EVOKE;
- key_to_command_table[(int) 'F'] = CMD_NO_CMD;
- key_to_command_table[(int) 'G'] = CMD_NO_CMD;
- key_to_command_table[(int) 'H'] = CMD_RUN_LEFT;
- key_to_command_table[(int) 'I'] = CMD_OBSOLETE_INVOKE;
- key_to_command_table[(int) 'J'] = CMD_RUN_DOWN;
- key_to_command_table[(int) 'K'] = CMD_RUN_UP;
- key_to_command_table[(int) 'L'] = CMD_RUN_RIGHT;
- key_to_command_table[(int) 'M'] = CMD_MEMORISE_SPELL;
- key_to_command_table[(int) 'N'] = CMD_RUN_DOWN_RIGHT;
- key_to_command_table[(int) 'O'] = CMD_DISPLAY_OVERMAP;
- key_to_command_table[(int) 'P'] = CMD_WEAR_JEWELLERY;
- key_to_command_table[(int) 'Q'] = CMD_QUIT;
- key_to_command_table[(int) 'R'] = CMD_REMOVE_JEWELLERY;
- key_to_command_table[(int) 'S'] = CMD_SAVE_GAME;
- key_to_command_table[(int) 'T'] = CMD_REMOVE_ARMOUR;
- key_to_command_table[(int) 'U'] = CMD_RUN_UP_RIGHT;
- key_to_command_table[(int) 'V'] = CMD_GET_VERSION;
- key_to_command_table[(int) 'W'] = CMD_WEAR_ARMOUR;
- key_to_command_table[(int) 'X'] = CMD_DISPLAY_MAP;
- key_to_command_table[(int) 'Y'] = CMD_RUN_UP_LEFT;
- key_to_command_table[(int) 'Z'] = CMD_CAST_SPELL;
-
- // control
- key_to_command_table[ (int) CONTROL('A') ] = CMD_TOGGLE_AUTOPICKUP;
- key_to_command_table[ (int) CONTROL('B') ] = CMD_OPEN_DOOR_DOWN_LEFT;
- key_to_command_table[ (int) CONTROL('C') ] = CMD_CLEAR_MAP;
-
-#ifdef ALLOW_DESTROY_ITEM_COMMAND
- key_to_command_table[ (int) CONTROL('D') ] = CMD_DESTROY_ITEM;
-#else
- key_to_command_table[ (int) CONTROL('D') ] = CMD_NO_CMD;
-#endif
-
- key_to_command_table[ (int) CONTROL('E') ] = CMD_FORGET_STASH;
- key_to_command_table[ (int) CONTROL('F') ] = CMD_SEARCH_STASHES;
- key_to_command_table[ (int) CONTROL('G') ] = CMD_INTERLEVEL_TRAVEL;
- key_to_command_table[ (int) CONTROL('H') ] = CMD_OPEN_DOOR_LEFT;
- key_to_command_table[ (int) CONTROL('I') ] = CMD_NO_CMD;
- key_to_command_table[ (int) CONTROL('J') ] = CMD_OPEN_DOOR_DOWN;
- key_to_command_table[ (int) CONTROL('K') ] = CMD_OPEN_DOOR_UP;
- key_to_command_table[ (int) CONTROL('L') ] = CMD_OPEN_DOOR_RIGHT;
- key_to_command_table[ (int) CONTROL('M') ] = CMD_NO_CMD;
- key_to_command_table[ (int) CONTROL('N') ] = CMD_OPEN_DOOR_DOWN_RIGHT;
- key_to_command_table[ (int) CONTROL('O') ] = CMD_EXPLORE;
- key_to_command_table[ (int) CONTROL('P') ] = CMD_REPLAY_MESSAGES;
- key_to_command_table[ (int) CONTROL('Q') ] = CMD_NO_CMD;
- key_to_command_table[ (int) CONTROL('R') ] = CMD_REDRAW_SCREEN;
- key_to_command_table[ (int) CONTROL('S') ] = CMD_MARK_STASH;
- key_to_command_table[ (int) CONTROL('T') ] = CMD_NO_CMD;
- key_to_command_table[ (int) CONTROL('U') ] = CMD_OPEN_DOOR_UP_LEFT;
- key_to_command_table[ (int) CONTROL('V') ] = CMD_NO_CMD;
- key_to_command_table[ (int) CONTROL('W') ] = CMD_FIX_WAYPOINT;
- key_to_command_table[ (int) CONTROL('X') ] = CMD_SAVE_GAME_NOW;
- key_to_command_table[ (int) CONTROL('Y') ] = CMD_OPEN_DOOR_UP_RIGHT;
- key_to_command_table[ (int) CONTROL('Z') ] = CMD_SUSPEND_GAME;
-
- // other printables
- key_to_command_table[(int) '.'] = CMD_MOVE_NOWHERE;
- key_to_command_table[(int) '<'] = CMD_GO_UPSTAIRS;
- key_to_command_table[(int) '>'] = CMD_GO_DOWNSTAIRS;
- key_to_command_table[(int) '@'] = CMD_DISPLAY_CHARACTER_STATUS;
- key_to_command_table[(int) ','] = CMD_PICKUP;
- key_to_command_table[(int) ':'] = CMD_NO_CMD;
- key_to_command_table[(int) ';'] = CMD_INSPECT_FLOOR;
- key_to_command_table[(int) '!'] = CMD_SHOUT;
- key_to_command_table[(int) '^'] = CMD_DISPLAY_RELIGION;
- key_to_command_table[(int) '#'] = CMD_CHARACTER_DUMP;
- key_to_command_table[(int) '='] = CMD_ADJUST_INVENTORY;
- key_to_command_table[(int) '?'] = CMD_DISPLAY_COMMANDS;
- key_to_command_table[(int) '`'] = CMD_MACRO_ADD;
- key_to_command_table[(int) '~'] = CMD_MACRO_SAVE;
- key_to_command_table[(int) '&'] = CMD_WIZARD;
- key_to_command_table[(int) '"'] = CMD_LIST_JEWELLERY;
-
-
- // I'm making this both, because I'm tried of changing it
- // back to '[' (the character that represents armour on the map) -- bwr
- key_to_command_table[(int) '['] = CMD_LIST_ARMOUR;
- key_to_command_table[(int) ']'] = CMD_LIST_ARMOUR;
-
- // This one also ended up backwards this time, so it's also going on
- // both now -- should be ')'... the same character that's used to
- // represent weapons.
- key_to_command_table[(int) ')'] = CMD_LIST_WEAPONS;
- key_to_command_table[(int) '('] = CMD_LIST_WEAPONS;
-
- key_to_command_table[(int) '\\'] = CMD_DISPLAY_KNOWN_OBJECTS;
- key_to_command_table[(int) '\''] = CMD_WEAPON_SWAP;
-
- // digits
- key_to_command_table[(int) '0'] = CMD_NO_CMD;
- key_to_command_table[(int) '1'] = CMD_MOVE_DOWN_LEFT;
- key_to_command_table[(int) '2'] = CMD_MOVE_DOWN;
- key_to_command_table[(int) '3'] = CMD_MOVE_DOWN_RIGHT;
- key_to_command_table[(int) '4'] = CMD_MOVE_LEFT;
- key_to_command_table[(int) '5'] = CMD_REST;
- key_to_command_table[(int) '6'] = CMD_MOVE_RIGHT;
- key_to_command_table[(int) '7'] = CMD_MOVE_UP_LEFT;
- key_to_command_table[(int) '8'] = CMD_MOVE_UP;
- key_to_command_table[(int) '9'] = CMD_MOVE_UP_RIGHT;
-
- // keypad
- key_to_command_table[KEY_A1] = CMD_MOVE_UP_LEFT;
- key_to_command_table[KEY_A3] = CMD_MOVE_UP_RIGHT;
- key_to_command_table[KEY_C1] = CMD_MOVE_DOWN_LEFT;
- key_to_command_table[KEY_C3] = CMD_MOVE_DOWN_RIGHT;
-
- key_to_command_table[KEY_HOME] = CMD_MOVE_UP_LEFT;
- key_to_command_table[KEY_PPAGE] = CMD_MOVE_UP_RIGHT;
- key_to_command_table[KEY_END] = CMD_MOVE_DOWN_LEFT;
- key_to_command_table[KEY_NPAGE] = CMD_MOVE_DOWN_RIGHT;
-
- key_to_command_table[KEY_B2] = CMD_REST;
-
- key_to_command_table[KEY_UP] = CMD_MOVE_UP;
- key_to_command_table[KEY_DOWN] = CMD_MOVE_DOWN;
- key_to_command_table[KEY_LEFT] = CMD_MOVE_LEFT;
- key_to_command_table[KEY_RIGHT] = CMD_MOVE_RIGHT;
-
-
- // other odd things
- // key_to_command_table[ 263 ] = CMD_OPEN_DOOR_LEFT; // backspace
-
- // these are invalid keys, but to help kludge running
- // pass them through unmolested
- key_to_command_table[128] = 128;
- key_to_command_table[(int) '*'] = '*';
-}
-
-int key_to_command(int keyin)
-{
- bool is_userfunction(int key);
-
- if (is_userfunction(keyin))
- return keyin;
- return (key_to_command_table[keyin]);
-}
-
-void unixcurses_startup( void )
-{
- termio_init();
-
-#ifdef USE_UNIX_SIGNALS
-#ifdef SIGQUIT
- signal(SIGQUIT, SIG_IGN);
-#endif
-
-#ifdef SIGINT
- signal(SIGINT, SIG_IGN);
-#endif
-#endif
-
- //savetty();
-
- initscr();
- // cbreak();
- raw();
- noecho();
-
- nonl();
- intrflush(stdscr, FALSE);
-#ifdef CURSES_USE_KEYPAD
- keypad(stdscr, TRUE);
-
-#if CURSES_SET_ESCDELAY
- ESCDELAY = CURSES_SET_ESCDELAY;
-#endif
-#endif
- //cbreak();
-
- meta(stdscr, TRUE);
- start_color();
- setup_colour_pairs();
-
- init_key_to_command();
-
-#ifndef SOLARIS
- // These can cause some display problems under Solaris
- scrollok(stdscr, TRUE);
-#endif
-}
-
-
-void unixcurses_shutdown()
-{
- tcsetattr(0, TCSAFLUSH, &def_term);
-
-#ifdef USE_UNIX_SIGNALS
-#ifdef SIGQUIT
- signal(SIGQUIT, SIG_DFL);
-#endif
-
-#ifdef SIGINT
- signal(SIGINT, SIG_DFL);
-#endif
-#endif
-
- // resetty();
- endwin();
-}
-
-
-/* Convert value to string */
-int itoa(int value, char *strptr, int radix)
-{
- unsigned int bitmask = 32768;
- int ctr = 0;
- int startflag = 0;
-
- if (radix == 10)
- {
- sprintf(strptr, "%i", value);
- }
- if (radix == 2) /* int to "binary string" */
- {
- while (bitmask)
- {
- if (value & bitmask)
- {
- startflag = 1;
- sprintf(strptr + ctr, "1");
- }
- else
- {
- if (startflag)
- sprintf(strptr + ctr, "0");
- }
-
- bitmask = bitmask >> 1;
- if (startflag)
- ctr++;
- }
-
- if (!startflag) /* Special case if value == 0 */
- sprintf((strptr + ctr++), "0");
-
- strptr[ctr] = (char) NULL;
- }
- return (OK); /* Me? Fail? Nah. */
-}
-
-
-// Convert string to lowercase.
-char *strlwr(char *str)
-{
- unsigned int i;
-
- for (i = 0; i < strlen(str); i++)
- str[i] = tolower(str[i]);
-
- return (str);
-}
-
-
-int cprintf(const char *format,...)
-{
- int i;
- char buffer[2048]; // One full screen if no control seq...
-
- va_list argp;
-
- va_start(argp, format);
- vsprintf(buffer, format, argp);
- va_end(argp);
- i = addstr(buffer);
- refresh();
- return (i);
-}
-
-
-int putch(unsigned char chr)
-{
- if (chr == 0)
- chr = ' ';
-
- return (addch(chr));
-}
-
-
-char getche()
-{
- char chr;
-
- chr = getch();
- addch(chr);
- refresh();
- return (chr);
-}
-
-
-int window(int x1, int y1, int x2, int y2)
-{
- x1 = y1 = x2 = y2 = 0; /* Do something to them.. makes gcc happy :) */
- return (refresh());
-}
-
-// These next four are front functions so that we can reduce
-// the amount of curses special code that occurs outside this
-// this file. This is good, since there are some issues with
-// name space collisions between curses macros and the standard
-// C++ string class. -- bwr
-void update_screen(void)
-{
- refresh();
-}
-
-void clear_to_end_of_line(void)
-{
- textcolor( LIGHTGREY );
- textbackground( BLACK );
- clrtoeol();
-}
-
-void clear_to_end_of_screen(void)
-{
- textcolor( LIGHTGREY );
- textbackground( BLACK );
- clrtobot();
-}
-
-int get_number_of_lines_from_curses(void)
-{
- return (LINES);
-}
-
-void get_input_line_from_curses( char *const buff, int len )
-{
- echo();
- wgetnstr( stdscr, buff, len );
- noecho();
-}
-
-int clrscr()
-{
- int retval;
-
- textcolor( LIGHTGREY );
- textbackground( BLACK );
- retval = clear();
- refresh();
- return (retval);
-}
-
-
-void _setcursortype(int curstype)
-{
- curs_set(curstype);
-}
-
-inline unsigned get_brand(int col)
-{
- return (col & COLFLAG_FRIENDLY_MONSTER)? Options.friend_brand :
- (col & COLFLAG_ITEM_HEAP)? Options.heap_brand :
- (col & COLFLAG_WILLSTAB)? Options.stab_brand :
- (col & COLFLAG_MAYSTAB)? Options.may_stab_brand :
- CHATTR_NORMAL;
-}
-
-void textcolor(int col)
-{
- short fg, bg;
-
- FG_COL = col & 0x00ff;
- fg = translate_colour( macro_colour( FG_COL ) );
- bg = translate_colour( (BG_COL == BLACK) ? Options.background : BG_COL );
-
- // calculate which curses flags we need...
- unsigned int flags = 0;
-
-#ifdef USE_COLOUR_OPTS
- unsigned brand = get_brand(col);
- if (brand != CHATTR_NORMAL)
- {
- flags |= convert_to_curses_attr( brand );
-
- if ((brand & CHATTR_ATTRMASK) == CHATTR_HILITE)
- {
- bg = (brand & CHATTR_COLMASK) >> 8;
- if (fg == bg)
- fg = COLOR_BLACK;
- }
-
- // If we can't do a dark grey friend brand, then we'll
- // switch the colour to light grey.
- if (Options.no_dark_brand
- && fg == (COLOR_BLACK | COLFLAG_CURSES_BRIGHTEN)
- && bg == 0)
- {
- fg = COLOR_WHITE;
- }
- }
-#endif
-
- // curses typically uses A_BOLD to give bright foreground colour,
- // but various termcaps may disagree
- if (fg & COLFLAG_CURSES_BRIGHTEN)
- flags |= A_BOLD;
-
- // curses typically uses A_BLINK to give bright background colour,
- // but various termcaps may disagree (in whole or in part)
- if (bg & COLFLAG_CURSES_BRIGHTEN)
- flags |= A_BLINK;
-
- // Strip out all the bits above the raw 3-bit colour definition
- fg &= 0x0007;
- bg &= 0x0007;
-
- // figure out which colour pair we want
- const int pair = (fg == 0 && bg == 0) ? 63 : (bg * 8 + fg);
-
- attrset( COLOR_PAIR(pair) | flags | character_set );
-}
-
-
-void textbackground(int col)
-{
- short fg, bg;
-
- BG_COL = col & 0x00ff;
- fg = translate_colour( macro_colour( FG_COL ) );
- bg = translate_colour( (BG_COL == BLACK) ? Options.background : BG_COL );
-
- unsigned int flags = 0;
-
-#ifdef USE_COLOUR_OPTS
- unsigned brand = get_brand(col);
- if (brand != CHATTR_NORMAL)
- {
- flags |= convert_to_curses_attr( brand );
-
- if ((brand & CHATTR_ATTRMASK) == CHATTR_HILITE)
- {
- bg = (brand & CHATTR_COLMASK) >> 8;
- if (fg == bg)
- fg = COLOR_BLACK;
- }
-
- // If we can't do a dark grey friend brand, then we'll
- // switch the colour to light grey.
- if (Options.no_dark_brand
- && fg == (COLOR_BLACK | COLFLAG_CURSES_BRIGHTEN)
- && bg == 0)
- {
- fg = COLOR_WHITE;
- }
- }
-#endif
-
- // curses typically uses A_BOLD to give bright foreground colour,
- // but various termcaps may disagree
- if (fg & COLFLAG_CURSES_BRIGHTEN)
- flags |= A_BOLD;
-
- // curses typically uses A_BLINK to give bright background colour,
- // but various termcaps may disagree
- if (bg & COLFLAG_CURSES_BRIGHTEN)
- flags |= A_BLINK;
-
- // Strip out all the bits above the raw 3-bit colour definition
- fg &= 0x0007;
- bg &= 0x0007;
-
- // figure out which colour pair we want
- const int pair = (fg == 0 && bg == 0) ? 63 : (bg * 8 + fg);
-
- attrset( COLOR_PAIR(pair) | flags | character_set );
-}
-
-
-int gotoxy(int x, int y)
-{
- return (move(y - 1, x - 1));
-}
-
-
-int wherex()
-{
- int x, y;
-
- getyx(stdscr, y, x);
- return (x + 1);
-}
-
-
-int wherey()
-{
- int x, y;
-
- getyx(stdscr, y, x);
- return (y + 1);
-}
-
-
-int stricmp( const char *str1, const char *str2 )
-{
- return (strcmp(str1, str2));
-}
-
-
-void delay( unsigned long time )
-{
- usleep( time * 1000 );
-}
-
-
-/*
- Note: kbhit now in macro.cc
- */
-
-/* This is Juho Snellman's modified kbhit, to work with macros */
-int kbhit()
-{
- int i;
-
- nodelay(stdscr, TRUE);
- timeout(0); // apparently some need this to guarantee non-blocking -- bwr
- i = wgetch(stdscr);
- nodelay(stdscr, FALSE);
-
- if (i == -1)
- i = 0;
- else
- ungetch(i);
-
- return (i);
-}
diff --git a/stone_soup/crawl-ref/source/libunix.h b/stone_soup/crawl-ref/source/libunix.h
deleted file mode 100644
index c416733666..0000000000
--- a/stone_soup/crawl-ref/source/libunix.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef LIBUNIX_H
-#define LIBUNIX_H
-
-
-// Some replacement routines missing in gcc
-
-#define _NORMALCURSOR 1
-#define _NOCURSOR 0
-#define O_BINARY O_RDWR
-
-char *strlwr(char *str);
-char getche(void);
-
-int getch_ck(void);
-int clrscr(void);
-int cprintf(const char *format,...);
-int gotoxy(int x, int y);
-int itoa(int value, char *strptr, int radix);
-int kbhit(void);
-int key_to_command(int);
-int putch(unsigned char chr);
-int stricmp(const char *str1, const char *str2);
-int translate_keypad(int keyin);
-int wherex(void);
-int wherey(void);
-int window(int x1, int y1, int x2, int y2);
-void update_screen(void);
-void clear_to_end_of_line(void);
-void clear_to_end_of_screen(void);
-int get_number_of_lines_from_curses(void);
-void get_input_line_from_curses( char *const buff, int len );
-
-void _setcursortype(int curstype);
-void delay(unsigned long time);
-void init_key_to_command();
-void unixcurses_shutdown(void);
-void unixcurses_startup(void);
-void textbackground(int bg);
-void textcolor(int col);
-
-#ifndef _LIBUNIX_IMPLEMENTATION
-/* Some stuff from curses, to remove compiling warnings.. */
-extern "C"
-{
- int getstr(char *);
- int getch(void);
- int noecho(void);
- int echo(void);
-}
-#endif
-
-
-#endif
diff --git a/stone_soup/crawl-ref/source/libutil.cc b/stone_soup/crawl-ref/source/libutil.cc
deleted file mode 100644
index 734ae2dc0a..0000000000
--- a/stone_soup/crawl-ref/source/libutil.cc
+++ /dev/null
@@ -1,730 +0,0 @@
-/*
- * File: libutil.cc
- * Summary: Functions that may be missing from some systems
- * Written by: ?
- *
- * Modified for Crawl Reference by $Author$ on $Date$
- *
- * Change History (most recent first):
- *
- * <1> 2001/Nov/01 BWR Created
- *
- */
-
-#include "AppHdr.h"
-#include "defines.h"
-#include "libutil.h"
-#include "externs.h"
-#include <stdio.h>
-#include <ctype.h>
-#include <stdarg.h>
-#include <string.h>
-
-#ifdef WIN32CONSOLE
- #include <windows.h>
-
- #ifdef WINMM_PLAY_SOUNDS
- #include <mmsystem.h>
- #endif
-#endif
-
-#ifdef REGEX_PCRE
- // Statically link pcre on Windows
- #ifdef WIN32CONSOLE
- #define PCRE_STATIC
- #endif
-
- #include <pcre.h>
-#endif
-
-#ifdef REGEX_POSIX
- // Do we still need to include sys/types.h?
- #include <sys/types.h>
- #include <regex.h>
-#endif
-
-// Should return true if the filename contains nothing that
-// the shell can do damage with.
-bool shell_safe(const char *file)
-{
- int match = strcspn(file, "`$*?|><");
- return !(match >= 0 && file[match]);
-}
-
-void play_sound( const char *file )
-{
-#if defined(WINMM_PLAY_SOUNDS)
- // Check whether file exists, is readable, etc.?
- if (file && *file)
- sndPlaySound(file, SND_ASYNC | SND_NODEFAULT);
-#elif defined(SOUND_PLAY_COMMAND)
- char command[255];
- command[0] = '\0';
- if (file && *file && (strlen(file) + strlen(SOUND_PLAY_COMMAND) < 255)
- && shell_safe(file))
- {
- snprintf(command, sizeof command, SOUND_PLAY_COMMAND, file);
- system(command);
- }
-#endif
-}
-
-void get_input_line( char *const buff, int len )
-{
- buff[0] = '\0'; // just in case
-
-#if defined(UNIX)
- get_input_line_from_curses( buff, len ); // implemented in libunix.cc
-#elif defined(MAC) || defined(WIN32CONSOLE)
- getstr( buff, len ); // implemented in libmac.cc
-#else
- fgets( buff, len, stdin ); // much safer than gets()
-#endif
-
- buff[ len - 1 ] = '\0'; // just in case
-
- // Removing white space from the end in order to get rid of any
- // newlines or carriage returns that any of the above might have
- // left there (ie fgets especially). -- bwr
- const int end = strlen( buff );
- int i;
-
- for (i = end - 1; i >= 0; i++)
- {
- if (isspace( buff[i] ))
- buff[i] = '\0';
- else
- break;
- }
-}
-
-#ifdef DOS
-static int getch_ck() {
- int c = getch();
- if (!c) {
- switch (c = getch()) {
- case 'O': return CK_END;
- case 'P': return CK_DOWN;
- case 'I': return CK_PGUP;
- case 'H': return CK_UP;
- case 'G': return CK_HOME;
- case 'K': return CK_LEFT;
- case 'Q': return CK_PGDN;
- case 'M': return CK_RIGHT;
- case 119: return CK_CTRL_HOME;
- case 141: return CK_CTRL_UP;
- case 132: return CK_CTRL_PGUP;
- case 116: return CK_CTRL_RIGHT;
- case 118: return CK_CTRL_PGDN;
- case 145: return CK_CTRL_DOWN;
- case 117: return CK_CTRL_END;
- case 115: return CK_CTRL_LEFT;
- case 'S': return CK_DELETE;
- }
- }
- return c;
-}
-#endif
-
-// Hacky wrapper around getch() that returns CK_ codes for keys
-// we want to use in cancelable_get_line() and menus.
-int c_getch() {
-#if defined(DOS) || defined(LINUX) || defined(WIN32CONSOLE)
- return getch_ck();
-#else
- return getch();
-#endif
-}
-
-// cprintf that knows how to wrap down lines (primitive, but what the heck)
-int wrapcprintf( int wrapcol, const char *s, ... )
-{
- char buf[1000]; // Hard max
- va_list args;
- va_start(args, s);
-
- // XXX: If snprintf isn't available, vsnprintf probably isn't, either.
- int len = vsnprintf(buf, sizeof buf, s, args), olen = len;
- va_end(args);
-
- char *run = buf;
- while (len > 0)
- {
- int x = wherex(), y = wherey();
-
- if (x > wrapcol) // Somebody messed up!
- return 0;
-
- int avail = wrapcol - x + 1;
- int c = 0;
- if (len > avail) {
- c = run[avail];
- run[avail] = 0;
- }
- cprintf("%s", run);
-
- if (len > avail)
- run[avail] = c;
-
- if ((len -= avail) > 0)
- gotoxy(1, y + 1);
- run += avail;
- }
- return (olen);
-}
-
-#define WX(x) ( ((x) - 1) % maxcol + 1 )
-#define WY(x,y) ( (y) + ((x) - 1) / maxcol )
-#define WC(x,y) WX(x), WY(x,y)
-#define GOTOXY(x,y) gotoxy( WC(x,y) )
-bool cancelable_get_line( char *buf, int len, int maxcol,
- input_history *mh )
-{
- if (len <= 0) return false;
-
- buf[0] = 0;
-
- char *cur = buf;
- int start = wherex(), line = wherey();
- int length = 0, pos = 0;
-
- if (mh)
- mh->go_end();
-
- for ( ; ; ) {
- int ch = c_getch();
-
- switch (ch) {
- case CK_ESCAPE:
- return false;
- case CK_UP:
- case CK_DOWN:
- {
- if (!mh)
- break;
- const std::string *text = ch == CK_UP? mh->prev() : mh->next();
- if (text)
- {
- int olen = length;
- length = text->length();
- if (length >= len)
- length = len - 1;
- memcpy(buf, text->c_str(), length);
- buf[length] = 0;
- GOTOXY(start, line);
-
- int clear = length < olen? olen - length : 0;
- wrapcprintf(maxcol, "%s%*s", buf, clear, "");
-
- pos = length;
- cur = buf + pos;
- GOTOXY(start + pos, line);
- }
- break;
- }
- case CK_ENTER:
- buf[length] = 0;
- if (mh && length)
- mh->new_input(buf);
- return true;
- case CONTROL('K'):
- {
- // Kill to end of line
- int erase = length - pos;
- if (erase)
- {
- length = pos;
- buf[length] = 0;
- wrapcprintf( maxcol, "%*s", erase, "" );
- GOTOXY(start + pos, line);
- }
- break;
- }
- case CK_DELETE:
- if (pos < length) {
- char *c = cur;
- while (c - buf < length) {
- *c = c[1];
- c++;
- }
- --length;
-
- GOTOXY( start + pos, line );
- buf[length] = 0;
- wrapcprintf( maxcol, "%s ", cur );
- GOTOXY( start + pos, line );
- }
- break;
- case CK_BKSP:
- if (pos) {
- --cur;
- char *c = cur;
- while (*c) {
- *c = c[1];
- c++;
- }
- --pos;
- --length;
-
- GOTOXY( start + pos, line );
- buf[length] = 0;
- wrapcprintf( maxcol, "%s ", cur );
- GOTOXY( start + pos, line );
- }
- break;
- case CK_LEFT:
- if (pos) {
- --pos;
- cur = buf + pos;
- GOTOXY( start + pos, line );
- }
- break;
- case CK_RIGHT:
- if (pos < length) {
- ++pos;
- cur = buf + pos;
- GOTOXY( start + pos, line );
- }
- break;
- case CK_HOME:
- case CONTROL('A'):
- pos = 0;
- cur = buf + pos;
- GOTOXY( start + pos, line );
- break;
- case CK_END:
- case CONTROL('E'):
- pos = length;
- cur = buf + pos;
- GOTOXY( start + pos, line );
- break;
- default:
- if (isprint(ch) && length < len - 1) {
- if (pos < length) {
- char *c = buf + length - 1;
- while (c >= cur) {
- c[1] = *c;
- c--;
- }
- }
- *cur++ = (char) ch;
- ++length;
- ++pos;
- putch(ch);
- if (pos < length) {
- buf[length] = 0;
- wrapcprintf( maxcol, "%s", cur );
- }
- GOTOXY(start + pos, line);
- }
- break;
- }
- }
-}
-#undef GOTOXY
-#undef WC
-#undef WX
-#undef WY
-
-// also used with macros
-std::string & trim_string( std::string &str )
-{
- // OK, this is really annoying. Borland C++ seems to define
- // basic_string::erase to take iterators, and basic_string::remove
- // to take size_t or integer. This is ass-backwards compared to
- // nearly all other C++ compilers. Crap. (GDL)
- //
- // Borland 5.5 does this correctly now... leaving the old code
- // around for now in case anyone needs it. -- bwr
-// #ifdef __BCPLUSPLUS__
-// str.remove( 0, str.find_first_not_of( " \t\n\r" ) );
-// str.remove( str.find_last_not_of( " \t\n\r" ) + 1 );
-// #else
- str.erase( 0, str.find_first_not_of( " \t\n\r" ) );
- str.erase( str.find_last_not_of( " \t\n\r" ) + 1 );
-// #endif
-
- return (str);
-}
-
-std::vector<std::string> split_string(const char *sep, std::string s)
-{
- std::vector<std::string> segments;
-
- std::string::size_type pos;
- while ((pos = s.find(sep, 0)) != std::string::npos) {
- if (pos > 0)
- segments.push_back(s.substr(0, pos));
- s.erase(0, pos + 1);
- }
- if (s.length() > 0)
- segments.push_back(s);
-
- for (int i = 0, count = segments.size(); i < count; ++i)
- trim_string(segments[i]);
- return segments;
-}
-
-// The old school way of doing short delays via low level I/O sync.
-// Good for systems like old versions of Solaris that don't have usleep.
-#ifdef NEED_USLEEP
-
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/unistd.h>
-
-void usleep(unsigned long time)
-{
- struct timeval timer;
-
- timer.tv_sec = (time / 1000000L);
- timer.tv_usec = (time % 1000000L);
-
- select(0, NULL, NULL, NULL, &timer);
-}
-#endif
-
-// Not the greatest version of snprintf, but a functional one that's
-// a bit safer than raw sprintf(). Note that this doesn't do the
-// special behaviour for size == 0, largely because the return value
-// in that case varies depending on which standard is being used (SUSv2
-// returns an unspecified value < 1, whereas C99 allows str == NULL
-// and returns the number of characters that would have been written). -- bwr
-#ifdef NEED_SNPRINTF
-
-#include <string.h>
-
-int snprintf( char *str, size_t size, const char *format, ... )
-{
- va_list argp;
- va_start( argp, format );
-
- char buff[ 10 * size ]; // hopefully enough
-
- vsprintf( buff, format, argp );
- strncpy( str, buff, size );
- str[ size - 1 ] = '\0';
-
- int ret = strlen( str );
- if ((unsigned int) ret == size - 1 && strlen( buff ) >= size)
- ret = -1;
-
- va_end( argp );
-
- return (ret);
-}
-
-#endif
-
-///////////////////////////////////////////////////////////////////////
-// Pattern matching
-
-inline int pm_lower(int ch, bool icase) {
- return icase? tolower(ch) : ch;
-}
-
-// Determines whether the pattern specified by 'pattern' matches the given
-// text. A pattern is a simple glob, with the traditional * and ? wildcards.
-static bool glob_match( const char *pattern, const char *text, bool icase )
-{
- char p, t;
- bool special;
-
- for (;;)
- {
- p = pm_lower(*pattern++, icase);
- t = pm_lower(*text++, icase);
- special = true;
-
- if (!p) return t == 0;
- if (p == '\\' && *pattern)
- {
- p = pm_lower(*pattern++, icase);
- special = false;
- }
-
- if (p == '*' && special)
- // Try to match exactly at the current text position...
- return !*pattern || glob_match(pattern, text - 1, icase)? true :
- // Or skip one character in the text and try the wildcard
- // match again. If this is the end of the text, the match has
- // failed.
- t? glob_match(pattern - 1, text, icase) : false;
- else if (!t || (p != t && (p != '?' || !special)))
- return false;
- }
-}
-
-#if defined(REGEX_PCRE)
-////////////////////////////////////////////////////////////////////
-// Perl Compatible Regular Expressions
-
-void *compile_pattern(const char *pattern, bool icase) {
- const char *error;
- int erroffset;
- int flags = icase? PCRE_CASELESS : 0;
- return pcre_compile(pattern,
- flags,
- &error,
- &erroffset,
- NULL);
-}
-
-void free_compiled_pattern(void *cp) {
- if (cp)
- pcre_free(cp);
-}
-
-bool pattern_match(void *compiled_pattern, const char *text, int length)
-{
- int ovector[42];
- int pcre_rc = pcre_exec(static_cast<pcre *>(compiled_pattern),
- NULL,
- text,
- length,
- 0,
- 0,
- ovector,
- sizeof(ovector) / sizeof(*ovector));
- return (pcre_rc >= 0);
-}
-
-////////////////////////////////////////////////////////////////////
-#elif defined(REGEX_POSIX)
-////////////////////////////////////////////////////////////////////
-// POSIX regular expressions
-
-void *compile_pattern(const char *pattern, bool icase) {
- regex_t *re = new regex_t;
- if (!re)
- return NULL;
-
- int flags = REG_EXTENDED | REG_NOSUB;
- if (icase)
- flags |= REG_ICASE;
- int rc = regcomp(re, pattern, flags);
- // Nonzero return code == failure
- if (rc) {
- delete re;
- return NULL;
- }
- return re;
-}
-
-void free_compiled_pattern(void *cp) {
- if (cp) {
- regex_t *re = static_cast<regex_t *>( cp );
- regfree(re);
- delete re;
- }
-}
-
-bool pattern_match(void *compiled_pattern, const char *text, int length)
-{
- regex_t *re = static_cast<regex_t *>( compiled_pattern );
- return !regexec(re, text, 0, NULL, 0);
-}
-
-////////////////////////////////////////////////////////////////////
-#else
-////////////////////////////////////////////////////////////////////
-// Basic glob
-
-struct glob_info
-{
- std::string s;
- bool ignore_case;
-};
-
-void *compile_pattern(const char *pattern, bool icase)
-{
- // If we're using simple globs, we need to box the pattern with '*'
- std::string s = std::string("*") + pattern + "*";
- glob_info *gi = new glob_info;
- if (gi) {
- gi->s = s;
- gi->ignore_case = icase;
- }
- return gi;
-}
-
-void free_compiled_pattern(void *compiled_pattern)
-{
- delete static_cast<glob_info *>( compiled_pattern );
-}
-
-bool pattern_match(void *compiled_pattern, const char *text, int length)
-{
- glob_info *gi = static_cast<glob_info *>( compiled_pattern );
- return glob_match(gi->s.c_str(), text, gi->ignore_case);
-}
-////////////////////////////////////////////////////////////////////
-
-#endif
-
-
-
-////////////////////////////////////////////////////////////////////
-// formatted_string
-//
-
-formatted_string::formatted_string(const std::string &s)
- : ops()
-{
- ops.push_back( s );
-}
-
-formatted_string::operator std::string() const
-{
- std::string s;
- for (int i = 0, size = ops.size(); i < size; ++i)
- {
- if (ops[i] == FSOP_TEXT)
- s += ops[i].text;
- }
- return s;
-}
-
-inline void cap(int &i, int max)
-{
- if (i < 0 && -i <= max)
- i += max;
- if (i >= max)
- i = max - 1;
- if (i < 0)
- i = 0;
-}
-
-std::string formatted_string::tostring(int s, int e) const
-{
- std::string st;
-
- int size = ops.size();
- cap(s, size);
- cap(e, size);
-
- for (int i = s; i <= e && i < size; ++i)
- {
- if (ops[i] == FSOP_TEXT)
- st += ops[i].text;
- }
- return st;
-}
-
-void formatted_string::display(int s, int e) const
-{
- int size = ops.size();
- if (!size)
- return ;
-
- cap(s, size);
- cap(e, size);
-
- for (int i = s; i <= e && i < size; ++i)
- ops[i].display();
-}
-
-void formatted_string::gotoxy(int x, int y)
-{
- ops.push_back( fs_op(x, y) );
-}
-
-void formatted_string::textcolor(int color)
-{
- ops.push_back(color);
-}
-
-void formatted_string::cprintf(const char *s, ...)
-{
- char buf[1000];
- va_list args;
- va_start(args, s);
- vsnprintf(buf, sizeof buf, s, args);
- va_end(args);
-
- cprintf(std::string(buf));
-}
-
-void formatted_string::cprintf(const std::string &s)
-{
- ops.push_back(s);
-}
-
-void formatted_string::fs_op::display() const
-{
- switch (type)
- {
- case FSOP_CURSOR:
- {
- int cx = (x == -1? wherex() : x);
- int cy = (y == -1? wherey() : y);
- ::gotoxy(cx, cy);
- break;
- }
- case FSOP_COLOUR:
- ::textcolor(x);
- break;
- case FSOP_TEXT:
- ::cprintf("%s", text.c_str());
- break;
- }
-}
-
-/////////////////////////////////////////////////////////////
-// input_history
-//
-
-input_history::input_history(size_t size)
- : history(), pos(), maxsize(size)
-{
- if (maxsize < 2)
- maxsize = 2;
-
- pos = history.end();
-}
-
-void input_history::new_input(const std::string &s)
-{
- history.remove(s);
-
- if (history.size() == maxsize)
- history.pop_front();
-
- history.push_back(s);
-
- // Force the iterator to the end (also revalidates it)
- go_end();
-}
-
-const std::string *input_history::prev()
-{
- if (history.empty())
- return NULL;
-
- if (pos == history.begin())
- pos = history.end();
-
- return &*--pos;
-}
-
-const std::string *input_history::next()
-{
- if (history.empty())
- return NULL;
-
- if (pos == history.end() || ++pos == history.end())
- pos = history.begin();
-
- return &*pos;
-}
-
-void input_history::go_end()
-{
- pos = history.end();
-}
-
-void input_history::clear()
-{
- history.clear();
- go_end();
-}
diff --git a/stone_soup/crawl-ref/source/libutil.h b/stone_soup/crawl-ref/source/libutil.h
deleted file mode 100644
index 807d3f25a2..0000000000
--- a/stone_soup/crawl-ref/source/libutil.h
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * File: libutil.h
- * Summary: System indepentant functions
- *
- * Change History (most recent first):
- *
- * <1> 2001/Nov/01 BWR Created
- *
- */
-
-#ifndef LIBUTIL_H
-#define LIBUTIL_H
-
-#include <string>
-#include <vector>
-
-// getch() that returns a consistent set of values for all platforms.
-int c_getch();
-
-void play_sound(const char *file);
-
-// Pattern matching
-void *compile_pattern(const char *pattern, bool ignore_case = false);
-void free_compiled_pattern(void *cp);
-bool pattern_match(void *compiled_pattern, const char *text, int length);
-
-void get_input_line( char *const buff, int len );
-
-class input_history;
-
-// Returns true if user pressed Enter, false if user hit Escape.
-bool cancelable_get_line( char *buf, int len, int wrapcol = 80,
- input_history *mh = NULL );
-
-std::string & trim_string( std::string &str );
-std::vector<std::string> split_string(const char *sep, std::string s);
-
-#ifdef NEED_USLEEP
-void usleep( unsigned long time );
-#endif
-
-#ifdef NEED_SNPRINTF
-int snprintf( char *str, size_t size, const char *format, ... );
-#endif
-
-// Keys that getch() must return for keys Crawl is interested in.
-enum KEYS
-{
- CK_ENTER = '\r',
- CK_BKSP = 8,
- CK_ESCAPE = '\x1b',
-
- // 128 is off-limits because it's the code that's used when running
- CK_DELETE = 129,
-
- // This sequence of enums should not be rearranged.
- CK_UP,
- CK_DOWN,
- CK_LEFT,
- CK_RIGHT,
-
- CK_INSERT,
-
- CK_HOME,
- CK_END,
- CK_CLEAR,
-
- CK_PGUP,
- CK_PGDN,
-
- CK_SHIFT_UP,
- CK_SHIFT_DOWN,
- CK_SHIFT_LEFT,
- CK_SHIFT_RIGHT,
-
- CK_SHIFT_INSERT,
-
- CK_SHIFT_HOME,
- CK_SHIFT_END,
- CK_SHIFT_CLEAR,
-
- CK_SHIFT_PGUP,
- CK_SHIFT_PGDN,
-
- CK_CTRL_UP,
- CK_CTRL_DOWN,
- CK_CTRL_LEFT,
- CK_CTRL_RIGHT,
-
- CK_CTRL_INSERT,
-
- CK_CTRL_HOME,
- CK_CTRL_END,
- CK_CTRL_CLEAR,
-
- CK_CTRL_PGUP,
- CK_CTRL_PGDN
-};
-
-class base_pattern
-{
-public:
- virtual ~base_pattern() { };
-
- virtual bool valid() const = 0;
- virtual bool matches(const std::string &s) const = 0;
-};
-
-class text_pattern : public base_pattern
-{
-public:
- text_pattern(const std::string &s, bool icase = false)
- : pattern(s), compiled_pattern(NULL),
- isvalid(true), ignore_case(icase)
- {
- }
-
- text_pattern()
- : pattern(), compiled_pattern(NULL),
- isvalid(false), ignore_case(false)
- {
- }
-
- text_pattern(const text_pattern &tp)
- : pattern(tp.pattern),
- compiled_pattern(NULL),
- isvalid(tp.isvalid),
- ignore_case(tp.ignore_case)
- {
- }
-
- ~text_pattern()
- {
- if (compiled_pattern)
- free_compiled_pattern(compiled_pattern);
- }
-
- const text_pattern &operator= (const text_pattern &tp)
- {
- if (this == &tp)
- return tp;
-
- if (compiled_pattern)
- free_compiled_pattern(compiled_pattern);
- pattern = tp.pattern;
- compiled_pattern = NULL;
- isvalid = tp.isvalid;
- ignore_case = tp.ignore_case;
- return *this;
- }
-
- const text_pattern &operator= (const std::string &spattern)
- {
- if (pattern == spattern)
- return *this;
-
- if (compiled_pattern)
- free_compiled_pattern(compiled_pattern);
- pattern = spattern;
- compiled_pattern = NULL;
- isvalid = true;
- // We don't change ignore_case
- return *this;
- }
-
- bool compile() const
- {
- // This function is const because compiled_pattern is not really part of
- // the state of the object.
-
- void *&cp = const_cast<text_pattern*>( this )->compiled_pattern;
- return !empty()?
- !!(cp = compile_pattern(pattern.c_str(), ignore_case))
- : false;
- }
-
- bool empty() const
- {
- return !pattern.length();
- }
-
- bool valid() const
- {
- return isvalid &&
- (compiled_pattern ||
- (const_cast<text_pattern*>( this )->isvalid = compile()));
- }
-
- bool matches(const char *s, int length) const
- {
- return valid() && pattern_match(compiled_pattern, s, length);
- }
-
- bool matches(const char *s) const
- {
- return matches(std::string(s));
- }
-
- bool matches(const std::string &s) const
- {
- return matches(s.c_str(), s.length());
- }
-
- const std::string &tostring() const
- {
- return pattern;
- }
-
-private:
- std::string pattern;
- void *compiled_pattern;
- bool isvalid;
- bool ignore_case;
-};
-
-
-#endif
diff --git a/stone_soup/crawl-ref/source/libw32c.cc b/stone_soup/crawl-ref/source/libw32c.cc
deleted file mode 100644
index 975e14e641..0000000000
--- a/stone_soup/crawl-ref/source/libw32c.cc
+++ /dev/null
@@ -1,838 +0,0 @@
-/*
- * File: libw32c.cc
- * Summary: Functions for windows32 console mode support
- * Written by: Gordon Lipford
- *
- * Change History (most recent first):
- *
- * <2> 8 Mar 2001 GDL Rewrite to use low level IO
- * <1> 1 Mar 2000 GDL Created
- *
- */
-
-// WINDOWS INCLUDES GO HERE
-/*
- * Exclude parts of WINDOWS.H that are not needed
- */
-#define NOCOMM /* Comm driver APIs and definitions */
-#define NOLOGERROR /* LogError() and related definitions */
-#define NOPROFILER /* Profiler APIs */
-#define NOLFILEIO /* _l* file I/O routines */
-#define NOOPENFILE /* OpenFile and related definitions */
-#define NORESOURCE /* Resource management */
-#define NOATOM /* Atom management */
-#define NOLANGUAGE /* Character test routines */
-#define NOLSTRING /* lstr* string management routines */
-#define NODBCS /* Double-byte character set routines */
-#define NOKEYBOARDINFO /* Keyboard driver routines */
-#define NOCOLOR /* COLOR_* color values */
-#define NODRAWTEXT /* DrawText() and related definitions */
-#define NOSCALABLEFONT /* Truetype scalable font support */
-#define NOMETAFILE /* Metafile support */
-#define NOSYSTEMPARAMSINFO /* SystemParametersInfo() and SPI_* definitions */
-#define NODEFERWINDOWPOS /* DeferWindowPos and related definitions */
-#define NOKEYSTATES /* MK_* message key state flags */
-#define NOWH /* SetWindowsHook and related WH_* definitions */
-#define NOCLIPBOARD /* Clipboard APIs and definitions */
-#define NOICONS /* IDI_* icon IDs */
-#define NOMDI /* MDI support */
-#define NOCTLMGR /* Control management and controls */
-#define NOHELP /* Help support */
-
-/*
- * Exclude parts of WINDOWS.H that are not needed (Win32)
- */
-#define WIN32_LEAN_AND_MEAN
-#define NONLS /* All NLS defines and routines */
-#define NOSERVICE /* All Service Controller routines, SERVICE_ equates, etc. */
-#define NOKANJI /* Kanji support stuff. */
-#define NOMCX /* Modem Configuration Extensions */
-#ifndef _X86_
-#define _X86_ /* target architecture */
-#endif
-
-#include <excpt.h>
-#include <stdarg.h>
-#include <windef.h>
-#include <winbase.h>
-#include <wingdi.h>
-#include <winuser.h>
-#include <winnls.h>
-#include <wincon.h>
-
-// END -- WINDOWS INCLUDES
-
-#include <string.h>
-#ifdef __BCPLUSPLUS__
-#include <stdio.h>
-#endif
-#include "AppHdr.h"
-#include "version.h"
-#include "defines.h"
-#include "view.h"
-#include "libutil.h"
-
-char oldTitle[80];
-
-static HANDLE inbuf = NULL;
-static HANDLE outbuf = NULL;
-static int current_color = -1;
-static bool current_cursor = _NOCURSOR;
-// dirty line (sx,ex,y)
-static int chsx=0, chex=0, chy=-1;
-// cursor position (start at 0,0 --> 1,1)
-static int cx=0, cy=0;
-
-//static FILE *foo = NULL; //DEBUG
-
-// and now, for the screen buffer
-static CHAR_INFO screen[80 * WIN_NUMBER_OF_LINES];
-static COORD screensize;
-#define SCREENINDEX(x,y) (x)+80*(y)
-static bool buffering = false;
-// static const char *windowTitle = "Crawl " VERSION;
-static unsigned InputCP, OutputCP;
-static const unsigned PREFERRED_CODEPAGE = 437;
-
-// we can do straight translation of DOS color to win32 console color.
-#define WIN32COLOR(col) (WORD)(col)
-static void writeChar(char c);
-static void bFlush(void);
-static void _setcursortype_internal(int curstype);
-
-// [ds] Unused for portability reasons
-/*
-static DWORD crawlColorData[16] =
-// BGR data, easier to put in registry
-{
- 0x00000000, // BLACK
- 0x00ff00cd, // BLUE
- 0x0046b964, // GREEN
- 0x00b4b400, // CYAN
- 0x000085ff, // RED
- 0x00ee82ee, // MAGENTA
- 0x005a6fcd, // BROWN
- 0x00c0c0c0, // LT GREY
- 0x00808080, // DK GREY
- 0x00ff8600, // LT BLUE
- 0x0000ff85, // LT GREEN
- 0x00ffff00, // LT CYAN
- 0x000000ff, // LT RED
- 0x00bf7091, // LT MAGENTA
- 0x0000ffff, // YELLOW
- 0x00ffffff // WHITE
-};
- */
-
-//#define TIMING_INFO
-#ifdef TIMING_INFO
-
-#include <time.h>
-#include "message.h"
-
-// TIMING info
-static int ncalls[6] = { 0,0,0,0,0,0 };
-static double runavg[6] = { 0.0,0.0,0.0,0.0,0.0,0.0 };
-static int oob[6] = { 0,0,0,0,0,0 };
-static int dlen[6] = { 0,0,0,0,0,0 };
-static LARGE_INTEGER t1, t2;
-
-static void addcall(int i, LARGE_INTEGER &tm1, LARGE_INTEGER &tm2)
-{
- double d = tm2.QuadPart - tm1.QuadPart;
-
- runavg[i] = (runavg[i] * ncalls[i] + d) / (ncalls[i] + 1);
- ncalls[i] ++;
-
- // oob
- if (ncalls[i] > 10)
- {
- if (d > 1.4*runavg[i])
- oob[i] ++;
- }
-}
-
-#define CLOCKIN {QueryPerformanceCounter(&t1);}
-#define CLOCKOUT(x) {QueryPerformanceCounter(&t2); \
- addcall((x), t1, t2);}
-
-static char *descrip[] = {
- "bflush:WriteConsoleOutput",
- "_setCursorType:SetConsoleCursorInfo",
- "gotoxy:SetConsoleCursorPosition",
- "textcolor:SetConsoleTextAttribute",
- "cprintf:WriteConsole",
- "getch:ReadConsoleInput"
-};
-
-void print_timings(void)
-{
- int i;
- char s[100];
-
- LARGE_INTEGER cps;
- QueryPerformanceFrequency(&cps);
-
- sprintf(s, "Avg (#/oob), CpS = %.1lf", cps.QuadPart);
- mpr(s);
- for(i=0; i<3; i++)
- {
- int dl = 0;
- if (ncalls[i] > 0)
- dl = dlen[i] / ncalls[i];
- sprintf(s, "%-40s %.1f us (%d/%d), avg dlen = %d", descrip[i],
- (1000000.0 * runavg[i]) / cps.QuadPart, ncalls[i], oob[i], dl);
- mpr(s);
- }
-}
-
-#else
-
-#define CLOCKIN
-#define CLOCKOUT(x)
-
-void print_timings()
-{ ; }
-
-#endif // TIMING INFO
-
-void writeChar(char c)
-{
- bool noop = true;
- PCHAR_INFO pci;
-
- // check for CR: noop
- if (c == 0x0D)
- return;
-
- // check for newline
- if (c == 0x0A)
- {
- // must flush current buffer
- bFlush();
-
- // reposition
- gotoxy(1, cy+2);
-
- return;
- }
-
- int tc = WIN32COLOR(current_color);
- pci = &screen[SCREENINDEX(cx,cy)];
-
- // is this a no-op?
- if (pci->Char.AsciiChar != c)
- noop = false;
- else if (pci->Attributes != tc)
- noop = false;
-
- if (!noop)
- {
- // write the info and update the dirty area
- pci->Char.AsciiChar = c;
- pci->Attributes = tc;
-
- if (chy < 0)
- chsx = cx;
- chy = cy;
- chex = cx;
-
- // if we're not buffering, flush
- if (!buffering)
- bFlush();
- }
-
- // update x position
- cx += 1;
- if (cx >= 80) cx = 80;
-}
-
-void bFlush(void)
-{
- COORD source;
- SMALL_RECT target;
-
- // see if we have a dirty area
- if (chy < 0)
- return;
-
- // set up call
- source.X = chsx;
- source.Y = chy;
-
- target.Left = chsx;
- target.Top = chy;
- target.Right = chex;
- target.Bottom = chy;
-
- CLOCKIN
- WriteConsoleOutput(outbuf, screen, screensize, source, &target);
- CLOCKOUT(0)
-
- chy = -1;
-
- // if cursor is not NOCURSOR, update screen
- if (current_cursor != _NOCURSOR)
- {
- COORD xy;
- xy.X = cx;
- xy.Y = cy;
- CLOCKIN
- if (SetConsoleCursorPosition(outbuf, xy) == 0)
- fputs("SetConsoleCursorPosition() failed!", stderr);
- CLOCKOUT(2)
- }
-}
-
-
-void setStringInput(bool value)
-{
- DWORD inmodes, outmodes;
- if (value == TRUE)
- {
- inmodes = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT;
- outmodes = ENABLE_PROCESSED_OUTPUT;
- }
- else
- {
- inmodes = 0;
- outmodes = 0;
- }
-
- if ( SetConsoleMode( inbuf, inmodes ) == 0) {
- fputs("Error initialising console input mode.", stderr);
- exit(0);
- }
-
- if ( SetConsoleMode( outbuf, outmodes ) == 0) {
- fputs("Error initialising console output mode.", stderr);
- exit(0);
- }
-
- // now flush it
- FlushConsoleInputBuffer( inbuf );
-}
-
-// this apparently only works for Win2K+ and ME+
-
-static void init_colors(char *windowTitle)
-{
- UNUSED( windowTitle );
-
- // look up the Crawl shortcut
-
- // if found, modify the colortable entries in the NT_CONSOLE_PROPS
- // structure.
-
- // if not found, quit.
-}
-
-void init_libw32c(void)
-{
- inbuf = GetStdHandle( STD_INPUT_HANDLE );
- outbuf = GetStdHandle( STD_OUTPUT_HANDLE );
-
- if (inbuf == INVALID_HANDLE_VALUE || outbuf == INVALID_HANDLE_VALUE) {
- fputs("Could not initialise libw32c console support.", stderr);
- exit(0);
- }
-
- GetConsoleTitle( oldTitle, 78 );
- SetConsoleTitle( "Crawl Stone Soup " VERSION );
-
- init_colors(oldTitle);
-
- // by default, set string input to false: use char-input only
- setStringInput( false );
- if (SetConsoleMode( outbuf, 0 ) == 0) {
- fputs("Error initialising console output mode.", stderr);
- exit(0);
- }
-
- // set up screen size
- screensize.X = 80;
- screensize.Y = get_number_of_lines();
-
- // initialise text color
- textcolor(DARKGREY);
-
- // initialise cursor to NONE.
- _setcursortype_internal(_NOCURSOR);
-
- // buffering defaults to ON -- very important!
- setBuffering(true);
-
- //DEBUG
- //foo = fopen("debug.txt", "w");
-
-
- // JWM, 06/12/2004: Code page setting, as XP does not use ANSI 437 by
- // default.
- InputCP = GetConsoleCP();
- OutputCP = GetConsoleOutputCP();
-
- // DS: Don't kill Crawl if we can't set the codepage. Windows 95/98/ME don't
- // have support for setting the input and output codepage. I'm also not
- // convinced we need to set the input codepage at all.
- if (InputCP != PREFERRED_CODEPAGE)
- SetConsoleCP(PREFERRED_CODEPAGE);
-
- if (OutputCP != PREFERRED_CODEPAGE)
- SetConsoleOutputCP(PREFERRED_CODEPAGE);
-}
-
-void deinit_libw32c(void)
-{
- // don't do anything if we were never initted
- if (inbuf == NULL || outbuf == NULL)
- return;
-
- // JWM, 06/12/2004: Code page stuff. If it was the preferred code page, it
- // doesn't need restoring. Shouldn't be an error and too bad if there is.
- if (InputCP && InputCP != PREFERRED_CODEPAGE)
- SetConsoleCP(InputCP);
-
- if (OutputCP && OutputCP != PREFERRED_CODEPAGE)
- SetConsoleOutputCP(OutputCP);
-
- // restore console attributes for normal function
- setStringInput(true);
-
- // set cursor and normal textcolor
- _setcursortype_internal(_NORMALCURSOR);
- textcolor(DARKGREY);
-
- // finally, restore title
- SetConsoleTitle( oldTitle );
-}
-
-// we don't take our cues from Crawl. Cursor is shown
-// only on input.
-void _setcursortype(int curstype)
-{
- UNUSED( curstype );
- ;
-}
-
-
-void _setcursortype_internal(int curstype)
-{
- CONSOLE_CURSOR_INFO cci;
-
- if (curstype == current_cursor)
- return;
-
- cci.dwSize = 5;
- cci.bVisible = (bool)curstype;
- current_cursor = curstype;
- CLOCKIN
- SetConsoleCursorInfo( outbuf, &cci );
- CLOCKOUT(1)
-
- // now, if we just changed from NOCURSOR to CURSOR,
- // actually move screen cursor
- if (current_cursor != _NOCURSOR)
- gotoxy(cx+1, cy+1);
-}
-
-void clrscr(void)
-{
- int x,y;
- COORD source;
- SMALL_RECT target;
-
- const int num_lines = get_number_of_lines();
-
- PCHAR_INFO pci = screen;
-
- for(x=0; x<80; x++)
- {
- for(y=0; y<num_lines; y++)
- {
- pci->Char.AsciiChar = ' ';
- pci->Attributes = 0;
- pci++;
- }
- }
-
- source.X = 0;
- source.Y = 0;
- target.Left = 0;
- target.Top = 0;
- target.Right = 79;
- target.Bottom = num_lines - 1;
-
- WriteConsoleOutput(outbuf, screen, screensize, source, &target);
-
- // reset cursor to 1,1 for convenience
- gotoxy(1,1);
-}
-
-void gotoxy(int x, int y)
-{
- const int num_lines = get_number_of_lines();
-
- // always flush on goto
- bFlush();
-
- // bounds check
- if (x<1)
- x=1;
- if (x>80)
- x=80;
- if (y<1)
- y=1;
- if (y>num_lines)
- y=num_lines;
-
- // change current cursor
- cx = x-1;
- cy = y-1;
-
- // if cursor is not NOCURSOR, update screen
- if (current_cursor != _NOCURSOR)
- {
- COORD xy;
- xy.X = cx;
- xy.Y = cy;
- CLOCKIN
- if (SetConsoleCursorPosition(outbuf, xy) == 0)
- fputs("SetConsoleCursorPosition() failed!", stderr);
- CLOCKOUT(2)
- }
-}
-
-void textcolor(int c)
-{
- // change current color used to stamp chars
- current_color = c;
-}
-
-static void cprintf_aux(const char *s)
-{
- // early out -- not initted yet
- if (outbuf == NULL)
- {
- printf(s);
- return;
- }
-
- // turn buffering ON (temporarily)
- bool oldValue = buffering;
- setBuffering(true);
-
- // loop through string
- char *p = (char *)s;
- while(*p)
- {
- if (p[0] == '%' && p[1] == '%')
- {
- p++;
- continue;
- }
- writeChar(*p++);
- }
-
- // reset buffering
- setBuffering(oldValue);
-
- // flush string
- bFlush();
-}
-
-void cprintf(const char *format, ...)
-{
- va_list argp;
- char buffer[4096]; // one could hope it's enough
-
- va_start( argp, format );
-
- vsprintf(buffer, format, argp);
- cprintf_aux(buffer);
-
- va_end(argp);
-}
-
-void window(int x, int y, int lx, int ly)
-{
- // do nothing
- UNUSED( x );
- UNUSED( y );
- UNUSED( lx );
- UNUSED( ly );
-}
-
-int wherex(void)
-{
- return cx+1;
-}
-
-int wherey(void)
-{
- return cy+1;
-}
-
-void putch(char c)
-{
- // special case: check for '0' char: map to space
- if (c==0)
- c = ' ';
-
- writeChar(c);
-}
-
-// translate virtual keys
-
-#define VKEY_MAPPINGS 10
-static int vk_tr[4][VKEY_MAPPINGS] = // virtual key, unmodified, shifted, control
- {
- { VK_END, VK_DOWN, VK_NEXT, VK_LEFT, VK_CLEAR, VK_RIGHT, VK_HOME, VK_UP, VK_PRIOR, VK_INSERT },
- { CK_END, CK_DOWN, CK_PGDN, CK_LEFT, CK_CLEAR, CK_RIGHT, CK_HOME, CK_UP, CK_PGUP , CK_INSERT },
- { CK_SHIFT_END, CK_SHIFT_DOWN, CK_SHIFT_PGDN, CK_SHIFT_LEFT, CK_SHIFT_CLEAR, CK_SHIFT_RIGHT, CK_SHIFT_HOME, CK_SHIFT_UP, CK_SHIFT_PGUP, CK_SHIFT_INSERT },
- { CK_CTRL_END, CK_CTRL_DOWN, CK_CTRL_PGDN, CK_CTRL_LEFT, CK_CTRL_CLEAR, CK_CTRL_RIGHT, CK_CTRL_HOME, CK_CTRL_UP, CK_CTRL_PGUP, CK_CTRL_INSERT },
- };
-
-static int ck_tr[] = {
- 'k', 'j', 'h', 'l', '0', 'y', 'b', '.', 'u', 'n',
- // 'b', 'j', 'n', 'h', '.', 'l', 'y', 'k', 'u' ,
- '8', '2', '4', '6', '0', '7', '1', '5', '9', '3',
- // '1', '2', '3', '4', '5', '6', '7', '8', '9' ,
- 11, 10, 8, 12, '0', 25, 2, 0, 21, 14
- // 2, 10, 14, 8, 0, 12, 25, 11, 21 ,
-};
-
-int key_to_command( int keyin ) {
- if (keyin >= CK_UP && keyin <= CK_CTRL_PGDN)
- return ck_tr[ keyin - CK_UP ];
-
- if (keyin == CK_DELETE)
- return '.';
-
- return keyin;
-}
-
-int vk_translate( WORD VirtCode, CHAR c, DWORD cKeys)
-{
- bool shftDown = false;
- bool ctrlDown = false;
- bool altDown = !!(cKeys & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED));
-
- // DEBUG
- //fprintf(foo, "Received code %d (%c) with modifiers: %d\n", VirtCode, c, cKeys);
-
- // step 1 - we don't care about shift or control
- if (VirtCode == VK_SHIFT || VirtCode == VK_CONTROL ||
- VirtCode == VK_MENU || VirtCode == VK_CAPITAL ||
- VirtCode == VK_NUMLOCK)
- return 0;
-
- // step 2 - translate the <Esc> key to 0x1b
- if (VirtCode == VK_ESCAPE)
- return 0x1b; // same as it ever was..
-
- // step 3 - translate shifted or controlled numeric keypad keys
- if (cKeys & SHIFT_PRESSED)
- shftDown = true;
- if (cKeys & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
- ctrlDown = true; // control takes precedence over shift
-
- // hack - translate ^P and ^Q since 16 and 17 are taken by CTRL and SHIFT
- if ((VirtCode == 80 || VirtCode == 81) && ctrlDown)
- return VirtCode & 0x003f; // shift back down
-
- if (VirtCode == VK_DELETE && !ctrlDown) // assume keypad '.'
- return CK_DELETE;
-
- // see if we're a vkey
- int mkey;
- for(mkey = 0; mkey<VKEY_MAPPINGS; mkey++)
- if (VirtCode == vk_tr[0][mkey]) break;
-
- // step 4 - just return the damn key.
- if (mkey == VKEY_MAPPINGS) {
- if (c)
- return c;
-
- // ds -- Icky hacks to allow keymaps with funky keys.
- if (ctrlDown)
- VirtCode |= 512;
- if (shftDown)
- VirtCode |= 1024;
- if (altDown)
- VirtCode |= 2048;
-
- // ds -- Cheat and returns 256 + VK if the char is zero. This allows us
- // to use the VK for macros and is on par for evil with the rest of
- // this function anyway.
- return VirtCode | 256;
- }
-
- // now translate the key. Dammit. This is !@#$(*& garbage.
-
- // control key?
- if (ctrlDown)
- return vk_tr[3][mkey];
-
- // shifted?
- if (shftDown)
- return vk_tr[2][mkey];
- return vk_tr[1][mkey];
-}
-
-int getch_ck(void)
-{
- INPUT_RECORD ir;
- DWORD nread;
- int key = 0;
- static int repeat_count = 0;
- static int repeat_key = 0;
-
- KEY_EVENT_RECORD *kr;
-
- // handle key repeats
- if (repeat_count > 0)
- {
- repeat_count -= 1;
- return repeat_key;
- }
-
- bool oldValue = current_cursor;
- _setcursortype_internal(_NORMALCURSOR);
-
- while(1)
- {
- CLOCKIN
- if (ReadConsoleInput( inbuf, &ir, 1, &nread) == 0)
- fputs("Error in ReadConsoleInput()!", stderr);
- CLOCKOUT(5)
- if (nread > 0)
- {
- // ignore if it isn't a keyboard event.
- if (ir.EventType == KEY_EVENT)
- {
- kr = &(ir.Event.KeyEvent);
- // ignore if it is a 'key up' - we only want 'key down'
- if (kr->bKeyDown == true)
- {
- key = vk_translate( kr->wVirtualKeyCode, kr->uChar.AsciiChar, kr->dwControlKeyState );
- if (key > 0)
- {
- repeat_count = kr->wRepeatCount - 1;
- repeat_key = key;
- break;
- }
- }
- }
- }
- }
- // DEBUG
- //fprintf(foo, "getch() returning %02x (%c)\n", key, key);
-
- _setcursortype_internal(oldValue);
-
- return key;
-}
-
-int getch(void)
-{
- int c = getch_ck();
- return key_to_command( c );
-}
-
-int getche(void)
-{
- // turn buffering off temporarily
- bool oldValue = buffering;
- setBuffering(false);
-
- int val = getch();
-
- if (val != 0)
- putch(val);
-
- // restore buffering value
- setBuffering(oldValue);
-
- return val;
-}
-
-int kbhit()
-{
- INPUT_RECORD ir[10];
- DWORD read_count = 0;
- PeekConsoleInput(inbuf, ir, sizeof ir / sizeof(ir[0]), &read_count);
- if (read_count > 0) {
- for (unsigned i = 0; i < read_count; ++i)
- if (ir[i].EventType == KEY_EVENT) {
- KEY_EVENT_RECORD *kr;
- kr = &(ir[i].Event.KeyEvent);
-
- if (kr->bKeyDown)
- return 1;
- }
- }
- return 0;
-}
-
-void delay(int ms)
-{
- Sleep((DWORD)ms);
-}
-
-void textbackground(int c)
-{
- // do nothing
- UNUSED( c );
-}
-
-int getConsoleString(char *buf, int maxlen)
-{
- DWORD nread;
- // set console input to line mode
- setStringInput( true );
-
- // force cursor
- bool oldValue = current_cursor;
- _setcursortype_internal(_NORMALCURSOR);
-
- // set actual screen color to current color
- SetConsoleTextAttribute( outbuf, WIN32COLOR(current_color) );
-
- if (ReadConsole( inbuf, buf, (DWORD)(maxlen-1), &nread, NULL) == 0)
- fputs("Error in ReadConsole()!", stderr);
-
- // terminate string, then strip CRLF, replace with \0
- buf[maxlen-1] = '\0';
- for (unsigned i=(nread<3 ? 0 : nread-3); i<nread; i++)
- {
- if (buf[i] == 0x0A || buf[i] == 0x0D)
- {
- buf[i] = '\0';
- break;
- }
- }
-
- // reset console mode - also flushes if player has typed in
- // too long of a name so we don't get silly garbage on return.
- setStringInput( false );
-
- // restore old cursor
- _setcursortype_internal(oldValue);
-
- // return # of bytes read
- return (int)nread;
-}
-
-bool setBuffering( bool value )
-{
- bool oldValue = buffering;
-
- if (value == false)
- {
- // must flush buffer
- bFlush();
- }
- buffering = value;
-
- return oldValue;
-}
diff --git a/stone_soup/crawl-ref/source/libw32c.h b/stone_soup/crawl-ref/source/libw32c.h
deleted file mode 100644
index 319efb02d8..0000000000
--- a/stone_soup/crawl-ref/source/libw32c.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef LIBW32C_H
-#define LIBW32C_H
-
-#define WIN_NUMBER_OF_LINES 25
-
-#include <string>
-// I think the following definition is all we need from STD namespace..
-#ifdef __IBMCPP__ // Borland 5.01 doesn't seem to need this
-typedef std::basic_string<char> string;
-#endif
-
-#include <excpt.h>
-#include <stdarg.h>
-
-#define _NORMALCURSOR true
-#define _NOCURSOR false
-
-void init_libw32c(void);
-void deinit_libw32c(void);
-void _setcursortype(int curstype);
-void clrscr(void);
-void gotoxy(int x, int y);
-void textcolor(int c);
-void cprintf( const char *format, ... );
-// void cprintf(const char *s);
-void setStringInput(bool value);
-bool setBuffering(bool value);
-int getConsoleString(char *buf, int maxlen);
-void print_timings(void);
-
-void window(int x, int y, int lx, int ly);
-int wherex(void);
-int wherey(void);
-void putch(char c);
-int getch(void);
-int getch_ck(void);
-int key_to_command(int);
-int getche(void);
-int kbhit(void);
-void delay(int ms);
-void textbackground(int c);
-
-inline void srandom(unsigned int seed) { srand(seed); }
-
-#endif
-
-
diff --git a/stone_soup/crawl-ref/source/lua/base.lua b/stone_soup/crawl-ref/source/lua/base.lua
deleted file mode 100644
index db7b15afda..0000000000
--- a/stone_soup/crawl-ref/source/lua/base.lua
+++ /dev/null
@@ -1,74 +0,0 @@
----------------------------------------------------------------------------
--- base.lua:
--- Base Lua definitions that other Lua scripts rely on.
--- NOTE: Other Lua scripts may demonstrate buggy behaviour if you do
--- not source this file. If you're using no Lua scripts at all, you
--- needn't source base.lua.
---
--- To use this, add this line to your init.txt:
--- lua_file = lua/base.lua
----------------------------------------------------------------------------
-
--- Lua global data
-chk_interrupt_macro = { }
-chk_interrupt_activity = { }
-chk_lua_option = { }
-
--- Push into this table, rather than indexing into it.
-chk_lua_save = { }
-
-function c_save(file)
- if not chk_lua_save then
- return
- end
-
- for i, fn in ipairs(chk_lua_save) do
- fn(file)
- end
-end
-
--- This function returns true to tell Crawl not to process the option further
-function c_process_lua_option(key, val)
- if chk_lua_option and chk_lua_option[key] then
- return chk_lua_option[key](key, val)
- end
- return false
-end
-
-function c_interrupt_macro(iname, cause, extra)
- -- If some joker undefined the table, stop all macros
- if not chk_interrupt_macro then
- return true
- end
-
- -- Maybe we don't know what macro is running? Kill it to be safe
- -- We also kill macros that don't add an entry to chk_interrupt_macro.
- if not c_macro_name or not chk_interrupt_macro[c_macro_name] then
- return true
- end
-
- return chk_interrupt_macro[c_macro_name](iname, cause, extra)
-end
-
--- Notice that c_interrupt_activity defaults to *false* whereas
--- c_interrupt_macro defaults to *true*. This is because "false" really just
--- means "go ahead and use the default logic to kill this activity" here,
--- whereas false is interpreted as "no, don't stop this macro" for
--- c_interrupt_macro.
---
--- If c_interrupt_activity, or one of the individual hooks wants to ensure that
--- the activity continues, it must return *nil* (make sure you know what you're
--- doing when you return nil!).
-function c_interrupt_activity(aname, iname, cause, extra)
- -- If some joker undefined the table, bail out
- if not chk_interrupt_activity then
- return false
- end
-
- -- No activity name? Bail!
- if not aname or not chk_interrupt_activity[aname] then
- return false
- end
-
- return chk_interrupt_activity[aname](iname, cause, extra)
-end
diff --git a/stone_soup/crawl-ref/source/lua/chnkdata.lua b/stone_soup/crawl-ref/source/lua/chnkdata.lua
deleted file mode 100644
index 60f098c96b..0000000000
--- a/stone_soup/crawl-ref/source/lua/chnkdata.lua
+++ /dev/null
@@ -1,35 +0,0 @@
--- SPOILER WARNING
---
--- This file contains spoiler information. Do not read or use this file if you
--- don't want to be spoiled. Further, the Lua code in this file may use this
--- spoily information to take actions on your behalf. If you don't want
--- automatic exploitation of spoilers, don't use this.
---
----------------------------------------------------------------------------
--- chnkdata.lua:
--- Raw data on chunks of meat, auto-extracted from mon-data.h.
---
--- To use this, add this line to your init.txt:
--- lua_file = lua/chnkdata.lua
---
--- This file has no directly usable functions, but is needed by gourmand.lua
--- and enables auto_eat_chunks in eat.lua.
----------------------------------------------------------------------------
-
-sc_cont = {"program bug","ettin","goblin","jackal","manticore","orc","ugly thing","two-headed ogre","hobgoblin","ogre","troll","orc warrior","orc wizard","orc knight","minotaur","beast","iron devil","orc sorcerer","","","hell knight","necromancer","wizard","orc priest","orc high priest","human","gnoll","earth elemental","fire elemental","air elemental","Ice Fiend","Shadow Fiend","spectral warrior","pulsating lump","rock troll","stone giant","flayed ghost","insubstantial wisp","vapour","ogre-mage","dancing weapon","elf","war dog","grey rat","giant mosquito","fire giant","frost giant","firedrake","deep troll","giant blowfly","swamp dragon","swamp drake","hill giant","giant cockroach","white imp","lemure","ufetubus","manes","midge","neqoxec","hellwing","smoke demon","ynoxinul","Executioner","Blue Death","Balrug","Cacodemon","demonic crawler","sun demon","shadow imp","shadow wraith","Mnoleg","Lom Lobon","Cerebov","Gloorx Vloq","orc warlord","deep elf soldier","deep elf fighter","deep elf knight","deep elf mage","deep elf summoner","deep elf conjurer","deep elf priest","deep elf high priest","deep elf demonologist","deep elf annihilator","deep elf sorcerer","deep elf death mage","Terence","Jessica","Ijyb","Sigmund","Blork the orc","Edmund","Psyche","Erolcha","Donald","Urug","Michael","Joseph","Snorg","Erica","Josephine","Harold","Norbert","Jozef","Agnes","Maud","Louise","Francis","Frances","Rupert","Wayne","Duane","Xtahua","Norris","Adolf","Margery","Boris","Geryon","Dispater","Asmodeus","Antaeus","Ereshkigal","vault guard","Killer Klown","ball lightning","orb of fire","boggart","quicksilver dragon","iron dragon","skeletal warrior","","&","warg","","","komodo dragon"}
-sc_pois = {"killer bee","killer bee larva","quasit","scorpion","yellow wasp","giant beetle","kobold","queen bee","kobold demonologist","big kobold","wolf spider","brain worm","boulder beetle","giant mite","hydra","mottled dragon","brown snake","death yak","bumblebee","redback","spiny worm","golden dragon","elephant slug","green rat","orange rat","black snake","giant centipede","iron troll","naga","yellow snake","red wasp","soldier ant","queen ant","ant larva","spiny frog","orange demon","Green Death","giant amoeba","giant slug","giant snail","boring beetle","naga mage","naga warrior","brown ooze","azure jelly","death ooze","acid blob","ooze","shining eye","greater naga","eye of devastation","gila monster"}
-sc_hcl = {"necrophage","ghoul"}
-sc_mut = {"guardian naga","eye of draining","giant orange brain","great orb of eyes","glowing shapeshifter","shapeshifter","very ugly thing"}
-
-function sc_to_hash(list)
- local hash = { }
- for _, i in ipairs(list) do
- hash[i] = true
- end
- return hash
-end
-
-sc_cont = sc_to_hash( sc_cont )
-sc_pois = sc_to_hash( sc_pois )
-sc_hcl = sc_to_hash( sc_hcl )
-sc_mut = sc_to_hash( sc_mut )
diff --git a/stone_soup/crawl-ref/source/lua/eat.lua b/stone_soup/crawl-ref/source/lua/eat.lua
deleted file mode 100644
index 2e5bda2432..0000000000
--- a/stone_soup/crawl-ref/source/lua/eat.lua
+++ /dev/null
@@ -1,97 +0,0 @@
----------------------------------------------------------------------------
--- eat.lua:
--- Prompts to eat chunks from inventory.
---
--- To use this, add this line to your init.txt:
--- lua_file = lua/eat.lua
---
--- See c_eat in this file if you want to tweak eating behaviour further.
----------------------------------------------------------------------------
-function prompt_eat(i)
- local iname = item.name(i, "a")
- if item.quantity(i) > 1 then
- iname = "one of " .. iname
- end
- crawl.mpr("Eat " .. iname .. "?", "prompt")
-
- local res
- res = crawl.getch()
- if res == 27 then
- res = "escape"
- elseif res < 32 or res > 127 then
- res = ""
- else
- res = string.lower(string.format("%c", res))
- end
- return res
-end
-
-function is_chunk_safe(chunk)
- local rot = food.rotting(chunk)
- local race = you.race()
-
- -- Check if the user has sourced safechunk.lua and chnkdata.lua
- if not (sc_cont and sc_pois and sc_hcl and sc_mut and sc_safechunk) then
- return false
- end
-
- local cname = item.name(chunk)
- local mon
- _, _, mon = string.find(cname, "chunk of (.+) flesh")
-
- return sc_safechunk(rot, race, mon)
-end
-
--- Called by Crawl. Note that once Crawl sees a c_eat function, it bypasses the
--- built-in (e)at command altogether.
---
-function c_eat(floor, inv)
- -- To enable auto_eat_chunks, you also need to source chnkdata.lua and
- -- safechunk.lua. WARNING: These files contain spoily information.
- local auto_eat_chunks = options.auto_eat_chunks == "yes" or
- options.auto_eat_chunks == "true"
-
- if auto_eat_chunks then
- local all = { }
- for _, it in ipairs(floor) do table.insert(all, it) end
- for _, it in ipairs(inv) do table.insert(all, it) end
-
- for _, it in ipairs(all) do
- if food.ischunk(it) and food.can_eat(it) and is_chunk_safe(it) then
- local iname = item.name(it, "a")
- if item.quantity(it) > 1 then
- iname = "one of " .. iname
- end
- crawl.mpr("Eating " .. iname)
- food.eat(it)
- return
- end
- end
- end
-
- -- Prompt to eat chunks off the floor. Returns true if the player chose
- -- to eat a chunk.
- if food.prompt_floor() then
- return
- end
-
- for i, it in ipairs(inv) do
- -- If we have chunks in inventory that the player can eat, prompt.
- if food.ischunk(it) and food.can_eat(it) then
- local answer = prompt_eat(it)
- if answer == "q" then
- break
- end
- if answer == "escape" then
- return
- end
- if answer == "y" then
- food.eat(it)
- return
- end
- end
- end
-
- -- Allow the player to choose a snack from inventory
- food.prompt_inventory()
-end
diff --git a/stone_soup/crawl-ref/source/lua/gearset.lua b/stone_soup/crawl-ref/source/lua/gearset.lua
deleted file mode 100644
index 494ebd65ff..0000000000
--- a/stone_soup/crawl-ref/source/lua/gearset.lua
+++ /dev/null
@@ -1,206 +0,0 @@
-------------------------------------------------------------------------
--- gearset.lua: (requires base.lua)
--- Allows for quick switching between two sets of equipment.
---
--- IMPORTANT
--- This Lua script remembers only the *inventory slots* of the gear you're
--- wearing (it could remember item names, but they're prone to change based on
--- identification, enchantment and curse status). If you swap around items in
--- your inventory, the script may attempt to wear odd items (this will not kill
--- the game, but it can be disconcerting if you're not expecting it).
---
--- To use this, source this file in your init.txt:
--- lua_file = lua/gearset.lua
---
--- Then start Crawl and create two macros:
--- 1. Any macro input key (say F2), set macro action to "===rememberkit"
--- 2. Any macro input key (say F3), set macro action to "===swapkit"
--- It helps to save your macros at this point. :-)
---
--- You can now hit F2 to remember the equipment you're wearing. Once you've
--- defined two sets of equipment, hit F3 to swap between them.
---
--- You can also just define one set of equipment; in this case, every time
--- you hit F3 (swapkit), the macro makes sure you're wearing all the items in
--- that set (and only the items in that set). This is handy for transmuters who
--- need to kit up after a transform ends.
-------------------------------------------------------------------------
-function scan_kit()
- local kit = { }
- for i = 9, 0, -1 do
- local it = item.equipped_at(i)
- if it then
- table.insert(kit, item.slot(it))
- end
- end
- return kit
-end
-
-function kit_items(kit)
- local items = { }
- local inv = item.inventory()
-
- for _, slot in ipairs(kit) do
- for _, it in ipairs(inv) do
- if slot == item.slot(it) then
- table.insert(items, it)
- end
- end
- end
- return items
-end
-
-function getkey(vkeys)
- local key
-
- while true do
- key = crawl.getch()
- if key == 27 then return "escape" end
-
- if key > 31 and key < 127 then
- local c = string.lower(string.char(key))
- if string.find(vkeys, c) then
- return c
- end
- end
- end
-end
-
--- Macroable
-function rememberkit()
- local kit = scan_kit()
- crawl.mpr("Is this (T)ravel or (B)attle kit? ", "prompt")
- local answer = getkey("tb")
- crawl.mesclr()
- if answer == "escape" then
- return false
- end
-
- if answer == 't' then
- g_kit_travel = kit
- else
- g_kit_battle = kit
- end
-
- return false
-end
-
-function write_array(f, arr, aname)
- file.write(f, aname .. " = { ")
- for i, v in ipairs(arr) do
- file.write(f, v .. ", ")
- end
- file.write(f, "}\n")
-end
-
-function gearset_save(file)
- if g_kit_travel then
- write_array(file, g_kit_travel, "g_kit_travel")
- end
- if g_kit_battle then
- write_array(file, g_kit_battle, "g_kit_battle")
- end
-end
-
-function matchkit(kit1, kit2)
- local matches = 0
- if not kit2 then
- -- Return a positive match for an empty gearset so that swapkit
- -- switches to the *other* gearset. :-)
- return 500
- end
- for _, v1 in ipairs(kit1) do
- for _, v2 in ipairs(kit2) do
- if v1 == v2 then
- matches = matches + 1
- end
- end
- end
- return matches
-end
-
-function wear(it)
- local _, eqt = item.equip_type(it)
- if eqt == "Weapon" then
- return item.wield(it)
- elseif eqt == "Amulet" or eqt == "Ring" then
- return item.puton(it)
- elseif eqt ~= "" then
- return item.wear(it)
- else
- return false
- end
-end
-
-function wearkit(kit)
- -- Remove all items not in the kit, then wear all items in the kit
- local currkit = scan_kit()
- local toremove = { }
- local noop = true
-
- for _, v in ipairs(currkit) do
- local found = false
- for _, v1 in ipairs(kit) do
- if v == v1 then
- found = true
- break
- end
- end
- if not found then
- table.insert(toremove, v)
- end
- end
-
- local remitems = kit_items(toremove)
- for _, it in ipairs(remitems) do
- noop = false
- if not item.remove(it) then
- coroutine.yield(false)
- end
- coroutine.yield(true)
- end
-
- local kitems = kit_items(kit)
-
- for _, it in ipairs(kitems) do
- if not item.worn(it) then
- noop = false
- if not wear(it) then
- coroutine.yield(false)
- end
- coroutine.yield(true)
- end
- end
-
- if noop then
- crawl.mpr("Nothing to do.")
- end
-end
-
--- Macroable
-function swapkit()
- if not g_kit_battle and not g_kit_travel then
- crawl.mpr("You need to define a gear set first")
- return false
- end
-
- local kit = scan_kit()
- if matchkit(kit, g_kit_travel) < matchkit(kit, g_kit_battle) then
- crawl.mpr("Switching to travel kit")
- wearkit(g_kit_travel)
- else
- crawl.mpr("Switching to battle kit")
- wearkit(g_kit_battle)
- end
-end
-
-function swapkit_interrupt_macro(interrupt_name)
- return interrupt_name == "hp_loss" or interrupt_name == "stat" or
- interrupt_name == "monster" or interrupt_name == "force"
-end
-
--- Add a macro interrupt hook so that we don't get stopped by any old interrupt
-chk_interrupt_macro.swapkit = swapkit_interrupt_macro
-
--- Add ourselves in the Lua save chain
-table.insert(chk_lua_save, gearset_save)
diff --git a/stone_soup/crawl-ref/source/lua/gourmand.lua b/stone_soup/crawl-ref/source/lua/gourmand.lua
deleted file mode 100644
index a730438419..0000000000
--- a/stone_soup/crawl-ref/source/lua/gourmand.lua
+++ /dev/null
@@ -1,145 +0,0 @@
--- SPOILER WARNING
---
--- This file contains spoiler information. Do not read or use this file if you
--- don't want to be spoiled. Further, the Lua code in this file may use this
--- spoily information to take actions on your behalf. If you don't want
--- automatic exploitation of spoilers, don't use this.
---
----------------------------------------------------------------------------
--- gourmand.lua: (requires eat.lua, chnkdata.lua, and safechunk.lua)
---
--- Eats all available chunks on current square and inventory, swapping to an
--- identified amulet of the gourmand if necessary, with no prompts. Note that
--- it relies on spoiler information to identify chunks it can eat without
--- prompting the user.
---
--- This is a Lua macro, so the action will be interrupted by the hp/stat loss,
--- or monsters.
---
--- To use this, add these line to your init.txt:
--- lua_file = lua/gourmand.lua
---
--- And macro the "eat_gourmand" function to a key.
----------------------------------------------------------------------------
--- Macroable
-function eat_gourmand()
- local race = you.race()
- local all = { }
- for _, it in ipairs(you.floor_items()) do table.insert(all, it) end
- for _, it in ipairs(item.inventory()) do table.insert(all, it) end
-
- local chunks = { }
- local needgourmand = false
- local oneedible = false
-
- for _, itym in ipairs(all) do
- if food.ischunk(itym) then
- table.insert(chunks, itym)
- end
- end
-
- for _, itym in ipairs(chunks) do
- local rot = food.rotting(itym)
- local mon = chunkmon(itym)
-
- if food.can_eat(itym) and sc_safechunk and
- sc_safechunk(rot, race, mon) then
- oneedible = true
- end
-
- -- If we can't eat it now, but we could eat it if hungry, a gourmand
- -- switch would be nice.
- if not food.can_eat(itym) and food.can_eat(itym, false) then
- needgourmand = true
- end
-
- if sc_safechunk and not sc_safechunk(rot, race, mon)
- and sc_safechunk(false, race, mon)
- then
- needgourmand = true
- end
- end
-
- if table.getn(chunks) == 0 then
- crawl.mpr("No chunks to eat.")
- return
- end
-
- local amuremoved
- if needgourmand and not oneedible then
- amuremoved = switch_amulet("gourmand")
- end
-
- for _, ch in ipairs(chunks) do
- if food.can_eat(ch) and is_chunk_safe(ch) then
- while item.quantity(ch) > 0 do
- if food.eat(ch) then
- coroutine.yield(true)
- else
- break
- end
- end
- end
- end
-
- if amuremoved then
- switch_amulet(amuremoved)
- end
-end
-
-function chunkmon(chunk)
- local cname = item.name(chunk)
- local mon
- _, _, mon = string.find(cname, "chunk of (.+) flesh")
- return mon
-end
-
-function switch_amulet(amu)
- local towear
- if type(amu) == "string" then
- for _, it in ipairs(item.inventory()) do
- if item.class(it, true) == "jewelry"
- and item.subtype(it) == amu
- and not item.cursed(it) then
- towear = item.slot(it)
- break
- end
- end
-
- if not towear then
- crawl.mpr("Can't find suitable amulet: " .. amu)
- coroutine.yield(false)
- end
- else
- towear = amu
- end
-
- local curramu = item.equipped_at("amulet")
- if curramu and item.cursed(curramu) then
- crawl.mpr("Can't swap out cursed amulet!")
- coroutine.yield(false)
- end
-
- local wearitem = item.inslot(towear)
-
- if curramu then
- if not item.remove(curramu) then
- coroutine.yield(false)
- end
-
- -- Yield, so that a turn can pass and we can take another action.
- coroutine.yield(true)
- end
-
- if not item.puton(wearitem) then
- coroutine.yield(false)
- end
-
- coroutine.yield(true)
- return curramu and item.slot(curramu)
-end
-
-function c_interrupt_macro(interrupt_name)
- return interrupt_name == "hp_loss" or interrupt_name == "stat" or
- interrupt_name == "monster" or interrupt_name == "force"
-end
diff --git a/stone_soup/crawl-ref/source/lua/kills.lua b/stone_soup/crawl-ref/source/lua/kills.lua
deleted file mode 100644
index b84b1f93c0..0000000000
--- a/stone_soup/crawl-ref/source/lua/kills.lua
+++ /dev/null
@@ -1,240 +0,0 @@
-------------------------------------------------------------------
--- kills.lua:
--- Generates fancier vanquished creatures lists.
---
--- List ideas courtesy Jukka Kuusisto and Erik Piper.
---
--- To use this, add this line to your init.txt:
--- lua_file = lua/kills.lua
---
--- Take a look at the c_kill_list function - that's where to start if you
--- want to customize things.
-------------------------------------------------------------------
-
-function kill_filter(a, condition)
- local t = { }
- for i, k in ipairs(a) do
- if condition(k) then
- table.insert(t, k)
- end
- end
- return t
-end
-
-function show_sorted_list(list, baseindent, sortfn)
- baseindent = baseindent or " "
- sortfn = sortfn or
- function (x, y)
- return kills.exp(x) > kills.exp(y) or
- (kills.exp(x) == kills.exp(y) and
- kills.base_name(x) < kills.base_name(y))
- end
- table.sort(list, sortfn)
- for i, k in ipairs(list) do
- kills.rawwrite(baseindent .. " " .. kills.desc(k))
- end
- kills.rawwrite(baseindent .. kills.summary(list))
-end
-
-function group_kills(a, namemap, keys, selector)
- local count = 0
- for i, key in ipairs(keys) do
- local selected = kill_filter(a,
- function (k)
- return selector(key, k)
- end
- )
- if table.getn(selected) > 0 then
- if count > 0 then
- kills.rawwrite("")
- end
- count = count + 1
- kills.rawwrite(" " .. namemap[key])
- show_sorted_list(selected)
- end
- end
-end
-
-function holiness_list(a)
- local holies = {
- strange = "Strange Monsters",
- unique = "Uniques",
- holy = "Holy Monsters",
- natural = "Natural Monsters",
- undead = "Undead Monsters",
- demonic = "Demonic Monsters",
- nonliving = "Non-Living Monsters",
- plant = "Plants",
- }
- local holysort = { "strange", "unique",
- "natural", "nonliving",
- "undead", "demonic", "plant" }
- kills.rawwrite(" Monster Nature")
- group_kills( a, holies, holysort,
- function ( key, kill )
- return (kills.holiness(kill) == key and not kills.isunique(kill))
- or
- (key == "unique" and kills.isunique(kill))
- end
- )
- kills.rawwrite(" " .. kills.summary(a))
-end
-
-function count_list(a, ascending)
- kills.rawwrite(" Ascending Order")
- show_sorted_list(a,
- " ",
- function (x, y)
- if ascending then
- return kills.nkills(x) < kills.nkills(y)
- or (kills.nkills(x) == kills.nkills(y) and
- kills.exp(x) > kills.exp(y))
- else
- return kills.nkill(x) > kills.nkills(y)
- or (kills.nkills(x) == kills.nkills(y) and
- kills.exp(x) > kills.exp(y))
- end
- end
- )
-end
-
-function symbol_list(a)
- -- Create a list of monster characters and sort it
- local allsyms = { }
- for i, k in ipairs(a) do
- local ksym = kills.symbol(k)
- allsyms[ kills.symbol(k) ] = true
- end
-
- local sortedsyms = { }
- for sym, dud in pairs(allsyms) do table.insert(sortedsyms, sym) end
- table.sort(sortedsyms)
-
- kills.rawwrite(" Monster Symbol")
- for i, sym in ipairs(sortedsyms) do
- if i > 1 then
- kills.rawwrite("")
- end
-
- local symlist = kill_filter(a,
- function (k)
- return kills.symbol(k) == sym
- end
- )
- kills.rawwrite(" All '" .. sym .. "'")
- show_sorted_list(symlist)
- end
-
- kills.rawwrite(" " .. kills.summary(a))
-end
-
-function classic_list(title, a, suffix)
- if table.getn(a) == 0 then return end
- kills.rawwrite(title)
- for i, k in ipairs(a) do
- kills.rawwrite(" " .. kills.desc(k))
- end
- kills.rawwrite(" " .. kills.summary(a))
- if suffix then
- kills.rawwrite(suffix)
- end
-end
-
-function separator()
- kills.rawwrite("----------------------------------------\n")
-end
-
-function newline()
- kills.rawwrite("")
-end
-
------------------------------------------------------------------------------
--- This is the function that Crawl calls when it wants to dump the kill list
--- The parameter "a" is the list (Lua table) of kills, initially sorted in
--- descending order of experience. Kill entries must be inspected using
--- kills.foo(ke).
---
--- NOTE: Comment out the kill lists that you don't like!
---
--- As of 20060224, the kill list is divided into three:
--- * Direct player kills
--- * Monsters killed by friendlies
--- * Monsters killed by other things (traps, etc.)
---
--- For each category, the game calls c_kill_list, with a table of killed
--- monsters, and the killer (who). The killer will be nil for direct player
--- kills, and a string ("collateral kills", "others") otherwise.
---
--- c_kill_list will not be called for a category if the category contains no
--- kills.
---
--- After all categories, c_kill_list will be called with no arguments to
--- indicate the end of the kill listing.
-
-function c_kill_list(a, who, needsep)
- -- If there aren't any kills yet, bail out
- if not a or table.getn(a) == 0 then
- if not a and who and who ~= "" then
- -- This is the grand total
- separator()
- kills.rawwrite(who)
- end
- return
- end
-
- if needsep then
- separator()
- end
-
- local title = "Vanquished Creatures"
- if who then
- title = title .. " (" .. who .. ")"
- end
-
- kills.rawwrite(title)
-
- -- Group kills by monster symbol
- symbol_list(a)
- newline()
-
- -- Group by holiness
- holiness_list(a)
- newline()
-
- -- Sort by kill count (ascending).
- count_list(a, true)
- newline()
-
- -- Classic list without zombies and skeletons
- -- Commented-out - this is a boring list.
- --[[
- -- First re-sort into descending order of exp, since
- -- count_list has re-sorted the array.
- table.sort(a, function (x, y)
- return kills.exp(x) > kills.exp(y)
- end);
-
- -- Filter out zombies and skeletons and display the rest
- classic_list(
- " Kills minus zombies and skeletons",
- kill_filter(a,
- function (k)
- return kills.modifier(k) ~= "zombie" and
- kills.modifier(k) ~= "skeleton"
- end
- ))
-
- separator()
- --]]
-
- -- Show only monsters with 3 digit kill count
- classic_list(
- " The 3-digit Club",
- kill_filter(a,
- function (k)
- return kills.nkills(k) > 99
- end
- ),
- "")
-
-end
diff --git a/stone_soup/crawl-ref/source/lua/runrest.lua b/stone_soup/crawl-ref/source/lua/runrest.lua
deleted file mode 100644
index 6f5536506e..0000000000
--- a/stone_soup/crawl-ref/source/lua/runrest.lua
+++ /dev/null
@@ -1,108 +0,0 @@
----------------------------------------------------------------------------
--- runrest.lua: (requires base.lua)
--- Controls shift-running and resting stop conditions.
---
--- To use this, add this line to your init.txt:
--- lua_file = lua/runrest.lua
---
--- What it does:
---
--- * Any message in runrest_ignore_message will *not* stop your run.
--- * Poison damage of x will be ignored if you have at least y hp if you've
--- defined a runrest_ignore_poison = x:y option.
---
--- IMPORTANT: You must define runrest_ options *after* sourcing runrest.lua.
----------------------------------------------------------------------------
-
-g_rr_ignored = { }
-
-chk_interrupt_activity.run = function (iname, cause, extra)
- if not rr_check_params() then
- return false
- end
-
- if iname == 'message' then
- return rr_handle_message(cause, extra)
- end
-
- if iname == 'hp_loss' then
- return rr_handle_hploss(cause, extra)
- end
-
- return false
-end
-
-function rr_handle_message(cause, extra)
- local ch, mess = rr_split_channel(cause)
- for _, m in ipairs(g_rr_ignored) do
- if m:matches(mess, ch) then
- return nil
- end
- end
- return false
-end
-
-function rr_split_channel(s)
- local chi = string.find(s, ':')
- local channel = -1
- if chi and chi > 1 then
- local chstr = string.sub(s, 1, chi - 1)
- channel = crawl.msgch_num(chstr)
- end
-
- local sor = s
- if chi then
- s = string.sub(s, chi + 1, -1)
- end
-
- return channel, s
-end
-
-function rr_handle_hploss(hplost, source)
- -- source == 1 for poisoning
- if not g_rr_yhpmin or not g_rr_hplmax or source ~= 1 then
- return false
- end
-
- -- If the hp lost is smaller than configured, and you have more than the
- -- minimum health, ignore this poison event.
- if hplost <= g_rr_hplmax and you.hp() >= g_rr_yhpmin then
- return nil
- end
-
- return false
-end
-
-function rr_check_params()
- if g_rrim ~= options.runrest_ignore_message then
- g_rrim = options.runrest_ignore_message
- rr_add_messages(nil, g_rrim)
- end
-
- if ( not g_rr_hplmax or not g_rr_yhpmin )
- and options.runrest_ignore_poison
- then
- local opt = options.runrest_ignore_poison
- local hpl, hpm
- _, _, hpl, hpm = string.find(opt, "(%d+)%s*:%s*(%d+)")
- if hpl and hpm then
- g_rr_hplmax = tonumber(hpl)
- g_rr_yhpmin = tonumber(hpm)
- end
- end
- return true
-end
-
-function rr_add_message(s)
- local channel, str = rr_split_channel(s)
- table.insert( g_rr_ignored, crawl.message_filter( str, channel ) )
-end
-
-function rr_add_messages(key, value)
- local segs = crawl.split(value, ',')
- for _, s in ipairs(segs) do
- rr_add_message(s)
- end
-end
-
-chk_lua_option.runrest_ignore_message = rr_add_messages
diff --git a/stone_soup/crawl-ref/source/lua/safechunk.lua b/stone_soup/crawl-ref/source/lua/safechunk.lua
deleted file mode 100644
index cd0c9f036d..0000000000
--- a/stone_soup/crawl-ref/source/lua/safechunk.lua
+++ /dev/null
@@ -1,41 +0,0 @@
--- SPOILER WARNING
---
--- This file contains spoiler information. Do not read or use this file if you
--- don't want to be spoiled. Further, the Lua code in this file may use this
--- spoily information to take actions on your behalf. If you don't want
--- automatic exploitation of spoilers, don't use this.
---
----------------------------------------------------------------------------
--- safechunk.lua:
--- Determines whether a chunk of meat is safe for your character to eat.
---
--- To use this, add this line to your init.txt:
--- lua_file = lua/safechunk.lua
---
--- This file has no directly usable functions, but is needed by gourmand.lua
--- and enables auto_eat_chunks in eat.lua.
----------------------------------------------------------------------------
-
-function sc_safechunk(rot, race, mon)
- if race == "Ghoul" then
- return true
- end
-
- if rot then
- if race ~= "Kobold" and race ~= "Troll" and not you.gourmand() then
- return false
- end
- end
-
- if sc_pois[mon] and you.res_poison() > 0 then
- return true
- end
-
- if sc_hcl[mon] or sc_mut[mon] then
- return false
- end
-
- -- Only contaminated and clean chunks remain, in theory. We'll accept
- -- either
- return true
-end
diff --git a/stone_soup/crawl-ref/source/lua/stash.lua b/stone_soup/crawl-ref/source/lua/stash.lua
deleted file mode 100644
index 461a504cf3..0000000000
--- a/stone_soup/crawl-ref/source/lua/stash.lua
+++ /dev/null
@@ -1,32 +0,0 @@
----------------------------------------------------------------------------
--- stash.lua
--- Annotates items for the stash-tracker.
---
--- To use this, add this line to your init.txt:
--- lua_file = lua/stash.lua
---
----------------------------------------------------------------------------
-
--- Annotate items for searches
-function ch_stash_search_annotate_item(it)
- local annot = ""
-
- if item.artifact(it) then
- annot = annot .. "{art} "
- elseif item.branded(it) then
- annot = annot .. "{ego} "
- elseif item.class(it, true) == "book" then
- annot = annot .. "{book} "
- end
-
- local skill = item.weap_skill(it)
- if skill then
- annot = annot .. "{" .. skill .. "} "
- end
-
- return annot
-end
-
---- If you want dumps (.lst files) to be annotated, uncomment this line:
--- ch_stash_dump_annotate_item = ch_stash_search_annotate_item
-
diff --git a/stone_soup/crawl-ref/source/lua/wield.lua b/stone_soup/crawl-ref/source/lua/wield.lua
deleted file mode 100644
index e4fe9951e3..0000000000
--- a/stone_soup/crawl-ref/source/lua/wield.lua
+++ /dev/null
@@ -1,47 +0,0 @@
----------------------------------------------------------------------------
--- wield.lua
--- Selects extra items to wield.
---
--- To use this, add this line to your init.txt:
--- lua_file = lua/wield.lua
----------------------------------------------------------------------------
-
-function make_hash(ls)
- local h = { }
- for _, i in ipairs(ls) do
- h[i] = true
- end
- return h
-end
-
-function ch_item_wieldable(it)
- -- We only need to check for unusual cases - basic matching is handled
- -- by Crawl itself.
- local spells = make_hash( you.spells() )
-
- if spells["Bone Shards"]
- and string.find( item.name(it, "a"), " skeleton" )
- then
- return true
- end
-
- if (spells["Sublimation of Blood"] or spells["Simulacrum"])
- and food.ischunk(it)
- then
- return true
- end
-
- if spells["Sandblast"]
- and string.find( item.name(it, "a"), " stones?$" )
- then
- return true
- end
-
- if spells["Sticks to Snakes"]
- and string.find( item.name(it, "a"), " arrows?$" )
- then
- return true
- end
-
- return false
-end
diff --git a/stone_soup/crawl-ref/source/machdr.h b/stone_soup/crawl-ref/source/machdr.h
deleted file mode 100644
index 5bad24eab7..0000000000
--- a/stone_soup/crawl-ref/source/machdr.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * File: MacHdr.h
- * Summary: OS specific stuff for inclusion into AppHdr.h.
- * Written by: Jesse Jones
- *
- * Copyright © 1999 Jesse Jones.
- *
- * Change History (most recent first):
- *
- * <1> 5/30/99 JDJ Created.
- */
-#ifndef MACHDR_H
-#define MACHDR_H
-
-#pragma check_header_flags on
-
-
-// ===================================================================================
-// MSL Defines
-// ===================================================================================
-#include <ansi_parms.h>
-
-#ifndef __dest_os
-#define __dest_os __mac_os
-#endif
-
-#ifndef __MSL_LONGLONG_SUPPORT__
-#define __MSL_LONGLONG_SUPPORT__
-#endif
-
-#ifndef MSIPL_DEF_EXPLICIT
-#define MSIPL_DEF_EXPLICIT // prevent explicit from being defined away
-#endif
-
-#if __MWERKS__ >= 0x2000
-#define MSIPL_TEMPL_NEWSPEC 1 // enable null_template
-#endif
-
-
-// ===================================================================================
-// Universal headers
-// ===================================================================================
-#define OLDROUTINENAMES 0
-#define OLDROUTINELOCATIONS 0
-
-#define STRICT_WINDOWS 0
-#define STRICT_CONTROLS 0
-#define STRICT_LISTS 0
-#define STRICT_MENUS 0
-
-#define USE_OLD_INPUT_SPROCKET_LABELS 0
-#define USE_OLD_ISPNEED_STRUCT 0
-
-#if 1
-// #include <ADSP.h>
-// #include <AEObjects.h>
-// #include <AEPackObject.h>
-// #include <AERegistry.h>
-// #include <AEUserTermTypes.h>
-// #include <AIFF.h>
-#include <Aliases.h>
-#include <AppleEvents.h>
-// #include <AppleGuide.h>
-// #include <AppleScript.h>
-// #include <AppleTalk.h>
-// #include <ASDebugging.h>
-// #include <ASRegistry.h>
-#include <Balloons.h>
-// #include <CMApplication.h>
-// #include <CMComponent.h>
-// #include <CodeFragments.h>
-#include <ColorPicker.h>
-// #include <CommResources.h>
-// #include <Components.h>
-#include <ConditionalMacros.h>
-// #include <Connections.h>
-// #include <ConnectionTools.h>
-#include <Controls.h>
-// #include <ControlStrip.h>
-// #include <CRMSerialDevices.h>
-// #include <CTBUtilities.h>
-// #include <CursorCtl.h>
-// #include <CursorDevices.h>
-// #include <DatabaseAccess.h>
-// #include <DeskBus.h>
-#include <Devices.h>
-#include <Dialogs.h>
-// #include <Dictionary.h>
-// #include <DisAsmLookup.h>
-// #include <Disassembler.h>
-#include <DiskInit.h>
-// #include <Disks.h>
-#include <Displays.h>
-#include <Drag.h>
-// #include <Editions.h>
-// #include <ENET.h>
-// #include <EPPC.h>
-// #include <ErrMgr.h>
-#include <Errors.h>
-#include <Events.h>
-// #include <fenv.h>
-#include <Files.h>
-// #include <FileTransfers.h>
-// #include <FileTransferTools.h>
-// #include <FileTypesAndCreators.h>
-#include <Finder.h>
-// #include <FixMath.h>
-#include <Folders.h>
-#include <Fonts.h>
-// #include <fp.h>
-// #include <FragLoad.h>
-// #include <FSM.h>
-#include <Gestalt.h>
-// #include <HyperXCmd.h>
-// #include <Icons.h>
-// #include <ImageCodec.h>
-// #include <ImageCompression.h>
-// #include <IntlResources.h>
-// #include <Language.h>
-// #include <Lists.h>
-#include <LowMem.h>
-// #include <MachineExceptions.h>
-// #include <MacTCP.h>
-// #include <MediaHandlers.h>
-#include <Memory.h>
-#include <Menus.h>
-// #include <MIDI.h>
-#include <MixedMode.h>
-// #include <Movies.h>
-// #include <MoviesFormat.h>
-// #include <Notification.h>
-// #include <OSA.h>
-// #include <OSAComp.h>
-// #include <OSAGeneric.h>
-#include <OSUtils.h>
-#include <Packages.h>
-#include <Palettes.h>
-// #include <PictUtil.h>
-// #include <PictUtils.h>
-#include <PLStringFuncs.h>
-// #include <Power.h>
-// #include <PPCToolbox.h>
-#include <Printing.h>
-#include <Processes.h>
-#include <QDOffscreen.h>
-#include <Quickdraw.h>
-#include <QuickdrawText.h>
-// #include <QuickTimeComponents.h>
-#include <Resources.h>
-// #include <Retrace.h>
-// #include <ROMDefs.h>
-#include <Scrap.h>
-// #include <Script.h>
-// #include <SCSI.h>
-#include <SegLoad.h>
-// #include <Serial.h>
-// #include <ShutDown.h>
-// #include <Slots.h>
-// #include <Sound.h>
-// #include <SoundComponents.h>
-// #include <SoundInput.h>
-// #include <Speech.h>
-#include <StandardFile.h>
-// #include <Start.h>
-#include <Strings.h>
-// #include <Terminals.h>
-// #include <TerminalTools.h>
-#include <TextEdit.h>
-// #include <TextServices.h>
-#include <TextUtils.h>
-// #include <Threads.h>
-// #include <Timer.h>
-#include <ToolUtils.h>
-// #include <Translation.h>
-// #include <TranslationExtensions.h>
-#include <Traps.h>
-// #include <TSMTE.h>
-#include <Types.h>
-// #include <Unmangler.h>
-// #include <Video.h>
-#include <Windows.h>
-// #include <WorldScript.h>
-#endif // PRECOMPILE_SYSTEM_HEADERS
-
-#endif
diff --git a/stone_soup/crawl-ref/source/macro.cc b/stone_soup/crawl-ref/source/macro.cc
deleted file mode 100644
index 13838a947c..0000000000
--- a/stone_soup/crawl-ref/source/macro.cc
+++ /dev/null
@@ -1,731 +0,0 @@
-/*
- * File: macro.cc
- * Summary: Crude macro-capability
- * Written by: Juho Snellman <jsnell@lyseo.edu.ouka.fi>
- *
- * Change History (most recent first):
- *
- * <3> 6/25/02 JS Completely rewritten
- * <2> 6/13/99 BWR SysEnv.crawl_dir support
- * <1> -/--/-- JS Created
- */
-
-/*
- * The macro-implementation works like this:
- * - For generic game code, #define getch() getchm().
- * - getchm() works by reading characters from an internal
- * buffer. If none are available, new characters are read into
- * the buffer with getch_mul().
- * - getch_mul() reads at least one character, but will read more
- * if available (determined using kbhit(), which should be defined
- * in the platform specific libraries).
- * - Before adding the characters read into the buffer, any macros
- * in the sequence are replaced (see macro_add_buf_long for the
- * details).
- *
- * (When the above text mentions characters, it actually means int).
- */
-
-#include "AppHdr.h"
-
-#ifdef USE_MACROS
-#define MACRO_CC
-#include "macro.h"
-
-#include <iostream>
-#include <fstream>
-#include <string>
-#include <map>
-#include <deque>
-#include <vector>
-
-#include <stdio.h> // for snprintf
-#include <ctype.h> // for tolower
-
-#include "externs.h"
-#include "stuff.h"
-
-// for trim_string:
-#include "initfile.h"
-
-typedef std::deque<int> keyseq;
-typedef std::deque<int> keybuf;
-typedef std::map<keyseq,keyseq> macromap;
-
-static macromap Keymaps[KC_CONTEXT_COUNT];
-static macromap Macros;
-
-static macromap *all_maps[] =
-{
- &Keymaps[KC_DEFAULT],
- &Keymaps[KC_LEVELMAP],
- &Keymaps[KC_TARGETING],
- &Macros,
-};
-
-static keybuf Buffer;
-
-#define USERFUNCBASE -10000
-static std::vector<std::string> userfunctions;
-
-inline int userfunc_index(int key)
-{
- int index = (key <= USERFUNCBASE? USERFUNCBASE - key : -1);
- return (index < 0 || index >= (int) userfunctions.size()? -1 : index);
-}
-
-static int userfunc_index(const keyseq &seq)
-{
- if (seq.empty())
- return (-1);
-
- return userfunc_index(seq.front());
-}
-
-bool is_userfunction(int key)
-{
- return (userfunc_index(key) != -1);
-}
-
-static bool is_userfunction(const keyseq &seq)
-{
- return (userfunc_index(seq) != -1);
-}
-
-const char *get_userfunction(int key)
-{
- int index = userfunc_index(key);
- return (index == -1? NULL : userfunctions[index].c_str());
-}
-
-static const char *get_userfunction(const keyseq &seq)
-{
- int index = userfunc_index(seq);
- return (index == -1? NULL : userfunctions[index].c_str());
-}
-
-static bool userfunc_referenced(int index, const macromap &mm)
-{
- for (macromap::const_iterator i = mm.begin(); i != mm.end(); i++)
- {
- if (userfunc_index(i->second) == index)
- return (true);
- }
- return (false);
-}
-
-static bool userfunc_referenced(int index)
-{
- for (unsigned i = 0; i < sizeof(all_maps) / sizeof(*all_maps); ++i)
- {
- macromap *m = all_maps[i];
- if (userfunc_referenced(index, *m))
- return (true);
- }
- return (false);
-}
-
-// Expensive function to discard unused function names
-static void userfunc_collectgarbage(void)
-{
- for (int i = userfunctions.size() - 1; i >= 0; --i)
- {
- if (!userfunctions.empty() && !userfunc_referenced(i))
- userfunctions[i].clear();
- }
-}
-
-static int userfunc_getindex(const std::string &fname)
-{
- if (fname.length() == 0)
- return (-1);
-
- userfunc_collectgarbage();
-
- // Pass 1 to see if we have this string already
- for (int i = 0, count = userfunctions.size(); i < count; ++i)
- {
- if (userfunctions[i] == fname)
- return (i);
- }
-
- // Pass 2 to hunt for gaps
- for (int i = 0, count = userfunctions.size(); i < count; ++i)
- {
- if (userfunctions[i].empty())
- {
- userfunctions[i] = fname;
- return (i);
- }
- }
-
- userfunctions.push_back(fname);
- return (userfunctions.size() - 1);
-}
-
-/*
- * Returns the name of the file that contains macros.
- */
-static std::string get_macro_file()
-{
- std::string s;
-
- if (SysEnv.crawl_dir)
- s = SysEnv.crawl_dir;
-
- return (s + "macro.txt");
-}
-
-static void buf2keyseq(const char *buff, keyseq &k)
-{
- // Sanity check
- if (!buff)
- return;
-
- // convert c_str to keyseq
-
- // Check for user functions
- if (*buff == '=' && buff[1] == '=' && buff[2] == '=' && buff[3])
- {
- int index = userfunc_getindex(buff + 3);
- if (index != -1)
- k.push_back( USERFUNCBASE - index );
- }
- else
- {
- const int len = strlen( buff );
- for (int i = 0; i < len; i++)
- k.push_back( buff[i] );
- }
-}
-
-/*
- * Takes as argument a string, and returns a sequence of keys described
- * by the string. Most characters produce their own ASCII code. There
- * are two special cases:
- * \\ produces the ASCII code of a single \
- * \{123} produces 123 (decimal)
- */
-static keyseq parse_keyseq( std::string s )
-{
- int state = 0;
- keyseq v;
- int num;
-
- if (s.find("===") == 0)
- {
- buf2keyseq(s.c_str(), v);
- return (v);
- }
-
- for (std::string::iterator i = s.begin(); i != s.end(); i++)
- {
- char c = *i;
-
- switch (state)
- {
- case 0: // Normal state
- if (c == '\\') {
- state = 1;
- } else {
- v.push_back(c);
- }
- break;
-
- case 1: // Last char is a '\'
- if (c == '\\') {
- state = 0;
- v.push_back(c);
- } else if (c == '{') {
- state = 2;
- num = 0;
- }
- // XXX Error handling
- break;
-
- case 2: // Inside \{}
- if (c == '}') {
- v.push_back(num);
- state = 0;
- } else if (c >= '0' && c <= '9') {
- num = num * 10 + c - '0';
- }
- // XXX Error handling
- break;
- }
- }
-
- return (v);
-}
-
-/*
- * Serializes a key sequence into a string of the format described
- * above.
- */
-static std::string vtostr( const keyseq &seq )
-{
- std::string s;
-
- const keyseq *v = &seq;
- keyseq dummy;
- if (is_userfunction(seq))
- {
- // Laboriously reconstruct the original user input
- std::string newseq = std::string("==") + get_userfunction(seq);
- buf2keyseq(newseq.c_str(), dummy);
- dummy.push_front('=');
-
- v = &dummy;
- }
-
- for (keyseq::const_iterator i = v->begin(); i != v->end(); i++)
- {
- if (*i <= 32 || *i > 127) {
- char buff[10];
-
- snprintf( buff, sizeof(buff), "\\{%d}", *i );
- s += std::string( buff );
-
- // Removing the stringstream code because its highly
- // non-portable. For starters, people and compilers
- // are supposed to be using the <sstream> implementation
- // (with the ostringstream class) not the old <strstream>
- // version, but <sstream> is not as available as it should be.
- //
- // The strstream implementation isn't very standard
- // either: some compilers require the "ends" marker,
- // others don't (and potentially fatal errors can
- // happen if you don't have it correct for the system...
- // ie its hard to make portable). It also isn't a very
- // good implementation to begin with.
- //
- // Everyone should have snprintf()... we supply a version
- // in libutil.cc to make sure of that! -- bwr
- //
- // std::ostrstream ss;
- // ss << "\\{" << *i << "}" << ends;
- // s += ss.str();
- } else if (*i == '\\') {
- s += "\\\\";
- } else {
- s += *i;
- }
- }
-
- return (s);
-}
-
-/*
- * Add a macro (suprise, suprise).
- */
-static void macro_add( macromap &mapref, keyseq key, keyseq action )
-{
- mapref[key] = action;
-}
-
-static void macro_add( macromap &mapref, keyseq key, const char *buff )
-{
- keyseq act;
- buf2keyseq(buff, act);
- if (!act.empty())
- macro_add( mapref, key, act );
-}
-
-/*
- * Remove a macro.
- */
-static void macro_del( macromap &mapref, keyseq key )
-{
- mapref.erase( key );
-}
-
-
-/*
- * Adds keypresses from a sequence into the internal keybuffer. Ignores
- * macros.
- */
-static void macro_buf_add( keyseq actions )
-{
- for (keyseq::iterator i = actions.begin(); i != actions.end(); i++)
- Buffer.push_back(*i);
-}
-
-/*
- * Adds a single keypress into the internal keybuffer.
- */
-void macro_buf_add( int key )
-{
- Buffer.push_back( key );
-}
-
-
-/*
- * Adds keypresses from a sequence into the internal keybuffer. Does some
- * O(N^2) analysis to the sequence to replace macros.
- */
-static void macro_buf_add_long( keyseq actions, macromap &keymap = Keymaps[KC_DEFAULT] )
-{
- keyseq tmp;
-
- // debug << "Adding: " << vtostr(actions) << endl;
- // debug.flush();
-
- // Check whether any subsequences of the sequence are macros.
- // The matching starts from as early as possible, and is
- // as long as possible given the first constraint. I.e from
- // the sequence "abcdef" and macros "ab", "bcde" and "de"
- // "ab" and "de" are recognized as macros.
-
- while (actions.size() > 0)
- {
- tmp = actions;
-
- while (tmp.size() > 0)
- {
- keyseq result = keymap[tmp];
-
- // Found a macro. Add the expansion (action) of the
- // macro into the buffer.
- if (result.size() > 0) {
- macro_buf_add( result );
- break;
- }
-
- // Didn't find a macro. Remove a key from the end
- // of the sequence, and try again.
- tmp.pop_back();
- }
-
- if (tmp.size() == 0) {
- // Didn't find a macro. Add the first keypress of the sequence
- // into the buffer, remove it from the sequence, and try again.
- macro_buf_add( actions.front() );
- actions.pop_front();
-
- } else {
- // Found a macro, which has already been added above. Now just
- // remove the macroed keys from the sequence.
- for (unsigned int i = 0; i < tmp.size(); i++)
- actions.pop_front();
- }
- }
-}
-
-/*
- * Command macros are only applied from the immediate front of the
- * buffer, and only when the game is expecting a command.
- */
-static void macro_buf_apply_command_macro( void )
-{
- keyseq tmp = Buffer;
-
- // find the longest match from the start of the buffer and replace it
- while (tmp.size() > 0)
- {
- keyseq result = Macros[tmp];
-
- if (result.size() > 0)
- {
- // Found macro, remove match from front:
- for (unsigned int i = 0; i < tmp.size(); i++)
- Buffer.pop_front();
-
- // Add macro to front:
- for (keyseq::reverse_iterator k = result.rbegin(); k != result.rend(); k++)
- Buffer.push_front(*k);
-
- break;
- }
-
- tmp.pop_back();
- }
-}
-
-/*
- * Removes the earlies keypress from the keybuffer, and returns its
- * value. If buffer was empty, returns -1;
- */
-static int macro_buf_get( void )
-{
- if (Buffer.size() == 0)
- return (-1);
-
- int key = Buffer.front();
- Buffer.pop_front();
-
- return (key);
-}
-
-static void write_map(std::ofstream &f, const macromap &mp, const char *key)
-{
- for (macromap::const_iterator i = mp.begin(); i != mp.end(); i++)
- {
- // Need this check, since empty values are added into the
- // macro struct for all used keyboard commands.
- if (i->second.size())
- {
- f << key << vtostr((*i).first) << std::endl
- << "A:" << vtostr((*i).second) << std::endl << std::endl;
- }
- }
-}
-
-/*
- * Saves macros into the macrofile, overwriting the old one.
- */
-void macro_save( void )
-{
- std::ofstream f;
- f.open( get_macro_file().c_str() );
-
- f << "# WARNING: This file is entirely auto-generated." << std::endl
- << std::endl << "# Key Mappings:" << std::endl;
- for (int mc = KC_DEFAULT; mc < KC_CONTEXT_COUNT; ++mc) {
- char keybuf[30] = "K:";
- if (mc)
- snprintf(keybuf, sizeof keybuf, "K%d:", mc);
- write_map(f, Keymaps[mc], keybuf);
- }
-
- f << "# Command Macros:" << std::endl;
- write_map(f, Macros, "M:");
-
- f.close();
-}
-
-/*
- * Reads as many keypresses as are available (waiting for at least one),
- * and returns them as a single keyseq.
- */
-static keyseq getch_mul( int (*rgetch)() = NULL )
-{
- keyseq keys;
- int a;
-
- if (!rgetch)
- rgetch = getch;
-
- keys.push_back( a = rgetch() );
-
- // The a == 0 test is legacy code that I don't dare to remove. I
- // have a vague recollection of it being a kludge for conio support.
- while ((kbhit() || a == 0)) {
- keys.push_back( a = rgetch() );
- }
-
- return (keys);
-}
-
-/*
- * Replacement for getch(). Returns keys from the key buffer if available.
- * If not, adds some content to the buffer, and returns some of it.
- */
-int getchm( int (*rgetch)() )
-{
- return getchm( KC_DEFAULT, rgetch );
-}
-
-int getchm(KeymapContext mc, int (*rgetch)())
-{
- int a;
-
- // Got data from buffer.
- if ((a = macro_buf_get()) != -1)
- return (a);
-
- // Read some keys...
- keyseq keys = getch_mul(rgetch);
- // ... and add them into the buffer
- macro_buf_add_long( keys, Keymaps[mc] );
-
- return (macro_buf_get());
-}
-
-/*
- * Replacement for getch(). Returns keys from the key buffer if available.
- * If not, adds some content to the buffer, and returns some of it.
- */
-int getch_with_command_macros( void )
-{
- if (Buffer.size() == 0)
- {
- // Read some keys...
- keyseq keys = getch_mul();
- // ... and add them into the buffer (apply keymaps)
- macro_buf_add_long( keys );
- }
-
- // Apply longest matching macro at front of buffer:
- macro_buf_apply_command_macro();
-
- return (macro_buf_get());
-}
-
-/*
- * Flush the buffer. Later we'll probably want to give the player options
- * as to when this happens (ex. always before command input, casting failed).
- */
-void flush_input_buffer( int reason )
-{
- if (Options.flush_input[ reason ])
- Buffer.clear();
-}
-
-void macro_add_query( void )
-{
- unsigned char input;
- bool keymap = false;
- KeymapContext keymc = KC_DEFAULT;
-
- mesclr();
- mpr( "Command (m)acro or keymap [(k) default, (x) level-map or "
- "(t)argeting]? ", MSGCH_PROMPT );
- input = getch();
- if (input == 0)
- input = getch();
-
- input = tolower( input );
- if (input == 'k')
- {
- keymap = true;
- keymc = KC_DEFAULT;
- }
- else if (input == 'x')
- {
- keymap = true;
- keymc = KC_LEVELMAP;
- }
- else if (input == 't')
- {
- keymap = true;
- keymc = KC_TARGETING;
- }
- else if (input == 'm')
- keymap = false;
- else
- {
- mpr( "Aborting." );
- return;
- }
-
- // reference to the appropriate mapping
- macromap &mapref = (keymap ? Keymaps[keymc] : Macros);
-
- snprintf( info, INFO_SIZE, "Input %s%s trigger key: ",
- keymap?
- (keymc == KC_DEFAULT? "default " :
- keymc == KC_LEVELMAP? "level-map " :
- "targeting ") :
- "",
- (keymap ? "keymap" : "macro") );
-
- mpr( info, MSGCH_PROMPT );
- keyseq key = getch_mul();
-
- cprintf( "%s" EOL, (vtostr( key )).c_str() ); // echo key to screen
-
- if (mapref[key].size() > 0)
- {
- snprintf( info, INFO_SIZE, "Current Action: %s",
- (vtostr( mapref[key] )).c_str() );
-
- mpr( info, MSGCH_WARN );
- mpr( "Do you wish to (r)edefine, (c)lear, or (a)bort?", MSGCH_PROMPT );
-
- input = getch();
- if (input == 0)
- input = getch();
-
- input = tolower( input );
- if (input == 'a' || input == ESCAPE)
- {
- mpr( "Aborting." );
- return;
- }
- else if (input == 'c')
- {
- mpr( "Cleared." );
- macro_del( mapref, key );
- return;
- }
- }
-
- mpr( "Input Macro Action: ", MSGCH_PROMPT );
-
- // Using getch_mul() here isn't very useful... We'd like the
- // flexibility to define multicharacter macros without having
- // to resort to editing files and restarting the game. -- bwr
- // keyseq act = getch_mul();
-
- char buff[4096];
- get_input_line(buff, sizeof buff);
-
- if (Options.macro_meta_entry)
- {
- macro_add( mapref, key, parse_keyseq(buff) );
- }
- else
- {
- macro_add( mapref, key, buff );
- }
-
- redraw_screen();
-}
-
-
-/*
- * Initializes the macros.
- */
-int macro_init( void )
-{
- std::string s;
- std::ifstream f;
- keyseq key, action;
- bool keymap = false;
- KeymapContext keymc = KC_DEFAULT;
-
- f.open( get_macro_file().c_str() );
-
- while (f >> s)
- {
- trim_string(s); // remove white space from ends
-
- if (s[0] == '#') {
- continue; // skip comments
-
- } else if (s.substr(0, 2) == "K:") {
- key = parse_keyseq(s.substr(2));
- keymap = true;
- keymc = KC_DEFAULT;
-
- } else if (s.length() >= 3 && s[0] == 'K' && s[2] == ':') {
- keymc = KeymapContext( KC_DEFAULT + s[1] - '0' );
- if (keymc >= KC_DEFAULT && keymc < KC_CONTEXT_COUNT) {
- key = parse_keyseq(s.substr(3));
- keymap = true;
- }
-
- } else if (s.substr(0, 2) == "M:") {
- key = parse_keyseq(s.substr(2));
- keymap = false;
-
- } else if (s.substr(0, 2) == "A:") {
- action = parse_keyseq(s.substr(2));
- macro_add( (keymap ? Keymaps[keymc] : Macros), key, action );
- }
- }
-
- return (0);
-}
-
-#ifdef CLUA_BINDINGS
-void macro_userfn(const char *keys, const char *regname)
-{
- // TODO: Implement.
- // Converting 'keys' to a key sequence is the difficulty. Doing it portably
- // requires a mapping of key names to whatever getch() spits back, unlikely
- // to happen in a hurry.
-}
-#endif
-
-#endif
diff --git a/stone_soup/crawl-ref/source/macro.h b/stone_soup/crawl-ref/source/macro.h
deleted file mode 100644
index dba3bafafe..0000000000
--- a/stone_soup/crawl-ref/source/macro.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * File: macro.cc
- * Summary: Crude macro-capability
- * Written by: Juho Snellman <jsnell@lyseo.edu.ouka.fi>
- *
- * Change History (most recent first):
- *
- * <2> 6/25/02 JS Removed old cruft
- * <1> -/--/-- JS Created
- */
-
-#ifdef USE_MACROS
-
-#ifndef MACRO_H
-#define MACRO_H
-
-#ifndef MACRO_CC
-
-#undef getch
-#define getch() getchm()
-
-#endif
-
-enum KeymapContext {
- KC_DEFAULT, // For no-arg getchm().
- KC_LEVELMAP, // When in the 'X' level map
- KC_TARGETING, // Only during 'x' and other targeting modes
-
- KC_CONTEXT_COUNT // Must always be the last
-};
-
-int getchm(int (*rgetch)() = NULL); // keymaps applied (ie for prompts)
-int getchm(KeymapContext context, int (*rgetch)() = NULL);
-
-int getch_with_command_macros(void); // keymaps and macros (ie for commands)
-
-void flush_input_buffer( int reason );
-
-void macro_add_query(void);
-int macro_init(void);
-void macro_save(void);
-
-void macro_userfn(const char *keys, const char *registryname);
-
-void macro_buf_add(int key);
-
-bool is_userfunction(int key);
-
-const char *get_userfunction(int key);
-
-#endif
-
-#else
-
-#define getch_with_command_macros() getch()
-#define getchm(x) getch()
-#define flush_input_buffer(XXX) ;
-#define macro_buf_add(x)
-#define is_userfunction(x) false
-#define get_userfunction(x) NULL
-#define call_userfunction(x)
-
-#endif
diff --git a/stone_soup/crawl-ref/source/makefile b/stone_soup/crawl-ref/source/makefile
deleted file mode 100644
index 9dc90ac5ad..0000000000
--- a/stone_soup/crawl-ref/source/makefile
+++ /dev/null
@@ -1,44 +0,0 @@
-#
-# Modified for Crawl Reference by $Author$ on $Date$
-#
-
-#Makefile chooser. Choose one:
-
-MAKEFILE = makefile.lnx
-#MAKEFILE = makefile.sgi
-#MAKEFILE = makefile.dos
-#MAKEFILE = makefile.emx
-#MAKEFILE = makefile.sol
-#MAKEFILE = makefile.osx
-#MAKEFILE = makefile.mgw
-
-#jmf: number of concurrent jobs -- good value is (#_of_CPUs * 2) + 1
-# cuts build time a lot on multi-cpu machines
-#OTHER=-j2
-
-all:
- $(MAKE) $(OTHER) -f $(MAKEFILE) EXTRA_FLAGS='-O2 -fno-strength-reduce'
-
-noopt:
- $(MAKE) $(OTHER) -f $(MAKEFILE)
-
-install:
- $(MAKE) $(OTHER) -f $(MAKEFILE) install
-
-clean:
- $(MAKE) $(OTHER) -f $(MAKEFILE) clean
-
-distclean:
- $(MAKE) $(OTHER) -f $(MAKEFILE) distclean
-
-# WIZARD mode currently includes asserts, bounds checking, and item checking
-wizard:
- $(MAKE) $(OTHER) -f $(MAKEFILE) debug EXTRA_FLAGS='-g -DWIZARD -DDEBUG -DDEBUG_ITEM_SCAN'
-
-# DEBUG mode includes WIZARD mode as well as copious debugging input
-debug:
- $(MAKE) $(OTHER) -f $(MAKEFILE) DEBUG_CRAWL=y debug EXTRA_FLAGS='-g -DFULLDEBUG -DWIZARD'
-
-# DO NOT DELETE THIS LINE -- $(MAKE) depend depends on it.
-
-
diff --git a/stone_soup/crawl-ref/source/makefile.bor b/stone_soup/crawl-ref/source/makefile.bor
deleted file mode 100644
index d90cf636d9..0000000000
--- a/stone_soup/crawl-ref/source/makefile.bor
+++ /dev/null
@@ -1,53 +0,0 @@
-#
-# Makefile for Borland C++ 5.5 free commandline tools
-#
-
-!include makefile.obj
-
-GAME = ..\crawl.exe
-
-all : $(GAME)
-
-.PHONY : clean
-.PHONY : debug
-.PHONY : noopt
-.PHONY : install
-.PHONY : wizard
-
-clean :
- $(DEL) *.o
-
-debug :
-
-noopt :
-
-install :
-
-wizard :
-
-#
-# Borland C++ tools
-#
-CC = bcc32
-LINK = ilink32
-DEL = del
-
-#
-# windows defines, including windows version to make sure code runs on
-# all windows systems
-#
-WIN32DEFINES = WIN32CONSOLE;NEED_SPRINTF;WINVER=0x0400;_WIN32_WINNT=0x0400;__BCPLUSPLUS__
-
-#
-# Options
-#
-LINKOPTS = -Tpe -ap -c -x /V4.0
-CFLAGS = -I. -D$(WIN32DEFINES) -4 -a -k- -Oc -OS -Oi -Ov -H- -P -c
-NICEFLAGS = -w-8004
-DEBUGFLAGS = -v -y
-
-$(GAME) : $(OBJECTS) libw32c.o
- $(LINK) $(LINKOPTS) c0x32.obj $?, $(GAME),, import32.lib cw32.lib
-
-.cc.o:
- $(CC) $(CFLAGS) $(NICEFLAGS) -o$*.o $<
diff --git a/stone_soup/crawl-ref/source/makefile.bsd b/stone_soup/crawl-ref/source/makefile.bsd
deleted file mode 100644
index 9e10d1ebf8..0000000000
--- a/stone_soup/crawl-ref/source/makefile.bsd
+++ /dev/null
@@ -1,64 +0,0 @@
-# -*- Makefile -*- for Dungeon Crawl (BSD)
-
-#
-# Modified for Crawl Reference by $Author$ on $Date$
-#
-
-GAME = crawl
-
-# this file contains a list of the libraries.
-# it will make a variable called OBJECTS that contains all the libraries
-include makefile.obj
-
-OBJECTS += libunix.o
-
-CXX = g++
-DELETE = rm -f
-COPY = cp
-OS_TYPE = BSD
-CFLAGS = -Wall -D$(OS_TYPE) $(EXTRA_FLAGS)
-LDFLAGS = -static -L/usr/lib
-MCHMOD = 711
-# INSTALLDIR = /usr/games
-INSTALLDIR = /tmp/CRAWLTEST/testdev
-LIB = -lncurses
-
-INCLUDES = -I/usr/include/ncurses
-
-all: $(GAME)
-
-install: $(GAME)
- $(COPY) $(GAME) ${INSTALLDIR}
- chmod ${MCHMOD} ${INSTALLDIR}/$(GAME)
-
-clean:
- $(DELETE) *.o
-
-distclean:
- $(DELETE) *.o
- $(DELETE) bones.*
- $(DELETE) morgue.txt
- $(DELETE) scores
- $(DELETE) $(GAME)
- $(DELETE) *.sav
- $(DELETE) core
- $(DELETE) *.0*
- $(DELETE) *.lab
-
-
-$(GAME): $(OBJECTS)
- ${CXX} ${LDFLAGS} $(INCLUDES) $(CFLAGS) $(OBJECTS) -o $(GAME) $(LIB)
- strip $(GAME)
- chmod ${MCHMOD} $(GAME)
-
-debug: $(OBJECTS)
- ${CXX} ${LDFLAGS} $(INCLUDES) $(CFLAGS) $(OBJECTS) -o $(GAME) $(LIB)
-
-profile: $(OBJECTS)
- ${CXX} -g -p ${LDFLAGS} $(INCLUDES) $(CFLAGS) $(OBJECTS) -o $(GAME) $(LIB)
-
-.cc.o:
- ${CXX} ${CFLAGS} -c $< ${INCLUDE}
-
-.h.cc:
- touch $@
diff --git a/stone_soup/crawl-ref/source/makefile.dos b/stone_soup/crawl-ref/source/makefile.dos
deleted file mode 100644
index 869d6f8745..0000000000
--- a/stone_soup/crawl-ref/source/makefile.dos
+++ /dev/null
@@ -1,53 +0,0 @@
-# Make file for Dungeon Crawl (dos)
-
-# this file contains a list of the libraries.
-# it will make a variable called OBJECTS that contains all the libraries
-include makefile.obj
-
-# need .exe so make will find the right file
-APPNAME = crawl.exe
-CXX = gxx
-DELETE = del
-COPY = copy
-OS_TYPE = DOS
-CFLAGS = -D$(OS_TYPE) $(EXTRA_FLAGS)
-LDFLAGS = -Bc:/djgpp/contrib/pdcurs22/lib
-INSTALLDIR = c:\games\crawl
-# LIB = -lcurso -lpano
-
-all: $(APPNAME)
-
-install: $(APPNAME)
- $(COPY) $(APPNAME) ${INSTALLDIR}
-
-clean:
- $(DELETE) *.o
-
-distclean:
- $(DELETE) *.o
- $(DELETE) bones.*
- $(DELETE) morgue.txt
- $(DELETE) scores
- $(DELETE) $(APPNAME)
- $(DELETE) *.sav
- $(DELETE) core
- $(DELETE) *.0*
- $(DELETE) *.lab
-
-$(APPNAME): $(OBJECTS)
- ${CXX} ${LDFLAGS} $(INCLUDES) $(CFLAGS) $(OBJECTS) -o $(APPNAME) $(LIB)
- strip $(APPNAME)
-
-debug: $(OBJECTS)
- ${CXX} ${LDFLAGS} $(INCLUDES) $(CFLAGS) $(OBJECTS) -o $(APPNAME) $(LIB)
-
-profile: $(OBJECTS)
- ${CXX} -g -p ${LDFLAGS} $(INCLUDES) $(CFLAGS) $(OBJECTS) -o $(APPNAME) $(LIB)
-
-.cc.o:
- ${CXX} ${CFLAGS} -c $< ${INCLUDE}
-
-# I don't have touch for DOS, but if you do, you can put this back.
-#
-#.h.cc:
-# touch $@
diff --git a/stone_soup/crawl-ref/source/makefile.emx b/stone_soup/crawl-ref/source/makefile.emx
deleted file mode 100644
index 13e99e47fe..0000000000
--- a/stone_soup/crawl-ref/source/makefile.emx
+++ /dev/null
@@ -1,53 +0,0 @@
-# Makefile for Dungeon Crawl (OS/2 EMX port)
-# 1998 (C) Alexey Guzeev, aga@russia.crosswinds.net
-# EMX is covered by GNU GPL
-# Dungeon Crawl is covered by Crawl GPL
-# OS/2 is a trademark of IBM Corp.
-# IBM is a trademark of IBM Corp.
-# :)
-
-# 1. make some directory, like \crawl
-# 2. make subdirectory for sources, \crawl\src
-# 3. put crawl sources in \crawl\src directory
-# 4. make directory \crawl\src current
-# 5. execute command 'dmake -B -r -f makefile.emx install'
-# 6. remove \crawl\src subdirectory with all contents
-# 7. delete \crawl\scoretable.exe - I don't know what it does :)
-# 8. run \crawl\crawl.exe & enjoy!
-
-
-CC = gcc
-CFLAGS = -Wall -O3 -MMD -Zmt -DUSE_EMX
-LIBS = -lvideo -lbsd
-AR = ar
-
-include makefile.obj
-
-OBJ = $(OBJECTS)
-
-
-all: crawl.exe scoretable.exe
-
-install: ..\crawl.exe ..\scoretable.exe
-
-crawl.a: $(OBJS)
- $(AR) r crawl.a $(OBJS)
-
-..\crawl.exe: crawl.exe
- +copy crawl.exe ..
- emxbind -s ..\crawl.exe
-
-..\scoretable.exe: scoretable.exe
- +copy scoretable.exe ..
- emxbind -s ..\scoretable.exe
-clean:
- +del *.o
-
-crawl.exe: crawl.a libemx.o
- $(CC) -o crawl.exe crawl.a libemx.o $(LIBS)
-
-scoretable.exe: scoretab.o libemx.o
- $(CC) -o scoretable.exe scoretab.o libemx.o $(LIBS)
-
-.cc.o:
- $(CC) $(CFLAGS) -c $*.cc
diff --git a/stone_soup/crawl-ref/source/makefile.lnx b/stone_soup/crawl-ref/source/makefile.lnx
deleted file mode 100644
index 8b8b8994fd..0000000000
--- a/stone_soup/crawl-ref/source/makefile.lnx
+++ /dev/null
@@ -1,68 +0,0 @@
-# -*- Makefile -*- for Dungeon Crawl (linux)
-
-#
-# Modified for Crawl Reference by $Author$ on $Date$
-#
-
-GAME = crawl
-
-# this file contains a list of the libraries.
-# it will make a variable called OBJECTS that contains all the libraries
-include makefile.obj
-
-OBJECTS += libunix.o
-
-CXX = g++
-DELETE = rm -f
-COPY = cp
-OS_TYPE = LINUX
-
-CFLAGS = -Wall -Wwrite-strings -fsigned-char \
- -g -D$(OS_TYPE) $(EXTRA_FLAGS)
-
-MCHMOD = 2755
-
-# [dshaligram] More common location than /opt/crawl/bin - this is from the
-# Debian patch.
-INSTALLDIR = /usr/games
-LIB = -lncurses
-
-# Include for Linux
-INCLUDES = -I/usr/include/ncurses
-
-all: $(GAME)
-
-install: $(GAME)
- $(COPY) $(GAME) ${INSTALLDIR}
- chmod ${MCHMOD} ${INSTALLDIR}/$(GAME)
-
-clean:
- $(DELETE) *.o
-
-distclean:
- $(DELETE) *.o
- $(DELETE) bones.*
- $(DELETE) morgue.txt
- $(DELETE) scores
- $(DELETE) $(GAME)
- $(DELETE) *.sav
- $(DELETE) core
- $(DELETE) *.0*
- $(DELETE) *.lab
-
-
-$(GAME): $(OBJECTS)
- ${CXX} ${LDFLAGS} $(INCLUDES) $(CFLAGS) $(OBJECTS) -o $(GAME) $(LIB)
- chmod ${MCHMOD} $(GAME)
-
-debug: $(OBJECTS)
- ${CXX} ${LDFLAGS} $(INCLUDES) $(CFLAGS) $(OBJECTS) -o $(GAME) $(LIB)
-
-profile: $(OBJECTS)
- ${CXX} -g -p ${LDFLAGS} $(INCLUDES) $(CFLAGS) $(OBJECTS) -o $(GAME) $(LIB)
-
-.cc.o:
- ${CXX} ${CFLAGS} -c $< ${INCLUDE}
-
-.h.cc:
- touch $@
diff --git a/stone_soup/crawl-ref/source/makefile.mgw b/stone_soup/crawl-ref/source/makefile.mgw
deleted file mode 100644
index 7c683cd369..0000000000
--- a/stone_soup/crawl-ref/source/makefile.mgw
+++ /dev/null
@@ -1,74 +0,0 @@
-# Make file for Dungeon Crawl (Win32, MinGW)
-
-# this file contains a list of the libraries.
-# it will make a variable called OBJECTS that contains all the libraries
-include makefile.obj
-
-ifeq ($(DEBUG_CRAWL),)
-OPATH := rel
-else
-OPATH := dbg
-endif
-
-# need .exe so make will find the right file
-APPNAME = $(OPATH)\crawl.exe
-CXX = g++
-DELETE = del
-COPY = copy
-OS_TYPE = WIN32CONSOLE
-CFLAGS = -Wall -Wwrite-strings -Wstrict-prototypes \
- -Wmissing-prototypes -Wmissing-declarations \
- -D$(OS_TYPE) $(EXTRA_FLAGS) -DCLUA_BINDINGS \
- -DWINMM_PLAY_SOUNDS -DREGEX_PCRE
-
-OBJECTS := $(OBJECTS) libw32c.o
-OBJECTS := $(foreach file,$(OBJECTS),$(OPATH)/$(file))
-
-LDFLAGS =
-INSTALLDIR = .
-#LIB = -lcurso -lpano
-LIB = -lwinmm -static -lpcre -llua -llualib
-
-all: $(APPNAME)
-
-prepare:
- if not exist $(OPATH) mkdir $(OPATH)
-
-install: $(APPNAME)
- $(COPY) $(APPNAME) ${INSTALLDIR}
-
-clean:
- $(DELETE) $(OPATH)\*.o
-
-distclean:
- $(DELETE) $(OPATH)\*.o
- $(DELETE) *.o
- $(DELETE) bones.*
- $(DELETE) $(OPATH)\bones.*
- $(DELETE) morgue.txt
- $(DELETE) $(OPATH)\morgue.txt
- $(DELETE) scores
- $(DELETE) $(OPATH)\scores
- $(DELETE) crawl.exe
- $(DELETE) $(subst /,\,$(APPNAME))
- $(DELETE) *.sav
- $(DELETE) $(OPATH)\*.sav
- $(DELETE) core
- $(DELETE) $(OPATH)\core
- $(DELETE) *.0*
- $(DELETE) $(OPATH)\*.0*
- $(DELETE) *.lab
- $(DELETE) $(OPATH)\*.lab
-
-$(APPNAME): prepare $(OBJECTS)
- ${CXX} ${LDFLAGS} $(INCLUDES) $(CFLAGS) $(OBJECTS) -o $(APPNAME) $(LIB)
- strip $(APPNAME)
-
-debug: prepare $(OBJECTS)
- ${CXX} ${LDFLAGS} $(INCLUDES) $(CFLAGS) $(OBJECTS) -o $(APPNAME) $(LIB)
-
-profile: $(OBJECTS)
- ${CXX} -g -p ${LDFLAGS} $(INCLUDES) $(CFLAGS) $(OBJECTS) -o $(APPNAME) $(LIB)
-
-$(OPATH)/%.o: %.cc
- ${CXX} ${CFLAGS} ${INCLUDES} -o $@ -c $<
diff --git a/stone_soup/crawl-ref/source/makefile.obj b/stone_soup/crawl-ref/source/makefile.obj
deleted file mode 100644
index 8cadd1cebd..0000000000
--- a/stone_soup/crawl-ref/source/makefile.obj
+++ /dev/null
@@ -1,69 +0,0 @@
-OBJECTS = \
-abl-show.o \
-abyss.o \
-acr.o \
-beam.o \
-chardump.o \
-cloud.o \
-command.o \
-debug.o \
-delay.o \
-decks.o \
-describe.o \
-direct.o \
-dungeon.o \
-effects.o \
-fight.o \
-files.o \
-food.o \
-hiscores.o \
-initfile.o \
-insult.o \
-invent.o \
-it_use2.o \
-it_use3.o \
-item_use.o \
-itemname.o \
-itemprop.o \
-items.o \
-lev-pand.o \
-libutil.o \
-macro.o \
-maps.o \
-menu.o \
-message.o \
-misc.o \
-monplace.o \
-mon-pick.o \
-monstuff.o \
-monspeak.o \
-mon-util.o \
-mstuff2.o \
-mutation.o \
-newgame.o \
-ouch.o \
-output.o \
-overmap.o \
-player.o \
-randart.o \
-religion.o \
-shopping.o \
-skills.o \
-skills2.o \
-spells1.o \
-spells2.o \
-spells3.o \
-spells4.o \
-spl-book.o \
-spl-cast.o \
-spl-util.o \
-stash.o \
-stuff.o \
-tags.o \
-transfor.o \
-travel.o \
-view.o \
-wpn-misc.o \
-Kills.o \
-mt19937ar.o \
-clua.o
diff --git a/stone_soup/crawl-ref/source/makefile.osx b/stone_soup/crawl-ref/source/makefile.osx
deleted file mode 100644
index 7cee7c3452..0000000000
--- a/stone_soup/crawl-ref/source/makefile.osx
+++ /dev/null
@@ -1,61 +0,0 @@
-# -*- Makefile -*- for Dungeon Crawl
-
-#
-# Modified for Crawl Reference by $Author$ on $Date$
-#
-
-GAME = crawl
-
-# this file contains a list of the libraries.
-# it will make a variable called OBJECTS that contains all the libraries
-include makefile.obj
-
-OBJECTS += libunix.o
-
-CXX = g++
-DELETE = rm -f
-COPY = cp
-OS_TYPE = OSX
-
-CFLAGS = -Wall -Werror -D$(OS_TYPE) $(EXTRA_FLAGS)
-
-MCHMOD = 711
-INSTALLDIR = /tmp/CRAWLTEST/testdev
-LIB = -lncurses -lstdc++
-
-all: $(GAME)
-
-install: $(GAME)
- $(COPY) $(GAME) ${INSTALLDIR}
- ${MCHMOD} ${INSTALLDIR}/$(GAME)
-
-clean:
- $(DELETE) *.o
-
-distclean:
- $(DELETE) *.o
- $(DELETE) bones.*
- $(DELETE) morgue.txt
- $(DELETE) scores
- $(DELETE) $(GAME)
- $(DELETE) *.sav
- $(DELETE) core
- $(DELETE) *.0*
- $(DELETE) *.lab
-
-
-$(GAME): $(OBJECTS)
- ${CXX} ${LDFLAGS} $(INCLUDES) $(CFLAGS) $(OBJECTS) -o $(GAME) $(LIB)
-
-debug: $(OBJECTS)
- ${CXX} ${LDFLAGS} $(INCLUDES) $(CFLAGS) $(OBJECTS) -o $(GAME) $(LIB)
-
-profile: $(OBJECTS)
- ${CXX} -g -p ${LDFLAGS} $(INCLUDES) $(CFLAGS) $(OBJECTS) -o $(GAME) $(LIB)
-
-.cc.o:
- ${CXX} ${CFLAGS} $(INCLUDES) -c $< ${INCLUDE}
-
-.h.cc:
- touch $@
-
diff --git a/stone_soup/crawl-ref/source/makefile.sgi b/stone_soup/crawl-ref/source/makefile.sgi
deleted file mode 100644
index 67815feaae..0000000000
--- a/stone_soup/crawl-ref/source/makefile.sgi
+++ /dev/null
@@ -1,54 +0,0 @@
-# Make file for Dungeon Crawl (irix)
-
-APPNAME = crawl
-
-# this file contains a list of the libraries.
-# it will make a variable called OBJECTS that contains all the libraries
-include makefile.obj
-
-CXX = CC
-DELETE = rm -f
-COPY = cp
-OS_TYPE = LINUX
-CFLAGS = -Wall -D$(OS_TYPE) $(EXTRA_FLAGS)
-LDFLAGS = -L/usr/lib
-MCHMOD = 711
-INSTALLDIR = /usr/games
-LIB = -lncurses
-
-# Include for Linux
-INCLUDES = -I/usr/include/ncurses
-
-all: $(APPNAME)
-
-%.o: %.cc
- @echo hello
- @${CXX} ${CFLAGS} -c $< ${INCLUDE}
-
-install: $(APPNAME)
- $(COPY) $(APPNAME) ${INSTALLDIR}
- chmod ${MCHMOD} ${INSTALLDIR}/$(APPNAME)
-
-clean:
- $(DELETE) *.o
-
-distclean:
- $(DELETE) *.o
- $(DELETE) bones.*
- $(DELETE) morgue.txt
- $(DELETE) scores
- $(DELETE) $(APPNAME)
-
-$(APPNAME): $(OBJECTS)
- ${CXX} ${LDFLAGS} $(INCLUDES) $(CFLAGS) $(OBJECTS) -o $(APPNAME) $(LIB)
- strip $(APPNAME)
- chmod ${MCHMOD} $(APPNAME)
-
-debug: $(OBJECTS)
- ${CXX} ${LDFLAGS} $(INCLUDES) $(CFLAGS) $(OBJECTS) -o $(APPNAME) $(LIB)
-
-profile: $(OBJECTS)
- ${CXX} -g -p ${LDFLAGS} $(INCLUDES) $(CFLAGS) $(OBJECTS) -o $(APPNAME) $(LIB)
-
-.h.cc:
- touch $@
diff --git a/stone_soup/crawl-ref/source/makefile.sol b/stone_soup/crawl-ref/source/makefile.sol
deleted file mode 100644
index e79d7e3a53..0000000000
--- a/stone_soup/crawl-ref/source/makefile.sol
+++ /dev/null
@@ -1,68 +0,0 @@
-# Make file for Dungeon Crawl (solaris)
-
-#
-# Modified for Crawl Reference by $Author$ on $Date$
-#
-
-APPNAME = crawl
-
-# this file contains a list of the libraries.
-# it will make a variable called OBJECTS that contains all the libraries
-include makefile.obj
-
-OBJECTS += libunix.o
-
-CXX = g++
-DELETE = rm -f
-COPY = cp
-GROUP = games
-MOVE = mv
-OS_TYPE = SOLARIS
-
-CFLAGS = -Wall -Wwrite-strings -Wstrict-prototypes \
- -Wmissing-prototypes -Wmissing-declarations \
- -g -D$(OS_TYPE) $(EXTRA_FLAGS)
-
-LDFLAGS = -static
-MCHMOD = 2755
-INSTALLDIR = /opt/local/newcrawl/bin
-LIB = -lcurses
-
-all: $(APPNAME)
-
-install: $(APPNAME)
- #strip $(APPNAME)
- $(MOVE) ${INSTALLDIR}/${APPNAME} ${INSTALLDIR}/${APPNAME}.old
- $(COPY) $(APPNAME) ${INSTALLDIR}
- chgrp ${GROUP} ${INSTALLDIR}/${APPNAME}
- chmod ${MCHMOD} ${INSTALLDIR}/$(APPNAME)
-
-clean:
- $(DELETE) *.o
-
-distclean:
- $(DELETE) *.o
- $(DELETE) bones.*
- $(DELETE) morgue.txt
- $(DELETE) scores
- $(DELETE) $(APPNAME)
- $(DELETE) *.sav
- $(DELETE) core
- $(DELETE) *.0*
- $(DELETE) *.lab
-
-
-$(APPNAME): $(OBJECTS)
- ${CXX} ${LDFLAGS} $(INCLUDES) $(CFLAGS) $(OBJECTS) -o $(APPNAME) $(LIB)
-
-debug: $(OBJECTS)
- ${CXX} ${LDFLAGS} $(INCLUDES) $(CFLAGS) $(OBJECTS) -o $(APPNAME) $(LIB)
-
-profile: $(OBJECTS)
- ${CXX} -g -p ${LDFLAGS} $(INCLUDES) $(CFLAGS) $(OBJECTS) -o $(APPNAME) $(LIB)
-
-.cc.o:
- ${CXX} ${CFLAGS} -c $< ${INCLUDE}
-
-.h.cc:
- touch $@
diff --git a/stone_soup/crawl-ref/source/maps.cc b/stone_soup/crawl-ref/source/maps.cc
deleted file mode 100644
index 3e99b298e1..0000000000
--- a/stone_soup/crawl-ref/source/maps.cc
+++ /dev/null
@@ -1,3641 +0,0 @@
-/*
- * File: maps.cc
- * Summary: Functions used to create vaults.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <2> 5/20/99 BWR Added stone lining to Zot vault,
- * this should prevent digging?
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "maps.h"
-
-#include <string.h>
-#include <stdlib.h>
-
-#include "enum.h"
-#include "monplace.h"
-#include "stuff.h"
-
-
-static char vault_1(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char vault_2(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char vault_3(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char vault_4(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char vault_5(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char vault_6(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char vault_7(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char vault_8(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char vault_9(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char vault_10(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-
-
-static char antaeus(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char asmodeus(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char beehive(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char box_level(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char castle_dis(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char elf_hall(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char ereshkigal(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char farm_and_country(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char fort_yaktaur(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char hall_of_Zot(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char hall_of_blades(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char gloorx_vloq(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-//static char mollusc(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char my_map(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char mnoleg(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char cerebov(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char orc_temple(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char lom_lobon(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char slime_pit(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char snake_pit(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char swamp(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char temple(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char tomb_1(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char tomb_2(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char tomb_3(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char vaults_vault(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char vestibule_map(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-
-
-static char minivault_1(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_2(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_3(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_4(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_5(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_6(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_7(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_8(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_9(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_10(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_11(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_12(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_13(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_14(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_15(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_16(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_17(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_18(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_19(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_20(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_21(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_22(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_23(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_24(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_25(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_26(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_27(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_28(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_29(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_30(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_31(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_32(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_33(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-
-//jmf: originals and slim wrappers to fit into don's non-switch
-static char minivault_34(char vgrid[81][81], FixedVector<int, 7>& mons_array, bool orientation);
-static char minivault_35(char vgrid[81][81], FixedVector<int, 7>& mons_array, bool orientation);
-static char minivault_34_a(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_34_b(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_35_a(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char minivault_35_b(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-
-static char rand_demon_1(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char rand_demon_2(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char rand_demon_3(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char rand_demon_4(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char rand_demon_5(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char rand_demon_6(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char rand_demon_7(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char rand_demon_8(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-static char rand_demon_9(char vgrid[81][81], FixedVector<int, 7>& mons_array);
-
-
-
-
-/* ******************** BEGIN PUBLIC FUNCTIONS ******************* */
-
-
-// remember (!!!) - if a member of the monster array isn't specified
-// within a vault subroutine, assume that it holds a random monster
-// -- only in cases of explicit monsters assignment have I listed
-// out random monster insertion {dlb}
-
-// make sure that vault_n, where n is a number, is a vault which can be put
-// anywhere, while other vault names are for specific level ranges, etc.
-char vault_main( char vgrid[81][81], FixedVector<int, 7>& mons_array, int vault_force, int many_many )
-{
-
- int which_vault = 0;
- unsigned char vx, vy;
- char (*fnc_vault) (char[81][81], FixedVector<int, 7>&) = 0;
-
-// first, fill in entirely with walls and null-terminate {dlb}:
- for (vx = 0; vx < 80; vx++)
- {
- for (vy = 0; vy < 80; vy++)
- vgrid[vx][vy] = 'x';
-
- vgrid[80][vx] = '\0';
- vgrid[vx][80] = '\0';
- }
-
- // next, select an appropriate vault to place {dlb}:
- for (;;)
- {
- which_vault = ( (vault_force == 100) ? random2(14) : vault_force );
-
- // endless loops result if forced vault cannot pass these tests {dlb}:
- if ( which_vault == 9 )
- {
- // if ( many_many > 23 || many_many > 12 )
- if (many_many > 12)
- break;
- }
- else if (which_vault == 11 || which_vault == 12)
- {
- if (many_many > 20)
- break;
- }
- else
- break;
- }
-
- // then, determine which drawing routine to use {dlb}:
- fnc_vault = ( (which_vault == 0) ? vault_1 :
- (which_vault == 1) ? vault_2 :
- (which_vault == 2) ? vault_3 :
- (which_vault == 3) ? vault_4 :
- (which_vault == 4) ? vault_5 :
- (which_vault == 5) ? vault_6 :
- (which_vault == 6) ? vault_7 :
- (which_vault == 7) ? vault_8 :
- (which_vault == 8) ? vault_9 :
- (which_vault == 9) ? ( (many_many > 23) ? my_map : orc_temple ) :
- (which_vault == 10) ? vault_10 :
- (which_vault == 11) ? farm_and_country :
- (which_vault == 12) ? fort_yaktaur :
- (which_vault == 13) ? box_level :
-
- // the hell vaults:
- (which_vault == 50) ? vestibule_map :
- (which_vault == 51) ? castle_dis :
- (which_vault == 52) ? asmodeus :
- (which_vault == 53) ? antaeus :
- (which_vault == 54) ? ereshkigal :
-
- // the pandemonium big demonlord vaults:
- (which_vault == 60) ? mnoleg : // was nemelex
- (which_vault == 61) ? lom_lobon : // was sif muna
- (which_vault == 62) ? cerebov : // was okawaru
- (which_vault == 63) ? gloorx_vloq : // was kikubaaqudgha
-
- //(which_vault == 64) ? mollusc :
- (which_vault == 80) ? beehive :
- (which_vault == 81) ? slime_pit :
- (which_vault == 82) ? vaults_vault :
- (which_vault == 83) ? hall_of_blades :
- (which_vault == 84) ? hall_of_Zot :
- (which_vault == 85) ? temple :
- (which_vault == 86) ? snake_pit :
- (which_vault == 87) ? elf_hall :
- (which_vault == 88) ? tomb_1 :
- (which_vault == 89) ? tomb_2 :
- (which_vault == 90) ? tomb_3 :
- (which_vault == 91) ? swamp :
- (which_vault == 200) ? minivault_1 :
- (which_vault == 201) ? minivault_2 :
- (which_vault == 202) ? minivault_3 :
- (which_vault == 203) ? minivault_4 :
- (which_vault == 204) ? minivault_5 :
- (which_vault == 205) ? ( (many_many > 15) ? minivault_6 : minivault_1 ) :
- (which_vault == 206) ? ( (many_many > 10) ? minivault_7 : minivault_2 ) :
- (which_vault == 207) ? ( (many_many > 15) ? minivault_8 : minivault_3 ) :
- (which_vault == 208) ? ( (many_many > 15) ? minivault_9 : minivault_4 ) :
- (which_vault == 209) ? minivault_10 :
- (which_vault == 210) ? minivault_11 :
- (which_vault == 211) ? minivault_12 :
- (which_vault == 212) ? minivault_13 :
- (which_vault == 213) ? minivault_14 :
- (which_vault == 214) ? minivault_15 :
- (which_vault == 215) ? minivault_16 :
- (which_vault == 216) ? minivault_17 :
- (which_vault == 217) ? minivault_18 :
- (which_vault == 218) ? minivault_19 :
- (which_vault == 219) ? minivault_20 :
- (which_vault == 220) ? minivault_21 :
- (which_vault == 221) ? minivault_22 :
- (which_vault == 222) ? minivault_23 :
- (which_vault == 223) ? minivault_24 :
- (which_vault == 224) ? minivault_25 :
- (which_vault == 225) ? minivault_26 :
- (which_vault == 226) ? minivault_27 :
- (which_vault == 227) ? minivault_28 :
- (which_vault == 228) ? minivault_29 :
- (which_vault == 229) ? minivault_30 :
- (which_vault == 230) ? minivault_31 :
- (which_vault == 231) ? minivault_32 :
- (which_vault == 232) ? minivault_33 :
- (which_vault == 233) ? minivault_34_a :
- (which_vault == 234) ? minivault_34_b :
- (which_vault == 235) ? minivault_35_a :
- (which_vault == 236) ? minivault_35_b :
- (which_vault == 300) ? rand_demon_1 :
- (which_vault == 301) ? rand_demon_2 :
- (which_vault == 302) ? rand_demon_3 :
- (which_vault == 303) ? rand_demon_4 :
- (which_vault == 304) ? rand_demon_5 :
- (which_vault == 305) ? rand_demon_6 :
- (which_vault == 306) ? rand_demon_7 :
- (which_vault == 307) ? rand_demon_8 :
- (which_vault == 308) ? rand_demon_9
- : 0 ); // yep, NULL -- original behaviour {dlb}
-
- // NB - a return value of zero is not handled well by dungeon.cc (but there it is) 10mar2000 {dlb}
- return ( (fnc_vault == 0) ? 0 : fnc_vault(vgrid, mons_array) );
-} // end vault_main()
-
-/* ********************* END PUBLIC FUNCTIONS ******************** */
-
-/*
- key:
- x - DNGN_ROCK_WALL
- X - DNGN_PERMAROCK_WALL -> should always be undiggable! -- bwr
- c - DNGN_STONE_WALL
- v - DNGN_METAL_WALL
- b - DNGN_GREEN_CRYSTAL_WALL
- a - DNGN_WAX_WALL
- . - DNGN_FLOOR
- + - DNGN_CLOSED_DOOR
- = - DNGN_SECRET_DOOR
- @ - entry point - must be on outside and on a particular side - see templates
- w - water
- l - lava
- >< - extra stairs - you can leave level by these but will never be placed on them from another level
- }{ - stairs 82/86 - You must be able to reach these from each other
- )( - stairs 83/87
- ][ - stairs 84/88
- I - orcish idol (does nothing)
- ^ - random trap
-
- A - Vestibule gateway (opened by Horn). Can also be put on other levels for colour, where it won't do anything.
- B - Altar. These are assigned specific types (eg of Zin etc) in dungeon.cc, in order.
- C - Random Altar.
- F - Typically a Granite Statue, but may be Orange or Silver (1 in 100)
- G - Granite statue (does nothing)
- H - orange crystal statue (attacks mind)
- S - Silver statue (summons demons). Avoid using (rare).
- T - Water fountain
- U - Magic fountain
- V - Permenantly dry fountain
-
- Statues can't be walked over and are only destroyed by disintegration
-
- $ - gold
- % - normal item
- * - higher level item (good)
- | - acquirement-level item (almost guaranteed excellent)
- O - place an appropriate rune here
- P - maybe place a rune here (50%)
- R - honeycomb (2/3) or royal jelly (1/3)
- Z - the Orb of Zot
-
- 0 - normal monster
- 9 - +5 depth monster
- 8 - (+2) * 2 depth monster (aargh!). Can get golden dragons and titans this way.
- 1-7 - monster array monster
- used to allocate specific monsters for a vault.
- is filled with RANDOM_MONSTER if monster not specified
-
- note that a lot of the vaults are in there mainly to add some interest to the
- scenery, and are not the lethal treasure-fests you find in Angband
- (not that there's anything wrong with that)
-
- Guidelines for creating new vault maps:
-
- Basically you can just let your creativity run wild. You do not have
- to place all of the stairs unless the level is full screen, in which
- case you must place all except the extra stairs (> and <). The <> stairs
- can be put anywhere and in any quantities but do not have to be there. Any
- of the other stairs which are not present in the vault will be randomly
- placed outside it. Also generally try to avoid rooms with no exit.
-
- You can use the templates below to build vaults, and remember to return the
- same number (this number is used in builder2.cc to determine where on the map
- the vault is located). The entry point '@' must be present (except
- full-screen vaults where it must not) and be on the same side of the vault
- as it is on the template, but can be anywhere along that side.
-
- You'll have to tell me the level range in which you want the vault to appear,
- so that I can code it into the vault management function. Unless you've
- placed specific monster types this will probably be unnecessary.
-
- I think that's all. Have fun!
-
- ps - remember to add one to the monster array value when placing monsters
- on each map (it is 1-7, not 0-6) {dlb}
- */
-
-static char vault_1(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // my first vault
- strcpy(vgrid[0], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[1], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[2], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[3], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[4], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[5], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[6], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[7], "xxxxxxxxxxxx....x........x........x.................................xxxxxxxxxxxx");
- strcpy(vgrid[8], "xxxxxxxxxx|=8...x........+........x......x....x1...x2...x2...x3...x...xxxxxxxxxx");
- strcpy(vgrid[9], "xxxxxxxxxx|x....x........x........x....................................xxxxxxxxx");
- strcpy(vgrid[10], "xxxxxxxxxxxxxxxx+xxx+xxxxxxxxxxxxxx..................................xxxxxxxxxxx");
- strcpy(vgrid[11], "xxxxxxxxx.......x.................+...................................8xxxxxxxxx");
- strcpy(vgrid[12], "xxxxxxxxx.......x.................x..................................xxxxxxxxxxx");
- strcpy(vgrid[13], "xxxxxxxxx.......+........3........xx+xx................................xxxxxxxxx");
- strcpy(vgrid[14], "xxxxxxxxx.......x.................x...x..x....x1...x2...x2...x3...x...xxxxxxxxxx");
- strcpy(vgrid[15], "xxxxxxxxx.......x.................x...x.............................xxxxxxxxxxxx");
- strcpy(vgrid[16], "xxxxxxxxxx+xxxxxxxxxxxxxxxxxxxxxxxx...xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[17], "xxxxxxxxx.........................x.S.x...xxxxxx..................|||||xxxxxxxxx");
- strcpy(vgrid[18], "xxxxxxxxx....xxxxxxxxxxxxxxxxxx...x...x......xxxxxx..................||xxxxxxxxx");
- strcpy(vgrid[19], "xxxxxxxxx....x...$$$$x****.999x...x...x.........xxxxxx.................xxxxxxxxx");
- strcpy(vgrid[20], "xxxxxxxxx....+...$$$$x****....x...x...+............xxxxxx.........8....xxxxxxxxx");
- strcpy(vgrid[21], "xxxxxxxxx....x...$$$$x****....+...x...x...............xxxxxx...........xxxxxxxxx");
- strcpy(vgrid[22], "xxxxxxxxx....x...$$$$x****....x...x999x..................xxxxxx........xxxxxxxxx");
- strcpy(vgrid[23], "xxxxxxxxx....xxxxxxxxxxxxxxxxxx...x...xxx...................xxxxxx.....xxxxxxxxx");
- strcpy(vgrid[24], "xxxxxxxxx.........................x...xxxxxx...................xxxxxx..xxxxxxxxx");
- strcpy(vgrid[25], "xxxxxxxxxxxxx+xxxxxxxx+xxxxxxx+xxxx...xxxxxx+xxxxxxxx+xxxxxxxx+xxxxxxx=xxxxxxxxx");
- strcpy(vgrid[26], "xxxxxxxxx.........x.......x.......x...x.........x........x.............xxxxxxxxx");
- strcpy(vgrid[27], "xxxxxxxxx.........x.......x.......x...x.........x........x.............xxxxxxxxx");
- strcpy(vgrid[28], "xxxxxxxxx.........x.......x.......x...x.........x........x.............xxxxxxxxx");
- strcpy(vgrid[29], "xxxxxxxxx....1....x...2...x...3...x...x....3....x....2...x......1......xxxxxxxxx");
- strcpy(vgrid[30], "xxxxxxxxx.........x.......x.......x...x.........x........x.............xxxxxxxxx");
- strcpy(vgrid[31], "xxxxxxxxx.........x.......x.......x...x.........x........x.............xxxxxxxxx");
- strcpy(vgrid[32], "xxxxxxxxx.........x.......x.......x...x.........x........x.............xxxxxxxxx");
- strcpy(vgrid[33], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[34], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[35], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- mons_array[0] = MONS_SHAPESHIFTER;
- mons_array[1] = MONS_SHAPESHIFTER;
- mons_array[2] = MONS_GLOWING_SHAPESHIFTER;
-
- return MAP_NORTH;
-}
-
-
-static char vault_2(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // cell vault
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[1], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[2], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[3], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[4], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[5], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[6], "xxxxxxxxcccccccccccccccccccccccccccccccc");
- strcpy(vgrid[7], "xxxxxxxxccw......^......w......^......wc");
- strcpy(vgrid[8], "xxxxxxxxcc.ccccccccccccc.ccccccccccccc.c");
- strcpy(vgrid[9], "xxxxxxxxcc.c....c.c....c.c....c.c....c.c");
- strcpy(vgrid[10], "xxxxxxxxcc.c.8..+.c....c.c....+.c..9.c.c");
- strcpy(vgrid[11], "xxxxxxxxcc.c....c.+..9.c.c.9..c.+....c.c");
- strcpy(vgrid[12], "xxxxxxxxcc.c....c.c....c.c....c.c....c.c");
- strcpy(vgrid[13], "xxxxxxxxcc.cccccc.cccccc.cccccc.cccccc.c");
- strcpy(vgrid[14], "xxxxxxxxcc^c....c.c....c.c....c.c....c.c");
- strcpy(vgrid[15], "xxxxxxxxcc.c....c.c....c.c....+.c....c.c");
- strcpy(vgrid[16], "xxxxxxxxcc.c8...+.+..8.c.c.8..c.+....c.c");
- strcpy(vgrid[17], "xxxxxxxxcc.c....c.c....c.c....c.c....c.c");
- strcpy(vgrid[18], "xxxxxxxxcc.cccccc.cccccc.cccccc.cccccc.c");
- strcpy(vgrid[19], "xxxxxxxxcc.c....c.c....c.c....c.c....c.c");
- strcpy(vgrid[20], "xxxxxxxxcc.c....+.c....c.c.0..c.c....c.c");
- strcpy(vgrid[21], "xxxxxxxxcc.c..9.c.+.8..c^c....+.+.0..c.c");
- strcpy(vgrid[22], "xxxxxxxxcc.c....c.c....c.c....c.c....c.c");
- strcpy(vgrid[23], "xxxxxxxxcc.cccccc.cccccc.cccccc.cccccc.c");
- strcpy(vgrid[24], "xxxxxxxxcc.c....c.c....c.c....c.c....c.c");
- strcpy(vgrid[25], "xxxxxxxxcc.c.0..+.+.0..c.c....+.+....c.c");
- strcpy(vgrid[26], "xxxxxxxxcc.c....c.c....c.c.0..c.c.8..c.c");
- strcpy(vgrid[27], "xxxxxxxxcc.cccccc.c....c.c....c.cccccc.c");
- strcpy(vgrid[28], "xxxxxxxxcc.c....c.cccccc.cccccc.c....c^c");
- strcpy(vgrid[29], "xxxxxxxxcc.c....c.c....c.c..9.+.+....c.c");
- strcpy(vgrid[30], "xxxxxxxxcc.c.0..+.+....c.c9...c.c.0..c.c");
- strcpy(vgrid[31], "xxxxxxxxcc.c....c.c.8..c.c....c.c....c.c");
- strcpy(vgrid[32], "xxxxxxxxcc.cccccc^cccccc.cccccc^cccccc.c");
- strcpy(vgrid[33], "xxxxxxxxccw.......Twwwwc.cwwwwT.......wc");
- strcpy(vgrid[34], "xxxxxxxxcccccccccccccccc.ccccccccccccccc");
- strcpy(vgrid[35], "xxxxxxxxxxxxxxxxxxxxxxxc@cxxxxxxxxxxxxxx");
-
- return MAP_NORTHWEST;
-}
-
-
-static char vault_3(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // little maze vault
- UNUSED( mons_array );
-
- for (unsigned char i = 0; i < 81; i++)
- strcpy(vgrid[i], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- strcat(vgrid[0], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[1], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[2], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[3], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[4], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[5], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[6], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[7], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[8], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[9], "x900x..............x..........xxxxxxxxxx");
- strcat(vgrid[10], "x999x.xxxxxxxxxxxx.x.xxxxxxxx.xxxxxxxxxx");
- strcat(vgrid[11], "x000x.x............x.x......x.xxxxxxxxxx");
- strcat(vgrid[12], "xx.xx.xxxxxxxxxxxxxx.x.xxxx.x.xxxxxxxxxx");
- strcat(vgrid[13], "xx.x..............xx.x.88|x.x.xxxxxxxxxx");
- strcat(vgrid[14], "xx.x.x.xxxxxxxxxx.xx.xxxxxx.x.xxxxxxxxxx");
- strcat(vgrid[15], "xx.x.x.x........x...........x.xxxxxxxxxx");
- strcat(vgrid[16], "xx.x.x.x.xxxxxx.xxxxxxxxxxxxx.xxxxxxxxxx");
- strcat(vgrid[17], "xx.xxx.x.x$$$$x...............xxxxxxxxxx");
- strcat(vgrid[18], "xx.....x.x$$$$x.xxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[19], "xxxxxxxx.x$$$$x...............xxxxxxxxxx");
- strcat(vgrid[20], "x........x$$$$x.xxxxxxxxxxxxx.xxxxxxxxxx");
- strcat(vgrid[21], "x.xxxxxx.xxxx.x.............x.xxxxxxxxxx");
- strcat(vgrid[22], "x.xxxxxx.xxxx.xxxxxxxxxxxxx.x.xxxxxxxxxx");
- strcat(vgrid[23], "x.x.......xxx.x...........x.x.xxxxxxxxxx");
- strcat(vgrid[24], "x.x.xxxxx.....x.x.xxxxx...x.x.xxxxxxxxxx");
- strcat(vgrid[25], "x.x.x999xxxxxxx.x.x***x...x.x.xxxxxxxxxx");
- strcat(vgrid[26], "x.x.x889........x.x|||xxxxx.x.xxxxxxxxxx");
- strcat(vgrid[27], "x.x.x899x.xxxxx.x.x***xxxxx.x.xxxxxxxxxx");
- strcat(vgrid[28], "x.x.xxxxx.xxxxx.x.xx.xxxxxx.x.xxxxxxxxxx");
- strcat(vgrid[29], "x.x..........xx.x.xx........x.xxxxxxxxxx");
- strcat(vgrid[30], "x.xxxxxxx.xx.xx.x.xxxxx.xxxxx.xxxxxxxxxx");
- strcat(vgrid[31], "x.xxx000x.xx.xx.x.x$$$x.xxxxx.xxxxxxxxxx");
- strcat(vgrid[32], "x|||x000x.x$$$x.x.x$$$x%%x%%%.xxxxxxxxxx");
- strcat(vgrid[33], "x|||x000..x$8$x.x.x$$$x%%x%8%xxxxxxxxxxx");
- strcat(vgrid[34], "x|||xxxxxxx$$$x.x..$$$xxxx%%%xxxxxxxxxxx");
- strcat(vgrid[35], "xxxxxxxxxxxxxxx@xxxxxxxxxxxxxxxxxxxxxxxx");
-
- return MAP_NORTHEAST;
-}
-
-
-static char vault_4(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // thingy vault
- UNUSED( mons_array );
-
- for (unsigned char i = 0; i < 81; i++)
- strcpy(vgrid[i], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- strcpy(vgrid[36], "xxxxxxxxxxxxxxxxxxxxxxxxx@xxxxxxxxxxxxxx");
- strcpy(vgrid[37], "xxxxxxxxxxxxxxxxxxxxxxxxx^xxxxxxxxxxxxxx");
- strcpy(vgrid[38], "xxxxxxxxxxxxxxxxxxxxxxxx...xxxxxxxxxxxxx");
- strcpy(vgrid[39], "xxxxxxxxxxxxxxxxxxxxxxx.....xxxxxxxxxxxx");
- strcpy(vgrid[40], "xxxxxxxxxxxxxxxxxxxxxxxx...xxxxxxxxxxxxx");
- strcpy(vgrid[41], "xxxxxxxxxxxxxxxxxxxxxxxx...xxxxxxxxxxxxx");
- strcpy(vgrid[42], "xxxxxxxxxxxxxxxxxxxxxxx.....xxxxxxxxxxxx");
- strcpy(vgrid[43], "xxxxxxxxxxxxxxxxxxxxx.........xxxxxxxxxx");
- strcpy(vgrid[44], "xxxxxxxxxxxxxxxxx......0...0......xxxxxx");
- strcpy(vgrid[45], "xxxxxxxxxxxxxx.......................xxx");
- strcpy(vgrid[46], "xxxxxxxxxxxxxx.........0...0.........xxx");
- strcpy(vgrid[47], "xxxxxxxxxxxxx8......0.........0......8xx");
- strcpy(vgrid[48], "xxxxxxxxxxxxxx.........0...0.........xxx");
- strcpy(vgrid[49], "xxxxxxxxxxxxxx.......................xxx");
- strcpy(vgrid[50], "xxxxxxxxxxxxxxx........0...0........xxxx");
- strcpy(vgrid[51], "xxxxxxxxxxxxxxxxxxxx...........xxxxxxxxx");
- strcpy(vgrid[52], "xxxxxxxxxxxxxxxxxxxxxxxx...xxxxxxxxxxxxx");
- strcpy(vgrid[53], "xxxxxxxxxxxxxxxxxxxxxxxx...xxxxxxxxxxxxx");
- strcpy(vgrid[54], "xxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxx");
- strcpy(vgrid[55], "xxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxx");
- strcpy(vgrid[56], "xxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxx");
- strcpy(vgrid[57], "xxxxxxxxxxxxxxxxxxxxxxx.....xxxxxxxxxxxx");
- strcpy(vgrid[58], "xxxxxxxxxxxxxxxxxx...............xxxxxxx");
- strcpy(vgrid[59], "xxxxxxxxxxxxxxxx8.................8xxxxx");
- strcpy(vgrid[60], "xxxxxxxxxxxxxxxxxxx.............xxxxxxxx");
- strcpy(vgrid[61], "xxxxxxxxxxxxxxxxxxxxxxxx999xxxxxxxxxxxxx");
- strcpy(vgrid[62], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[63], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[64], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[65], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[66], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[67], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[68], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[69], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- return MAP_SOUTHWEST;
-}
-
-static char vault_5(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // hourglass vault
- UNUSED( mons_array );
-
- for (unsigned char i = 0; i < 81; i++)
- strcpy(vgrid[i], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- strcat(vgrid[36], "xxxxxxxxxxxxxx@xxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[37], "xxxxxx.................xxxxxxxxxxxxxxxxx");
- strcat(vgrid[38], "xxxxx...................xxxxxxxxxxxxxxxx");
- strcat(vgrid[39], "xxxxx...................xxxxxxxxxxxxxxxx");
- strcat(vgrid[40], "xxxxxx.................xxxxxxxxxxxxxxxxx");
- strcat(vgrid[41], "xxxxxx.................xxxxxxxxxxxxxxxxx");
- strcat(vgrid[42], "xxxxxx.................xxxxxxxxxxxxxxxxx");
- strcat(vgrid[43], "xxxxxxx...............xxxxxxxxxxxxxxxxxx");
- strcat(vgrid[44], "xxxxxxx...............xxxxxxxxxxxxxxxxxx");
- strcat(vgrid[45], "xxxxxxxx.............xxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[46], "xxxxxxxxx.....8.....xxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[47], "xxxxxxxxxx...999...xxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[48], "xxxxxxxxxxxx00000xxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[49], "xxxxxxxxxxxxx===xxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[50], "xxxxxxxxxxxx.....xxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[51], "xxxxxxxxxx.........xxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[52], "xxxxxxxxx...........xxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[53], "xxxxxxxx......|......xxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[54], "xxxxxxx...............xxxxxxxxxxxxxxxxxx");
- strcat(vgrid[55], "xxxxxxx...............xxxxxxxxxxxxxxxxxx");
- strcat(vgrid[56], "xxxxxx........$........xxxxxxxxxxxxxxxxx");
- strcat(vgrid[57], "xxxxxx.......$$$.......xxxxxxxxxxxxxxxxx");
- strcat(vgrid[58], "xxxxxx....$$$$$$$$$....xxxxxxxxxxxxxxxxx");
- strcat(vgrid[59], "xxxxx$$$$$$$$$$$$$$$$$$$xxxxxxxxxxxxxxxx");
- strcat(vgrid[60], "xxxxx$$$$$$$$$$$$$$$$$$$xxxxxxxxxxxxxxxx");
- strcat(vgrid[61], "xxxxxx$$$$$$$$$$$$$$$$$xxxxxxxxxxxxxxxxx");
- strcat(vgrid[62], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[63], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[64], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[65], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[66], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[67], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[68], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[69], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- return MAP_SOUTHEAST;
-}
-
-
-static char vault_6(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // a more Angbandy vault
- UNUSED( mons_array );
-
- for (unsigned char i = 0; i < 81; i++)
- strcpy(vgrid[i], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- strcat(vgrid[0], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[1], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[2], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[3], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[4], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[5], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[6], "ccccccccccccccccccccccccccccccccxxxxxxxx");
- strcat(vgrid[7], "c*******cc..9...cc.+8c0c*c.c*c8cxxxxxxxx");
- strcat(vgrid[8], "c******cc..cc..cc..cc0c.c.c.c8ccxxxxxxxx");
- strcat(vgrid[9], "c*****cc..cc..cc..cc.c$c.c.c8c.cxxxxxxxx");
- strcat(vgrid[10], "c****cc9.cc..cc8.cc|c.c|c.c*c0ccxxxxxxxx");
- strcat(vgrid[11], "c***cc..cc..cc..cc.c.c.c.c.c.c$cxxxxxxxx");
- strcat(vgrid[12], "c**cc..cc8.cc..cc.c*c.c.c.c.c.ccxxxxxxxx");
- strcat(vgrid[13], "c+cc9.cc..cc..cc.c.c.c.c*c.c.c.cxxxxxxxx");
- strcat(vgrid[14], "c^c..cc..cc..cc.c$c.c.c.c.c.c*ccxxxxxxxx");
- strcat(vgrid[15], "c...cc..cc..cc.c.c.c9c$c.c.c.c9cxxxxxxxx");
- strcat(vgrid[16], "c..cc..cc..cc$c.c.c*c.c.c.c9c9ccxxxxxxxx");
- strcat(vgrid[17], "c.cc..cc..cc.c.c|c.c.c.c.c$c.c9cxxxxxxxx");
- strcat(vgrid[18], "ccc..cc..cc.c.c.c.c.c.c.c.c.cc+cxxxxxxxx");
- strcat(vgrid[19], "cc..cc..cc.c*c.c.c.c.c.c$c.cc..cxxxxxxxx");
- strcat(vgrid[20], "c0.cc..cc.c.c.c.c8c.c*c.c.cc0.ccxxxxxxxx");
- strcat(vgrid[21], "c.cc..cc*c.c.c.c.c$c.c.c.cc..cccxxxxxxxx");
- strcat(vgrid[22], "c^c..cc.c.c9c.c.c.c.c.c.cc..cc.cxxxxxxxx");
- strcat(vgrid[23], "c0..cc$c.c.c*c0c.c.c.c.cc..cc.0cxxxxxxxx");
- strcat(vgrid[24], "c..cc.c.c9c.c.c.c$c.c.cc.9cc...cxxxxxxxx");
- strcat(vgrid[25], "c.cc9c.c.c.c.c.c.c.c.cc..cc..c^cxxxxxxxx");
- strcat(vgrid[26], "ccc.c.c$c.c.c.c.c.c$cc..cc..cc^cxxxxxxxx");
- strcat(vgrid[27], "cc$c.c.c.c.c$c.c0c.cc..cc..cc..cxxxxxxxx");
- strcat(vgrid[28], "c.c.c.c.c.c.c.c.c.cc9.cc..cc..ccxxxxxxxx");
- strcat(vgrid[29], "cc.c8c.c.c$c.c.c.cc..cc..cc0.cccxxxxxxxx");
- strcat(vgrid[30], "c.c$c.c$c0c.c.c.cc..cc..cc..cc$cxxxxxxxx");
- strcat(vgrid[31], "cc.c.c.c.c.c*c.cc..cc..cc..cc$$cxxxxxxxx");
- strcat(vgrid[32], "c.c.c.c.c.c.c.cc..cc0.cc..cc$$$cxxxxxxxx");
- strcat(vgrid[33], "cc.c.c.c.c.c$cc..cc..cc..cc$$$$cxxxxxxxx");
- strcat(vgrid[34], "c.c.c.c.c.c.cc.8.^..cc....+$$$$cxxxxxxxx");
- strcat(vgrid[35], "cccc@cccccccccccccccccccccccccccxxxxxxxx");
-
- return MAP_NORTHEAST;
-}
-
-static char vault_7(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // four-leaf vault
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[1], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[2], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[3], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[4], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[5], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[6], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[7], "xxxxxxxxxxxxx.........^..^.........xxxxx");
- strcpy(vgrid[8], "xxxxxxxxxxxx...xxxxxxxx..xxxxxxxx...xxxx");
- strcpy(vgrid[9], "xxxxxxxxxxx...xxxxxxxxx..xxxxxxxxx...xxx");
- strcpy(vgrid[10], "xxxxxxxxxx...xx$*....xx..xx....$$xx...xx");
- strcpy(vgrid[11], "xxxxxxxxx...xx$*$....xx..xx....$*$xx...x");
- strcpy(vgrid[12], "xxxxxxxxx..xx*$*$....xx..xx....*$$$xx..x");
- strcpy(vgrid[13], "xxxxxxxxx..xx$$$.00..xx..xx..00.*$*xx..x");
- strcpy(vgrid[14], "xxxxxxxxx..xx....09..xx..xx..90....xx..x");
- strcpy(vgrid[15], "xxxxxxxxx..xx......+xx....xx+......xx..x");
- strcpy(vgrid[16], "xxxxxxxxx..xx......x^......^x......xx..x");
- strcpy(vgrid[17], "xxxxxxxxx..xxxxxxxxx........xxxxxxxxx..x");
- strcpy(vgrid[18], "xxxxxxxxx..xxxxxxxx..........xxxxxxxx..x");
- strcpy(vgrid[19], "xxxxxxxxx..............TT..............x");
- strcpy(vgrid[20], "xxxxxxxxx..............TT..............x");
- strcpy(vgrid[21], "xxxxxxxxx..xxxxxxxx..........xxxxxxxx..x");
- strcpy(vgrid[22], "xxxxxxxxx..xxxxxxxxx........xxxxxxxxx..x");
- strcpy(vgrid[23], "xxxxxxxxx..xx......x^......^x......xx..x");
- strcpy(vgrid[24], "xxxxxxxxx..xx......+xx....xx+......xx..x");
- strcpy(vgrid[25], "xxxxxxxxx..xx....09..xx..xx..90....xx..x");
- strcpy(vgrid[26], "xxxxxxxxx..xx$$*.00..xx..xx..00.*$$xx..x");
- strcpy(vgrid[27], "xxxxxxxxx..xx*$*$....xx..xx....*$$*xx..x");
- strcpy(vgrid[28], "xxxxxxxxx...xx*$*....xx..xx....$$$xx...x");
- strcpy(vgrid[29], "xxxxxxxxxx...xx*$....xx..xx....*$xx...xx");
- strcpy(vgrid[30], "xxxxxxxxxxx...xxxxxxxxx..xxxxxxxxx...xxx");
- strcpy(vgrid[31], "xxxxxxxxxxxx...xxxxxxxx..xxxxxxxx...xxxx");
- strcpy(vgrid[32], "xxxxxxxxxxxxx..^................^..xxxxx");
- strcpy(vgrid[33], "xxxxxxxxxxxxxxxxxxxxxxx^^xxxxxxxxxxxxxxx");
- strcpy(vgrid[34], "xxxxxxxxxxxxxxxxxxxxxxx++xxxxxxxxxxxxxxx");
- strcpy(vgrid[35], "xxxxxxxxxxxxxxxxxxxxxxx@xxxxxxxxxxxxxxxx");
-
- return MAP_NORTHWEST;
-}
-
-static char vault_8(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // cross vault
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[1], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[2], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[3], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[4], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[5], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[6], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[7], "xxxxxxxxxxxxxxxxxx............xxxxxxxxxx");
- strcpy(vgrid[8], "xxxxxxxxxxxxxxx..................xxxxxxx");
- strcpy(vgrid[9], "xxxxxxxxxxxxx......................xxxxx");
- strcpy(vgrid[10], "xxxxxxxxxxxx..........w..w..........xxxx");
- strcpy(vgrid[11], "xxxxxxxxxxx........wwww++wwww........xxx");
- strcpy(vgrid[12], "xxxxxxxxxxx......wwwvvv^^vvvwww......xxx");
- strcpy(vgrid[13], "xxxxxxxxxx......wwwwv.9..9.vwwww......xx");
- strcpy(vgrid[14], "xxxxxxxxxx.....wwwwwv......vwwwww.....xx");
- strcpy(vgrid[15], "xxxxxxxxxx....wwwwwvv......vvwwwww....xx");
- strcpy(vgrid[16], "xxxxxxxxx....wwwwwvv........vvwwwww....x");
- strcpy(vgrid[17], "xxxxxxxxx....wwvvvv....vv....vvvvww....x");
- strcpy(vgrid[18], "xxxxxxxxx...wwwv......vvvv......vwww...x");
- strcpy(vgrid[19], "xxxxxxxxx...wwwv....vv8vv8vv....vwww...x");
- strcpy(vgrid[20], "xxxxxxxxx..wwwwv...vvvv||vvvv...vwwww..x");
- strcpy(vgrid[21], "xxxxxxxxx^^wwwwv...vvvv||vvvv...vwwww^^x");
- strcpy(vgrid[22], "xxxxxxxxx..wwwwv....vv8vv8vv....vwwww..x");
- strcpy(vgrid[23], "xxxxxxxxx...wwwv......vvvv......vwww...x");
- strcpy(vgrid[24], "xxxxxxxxx...wwwvvvv....vv....vvvvwww...x");
- strcpy(vgrid[25], "xxxxxxxxx....wwwwwvv........vvwwwww....x");
- strcpy(vgrid[26], "xxxxxxxxxx...wwwwwwvv......vvwwwwww...xx");
- strcpy(vgrid[27], "xxxxxxxxxx....wwwwwwv......vwwwwww....xx");
- strcpy(vgrid[28], "xxxxxxxxxx.....wwwwwv......vwwwww.....xx");
- strcpy(vgrid[29], "xxxxxxxxxxx.....wwwwvvvvvvvvwwww.....xxx");
- strcpy(vgrid[30], "xxxxxxxxxxx.......wwwwwwwwwwww.......xxx");
- strcpy(vgrid[31], "xxxxxxxxxxxx.........wwwwww.........xxxx");
- strcpy(vgrid[32], "xxxxxxxxxxxxx.........^..^.........xxxxx");
- strcpy(vgrid[33], "xxxxxxxxxxxxxxx.......x++x.......xxxxxxx");
- strcpy(vgrid[34], "xxxxxxxxxxxxxxxxxx...xx..xx...xxxxxxxxxx");
- strcpy(vgrid[35], "xxxxxxxxxxxxxxxxxxxxxx..@.xxxxxxxxxxxxxx");
-
- return MAP_NORTHWEST;
-}
-
-
-static char vault_9(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // another thingy vault
- UNUSED( mons_array );
-
- for (unsigned char i = 0; i < 81; i++)
- strcpy(vgrid[i], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- strcat(vgrid[36], "xxxxxxxxxxxxxxx@xxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[37], "xxxxxxxxxxxxxxx^xxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[38], "xxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[39], "xx.....^...............^.....xxxxxxxxxxx");
- strcat(vgrid[40], "x..bb..xxxxxxxxxxxxxxxxx..bb..xxxxxxxxxx");
- strcat(vgrid[41], "x..b...xxxxxxxxxxxxxxxxx...b..xxxxxxxxxx");
- strcat(vgrid[42], "x...b..xxxxbbbbbbbbbxxxx..b...xxxxxxxxxx");
- strcat(vgrid[43], "x..bb..xxbbb.......bbbxx..bb..xxxxxxxxxx");
- strcat(vgrid[44], "x......xxb....9.9....bxx......xxxxxxxxxx");
- strcat(vgrid[45], "x..bb..xbb..%$$$$$%..bbx..bb..xxxxxxxxxx");
- strcat(vgrid[46], "x...b..xb..0%$***$%0..bx..b...xxxxxxxxxx");
- strcat(vgrid[47], "x..b...xb..0%$*H*$%0..bx...b..xxxxxxxxxx");
- strcat(vgrid[48], "x...b..xb..0%$***$%0..bx..b...xxxxxxxxxx");
- strcat(vgrid[49], "x..b...xb...%$$$$$%...bx...b..xxxxxxxxxx");
- strcat(vgrid[50], "x...b..xbb.900000009.bbx..b...xxxxxxxxxx");
- strcat(vgrid[51], "x..b...xxb...........bxx...b..xxxxxxxxxx");
- strcat(vgrid[52], "x..bb..xxbbb..9.9..bbbxx..bb..xxxxxxxxxx");
- strcat(vgrid[53], "x......xxxxbbbb.bbbbxxxx......xxxxxxxxxx");
- strcat(vgrid[54], "x..bb..xxxxxxxb=bxxxxxxx..bb..xxxxxxxxxx");
- strcat(vgrid[55], "x..b...xxxxxxxx=xxxxxxxx...b..xxxxxxxxxx");
- strcat(vgrid[56], "x...b..xxxxxxxx^xxxxxxxx..b...xxxxxxxxxx");
- strcat(vgrid[57], "x..b....xxxxxxx=xxxxxxx....b..xxxxxxxxxx");
- strcat(vgrid[58], "x...b...^.............^...b...xxxxxxxxxx");
- strcat(vgrid[59], "x..b....xxxxxxxxxxxxxxx....b..xxxxxxxxxx");
- strcat(vgrid[60], "x..bb..xxxxxxxxxxxxxxxxx..bb..xxxxxxxxxx");
- strcat(vgrid[61], "xx....xxxxxxxxxxxxxxxxxxx....xxxxxxxxxxx");
- strcat(vgrid[62], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[63], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[64], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[65], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[66], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[67], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[68], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[69], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- return MAP_SOUTHEAST;
-}
-
-
-static char vault_10(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // impenetrable vault
- UNUSED( mons_array );
-
- for (unsigned char i = 0; i < 81; i++)
- strcpy(vgrid[i], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- strcat(vgrid[36], "..............@................xxxxxxxxx");
- strcat(vgrid[37], "...............................xxxxxxxxx");
- strcat(vgrid[38], "...............................xxxxxxxxx");
- strcat(vgrid[39], "...............................xxxxxxxxx");
- strcat(vgrid[40], "...............................xxxxxxxxx");
- strcat(vgrid[41], ".....cccccccccccccccc..........xxxxxxxxx");
- strcat(vgrid[42], ".....c[^...........9cc.........xxxxxxxxx");
- strcat(vgrid[43], ".....c^xxxxx=xxxxxx..cc........xxxxxxxxx");
- strcat(vgrid[44], ".....c.x9..^^^...9xx..cc.......xxxxxxxxx");
- strcat(vgrid[45], ".....c.x.xxx=xxxx..xx..cc......xxxxxxxxx");
- strcat(vgrid[46], ".....c.x^x$$$$$$xx..xx.9c......xxxxxxxxx");
- strcat(vgrid[47], ".....c.=^=$*|||*$xx..xx.c......xxxxxxxxx");
- strcat(vgrid[48], ".....c.x^xx$*|||*$xx.9x.c......xxxxxxxxx");
- strcat(vgrid[49], ".....c.x9.xx$*|||*$xx^x.c......xxxxxxxxx");
- strcat(vgrid[50], ".....c.xx..xx$*|||*$=^=.c......xxxxxxxxx");
- strcat(vgrid[51], ".....c9.xx..xx$$$$$$x^x.c......xxxxxxxxx");
- strcat(vgrid[52], ".....cc..xx..xxxx=xxx.x.c......xxxxxxxxx");
- strcat(vgrid[53], "......cc..xx9...^^^..9x.c......xxxxxxxxx");
- strcat(vgrid[54], ".......cc..xxxxxx=xxxxx^c......xxxxxxxxx");
- strcat(vgrid[55], "........cc9...........^]c......xxxxxxxxx");
- strcat(vgrid[56], ".........cccccccccccccccc......xxxxxxxxx");
- strcat(vgrid[57], "...............................xxxxxxxxx");
- strcat(vgrid[58], "...............................xxxxxxxxx");
- strcat(vgrid[59], "...............................xxxxxxxxx");
- strcat(vgrid[60], "...............................xxxxxxxxx");
- strcat(vgrid[61], "...............................xxxxxxxxx");
- strcat(vgrid[62], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[63], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[64], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[65], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[66], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[67], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[68], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[69], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- return MAP_SOUTHEAST;
-}
-
-
-static char orc_temple(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
- for (unsigned char i = 0; i < 81; i++)
- strcpy(vgrid[i], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- strcpy(vgrid[36], "xxxxxxxxxxxxxxxxxxxxxxx@xxxxxxxxxxxxxxxx");
- strcpy(vgrid[37], "xxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxx");
- strcpy(vgrid[38], "xxxxxxxxxxxxxxxxxxxxxx...xxxxxxxxxxxxxxx");
- strcpy(vgrid[39], "xxxxxxxxxxxxxxxxxxxxxx4.4xxxxxxxxxxxxxxx");
- strcpy(vgrid[40], "xxxxxxxxx**..........x414x..........**xx");
- strcpy(vgrid[41], "xxxxxxxxx**..........x4.4x..........**xx");
- strcpy(vgrid[42], "xxxxxxxxx............+...+....4.......xx");
- strcpy(vgrid[43], "xxxxxxxxx....4..4....x...x............xx");
- strcpy(vgrid[44], "xxxxxxxxx............x...x.......4....xx");
- strcpy(vgrid[45], "xxxxxxxxx............xx.xx............xx");
- strcpy(vgrid[46], "xxxxxxxxx...4......xxxx+xxxx......6...xx");
- strcpy(vgrid[47], "xxxxxxxxx........xxx.......xxx........xx");
- strcpy(vgrid[48], "xxxxxxxxxxx...xxxx..2.....2..xxxx...xxxx");
- strcpy(vgrid[49], "xxxxxxxxxxxx+xxxx.............xxxx+xxxxx");
- strcpy(vgrid[50], "xxxxxxxxxxx...xxx.............xxx...xxxx");
- strcpy(vgrid[51], "xxxxxxxxx......x...............x......xx");
- strcpy(vgrid[52], "xxxxxxxxx..4...x...2...I...2...x...5..xx");
- strcpy(vgrid[53], "xxxxxxxxx......x...............x......xx");
- strcpy(vgrid[54], "xxxxxxxxx...4..xx.............xx..5...xx");
- strcpy(vgrid[55], "xxxxxxxxx$......x....2...2....x......$xx");
- strcpy(vgrid[56], "xxxxxxxxx$6..5..xx.....3.....xx.5...7$xx");
- strcpy(vgrid[57], "xxxxxxxxx$$$.....xxx.......xxx.....$$$xx");
- strcpy(vgrid[58], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[59], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[60], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[61], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[62], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[63], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[64], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[65], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[66], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[67], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[68], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[69], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- mons_array[0] = MONS_ORC_WARLORD;
- mons_array[1] = MONS_ORC_PRIEST;
- mons_array[2] = MONS_ORC_HIGH_PRIEST;
- mons_array[3] = MONS_ORC_WARRIOR;
- mons_array[4] = MONS_ORC_WIZARD;
- mons_array[5] = MONS_ORC_KNIGHT;
- mons_array[6] = MONS_ORC_SORCERER;
-
- return MAP_SOUTHWEST;
-}
-
-static char my_map(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // by Matthew Ludivico
-
- for (unsigned char i = 0; i < 81; i++)
- strcpy(vgrid[i], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- strcpy(vgrid[36], "xxxxxxxxxx.@.xxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[37], "xxxxxxxxxxx...xxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[38], "xxxxxxxxxxxx..........................xx");
- strcpy(vgrid[39], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx..xx");
- strcpy(vgrid[40], "xxxxxxxxx.^^..........................xx");
- strcpy(vgrid[41], "xxxxxxxxxx.^^xx+xxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[42], "xxxxxxxxxxx.^...11....xxxxxxxx..xxxxxxxx");
- strcpy(vgrid[43], "xxxxxxxxxxxx..x.1..6..xxx........xx..xxx");
- strcpy(vgrid[44], "xxxxxxxxxxxxx.xxxxxxxxx...vvvvv...x...xx");
- strcpy(vgrid[45], "xxxxxxxxx6..1...x.........+1..v.......xx");
- strcpy(vgrid[46], "xxxxxxxxx..1....x.........vvvvv........x");
- strcpy(vgrid[47], "xxxxxxxxx..5...xx......................x");
- strcpy(vgrid[48], "xxxxxxxxxxxxxx^++...........vvvvvvv....x");
- strcpy(vgrid[49], "xxxxxxxxxxxxxx^xx...xx=xx...vv$%$vvvvv.x");
- strcpy(vgrid[50], "xxxxxxxxxxxxxx^x...xxv1vxx...vvv*2...v.x");
- strcpy(vgrid[51], "xxxxxxxxxxxxxx^x..vvvv7.vvvv...vv.vv+v^x");
- strcpy(vgrid[52], "xxxxxxxxx..xxx^..vvvb....bvvv...vvv^...x");
- strcpy(vgrid[53], "xxxxxxxxx%%.xx..vvvvb....bvvvv.......xxx");
- strcpy(vgrid[54], "xxxxxxxxxx.....vvbbb......bbbvv.....xxxx");
- strcpy(vgrid[55], "xxxxxxxxxxx....vvb....66....bvvxxxxxxxxx");
- strcpy(vgrid[56], "xxxxxxxxxxxxxxvvvb..llllll..bvvvxxxxxxxx");
- strcpy(vgrid[57], "xxxxxxxxxvvvvvvvvb..ll45ll..bvvvvvvvvxxx");
- strcpy(vgrid[58], "xxxxxxxxxccc***+== .l3.2.l..cccccccccxxx");
- strcpy(vgrid[59], "xxxxxxxxxccc+cccbb....ll....c..$$$$+$*cx");
- strcpy(vgrid[60], "xxxxxxxxxcc|||cbb...3llll2...cc%*%*c$|cx");
- strcpy(vgrid[61], "xxxxxxxxxcccccccbbbbbbbbbbbccccccccccccx");
- strcpy(vgrid[62], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[63], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[64], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[65], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[66], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[67], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[68], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[69], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- mons_array[0] = MONS_HELL_HOUND;
- mons_array[1] = MONS_NECROMANCER;
- mons_array[2] = MONS_WIZARD;
- mons_array[3] = MONS_ORANGE_DEMON;
- mons_array[4] = MONS_ROTTING_DEVIL;
- mons_array[5] = MONS_HELL_KNIGHT;
- mons_array[6] = MONS_GREAT_ORB_OF_EYES;
-
- return MAP_SOUTHWEST;
-}
-
-static char farm_and_country(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // by Matthew Ludivico (mll6@lehigh.edu)
-
- for (unsigned char i = 0; i < 81; i++)
- strcpy(vgrid[i], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- strcpy(vgrid[0], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[1], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[2], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[3], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[4], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[5], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[6], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[7], "xxxxxxxxxxxxxxxxx..........................................xxxxxxxx}.xxxxxxxxxxx");
- strcpy(vgrid[8], "xxxxxxxxxxxxxxxxxxx............xxxxxx....xxx.......xx...........xxxx..]xxxxxxxxx");
- strcpy(vgrid[9], "xxxxxxxxxxxxxxx***x...........xxx..xxx............xxxx...........xx..xxxxxxxxxxx");
- strcpy(vgrid[10], "xxxxxxxxxxxxxxx|*$=...xx.xxxxxxx....xxxxxxxxxx......xx................xxxxxxxxxx");
- strcpy(vgrid[11], "xxxxxxxxxxxxxxxxxxx....xxxxxxxx......3..xxx.................x..........xxxxxxxxx");
- strcpy(vgrid[12], "xxxxxxxxxxxxxxxxxx......x........x......xx.........w...................xxxxxxxxx");
- strcpy(vgrid[13], "xxxxxxxxxxx)......xx...xxx.....xxx......x........www3....3.............xxxxxxxxx");
- strcpy(vgrid[14], "xxxxxxxxxxxx=xxxxxxxxxxx...xxxxxxxxx..xxx.....wwwww....%%%.............xxxxxxxxx");
- strcpy(vgrid[15], "xxxxxxxxxx......xxx.......xx.xxxx.x...xxxxxxxwwwwwww..5%%%..........xx.xxxxxxxxx");
- strcpy(vgrid[16], "xxxxxxxxx.........x..xxxxxxxx.....x........3wwwwwwwww..%%%........xxx..xxxxxxxxx");
- strcpy(vgrid[17], "xxxxxxxxx....5...xx..x.xxxxx.....xxx........wwwwwwwww..%%%..........xx.xxxxxxxxx");
- strcpy(vgrid[18], "xxxxxxxxxxx.....xxx..xx..xx........xxxxxxxxxwwwwwwwww..............xxx.xxxxxxxxx");
- strcpy(vgrid[19], "xxxxxxxxxx........x..x...............xx..xxxxwwwwwwwwwwwwww............xxxxxxxxx");
- strcpy(vgrid[20], "xxxxxxxxx.............................x.....xxwwwwww3wwwwww............xxxxxxxxx");
- strcpy(vgrid[21], "xxxxxxxxxxx...x...........5.....7...............ww.......ww.....44....xxxxxxxxxx");
- strcpy(vgrid[22], "xxxxxxxxxwxx..xx.....622...2.26...6.2...22.6...62..2..226ww.....44xx...xxxxxxxxx");
- strcpy(vgrid[23], "xxxxxxxxxwwxxxx......2....2.22....2..2...2.2.......22...2ww....xxxx..xxxxxxxxxxx");
- strcpy(vgrid[24], "xxxxxxxxxwwwwxxx......2...2.2.2...2.22..2.22...22.2.2..22ww.....xxx....xxxxxxxxx");
- strcpy(vgrid[25], "xxxxxxxxxwwwwwx....4..2...2...........22...277..2..2.2.22ww...........xxxxxxxxxx");
- strcpy(vgrid[26], "xxxxxxxxxwwwwwxx....42..2....22.4..2..2...2.4..2.22..22.2ww............xxxxxxxxx");
- strcpy(vgrid[27], "xxxxxxxxxwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww.wwwwwwwwwwwww..2.........xxxxxxxxx");
- strcpy(vgrid[28], "xxxxxxxxxwwwwwxx.....62....2.26...62.2.2..26...6...22..26..............xxxxxxxxx");
- strcpy(vgrid[29], "xxxxxxxxxwwwww.........................................................xxxxxxxxx");
- strcpy(vgrid[30], "xxxxxxxxxwwwwwxx....222.2.22..2.7.......7..............................xxxxxxxxx");
- strcpy(vgrid[31], "xxxxxxxxxwwwww...........ccccccc+ccccccc...ccc......cc+ccc...xxxxx.....xxxxxxxxx");
- strcpy(vgrid[32], "xxxxxxxxxwwwwwxx.........c$$*.c$$5$+.5.c...+5c......c%%%%c......xxx3...xxxxxxxxx");
- strcpy(vgrid[33], "xxxxxxxxxwwwwwx....2.....c$.c+cccccc.%.c...ccc......c%%%%c....xxxxx....xxxxxxxxx");
- strcpy(vgrid[34], "xxxxxxxxxwwwwwx..........c..c..........c............cccccc......xxx....xxxxxxxxx");
- strcpy(vgrid[35], "xxxxxxxxxwwxxxxxxx.......ccccc+ccccccccc.........................xx....xxxxxxxxx");
- strcpy(vgrid[36], "xxxxxxxxxwxx.....xxxx........c...c.................2...................xxxxxxxxx");
- strcpy(vgrid[37], "xxxxxxxxxxx.........xxxx...........2....xxxx...........................xxxxxxxxx");
- strcpy(vgrid[38], "xxxxxxxxx..............xxxx..........xxxx..x...........................xxxxxxxxx");
- strcpy(vgrid[39], "xxxxxxxxx.................xxxxx++xxxxx.....xx............xx...x........xxxxxxxxx");
- strcpy(vgrid[40], "xxxxxxxxx.....................c..c..........xxxxx..........xxxxx.......xxxxxxxxx");
- strcpy(vgrid[41], "xxxxxxxxx.......cccc..........c..c...cccc......xxx...........x.........xxxxxxxxx");
- strcpy(vgrid[42], "xxxxxxxxx.......c..c..........c++c...c..c........xxx.........x.........xxxxxxxxx");
- strcpy(vgrid[43], "xxxxxxxxx.......c..c..........c..c...c..c..........xxx.................xxxxxxxxx");
- strcpy(vgrid[44], "xxxxxxxxx....cccc++cccccccccccc++ccccc..ccccccc......xxx...............xxxxxxxxx");
- strcpy(vgrid[45], "xxxxxxxxx....c..........1.....................c........xxx.............xxxxxxxxx");
- strcpy(vgrid[46], "xxxxxxxxx.cccc.....w....w....%1.....w.....%...c..........xxx...........xxxxxxxxx");
- strcpy(vgrid[47], "xxxxxxxxx.c1.+....www..www..%%%....www...%%%1.c...........xxxxxxxxx....xxxxxxxxx");
- strcpy(vgrid[48], "xxxxxxxxx.cccc.....w....w....%......w.....%...c..................xxx...xxxxxxxxx");
- strcpy(vgrid[49], "xxxxxxxxx....c.......5........................c....................xxxxxxxxxxxxx");
- strcpy(vgrid[50], "xxxxxxxxx....ccc....%%%%%....cccccccccccccccccc........................xxxxxxxxx");
- strcpy(vgrid[51], "xxxxxxxxx......cc...........cc.........................................xxxxxxxxx");
- strcpy(vgrid[52], "xxxxxxxxx.......cccccc+cccccc..........................................xxxxxxxxx");
- strcpy(vgrid[53], "xxxxxxxxx........cc.......cc...........................................xxxxxxxxx");
- strcpy(vgrid[54], "xxxxxxxxx.........cc.....cc.....................cccccccccccccccccccccccxxxxxxxxx");
- strcpy(vgrid[55], "xxxxxxxxx..........ccc+ccc......................c......vvv.............xxxxxxxxx");
- strcpy(vgrid[56], "xxxxxxxxx..........ccc.c........................c......v5+...vvvvv.....xxxxxxxxx");
- strcpy(vgrid[57], "xxxxxxxxx..........ccc.c........................c......vvv...v.5.v.....xxxxxxxxx");
- strcpy(vgrid[58], "xxxxxxxxxccccccccccccc.ccc......................c............v..5v.....xxxxxxxxx");
- strcpy(vgrid[59], "xxxxxxxxx..........c.....cccccccccccccccccccccccccccc..........vv+vv...xxxxxxxxx");
- strcpy(vgrid[60], "xxxxxxxxx..........c............................+................5111..xxxxxxxxx");
- strcpy(vgrid[61], "xxxxxxxxx..........c.{([.c......................+................5.....xxxxxxxxx");
- strcpy(vgrid[62], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[63], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[64], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[65], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[66], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[67], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[68], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[69], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- mons_array[0] = MONS_DEATH_YAK;
- mons_array[1] = MONS_PLANT;
- mons_array[2] = MONS_GRIFFON;
- mons_array[3] = MONS_KILLER_BEE;
- mons_array[4] = MONS_OGRE;
- mons_array[5] = MONS_OKLOB_PLANT;
- mons_array[6] = MONS_WANDERING_MUSHROOM;
-
- return MAP_ENCOMPASS;
-}
-
-
-static char fort_yaktaur(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // by Matthew Ludivico (mll6@lehigh.edu)
-
- for (unsigned char i = 0; i < 81; i++)
- strcpy(vgrid[i], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- strcat(vgrid[36], ".........@....wwwwwwwwwwwwwwwwwxxxxxxxxx");
- strcat(vgrid[37], ".ccccc.......ww....wwww....wwwwxxxxxxxxx");
- strcat(vgrid[38], ".c$c%c......ww.ccccccccc.......xxxxxxxxx");
- strcat(vgrid[39], ".c+c+c......ww.c.%$....ccccccccxxxxxxxxx");
- strcat(vgrid[40], ".c...+......ww.c*.115..c$$+|*|cxxxxxxxxx");
- strcat(vgrid[41], ".c1..c.....ww..c...55+ccc+cxx=cxxxxxxxxx");
- strcat(vgrid[42], ".ccccc.....ww..ccccccc....c|=*cxxxxxxxxx");
- strcat(vgrid[43], "............ww.......c5...cxx=cxxxxxxxxx");
- strcat(vgrid[44], "....6.ccccc.ww.w...2.+51..c|1.cxxxxxxxxx"); // last 1 here was 7
- strcat(vgrid[45], "....63+...c..wwww..21+51..c2.2cxxxxxxxxx");
- strcat(vgrid[46], "....6.ccccc..wwwwww..c5...cc+ccxxxxxxxxx");
- strcat(vgrid[47], "............wwwwwww..c........cxxxxxxxxx");
- strcat(vgrid[48], "............wwwwwww..ccccccccccxxxxxxxxx");
- strcat(vgrid[49], "...........ww1w..www...........xxxxxxxxx");
- strcat(vgrid[50], ".......566.www.....www.........xxxxxxxxx");
- strcat(vgrid[51], ".........1ww....ccccc..........xxxxxxxxx");
- strcat(vgrid[52], ".....566.w......+...c..........xxxxxxxxx");
- strcat(vgrid[53], ".........www....ccccc..........xxxxxxxxx");
- strcat(vgrid[54], "...........ww............wwwwwwxxxxxxxxx");
- strcat(vgrid[55], ".......3....wwwww......www.....xxxxxxxxx");
- strcat(vgrid[56], "......666.......ww...www.......xxxxxxxxx");
- strcat(vgrid[57], ".....cc+cc.......wwwww.........xxxxxxxxx");
- strcat(vgrid[58], ".....c...c.....................xxxxxxxxx");
- strcat(vgrid[59], ".....ccccc.....................xxxxxxxxx");
- strcat(vgrid[60], "...............................xxxxxxxxx");
- strcat(vgrid[61], "...............................xxxxxxxxx");
- strcat(vgrid[62], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[63], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[64], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[65], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[66], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[67], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[68], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[69], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- mons_array[0] = MONS_YAKTAUR;
- mons_array[1] = MONS_DEATH_YAK;
- mons_array[2] = MONS_MINOTAUR;
- mons_array[3] = RANDOM_MONSTER;
- mons_array[4] = MONS_YAK;
- mons_array[5] = MONS_GNOLL;
- mons_array[6] = RANDOM_MONSTER;
-
- return MAP_SOUTHEAST;
-}
-
-
-static char box_level(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // by John Savard
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[1], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[2], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[3], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[4], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[5], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[6], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[7], "xxxxxxxxx.................xx.............x...................^.........xxxxxxxxx");
- strcpy(vgrid[8], "xxxxxxxxx.................xx...xxxxxx....x.xxxxxxx.xxxxxxxxxxxxxxxxxxx.xxxxxxxxx");
- strcpy(vgrid[9], "xxxxxxxxx.................xx...xx.0......x.x........x......x.........x.xxxxxxxxx");
- strcpy(vgrid[10], "xxxxxxxxx..$..............xx...xx........x.x........x.....%x.x..*..xxx.xxxxxxxxx");
- strcpy(vgrid[11], "xxxxxxxxx......................xx........x.x........x.xxxxxx.x.....x...xxxxxxxxx");
- strcpy(vgrid[12], "xxxxxxxxx......................xx....%...x.x........x.x......xxxxxxx.x.xxxxxxxxx");
- strcpy(vgrid[13], "xxxxxxxxx.................xx...xx........x.x........x.x.xxxxxx.......x.xxxxxxxxx");
- strcpy(vgrid[14], "xxxxxxxxx.................xx...xx........x.x..{.....x.x..............x.xxxxxxxxx");
- strcpy(vgrid[15], "xxxxxxxxx.............0...xx...xxxxxxxxxxx.xxxxxxxxxx.xxxxxxxxxxxxxxxx.xxxxxxxxx");
- strcpy(vgrid[16], "xxxxxxxxx.................xx...........................................xxxxxxxxx");
- strcpy(vgrid[17], "xxxxxxxxxxxxxxxxxxxxxxxxxxxx...xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[18], "xxxxxxxxxxxxxxxxxxxxxxxxxxxx...xxx}x.........................>=........xxxxxxxxx");
- strcpy(vgrid[19], "xxxxxxxxx..................x...xxx.x.xxx+xxxxxxxxxxxxxxxx+xxxxx........xxxxxxxxx");
- strcpy(vgrid[20], "xxxxxxxxx..xxxxxxxxxxxxxx..x...xxx.x.x0...x..0..............0.x........xxxxxxxxx");
- strcpy(vgrid[21], "xxxxxxxxx..x............x..x...xxx.x.x....x...................x........xxxxxxxxx");
- strcpy(vgrid[22], "xxxxxxxxx....xxxxxxxxx..x..x...xxx.x.x....x...................x......8*xxxxxxxxx");
- strcpy(vgrid[23], "xxxxxxxxx..x.x....0..x..x..x...xxx...x...%x...................x......*|xxxxxxxxx");
- strcpy(vgrid[24], "xxxxxxxxx..x.x..........x..x...xxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[25], "xxxxxxxxx..x.x*......x..x..x..........x...........0...x...%............xxxxxxxxx");
- strcpy(vgrid[26], "xxxxxxxxx..x.xxxxxxxxx..x..=..........x.xxxxxxxxxxxxx.x................xxxxxxxxx");
- strcpy(vgrid[27], "xxxxxxxxx..x......0.....xxxxxxx.......x.x...x...x...x.x................xxxxxxxxx");
- strcpy(vgrid[28], "xxxxxxxxx..xxxxxxxxxxxxxxxxxxxx..0....x...x.x.x.x.x.x.x......0.........xxxxxxxxx");
- strcpy(vgrid[29], "xxxxxxxxx..........^.........xx.......x.x.x.x.x.x.x...+................xxxxxxxxx");
- strcpy(vgrid[30], "xxxxxxxxxcccccccccccccccccc..xx.......x.x$x...x...xxxxx................xxxxxxxxx");
- strcpy(vgrid[31], "xxxxxxxxxc...........9....c..xx.......x.x.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[32], "xxxxxxxxxc......c............xx.......x.x.x...x..0.....................xxxxxxxxx");
- strcpy(vgrid[33], "xxxxxxxxxc.....|c............xx.......x.x.x.x.x........................xxxxxxxxx");
- strcpy(vgrid[34], "xxxxxxxxxc...........9....c..xx.......x.x...x.x........................xxxxxxxxx");
- strcpy(vgrid[35], "xxxxxxxxxcccccccccccccccccc..xx.......x.xxxxx.x........................xxxxxxxxx");
- strcpy(vgrid[36], "xxxxxxxxx....................xx.......x.x.....=....................*...xxxxxxxxx");
- strcpy(vgrid[37], "xxxxxxxxx....................xx.......x.x.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[38], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.......x.x.x...........................(xxxxxxxxx");
- strcpy(vgrid[39], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxx.x$x..xxxx.xxxxxxxxxxxxxxxxxxxx.xxxxxxxxx");
- strcpy(vgrid[40], "xxxxxxxxx...............................x.x..x.......................x.xxxxxxxxx");
- strcpy(vgrid[41], "xxxxxxxxx..xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.x..x.xxxxxxxxxxxxx.........x.xxxxxxxxx");
- strcpy(vgrid[42], "xxxxxxxxx.............)xxx................x..x.xxxxxxxxxxxxx.........x.xxxxxxxxx");
- strcpy(vgrid[43], "xxxxxxxxx..............xxx.xxxxxxxxxxxxxxxx..x.xxxxxxxxxxxxx.........x.xxxxxxxxx");
- strcpy(vgrid[44], "xxxxxxxxx..............xxx...................x.x...........xxxxx+xxxxx.xxxxxxxxx");
- strcpy(vgrid[45], "xxxxxxxxx..............xxxxxxxxxxxxxxxxxxxxxxx.x..$........x.........x.xxxxxxxxx");
- strcpy(vgrid[46], "xxxxxxxxx......9.......xxxxxxxxxxxxxxxxxxxxxxx.x...........x........%x.xxxxxxxxx");
- strcpy(vgrid[47], "xxxxxxxxx..............xxxxxxxxxxxxxxxxxxxxxxx.x.0.........x0........x.xxxxxxxxx");
- strcpy(vgrid[48], "xxxxxxxxx..............xxxxxxxxxxxxxxxxxxxxxxx.x.......$...x.........x.xxxxxxxxx");
- strcpy(vgrid[49], "xxxxxxxxx..............xxxxxxxxxxxxxxxxxxxxxxx.x...........xxxxxxxxxxx.xxxxxxxxx");
- strcpy(vgrid[50], "xxxxxxxxx..............xxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxx.x...........xxxxxxxxx");
- strcpy(vgrid[51], "xxxxxxxxx..............xxxxxxxxxxxxxxxxxxxxxxx.............x...........xxxxxxxxx");
- strcpy(vgrid[52], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx+xxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[53], "xxxxxxxxx..............................................................xxxxxxxxx");
- strcpy(vgrid[54], "xxxxxxxxx.xxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxx.xxxxxxx=xxxxxx.xxxxxx.xxxxxxxxx");
- strcpy(vgrid[55], "xxxxxxxxx.....xx.................xxxxxxxxxxx.......x........x.....x....xxxxxxxxx");
- strcpy(vgrid[56], "xxxxxxxxx....0xx.................xxxxxxxxxxx.%.....x.0......x...0.x....xxxxxxxxx");
- strcpy(vgrid[57], "xxxxxxxxx.....xx.9...............xxxxxxxxxxx.......x........x.%...x..$.xxxxxxxxx");
- strcpy(vgrid[58], "xxxxxxxxx.....xx.................xxxxxxxxxxx.......x........x.....x....xxxxxxxxx");
- strcpy(vgrid[59], "xxxxxxxxx.....xx.................xxxxxxxxxxx.......x........x.....x..0.xxxxxxxxx");
- strcpy(vgrid[60], "xxxxxxxxx....0xx.................xxxxxxxxxxx.......x$.......x.....x....xxxxxxxxx");
- strcpy(vgrid[61], "xxxxxxxxx]....xx................*xxxxxxxxxxx......[x........x.....x$...xxxxxxxxx");
- strcpy(vgrid[62], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[63], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[64], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[65], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[66], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[67], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[68], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[69], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- return MAP_ENCOMPASS;
-}
-
-
-static char vestibule_map(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // this is the vestibule
-
- strcpy(vgrid[0], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[1], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[2], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[3], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[4], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[5], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[6], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxvvvvvvvxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[7], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx..v.....v..xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[8], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.....v.....v.....xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[9], "xxxxxxxxxxxxxxxxxxxxxxxxxxxx........v.....v........xxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[10], "xxxxxxxxxxxxxxxxxxxxxxxxxx..........v..A..v..........xxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[11], "xxxxxxxxxxxxxxxxxxxxxxxx............v.....v............xxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[12], "xxxxxxxxxxxxxxxxxxxxxxx.............v.....v.............xxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[13], "xxxxxxxxxxxxxxxxxxxxxx..............vvv+vvv..............xxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[14], "xxxxxxxxxxxxxxxxxxxxx.....................................xxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[15], "xxxxxxxxxxxxxxxxxxxx.......................................xxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[16], "xxxxxxxxxxxxxxxxxxx.........................................xxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[17], "xxxxxxxxxxxxxxxxxx...........................................xxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[18], "xxxxxxxxxxxxxxxxx.............................................xxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[19], "xxxxxxxxxxxxxxxx...............................................xxxxxxxxxxxxxxxxx");
- strcpy(vgrid[20], "xxxxxxxxxxxxxxx.................................................xxxxxxxxxxxxxxxx");
- strcpy(vgrid[21], "xxxxxxxxxxxxxx...................................................xxxxxxxxxxxxxxx");
- strcpy(vgrid[22], "xxxxxxxxxxxxx.....................................................xxxxxxxxxxxxxx");
- strcpy(vgrid[23], "xxxxxxxxxxxxx.....................................................xxxxxxxxxxxxxx");
- strcpy(vgrid[24], "xxxxxxxxxxxx.......................................................xxxxxxxxxxxxx");
- strcpy(vgrid[25], "xxxxxxxxxxxx.......................................................xxxxxxxxxxxxx");
- strcpy(vgrid[26], "xxxxxxxxxxx.........................................................xxxxxxxxxxxx");
- strcpy(vgrid[27], "xxxxxxxxxxx............................{............................xxxxxxxxxxxx");
- strcpy(vgrid[28], "xxxxxxxxxxx.........................................................xxxxxxxxxxxx");
- strcpy(vgrid[29], "xxxxxxxxxx...l.l.....................................................xxxxxxxxxxx");
- strcpy(vgrid[30], "xxxxxxxxxx..l.l.l.l..................................................xxxxxxxxxxx");
- strcpy(vgrid[31], "xxxxxxxxxx.l.l.l.l.l.................................................xxxxxxxxxxx");
- strcpy(vgrid[32], "xxxxxxxxx.l.l.l.l.l...................................................xxxxxxxxxx");
- strcpy(vgrid[33], "xxxxxxxxxl.l.l.l.l.l..................................................xxxxxxxxxx");
- strcpy(vgrid[34], "xxxxxxxxx.l.l.l.A.l.l.................}1].............................=Axxxxxxxx");
- strcpy(vgrid[35], "xxxxxxxxxl.l.l.l.l.l.l.................)..............................xxxxxxxxxx");
- strcpy(vgrid[36], "xxxxxxxxx.l.l.l.l.l.l.................................................xxxxxxxxxx");
- strcpy(vgrid[37], "xxxxxxxxxx.l.l.l.l.l.l...............................................xxxxxxxxxxx");
- strcpy(vgrid[38], "xxxxxxxxxx..l.l.l.l..................................................xxxxxxxxxxx");
- strcpy(vgrid[39], "xxxxxxxxxx.....l.l...................................................xxxxxxxxxxx");
- strcpy(vgrid[40], "xxxxxxxxxxx......................[...........(......................xxxxxxxxxxxx");
- strcpy(vgrid[41], "xxxxxxxxxxx.........................................................xxxxxxxxxxxx");
- strcpy(vgrid[42], "xxxxxxxxxxx.........................................................xxxxxxxxxxxx");
- strcpy(vgrid[43], "xxxxxxxxxxxx.......................................................xxxxxxxxxxxxx");
- strcpy(vgrid[44], "xxxxxxxxxxxx.......................................................xxxxxxxxxxxxx");
- strcpy(vgrid[45], "xxxxxxxxxxxxx.....................................................xxxxxxxxxxxxxx");
- strcpy(vgrid[46], "xxxxxxxxxxxxx.....................................................xxxxxxxxxxxxxx");
- strcpy(vgrid[47], "xxxxxxxxxxxxxx...................................................xxxxxxxxxxxxxxx");
- strcpy(vgrid[48], "xxxxxxxxxxxxxxx....................wwwww........................xxxxxxxxxxxxxxxx");
- strcpy(vgrid[49], "xxxxxxxxxxxxxxxx..................wwwwwwww.....................xxxxxxxxxxxxxxxxx");
- strcpy(vgrid[50], "xxxxxxxxxxxxxxxxx..............wwwwwwwwwwwww..................xxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[51], "xxxxxxxxxxxxxxxxxx...........w..wwww..wwwww..w...............xxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[52], "xxxxxxxxxxxxxxxxxxx..........w...ww.....ww..wwwww...........xxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[53], "xxxxxxxxxxxxxxxxxxxx.........ww......ww....wwwwwwwww.......xxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[54], "xxxxxxxxxxxxxxxxxxxxx.........ww....wwww...wwwwwwwwww.....xxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[55], "xxxxxxxxxxxxxxxxxxxxxx.........ww....ww....wwwwwwwwwww...xxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[56], "xxxxxxxxxxxxxxxxxxxxxxx........wwww.......wwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[57], "xxxxxxxxxxxxxxxxxxxxxxxx......wwwwwww....wwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[58], "xxxxxxxxxxxxxxxxxxxxxxxxxx...wwwwwwwwwwAwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[59], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxwwwwwwwwwwwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[60], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxwwwwwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[61], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxwwwwwwwwwwwxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[62], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[63], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[64], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[65], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[66], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[67], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[68], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[69], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- mons_array[0] = MONS_GERYON;
- mons_array[1] = RANDOM_MONSTER;
- mons_array[2] = RANDOM_MONSTER;
- mons_array[3] = RANDOM_MONSTER;
- mons_array[4] = RANDOM_MONSTER;
- mons_array[5] = RANDOM_MONSTER;
- mons_array[6] = RANDOM_MONSTER;
-
- return MAP_ENCOMPASS;
-}
-
-
-static char castle_dis(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // Dispater's castle - rest of level filled up with plan_4 (irregular city)
-
- strcpy(vgrid[0], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[1], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[2], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[3], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[4], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[5], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[6], "xxxxxxxxvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvxxxxxxxx");
- strcpy(vgrid[7], "xxxxxxxxv..............................................................vxxxxxxxx");
- strcpy(vgrid[8], "xxxxxxxxv..vvvvvvvvv........................................vvvvvvvvv..vxxxxxxxx");
- strcpy(vgrid[9], "xxxxxxxxv..v3.....|v........................................v|.....2v..vxxxxxxxx");
- strcpy(vgrid[10], "xxxxxxxxv..v.vv+vvvv.v.v.v.v.v.v.v.v.v..v.v.v.v.v.v.v.v.v.v.vvvv+vv.v..vxxxxxxxx");
- strcpy(vgrid[11], "xxxxxxxxv..v.v.....vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv.....v.v..vxxxxxxxx");
- strcpy(vgrid[12], "xxxxxxxxv..v|v.....+$$v$$+$$v||vvvvvvvvvvvvvvvvv$$$$v4.4.v$$v.....v|v..vxxxxxxxx");
- strcpy(vgrid[13], "xxxxxxxxv..vvvv+vvvv$$+$$v$$+||v...............v$$$$+.4.4+$$v+vv+vvvv..vxxxxxxxx");
- strcpy(vgrid[14], "xxxxxxxxv....vv.vvvvvvvvvvvvvvvv.v..v..v..v..v.v$$$$v4.4.v$$+||v.vv5...vxxxxxxxx");
- strcpy(vgrid[15], "xxxxxxxxv...vvv................v...............vvvvvvvvvvvvvvvvv.vvv...vxxxxxxxx");
- strcpy(vgrid[16], "xxxxxxxxv...5vv................+...............+.................vv....vxxxxxxxx");
- strcpy(vgrid[17], "xxxxxxxxv...vvv+vvvvvvvvvvvvvvvv.v..v..v..v..v.vvvvvvvvvvvvvvvvv.vvv...vxxxxxxxx");
- strcpy(vgrid[18], "xxxxxxxxv....vv..v.+$$$$$v.....v...............vvvvvvvvvvvvvvvvv.vv5...vxxxxxxxx");
- strcpy(vgrid[19], "xxxxxxxxv...vvv..v.v$$$$$v.....v...............vv|$|$|vv|$|$|$vv.vvv...vxxxxxxxx");
- strcpy(vgrid[20], "xxxxxxxxv...5vv..v.vvvvvvv.....vvvvv.......vvvvvv$|$|$++$|$|$|vv.vv....vxxxxxxxx");
- strcpy(vgrid[21], "xxxxxxxxv...vvv..v...............v.vvvv+vvvvvvvvvvvvvvvvvvvvv+vv.vvv...vxxxxxxxx");
- strcpy(vgrid[22], "xxxxxxxxv....vvv+v..........vvvvv.4vvv...vvvvvvvvvvvvvvvvvvvv+vv.vv5...vxxxxxxxx");
- strcpy(vgrid[23], "xxxxxxxxv...vvv..v.v..v..v....2vvv+vv5...5vvvvvvv.4.4.vv.4.4.4vv.vvv...vxxxxxxxx");
- strcpy(vgrid[24], "xxxxxxxxv...5vv.................vv|vvv...vvvvv.++4.4.4++4.4.4.vv.vv....vxxxxxxxx");
- strcpy(vgrid[25], "xxxxxxxxv...vvv.................1vOvv5...5vvvv.vvvvvvvvvvvvvvvvv.vvv...vxxxxxxxx");
- strcpy(vgrid[26], "xxxxxxxxv....vv.................vv|vvv...vvvvv.vvvvvvvvvvvvvvvvv.vv5...vxxxxxxxx");
- strcpy(vgrid[27], "xxxxxxxxv...vvv.v..v..v..v....3vvv+vv5...5vvvv...................vvv...vxxxxxxxx");
- strcpy(vgrid[28], "xxxxxxxxv...5vv.............vvvvv.4vvv...vvvvvvvvvvvvvvvvvvvvvvv.vv....vxxxxxxxx");
- strcpy(vgrid[29], "xxxxxxxxv..vvvv+vvvv.............v.vv5...5vvvvvvvvvvvvvvvvvvvvvv+vvvv..vxxxxxxxx");
- strcpy(vgrid[30], "xxxxxxxxv..v|v.....vvvvvvvvvvvvvvvvvvv...vvvvvvvvvvvvvvvvvvvv.....v|v..vxxxxxxxx");
- strcpy(vgrid[31], "xxxxxxxxv..v.v.....vvvvvvvvvvvvvvvvvvvv+vvvvvvvvvvvvvvvvvvvvv.....v.v..vxxxxxxxx");
- strcpy(vgrid[32], "xxxxxxxxv..v.vv+vvvv5.............5.........5..............5vvvv+vv.v..vxxxxxxxx");
- strcpy(vgrid[33], "xxxxxxxxv..v2.....|v........................................v|.....3v..vxxxxxxxx");
- strcpy(vgrid[34], "xxxxxxxxv..vvvvvvvvv........................................vvvvvvvvv..vxxxxxxxx");
- strcpy(vgrid[35], "xxxxxxxxv............................{.[.(.............................vxxxxxxxx");
-
- mons_array[0] = MONS_DISPATER;
- mons_array[1] = MONS_FIEND;
- mons_array[2] = MONS_ICE_FIEND;
- mons_array[3] = MONS_IRON_DEVIL;
- mons_array[4] = MONS_METAL_GARGOYLE;
- mons_array[5] = RANDOM_MONSTER;
- mons_array[6] = RANDOM_MONSTER;
-
- return MAP_NORTH_DIS;
-}
-
-
-static char asmodeus(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
-
- strcpy(vgrid[0], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[1], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[2], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[3], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[4], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[5], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[6], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[7], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxx....xxxxxxxxxxxxxxx.xxxxxxxxxxxx");
- strcpy(vgrid[8], "xxxxxxxxxxxxxxxxxxxxxxxxx............................xxxxxxxxxxxxxx..xxxxxxxxxxx");
- strcpy(vgrid[9], "xxxxxxxxxxxxxxxxxxxxxxxxxx..............................xxxxxxxxxx....xxxxxxxxxx");
- strcpy(vgrid[10], "xxxxxxxxxxxxxxxxxxxxx...xxx................................xxxxxx....xxxxxxxxxxx");
- strcpy(vgrid[11], "xxxxxxxxxxxx.x.xxxxx.........................................xxx....xxxxxxxxxxxx");
- strcpy(vgrid[12], "xxxxxxxxxxxx....xx.....................4......................xx...xxxxxxxxxxxxx");
- strcpy(vgrid[13], "xxxxxxxxxxx......x......................llllllllllllll.........x..xxxxxxxxxxxxxx");
- strcpy(vgrid[14], "xxxxxxxxxxx..xx..................lllllllllllllllllllllllll........xxxxxxxxxxxxxx");
- strcpy(vgrid[15], "xxxxxxxxxx...xxx....0..........llllllllllllllllllllllllll........xx...xxxxxxxxxx");
- strcpy(vgrid[16], "xxxxxxxxx....xxx.............llllllllllllllllllllllllllll..............xxxxxxxxx");
- strcpy(vgrid[17], "xxxxxxxxxx....xx...........lllllllllllllllllllllllllllll...............xxxxxxxxx");
- strcpy(vgrid[18], "xxxxxxxxxxxx..............llllllllllllllllllllllllllllll...2..xx...0...xxxxxxxxx");
- strcpy(vgrid[19], "xxxxxxxxxxxxx...........lllllllllllllllllll.......llllll......xx......xxxxxxxxxx");
- strcpy(vgrid[20], "xxxxxxxxxxxxxx.......llllllllllllllllll............llllll.............xxxxxxxxxx");
- strcpy(vgrid[21], "xxxxxxxxxxxxxxx......lllllllll..........4.........4.lllllll..........xxxxxxxxxxx");
- strcpy(vgrid[22], "xxxxxxxxxx...xx...ll3lllll......4...................llllllll......x.xxxxxxxxxxxx");
- strcpy(vgrid[23], "xxxxxxxxx.......lllll.l................................llll.......xxxxxxxxxxxxxx");
- strcpy(vgrid[24], "xxxxxxxxxx..4..llllll...cccccccc+c+c+c+c+c+c+c+c+c+c....lll......xxxxxxxxxxxxxxx");
- strcpy(vgrid[25], "xxxxxxxxxxx..lllllll..4.c.....c....................c....llll.....xxxxxxxxxxxxxxx");
- strcpy(vgrid[26], "xxxxxxxxxx...llllll.....c.V.V.+....0.....3.....0...c.....llll....x..xxxxxxxxxxxx");
- strcpy(vgrid[27], "xxxxxxxxx...llllll...l..c.....c....................c....lllll........xxxxxxxxxxx");
- strcpy(vgrid[28], "xxxxxxxxxx...lllll..ll..c..5..cccccccccccccccccccccc.4..llllll........xxxxxxxxxx");
- strcpy(vgrid[29], "xxxxxxxxx...lllll..llll.c.....c...............c....c....lllllll.......xxxxxxxxxx");
- strcpy(vgrid[30], "xxxxxxxxx...lllll..llll.c.V.V.c.......0.......c....c....lllllll.......xxxxxxxxxx");
- strcpy(vgrid[31], "xxxxxxxxxx...lllll..lll.c.....+...............+....c...lllllll........xxxxxxxxxx");
- strcpy(vgrid[32], "xxxxxxxxxxx..lllll...ll.cccccccccc....0.......c....c...llllllll........xxxxxxxxx");
- strcpy(vgrid[33], "xxxxxxxxxx...lllll..4...c|$$||$$|c............c.0..c...llllllll........xxxxxxxxx");
- strcpy(vgrid[34], "xxxxxxxxx...lllll.......c$$$$$$$$cccccccccccccc....c...lllllll.........xxxxxxxxx");
- strcpy(vgrid[35], "xxxxxxxxx...lllll.......c$$|2|$$|c..0.........+....c...lllllll........xxxxxxxxxx");
- strcpy(vgrid[36], "xxxxxxxxxx.lllllll......c|$$$$$$$c........9...c....c....llllllll.....xxxxxxxxxxx");
- strcpy(vgrid[37], "xxxxxxxxxx.lllllll......c$|$|$$|$c+ccccccccccccccccc....lllllll......xxxxxxxxxxx");
- strcpy(vgrid[38], "xxxxxxxxxx..llllll......cccccccc+c.....9.......c.........llllll......x.xxxxxxxxx");
- strcpy(vgrid[39], "xxxxxxxxxx..lllllll.....c$$$$$$+3c.....8...3...c.....4...llllll........xxxxxxxxx");
- strcpy(vgrid[40], "xxxxxxxxxx..llllllll....c$$$$$$c.c.....9.......c..ll....llllll.........xxxxxxxxx");
- strcpy(vgrid[41], "xxxxxxxxxx...llllll..4..c$$2$$$c.ccccccccccccc+c.lll...lllllll...0....xxxxxxxxxx");
- strcpy(vgrid[42], "xxxxxxxxxxx..llllll.....c$$$$$$c..+............c.ll...lllllll..........xxxxxxxxx");
- strcpy(vgrid[43], "xxxxxxxxxxx..llllllll...ccccccccc+cccccccccccccc.....lllllll...........xxxxxxxxx");
- strcpy(vgrid[44], "xxxxxxxxxxxx..llllllll.........cc..........cc........lllllll.......x..xxxxxxxxxx");
- strcpy(vgrid[45], "xxxxxxxxxxxxx.llllllllll.......ccc.........cc......lllllllll.......xxxxxxxxxxxxx");
- strcpy(vgrid[46], "xxxxxxxxxx....lllllllllll...4...cc.....2.2.cc....llllllllll.4.......xxxxxxxxxxxx");
- strcpy(vgrid[47], "xxxxxxxxx....4.lllllllllllll....cccccccc+cccc..lllllllllll.....xx....xxxxxxxxxxx");
- strcpy(vgrid[48], "xxxxxxxxxx.....llllllllllllll...cccccccc+cccc..llllllllll......xx....xxxxxxxxxxx");
- strcpy(vgrid[49], "xxxxxxxxxxx.....lllllllllllllll..cc......cc...lllllllllll...........xxxxxxxxxxxx");
- strcpy(vgrid[50], "xxxxxxxxxxx.....llllllllllllll...ccO1....cc.4..lllllllll...........xxxxxxxxxxxxx");
- strcpy(vgrid[51], "xxxxxxxxxxxx.....lllllllllllll...cc......cc....lllllllll.......xx.xxxxxxxxxxxxxx");
- strcpy(vgrid[52], "xxxxxxxxxxxx.......llllllllllll..cccccccccc...lllllllll........xxxxxxxxxxxxxxxxx");
- strcpy(vgrid[53], "xxxxxxxxx.........llllllllllllll.cccccccccc.lllllllllll.......xxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[54], "xxxxxxxxxx....0...llllllllllllll............lllllllll....0....xxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[55], "xxxxxxxxxx.......4.lllllllllllllll..4....lllllllll...........xxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[56], "xxxxxxxxxxx..........llllllllllllll....lllllll....4.....x........xxxxxxxxxxxxxxx");
- strcpy(vgrid[57], "xxxxxxxxxxx...xx.........lllllllllllllllll...................xx{xxxxxxxxxxxxxxxx");
- strcpy(vgrid[58], "xxxxxxxxxxxxx..xx................lllllll.....................xxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[59], "xxxxxxxxxxxxxxxxx.........xxx.................xxxxxx......xxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[60], "xxxxxxxxxxxxxxxxxxx....xxxxxxxx...xxx......xxxxxxxxxx.......xxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[61], "xxxxxxxxxxxxxxxxxxxx(xxxxxxxxxxxx[xxxxx...xxxxxxxxxxxxxx...xxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[62], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[63], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[64], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[65], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[66], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[67], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[68], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[69], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- mons_array[0] = MONS_ASMODEUS;
- mons_array[1] = MONS_FIEND;
- mons_array[2] = MONS_BALRUG;
- mons_array[3] = MONS_MOLTEN_GARGOYLE;
- mons_array[4] = MONS_SERPENT_OF_HELL;
- mons_array[5] = RANDOM_MONSTER;
- mons_array[6] = RANDOM_MONSTER;
-
- return MAP_ENCOMPASS;
-}
-
-static char antaeus(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // bottom of Cocytus. This needs work
-
- strcpy(vgrid[0], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[1], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[2], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[3], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[4], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[5], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[6], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[7], "xxxxxxxxxxxxxxxxxxxxxxxxxxxx........................xxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[8], "xxxxxxxxxxxxxxxxxxxxxxxxxxx..........................xxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[9], "xxxxxxxxxxxxxxxxxxxxxxxxxx............................xxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[10], "xxxxxxxxxxxxxxxxxxxxxxxxx..............................xxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[11], "xxxxxxxxxxxxxxxxxxxxxxxx................................xxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[12], "xxxxxxxxxxxxxxxxxxxxxxx....cccccccccccc..cccccccccccc....xxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[13], "xxxxxxxxxxxxxxxxxxxxxx....ccccccccccccc2.ccccccccccccc....xxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[14], "xxxxxxxxxxxxxxxxxxxxx....cc..........................cc....xxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[15], "xxxxxxxxxxxxxxxxxxxx....cc............................cc....xxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[16], "xxxxxxxxxxxxxxxxxxx....cc...wwwwwwwwwwwwwwwwwwwwwwww...cc....xxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[17], "xxxxxxxxxxxxxxxxxx....cc...wwwwwwwwwwwwwwwwwwwwwwwwww...cc....xxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[18], "xxxxxxxxxxxxxxxxx....cc...wwwwwwwwwwwwwwwwwwwwwwwwwwww...cc....xxxxxxxxxxxxxxxxx");
- strcpy(vgrid[19], "xxxxxxxxxxxxxxxx....cc...ww.......3..........3.......ww...cc....xxxxxxxxxxxxxxxx");
- strcpy(vgrid[20], "xxxxxxxxxxxxxxx....cc...ww............................ww...cc....xxxxxxxxxxxxxxx");
- strcpy(vgrid[21], "xxxxxxxxxxxxxx....cc...ww....cccccccccccccccccccccc....ww...cc....xxxxxxxxxxxxxx");
- strcpy(vgrid[22], "xxxxxxxxxxxxx....cc...ww....cccccccccccccccccccccccc....ww...cc....xxxxxxxxxxxxx");
- strcpy(vgrid[23], "xxxxxxxxxxxx....cc...ww....cc......................cc....ww...cc....xxxxxxxxxxxx");
- strcpy(vgrid[24], "xxxxxxxxxxx....cc...ww....cc...T................T...cc....ww...cc....xxxxxxxxxxx");
- strcpy(vgrid[25], "xxxxxxxxxx....cc...ww....cc..........wwwwww..........cc....ww...cc....xxxxxxxxxx");
- strcpy(vgrid[26], "xxxxxxxxx....cc...ww....cc.......wwwwwwwwwwwwww.......cc....ww...cc....xxxxxxxxx");
- strcpy(vgrid[27], "xxxxxxxxx....cc...ww...cc.....wwwwwwwwwwwwwwwwwwww.....cc...ww...cc....xxxxxxxxx");
- strcpy(vgrid[28], "xxxxxxxxx....cc..www..cc....wwwwwwwwwccccccwwwwwwwww....cc..www..cc....xxxxxxxxx");
- strcpy(vgrid[29], "xxxxxxxxx....cc..www.cc....wwwwwwwwccc2O12cccwwwwwwww....cc.www..cc....xxxxxxxxx");
- strcpy(vgrid[30], "xxxxxxxxx....cc..www.cc...wwwwwwwwcc2+....+2ccwwwwwwww...cc.www..cc....xxxxxxxxx");
- strcpy(vgrid[31], "xxxxxxxxx....cc..www.cc...wwwwwwwwcc+cc++cc+ccwwwwwwww...cc.www..cc....xxxxxxxxx");
- strcpy(vgrid[32], "xxxxxxxxx....cc..www..c..wwwwwwwwwc|||c..c$$$cwwwwwwwww..c..www..cc....xxxxxxxxx");
- strcpy(vgrid[33], "xxxxxxxxx....cc..wwww.c.wwwwwwwwwwc|||c..c$$$cwwwwwwwwww.c.wwww..cc....xxxxxxxxx");
- strcpy(vgrid[34], "xxxxxxxxx....cc..wwww.c.wwwwwwwwwwcc||c..c$$ccwwwwwwwwww.c.wwww..cc....xxxxxxxxx");
- strcpy(vgrid[35], "xxxxxxxxx....cc..wwww.c.wwwwwwwwwwwcccc++ccccwwwwwwwwwww.c.wwww..cc....xxxxxxxxx");
- strcpy(vgrid[36], "xxxxxxxxx....cc..www..c..wwwwwwwwwwwwww..wwwwwwwwwwwwww..c..www..cc....xxxxxxxxx");
- strcpy(vgrid[37], "xxxxxxxxx....cc..www.cc...wwwwwwwwwwwwwwwwwwwwwwwwwwww...cc.www..cc....xxxxxxxxx");
- strcpy(vgrid[38], "xxxxxxxxx....cc..www.cc....wwwwwwwwwwwwwwwwwwwwwwwwwww...cc.www..cc....xxxxxxxxx");
- strcpy(vgrid[39], "xxxxxxxxx....cc..www.cc....wwwwwwwwwwwwwwwwwwwwwwwwww....cc.www..cc....xxxxxxxxx");
- strcpy(vgrid[40], "xxxxxxxxx....cc..www..cc....wwwwwwwwwwwwwwwwwwwwwwww....cc..www..cc....xxxxxxxxx");
- strcpy(vgrid[41], "xxxxxxxxx....cc...ww...cc.....wwwwwwwwwwwwwwwwwwww.....cc...ww...cc....xxxxxxxxx");
- strcpy(vgrid[42], "xxxxxxxxx....cc...ww....cc.......wwwwwwwwwwwwww.......cc....ww...cc....xxxxxxxxx");
- strcpy(vgrid[43], "xxxxxxxxxx....cc...ww....cc..........wwwwww..........cc....ww...cc....xxxxxxxxxx");
- strcpy(vgrid[44], "xxxxxxxxxxx....cc...ww....cc...T................T...cc....ww...cc....xxxxxxxxxxx");
- strcpy(vgrid[45], "xxxxxxxxxxxx....cc...ww....cc......................cc....ww...cc....xxxxxxxxxxxx");
- strcpy(vgrid[46], "xxxxxxxxxxxxx....cc...ww....ccccccccccc..ccccccccccc....ww...cc....xxxxxxxxxxxxx");
- strcpy(vgrid[47], "xxxxxxxxxxxxxx....cc...ww....cccccccccc2.cccccccccc....ww...cc....xxxxxxxxxxxxxx");
- strcpy(vgrid[48], "xxxxxxxxxxxxxxx....cc...ww............................ww...cc....xxxxxxxxxxxxxxx");
- strcpy(vgrid[49], "xxxxxxxxxxxxxxxx....cc...ww..........................ww...cc....xxxxxxxxxxxxxxxx");
- strcpy(vgrid[50], "xxxxxxxxxxxxxxxxx....cc...wwwwwwwwwwwww..wwwwwwwwwwwww...cc....xxxxxxxxxxxxxxxxx");
- strcpy(vgrid[51], "xxxxxxxxxxxxxxxxxx....cc...wwwwwwwwwwww..wwwwwwwwwwww...cc....xxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[52], "xxxxxxxxxxxxxxxxxxx....cc...wwwwwwwwwww..wwwwwwwwwww...cc....xxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[53], "xxxxxxxxxxxxxxxxxxxx....cc............................cc....xxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[54], "xxxxxxxxxxxxxxxxxxxxx....cc..........................cc....xxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[55], "xxxxxxxxxxxxxxxxxxxxxx....cccccccccccccccccccccccccccc....xxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[56], "xxxxxxxxxxxxxxxxxxxxxxx....cccccccccccccccccccccccccc....xxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[57], "xxxxxxxxxxxxxxxxxxxxxxxx................................xxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[58], "xxxxxxxxxxxxxxxxxxxxxxxxx..............................xxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[59], "xxxxxxxxxxxxxxxxxxxxxxxxxx............................xxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[60], "xxxxxxxxxxxxxxxxxxxxxxxxxxx..........{.(.[...........xxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[61], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[62], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[63], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[64], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[65], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[66], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[67], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[68], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[69], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- mons_array[0] = MONS_ANTAEUS;
- mons_array[1] = MONS_ICE_FIEND;
- mons_array[2] = MONS_ICE_DRAGON;
- mons_array[3] = RANDOM_MONSTER;
- mons_array[4] = RANDOM_MONSTER;
- mons_array[5] = RANDOM_MONSTER;
- mons_array[6] = RANDOM_MONSTER;
-
- return MAP_ENCOMPASS;
-}
-
-
-static char ereshkigal(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // Tartarus
- // note that the tomb on the right isn't supposed to have any doors
-
- strcpy(vgrid[0], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[1], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[2], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[3], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[4], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[5], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[6], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[7], "xxxxxxxxx..............................................................xxxxxxxxx");
- strcpy(vgrid[8], "xxxxxxxxx..............................................................xxxxxxxxx");
- strcpy(vgrid[9], "xxxxxxxxx.................cccc..........ccc............................xxxxxxxxx");
- strcpy(vgrid[10], "xxxxxxxxx.............ccccc..cccc.....ccc.cccc.........................xxxxxxxxx");
- strcpy(vgrid[11], "xxxxxxxxx...........ccc.........ccccccc.....cc.........................xxxxxxxxx");
- strcpy(vgrid[12], "xxxxxxxxx.........ccc.......2............V..cc.........................xxxxxxxxx");
- strcpy(vgrid[13], "xxxxxxxxx........cc4........................cc...........xxxxxxxx......xxxxxxxxx");
- strcpy(vgrid[14], "xxxxxxxxx........cc44xxx==xxx...............cc..........xx......xx.....xxxxxxxxx");
- strcpy(vgrid[15], "xxxxxxxxx........ccxxx......xxx.......ccc++ccc.........xx........xx....xxxxxxxxx");
- strcpy(vgrid[16], "xxxxxxxxx........cxx..........xxx.....ccc44ccc.........x..........x....xxxxxxxxx");
- strcpy(vgrid[17], "xxxxxxxxx........cx............xx....cccc44cc.........xx..........xx...xxxxxxxxx");
- strcpy(vgrid[18], "xxxxxxxxx.......ccx.G........G.xxx7ccc..c44c..........x.....|......x...xxxxxxxxx");
- strcpy(vgrid[19], "xxxxxxxxx.......cxx............xxxcc..................x......7.....x...xxxxxxxxx");
- strcpy(vgrid[20], "xxxxxxxxx......ccx..............xxc...................xx..........xx...xxxxxxxxx");
- strcpy(vgrid[21], "xxxxxxxxx......ccx..G........G..xxc..x.........x.......x..........x....xxxxxxxxx");
- strcpy(vgrid[22], "xxxxxxxxx......ccx..............xcc....................xx........xx....xxxxxxxxx");
- strcpy(vgrid[23], "xxxxxxxxx.......cxx............xxc......................xx......xx.....xxxxxxxxx");
- strcpy(vgrid[24], "xxxxxxxxx.......ccx.F........F.xcc.......................xxxxxxxx......xxxxxxxxx");
- strcpy(vgrid[25], "xxxxxxxxx........cx............xc......................................xxxxxxxxx");
- strcpy(vgrid[26], "xxxxxxxxx........cxx....17....xxc....x.........x.......................xxxxxxxxx");
- strcpy(vgrid[27], "xxxxxxxxx........ccxxx......xxxcc......................................xxxxxxxxx");
- strcpy(vgrid[28], "xxxxxxxxx........cccc=xxxxxx=cccc......................................xxxxxxxxx");
- strcpy(vgrid[29], "xxxxxxxxx........cc||cccccccc||cc......................................xxxxxxxxx");
- strcpy(vgrid[30], "xxxxxxxxx.........cc||||O|||||cc.......................................xxxxxxxxx");
- strcpy(vgrid[31], "xxxxxxxxx..........cccccccccccc......x.........x............V..........xxxxxxxxx");
- strcpy(vgrid[32], "xxxxxxxxx..............................................................xxxxxxxxx");
- strcpy(vgrid[33], "xxxxxxxxx...........................................xxxxxxxxxxxxxxxx...xxxxxxxxx");
- strcpy(vgrid[34], "xxxxxxxxx...........................................xxxxxxxxxxxxxxxx...xxxxxxxxx");
- strcpy(vgrid[35], "xxxxxxxxx...........................................xx$$$$xxx|||||xx...xxxxxxxxx");
- strcpy(vgrid[36], "xxxxxxxxx.......V........V...........x.........x....xx$$$$xxx|||||xx...xxxxxxxxx");
- strcpy(vgrid[37], "xxxxxxxxx...........................................xxxxxxxxxxxxxxxx...xxxxxxxxx");
- strcpy(vgrid[38], "xxxxxxxxx...........................................xxxxxxxxxxxxxxxx...xxxxxxxxx");
- strcpy(vgrid[39], "xxxxxxxxx...........................................xx44444xx22222xx...xxxxxxxxx");
- strcpy(vgrid[40], "xxxxxxxxx.......xxxxxxxxx+xxxxxxxxx.................xx44444xx22222xx...xxxxxxxxx");
- strcpy(vgrid[41], "xxxxxxxxx.......x3.2..........3...x..x.........x..xxxxxxxxxxxxxxxxxx...xxxxxxxxx");
- strcpy(vgrid[42], "xxxxxxxxx.......x.x.x.x.x.x.x.x.x.x.................xxxxxxxxxxxxxxxx...xxxxxxxxx");
- strcpy(vgrid[43], "xxxxxxxxx.......x...2.3..4..5..4..x......................=.......xxx...xxxxxxxxx");
- strcpy(vgrid[44], "xxxxxxxxx.......xx.x.x.x.x.x.x.x.xx......................=.......xxx...xxxxxxxxx");
- strcpy(vgrid[45], "xxxxxxxxx.......x..65..3..6.6...5.x.................xxxxxxxxxxxxxxxx...xxxxxxxxx");
- strcpy(vgrid[46], "xxxxxxxxx.......x.x.x.x.x.x.x.x.x.x..x.........x..xxxxxxxxxxxxxxxxxx...xxxxxxxxx");
- strcpy(vgrid[47], "xxxxxxxxx.......x...4...3.....4...x.................xx.....xx555555x...xxxxxxxxx");
- strcpy(vgrid[48], "xxxxxxxxx.......xx=xxxxx.x.xxxxxxxx.................xx.....xx555555x...xxxxxxxxx");
- strcpy(vgrid[49], "xxxxxxxxx.......x$$$$$$x.25.x$$$||x.................xxxxxxxxxxxxxxxx...xxxxxxxxx");
- strcpy(vgrid[50], "xxxxxxxxx.......x$x$$x$xx.x.x$x$x|x.................xxxxxxxxxxxxxxxx...xxxxxxxxx");
- strcpy(vgrid[51], "xxxxxxxxx.......x||||||x.556=$$$||x..x.........x....xx$$xx56565xx$|x...xxxxxxxxx");
- strcpy(vgrid[52], "xxxxxxxxx.......xxxxxxxxxxxxxxxxxxx.................xx$$xx65656xx|7x...xxxxxxxxx");
- strcpy(vgrid[53], "xxxxxxxxx...........................................xxxxxxxxxxxxxxxx...xxxxxxxxx");
- strcpy(vgrid[54], "xxxxxxxxx...........................................xxxxxxxxxxxxxxxx...xxxxxxxxx");
- strcpy(vgrid[55], "xxxxxxxxx..............................................................xxxxxxxxx");
- strcpy(vgrid[56], "xxxxxxxxx..............................................................xxxxxxxxx");
- strcpy(vgrid[57], "xxxxxxxxx........(...........................................[.........xxxxxxxxx");
- strcpy(vgrid[58], "xxxxxxxxx..............................................................xxxxxxxxx");
- strcpy(vgrid[59], "xxxxxxxxx..............................................................xxxxxxxxx");
- strcpy(vgrid[60], "xxxxxxxxx..............................{...............................xxxxxxxxx");
- strcpy(vgrid[61], "xxxxxxxxx..............................................................xxxxxxxxx");
- strcpy(vgrid[62], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[63], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[64], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[65], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[66], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[67], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[68], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[69], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- mons_array[0] = MONS_ERESHKIGAL;
- mons_array[1] = MONS_NECROPHAGE;
- mons_array[2] = MONS_WRAITH;
- mons_array[3] = MONS_SHADOW;
- mons_array[4] = MONS_ZOMBIE_SMALL;
- mons_array[5] = MONS_SKELETON_SMALL;
- mons_array[6] = MONS_SHADOW_FIEND;
-
- return MAP_ENCOMPASS;
-}
-
-
-static char mnoleg(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
-
- for (unsigned char i = 0; i < 81; i++)
- strcpy(vgrid[i], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- strcat(vgrid[0], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[1], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[2], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[3], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[4], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[5], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[6], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[7], "x.................2............xxxxxxxxx");
- strcat(vgrid[8], "x.....2........................xxxxxxxxx");
- strcat(vgrid[9], "x..cccccccc...ccccccc..ccccccc.xxxxxxxxx");
- strcat(vgrid[10], "x..ccccccccc.2.ccccccc..cccccc.xxxxxxxxx");
- strcat(vgrid[11], "x..cccccccccc...ccccccc..ccccc.xxxxxxxxx");
- strcat(vgrid[12], "x..ccccccccccc.1.ccccccc..cccc.xxxxxxxxx");
- strcat(vgrid[13], "x2.cccccccccc.2..Occccccc2.ccc.xxxxxxxxx");
- strcat(vgrid[14], "x..ccccccccc.....ccccccccc..cc.xxxxxxxxx");
- strcat(vgrid[15], "x..cccccccc...c...ccccccccc..c.xxxxxxxxx");
- strcat(vgrid[16], "x..ccccccc...ccc...ccccccccc...xxxxxxxxx");
- strcat(vgrid[17], "x..cccccc...ccccc...ccccccccc..xxxxxxxxx");
- strcat(vgrid[18], "x..ccccc...ccccccc...ccccccccc.xxxxxxxxx");
- strcat(vgrid[19], "x..cccc...ccccccccc...ccccccc..xxxxxxxxx");
- strcat(vgrid[20], "x..ccc.2.ccccccccccc.2.ccccc...xxxxxxxxx");
- strcat(vgrid[21], "x..cc.....ccccccccccc...ccc....xxxxxxxxx");
- strcat(vgrid[22], "x..c...c...ccccccccccc...c.2...xxxxxxxxx");
- strcat(vgrid[23], "x.....ccc.2.ccccccccccc......c.xxxxxxxxx");
- strcat(vgrid[24], "x....ccccc...ccccccccccc....cc.xxxxxxxxx");
- strcat(vgrid[25], "x.2.ccccccc...ccccccccccc..ccc.xxxxxxxxx");
- strcat(vgrid[26], "x.................2.......cccc.xxxxxxxxx");
- strcat(vgrid[27], "x...c..ccccccc.ccccccc...ccccc.xxxxxxxxx");
- strcat(vgrid[28], "x..ccc......2c.c2cccc...cccccc.xxxxxxxxx");
- strcat(vgrid[29], "x.ccccc..ccc.c.c2ccc.2.ccccccc.xxxxxxxxx");
- strcat(vgrid[30], "x.cccccc..cc.c.c.cc...cccccccc.xxxxxxxxx");
- strcat(vgrid[31], "x.ccccccc..c.c.c.c...ccccccccc.xxxxxxxxx");
- strcat(vgrid[32], "x.cccccccc...c.c....cccccccccc.xxxxxxxxx");
- strcat(vgrid[33], "x.ccccccccc..c.c...ccccccccccc.xxxxxxxxx");
- strcat(vgrid[34], "x..............................xxxxxxxxx");
- strcat(vgrid[35], "xxxxxxxxxxxxxx@xxxxxxxxxxxxxxxxxxxxxxxxx");
-
- mons_array[0] = MONS_MNOLEG;
- mons_array[1] = MONS_NEQOXEC;
- mons_array[2] = RANDOM_MONSTER;
- mons_array[3] = RANDOM_MONSTER;
- mons_array[4] = RANDOM_MONSTER;
- mons_array[5] = RANDOM_MONSTER;
- mons_array[6] = RANDOM_MONSTER;
-
- return MAP_NORTHEAST;
-}
-
-
-static char lom_lobon(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
-
- strcpy(vgrid[0], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[1], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[2], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[3], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[4], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[5], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[6], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[7], "xxxxxxxxxxxxxxxxxxxxxxxxxxxwwwwwwwwwwww.......wwwwwwwxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[8], "xxxxxxxxxxxxxxxxxxxxxxwwwwwwwwwwwwbbbwwwwwww.......wwwwwwwxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[9], "xxxxxxxxxxxxxxxxxxwwwwwwwwwwwwbbbbbbbbbbbwwwwww.........wwwwwwxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[10], "xxxxxxxxxxxxxxxwwwwwwwwwwwwbbbbwwwwwwwwwbbbbwwwwww.........wwwwwwxxxxxxxxxxxxxxx");
- strcpy(vgrid[11], "xxxxxxxxxxxxxwwwwwwwbbbbbbbbwwwwwwwwwwwwwwwbbbwwwww...........wwwwwxxxxxxxxxxxxx");
- strcpy(vgrid[12], "xxxxxxxxxxxxwwwwwbbbb......bbbwwwwwwwwwwww...bbwwwww.............wwwxxxxxxxxxxxx");
- strcpy(vgrid[13], "xxxxxxxxxxxxwwwbbb...........bbbwwwwww........bbwwwww.............wwxxxxxxxxxxxx");
- strcpy(vgrid[14], "xxxxxxxxxxxwwwbb...............bbwwww..........bwwwwww.............wwxxxxxxxxxxx");
- strcpy(vgrid[15], "xxxxxxxxxxxwwbb........1O.......bbww...........bbwwww..............wwxxxxxxxxxxx");
- strcpy(vgrid[16], "xxxxxxxxxxwwwb...................bw......2......bwww.....U....2.....wwxxxxxxxxxx");
- strcpy(vgrid[17], "xxxxxxxxxxwwbb...................bb.............bww.................wwxxxxxxxxxx");
- strcpy(vgrid[18], "xxxxxxxxxxwwbb..3................bbb............bbw..............4..wwxxxxxxxxxx");
- strcpy(vgrid[19], "xxxxxxxxxwwbbb...................b.b............4....................wwxxxxxxxxx");
- strcpy(vgrid[20], "xxxxxxxxxwwbwbb.................bb.......U......4..........U..........wxxxxxxxxx");
- strcpy(vgrid[21], "xxxxxxxxxwwbwwbb...............bb..b............bbw..............4.....xxxxxxxxx");
- strcpy(vgrid[22], "xxxxxxxxxwwbbwwbbb...........bbb..bb............bwww...................xxxxxxxxx");
- strcpy(vgrid[23], "xxxxxxxxxwwwbwwwwb..b..2..bbbb....b.............bwww...................xxxxxxxxx");
- strcpy(vgrid[24], "xxxxxxxxxxwwbwwww...bbbbbbb.......bw.....3.....bbwwww...U.....3.......xxxxxxxxxx");
- strcpy(vgrid[25], "xxxxxxxxxxwwbbww.................bbww........wwbwwwww.................xxxxxxxxxx");
- strcpy(vgrid[26], "xxxxxxxxxxwwwbbw................bbwwwww....wwwbbwwww..................xxxxxxxxxx");
- strcpy(vgrid[27], "xxxxxxxxxxwwwwbb...4...U........bwwwwwwwwwwwwbbwww....................xxxxxxxxxx");
- strcpy(vgrid[28], "xxxxxxxxxxxwwwwbbb...........bbbbbwwwwwwwwwbbbwww....................xxxxxxxxxxx");
- strcpy(vgrid[29], "xxxxxxxxxxxwwwwwwbbbb.....bbbbwwwbbbbwwwbbbbwwww....................xxxxxxxxxxxx");
- strcpy(vgrid[30], "xxxxxxxxxxxwwwwwwwwwbbbbbbbwwwwwwwwwbbbbbwwwww......4.....4........xxxxxxxxxxxxx");
- strcpy(vgrid[31], "xxxxxxxxxxxxwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww......................xxxxxxxxxxxxxx");
- strcpy(vgrid[32], "xxxxxxxxxxxxwwwwwwwwwwwwwwwwwwwwwwwwwwwww.......................xxxxxxxxxxxxxxxx");
- strcpy(vgrid[33], "xxxxxxxxxxxxxxwwwwwwwwwwwwwwwwwwwww........................xxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[34], "xxxxxxxxxxxxxxxxxxxxxxxxxwwwwwww......................xxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[35], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...@.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- mons_array[0] = MONS_LOM_LOBON;
- mons_array[1] = MONS_GIANT_ORANGE_BRAIN;
- mons_array[2] = MONS_RAKSHASA;
- mons_array[3] = MONS_WIZARD;
- mons_array[4] = RANDOM_MONSTER;
- mons_array[5] = RANDOM_MONSTER;
- mons_array[6] = RANDOM_MONSTER;
-
- return MAP_NORTH;
-}
-
-
-static char cerebov(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // you might not want to teleport too much on this level -
- // unless you can reliably teleport away again.
-
- for (unsigned char i = 0; i < 81; i++)
- strcpy(vgrid[i], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- strcat(vgrid[0], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[1], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[2], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[3], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[4], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[5], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[6], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[7], "...............................xxxxxxxxx");
- strcat(vgrid[8], ".............vvvvv.............xxxxxxxxx");
- strcat(vgrid[9], ".............v$$$v.............xxxxxxxxx");
- strcat(vgrid[10], ".............v|||v.............xxxxxxxxx");
- strcat(vgrid[11], ".............v$$$v.............xxxxxxxxx");
- strcat(vgrid[12], ".vvvvv...vvvvvvvvvvvvv...vvvvv.xxxxxxxxx");
- strcat(vgrid[13], ".v|$|vvvvv...........vvvvv$|$v.xxxxxxxxx");
- strcat(vgrid[14], ".v$|$v.....vvvvvvvvv.....v|$|v.xxxxxxxxx");
- strcat(vgrid[15], ".v|$|v.vvvvvvvvOvvvvvvvv.v$|$v.xxxxxxxxx");
- strcat(vgrid[16], ".vvvvv.vvvvvv..3..vvvvvv.vvvvv.xxxxxxxxx");
- strcat(vgrid[17], "...v...vv.....vvv.....vv...v...xxxxxxxxx");
- strcat(vgrid[18], "...v.vvvv....vv1vv....vvvv.v...xxxxxxxxx");
- strcat(vgrid[19], "...v.vv......v...v......vv.v...xxxxxxxxx");
- strcat(vgrid[20], "...v.vvvv.............vvvv.v...xxxxxxxxx");
- strcat(vgrid[21], "...v...vv..2.......2..vv...v...xxxxxxxxx");
- strcat(vgrid[22], ".vvvvv.vv..2.......2..vv.vvvvv.xxxxxxxxx");
- strcat(vgrid[23], ".v|$|v.vv.............vv.v$|$v.xxxxxxxxx");
- strcat(vgrid[24], ".v|$|v.vv...vv...vv...vv.v$|$v.xxxxxxxxx");
- strcat(vgrid[25], ".v|$|v.vv...vv+++vv...vv.v$|$v.xxxxxxxxx");
- strcat(vgrid[26], ".vvvvv.vvvvvvv...vvvvvvv.vvvvv.xxxxxxxxx");
- strcat(vgrid[27], "....v..vvvvvvv...vvvvvvv..v....xxxxxxxxx");
- strcat(vgrid[28], "....vv...................vv....xxxxxxxxx");
- strcat(vgrid[29], ".....vv.vvvvv..2..vvvvv.vv.....xxxxxxxxx");
- strcat(vgrid[30], "......vvv|||v.....v$$$vvv......xxxxxxxxx");
- strcat(vgrid[31], "........v|$|vv...vv$|$v........xxxxxxxxx");
- strcat(vgrid[32], "........v|||v.....v$$$v........xxxxxxxxx");
- strcat(vgrid[33], "........vvvvv.....vvvvv........xxxxxxxxx");
- strcat(vgrid[34], "...............................xxxxxxxxx");
- strcat(vgrid[35], "...............@...............xxxxxxxxx");
-
- mons_array[0] = MONS_CEREBOV;
- mons_array[1] = MONS_BALRUG;
- mons_array[2] = MONS_PIT_FIEND;
- mons_array[3] = RANDOM_MONSTER;
- mons_array[4] = RANDOM_MONSTER;
- mons_array[5] = RANDOM_MONSTER;
- mons_array[6] = RANDOM_MONSTER;
-
- return MAP_NORTHEAST;
-}
-
-
-static char gloorx_vloq(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
-
- for (unsigned char i = 0; i < 81; i++)
- strcpy(vgrid[i], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- strcpy(vgrid[36], "xxxxxxxxxxxxxxxxxxxxxxx@.xxxxxxxxxxxxxxx");
- strcpy(vgrid[37], "xxxxxxxxx..............................x");
- strcpy(vgrid[38], "xxxxxxxxx..............................x");
- strcpy(vgrid[39], "xxxxxxxxx..............................x");
- strcpy(vgrid[40], "xxxxxxxxx.x.x.x.x.x.x.x..x.x.x.x.x.x.x.x");
- strcpy(vgrid[41], "xxxxxxxxx..............................x");
- strcpy(vgrid[42], "xxxxxxxxx.x.xxxx=xxxxxxxxxxxx=xxxxxx.x.x");
- strcpy(vgrid[43], "xxxxxxxxx...xx....................xx...x");
- strcpy(vgrid[44], "xxxxxxxxx.x.x..ccccc..4..4..ccccc..x.x.x");
- strcpy(vgrid[45], "xxxxxxxxx...x.cc.3............3.cc.x...x");
- strcpy(vgrid[46], "xxxxxxxxx.x.x.c..ccccc.cc.ccccc..c.x.x.x");
- strcpy(vgrid[47], "xxxxxxxxx...x.c.cc.....cc.....cc.c.x...x");
- strcpy(vgrid[48], "xxxxxxxxx.x.x.c.c.2...cccc...2.c.c.x.x.x");
- strcpy(vgrid[49], "xxxxxxxxx...x...c...ccc..ccc...c...=...x");
- strcpy(vgrid[50], "xxxxxxxxx.x.x.3.....2..1O..2.....3.x.x.x");
- strcpy(vgrid[51], "xxxxxxxxx...=...c...ccc..ccc...c...x...x");
- strcpy(vgrid[52], "xxxxxxxxx.x.x.c.c.2...cccc...2.c.c.x.x.x");
- strcpy(vgrid[53], "xxxxxxxxx...x.c.cc.....cc.....cc.c.x...x");
- strcpy(vgrid[54], "xxxxxxxxx.x.x.c..ccccc.cc.ccccc..c.x.x.x");
- strcpy(vgrid[55], "xxxxxxxxx...x.cc.3............3.cc.x...x");
- strcpy(vgrid[56], "xxxxxxxxx.x.x..ccccc..4..4..ccccc..=.x.x");
- strcpy(vgrid[57], "xxxxxxxxx...xx....................xx...x");
- strcpy(vgrid[58], "xxxxxxxxx.x.xxxx=xxxx=xxxxxxxx=xxxxx.x.x");
- strcpy(vgrid[59], "xxxxxxxxx..............................x");
- strcpy(vgrid[60], "xxxxxxxxx.x.x.x.x.x.x.x..x.x.x.x.x.x.x.x");
- strcpy(vgrid[61], "xxxxxxxxx..............................x");
- strcpy(vgrid[62], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[63], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[64], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[65], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[66], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[67], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[68], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[69], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- mons_array[0] = MONS_GLOORX_VLOQ;
- mons_array[1] = MONS_EXECUTIONER;
- mons_array[2] = MONS_DEMONIC_CRAWLER;
- mons_array[3] = MONS_SHADOW_DEMON;
- mons_array[4] = RANDOM_MONSTER;
- mons_array[5] = RANDOM_MONSTER;
- mons_array[6] = RANDOM_MONSTER;
-
- return MAP_SOUTHWEST;
-}
-
-
-static char beehive(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
-
- strcpy(vgrid[0], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[1], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[2], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[3], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[4], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[5], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[6], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[7], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[8], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[9], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxaaaaaaaaaxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[10], "xxxxxxxxxxxxxxxxxxxxxxaaaaaaaaaaaRaaaaaaaaaxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[11], "xxxxxxxxxxxxxxxxxaaaaaaaaaaRa2aaR1RaaRa2aaaaaaxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[12], "xxxxxxxxxxxxxxxxxxaaaaaaaaaaRa2a3R3aRaRaRaaaaaaaaaxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[13], "xxxxxxxxxxxxxxxxxxxxxaaaaRaRaRaaa3aaa3aRa.a.aaaaaaaaaaaxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[14], "xxxxxxxxxxxxxxxxaaaaaaRa.aRa2a2a2a2aRaRa.a.a3aaaaaaaaaaaaaaxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[15], "xxxxxxxxxxxxx4aaaaaaaaa.aaRaRaa2aa2aaRaaa.aa3a33aaaaaaaaaa.44xxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[16], "xxxxxxxxxxx.4aaaaaaa.222a3a.aaaRaaa.aaa.R3aa3a3aaaaaaaa.....4xxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[17], "xxxxxxxxxx....aaaaaaa.aRa.a3aRaRa.a3a.a.a.a.aRa2aaaaaa....xxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[18], "xxxxxxxxxxx...aaaaaa3a3a.a.a.a3aRa2aRa3a.a.aRaRa.aaaaa...xxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[19], "xxxxxxxxxxxx...aa2aRa3a3a3aRa.a3a.a.a.a.a.a.a.a3a.aaa...xxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[20], "xxxxxxxxxxxx...aaa.a.a.a2a.aaa.aRaRa2a.a2a3a.a2aaaa..T..xxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[21], "xxxxxxxxxxx.....a2a.a2a.aRaaaaa3a.a.aaa3a3a3a3a.a.........xxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[22], "xxxxxxxxxxx.4...aaRRaa.a2a.a3a3a3a.aaa.a.aRa.a.aa..4.......xxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[23], "xxxxxxxxxx......a.a.aaa.a3a.a.a.a.aaa2a.a2a.a.aRaa.....4...xxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[24], "xxxxxxxxxx.....aa3a2aaa.a.a.a3a3a3a3aRaaa.a2a.a2aa........xxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[25], "xxxxxxxxxxx...aaaa.a2aRa.a.a2aaa.a.a.a.aaa.a.aaaa.....xxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[26], "xxxxxxxxxxxx..aaa.a.a.a.a.a.a.aaa2a.a3a2a.a2aaa.....xxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[27], "xxxxxxxxxxxxxx.aaaa3a.a2aRa.a.aaaRa.a.aa.a.aaa....xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[28], "xxxxxxxxxxxxxxx...aaaaRa.a3a3a.a.a.aaa.aa.aa....4xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[29], "xxxxxxxxxxxxx........aa.a2a.a.aaa2aa.aa.aaa....xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[30], "xxxxxxxxxxxxx....4.....a.a2a2a.a2a.a2a.......4.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[31], "xxxxxxxxxxx.............a.a.a.a.a.a.....4....xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[32], "xxxxxxxxxx..............4..a.a.a......4...xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[33], "xxxxxxxxxx.................a.a.........xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[34], "xxxxxxxxxxx........................xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[35], "xxxxxxxxxxx.....4...T............xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[36], "xxxxxxxxxxx.......................xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[37], "xxxxxxxxxxxx.........................xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[38], "xxxxxxxxxxxx.................T.........xxxxxxxx..xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[39], "xxxxxxxxxxxx.......4.....................xxxxxxx...xxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[40], "xxxxxxxxxxx..............xx...............xxxxxx....xxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[41], "xxxxxxxxxxx............xxxxx........4......xxxx..4....xxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[42], "xxxxxxxxxxx..T..........xxx................xxxxx...T.xxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[43], "xxxxxxxxxxx............xxx........T.........xxx........xxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[44], "xxxxxxxxxxx....4........xx....................x..........xxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[45], "xxxxxxxxxx...............x.x...xxx...............xx.xxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[46], "xxxxxxxxxx.........4...........xxx..................xxxxxxxxxxxxxxxxxxaaaaaxxxxx");
- strcpy(vgrid[47], "xxxxxxxxx.....4.....................4......4...........4...xxxxxxxxxxaa5a5aaxxxx");
- strcpy(vgrid[48], "xxxxxxxxx.................................................wwwwwwwwxxxa5*|*5axxxx");
- strcpy(vgrid[49], "xxxxxxxxx............x...x...T.....xxxx.................wwwwwwwwwwwwxaa*|*aaxxxx");
- strcpy(vgrid[50], "xxxxxxxxxx.........xx.............xxxxx................wwwwwwwwwwwwwwxaa5aaxxxxx");
- strcpy(vgrid[51], "xxxxxxxxxxx.......x..................xxx....4..........wwwwwwwwwwwwwwwxa5axxxxxx");
- strcpy(vgrid[52], "xxxxxxxxxxx.....xxx...4...........................xxxx.4wwwwwwwwwwwwwwwa=axxxxxx");
- strcpy(vgrid[53], "xxxxxxxxxxxx..xxx.............xx....(.........xxxxxxxx....wwwwwwwwwwwwwwaaxxxxxx");
- strcpy(vgrid[54], "xxxxxxxxxxxxxxxx.............xxxx..................xxxx......wwwwwwwwwwxxxxxxxxx");
- strcpy(vgrid[55], "xxxxxxxxxxxxxxxxx....{..}..xxxxxx..]......xxx...........4.wwwwwwwwwwwwxxxxxxxxxx");
- strcpy(vgrid[56], "xxxxxxxxxxxxxxxxxxxx........xxx........xxxxxx....4....wwwwwwwwwwwwwwxxxxxxxxxxxx");
- strcpy(vgrid[57], "xxxxxxxxxxxxxxxxxxxxxxxxx..[.xxx........xxx)....wwwwwwwwwwwwwwwwwwxxxxxxxxxxxxxx");
- strcpy(vgrid[58], "xxxxxxxxxxxxxxxxxxxxxxxxxxxx.........xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[59], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[60], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[61], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[62], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[63], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[64], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[65], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[66], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[67], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[68], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[69], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- mons_array[0] = MONS_QUEEN_BEE;
- mons_array[1] = MONS_KILLER_BEE;
- mons_array[2] = MONS_KILLER_BEE_LARVA;
- mons_array[3] = MONS_PLANT;
- mons_array[4] = MONS_YELLOW_WASP;
- mons_array[5] = RANDOM_MONSTER;
- mons_array[6] = RANDOM_MONSTER;
-
- return MAP_ENCOMPASS;
-}
-
-
-static char vaults_vault(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // last level of the vaults -- dungeon.cc will change all these 'x's
-
- strcpy(vgrid[0], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[1], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[2], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[3], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[4], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[5], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[6], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[7], "xxxxxxxxx..............................................................xxxxxxxxx");
- strcpy(vgrid[8], "xxxxxxxxx..............................................................xxxxxxxxx");
- strcpy(vgrid[9], "xxxxxxxxx..xxxxxxxxxxxxxxxxxxxxxxxxxxx....xxxxxxxxxxxxxxxxxxxxxxxxxxx..xxxxxxxxx");
- strcpy(vgrid[10], "xxxxxxxxx..x.........................x....xxxxxxxxxxxxxxxxxxxxxxxxxxx..xxxxxxxxx");
- strcpy(vgrid[11], "xxxxxxxxx..x.xxxxxxxxxxx..xxxxxxxxxx.x....xxxxx.................xxxxx..xxxxxxxxx");
- strcpy(vgrid[12], "xxxxxxxxx..x.x*.*.*.*.*x..x........x.x....xxx..........8..........xxx..xxxxxxxxx");
- strcpy(vgrid[13], "xxxxxxxxx..x.x.*.*.*.*.x..x........x.x....xxx.....................xxx..xxxxxxxxx");
- strcpy(vgrid[14], "xxxxxxxxx..x.x*.*.*.*.*x..x...||...x.x....xx......9........9.......xx..xxxxxxxxx");
- strcpy(vgrid[15], "xxxxxxxxx..x.x.*.*.*.*.x..x...||...x.x....xx.......................xx..xxxxxxxxx");
- strcpy(vgrid[16], "xxxxxxxxx..x.x*.*.*.*.*x..x...||...x.x....xx......xxxxxxxxxxx......xx..xxxxxxxxx");
- strcpy(vgrid[17], "xxxxxxxxx..x.x.*.*.*.*.x..x........x.x....xx......x.........x......xx..xxxxxxxxx");
- strcpy(vgrid[18], "xxxxxxxxx..x.x*.*.*.*.*+..+........x.x....xx....xxx..........xx....xx..xxxxxxxxx");
- strcpy(vgrid[19], "xxxxxxxxx..x.x.*.*.*.*.xxxxxxxxxxxxx.x....xx.9..x....xxxxx....x..8.xx..xxxxxxxxx");
- strcpy(vgrid[20], "xxxxxxxxx..x.xxxxxxxxxxx9998.........x....xx....x...xx$$$xx...x....xx..xxxxxxxxx");
- strcpy(vgrid[21], "xxxxxxxxx..x...........899xxxxxxxxxx.x....xx....x..xx$***$xx..x....xx..xxxxxxxxx");
- strcpy(vgrid[22], "xxxxxxxxx..x.xxxxxxxxxxx99x........x.x....xx....x..x$$*|*$$x..x....xx..xxxxxxxxx");
- strcpy(vgrid[23], "xxxxxxxxx..x.x.....|...x88x.$$$$$$.x.x....xx..8.x..xx$***$xx..x....xx..xxxxxxxxx");
- strcpy(vgrid[24], "xxxxxxxxx..x.x.|..|..|.x..x.$$$$$$.x.x....xx....x....x$$$xx...x..9.xx..xxxxxxxxx");
- strcpy(vgrid[25], "xxxxxxxxx..x.x.........x..x.$$$$$$.x.x....xx....xxx..xxxxx..xxx....xx..xxxxxxxxx");
- strcpy(vgrid[26], "xxxxxxxxx..x.x.|..|..|.x..x.$$$$$$.x.x....xx......x.........x......xx..xxxxxxxxx");
- strcpy(vgrid[27], "xxxxxxxxx..x.x.........x..x.$$$$$$.x.x....xx......xxxxxxxxxxx......xx..xxxxxxxxx");
- strcpy(vgrid[28], "xxxxxxxxx..x.x|..|..|..x..x.$$$$$$.x.x....xxx.....................xxx..xxxxxxxxx");
- strcpy(vgrid[29], "xxxxxxxxx..x.x.........x..+........x.x....xxx......9.........9....xxx..xxxxxxxxx");
- strcpy(vgrid[30], "xxxxxxxxx..x.xxxxxxxxx+x..xxxxxxxxxx.xx.11....xx................xxxxx..xxxxxxxxx");
- strcpy(vgrid[31], "xxxxxxxxx..x...........x..x...........x1111...xxxxxxxxxxxxxxxxxxxxxxx..xxxxxxxxx");
- strcpy(vgrid[32], "xxxxxxxxx..xxxxxxxxxxxxxxxxxxxxxxxxx..1....1..xxxxxxxxxxxxxxxxxxxxxxx..xxxxxxxxx");
- strcpy(vgrid[33], "xxxxxxxxx..........................xx1..(}..1..........................xxxxxxxxx");
- strcpy(vgrid[34], "xxxxxxxxx...........................11.[..{.11.........................xxxxxxxxx");
- strcpy(vgrid[35], "xxxxxxxxx............................1..])..1..........................xxxxxxxxx");
- strcpy(vgrid[36], "xxxxxxxxx.............................1....1...........................xxxxxxxxx");
- strcpy(vgrid[37], "xxxxxxxxx..xxxxxxxxxxxxxxxxxxxxxxx.....1111..x.xxx.xxxxxxxxxxxxxxxxxx..xxxxxxxxx");
- strcpy(vgrid[38], "xxxxxxxxx..xx.x.x.x.x.x.x.x.x.x.x.x.....11..........................x..xxxxxxxxx");
- strcpy(vgrid[39], "xxxxxxxxx..x.x.x.x.x.x.x.x|x.x.x.x.x................................x..xxxxxxxxx");
- strcpy(vgrid[40], "xxxxxxxxx..xx.x|x.x.x.x.x.x.x.x.x.x.x.....x.........................x..xxxxxxxxx");
- strcpy(vgrid[41], "xxxxxxxxx..x.x.x.x.x.x.x.x9x.x.x.x.x.x..........8..........9........x..xxxxxxxxx");
- strcpy(vgrid[42], "xxxxxxxxx..xx.x.x.x.x.x.x.x.x.x.x.x.xx....x..9......................x..xxxxxxxxx");
- strcpy(vgrid[43], "xxxxxxxxx..x.x.x.x.x.x.x.x.x.x|x.x.x.x....x.........................x..xxxxxxxxx");
- strcpy(vgrid[44], "xxxxxxxxx..xx.x8x.x.x|x.x.x.x.x.x.x.xx....x..............9...9......x..xxxxxxxxx");
- strcpy(vgrid[45], "xxxxxxxxx..x.x.x.x.x9x.x.x.x.x.x.x.x.x...........8..................x..xxxxxxxxx");
- strcpy(vgrid[46], "xxxxxxxxx..xx.x.x.x.x.x.x.x.x.x.x.x.xx....x..9......................x..xxxxxxxxx");
- strcpy(vgrid[47], "xxxxxxxxx..x.x.x.x.x.x.x.x.x|x.x9x.x.x....x.........................x..xxxxxxxxx");
- strcpy(vgrid[48], "xxxxxxxxx..xx.x.x.x.x.x.x.x.x.x.x.x.xx....x...................9.....x..xxxxxxxxx");
- strcpy(vgrid[49], "xxxxxxxxx..x.x.x9x.x.x.x.x.x.x.x.x.x.x....x....9......8.............x..xxxxxxxxx");
- strcpy(vgrid[50], "xxxxxxxxx..xx.x.x.x.x.x.x9x.x.x.x.x.xx....x.........................x..xxxxxxxxx");
- strcpy(vgrid[51], "xxxxxxxxx..x.x.x.x.x.x.x.x.x.x.x.x.x.x....x.........................x..xxxxxxxxx");
- strcpy(vgrid[52], "xxxxxxxxx..xx.x.x.x.x.x.x.x.x.x.x.x.xx....x.......9......9..........x..xxxxxxxxx");
- strcpy(vgrid[53], "xxxxxxxxx..x.x.x.x.x.x.x.x.x.x8x.x.x.x....x.....................8...x..xxxxxxxxx");
- strcpy(vgrid[54], "xxxxxxxxx..xx.x8x.x.x.x.x.x.x.x.x.x.xx....x.....................||.|x..xxxxxxxxx");
- strcpy(vgrid[55], "xxxxxxxxx..x.x|x.x.x.x.x.x.x|x.x.x.x.x....x.....................|...x..xxxxxxxxx");
- strcpy(vgrid[56], "xxxxxxxxx..xx.x.x.x.x.x.x8x.x.x.x.x.xx....x......8..................x..xxxxxxxxx");
- strcpy(vgrid[57], "xxxxxxxxx..x.x.x.x.x.x.x.x.x.x.x.x.x.x....x..........8..8...8.....||x..xxxxxxxxx");
- strcpy(vgrid[58], "xxxxxxxxx..xO.x.x.x.x.x.x.x.x.x.x|x.xx....x.....................|.||x..xxxxxxxxx");
- strcpy(vgrid[59], "xxxxxxxxx..xxxxxxxxxxxxxxxxxxxxxxxxxxx....xxxxxxxxxxxxxxxxxxxxxxxxxxx..xxxxxxxxx");
- strcpy(vgrid[60], "xxxxxxxxx..............................................................xxxxxxxxx");
- strcpy(vgrid[61], "xxxxxxxxx..............................................................xxxxxxxxx");
- strcpy(vgrid[62], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[63], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[64], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[65], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[66], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[67], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[68], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[69], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- mons_array[0] = MONS_VAULT_GUARD;
- mons_array[1] = RANDOM_MONSTER;
- mons_array[2] = RANDOM_MONSTER;
- mons_array[3] = RANDOM_MONSTER;
- mons_array[4] = RANDOM_MONSTER;
- mons_array[5] = RANDOM_MONSTER;
- mons_array[6] = RANDOM_MONSTER;
-
- return MAP_ENCOMPASS;
-}
-
-
-static char snake_pit(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // Hey, this looks a bit like a face ...
-
- for (unsigned char i = 0; i < 81; i++)
- strcpy(vgrid[i], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- strcpy(vgrid[36], "xxxxxxxxxxxxxxxxxxxxxxx..@.xxxxxxxxxxxxx");
- strcpy(vgrid[37], "xxxxxxxxxxxxxxxxxxx.............xxxxxxxx");
- strcpy(vgrid[38], "xxxxxxxxxxxxxx....x.............x..xxxxx");
- strcpy(vgrid[39], "xxxxxxxxxxxx....2.x.............x.2..xxx");
- strcpy(vgrid[40], "xxxxxxxxxxx.....2.x....x.....x..x..3.xxx");
- strcpy(vgrid[41], "xxxxxxxxxxx.....22x.............xx.2..xx");
- strcpy(vgrid[42], "xxxxxxxxxxx.......xx..x........xx..3..xx");
- strcpy(vgrid[43], "xxxxxxxxxx.....x23.xx....T...xxx.44...xx");
- strcpy(vgrid[44], "xxxxxxxxxx......4.4.x.........x.333....x");
- strcpy(vgrid[45], "xxxxxxxxxx......3.x4...x.......4x4.....x");
- strcpy(vgrid[46], "xxxxxxxxxx.......3.......x.............x");
- strcpy(vgrid[47], "xxxxxxxxxx..c......3.........x.......c.x");
- strcpy(vgrid[48], "xxxxxxxxx...cc...................3..cc.x");
- strcpy(vgrid[49], "xxxxxxxxx...cc..........4.4.........cc.x");
- strcpy(vgrid[50], "xxxxxxxxx...cc...3...x........2.....cc.x");
- strcpy(vgrid[51], "xxxxxxxxx...cc.........1...1.......cc..x");
- strcpy(vgrid[52], "xxxxxxxxxx..cc.....1.....1.....1..ccc.xx");
- strcpy(vgrid[53], "xxxxxxxxxx...ccc..................cc..xx");
- strcpy(vgrid[54], "xxxxxxxxxx....cccc....3333333.....cc..xx");
- strcpy(vgrid[55], "xxxxxxxxxx.....ccccccc...........cc...xx");
- strcpy(vgrid[56], "xxxxxxxxxx........cccccccO...ccccc....xx");
- strcpy(vgrid[57], "xxxxxxxxxxx........cccccccccccccc....xxx");
- strcpy(vgrid[58], "xxxxxxxxxxx.........cccccccccccc.....xxx");
- strcpy(vgrid[59], "xxxxxxxxxxxxx.......................xxxx");
- strcpy(vgrid[60], "xxxxxxxxxxxxxxxx..................xxxxxx");
- strcpy(vgrid[61], "xxxxxxxxxxxxxxxxxxxxx.......xxxxxxxxxxxx");
- strcpy(vgrid[62], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[63], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[64], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[65], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[66], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[67], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[68], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[69], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- mons_array[0] = MONS_GREATER_NAGA;
- mons_array[1] = MONS_NAGA;
- mons_array[2] = MONS_NAGA_MAGE;
- mons_array[3] = MONS_NAGA_WARRIOR;
- mons_array[4] = RANDOM_MONSTER;
- mons_array[5] = RANDOM_MONSTER;
- mons_array[6] = RANDOM_MONSTER;
-
- return MAP_SOUTHWEST;
-}
-
-
-static char elf_hall(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
-
- strcpy(vgrid[0], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[1], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[2], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[3], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[4], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[5], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[6], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[7], "xxxxxxxxxxxxxxxxxxcccccccccccccccccxxxxx");
- strcpy(vgrid[8], "xxxxxxxxxxxxxxxxxcc*|*|*|**|||||c$ccxxxx");
- strcpy(vgrid[9], "xxxxxxxxxxxxxxxxcc*$*|*|*|*|||||c$$ccxxx");
- strcpy(vgrid[10], "xxxxxxxxxxxxxxxcc*$|*$***$$|||||c|$$ccxx");
- strcpy(vgrid[11], "xxxxxxxxxxxxxxcc*$*|**ccccccccccc$$$$ccx");
- strcpy(vgrid[12], "xxxxxxxxxxxxxxc*|*$*$ccc.....2..c+$|$$cx");
- strcpy(vgrid[13], "xxxxxxxxxxxxxxc$*$*ccc...........c$$$$cx");
- strcpy(vgrid[14], "xxxxxxxxxxxxxxc||**cc...5.......4cc$|$cx");
- strcpy(vgrid[15], "xxxxxxxxxxxxxxc*$$cc........3..ccccccccx");
- strcpy(vgrid[16], "xxxxxxxxxxxxxxc$+ccc.....2....cc.....5cx");
- strcpy(vgrid[17], "xxxxxxxxxxxxxxc$c....5.......cc.......cx");
- strcpy(vgrid[18], "xxxxxxxxxxxxxxccc......5....cc..2....ccx");
- strcpy(vgrid[19], "xxxxxxxxxxxxxxxxc..........cc.......ccxx");
- strcpy(vgrid[20], "xxxxxxxxxxxxxxxcc..1..U..........4..ccxx");
- strcpy(vgrid[21], "xxxxxxxxxxxxxxcc.....................ccx");
- strcpy(vgrid[22], "xxxxxxxxxxxxxxc...........3...........cx");
- strcpy(vgrid[23], "xxxxxxxxxxxxxxc.......2.......3.......cx");
- strcpy(vgrid[24], "xxxxxxxxxxxxxxc..2................2..5cx");
- strcpy(vgrid[25], "xxxxxxxxxxxxxxc......x.........x......cx");
- strcpy(vgrid[26], "xxxxxxxxxxxxxxc.....xx.........xx.....cx");
- strcpy(vgrid[27], "xxxxxxxxxxxxxxc2...xxx....1....xxx.4..cx");
- strcpy(vgrid[28], "xxxxxxxxxxxxxxc..xxxx...........xxxx..cx");
- strcpy(vgrid[29], "xxxxxxxxxxxxxxc.xxx.....cc.cc.....xxx.cx");
- strcpy(vgrid[30], "xxxxxxxxxxxxxxc.x.....cccc.cccc.....x.cx");
- strcpy(vgrid[31], "xxxxxxxxxxxxxxc.3...cccxxc.cxxccc.3...cx");
- strcpy(vgrid[32], "xxxxxxxxxxxxxxc...cccxxxxc.cxxxxccc...cx");
- strcpy(vgrid[33], "xxxxxxxxxxxxxxc.cccxxxxxxc.cxxxxxxccc.cx");
- strcpy(vgrid[34], "xxxxxxxxxxxxxxcccxxxxxxxxc.cxxxxxxxxcccx");
- strcpy(vgrid[35], "xxxxxxxxxxxxxxxxxxxxxxxxxx@xxxxxxxxxxxxx");
-
- mons_array[0] = MONS_DEEP_ELF_HIGH_PRIEST;
- mons_array[1] = MONS_DEEP_ELF_DEMONOLOGIST;
- mons_array[2] = MONS_DEEP_ELF_ANNIHILATOR;
- mons_array[3] = MONS_DEEP_ELF_SORCERER;
- mons_array[4] = MONS_DEEP_ELF_DEATH_MAGE;
- mons_array[5] = RANDOM_MONSTER;
- mons_array[6] = RANDOM_MONSTER;
-
- return MAP_NORTHWEST;
-}
-
-
-// Slime pit take is reduced pending an increase in difficulty
-// of this subdungeon. -- bwr
-static char slime_pit(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
-
- strcpy(vgrid[0], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[1], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[2], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[3], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[4], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[5], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[6], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[7], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx....xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[8], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx..xxxx.........xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[9], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx....................xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[10], "xxxxxxxxxxxxxxxxxxxxxxxxxxxx......................xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[11], "xxxxxxxxxxxxxxxxxxxxxxxxxx..........................x.xxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[12], "xxxxxxxxxxxxxxxxxxxxxxxxxx............................xxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[13], "xxxxxxxxxxxxxxxxxxxxxxxxx.............................xxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[14], "xxxxxxxxxxxxxxxxxxxxxxxx.................................xxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[15], "xxxxxxxxxxxxxxxxxxxxxxxx..................................xxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[16], "xxxxxxxxxxxxxxxxxxxxxx....(................................xxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[17], "xxxxxxxxxxxxxxxxxxxxxx......................................xxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[18], "xxxxxxxxxxxxxxxxxxx..........................................xxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[19], "xxxxxxxxxxxxxxxxxxx..........................................xxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[20], "xxxxxxxxxxxxxxxxx............................................xxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[21], "xxxxxxxxxxxxxxxxx............................................xxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[22], "xxxxxxxxxxxxxx.....................ccc..ccc............]......xxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[23], "xxxxxxxxxxxxxxx...................cccc2ccccc...................xxxxxxxxxxxxxxxxx");
- strcpy(vgrid[24], "xxxxxxxxxxxxxx...................cc*cc..cc*cc....................xxxxxxxxxxxxxxx");
- strcpy(vgrid[25], "xxxxxxxxxxxxxx..................cc***cc4c***cc..................xxxxxxxxxxxxxxxx");
- strcpy(vgrid[26], "xxxxxxxxxxxxx..................cc*|*cc..cc*|*cc..................xxxxxxxxxxxxxxx");
- strcpy(vgrid[27], "xxxxxxxxxxxxx.................cc*|P|*c4cc*|P|*cc.................xxxxxxxxxxxxxxx");
- strcpy(vgrid[28], "xxxxxxxxxxxxx.................cc**|*cc..cc*|**cc....................xxxxxxxxxxxx");
- strcpy(vgrid[29], "xxxxxxxxxxxx..................ccc**c|cc4c|c**ccc...................xxxxxxxxxxxxx");
- strcpy(vgrid[30], "xxxxxxxxxxxx..................cccccccc..cccccccc....................xxxxxxxxxxxx");
- strcpy(vgrid[31], "xxxxxxxxxxx...................c.4.c.4.1..4.c.4.c.....................xxxxxxxxxxx");
- strcpy(vgrid[32], "xxxxxxxxxxx...................2.c.4.c..3.c.4.c.2.....................xxxxxxxxxxx");
- strcpy(vgrid[33], "xxxxxxxxxxx..........)........cccccccc..cccccccc.....................xxxxxxxxxxx");
- strcpy(vgrid[34], "xxxxxxxxxxx...................ccc**c|cc4c|c**ccc.....................xxxxxxxxxxx");
- strcpy(vgrid[35], "xxxxxxxxxx....................cc**|*cc..cc*|**cc....................xxxxxxxxxxxx");
- strcpy(vgrid[36], "xxxxxxxxxx....................cc*|P|*c4cc*|P|*cc....................xxxxxxxxxxxx");
- strcpy(vgrid[37], "xxxxxxxxxx.....................cc*|*cc..cc*|*cc....................xxxxxxxxxxxxx");
- strcpy(vgrid[38], "xxxxxxxxxxx.....................cc***cc4c***cc.....................xxxxxxxxxxxxx");
- strcpy(vgrid[39], "xxxxxxxxxxxx.....................cc*cc..cc*cc......................xxxxxxxxxxxxx");
- strcpy(vgrid[40], "xxxxxxxxxxxxx.....................cccc2ccccc......................xxxxxxxxxxxxxx");
- strcpy(vgrid[41], "xxxxxxxxxxxxxx.....................ccc..ccc.......................xxxxxxxxxxxxxx");
- strcpy(vgrid[42], "xxxxxxxxxxxxxx...........................................[.........xxxxxxxxxxxxx");
- strcpy(vgrid[43], "xxxxxxxxxxxxx......................................................xxxxxxxxxxxxx");
- strcpy(vgrid[44], "xxxxxxxxxxxxx..............................................xxxxx...xxxxxxxxxxxxx");
- strcpy(vgrid[45], "xxxxxxxxxxxxxx...........................................xxxxxxxx.xxxxxxxxxxxxxx");
- strcpy(vgrid[46], "xxxxxxxxxxxxxx..........................................xxxxxxxxx.xxxxxxxxxxxxxx");
- strcpy(vgrid[47], "xxxxxxxxxxxxxxxx........................................xxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[48], "xxxxxxxxxxxxxxxx.........................................xxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[49], "xxxxxxxxxxxxxxxxxx.......................................xxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[50], "xxxxxxxxxxxxxxxxxxxx......................................xxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[51], "xxxxxxxxxxxxxxxxxxxx......................................xxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[52], "xxxxxxxxxxxxxxxxxxxxx.....................................xxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[53], "xxxxxxxxxxxxxxxxxxxxx.............................}......xxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[54], "xxxxxxxxxxxxxxxxxxxxxxx.................................xxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[55], "xxxxxxxxxxxxxxxxxxxxxxxx..............................xxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[56], "xxxxxxxxxxxxxxxxxxxxxxxxx..............................xxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[57], "xxxxxxxxxxxxxxxxxxxxxxxxxx............................xxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[58], "xxxxxxxxxxxxxxxxxxxxxxxxxxxx...........{........xxx..xxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[59], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx................xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[60], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.........xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[61], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[62], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[63], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[64], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[65], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[66], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[67], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[68], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[69], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- mons_array[0] = MONS_ROYAL_JELLY;
- mons_array[1] = MONS_ACID_BLOB;
- mons_array[2] = MONS_GREAT_ORB_OF_EYES;
- mons_array[3] = RANDOM_MONSTER;
- mons_array[4] = RANDOM_MONSTER;
- mons_array[5] = RANDOM_MONSTER;
- mons_array[6] = RANDOM_MONSTER;
-
- return MAP_ENCOMPASS;
-
-}
-
-
-static char hall_of_blades(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
-
- strcpy(vgrid[0], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[1], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[2], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[3], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[4], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[5], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[6], "xxxxxxxxccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccxxxxxxxx");
- strcpy(vgrid[7], "xxxxxxxxccc....cccc.cccc.cccc.cccc.cccc.cccc.cccc.cccc.cccc.cccc.....cccxxxxxxxx");
- strcpy(vgrid[8], "xxxxxxxxcc......cc...cc...cc...cc...cc...cc...cc...cc...cc...cc.......ccxxxxxxxx");
- strcpy(vgrid[9], "xxxxxxxxc..............................................................cxxxxxxxx");
- strcpy(vgrid[10], "xxxxxxxxc..........c..............c..............c..............c......cxxxxxxxx");
- strcpy(vgrid[11], "xxxxxxxxc.........ccc............ccc............ccc............ccc.....cxxxxxxxx");
- strcpy(vgrid[12], "xxxxxxxxc........ccccc..........ccccc..........ccccc..........ccccc....cxxxxxxxx");
- strcpy(vgrid[13], "xxxxxxxxc.........ccc............ccc............ccc...........ccccc....cxxxxxxxx");
- strcpy(vgrid[14], "xxxxxxxxc..........c..............c..............c.............ccc.....cxxxxxxxx");
- strcpy(vgrid[15], "xxxxxxxxc......................................................ccc.....cxxxxxxxx");
- strcpy(vgrid[16], "xxxxxxxxc.......................................................c......cxxxxxxxx");
- strcpy(vgrid[17], "xxxxxxxxc..............................................................cxxxxxxxx");
- strcpy(vgrid[18], "xxxxxxxxc..............................................................cxxxxxxxx");
- strcpy(vgrid[19], "xxxxxxxxc..............................................................cxxxxxxxx");
- strcpy(vgrid[20], "xxxxxxxxc..............................................................cxxxxxxxx");
- strcpy(vgrid[21], "xxxxxxxxc..............................................................cxxxxxxxx");
- strcpy(vgrid[22], "xxxxxxxxc..............................................................cxxxxxxxx");
- strcpy(vgrid[23], "xxxxxxxxc.......................................................c......cxxxxxxxx");
- strcpy(vgrid[24], "xxxxxxxxc......................................................ccc.....cxxxxxxxx");
- strcpy(vgrid[25], "xxxxxxxxc..........c..............c..............c.............ccc.....cxxxxxxxx");
- strcpy(vgrid[26], "xxxxxxxxc.........ccc............ccc............ccc...........ccccc....cxxxxxxxx");
- strcpy(vgrid[27], "xxxxxxxxc........ccccc..........ccccc..........ccccc..........ccccc....cxxxxxxxx");
- strcpy(vgrid[28], "xxxxxxxxc.........ccc............ccc............ccc............ccc.....cxxxxxxxx");
- strcpy(vgrid[29], "xxxxxxxxc..........c..............c..............c..............c......cxxxxxxxx");
- strcpy(vgrid[30], "xxxxxxxxc..............................................................cxxxxxxxx");
- strcpy(vgrid[31], "xxxxxxxxc.......cc...cc...cc...cc...cc...cc...cc...cc...cc...cc.......ccxxxxxxxx");
- strcpy(vgrid[32], "xxxxxxxxcc.....cccc.cccc.cccc.cccc.cccc.cccc.cccc.cccc.cccc.cccc.....cccxxxxxxxx");
- strcpy(vgrid[33], "xxxxxxxxccc...ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccxxxxxxxx");
- strcpy(vgrid[34], "xxxxxxxxcccc.............................cccccccccccccccccccccccccccccccxxxxxxxx");
- strcpy(vgrid[35], "xxxxxxxxcccccccccccccccccccccccccccccc.@.cccccccccccccccccccccccccccccccxxxxxxxx");
-
- mons_array[0] = MONS_DANCING_WEAPON;
- mons_array[1] = RANDOM_MONSTER;
- mons_array[2] = RANDOM_MONSTER;
- mons_array[3] = RANDOM_MONSTER;
- mons_array[4] = RANDOM_MONSTER;
- mons_array[5] = RANDOM_MONSTER;
- mons_array[6] = RANDOM_MONSTER;
-
- return MAP_NORTH;
-}
-
-
-static char hall_of_Zot(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
-
- strcpy(vgrid[0], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[1], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[2], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[3], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[4], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[5], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[6], "xxxxxxxxxxxxxxccccccccccccccccxxxxxxxxxxxxxxxxxxxxxxxccccccccccccccxxxxxxxxxxxxx");
- strcpy(vgrid[7], "xxxxxxxxxxxcccc..............ccccxxxxxxxxxxxxxxxxxcccc............ccccxxxxxxxxxx");
- strcpy(vgrid[8], "xxxxxxxxxxcc....................cccxxxxxxxxxxxxxccc..................ccxxxxxxxxx");
- strcpy(vgrid[9], "xxxxxxxxxcc...........3...........ccxxxxxxxxxxxcc...........3.........ccxxxxxxxx");
- strcpy(vgrid[10], "xxxxxxxxxc..8......................cXXXXXXXXXXXc....................8..cxxxxxxxx");
- strcpy(vgrid[11], "xxxxxxxxxc...................8.....XXX...1...XXX....8..................cxxxxxxxx");
- strcpy(vgrid[12], "xxxxxxxxxcc........................XX..1...1..XX......................ccxxxxxxxx");
- strcpy(vgrid[13], "xxxxxxxxxxcc.......................X1.........1X.....................ccxxxxxxxxx");
- strcpy(vgrid[14], "xxxxxxxxxxxcc.....4....2..............1..Z..1............2....4.....ccxxxxxxxxxx");
- strcpy(vgrid[15], "xxxxxxxxxxcc.......................X1.........1X.....................ccxxxxxxxxx");
- strcpy(vgrid[16], "xxxxxxxxxcc........................XX..1...1..XX......................ccxxxxxxxx");
- strcpy(vgrid[17], "xxxxxxxxxc...................8.....XXX...1...XXX....8..................cxxxxxxxx");
- strcpy(vgrid[18], "xxxxxxxxxc...8.....................cXXXXXXXXXXXc...................8...cxxxxxxxx");
- strcpy(vgrid[19], "xxxxxxxxxcc..........8............ccccccccccccccc..........8..........ccxxxxxxxx");
- strcpy(vgrid[20], "xxxxxxxxxxcc....................ccccccccccccccccccc..................ccxxxxxxxxx");
- strcpy(vgrid[21], "xxxxxxxxxxxcc................ccccccccccccccccccccccccc..............ccxxxxxxxxxx");
- strcpy(vgrid[22], "xxxxxxxxxxxxccF111FcccccccccccccccccccccccccccccccccccccccccccF111Fccxxxxxxxxxxx");
- strcpy(vgrid[23], "xxxxxxxxxxxcc................^^1.ccccccccccccccccc.1^^..............ccxxxxxxxxxx");
- strcpy(vgrid[24], "xxxxxxxxxxcc.................cc1...ccccccccccccc...1cc...............ccxxxxxxxxx");
- strcpy(vgrid[25], "xxxxxxxxxcc.............8.....ccc...ccccccccccc...ccc...8.............ccxxxxxxxx");
- strcpy(vgrid[26], "xxxxxxxxxc....8................ccc...............ccc...........8...8...cxxxxxxxx");
- strcpy(vgrid[27], "xxxxxxxxxc.......8.....8...8...cxcc.............ccxc...................cxxxxxxxx");
- strcpy(vgrid[28], "xxxxxxxxxc.....................cxxc.............cxxc.......8...........cxxxxxxxx");
- strcpy(vgrid[29], "xxxxxxxxxc.....................cxxcc.1...1...1.ccxxc............8....8.cxxxxxxxx");
- strcpy(vgrid[30], "xxxxxxxxxc.......8....8.....8..cxxxc...........cxxxc....8..............cxxxxxxxx");
- strcpy(vgrid[31], "xxxxxxxxxc.....................cxxcc...........ccxxc..........8........cxxxxxxxx");
- strcpy(vgrid[32], "xxxxxxxxxcc...5...............ccxxc.............cxxcc..............8..ccxxxxxxxx");
- strcpy(vgrid[33], "xxxxxxxxxxcc........8........ccxxcc.............ccxxcc....8....5.....ccxxxxxxxxx");
- strcpy(vgrid[34], "xxxxxxxxxxxcc...............ccxxxc...............cxxxcc.............ccxxxxxxxxxx");
- strcpy(vgrid[35], "xxxxxxxxxxxxcccccccccccccccccxxxxcccccccc@ccccccccxxxxcccccccccccccccxxxxxxxxxxx");
-
- mons_array[0] = MONS_ORB_GUARDIAN;
- mons_array[1] = MONS_KILLER_KLOWN;
- mons_array[2] = MONS_ELECTRIC_GOLEM;
- mons_array[3] = MONS_ORB_OF_FIRE;
- mons_array[4] = MONS_ANCIENT_LICH;
- mons_array[5] = RANDOM_MONSTER;
- mons_array[6] = RANDOM_MONSTER;
-
- return MAP_NORTH;
-}
-
-
-static char temple(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // this is the ecumenical temple level
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[1], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[2], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[3], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[4], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[5], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[6], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[7], "xxxxxxxxxxxxxxxxxxxxxxxxxxccccccccccccccccccccccccccxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[8], "xxxxxxxxxxxxxxxxxxxxxxxxxcc............<............cxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[9], "xxxxxxxxxxxxxxxxxxxxxxxxcc...........................cxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[10], "xxxxxxxxxxxxxxxxxxxxxxxcc.............................cxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[11], "xxxxxxxxxxxxxxxxxxxxxxcc...............................cxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[12], "xxxxxxxxxxxxxxxxxxxxxcc.................................cxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[13], "xxxxxxxxxxxxxxxxxxxxcc...................................cxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[14], "xxxxxxxxxxxxxxxxxxxcc.....................................cxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[15], "xxxxxxxxxxxxxxxxxxcc.......................................cxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[16], "xxxxxxxxxxxxxxxxxcc.........................................cxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[17], "xxxxxxxxxxxxxxxxcc...........................................cxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[18], "xxxxxxxxxxxxxxxcc.............................................cxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[19], "xxxxxxxxxxxxxxcc...............................................cxxxxxxxxxxxxxxxx");
- strcpy(vgrid[20], "xxxxxxxxxxxxxcc.................................................cxxxxxxxxxxxxxxx");
- strcpy(vgrid[21], "xxxxxxxxxxxxcc...................................................cxxxxxxxxxxxxxx");
- strcpy(vgrid[22], "xxxxxxxxxxxcc..........................B..........................cxxxxxxxxxxxxx");
- strcpy(vgrid[23], "xxxxxxxxxxcc.......................................................cxxxxxxxxxxxx");
- strcpy(vgrid[24], "xxxxxxxxxcc.....................B.............B.....................cxxxxxxxxxxx");
- strcpy(vgrid[25], "xxxxxxxxcc...........................................................cxxxxxxxxxx");
- strcpy(vgrid[26], "xxxxxxxxc.............................................................cxxxxxxxxx");
- strcpy(vgrid[27], "xxxxxxxxc.............................................................cxxxxxxxxx");
- strcpy(vgrid[28], "xxxxxxxxc.................B.........................B.................cxxxxxxxxx");
- strcpy(vgrid[29], "xxxxxxxxc..............................T..............................cxxxxxxxxx");
- strcpy(vgrid[30], "xxxxxxxxc.............................................................cxxxxxxxxx");
- strcpy(vgrid[31], "xxxxxxxxc.............................................................cxxxxxxxxx");
- strcpy(vgrid[32], "xxxxxxxxc.............................................................cxxxxxxxxx");
- strcpy(vgrid[33], "xxxxxxxxc.............................................................cxxxxxxxxx");
- strcpy(vgrid[34], "xxxxxxxxc.............................................................cxxxxxxxxx");
- strcpy(vgrid[35], "xxxxxxxxc..............B...............................B..............cxxxxxxxxx");
- strcpy(vgrid[36], "xxxxxxxxc(....................T.................T....................{cxxxxxxxxx");
- strcpy(vgrid[37], "xxxxxxxxc.............................................................cxxxxxxxxx");
- strcpy(vgrid[38], "xxxxxxxxc.............................................................cxxxxxxxxx");
- strcpy(vgrid[39], "xxxxxxxxc.............................................................cxxxxxxxxx");
- strcpy(vgrid[40], "xxxxxxxxc.............................................................cxxxxxxxxx");
- strcpy(vgrid[41], "xxxxxxxxc.............................................................cxxxxxxxxx");
- strcpy(vgrid[42], "xxxxxxxxc.............................................................cxxxxxxxxx");
- strcpy(vgrid[43], "xxxxxxxxc................B...........................B................cxxxxxxxxx");
- strcpy(vgrid[44], "xxxxxxxxcc...........................................................ccxxxxxxxxx");
- strcpy(vgrid[45], "xxxxxxxxxcc............................T............................ccxxxxxxxxxx");
- strcpy(vgrid[46], "xxxxxxxxxxcc.......................................................ccxxxxxxxxxxx");
- strcpy(vgrid[47], "xxxxxxxxxxxcc.....................................................ccxxxxxxxxxxxx");
- strcpy(vgrid[48], "xxxxxxxxxxxxcc...................................................ccxxxxxxxxxxxxx");
- strcpy(vgrid[49], "xxxxxxxxxxxxxcc.................................................ccxxxxxxxxxxxxxx");
- strcpy(vgrid[50], "xxxxxxxxxxxxxxcc...............B................B..............ccxxxxxxxxxxxxxxx");
- strcpy(vgrid[51], "xxxxxxxxxxxxxxxcc.............................................ccxxxxxxxxxxxxxxxx");
- strcpy(vgrid[52], "xxxxxxxxxxxxxxxxcc.....................B.....................ccxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[53], "xxxxxxxxxxxxxxxxxcc.........................................ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[54], "xxxxxxxxxxxxxxxxxxcc.......................................ccxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[55], "xxxxxxxxxxxxxxxxxxxcc.....................................ccxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[56], "xxxxxxxxxxxxxxxxxxxxcc...................................ccxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[57], "xxxxxxxxxxxxxxxxxxxxxcc.................................ccxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[58], "xxxxxxxxxxxxxxxxxxxxxxcc...............................ccxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[59], "xxxxxxxxxxxxxxxxxxxxxxxcc.............................ccxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[60], "xxxxxxxxxxxxxxxxxxxxxxxxcc...........................ccxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[61], "xxxxxxxxxxxxxxxxxxxxxxxxxcc............[............ccxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[62], "xxxxxxxxxxxxxxxxxxxxxxxxxxcccccccccccccccccccccccccccxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[63], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[64], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[65], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[66], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[67], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[68], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[69], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- return MAP_ENCOMPASS;
-}
-
-
-static char tomb_1(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
-
- strcpy(vgrid[0], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[1], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[2], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[3], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[4], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[5], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[6], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[7], "xxxxxxxxx(.............................[..............................{xxxxxxxxx");
- strcpy(vgrid[8], "xxxxxxxxx..............................................................xxxxxxxxx");
- strcpy(vgrid[9], "xxxxxxxxx..............................................................xxxxxxxxx");
- strcpy(vgrid[10], "xxxxxxxxx..............................................................xxxxxxxxx");
- strcpy(vgrid[11], "xxxxxxxxx..............................................................xxxxxxxxx");
- strcpy(vgrid[12], "xxxxxxxxx..........ccccccccccccccccccccccccccccccccccccccccccc.........xxxxxxxxx");
- strcpy(vgrid[13], "xxxxxxxxx..........ccccccccccccccccccccccccccccccccccccccccccc.........xxxxxxxxx");
- strcpy(vgrid[14], "xxxxxxxxx..........cc..........................^............cc.........xxxxxxxxx");
- strcpy(vgrid[15], "xxxxxxxxx..........cc.........^....................^........cc.........xxxxxxxxx");
- strcpy(vgrid[16], "xxxxxxxxx..........cc..ccccccccccccccccccccccccccccccccccc..cc.........xxxxxxxxx");
- strcpy(vgrid[17], "xxxxxxxxx..........cc..c....^....^..c................c.^)c..cc.........xxxxxxxxx");
- strcpy(vgrid[18], "xxxxxxxxx..........cc..c..ccccccccc.c..3.............c.^.c..cc.........xxxxxxxxx");
- strcpy(vgrid[19], "xxxxxxxxx..........cc..c..c222c111c.c...............5c..^c..cc.........xxxxxxxxx");
- strcpy(vgrid[20], "xxxxxxxxx..........cc..c..c2c222c.^.c......2.........+cccc..cc.........xxxxxxxxx");
- strcpy(vgrid[21], "xxxxxxxxx..........cc..c..ccccccccccc..........3......5..c.^cc.........xxxxxxxxx");
- strcpy(vgrid[22], "xxxxxxxxx..........cc..c.................................c..cc.........xxxxxxxxx");
- strcpy(vgrid[23], "xxxxxxxxx..........cc..c..........................3......c..cc.........xxxxxxxxx");
- strcpy(vgrid[24], "xxxxxxxxx..........cc^.cccccccccccccc.......2............c..cc.........xxxxxxxxx");
- strcpy(vgrid[25], "xxxxxxxxx..........cc..c............c....................c..cc.........xxxxxxxxx");
- strcpy(vgrid[26], "xxxxxxxxx..........cc..c............c.................3..c..cc.........xxxxxxxxx");
- strcpy(vgrid[27], "xxxxxxxxx..........cc..c..cccccccc..c..........2.........c^5cc.........xxxxxxxxx");
- strcpy(vgrid[28], "xxxxxxxxx..........cc..c..c.^.c11c..c....................c..cc.........xxxxxxxxx");
- strcpy(vgrid[29], "xxxxxxxxx..........cc..c..c.c.c11c..c...3................c..cc.........xxxxxxxxx");
- strcpy(vgrid[30], "xxxxxxxxx..........cc..c..c^c.11cc..c..............2.....c..cc.........xxxxxxxxx");
- strcpy(vgrid[31], "xxxxxxxxx..........cc..c..c.cccccc..c.......2............c..cc.........xxxxxxxxx");
- strcpy(vgrid[32], "xxxxxxxxx..........cc..c..c..^..^...c.................2..c..cc.........xxxxxxxxx");
- strcpy(vgrid[33], "xxxxxxxxx..........cc5^c..ccccccccccc....................c..cc.........xxxxxxxxx");
- strcpy(vgrid[34], "xxxxxxxxx..........cc..c.................................c..cc.........xxxxxxxxx");
- strcpy(vgrid[35], "xxxxxxxxx..........cc..c.................................c..cc.........xxxxxxxxx");
- strcpy(vgrid[36], "xxxxxxxxx..........cc..cccccccccccccc..^.^..cccccccccccccc..cc.........xxxxxxxxx");
- strcpy(vgrid[37], "xxxxxxxxx..........cc..c...........ccc+++++ccc........^..c.^cc.........xxxxxxxxx");
- strcpy(vgrid[38], "xxxxxxxxx..........cc..c.^.....^...cc.2...2.cc......^....c..cc.........xxxxxxxxx");
- strcpy(vgrid[39], "xxxxxxxxx..........cc..c..ccccccc..cc.F...F.cc..ccccccc..c..cc.........xxxxxxxxx");
- strcpy(vgrid[40], "xxxxxxxxx..........cc..c..cc.322c..cc.......cc..c22..cc..c..cc.........xxxxxxxxx");
- strcpy(vgrid[41], "xxxxxxxxx..........cc..c..c].c22c..cc.......cc..c22c.}c^.c..cc.........xxxxxxxxx");
- strcpy(vgrid[42], "xxxxxxxxx..........cc..c..cccc..c.^cc.G...G.cc..c3.cccc..c..cc.........xxxxxxxxx");
- strcpy(vgrid[43], "xxxxxxxxx..........cc..c.....^..c..cc.......cc.^c........c..cc.........xxxxxxxxx");
- strcpy(vgrid[44], "xxxxxxxxx..........cc..c........c..cc.......cc..c....^...c..cc.........xxxxxxxxx");
- strcpy(vgrid[45], "xxxxxxxxx..........cc^.cccccccccc..cc.G...G.cc..cccccccccc.^cc.........xxxxxxxxx");
- strcpy(vgrid[46], "xxxxxxxxx..........cc......^.......cc.......cc..........^...cc.........xxxxxxxxx");
- strcpy(vgrid[47], "xxxxxxxxx..........cc...........^..cc.......cc.....^........cc.........xxxxxxxxx");
- strcpy(vgrid[48], "xxxxxxxxx..........cccccccccccccccccc.G...G.cccccccccccccccccc.........xxxxxxxxx");
- strcpy(vgrid[49], "xxxxxxxxx..........cccccccccccccccccc.......cccccccccccccccccc.........xxxxxxxxx");
- strcpy(vgrid[50], "xxxxxxxxx..............................................................xxxxxxxxx");
- strcpy(vgrid[51], "xxxxxxxxx.............................G...G............................xxxxxxxxx");
- strcpy(vgrid[52], "xxxxxxxxx...........................4.......4..........................xxxxxxxxx");
- strcpy(vgrid[53], "xxxxxxxxx..............................................................xxxxxxxxx");
- strcpy(vgrid[54], "xxxxxxxxx..............................................................xxxxxxxxx");
- strcpy(vgrid[55], "xxxxxxxxx...........................4..V.V..4..........................xxxxxxxxx");
- strcpy(vgrid[56], "xxxxxxxxx..............................................................xxxxxxxxx");
- strcpy(vgrid[57], "xxxxxxxxx..............................................................xxxxxxxxx");
- strcpy(vgrid[58], "xxxxxxxxx..............................................................xxxxxxxxx");
- strcpy(vgrid[59], "xxxxxxxxx...........................4.......4..........................xxxxxxxxx");
- strcpy(vgrid[60], "xxxxxxxxx..............................................................xxxxxxxxx");
- strcpy(vgrid[61], "xxxxxxxxx..............................................................xxxxxxxxx");
- strcpy(vgrid[62], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[63], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[64], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[65], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[66], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[67], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[68], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[69], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- mons_array[0] = MONS_MUMMY;
- mons_array[1] = MONS_GUARDIAN_MUMMY;
- mons_array[2] = MONS_MUMMY_PRIEST;
- mons_array[3] = MONS_SPHINX;
- mons_array[4] = MONS_GREATER_MUMMY;
- mons_array[5] = RANDOM_MONSTER;
- mons_array[6] = RANDOM_MONSTER;
-
- return MAP_ENCOMPASS;
-}
-
-
-static char tomb_2(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
-
- strcpy(vgrid[0], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[1], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[2], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[3], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[4], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[5], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[6], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[7], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[8], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[9], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[10], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[11], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[12], "xxxxxxxxxxxxxxxxxxxcccccccccccccccccccccccccccccccccccccccccccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[13], "xxxxxxxxxxxxxxxxxxxcccccccccccccccccccccccccccccccccccccccccccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[14], "xxxxxxxxxxxxxxxxxxxcc{...c......c.....3....c........c.......ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[15], "xxxxxxxxxxxxxxxxxxxcc....c.....^c^........^c......2^c.......ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[16], "xxxxxxxxxxxxxxxxxxxcc....c...2.^+..2.....2^+^..2....+.......ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[17], "xxxxxxxxxxxxxxxxxxxcc.3.^c^.....c^.........c^2.....^c^......ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[18], "xxxxxxxxxxxxxxxxxxxcc...^+^.....c..........c........c...2...ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[19], "xxxxxxxxxxxxxxxxxxxccccc+ccccccccccccccccccccccccccccccc....ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[20], "xxxxxxxxxxxxxxxxxxxcc..^.c.............................c....ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[21], "xxxxxxxxxxxxxxxxxxxcc....c.............................c..3.ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[22], "xxxxxxxxxxxxxxxxxxxcc....c..ccc4.................4ccc..c....ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[23], "xxxxxxxxxxxxxxxxxxxcc....c..ccc...................ccc..c..2.ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[24], "xxxxxxxxxxxxxxxxxxxcc....c..ccc.........1.........ccc..c)..}ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[25], "xxxxxxxxxxxxxxxxxxxcc.3..c..ccc.....2.......2.....ccc..cccccccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[26], "xxxxxxxxxxxxxxxxxxxcc....c.............................c....ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[27], "xxxxxxxxxxxxxxxxxxxcc....c.............................c^2..ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[28], "xxxxxxxxxxxxxxxxxxxcc....c........c...........c........+....ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[29], "xxxxxxxxxxxxxxxxxxxcc]...c.............................c^2..ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[30], "xxxxxxxxxxxxxxxxxxxccccccc.....3........(........3.....c....ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[31], "xxxxxxxxxxxxxxxxxxxcc....c.............................c.^.^ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[32], "xxxxxxxxxxxxxxxxxxxcc...^c........c...........c........ccc+cccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[33], "xxxxxxxxxxxxxxxxxxxcc....+.............................c..^.ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[34], "xxxxxxxxxxxxxxxxxxxcc...^c.............................c....ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[35], "xxxxxxxxxxxxxxxxxxxcc....c..ccc.....2.......2.....ccc..c..2.ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[36], "xxxxxxxxxxxxxxxxxxxccccccc..ccc.........1.........ccc..c....ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[37], "xxxxxxxxxxxxxxxxxxxcc....c..ccc...................ccc..c....ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[38], "xxxxxxxxxxxxxxxxxxxcc...^+..ccc4.................4ccc..c2...ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[39], "xxxxxxxxxxxxxxxxxxxcc....c.............................c....ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[40], "xxxxxxxxxxxxxxxxxxxccccccc.............................c..2.ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[41], "xxxxxxxxxxxxxxxxxxxcc....c.............................ccc+cccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[42], "xxxxxxxxxxxxxxxxxxxcc....+cccc+ccccccccccccccc+ccccccccc.^.^ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[43], "xxxxxxxxxxxxxxxxxxxcc.1.^^.c.^..c............c^.......c.3...ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[44], "xxxxxxxxxxxxxxxxxxxcc...2..c.1..c.....1.1....c.....2..c.....ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[45], "xxxxxxxxxxxxxxxxxxxcc......c....c..1......1.^c..2.....c...2.ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[46], "xxxxxxxxxxxxxxxxxxxcc..3...c.1..c...1...1..1^+........c.....ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[47], "xxxxxxxxxxxxxxxxxxxcc......c....c[...........c.......3c.....ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[48], "xxxxxxxxxxxxxxxxxxxcccccccccccccccccccccccccccccccccccccccccccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[49], "xxxxxxxxxxxxxxxxxxxcccccccccccccccccccccccccccccccccccccccccccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[50], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[51], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[52], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[53], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[54], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[55], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[56], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[57], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[58], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[59], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[60], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[61], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[62], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[63], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[64], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[65], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[66], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[67], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[68], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[69], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- mons_array[0] = MONS_MUMMY;
- mons_array[1] = MONS_GUARDIAN_MUMMY;
- mons_array[2] = MONS_MUMMY_PRIEST;
- mons_array[3] = MONS_GREATER_MUMMY;
- mons_array[4] = RANDOM_MONSTER;
- mons_array[5] = RANDOM_MONSTER;
- mons_array[6] = RANDOM_MONSTER;
-
- return MAP_ENCOMPASS;
-}
-
-
-static char tomb_3(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
-
- strcpy(vgrid[0], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[1], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[2], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[3], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[4], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[5], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[6], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[7], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[8], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[9], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[10], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[11], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[12], "xxxxxxxxxxxxxxxxxxxcccccccccccccccccccccccccccccccccccccccccccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[13], "xxxxxxxxxxxxxxxxxxxcccccccccccccccccccccccccccccccccccccccccccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[14], "xxxxxxxxxxxxxxxxxxxccccccc.............................cccccccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[15], "xxxxxxxxxxxxxxxxxxxcccc...............cccccc..............ccccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[16], "xxxxxxxxxxxxxxxxxxxccc...............cccccccc..............cccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[17], "xxxxxxxxxxxxxxxxxxxccc.......4......ccccO4cccc......4......cccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[18], "xxxxxxxxxxxxxxxxxxxccc............cccc......cccc...........cccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[19], "xxxxxxxxxxxxxxxxxxxcc............cccc........cccc...........ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[20], "xxxxxxxxxxxxxxxxxxxcc............cccc........cccc...........ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[21], "xxxxxxxxxxxxxxxxxxxcc...........cccc..444444..cccc..........ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[22], "xxxxxxxxxxxxxxxxxxxcc.......................................ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[23], "xxxxxxxxxxxxxxxxxxxcc.......................................ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[24], "xxxxxxxxxxxxxxxxxxxcc.................222222................ccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[25], "xxxxxxxxxxxxxxxxxxxccc................223322...............cccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[26], "xxxxxxxxxxxxxxxxxxxccc...3............223322............3..cccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[27], "xxxxxxxxxxxxxxxxxxxcccc...............222222..............ccccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[28], "xxxxxxxxxxxxxxxxxxxcccc....2..........................2...ccccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[29], "xxxxxxxxxxxxxxxxxxxcccccc....2......................2....cccccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[30], "xxxxxxxxxxxxxxxxxxxcccccccc............................cccccccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[31], "xxxxxxxxxxxxxxxxxxxccccccccc+ccc..................ccc+ccccccccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[32], "xxxxxxxxxxxxxxxxxxxcccccccc....cc................cc....cccccccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[33], "xxxxxxxxxxxxxxxxxxxcccccc.......cc22222222222222cc......$cccccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[34], "xxxxxxxxxxxxxxxxxxxcccc....^.....cc............cc..^.....$ccccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[35], "xxxxxxxxxxxxxxxxxxxcccc.^.........cc..........cc.....^.^.$ccccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[36], "xxxxxxxxxxxxxxxxxxxccc$...^...^..^.cc........cc..........$$cccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[37], "xxxxxxxxxxxxxxxxxxxccc$$$...........cc222222cc.^........$$$cccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[38], "xxxxxxxxxxxxxxxxxxxccc|$$$...........c......c.....^...$$$$$cccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[39], "xxxxxxxxxxxxxxxxxxxccc||$$$$...^.....c......c^......$$$$$$$cccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[40], "xxxxxxxxxxxxxxxxxxxccc|||||$$.....^..c......c......$$$$$$$$cccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[41], "xxxxxxxxxxxxxxxxxxxcccc|||||$........c......c...^.$$$$$$$$ccccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[42], "xxxxxxxxxxxxxxxxxxxccccc||||$$..^....c......c.....$$$$$$$cccccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[43], "xxxxxxxxxxxxxxxxxxxcccccc||||$.......c......c.....$$$$$$ccccccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[44], "xxxxxxxxxxxxxxxxxxxccccccc|||$$....^.c......c.^.^$$$$$$cccccccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[45], "xxxxxxxxxxxxxxxxxxxcccccccc|||$^....cc..{...cc...$$$$$ccccccccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[46], "xxxxxxxxxxxxxxxxxxxccccccccc||$.....cc...(..cc..$$$$$cccccccccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[47], "xxxxxxxxxxxxxxxxxxxcccccccccc|$...cccc..[...cccc$$$$ccccccccccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[48], "xxxxxxxxxxxxxxxxxxxcccccccccccccccccccccccccccccccccccccccccccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[49], "xxxxxxxxxxxxxxxxxxxcccccccccccccccccccccccccccccccccccccccccccxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[50], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[51], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[52], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[53], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[54], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[55], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[56], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[57], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[58], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[59], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[60], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[61], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[62], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[63], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[64], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[65], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[66], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[67], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[68], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcpy(vgrid[69], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- mons_array[0] = MONS_MUMMY;
- mons_array[1] = MONS_GUARDIAN_MUMMY;
- mons_array[2] = MONS_MUMMY_PRIEST;
- mons_array[3] = MONS_GREATER_MUMMY;
- mons_array[4] = RANDOM_MONSTER;
- mons_array[5] = RANDOM_MONSTER;
- mons_array[6] = RANDOM_MONSTER;
-
- return MAP_ENCOMPASS;
-}
-
-
-
-static char swamp(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // NB - most of the 'x's here will be set to water in dungeon.cc
-
- for (unsigned char i = 0; i < 81; i++)
- strcpy(vgrid[i], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- strcat(vgrid[36], "xxxxxxxxxxx@xxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[37], "xxxxxxxxxxx2xxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[38], "xxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[39], "xxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[40], "xxxxxxxxxx2x.xxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[41], "xxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[42], "xxxxxxxxxcc.ccxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[43], "xxxxxxxxcc...ccxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[44], "xxxxxxxcc3.2..ccxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[45], "xxxxxxcc.1.3.2.ccxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[46], "xxxxxccc....1.1cccxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[47], "xxxxxcc.1.32....ccxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[48], "xxxxxcc...3..1.3ccxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[49], "xxxxxcc2.1.3..2.ccxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[50], "xxxxxccc33..1..cccxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[51], "xxxxxxcccc3O3ccccxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[52], "xxxxxxxcccccccccxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[53], "xxxxxxxxcccccccxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[54], "xxxxxxxxxxcccxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[55], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[56], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[57], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[58], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[59], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[60], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[61], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[62], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[63], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[64], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[65], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[66], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[67], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[68], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- strcat(vgrid[69], "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-
- mons_array[0] = MONS_SWAMP_DRAGON;
- mons_array[1] = MONS_SWAMP_DRAKE;
- mons_array[2] = MONS_HYDRA;
- mons_array[3] = RANDOM_MONSTER;
- mons_array[4] = RANDOM_MONSTER;
- mons_array[5] = RANDOM_MONSTER;
- mons_array[6] = RANDOM_MONSTER;
-
- return MAP_SOUTHEAST;
-}
-
-
-/*
- NOTE: *Cannot* place 8,9 or 0 monsters in branch vaults which neither use the
- normal mons_level function or are around level 35, or generation will crash.
-
- Remember, minivaults are always sidewards
-*/
-
-static char minivault_1(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], "..xxxx=xxx..");
- strcpy(vgrid[2], ".xx..x...xx.");
- strcpy(vgrid[3], ".x....x...x.");
- strcpy(vgrid[4], ".x...x....x.");
- strcpy(vgrid[5], ".xx.x*x.x.=.");
- strcpy(vgrid[6], ".=.x.x*x.xx.");
- strcpy(vgrid[7], ".x....x...x.");
- strcpy(vgrid[8], ".x...x....x.");
- strcpy(vgrid[9], ".xx...x..xx.");
- strcpy(vgrid[10], "..xxx=xxxx..");
- strcpy(vgrid[11], "............");
-
- return MAP_NORTH;
-}
-
-
-static char minivault_2(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], "..xxxx.xxxx.");
- strcpy(vgrid[2], "..xx.....xx.");
- strcpy(vgrid[3], "..x.......x.");
- strcpy(vgrid[4], "..x.......x.");
- strcpy(vgrid[5], "......C.....");
- strcpy(vgrid[6], "..x.......x.");
- strcpy(vgrid[7], "..x.......x.");
- strcpy(vgrid[8], "..xx.....xx.");
- strcpy(vgrid[9], "..xxxx.xxxx.");
- strcpy(vgrid[10], "............");
- strcpy(vgrid[11], "............");
-
- return MAP_NORTH;
-}
-
-
-static char minivault_3(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], ".cccccccccc.");
- strcpy(vgrid[2], ".cccccccccc.");
- strcpy(vgrid[3], ".cBcBcBcBcc.");
- strcpy(vgrid[4], ".G.c.c.c.Bc.");
- strcpy(vgrid[5], ".........Bc.");
- strcpy(vgrid[6], ".........Bc.");
- strcpy(vgrid[7], ".G.c.c.c.Bc.");
- strcpy(vgrid[8], ".cBcBcBcBcc.");
- strcpy(vgrid[9], ".cccccccccc.");
- strcpy(vgrid[10], ".cccccccccc.");
- strcpy(vgrid[11], "............");
-
- return MAP_NORTH;
-}
-
-
-static char minivault_4(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], "....xwxx....");
- strcpy(vgrid[2], "..xxxwwxwx..");
- strcpy(vgrid[3], "..xwwwwwwx..");
- strcpy(vgrid[4], ".xwwxwwxwxx.");
- strcpy(vgrid[5], ".xwwwwwwwwx.");
- strcpy(vgrid[6], ".xwwxwwwxww.");
- strcpy(vgrid[7], ".xxwwwwwwxx.");
- strcpy(vgrid[8], "..wwwwxwwx..");
- strcpy(vgrid[9], "..xxxwwxxw..");
- strcpy(vgrid[10], "....xxww....");
- strcpy(vgrid[11], "............");
-
- return MAP_NORTH;
-}
-
-
-static char minivault_5(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], ".x.xxxxxxxx.");
- strcpy(vgrid[2], ".x.x......x.");
- strcpy(vgrid[3], ".x.x.xxxx.x.");
- strcpy(vgrid[4], ".x.x.x**x.x.");
- strcpy(vgrid[5], ".x.x.x**x.x.");
- strcpy(vgrid[6], ".x.x.xx.x.x.");
- strcpy(vgrid[7], ".x.x....x.x.");
- strcpy(vgrid[8], ".x.xxxxxx.x.");
- strcpy(vgrid[9], ".x........x.");
- strcpy(vgrid[10], ".xxxxxxxxxx.");
- strcpy(vgrid[11], "............");
-
- return MAP_NORTH;
-}
-
-
-static char minivault_6(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // Wizard's laboratory
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], ".ccccccc+cc.");
- strcpy(vgrid[2], ".c........c.");
- strcpy(vgrid[3], ".c........c.");
- strcpy(vgrid[4], ".c..1.....c.");
- strcpy(vgrid[5], ".c........c.");
- strcpy(vgrid[6], ".cc+ccccccc.");
- strcpy(vgrid[7], ".c***c3232c.");
- strcpy(vgrid[8], ".c|**+2223c.");
- strcpy(vgrid[9], ".c||*c3322c.");
- strcpy(vgrid[10], ".cccccccccc.");
- strcpy(vgrid[11], "............");
-
- mons_array[0] = MONS_WIZARD;
- mons_array[1] = MONS_ABOMINATION_SMALL;
- mons_array[2] = MONS_ABOMINATION_LARGE;
-
- return MAP_NORTH;
-
-}
-
-
-static char minivault_7(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // beehive minivault
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], "....aaaa....");
- strcpy(vgrid[2], "..a2a2aaaa..");
- strcpy(vgrid[3], "..aaRa3a2a..");
- strcpy(vgrid[4], ".aa2aRa2aaa.");
- strcpy(vgrid[5], ".a3aRa1aRa2.");
- strcpy(vgrid[6], ".aa3aRaRa2a.");
- strcpy(vgrid[7], ".aaa2a2a3aa.");
- strcpy(vgrid[8], "..a3aRa2aa..");
- strcpy(vgrid[9], "...aa2aa2a..");
- strcpy(vgrid[10], "....aaaa....");
- strcpy(vgrid[11], "............");
-
- mons_array[0] = MONS_QUEEN_BEE;
- mons_array[1] = MONS_KILLER_BEE;
- mons_array[2] = MONS_KILLER_BEE_LARVA;
-
- return MAP_NORTH;
-}
-
-
-static char minivault_8(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // lava pond
-
- strcpy(vgrid[0], "x.x.x.x.x.x.");
- strcpy(vgrid[1], ".c.c.c.c.c.x");
- strcpy(vgrid[2], "x...l1l...c.");
- strcpy(vgrid[3], ".c.llllll..x");
- strcpy(vgrid[4], "x.lllllll1c.");
- strcpy(vgrid[5], ".c.llFGll..x");
- strcpy(vgrid[6], "x..llGFll.c.");
- strcpy(vgrid[7], ".c1lllllll.x");
- strcpy(vgrid[8], "x..llllll.c.");
- strcpy(vgrid[9], ".c...l1l...x");
- strcpy(vgrid[10], "x.c.c.c.c.c.");
- strcpy(vgrid[11], ".x.x.x.x.x.x");
-
- mons_array[0] = MONS_MOLTEN_GARGOYLE;
-
- return MAP_NORTH;
-}
-
-
-static char minivault_9(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // evil zoo
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], ".==========.");
- strcpy(vgrid[2], ".==========.");
- strcpy(vgrid[3], ".==========.");
- strcpy(vgrid[4], ".===8888===.");
- strcpy(vgrid[5], ".===8998===.");
- strcpy(vgrid[6], ".===8998===.");
- strcpy(vgrid[7], ".===8888===.");
- strcpy(vgrid[8], ".==========.");
- strcpy(vgrid[9], ".==========.");
- strcpy(vgrid[10], ".==========.");
- strcpy(vgrid[11], "............");
-
- return MAP_NORTH;
-
-}
-
-
-static char minivault_10(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], ".xxxx..xxxx.");
- strcpy(vgrid[2], ".x**x..x**x.");
- strcpy(vgrid[3], ".x**+..+**x.");
- strcpy(vgrid[4], ".xx+x..x+xx.");
- strcpy(vgrid[5], "............");
- strcpy(vgrid[6], "............");
- strcpy(vgrid[7], ".xx+x..x+xx.");
- strcpy(vgrid[8], ".x**+..+**x.");
- strcpy(vgrid[9], ".x**x..x**x.");
- strcpy(vgrid[10], ".xxxx..xxxx.");
- strcpy(vgrid[11], "............");
-
- return MAP_NORTH;
-}
-
-
-static char minivault_11(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // multicoloured onion
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], ".+xxxxxxxx+.");
- strcpy(vgrid[2], ".x........x.");
- strcpy(vgrid[3], ".x.+cccc+.x.");
- strcpy(vgrid[4], ".x.c....c.x.");
- strcpy(vgrid[5], ".x.c.bb.c.x.");
- strcpy(vgrid[6], ".x.c.bb.c.x.");
- strcpy(vgrid[7], ".x.c....c.x.");
- strcpy(vgrid[8], ".x.+cccc+.x.");
- strcpy(vgrid[9], ".x........x.");
- strcpy(vgrid[10], ".+xxxxxxxx+.");
- strcpy(vgrid[11], "............");
-
- return MAP_NORTH;
-}
-
-
-static char minivault_12(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // closed box minivault
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], ".xxxxxxxxxx.");
- strcpy(vgrid[2], ".x>9$9$9$<x.");
- strcpy(vgrid[3], ".x.$9$9$.$x.");
- strcpy(vgrid[4], ".x$.****$.x.");
- strcpy(vgrid[5], ".x.$*||*.$x.");
- strcpy(vgrid[6], ".x$.*||*$.x.");
- strcpy(vgrid[7], ".x.$****.$x.");
- strcpy(vgrid[8], ".x$9$9$9$.x.");
- strcpy(vgrid[9], ".x<$9$9$9>x.");
- strcpy(vgrid[10], ".xxxxxxxxxx.");
- strcpy(vgrid[11], "............");
-
- return MAP_NORTH;
-}
-
-
-static char minivault_13(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // little trap spiral
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], ".xxxxxxxxxx.");
- strcpy(vgrid[2], ".=.^x..=.9x.");
- strcpy(vgrid[3], ".x.$=.^x..x.");
- strcpy(vgrid[4], ".xxxxxxxx=x.");
- strcpy(vgrid[5], ".x.8+|0x8.x.");
- strcpy(vgrid[6], ".x8$x.|x..x.");
- strcpy(vgrid[7], ".xx=xxxx=xx.");
- strcpy(vgrid[8], ".x.9=^.x..x.");
- strcpy(vgrid[9], ".x..x.^=9.x.");
- strcpy(vgrid[10], ".xxxxxxxxxx.");
- strcpy(vgrid[11], "............");
-
- return MAP_NORTH;
-}
-
-
-static char minivault_14(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // water cross
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], ".wwwww.wwww.");
- strcpy(vgrid[2], ".wwwww.wwww.");
- strcpy(vgrid[3], ".wwwww.wwww.");
- strcpy(vgrid[4], ".wwwww.wwww.");
- strcpy(vgrid[5], ".......wwww.");
- strcpy(vgrid[6], ".wwww.......");
- strcpy(vgrid[7], ".wwww.wwwww.");
- strcpy(vgrid[8], ".wwww.wwwww.");
- strcpy(vgrid[9], ".wwww.wwwww.");
- strcpy(vgrid[10], ".wwww.wwwww.");
- strcpy(vgrid[11], "............");
-
- return MAP_NORTH;
-}
-
-static char minivault_15(char vgrid[81][81], FixedVector<int, 7>& mons_array) /* lava pond */
-{
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], "............");
- strcpy(vgrid[2], "....lll.....");
- strcpy(vgrid[3], "...vvlvv....");
- strcpy(vgrid[4], "..lv|*|vl...");
- strcpy(vgrid[5], "..ll*S*ll...");
- strcpy(vgrid[6], "..lv|*|vl...");
- strcpy(vgrid[7], "...vvlvv....");
- strcpy(vgrid[8], "....lll.....");
- strcpy(vgrid[9], "............");
- strcpy(vgrid[10], "............");
- strcpy(vgrid[11], "............");
-
- return 1;
-}
-
-
-static char minivault_16(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // lava pond
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], "............");
- strcpy(vgrid[2], "............");
- strcpy(vgrid[3], "............");
- strcpy(vgrid[4], "............");
- strcpy(vgrid[5], "............");
- strcpy(vgrid[6], "......S.....");
- strcpy(vgrid[7], "............");
- strcpy(vgrid[8], "............");
- strcpy(vgrid[9], "............");
- strcpy(vgrid[10], "............");
- strcpy(vgrid[11], "............");
-
- return MAP_NORTH;
-}
-
-
-static char minivault_17(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // lava pond
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], "............");
- strcpy(vgrid[2], "............");
- strcpy(vgrid[3], "............");
- strcpy(vgrid[4], "............");
- strcpy(vgrid[5], ".....F......");
- strcpy(vgrid[6], "............");
- strcpy(vgrid[7], "............");
- strcpy(vgrid[8], "............");
- strcpy(vgrid[9], "............");
- strcpy(vgrid[10], "............");
- strcpy(vgrid[11], "............");
-
- return MAP_NORTH;
-}
-
-
-static char minivault_18(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // lava pond
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], "............");
- strcpy(vgrid[2], "............");
- strcpy(vgrid[3], "............");
- strcpy(vgrid[4], "............");
- strcpy(vgrid[5], ".....H......");
- strcpy(vgrid[6], "............");
- strcpy(vgrid[7], "............");
- strcpy(vgrid[8], "............");
- strcpy(vgrid[9], "............");
- strcpy(vgrid[10], "............");
- strcpy(vgrid[11], "............");
-
- return MAP_NORTH;
-}
-
-
-static char minivault_19(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], ".xx......xx.");
- strcpy(vgrid[2], ".xxx....xxx.");
- strcpy(vgrid[3], "..xxx..xxx..");
- strcpy(vgrid[4], "...xxxxxx...");
- strcpy(vgrid[5], "....xxxx....");
- strcpy(vgrid[6], "....xxxx....");
- strcpy(vgrid[7], "...xxxxxx...");
- strcpy(vgrid[8], "..xxx..xxx..");
- strcpy(vgrid[9], ".xxx....xxx.");
- strcpy(vgrid[10], ".xx......xx.");
- strcpy(vgrid[11], "............");
-
- return MAP_NORTH;
-}
-
-
-static char minivault_20(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // lava pond
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], ".xxxx..xxxx.");
- strcpy(vgrid[2], ".x........x.");
- strcpy(vgrid[3], ".x..xxxx..x.");
- strcpy(vgrid[4], ".x.x....x.x.");
- strcpy(vgrid[5], "...x.x9.x...");
- strcpy(vgrid[6], "...x.9x.x...");
- strcpy(vgrid[7], ".x.x....x.x.");
- strcpy(vgrid[8], ".x..xxxx..x.");
- strcpy(vgrid[9], ".x........x.");
- strcpy(vgrid[10], ".xxxx..xxxx.");
- strcpy(vgrid[11], "............");
-
- return MAP_NORTH;
-}
-
-
-static char minivault_21(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], ".^xxxxxxxx^.");
- strcpy(vgrid[2], ".x........x.");
- strcpy(vgrid[3], ".x.cccccc.x.");
- strcpy(vgrid[4], ".x.c|..<c.x.");
- strcpy(vgrid[5], ".x.c.**.c.x.");
- strcpy(vgrid[6], ".x.c.**.c.x.");
- strcpy(vgrid[7], ".x.c>..|c.x.");
- strcpy(vgrid[8], ".x.cccccc.x.");
- strcpy(vgrid[9], ".x........x.");
- strcpy(vgrid[10], ".^xxxxxxxx^.");
- strcpy(vgrid[11], "............");
-
- return MAP_NORTH;
-
-}
-
-
-static char minivault_22(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], ".....xx.....");
- strcpy(vgrid[2], "...xxxxxx...");
- strcpy(vgrid[3], "..x^x..x^x..");
- strcpy(vgrid[4], "..xx.xx.xx..");
- strcpy(vgrid[5], ".xx.x$$x.xx.");
- strcpy(vgrid[6], ".xx.x$$x.xx.");
- strcpy(vgrid[7], "..xx.xx.xx..");
- strcpy(vgrid[8], "..x^x..x^x..");
- strcpy(vgrid[9], "...xxxxxx...");
- strcpy(vgrid[10], ".....xx.....");
- strcpy(vgrid[11], "............");
-
- return MAP_NORTH;
-
-}
-
-
-static char minivault_23(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "x.x.x.x.x.x.");
- strcpy(vgrid[1], ".x.x.x.x.x.x");
- strcpy(vgrid[2], "x.x.x.x.x.x.");
- strcpy(vgrid[3], ".x.x.x.x.x.x");
- strcpy(vgrid[4], "x.x.x.x.x.x.");
- strcpy(vgrid[5], ".x.x.x.x.x.x");
- strcpy(vgrid[6], "x.x.x.x.x.x.");
- strcpy(vgrid[7], ".x.x.x.x.x.x");
- strcpy(vgrid[8], "x.x.x.x.x.x.");
- strcpy(vgrid[9], ".x.x.x.x.x.x");
- strcpy(vgrid[10], "x.x.x.x.x.x.");
- strcpy(vgrid[11], ".x.x.x.x.x.x");
-
- return MAP_NORTH;
-
-}
-
-
-static char minivault_24(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], "....xxxx....");
- strcpy(vgrid[2], "....xxxx....");
- strcpy(vgrid[3], "....xxxx....");
- strcpy(vgrid[4], ".xxxx.x.xxx.");
- strcpy(vgrid[5], ".xxx.x.xxxx.");
- strcpy(vgrid[6], ".xxxx.x.xxx.");
- strcpy(vgrid[7], ".xxx.x.xxxx.");
- strcpy(vgrid[8], "....xxxx....");
- strcpy(vgrid[9], "....xxxx....");
- strcpy(vgrid[10], "....xxxx....");
- strcpy(vgrid[11], "............");
-
- return MAP_NORTH;
-
-}
-
-
-static char minivault_25(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], ".xx+xxxxxxx.");
- strcpy(vgrid[2], ".x........x.");
- strcpy(vgrid[3], ".x........+.");
- strcpy(vgrid[4], ".x........x.");
- strcpy(vgrid[5], ".x........x.");
- strcpy(vgrid[6], ".x........x.");
- strcpy(vgrid[7], ".x........x.");
- strcpy(vgrid[8], ".+........x.");
- strcpy(vgrid[9], ".x........x.");
- strcpy(vgrid[10], ".xxxxxxx+xx.");
- strcpy(vgrid[11], "............");
-
- return MAP_NORTH;
-
-}
-
-
-static char minivault_26(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "c..........c");
- strcpy(vgrid[1], ".c...cc...c.");
- strcpy(vgrid[2], "..c..cc..c..");
- strcpy(vgrid[3], "...c....c...");
- strcpy(vgrid[4], "....c..c....");
- strcpy(vgrid[5], ".cc..cc..cc.");
- strcpy(vgrid[6], ".cc..cc..cc.");
- strcpy(vgrid[7], "....c..c....");
- strcpy(vgrid[8], "...c....c...");
- strcpy(vgrid[9], "..c..cc..c..");
- strcpy(vgrid[10], ".c...cc...c.");
- strcpy(vgrid[11], "c..........c");
-
- return MAP_NORTH;
-
-}
-
-
-static char minivault_27(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], ".x.xxxxxxxx.");
- strcpy(vgrid[2], ".x........x.");
- strcpy(vgrid[3], ".xxxxxxxx.x.");
- strcpy(vgrid[4], ".x........x.");
- strcpy(vgrid[5], ".x.xxxxxxxx.");
- strcpy(vgrid[6], ".x........x.");
- strcpy(vgrid[7], ".xxxxxxxx.x.");
- strcpy(vgrid[8], ".x........x.");
- strcpy(vgrid[9], ".x.xxxxxxxx.");
- strcpy(vgrid[10], "............");
- strcpy(vgrid[11], "............");
-
- return MAP_NORTH;
-
-}
-
-
-static char minivault_28(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], ".xxxx.xxxx..");
- strcpy(vgrid[2], ".x.......x..");
- strcpy(vgrid[3], ".x..999..x..");
- strcpy(vgrid[4], ".x.9...9.x..");
- strcpy(vgrid[5], "...9.I.9....");
- strcpy(vgrid[6], ".x.9...9.x..");
- strcpy(vgrid[7], ".x..999..x..");
- strcpy(vgrid[8], ".x.......x..");
- strcpy(vgrid[9], ".xxxx.xxxx..");
- strcpy(vgrid[10], "............");
- strcpy(vgrid[11], "............");
-
- return MAP_NORTH;
-
-}
-
-
-static char minivault_29(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
-
- strcpy(vgrid[0], ".3......3...");
- strcpy(vgrid[1], "...x.xx.x.2.");
- strcpy(vgrid[2], ".xxx2xxxxx..");
- strcpy(vgrid[3], ".xxxx42xxx2.");
- strcpy(vgrid[4], ".2xx243432x3");
- strcpy(vgrid[5], ".xx421424xx.");
- strcpy(vgrid[6], "3xx423242x..");
- strcpy(vgrid[7], ".x2x3243xxx.");
- strcpy(vgrid[8], ".x2xx42422x.");
- strcpy(vgrid[9], "..xxxxxxxx2.");
- strcpy(vgrid[10], "...x2xxxx3..");
- strcpy(vgrid[11], ".3.......33.");
-
- mons_array[0] = MONS_QUEEN_ANT;
- mons_array[1] = MONS_SOLDIER_ANT;
- mons_array[2] = MONS_GIANT_ANT;
- mons_array[3] = MONS_ANT_LARVA;
-
- return MAP_NORTH;
-
-}
-
-
-static char minivault_30(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // lava pond
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], "............");
- strcpy(vgrid[2], "............");
- strcpy(vgrid[3], "............");
- strcpy(vgrid[4], "............");
- strcpy(vgrid[5], ".....T......");
- strcpy(vgrid[6], "............");
- strcpy(vgrid[7], "............");
- strcpy(vgrid[8], "............");
- strcpy(vgrid[9], "............");
- strcpy(vgrid[10], "............");
- strcpy(vgrid[11], "............");
-
- return MAP_NORTH;
-
-}
-
-
-static char minivault_31(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // lava pond
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], "............");
- strcpy(vgrid[2], "............");
- strcpy(vgrid[3], "............");
- strcpy(vgrid[4], "............");
- strcpy(vgrid[5], ".....T......");
- strcpy(vgrid[6], "............");
- strcpy(vgrid[7], "............");
- strcpy(vgrid[8], "............");
- strcpy(vgrid[9], "............");
- strcpy(vgrid[10], "............");
- strcpy(vgrid[11], "............");
-
- return MAP_NORTH;
-
-}
-
-
-static char minivault_32(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // lava pond
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], "............");
- strcpy(vgrid[2], "............");
- strcpy(vgrid[3], "............");
- strcpy(vgrid[4], "............");
- strcpy(vgrid[5], ".....U......");
- strcpy(vgrid[6], "............");
- strcpy(vgrid[7], "............");
- strcpy(vgrid[8], "............");
- strcpy(vgrid[9], "............");
- strcpy(vgrid[10], "............");
- strcpy(vgrid[11], "............");
-
- return MAP_NORTH;
-
-}
-
-
-static char minivault_33(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // lava pond
- UNUSED( mons_array );
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], "............");
- strcpy(vgrid[2], "............");
- strcpy(vgrid[3], "............");
- strcpy(vgrid[4], "............");
- strcpy(vgrid[5], ".....V......");
- strcpy(vgrid[6], "............");
- strcpy(vgrid[7], "............");
- strcpy(vgrid[8], "............");
- strcpy(vgrid[9], "............");
- strcpy(vgrid[10], "............");
- strcpy(vgrid[11], "............");
-
- return MAP_NORTH;
-
-}
-
-static char minivault_34(char vgrid[81][81], FixedVector<int, 7>& mons_array, bool orientation)
-{
- //jmf: multi-god temple thing
- UNUSED( mons_array );
- int i, di;
-
- if ( orientation )
- {
- i = 0;
- di = +1;
- }
- else
- {
- i = 11;
- di = -1;
- }
-
- for (int c=0; c <= 11; c++, i += di)
- {
- strcpy(vgrid[i], "............");
- strcpy(vgrid[i], ".=xxxxxxxx=.");
- strcpy(vgrid[i], ".x9......9x.");
- strcpy(vgrid[i], ".xT......Tx.");
- strcpy(vgrid[i], ".x..C..C..x.");
- strcpy(vgrid[i], ".xT......Tx.");
- strcpy(vgrid[i], ".xxxxxxxxxx.");
- strcpy(vgrid[i], ".xxx$$$$xxx.");
- strcpy(vgrid[i], ".xx8....8xx.");
- strcpy(vgrid[i], "..xx....xx..");
- strcpy(vgrid[i], "...xG..Gx...");
- strcpy(vgrid[i], "............");
- }
-
- return MAP_NORTH;
-}
-
-static char minivault_34_a(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
- return minivault_34(vgrid, mons_array, true);
-}
-
-static char minivault_34_b(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
- return minivault_34(vgrid, mons_array, false);
-}
-
-static char minivault_35(char vgrid[81][81], FixedVector<int, 7>& mons_array, bool orientation)
-{
- UNUSED( mons_array );
- //jmf: another multi-god temple thing
- int i, di;
-
- if (orientation)
- {
- i = 0;
- di = +1;
- }
- else
- {
- i = 11;
- di = -1;
- }
-
- for (int c=0; c <= 11; c++, i += di)
- {
- strcpy(vgrid[i], "............");
- strcpy(vgrid[i], "..vvvvvvvv..");
- strcpy(vgrid[i], ".vv......vv.");
- strcpy(vgrid[i], ".v..x..x..v.");
- strcpy(vgrid[i], ".v.Cx..xC.v.");
- strcpy(vgrid[i], ".v..x..x..v.");
- strcpy(vgrid[i], ".vT8x..x8Tv.");
- strcpy(vgrid[i], ".vvvx==xvvv.");
- strcpy(vgrid[i], "...Gx99xG...");
- strcpy(vgrid[i], "...+*99*+...");
- strcpy(vgrid[i], "...GxxxxG...");
- strcpy(vgrid[i], "............");
- }
-
- return MAP_NORTH;
-}
-
-static char minivault_35_a(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
- return minivault_35(vgrid, mons_array, true);
-}
-
-static char minivault_35_b(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
- return minivault_35(vgrid, mons_array, false);
-}
-
-
-static char rand_demon_1(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], ".xx.xx.x.xx.");
- strcpy(vgrid[2], "..x.x..x.x..");
- strcpy(vgrid[3], "..x.x..x.x..");
- strcpy(vgrid[4], "..x.x..x.x..");
- strcpy(vgrid[5], "..x.x..x.x..");
- strcpy(vgrid[6], "..x.x1.x.x..");
- strcpy(vgrid[7], "..x.x..x.x..");
- strcpy(vgrid[8], "..x.x..x.x..");
- strcpy(vgrid[9], "..x.x..x.x..");
- strcpy(vgrid[10], ".xx.x.xx.xx.");
- strcpy(vgrid[11], "............");
-
- mons_array[0] = MONS_PANDEMONIUM_DEMON;
- mons_array[1] = RANDOM_MONSTER;
- mons_array[2] = RANDOM_MONSTER;
- mons_array[3] = RANDOM_MONSTER;
- mons_array[4] = RANDOM_MONSTER;
- mons_array[5] = RANDOM_MONSTER;
-
- return MAP_NORTH;
-}
-
-
-static char rand_demon_2(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], ".xxxxxxxx3x.");
- strcpy(vgrid[2], ".3.....xx.x.");
- strcpy(vgrid[3], ".xxxxxx4x.x.");
- strcpy(vgrid[4], ".xx4x..xx.x.");
- strcpy(vgrid[5], ".x.x.22.x.x.");
- strcpy(vgrid[6], ".x.x.12.x.x.");
- strcpy(vgrid[7], ".x.xx..x4xx.");
- strcpy(vgrid[8], ".x.x4xxxxxx.");
- strcpy(vgrid[9], ".x.xx.....3.");
- strcpy(vgrid[10], ".x3xxxxxxxx.");
- strcpy(vgrid[11], "............");
-
- mons_array[0] = MONS_PANDEMONIUM_DEMON;
- mons_array[1] = summon_any_demon(DEMON_GREATER);
- mons_array[2] = summon_any_demon(DEMON_COMMON);
- mons_array[3] = summon_any_demon(DEMON_COMMON);
- mons_array[4] = RANDOM_MONSTER;
- mons_array[5] = RANDOM_MONSTER;
-
- return MAP_NORTH;
-}
-
-
-static char rand_demon_3(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], ".x.x.x3x.x..");
- strcpy(vgrid[2], "..x.x3x3x.x.");
- strcpy(vgrid[3], ".x.x.x2x.x..");
- strcpy(vgrid[4], "..x3x2x2x3x.");
- strcpy(vgrid[5], ".x3x2x1x2x3.");
- strcpy(vgrid[6], "..x3x2x2x3x.");
- strcpy(vgrid[7], ".x.x.x2x3x..");
- strcpy(vgrid[8], "..x.x3x3x.x.");
- strcpy(vgrid[9], ".x.x.x3x.x..");
- strcpy(vgrid[10], "..x.x.x.x.x.");
- strcpy(vgrid[11], "............");
-
- mons_array[0] = MONS_PANDEMONIUM_DEMON;
- mons_array[1] = summon_any_demon(DEMON_COMMON);
- mons_array[2] = summon_any_demon(DEMON_COMMON);
-
- return MAP_NORTH;
-}
-
-
-static char rand_demon_4(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
- //jmf: all 3s below were 1s -- may have been bug
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], ".xxxxxxxxx..");
- strcpy(vgrid[2], ".x$=*=3=|x..");
- strcpy(vgrid[3], ".xxxxxxx=x..");
- strcpy(vgrid[4], ".x2=3=2x|x..");
- strcpy(vgrid[5], ".x=xxxxx=x..");
- strcpy(vgrid[6], ".x3=*x1=Px..");
- strcpy(vgrid[7], ".x=x=xxxxx..");
- strcpy(vgrid[8], ".x*x2=3=2=..");
- strcpy(vgrid[9], ".xxxxxxxxx..");
- strcpy(vgrid[10], "............");
- strcpy(vgrid[11], "............");
-
- mons_array[0] = MONS_PANDEMONIUM_DEMON;
- mons_array[1] = summon_any_demon(random2(3));
- mons_array[2] = summon_any_demon(random2(3));
-
- return MAP_NORTH;
-
-}
-
-
-static char rand_demon_5(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{ // obviously possible to get stuck - too bad (should've come prepared)
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], "...xxxxxx...");
- strcpy(vgrid[2], "..xx....xx..");
- strcpy(vgrid[3], ".xx......xx.");
- strcpy(vgrid[4], ".x..3232..x.");
- strcpy(vgrid[5], ".x..2|P3..x.");
- strcpy(vgrid[6], ".x..3P|2..x.");
- strcpy(vgrid[7], ".x..2123..x.");
- strcpy(vgrid[8], ".xx......xx.");
- strcpy(vgrid[9], "..xx....xx..");
- strcpy(vgrid[10], "...xxxxxx...");
- strcpy(vgrid[11], "............");
-
- mons_array[0] = MONS_PANDEMONIUM_DEMON;
- mons_array[1] = summon_any_demon(random2(3));
- mons_array[2] = summon_any_demon(random2(3));
-
- return MAP_NORTH;
-
-}
-
-
-static char rand_demon_6(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], "............");
- strcpy(vgrid[2], "......2.....");
- strcpy(vgrid[3], "............");
- strcpy(vgrid[4], ".3..........");
- strcpy(vgrid[5], "..........2.");
- strcpy(vgrid[6], ".....1......");
- strcpy(vgrid[7], "............");
- strcpy(vgrid[8], "............");
- strcpy(vgrid[9], ".2.......3..");
- strcpy(vgrid[10], "............");
- strcpy(vgrid[11], "............");
-
- mons_array[0] = MONS_PANDEMONIUM_DEMON;
- mons_array[1] = summon_any_demon(random2(3));
- mons_array[2] = summon_any_demon(random2(3));
-
- return MAP_NORTH;
-
-}
-
-
-static char rand_demon_7(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], ".xxx....xxx.");
- strcpy(vgrid[2], ".x|xx=xxx|x.");
- strcpy(vgrid[3], ".xx=....=xx.");
- strcpy(vgrid[4], "..x.x==x.x..");
- strcpy(vgrid[5], "..x.=12=.=..");
- strcpy(vgrid[6], "..=.=23=.x..");
- strcpy(vgrid[7], "..x.x==x.x..");
- strcpy(vgrid[8], ".xx=....=xx.");
- strcpy(vgrid[9], ".x|xxx=xx|x.");
- strcpy(vgrid[10], ".xxx....xxx.");
- strcpy(vgrid[11], "............");
-
- mons_array[0] = MONS_PANDEMONIUM_DEMON;
- mons_array[1] = summon_any_demon(random2(3));
- mons_array[2] = summon_any_demon(DEMON_GREATER);
-
- return MAP_NORTH;
-
-}
-
-
-static char rand_demon_8(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], "....xxxxxxx.");
- strcpy(vgrid[2], "..xxx....1x.");
- strcpy(vgrid[3], ".xx..2....x.");
- strcpy(vgrid[4], ".x........x.");
- strcpy(vgrid[5], ".xx.......x.");
- strcpy(vgrid[6], "..xx33..2.x.");
- strcpy(vgrid[7], "....33...xx.");
- strcpy(vgrid[8], ".....x...x..");
- strcpy(vgrid[9], "..F..xx.xx..");
- strcpy(vgrid[10], "......xxx...");
- strcpy(vgrid[11], "............");
-
- mons_array[0] = MONS_PANDEMONIUM_DEMON;
- mons_array[1] = summon_any_demon(DEMON_GREATER);
- mons_array[2] = summon_any_demon(random2(3));
-
- return MAP_NORTH;
-
-}
-
-
-static char rand_demon_9(char vgrid[81][81], FixedVector<int, 7>& mons_array)
-{
-
- strcpy(vgrid[0], "............");
- strcpy(vgrid[1], ".xxxxxxxxxx.");
- strcpy(vgrid[2], ".x2=3=3=3xx.");
- strcpy(vgrid[3], ".x=xxxxxx2x.");
- strcpy(vgrid[4], ".x3x^^^^x=x.");
- strcpy(vgrid[5], ".x=x^P^^x2x.");
- strcpy(vgrid[6], ".x3x^^1^x=x.");
- strcpy(vgrid[7], ".x=x^^^^x3x.");
- strcpy(vgrid[8], ".x2xxxx=x=x.");
- strcpy(vgrid[9], ".xx2=2=3x3x.");
- strcpy(vgrid[10], ".xxxxxxxx=x.");
- strcpy(vgrid[11], "............");
-
- mons_array[0] = MONS_PANDEMONIUM_DEMON;
- mons_array[1] = summon_any_demon(random2(3));
- mons_array[2] = summon_any_demon(DEMON_GREATER);
-
- return MAP_NORTH;
-
-}
diff --git a/stone_soup/crawl-ref/source/maps.h b/stone_soup/crawl-ref/source/maps.h
deleted file mode 100644
index e2ce11af80..0000000000
--- a/stone_soup/crawl-ref/source/maps.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * File: maps.cc
- * Summary: Functions used to create vaults.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef MAPS_H
-#define MAPS_H
-
-#include "FixVec.h"
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: dungeon
- * *********************************************************************** */
-char vault_main(char vgrid[81][81], FixedVector<int, 7>& mons_array, int vault_force, int many_many);
-
-
-#endif
diff --git a/stone_soup/crawl-ref/source/menu.cc b/stone_soup/crawl-ref/source/menu.cc
deleted file mode 100644
index 0728980058..0000000000
--- a/stone_soup/crawl-ref/source/menu.cc
+++ /dev/null
@@ -1,501 +0,0 @@
-#include <cctype>
-#include "menu.h"
-#include "macro.h"
-#include "view.h"
-
-Menu::Menu( int _flags )
- : selitem_text(NULL),
- title(NULL),
- flags(_flags),
- first_entry(0),
- y_offset(0),
- pagesize(0),
- items(),
- sel(NULL),
- select_filter(),
- highlighter(new MenuHighlighter),
- num(-1),
- lastch(0),
- alive(false)
-{
-}
-
-Menu::~Menu()
-{
- for (int i = 0, count = items.size(); i < count; ++i)
- delete items[i];
- delete title;
- delete highlighter;
-}
-
-void Menu::set_highlighter( MenuHighlighter *mh )
-{
- if (highlighter != mh)
- delete highlighter;
- highlighter = mh;
-}
-
-void Menu::set_title( MenuEntry *e )
-{
- if (title != e)
- delete title;
-
- title = e;
- title->level = MEL_TITLE;
-}
-
-void Menu::add_entry( MenuEntry *entry )
-{
- items.push_back( entry );
-}
-
-void Menu::reset()
-{
- first_entry = 0;
-}
-
-std::vector<MenuEntry *> Menu::show()
-{
- std::vector< MenuEntry * > selected;
-
- deselect_all(false);
-
- // Lose lines for the title + room for more.
- pagesize = get_number_of_lines() - 2;
-
-#ifdef DOS_TERM
- char buffer[4600];
-
- gettext(1, 1, 80, 25, buffer);
- window(1, 1, 80, 25);
-#endif
-
- do_menu( &selected );
-
-#ifdef DOS_TERM
- puttext(1, 1, 80, 25, buffer);
-#endif
-
- return selected;
-}
-
-void Menu::do_menu( std::vector<MenuEntry*> *selected )
-{
- sel = selected;
- draw_menu( selected );
-
- alive = true;
- while (alive)
- {
- int keyin = getchm(c_getch);
-
- if (!process_key( keyin ))
- return;
- }
-}
-
-bool Menu::is_set(int flag) const
-{
- if (flag == MF_EASY_EXIT && Options.easy_exit_menu)
- return true;
- return (flags & flag) == flag;
-}
-
-bool Menu::process_key( int keyin )
-{
- if (items.size() == 0)
- return false;
-
- bool nav = false, repaint = false;
- switch (keyin)
- {
- case CK_ENTER:
- return false;
- case CK_ESCAPE:
- sel->clear();
- lastch = keyin;
- return false;
- case ' ': case CK_PGDN: case '>': case '\'':
- nav = true;
- repaint = page_down();
- if (!repaint && flags && !is_set(MF_EASY_EXIT))
- {
- repaint = first_entry != 0;
- first_entry = 0;
- }
- break;
- case CK_PGUP: case '<': case ';':
- nav = true;
- repaint = page_up();
- break;
- case CK_UP:
- nav = true;
- repaint = line_up();
- break;
- case CK_DOWN:
- nav = true;
- repaint = line_down();
- break;
- default:
- lastch = keyin;
-
- // If no selection at all is allowed, exit now.
- if (!(flags & (MF_SINGLESELECT | MF_MULTISELECT)))
- return false;
-
- if (!is_set(MF_NO_SELECT_QTY) && isdigit( keyin ))
- {
- if (num > 999)
- num = -1;
- num = (num == -1)? keyin - '0' :
- num * 10 + keyin - '0';
- }
-
- select_items( keyin, num );
- get_selected( sel );
- if (sel->size() == 1 && (flags & MF_SINGLESELECT))
- return false;
- draw_select_count( sel->size() );
-
- if (flags & MF_ANYPRINTABLE && !isdigit( keyin ))
- return false;
-
- break;
- }
-
- if (!isdigit( keyin ))
- num = -1;
-
- if (nav)
- {
- if (repaint)
- draw_menu( sel );
- // Easy exit should not kill the menu if there are selected items.
- else if (sel->empty() && (!flags || is_set(MF_EASY_EXIT)))
- {
- sel->clear();
- return false;
- }
- }
- return true;
-}
-
-bool Menu::draw_title_suffix( const std::string &s, bool titlefirst )
-{
- int oldx = wherex(), oldy = wherey();
-
- if (titlefirst)
- draw_title();
-
- int x = wherex();
- if (x > GXM || x < 1)
- {
- gotoxy(oldx, oldy);
- return false;
- }
-
- // Note: 1 <= x <= GXM; we have no fear of overflow.
- unsigned avail_width = GXM - x + 1;
- std::string towrite = s.length() > avail_width? s.substr(0, avail_width) :
- s.length() == avail_width? s :
- s + std::string(avail_width - s.length(), ' ');
-
- cprintf(towrite.c_str());
-
- gotoxy( oldx, oldy );
- return true;
-}
-
-void Menu::draw_select_count( int count )
-{
- if (!is_set(MF_MULTISELECT))
- return;
-
- if (selitem_text)
- {
- draw_title_suffix( selitem_text( sel ) );
- }
- else
- {
- char buf[100] = "";
- if (count)
- snprintf(buf, sizeof buf, " (%d item%s) ", count,
- (count > 1? "s" : ""));
-
- draw_title_suffix( buf );
- }
-}
-
-void Menu::get_selected( std::vector<MenuEntry*> *selected ) const
-{
- selected->clear();
-
- for (int i = 0, count = items.size(); i < count; ++i)
- if (items[i]->selected())
- selected->push_back( items[i] );
-}
-
-void Menu::deselect_all(bool update_view)
-{
- for (int i = 0, count = items.size(); i < count; ++i)
- {
- if (items[i]->level == MEL_ITEM)
- {
- items[i]->select(0);
- if (update_view)
- draw_item(i);
- }
- }
-}
-
-bool Menu::is_hotkey(int i, int key)
-{
- int end = first_entry + pagesize;
- if (end > (int) items.size()) end = items.size();
-
- bool ishotkey = is_set(MF_SINGLESELECT)?
- items[i]->is_primary_hotkey(key)
- : items[i]->is_hotkey(key);
-
- return is_set(MF_SELECT_ANY_PAGE)? ishotkey
- : ishotkey && i >= first_entry && i < end;
-}
-
-void Menu::select_items( int key, int qty )
-{
- int x = wherex(), y = wherey();
-
- if (key == ',' || key == '*')
- select_index( -1, qty );
- else if (key == '-')
- select_index( -1, 0 );
- else
- {
- int final = items.size();
- bool selected = false;
-
- // Process all items, in case user hits hotkey for an
- // item not on the current page.
-
- // We have to use some hackery to handle items that share
- // the same hotkey (as for pickup when there's a stack of
- // >52 items). If there are duplicate hotkeys, the items
- // are usually separated by at least a page, so we should
- // only select the item on the current page. This is why we
- // use two loops, and check to see if we've matched an item
- // by its primary hotkey (which is assumed to always be
- // hotkeys[0]), in which case, we stop selecting further
- // items.
- for (int i = first_entry; i < final; ++i)
- {
- if (is_hotkey( i, key ))
- {
- select_index( i, qty );
- if (items[i]->hotkeys[0] == key)
- {
- selected = true;
- break;
- }
- }
- }
-
- if (!selected)
- {
- for (int i = 0; i < first_entry; ++i)
- {
- if (is_hotkey( i, key ))
- {
- select_index( i, qty );
- if (items[i]->hotkeys[0] == key)
- {
- selected = true;
- break;
- }
- }
- }
- }
- }
- gotoxy( x, y );
-}
-
-bool Menu::is_selectable(int item) const
-{
- if (select_filter.empty()) return true;
-
- std::string text = items[item]->get_text();
- for (int i = 0, count = select_filter.size(); i < count; ++i)
- {
- if (select_filter[i].matches(text))
- return true;
- }
- return false;
-}
-
-void Menu::select_index( int index, int qty )
-{
- int si = index == -1? first_entry : index;
-
- if (index == -1)
- {
- if (flags & MF_MULTISELECT)
- {
- for (int i = 0, count = items.size(); i < count; ++i)
- {
- if (items[i]->level != MEL_ITEM) continue;
- if (is_hotkey(i, items[i]->hotkeys[0]) && is_selectable(i))
- {
- items[i]->select( qty );
- draw_item( i );
- }
- }
- }
- }
- else if (items[si]->level == MEL_SUBTITLE && (flags & MF_MULTISELECT))
- {
- for (int i = si + 1, count = items.size(); i < count; ++i)
- {
- if (items[i]->level != MEL_ITEM)
- break;
- if (is_hotkey(i, items[i]->hotkeys[0]))
- {
- items[i]->select( qty );
- draw_item( i );
- }
- }
- }
- else if (items[si]->level == MEL_ITEM &&
- (flags & (MF_SINGLESELECT | MF_MULTISELECT)))
- {
- items[si]->select( qty );
- draw_item( si );
- }
-}
-
-void Menu::draw_menu( std::vector< MenuEntry* > *selected )
-{
- clrscr();
-
- draw_title();
- draw_select_count( selected->size() );
- y_offset = 2;
-
- int end = first_entry + pagesize;
- if (end > (int) items.size()) end = items.size();
-
- for (int i = first_entry; i < end; ++i)
- {
- draw_item( i );
- }
- if (end < (int) items.size())
- {
- gotoxy( 1, y_offset + pagesize );
- textcolor( LIGHTGREY );
- cprintf("-more-");
- }
-}
-
-void Menu::update_title()
-{
- int x = wherex(), y = wherey();
- draw_title();
- gotoxy(x, y);
-}
-
-int Menu::item_colour(const MenuEntry *entry) const
-{
- int icol = -1;
- if (highlighter)
- icol = highlighter->entry_colour(entry);
-
- return (icol == -1? entry->colour : icol);
-}
-
-void Menu::draw_title()
-{
- if (title)
- {
- gotoxy(1, 1);
- textcolor( item_colour(title) );
- cprintf( "%s", title->get_text().c_str() );
- }
-}
-
-void Menu::draw_item( int index ) const
-{
- if (index < first_entry || index >= first_entry + pagesize)
- return;
-
- gotoxy( 1, y_offset + index - first_entry );
- textcolor( item_colour(items[index]) );
- cprintf( "%s", items[index]->get_text().c_str() );
-}
-
-bool Menu::page_down()
-{
- int old_first = first_entry;
-
- if ((int) items.size() > first_entry + pagesize)
- {
- first_entry += pagesize;
- //if (first_entry + pagesize > (int) items.size())
- // first_entry = items.size() - pagesize;
-
- if (old_first != first_entry)
- return true;
- }
- return false;
-}
-
-bool Menu::page_up()
-{
- int old_first = first_entry;
-
- if (first_entry > 0)
- {
- if ((first_entry -= pagesize) < 0)
- first_entry = 0;
- if (old_first != first_entry)
- return true;
- }
- return false;
-}
-
-bool Menu::line_down()
-{
- if (first_entry + pagesize < (int) items.size())
- {
- ++first_entry;
- return true;
- }
- return false;
-}
-
-bool Menu::line_up()
-{
- if (first_entry > 0)
- {
- --first_entry;
- return true;
- }
- return false;
-}
-
-/////////////////////////////////////////////////////////////////
-// Menu colouring
-//
-
-int menu_colour(const std::string &text)
-{
- for (int i = 0, size = Options.menu_colour_mappings.size(); i < size; ++i)
- {
- colour_mapping &cm = Options.menu_colour_mappings[i];
- if (cm.pattern.matches(text))
- return (cm.colour);
- }
- return (-1);
-}
-
-int MenuHighlighter::entry_colour(const MenuEntry *entry) const
-{
- return (::menu_colour(entry->get_text()));
-}
diff --git a/stone_soup/crawl-ref/source/menu.h b/stone_soup/crawl-ref/source/menu.h
deleted file mode 100644
index 05e4796383..0000000000
--- a/stone_soup/crawl-ref/source/menu.h
+++ /dev/null
@@ -1,216 +0,0 @@
-#ifndef __MENU_H__
-#define __MENU_H__
-
-#include <string>
-#include <vector>
-#include <algorithm>
-#include "AppHdr.h"
-#include "defines.h"
-#include "libutil.h"
-
-enum MenuEntryLevel
-{
- MEL_NONE = -1,
- MEL_TITLE,
- MEL_SUBTITLE,
- MEL_ITEM
-};
-
-struct menu_letter
-{
- char letter;
-
- menu_letter() : letter('a') { }
- menu_letter(char c) : letter(c) { }
-
- operator char () const { return letter; }
-
- const menu_letter &operator ++ ()
- {
- letter = letter == 'z'? 'A' :
- letter == 'Z'? 'a' :
- letter + 1;
- return *this;
- }
-
- menu_letter operator ++ (int postfix)
- {
- menu_letter copy = *this;
- this->operator++();
- return copy;
- }
-};
-
-struct item_def;
-struct MenuEntry
-{
- std::string text;
- int quantity, selected_qty;
- int colour;
- std::vector<int> hotkeys;
- MenuEntryLevel level;
- void *data;
-
- MenuEntry( const std::string &txt = std::string(""),
- MenuEntryLevel lev = MEL_ITEM,
- int qty = 0,
- int hotk = 0 ) :
- text(txt), quantity(qty), selected_qty(0), colour(-1),
- hotkeys(), level(lev), data(NULL)
- {
- colour = lev == MEL_ITEM? LIGHTGREY :
- lev == MEL_SUBTITLE? BLUE :
- WHITE;
- if (hotk)
- hotkeys.push_back( hotk );
- }
- virtual ~MenuEntry() { }
-
- void add_hotkey( int key )
- {
- if (key && !is_hotkey(key))
- hotkeys.push_back( key );
- }
-
- bool is_hotkey( int key ) const
- {
- return find( hotkeys.begin(), hotkeys.end(), key ) != hotkeys.end();
- }
-
- bool is_primary_hotkey( int key ) const
- {
- return hotkeys.size()? hotkeys[0] == key : false;
- }
-
- virtual std::string get_text() const
- {
- if (level == MEL_ITEM && hotkeys.size())
- {
- char buf[300];
- snprintf(buf, sizeof buf,
- "%c - %s", hotkeys[0], text.c_str());
- return std::string(buf);
- }
- return std::string(level == MEL_SUBTITLE? " " :
- level == MEL_ITEM? "" : " ") + text;
- }
-
- virtual bool selected() const
- {
- return selected_qty > 0 && quantity;
- }
-
- void select( int qty = -1 )
- {
- if (selected())
- selected_qty = 0;
- else if (quantity)
- selected_qty = qty == -1? quantity : qty;
- }
-};
-
-class MenuHighlighter
-{
-public:
- virtual int entry_colour(const MenuEntry *entry) const;
- virtual ~MenuHighlighter() { }
-};
-
-enum MenuFlag
-{
- MF_NOSELECT = 0, // No selection is permitted
- MF_SINGLESELECT = 1, // Select just one item
- MF_MULTISELECT = 2, // Select multiple items
- MF_NO_SELECT_QTY = 4, // Disallow partial selections
- MF_ANYPRINTABLE = 8, // Any printable character is valid, and
- // closes the menu.
- MF_SELECT_ANY_PAGE = 16, // Allow selections to occur on any page.
-
- MF_EASY_EXIT = 64
-};
-
-///////////////////////////////////////////////////////////////////////
-// NOTE
-// As a general contract, any pointers you pass to Menu methods are OWNED BY
-// THE MENU, and will be deleted by the Menu on destruction. So any pointers
-// you pass in MUST be allocated with new, or Crawl will crash.
-
-#define NUMBUFSIZ 10
-class Menu
-{
-public:
- Menu( int flags = MF_MULTISELECT );
- virtual ~Menu();
-
- void set_flags( int new_flags ) { this->flags = new_flags; }
- int get_flags() const { return flags; }
- bool is_set( int flag ) const;
-
- bool draw_title_suffix( const std::string &s, bool titlefirst = true );
- void update_title();
-
- void set_highlighter( MenuHighlighter *h );
- void set_title( MenuEntry *e );
- void add_entry( MenuEntry *entry );
- void get_selected( std::vector<MenuEntry*> *sel ) const;
-
- void set_select_filter( std::vector<text_pattern> filter )
- {
- select_filter = filter;
- }
-
- unsigned char getkey() const { return lastch; }
-
- void reset();
- std::vector<MenuEntry *> show();
-
-public:
- typedef std::string (*selitem_tfn)( const std::vector<MenuEntry*> *sel );
-
- selitem_tfn selitem_text;
-
-protected:
- MenuEntry *title;
- int flags;
-
- int first_entry, y_offset;
- int pagesize;
-
- std::vector<MenuEntry*> items;
- std::vector<MenuEntry*> *sel;
- std::vector<text_pattern> select_filter;
-
- // Class that is queried to colour menu entries.
- MenuHighlighter *highlighter;
-
- int num;
-
- unsigned char lastch;
-
- bool alive;
-
- void do_menu( std::vector<MenuEntry*> *selected );
- virtual void draw_select_count( int count );
- void draw_item( int index ) const;
- virtual void draw_title();
- void draw_menu( std::vector<MenuEntry*> *selected );
- bool page_down();
- bool line_down();
- bool page_up();
- bool line_up();
-
- void deselect_all(bool update_view = true);
- void select_items( int key, int qty = -1 );
- void select_index( int index, int qty = -1 );
-
- bool is_hotkey(int index, int key );
- bool is_selectable(int index) const;
-
- int item_colour(const MenuEntry *me) const;
-
- virtual bool process_key( int keyin );
-};
-
-int menu_colour(const std::string &itemtext);
-
-#endif
diff --git a/stone_soup/crawl-ref/source/message.cc b/stone_soup/crawl-ref/source/message.cc
deleted file mode 100644
index 353a069abc..0000000000
--- a/stone_soup/crawl-ref/source/message.cc
+++ /dev/null
@@ -1,640 +0,0 @@
-/*
- * File: message.cc
- * Summary: Functions used to print messages.
- * Written by: Linley Henzell
- *
- * Modified for Crawl Reference by $Author$ on $Date$
- *
- * Change History (most recent first):
- *
- * <3> 5/20/99 BWR Extended screen lines support
- * <2> 5/08/99 JDJ mpr takes a const char* instead of a char array.
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "message.h"
-#include "religion.h"
-
-#include <cstdarg>
-#include <cstring>
-
-#ifdef DOS
-#include <conio.h>
-#endif
-
-#include "externs.h"
-
-#include "initfile.h"
-#include "macro.h"
-#include "player.h"
-#include "stuff.h"
-#include "travel.h"
-#include "view.h"
-
-
-// circular buffer for keeping past messages
-message_item Store_Message[ NUM_STORED_MESSAGES ]; // buffer of old messages
-int Next_Message = 0; // end of messages
-
-char Message_Line = 0; // line of next (previous?) message
-
-static bool suppress_messages = false;
-
-no_messages::no_messages() : msuppressed(suppress_messages)
-{
- suppress_messages = true;
-}
-
-no_messages::~no_messages()
-{
- suppress_messages = msuppressed;
-}
-
-static char god_message_altar_colour( char god )
-{
- int rnd;
-
- switch (god)
- {
- case GOD_SHINING_ONE:
- return (YELLOW);
-
- case GOD_ZIN:
- return (WHITE);
-
- case GOD_ELYVILON:
- return (LIGHTBLUE); // really, LIGHTGREY but that's plain text
-
- case GOD_OKAWARU:
- return (CYAN);
-
- case GOD_YREDELEMNUL:
- return (coinflip() ? DARKGREY : RED);
-
- case GOD_KIKUBAAQUDGHA:
- return (DARKGREY);
-
- case GOD_XOM:
- return (random2(15) + 1);
-
- case GOD_VEHUMET:
- rnd = random2(3);
- return ((rnd == 0) ? LIGHTMAGENTA :
- (rnd == 1) ? LIGHTRED
- : LIGHTBLUE);
-
- case GOD_MAKHLEB:
- rnd = random2(3);
- return ((rnd == 0) ? RED :
- (rnd == 1) ? LIGHTRED
- : YELLOW);
-
- case GOD_TROG:
- return (RED);
-
- case GOD_NEMELEX_XOBEH:
- return (LIGHTMAGENTA);
-
- case GOD_SIF_MUNA:
- return (BLUE);
-
- case GOD_NO_GOD:
- default:
- return(YELLOW);
- }
-}
-
-#ifdef USE_COLOUR_MESSAGES
-
-// returns a colour or MSGCOL_MUTED
-static char channel_to_colour( int channel, int param )
-{
- char ret;
-
- switch (Options.channels[ channel ])
- {
- case MSGCOL_PLAIN:
- // note that if the plain channel is muted, then we're protecting
- // the player from having that spead to other other channels here.
- // The intent of plain is to give non-coloured messages, not to
- // supress them.
- if (Options.channels[ MSGCH_PLAIN ] >= MSGCOL_DEFAULT)
- ret = LIGHTGREY;
- else
- ret = Options.channels[ MSGCH_PLAIN ];
- break;
-
- case MSGCOL_DEFAULT:
- case MSGCOL_ALTERNATE:
- switch (channel)
- {
- case MSGCH_GOD:
- ret = (Options.channels[ channel ] == MSGCOL_DEFAULT)
- ? god_colour( param )
- : god_message_altar_colour( param );
- break;
-
- case MSGCH_DURATION:
- ret = LIGHTBLUE;
- break;
-
- case MSGCH_DANGER:
- ret = RED;
- break;
-
- case MSGCH_WARN:
- ret = LIGHTRED;
- break;
-
- case MSGCH_FOOD:
- ret = YELLOW;
- break;
-
- case MSGCH_INTRINSIC_GAIN:
- ret = GREEN;
- break;
-
- case MSGCH_RECOVERY:
- ret = LIGHTGREEN;
- break;
-
- case MSGCH_TALK:
- ret = WHITE;
- break;
-
- case MSGCH_MONSTER_SPELL:
- case MSGCH_MONSTER_ENCHANT:
- ret = LIGHTMAGENTA;
- break;
-
- case MSGCH_MONSTER_DAMAGE:
- ret = ((param == MDAM_DEAD) ? RED :
- (param >= MDAM_HORRIBLY_DAMAGED) ? LIGHTRED :
- (param >= MDAM_MODERATELY_DAMAGED) ? YELLOW
- : LIGHTGREY);
- break;
-
- case MSGCH_PROMPT:
- ret = CYAN;
- break;
-
- case MSGCH_DIAGNOSTICS:
- ret = DARKGREY; // makes is easier to ignore at times -- bwr
- break;
-
- case MSGCH_PLAIN:
- case MSGCH_ROTTEN_MEAT:
- case MSGCH_EQUIPMENT:
- default:
- ret = param > 0? param : LIGHTGREY;
- break;
- }
- break;
-
- case MSGCOL_MUTED:
- ret = MSGCOL_MUTED;
- break;
-
- default:
- // Setting to a specific colour is handled here, special
- // cases should be handled above.
- if (channel == MSGCH_MONSTER_DAMAGE)
- {
- // a special case right now for monster damage (at least until
- // the init system is improved)... selecting a specific
- // colour here will result in only the death messages coloured
- if (param == MDAM_DEAD)
- ret = Options.channels[ channel ];
- else if (Options.channels[ MSGCH_PLAIN ] >= MSGCOL_DEFAULT)
- ret = LIGHTGREY;
- else
- ret = Options.channels[ MSGCH_PLAIN ];
- }
- else
- ret = Options.channels[ channel ];
- break;
- }
-
- return (ret);
-}
-
-#else // don't use colour messages
-
-static char channel_to_colour( int channel, int param )
-{
- return (LIGHTGREY);
-}
-
-#endif
-
-static void do_message_print( int channel, int param,
- const char *format, va_list argp )
-{
- char buff[80];
- vsnprintf( buff, sizeof( buff ), format, argp );
- buff[79] = '\0';
-
- mpr(buff, channel, param);
-}
-
-void mprf( int channel, const char *format, ... )
-{
- va_list argp;
- va_start( argp, format );
- do_message_print( channel, 0, format, argp );
- va_end( argp );
-}
-
-void mprf( const char *format, ... )
-{
- va_list argp;
- va_start( argp, format );
- do_message_print( MSGCH_PLAIN, 0, format, argp );
- va_end( argp );
-}
-
-void mpr(const char *inf, int channel, int param)
-{
- if (suppress_messages)
- return;
-
- char info2[80];
-
- int colour = channel_to_colour( channel, param );
- if (colour == MSGCOL_MUTED)
- return;
-
- interrupt_activity( AI_MESSAGE, channel_to_str(channel) + ":" + inf );
-
- // If you're travelling, only certain user-specified messages can break
- // travel
- if (you.running < 0)
- {
- std::string message = inf;
- for (unsigned i = 0; i < Options.stop_travel.size(); ++i)
- {
- if (Options.stop_travel[i].is_filtered( channel, message ))
- {
- stop_running();
- break;
- }
- }
- }
-
- if (Options.sound_mappings.size() > 0)
- {
- std::string message = inf;
- for (unsigned i = 0; i < Options.sound_mappings.size(); i++)
- {
- // Maybe we should allow message channel matching as for
- // stop_travel?
- if (Options.sound_mappings[i].pattern.matches(message))
- {
- play_sound(Options.sound_mappings[i].soundfile.c_str());
- break;
- }
- }
- }
-
- flush_input_buffer( FLUSH_ON_MESSAGE );
-
-#ifdef DOS_TERM
- window(1, 1, 80, 25);
-#endif
-
- textcolor(LIGHTGREY);
-
- const int num_lines = get_number_of_lines();
-
- if (Message_Line == num_lines - 18) // ( Message_Line == 8 )
- more();
-
- gotoxy( (Options.delay_message_clear) ? 2 : 1, Message_Line + 18 );
- strncpy(info2, inf, 78);
- info2[78] = 0;
-
- textcolor( colour );
- cprintf(info2);
- //
- // reset colour
- textcolor(LIGHTGREY);
-
- Message_Line++;
-
- if (Options.delay_message_clear
- && channel != MSGCH_PROMPT
- && Message_Line == num_lines - 18)
- {
- more();
- }
-
- // equipment lists just waste space in the message recall
- if (channel != MSGCH_EQUIPMENT)
- {
- /* Put the message into Store_Message, and move the '---' line forward */
- Store_Message[ Next_Message ].text = inf;
- Store_Message[ Next_Message ].channel = channel;
- Store_Message[ Next_Message ].param = param;
- Next_Message++;
-
- if (Next_Message >= NUM_STORED_MESSAGES)
- Next_Message = 0;
- }
-} // end mpr()
-
-bool any_messages(void)
-{
- return (Message_Line > 0);
-}
-
-void mesclr( bool force )
-{
- // if no messages, return.
- if (!any_messages())
- return;
-
- if (!force && Options.delay_message_clear)
- {
- gotoxy( 1, Message_Line + 18 );
- textcolor( channel_to_colour( MSGCH_PLAIN, 0 ) );
- cprintf( ">" );
- return;
- }
-
- // turn cursor off -- avoid 'cursor dance'
- _setcursortype(_NOCURSOR);
-
-#ifdef DOS_TERM
- window(1, 18, 78, 25);
- clrscr();
- window(1, 1, 80, 25);
-#endif
-
-#ifdef PLAIN_TERM
- int startLine = 18;
-
- gotoxy(1, startLine);
-
-#ifdef UNIX
- clear_to_end_of_screen();
-#else
-
- int numLines = get_number_of_lines() - startLine + 1;
-
- char blankline[81];
- memset(blankline, ' ', sizeof blankline);
- blankline[80] = 0;
-
- for (int i = 0; i < numLines; i++)
- {
- cprintf( blankline );
-
- if (i < numLines - 1)
- {
- cprintf(EOL);
- }
- }
-#endif
-#endif
-
- // turn cursor back on
- _setcursortype(_NORMALCURSOR);
-
- Message_Line = 0;
-} // end mseclr()
-
-void more(void)
-{
- char keypress = 0;
-
-#ifdef PLAIN_TERM
- gotoxy( 2, get_number_of_lines() );
-#endif
-
-#ifdef DOS_TERM
- window(1, 18, 80, 25);
- gotoxy(2, 7);
-#endif
-
- textcolor(LIGHTGREY);
-
-#ifdef DOS
- cprintf(EOL);
-#endif
- cprintf("--more--");
-
- do
- {
- keypress = getch();
- }
- while (keypress != ' ' && keypress != '\r' && keypress != '\n');
-
- mesclr( (Message_Line >= get_number_of_lines() - 18) );
-} // end more()
-
-std::string get_last_messages(int mcount)
-{
- if (mcount <= 0) return std::string();
- if (mcount > NUM_STORED_MESSAGES) mcount = NUM_STORED_MESSAGES;
-
- bool full_buffer = Store_Message[ NUM_STORED_MESSAGES - 1 ].text.length() == 0;
- int initial = Next_Message - mcount;
- if (initial < 0 || initial > NUM_STORED_MESSAGES)
- initial = full_buffer? initial + NUM_STORED_MESSAGES : 0;
-
- std::string text;
- int count = 0;
- for (int i = initial; i != Next_Message; )
- {
- if (Store_Message[i].text.length())
- {
- text += Store_Message[i].text;
- text += EOL;
- count++;
- }
-
- if (++i >= NUM_STORED_MESSAGES)
- i -= NUM_STORED_MESSAGES;
- }
-
- // An extra line of clearance.
- if (count) text += EOL;
-
- return text;
-}
-
-void replay_messages(void)
-{
- int win_start_line = 0;
- unsigned char keyin;
-
- bool full_buffer = true;
- int num_msgs = NUM_STORED_MESSAGES;
- int first_message = Next_Message;
-
- const int num_lines = get_number_of_lines();
-
- if (Store_Message[ NUM_STORED_MESSAGES - 1 ].text.length() == 0)
- {
- full_buffer = false;
- first_message = 0;
- num_msgs = Next_Message;
- }
-
- int last_message = Next_Message - 1;
- if (last_message < 0)
- last_message += NUM_STORED_MESSAGES;
-
-#ifdef DOS_TERM
- char buffer[4800];
-
- window(1, 1, 80, 25);
- gettext(1, 1, 80, 25, buffer);
-#endif
-
- // track back a screen's worth of messages from the end
- win_start_line = Next_Message - (num_lines - 2);
- if (win_start_line < 0)
- {
- if (full_buffer)
- win_start_line += NUM_STORED_MESSAGES;
- else
- win_start_line = 0;
- }
-
- for(;;)
- {
- // turn cursor off
- _setcursortype(_NOCURSOR);
-
- clrscr();
-
- gotoxy(1, 1);
-
- for (int i = 0; i < num_lines - 2; i++)
- {
- // calculate line in circular buffer
- int line = win_start_line + i;
- if (line >= NUM_STORED_MESSAGES)
- line -= NUM_STORED_MESSAGES;
-
- // avoid wrap-around
- if (line == first_message && i != 0)
- break;
-
- int colour = channel_to_colour( Store_Message[ line ].channel,
- Store_Message[ line ].param );
- if (colour == MSGCOL_MUTED)
- continue;
-
- textcolor( colour );
-
-#if DEBUG_DIAGNOSTICS
- cprintf( "%d: %s", line, Store_Message[ line ].text.c_str() );
-#else
- cprintf( Store_Message[ line ].text.c_str() );
-#endif
-
- cprintf(EOL);
- textcolor(LIGHTGREY);
- }
-
- // print a footer -- note: relative co-ordinates start at 1
- int rel_start;
- if (!full_buffer)
- {
- if (Next_Message == 0) // no messages!
- rel_start = 0;
- else
- rel_start = win_start_line + 1;
- }
- else if (win_start_line >= first_message)
- rel_start = win_start_line - first_message + 1;
- else
- rel_start = (win_start_line + NUM_STORED_MESSAGES) - first_message + 1;
-
- int rel_end = rel_start + (num_lines - 2) - 1;
- if (rel_end > num_msgs)
- rel_end = num_msgs;
-
- cprintf( "-------------------------------------------------------------------------------" );
- cprintf(EOL);
- cprintf( "<< Lines %d-%d of %d >>", rel_start, rel_end, num_msgs );
-
- // turn cursor back on
- _setcursortype(_NORMALCURSOR);
-
- keyin = get_ch();
-
- if ((full_buffer && NUM_STORED_MESSAGES > num_lines - 2)
- || (!full_buffer && Next_Message > num_lines - 2))
- {
- int new_line;
- int end_mark;
-
- if (keyin == 'k' || keyin == '8' || keyin == '-')
- {
- new_line = win_start_line - (num_lines - 2);
-
- // end_mark is equivalent to Next_Message, but
- // is always less than win_start_line.
- end_mark = first_message;
- if (end_mark > win_start_line)
- end_mark -= NUM_STORED_MESSAGES;
-
- ASSERT( end_mark <= win_start_line );
-
- if (new_line <= end_mark)
- new_line = end_mark; // hit top
-
- // handle wrap-around
- if (new_line < 0)
- {
- if (full_buffer)
- new_line += NUM_STORED_MESSAGES;
- else
- new_line = 0;
- }
- }
- else if (keyin == 'j' || keyin == '2' || keyin == '+')
- {
- new_line = win_start_line + (num_lines - 2);
-
- // as above, but since we're adding we want
- // this mark to always be greater.
- end_mark = last_message;
- if (end_mark < win_start_line)
- end_mark += NUM_STORED_MESSAGES;
-
- ASSERT( end_mark >= win_start_line );
-
- // hit bottom
- if (new_line >= end_mark - (num_lines - 2))
- new_line = end_mark - (num_lines - 2) + 1;
-
- if (new_line >= NUM_STORED_MESSAGES)
- new_line -= NUM_STORED_MESSAGES;
- }
- else
- break;
-
- win_start_line = new_line;
- }
- else
- {
- if (keyin != 'k' && keyin != '8' && keyin != '-'
- && keyin != 'j' && keyin != '2' && keyin != '+')
- {
- break;
- }
- }
- }
-
-
-#ifdef DOS_TERM
- puttext(1, 1, 80, 25, buffer);
-#endif
-
- return;
-} // end replay_messages()
diff --git a/stone_soup/crawl-ref/source/message.h b/stone_soup/crawl-ref/source/message.h
deleted file mode 100644
index 83f7787d35..0000000000
--- a/stone_soup/crawl-ref/source/message.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * File: message.cc
- * Summary: Functions used to print messages.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <2> 5/08/99 JDJ mpr takes a const char* instead of a char array.
- * <1> -/--/-- LRH Created
- */
-
-#ifndef MESSAGE_H
-#define MESSAGE_H
-
-#include <string>
-
-#include "externs.h"
-
-struct message_item {
- int channel; // message channel
- int param; // param for channel (god, enchantment)
- std::string text; // text of message
-};
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: ability - acr - command - direct - effects - item_use -
- * misc - player - spell - spl-book - spells1 - spells2 -
- * spells3
- * *********************************************************************** */
-void mesclr( bool force = false );
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - bang - beam - decks - fight - files - it_use3 -
- * item_use - items - message - misc - ouch - player -
- * religion - spell - spells - spells2 - spells3
- * *********************************************************************** */
-void more(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: ability - acr - bang - beam - chardump - command - debug -
- * decks - direct - effects - fight - files - food - it_use2 -
- * it_use3 - item_use - items - macro - misc - monplace -
- * monstuff - mstuff2 - mutation - ouch - overmap - player -
- * religion - shopping - skills - spell - spl-book - spells -
- * spells1 - spells2 - spells3 - spells4 - stuff - transfor -
- * view
- * *********************************************************************** */
-void mpr(const char *inf, int channel = MSGCH_PLAIN, int param = 0);
-
-// 4.1-style mpr, currently named mprf for minimal disruption.
-void mprf( int channel, const char *format, ... );
-void mprf( const char *format, ... );
-
-class no_messages
-{
-public:
- no_messages();
- ~no_messages();
-private:
- bool msuppressed;
-};
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void replay_messages(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - it_use3 - items - religion
- * *********************************************************************** */
-void set_colour(char set_message_colour);
-
-
-// last updated 18mar2001 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-bool any_messages(void);
-
-// last updated 13oct2003 {dlb}
-/* ***********************************************************************
- * called from: chardump
- * *********************************************************************** */
-std::string get_last_messages(int mcount);
-
-#endif
diff --git a/stone_soup/crawl-ref/source/misc.cc b/stone_soup/crawl-ref/source/misc.cc
deleted file mode 100644
index 4fd3083df2..0000000000
--- a/stone_soup/crawl-ref/source/misc.cc
+++ /dev/null
@@ -1,1962 +0,0 @@
-/*
- * File: misc.cc
- * Summary: Misc functions.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <3> 11/14/99 cdl evade with random40(ev) vice random2(ev)
- * <2> 5/20/99 BWR Multi-user support, new berserk code.
- * <1> -/--/-- LRH Created
- */
-
-
-#include "AppHdr.h"
-#include "misc.h"
-
-#include <string.h>
-#if !(defined(__IBMCPP__) || defined(__BCPLUSPLUS__))
-#include <unistd.h>
-#endif
-
-#ifdef __MINGW32__
-#include <io.h>
-#endif
-
-#include <stdlib.h>
-#include <stdio.h>
-
-#ifdef DOS
-#include <conio.h>
-#endif
-
-#include "externs.h"
-
-#include "cloud.h"
-#include "delay.h"
-#include "fight.h"
-#include "files.h"
-#include "food.h"
-#include "it_use2.h"
-#include "items.h"
-#include "itemname.h"
-#include "lev-pand.h"
-#include "macro.h"
-#include "monplace.h"
-#include "mon-util.h"
-#include "monstuff.h"
-#include "ouch.h"
-#include "player.h"
-#include "shopping.h"
-#include "skills.h"
-#include "skills2.h"
-#include "spells3.h"
-#include "spl-cast.h"
-#include "stuff.h"
-#include "transfor.h"
-#include "travel.h"
-#include "view.h"
-
-
-bool scramble(void);
-bool trap_item(char base_type, char sub_type, char beam_x, char beam_y);
-static void dart_trap(bool trap_known, int trapped, struct bolt &pbolt, bool poison);
-
-// void place_chunks(int mcls, unsigned char rot_status, unsigned char chx,
-// unsigned char chy, unsigned char ch_col)
-void turn_corpse_into_chunks( item_def &item )
-{
- const int mons_class = item.plus;
- const int max_chunks = mons_weight( mons_class ) / 150;
-
- ASSERT( item.base_type == OBJ_CORPSES );
-
- item.base_type = OBJ_FOOD;
- item.sub_type = FOOD_CHUNK;
- item.quantity = 1 + random2( max_chunks );
-
- item.quantity = stepdown_value( item.quantity, 4, 4, 12, 12 );
-
- // seems to me that this should come about only
- // after the corpse has been butchered ... {dlb}
- if (monster_descriptor( mons_class, MDSC_LEAVES_HIDE ) && !one_chance_in(3))
- {
- int o = get_item_slot( 100 + random2(200) );
- if (o == NON_ITEM)
- return;
-
- mitm[o].quantity = 1;
-
- // these values are common to all: {dlb}
- mitm[o].base_type = OBJ_ARMOUR;
- mitm[o].plus = 0;
- mitm[o].plus2 = 0;
- mitm[o].special = 0;
- mitm[o].flags = 0;
- mitm[o].colour = mons_colour( mons_class );
-
- // these values cannot be set by a reasonable formula: {dlb}
- switch (mons_class)
- {
- case MONS_DRAGON:
- mitm[o].sub_type = ARM_DRAGON_HIDE;
- break;
- case MONS_TROLL:
- mitm[o].sub_type = ARM_TROLL_HIDE;
- break;
- case MONS_ICE_DRAGON:
- mitm[o].sub_type = ARM_ICE_DRAGON_HIDE;
- break;
- case MONS_STEAM_DRAGON:
- mitm[o].sub_type = ARM_STEAM_DRAGON_HIDE;
- break;
- case MONS_MOTTLED_DRAGON:
- mitm[o].sub_type = ARM_MOTTLED_DRAGON_HIDE;
- break;
- case MONS_STORM_DRAGON:
- mitm[o].sub_type = ARM_STORM_DRAGON_HIDE;
- break;
- case MONS_GOLDEN_DRAGON:
- mitm[o].sub_type = ARM_GOLD_DRAGON_HIDE;
- break;
- case MONS_SWAMP_DRAGON:
- mitm[o].sub_type = ARM_SWAMP_DRAGON_HIDE;
- break;
- default:
- // future implementation {dlb}
- mitm[o].sub_type = ARM_ANIMAL_SKIN;
- break;
- }
-
- move_item_to_grid( &o, item.x, item.y );
- }
-} // end place_chunks()
-
-bool grid_is_opaque( int grid )
-{
- return (grid < MINSEE && grid != DNGN_ORCISH_IDOL);
-}
-
-bool grid_is_solid( int grid )
-{
- return (grid < MINMOVE);
-}
-
-bool grid_is_water( int grid )
-{
- return (grid == DNGN_SHALLOW_WATER || grid == DNGN_DEEP_WATER);
-}
-
-bool grid_destroys_items( int grid )
-{
- return (grid == DNGN_LAVA || grid == DNGN_DEEP_WATER);
-}
-
-const char *grid_item_destruction_message( unsigned char grid )
-{
- return grid == DNGN_DEEP_WATER? "You hear a splash."
- : grid == DNGN_LAVA ? "You hear a sizzling splash."
- : "You hear an empty echo.";
-}
-
-void search_around(void)
-{
- char srx = 0;
- char sry = 0;
- int i;
-
- // Never if doing something else... this prevents a slight asymetry
- // where using autopickup was giving free searches in comparison to
- // not using autopickup. -- bwr
- if (you_are_delayed())
- return;
-
- for (srx = you.x_pos - 1; srx < you.x_pos + 2; srx++)
- {
- for (sry = you.y_pos - 1; sry < you.y_pos + 2; sry++)
- {
- // don't exclude own square; may be levitating
- if (grd[srx][sry] == DNGN_SECRET_DOOR
- && random2(17) <= 1 + you.skills[SK_TRAPS_DOORS])
- {
- grd[srx][sry] = DNGN_CLOSED_DOOR;
- mpr("You found a secret door!");
- exercise(SK_TRAPS_DOORS, ((coinflip())? 2 : 1));
- }
-
- if (grd[srx][sry] == DNGN_UNDISCOVERED_TRAP
- && random2(17) <= 1 + you.skills[SK_TRAPS_DOORS])
- {
- i = trap_at_xy(srx, sry);
-
- if (i != -1)
- grd[srx][sry] = trap_category(env.trap[i].type);
-
- mpr("You found a trap!");
- }
- }
- }
-
- return;
-} // end search_around()
-
-void in_a_cloud(void)
-{
- int cl = env.cgrid[you.x_pos][you.y_pos];
- int hurted = 0;
- int resist;
-
- if (you.duration[DUR_CONDENSATION_SHIELD] > 0)
- {
- mpr("Your icy shield dissipates!", MSGCH_DURATION);
- you.duration[DUR_CONDENSATION_SHIELD] = 0;
- you.redraw_armour_class = 1;
- }
-
- switch (env.cloud[cl].type)
- {
- case CLOUD_FIRE:
- case CLOUD_FIRE_MON:
- if (you.fire_shield)
- return;
-
- mpr("You are engulfed in roaring flames!");
-
- resist = player_res_fire();
-
- if (resist <= 0)
- {
- hurted += ((random2avg(23, 3) + 10) * you.time_taken) / 10;
-
- if (resist < 0)
- hurted += ((random2avg(14, 2) + 3) * you.time_taken) / 10;
-
- hurted -= random2(player_AC());
-
- if (hurted < 1)
- hurted = 0;
- else
- ouch( hurted, cl, KILLED_BY_CLOUD, "flame" );
- }
- else
- {
- canned_msg(MSG_YOU_RESIST);
- hurted += ((random2avg(23, 3) + 10) * you.time_taken) / 10;
- hurted /= (1 + resist * resist);
- ouch( hurted, cl, KILLED_BY_CLOUD, "flame" );
- }
- scrolls_burn(7, OBJ_SCROLLS);
- break;
-
- case CLOUD_STINK:
- case CLOUD_STINK_MON:
- // If you don't have to breathe, unaffected
- mpr("You are engulfed in noxious fumes!");
- if (player_res_poison())
- break;
-
- hurted += (random2(3) * you.time_taken) / 10;
- if (hurted < 1)
- hurted = 0;
- else
- ouch( (hurted * you.time_taken) / 10, cl, KILLED_BY_CLOUD,
- "noxious fumes" );
-
- if (1 + random2(27) >= you.experience_level)
- {
- mpr("You choke on the stench!");
- confuse_player( (coinflip() ? 3 : 2) );
- }
- break;
-
- case CLOUD_COLD:
- case CLOUD_COLD_MON:
- mpr("You are engulfed in freezing vapours!");
-
- resist = player_res_cold();
-
- if (resist <= 0)
- {
- hurted += ((random2avg(23, 3) + 10) * you.time_taken) / 10;
-
- if (resist < 0)
- hurted += ((random2avg(14, 2) + 3) * you.time_taken) / 10;
-
- hurted -= random2(player_AC());
- if (hurted < 0)
- hurted = 0;
-
- ouch( (hurted * you.time_taken) / 10, cl, KILLED_BY_CLOUD,
- "freezing vapour" );
- }
- else
- {
- canned_msg(MSG_YOU_RESIST);
- hurted += ((random2avg(23, 3) + 10) * you.time_taken) / 10;
- hurted /= (1 + resist * resist);
- ouch( hurted, cl, KILLED_BY_CLOUD, "freezing vapour" );
- }
- scrolls_burn(7, OBJ_POTIONS);
- break;
-
- case CLOUD_POISON:
- case CLOUD_POISON_MON:
- // If you don't have to breathe, unaffected
- mpr("You are engulfed in poison gas!");
- if (!player_res_poison())
- {
- ouch( (random2(10) * you.time_taken) / 10, cl, KILLED_BY_CLOUD,
- "poison gas" );
- poison_player(1);
- }
- break;
-
- case CLOUD_GREY_SMOKE:
- case CLOUD_BLUE_SMOKE:
- case CLOUD_PURP_SMOKE:
- case CLOUD_BLACK_SMOKE:
- case CLOUD_GREY_SMOKE_MON:
- case CLOUD_BLUE_SMOKE_MON:
- case CLOUD_PURP_SMOKE_MON:
- case CLOUD_BLACK_SMOKE_MON:
- mpr("You are engulfed in a cloud of smoke!");
- break;
-
- case CLOUD_STEAM:
- case CLOUD_STEAM_MON:
- mpr("You are engulfed in a cloud of scalding steam!");
- if (you.species == SP_PALE_DRACONIAN && you.experience_level > 5)
- {
- mpr("It doesn't seem to affect you.");
- return;
- }
-
- if (player_equip( EQ_BODY_ARMOUR, ARM_STEAM_DRAGON_ARMOUR ))
- {
- mpr("It doesn't seem to affect you.");
- return;
- }
-
- hurted += (random2(6) * you.time_taken) / 10;
- if (hurted < 0 || player_res_fire() > 0)
- hurted = 0;
-
- ouch( (hurted * you.time_taken) / 10, cl, KILLED_BY_CLOUD, "poison gas" );
- break;
-
- case CLOUD_MIASMA:
- case CLOUD_MIASMA_MON:
- mpr("You are engulfed in a dark miasma.");
-
- if (player_prot_life() > random2(3))
- return;
-
- poison_player(1);
-
- hurted += (random2avg(12, 3) * you.time_taken) / 10; // 3
-
- if (hurted < 0)
- hurted = 0;
-
- ouch( hurted, cl, KILLED_BY_CLOUD, "foul pestilence" );
- potion_effect(POT_SLOWING, 5);
-
- if (you.hp_max > 4 && coinflip())
- rot_hp(1);
-
- break;
- }
-
- return;
-} // end in_a_cloud()
-
-void curare_hits_player(int agent, int degree)
-{
- const bool res_poison = player_res_poison();
-
- poison_player(degree);
-
- if (!player_res_asphyx())
- {
- int hurted = roll_dice(2, 6);
- // Note that the hurtage is halved by poison resistance.
- if (res_poison)
- hurted /= 2;
-
- if (hurted)
- {
- mpr("You feel difficulty breathing.");
- ouch( hurted, agent, KILLED_BY_CURARE, "curare-induced apnoea" );
- }
- potion_effect(POT_SLOWING, 2 + random2(4 + degree));
- }
-}
-
-void merfolk_start_swimming(void)
-{
- FixedVector < char, 8 > removed;
-
- if (you.attribute[ATTR_TRANSFORMATION] != TRAN_NONE)
- untransform();
-
- for (int i = EQ_WEAPON; i < EQ_RIGHT_RING; i++)
- {
- removed[i] = 0;
- }
-
- if (you.equip[EQ_BOOTS] != -1)
- removed[EQ_BOOTS] = 1;
-
- // Perhaps a bit to easy for the player, but we allow merfolk
- // to slide out of heavy body armour freely when entering water,
- // rather than handling emcumbered swimming. -- bwr
- if (!player_light_armour())
- {
- // Can't slide out of just the body armour, cloak comes off -- bwr
- if (you.equip[EQ_CLOAK])
- removed[EQ_CLOAK] = 1;
-
- removed[EQ_BODY_ARMOUR] = 1;
- }
-
- remove_equipment(removed);
-}
-
-void up_stairs(void)
-{
- unsigned char stair_find = grd[you.x_pos][you.y_pos];
- char old_where = you.where_are_you;
- bool was_a_labyrinth = false;
-
- if (stair_find == DNGN_ENTER_SHOP)
- {
- shop();
- return;
- }
-
- // probably still need this check here (teleportation) -- bwr
- if ((stair_find < DNGN_STONE_STAIRS_UP_I
- || stair_find > DNGN_ROCK_STAIRS_UP)
- && (stair_find < DNGN_RETURN_FROM_ORCISH_MINES || stair_find >= 150))
- {
- mpr("You can't go up here.");
- return;
- }
-
- // Since the overloaded message set turn_is_over, I'm assuming that
- // the overloaded character makes an attempt... so we're doing this
- // check before that one. -- bwr
- if (!player_is_levitating()
- && you.conf
- && (stair_find >= DNGN_STONE_STAIRS_UP_I
- && stair_find <= DNGN_ROCK_STAIRS_UP)
- && random2(100) > you.dex)
- {
- mpr("In your confused state, you trip and fall back down the stairs.");
-
- ouch( roll_dice( 3 + you.burden_state, 5 ), 0,
- KILLED_BY_FALLING_DOWN_STAIRS );
-
- you.turn_is_over = 1;
- return;
- }
-
- if (you.burden_state == BS_OVERLOADED)
- {
- mpr("You are carrying too much to climb upwards.");
- you.turn_is_over = 1;
- return;
- }
-
- if (you.your_level == 0
- && !yesno("Are you sure you want to leave the Dungeon?", false, 'n'))
- {
- mpr("Alright, then stay!");
- return;
- }
-
- unsigned char old_level = you.your_level;
-
- // Interlevel travel data:
- bool collect_travel_data = you.level_type != LEVEL_LABYRINTH
- && you.level_type != LEVEL_ABYSS
- && you.level_type != LEVEL_PANDEMONIUM;
-
- level_id old_level_id = level_id::get_current_level_id();
- LevelInfo &old_level_info = travel_cache.get_level_info(old_level_id);
- int stair_x = you.x_pos, stair_y = you.y_pos;
- if (collect_travel_data)
- old_level_info.update();
-
- // Make sure we return to our main dungeon level... labyrinth entrances
- // in the abyss or pandemonium a bit trouble (well the labyrinth does
- // provide a way out of those places, its really not that bad I suppose)
- if (you.level_type == LEVEL_LABYRINTH)
- {
- you.level_type = LEVEL_DUNGEON;
- was_a_labyrinth = true;
- }
-
- you.your_level--;
-
- int i = 0;
-
- if (you.your_level < 0)
- {
- mpr("You have escaped!");
-
- for (i = 0; i < ENDOFPACK; i++)
- {
- if (is_valid_item( you.inv[i] )
- && you.inv[i].base_type == OBJ_ORBS)
- {
- ouch(-9999, 0, KILLED_BY_WINNING);
- }
- }
-
- ouch(-9999, 0, KILLED_BY_LEAVING);
- }
-
- mpr("Entering...");
- you.prev_targ = MHITNOT;
- you.pet_target = MHITNOT;
-
- if (player_in_branch( BRANCH_VESTIBULE_OF_HELL ))
- {
- mpr("Thank you for visiting Hell. Please come again soon.");
- you.where_are_you = BRANCH_MAIN_DUNGEON;
- you.your_level = you.hell_exit;
- stair_find = DNGN_STONE_STAIRS_UP_I;
- }
-
- if (player_in_hell())
- {
- you.where_are_you = BRANCH_VESTIBULE_OF_HELL;
- you.your_level = 27;
- }
-
- switch (stair_find)
- {
- case DNGN_RETURN_FROM_ORCISH_MINES:
- case DNGN_RETURN_FROM_HIVE:
- case DNGN_RETURN_FROM_LAIR:
- case DNGN_RETURN_FROM_VAULTS:
- case DNGN_RETURN_FROM_TEMPLE:
- case DNGN_RETURN_FROM_ZOT:
- mpr("Welcome back to the Dungeon!");
- you.where_are_you = BRANCH_MAIN_DUNGEON;
- break;
- case DNGN_RETURN_FROM_SLIME_PITS:
- case DNGN_RETURN_FROM_SNAKE_PIT:
- case DNGN_RETURN_FROM_SWAMP:
- mpr("Welcome back to the Lair of Beasts!");
- you.where_are_you = BRANCH_LAIR;
- break;
- case DNGN_RETURN_FROM_CRYPT:
- case DNGN_RETURN_FROM_HALL_OF_BLADES:
- mpr("Welcome back to the Vaults!");
- you.where_are_you = BRANCH_VAULTS;
- break;
- case DNGN_RETURN_FROM_TOMB:
- mpr("Welcome back to the Crypt!");
- you.where_are_you = BRANCH_CRYPT;
- break;
- case DNGN_RETURN_FROM_ELVEN_HALLS:
- mpr("Welcome back to the Orcish Mines!");
- you.where_are_you = BRANCH_ORCISH_MINES;
- break;
- }
-
- unsigned char stair_taken = stair_find;
-
- if (player_is_levitating())
- {
- if (you.duration[DUR_CONTROLLED_FLIGHT])
- mpr("You fly upwards.");
- else
- mpr("You float upwards... And bob straight up to the ceiling!");
- }
- else
- mpr("You climb upwards.");
-
- load(stair_taken, LOAD_ENTER_LEVEL, was_a_labyrinth, old_level, old_where);
-
- you.turn_is_over = 1;
-
- save_game(false);
-
- new_level();
-
- viewwindow(1, true);
-
- if (you.skills[SK_TRANSLOCATIONS] > 0 && !allow_control_teleport( true ))
- mpr( "You sense a powerful magical force warping space.", MSGCH_WARN );
-
- // Tell the travel code that we're now on a new level
- travel_init_new_level();
- if (collect_travel_data)
- {
- // Update stair information for the stairs we just ascended, and the
- // down stairs we're currently on.
- level_id new_level_id = level_id::get_current_level_id();
-
- if (you.level_type != LEVEL_PANDEMONIUM &&
- you.level_type != LEVEL_ABYSS &&
- you.level_type != LEVEL_LABYRINTH)
- {
- LevelInfo &new_level_info =
- travel_cache.get_level_info(new_level_id);
- new_level_info.update();
-
- // First we update the old level's stair.
- level_pos lp;
- lp.id = new_level_id;
- lp.pos.x = you.x_pos;
- lp.pos.y = you.y_pos;
-
- bool guess = false;
- // Ugly hack warning:
- // The stairs in the Vestibule of Hell exhibit special behaviour:
- // they always lead back to the dungeon level that the player
- // entered the Vestibule from. This means that we need to pretend
- // we don't know where the upstairs from the Vestibule go each time
- // we take it. If we don't, interlevel travel may try to use portals
- // to Hell as shortcuts between dungeon levels, which won't work,
- // and will confuse the dickens out of the player (well, it confused
- // the dickens out of me when it happened).
- if (new_level_id.branch == BRANCH_MAIN_DUNGEON &&
- old_level_id.branch == BRANCH_VESTIBULE_OF_HELL)
- {
- lp.id.depth = -1;
- lp.pos.x = lp.pos.y = -1;
- guess = true;
- }
-
- old_level_info.update_stair(stair_x, stair_y, lp, guess);
-
- // We *guess* that going up a staircase lands us on a downstair,
- // and that we can descend that downstair and get back to where we
- // came from. This assumption is guaranteed false when climbing out
- // of one of the branches of Hell.
- if (new_level_id.branch != BRANCH_VESTIBULE_OF_HELL)
- {
- // Set the new level's stair, assuming arbitrarily that going
- // downstairs will land you on the same upstairs you took to
- // begin with (not necessarily true).
- lp.id = old_level_id;
- lp.pos.x = stair_x;
- lp.pos.y = stair_y;
- new_level_info.update_stair(you.x_pos, you.y_pos, lp, true);
- }
- }
- }
-} // end up_stairs()
-
-void down_stairs( bool remove_stairs, int old_level, bool force )
-{
- int i;
- char old_level_type = you.level_type;
- bool was_a_labyrinth = false;
- const unsigned char stair_find = grd[you.x_pos][you.y_pos];
-
- //int old_level = you.your_level;
- bool leave_abyss_pan = false;
- char old_where = you.where_are_you;
-
-#ifdef SHUT_LABYRINTH
- if (stair_find == DNGN_ENTER_LABYRINTH)
- {
- mpr("Sorry, this section of the dungeon is closed for fumigation.");
- mpr("Try again next release.");
- return;
- }
-#endif
-
- // probably still need this check here (teleportation) -- bwr
- if ((stair_find < DNGN_ENTER_LABYRINTH
- || stair_find > DNGN_ROCK_STAIRS_DOWN)
- && stair_find != DNGN_ENTER_HELL
- && ((stair_find < DNGN_ENTER_DIS
- || stair_find > DNGN_TRANSIT_PANDEMONIUM)
- && stair_find != DNGN_STONE_ARCH)
- && !(stair_find >= DNGN_ENTER_ORCISH_MINES
- && stair_find < DNGN_RETURN_FROM_ORCISH_MINES))
- {
- mpr( "You can't go down here!" );
- return;
- }
-
- if (stair_find >= DNGN_ENTER_LABYRINTH
- && stair_find <= DNGN_ROCK_STAIRS_DOWN
- && player_in_branch( BRANCH_VESTIBULE_OF_HELL ))
- {
- mpr("A mysterious force prevents you from descending the staircase.");
- return;
- } /* down stairs in vestibule are one-way */
-
- if (stair_find == DNGN_STONE_ARCH)
- {
- mpr("You can't go down here!");
- return;
- }
-
- if (!force && player_is_levitating()
- && !wearing_amulet(AMU_CONTROLLED_FLIGHT))
- {
- mpr("You're floating high up above the floor!");
- return;
- }
-
- if (stair_find == DNGN_ENTER_ZOT)
- {
- int num_runes = 0;
-
- for (i = 0; i < ENDOFPACK; i++)
- {
- if (is_valid_item( you.inv[i] )
- && you.inv[i].base_type == OBJ_MISCELLANY
- && you.inv[i].sub_type == MISC_RUNE_OF_ZOT)
- {
- num_runes += you.inv[i].quantity;
- }
- }
-
- if (num_runes < NUMBER_OF_RUNES_NEEDED)
- {
- switch (NUMBER_OF_RUNES_NEEDED)
- {
- case 1:
- mpr("You need a Rune to enter this place.");
- break;
-
- default:
- snprintf( info, INFO_SIZE,
- "You need at least %d Runes to enter this place.",
- NUMBER_OF_RUNES_NEEDED );
-
- mpr(info);
- }
- return;
- }
- }
-
- // Interlevel travel data:
- bool collect_travel_data = you.level_type != LEVEL_LABYRINTH
- && you.level_type != LEVEL_ABYSS
- && you.level_type != LEVEL_PANDEMONIUM;
-
- level_id old_level_id = level_id::get_current_level_id();
- LevelInfo &old_level_info = travel_cache.get_level_info(old_level_id);
- int stair_x = you.x_pos, stair_y = you.y_pos;
- if (collect_travel_data)
- old_level_info.update();
-
-
- if (you.level_type == LEVEL_PANDEMONIUM
- && stair_find == DNGN_TRANSIT_PANDEMONIUM)
- {
- was_a_labyrinth = true;
- }
- else
- {
- if (you.level_type != LEVEL_DUNGEON)
- was_a_labyrinth = true;
-
- you.level_type = LEVEL_DUNGEON;
- }
-
- mpr("Entering...");
- you.prev_targ = MHITNOT;
- you.pet_target = MHITNOT;
-
- if (stair_find == DNGN_ENTER_HELL)
- {
- you.where_are_you = BRANCH_VESTIBULE_OF_HELL;
- you.hell_exit = you.your_level;
-
- mpr("Welcome to Hell!");
- mpr("Please enjoy your stay.");
-
- // Kill -more- prompt if we're traveling.
- if (!you.running)
- more();
-
- you.your_level = 26; // = 59;
- }
-
- if ((stair_find >= DNGN_ENTER_DIS
- && stair_find <= DNGN_ENTER_TARTARUS)
- || (stair_find >= DNGN_ENTER_ORCISH_MINES
- && stair_find < DNGN_RETURN_FROM_ORCISH_MINES))
- {
- // no idea why such a huge switch and not 100-grd[][]
- // planning ahead for re-organizaing grd[][] values - 13jan2000 {dlb}
- strcpy( info, "Welcome to " );
- switch (stair_find)
- {
- case DNGN_ENTER_DIS:
- strcat(info, "the Iron City of Dis!");
- you.where_are_you = BRANCH_DIS;
- you.your_level = 26;
- break;
- case DNGN_ENTER_GEHENNA:
- strcat(info, "Gehenna!");
- you.where_are_you = BRANCH_GEHENNA;
- you.your_level = 26;
- break;
- case DNGN_ENTER_COCYTUS:
- strcat(info, "Cocytus!");
- you.where_are_you = BRANCH_COCYTUS;
- you.your_level = 26;
- break;
- case DNGN_ENTER_TARTARUS:
- strcat(info, "Tartarus!");
- you.where_are_you = BRANCH_TARTARUS;
- you.your_level = 26;
- break;
- case DNGN_ENTER_ORCISH_MINES:
- strcat(info, "the Orcish Mines!");
- you.where_are_you = BRANCH_ORCISH_MINES;
- break;
- case DNGN_ENTER_HIVE:
- strcpy(info, "You hear a buzzing sound coming from all directions.");
- you.where_are_you = BRANCH_HIVE;
- break;
- case DNGN_ENTER_LAIR:
- strcat(info, "the Lair of Beasts!");
- you.where_are_you = BRANCH_LAIR;
- break;
- case DNGN_ENTER_SLIME_PITS:
- strcat(info, "the Pits of Slime!");
- you.where_are_you = BRANCH_SLIME_PITS;
- break;
- case DNGN_ENTER_VAULTS:
- strcat(info, "the Vaults!");
- you.where_are_you = BRANCH_VAULTS;
- break;
- case DNGN_ENTER_CRYPT:
- strcat(info, "the Crypt!");
- you.where_are_you = BRANCH_CRYPT;
- break;
- case DNGN_ENTER_HALL_OF_BLADES:
- strcat(info, "the Hall of Blades!");
- you.where_are_you = BRANCH_HALL_OF_BLADES;
- break;
- case DNGN_ENTER_ZOT:
- strcat(info, "the Hall of Zot!");
- you.where_are_you = BRANCH_HALL_OF_ZOT;
- break;
- case DNGN_ENTER_TEMPLE:
- strcat(info, "the Ecumenical Temple!");
- you.where_are_you = BRANCH_ECUMENICAL_TEMPLE;
- break;
- case DNGN_ENTER_SNAKE_PIT:
- strcat(info, "the Snake Pit!");
- you.where_are_you = BRANCH_SNAKE_PIT;
- break;
- case DNGN_ENTER_ELVEN_HALLS:
- strcat(info, "the Elven Halls!");
- you.where_are_you = BRANCH_ELVEN_HALLS;
- break;
- case DNGN_ENTER_TOMB:
- strcat(info, "the Tomb!");
- you.where_are_you = BRANCH_TOMB;
- break;
- case DNGN_ENTER_SWAMP:
- strcat(info, "the Swamp!");
- you.where_are_you = BRANCH_SWAMP;
- break;
- }
-
- mpr(info);
- }
- else if (stair_find == DNGN_ENTER_LABYRINTH)
- {
- you.level_type = LEVEL_LABYRINTH;
- grd[you.x_pos][you.y_pos] = DNGN_FLOOR;
- }
- else if (stair_find == DNGN_ENTER_ABYSS)
- {
- you.level_type = LEVEL_ABYSS;
- }
- else if (stair_find == DNGN_ENTER_PANDEMONIUM)
- {
- you.level_type = LEVEL_PANDEMONIUM;
- }
-
- if (you.level_type == LEVEL_LABYRINTH || you.level_type == LEVEL_ABYSS
- || you.level_type == LEVEL_PANDEMONIUM)
- {
- char glorpstr[kFileNameSize];
- char del_file[kFileNameSize];
- int sysg;
-
-#ifdef SAVE_DIR_PATH
- snprintf( glorpstr, sizeof(glorpstr),
- SAVE_DIR_PATH "%s%d", you.your_name, (int) getuid() );
-#else
- strncpy(glorpstr, you.your_name, kFileNameLen);
-
- // glorpstr [strlen(glorpstr)] = 0;
- // This is broken. Length is not valid yet! We have to check if we got
- // a trailing NULL; if not, write one:
- /* is name 6 chars or more? */
- if (strlen(you.your_name) > kFileNameLen - 1)
- glorpstr[kFileNameLen] = '\0';
-#endif
-
- strcpy(del_file, glorpstr);
- strcat(del_file, ".lab");
-
-#ifdef DOS
- strupr(del_file);
-#endif
- sysg = unlink(del_file);
-
-#if DEBUG_DIAGNOSTICS
- strcpy( info, "Deleting: " );
- strcat( info, del_file );
- mpr( info, MSGCH_DIAGNOSTICS );
- more();
-#endif
- }
-
- if (stair_find == DNGN_EXIT_ABYSS || stair_find == DNGN_EXIT_PANDEMONIUM)
- {
- leave_abyss_pan = true;
- mpr("You pass through the gate, and find yourself at the top of a staircase.");
- more();
- }
-
- if (!player_is_levitating()
- && you.conf
- && (stair_find >= DNGN_STONE_STAIRS_DOWN_I
- && stair_find <= DNGN_ROCK_STAIRS_DOWN)
- && random2(100) > you.dex)
- {
- mpr("In your confused state, you trip and fall down the stairs.");
-
- // Nastier than when climbing stairs, but you'll aways get to
- // your destination, -- bwr
- ouch( roll_dice( 6 + you.burden_state, 10 ), 0,
- KILLED_BY_FALLING_DOWN_STAIRS );
- }
-
- if (you.level_type == LEVEL_DUNGEON)
- you.your_level++;
-
- int stair_taken = stair_find;
-
- //unsigned char save_old = 1;
-
- if (you.level_type == LEVEL_LABYRINTH || you.level_type == LEVEL_ABYSS)
- stair_taken = DNGN_FLOOR; //81;
-
- if (you.level_type == LEVEL_PANDEMONIUM)
- stair_taken = DNGN_TRANSIT_PANDEMONIUM;
-
- if (remove_stairs)
- grd[you.x_pos][you.y_pos] = DNGN_FLOOR;
-
- switch (you.level_type)
- {
- case LEVEL_LABYRINTH:
- mpr("You enter a dark and forbidding labyrinth.");
- break;
-
- case LEVEL_ABYSS:
- mpr("You enter the Abyss!");
- mpr("To return, you must find a gate leading back.");
- break;
-
- case LEVEL_PANDEMONIUM:
- if (old_level_type == LEVEL_PANDEMONIUM)
- mpr("You pass into a different region of Pandemonium.");
- else
- {
- mpr("You enter the halls of Pandemonium!");
- mpr("To return, you must find a gate leading back.");
- }
- break;
-
- default:
- mpr("You climb downwards.");
- break;
- }
-
- load(stair_taken, LOAD_ENTER_LEVEL, was_a_labyrinth, old_level, old_where);
-
- unsigned char pc = 0;
- unsigned char pt = random2avg(28, 3);
-
- switch (you.level_type)
- {
- case LEVEL_LABYRINTH:
- you.your_level++;
- break;
-
- case LEVEL_ABYSS:
- grd[you.x_pos][you.y_pos] = DNGN_FLOOR;
-
- if (old_level_type != LEVEL_PANDEMONIUM)
- you.your_level--; // Linley-suggested addition 17jan2000 {dlb}
-
- init_pandemonium(); /* colours only */
-
- if (player_in_hell())
- {
- you.where_are_you = BRANCH_MAIN_DUNGEON;
- you.your_level = you.hell_exit - 1;
- }
- break;
-
- case LEVEL_PANDEMONIUM:
- if (old_level_type == LEVEL_PANDEMONIUM)
- {
- init_pandemonium();
- for (pc = 0; pc < pt; pc++)
- pandemonium_mons();
- }
- else
- {
- // Linley-suggested addition 17jan2000 {dlb}
- if (old_level_type != LEVEL_ABYSS)
- you.your_level--;
-
- init_pandemonium();
-
- for (pc = 0; pc < pt; pc++)
- pandemonium_mons();
-
- if (player_in_hell())
- {
- you.where_are_you = BRANCH_MAIN_DUNGEON;
- you.hell_exit = 26;
- you.your_level = 26;
- }
- }
- break;
-
- default:
- break;
- }
-
- you.turn_is_over = 1;
-
- save_game(false);
-
- new_level();
-
- viewwindow(1, true);
-
- if (you.skills[SK_TRANSLOCATIONS] > 0 && !allow_control_teleport( true ))
- mpr( "You sense a powerful magical force warping space.", MSGCH_WARN );
-
- travel_init_new_level();
- if (collect_travel_data)
- {
- // Update stair information for the stairs we just descended, and the
- // upstairs we're currently on.
- level_id new_level_id = level_id::get_current_level_id();
-
- if (you.level_type != LEVEL_PANDEMONIUM &&
- you.level_type != LEVEL_ABYSS &&
- you.level_type != LEVEL_LABYRINTH)
- {
- LevelInfo &new_level_info =
- travel_cache.get_level_info(new_level_id);
- new_level_info.update();
-
- // First we update the old level's stair.
- level_pos lp;
- lp.id = new_level_id;
- lp.pos.x = you.x_pos;
- lp.pos.y = you.y_pos;
-
- old_level_info.update_stair(stair_x, stair_y, lp);
-
- // Then the new level's stair, assuming arbitrarily that going
- // upstairs will land you on the same downstairs you took to begin
- // with (not necessarily true).
- lp.id = old_level_id;
- lp.pos.x = stair_x;
- lp.pos.y = stair_y;
- new_level_info.update_stair(you.x_pos, you.y_pos, lp, true);
- }
- }
-} // end down_stairs()
-
-void new_level(void)
-{
- int curr_subdungeon_level = you.your_level + 1;
-
- textcolor(LIGHTGREY);
-
- // maybe last part better expresssed as <= PIT {dlb}
- if (player_in_hell() || player_in_branch( BRANCH_VESTIBULE_OF_HELL ))
- curr_subdungeon_level = you.your_level - 26;
-
- /* Remember, must add this to the death_string in ouch */
- if (you.where_are_you >= BRANCH_ORCISH_MINES
- && you.where_are_you <= BRANCH_SWAMP)
- {
- curr_subdungeon_level = you.your_level
- - you.branch_stairs[you.where_are_you - 10];
- }
-
- gotoxy(46, 12);
-
-#if DEBUG_DIAGNOSTICS
- cprintf( "(%d) ", you.your_level + 1 );
-#endif
-
- env.floor_colour = LIGHTGREY;
- env.rock_colour = BROWN;
-
- if (you.level_type == LEVEL_PANDEMONIUM)
- {
- cprintf("- Pandemonium ");
-
- env.floor_colour = (mcolour[env.mons_alloc[9]] == BLACK)
- ? LIGHTGREY : mcolour[env.mons_alloc[9]];
-
- env.rock_colour = (mcolour[env.mons_alloc[8]] == BLACK)
- ? LIGHTGREY : mcolour[env.mons_alloc[8]];
- }
- else if (you.level_type == LEVEL_ABYSS)
- {
- cprintf("- The Abyss ");
-
- env.floor_colour = (mcolour[env.mons_alloc[9]] == BLACK)
- ? LIGHTGREY : mcolour[env.mons_alloc[9]];
-
- env.rock_colour = (mcolour[env.mons_alloc[8]] == BLACK)
- ? LIGHTGREY : mcolour[env.mons_alloc[8]];
- }
- else if (you.level_type == LEVEL_LABYRINTH)
- {
- cprintf("- a Labyrinth ");
- }
- else
- {
- // level_type == LEVEL_DUNGEON
- if (!player_in_branch( BRANCH_VESTIBULE_OF_HELL ))
- cprintf( "%d", curr_subdungeon_level );
-
- switch (you.where_are_you)
- {
- case BRANCH_MAIN_DUNGEON:
- cprintf(" of the Dungeon ");
- break;
- case BRANCH_DIS:
- env.floor_colour = CYAN;
- env.rock_colour = CYAN;
- cprintf(" of Dis ");
- break;
- case BRANCH_GEHENNA:
- env.floor_colour = DARKGREY;
- env.rock_colour = RED;
- cprintf(" of Gehenna ");
- break;
- case BRANCH_VESTIBULE_OF_HELL:
- env.floor_colour = LIGHTGREY;
- env.rock_colour = LIGHTGREY;
- cprintf("- the Vestibule of Hell ");
- break;
- case BRANCH_COCYTUS:
- env.floor_colour = LIGHTBLUE;
- env.rock_colour = LIGHTCYAN;
- cprintf(" of Cocytus ");
- break;
- case BRANCH_TARTARUS:
- env.floor_colour = DARKGREY;
- env.rock_colour = DARKGREY;
- cprintf(" of Tartarus ");
- break;
- case BRANCH_INFERNO:
- env.floor_colour = LIGHTRED;
- env.rock_colour = RED;
- cprintf(" of the Inferno ");
- break;
- case BRANCH_THE_PIT:
- env.floor_colour = RED;
- env.rock_colour = DARKGREY;
- cprintf(" of the Pit ");
- break;
- case BRANCH_ORCISH_MINES:
- env.floor_colour = BROWN;
- env.rock_colour = BROWN;
- cprintf(" of the Orcish Mines ");
- break;
- case BRANCH_HIVE:
- env.floor_colour = YELLOW;
- env.rock_colour = BROWN;
- cprintf(" of the Hive ");
- break;
- case BRANCH_LAIR:
- env.floor_colour = GREEN;
- env.rock_colour = BROWN;
- cprintf(" of the Lair ");
- break;
- case BRANCH_SLIME_PITS:
- env.floor_colour = GREEN;
- env.rock_colour = LIGHTGREEN;
- cprintf(" of the Slime Pits ");
- break;
- case BRANCH_VAULTS:
- env.floor_colour = LIGHTGREY;
- env.rock_colour = BROWN;
- cprintf(" of the Vaults ");
- break;
- case BRANCH_CRYPT:
- env.floor_colour = LIGHTGREY;
- env.rock_colour = LIGHTGREY;
- cprintf(" of the Crypt ");
- break;
- case BRANCH_HALL_OF_BLADES:
- env.floor_colour = LIGHTGREY;
- env.rock_colour = LIGHTGREY;
- cprintf(" of the Hall of Blades ");
- break;
-
- case BRANCH_HALL_OF_ZOT:
- if (you.your_level - you.branch_stairs[7] <= 1)
- {
- env.floor_colour = LIGHTGREY;
- env.rock_colour = LIGHTGREY;
- }
- else
- {
- switch (you.your_level - you.branch_stairs[7])
- {
- case 2:
- env.rock_colour = LIGHTGREY;
- env.floor_colour = BLUE;
- break;
- case 3:
- env.rock_colour = BLUE;
- env.floor_colour = LIGHTBLUE;
- break;
- case 4:
- env.rock_colour = LIGHTBLUE;
- env.floor_colour = MAGENTA;
- break;
- case 5:
- env.rock_colour = MAGENTA;
- env.floor_colour = LIGHTMAGENTA;
- break;
- }
- }
- cprintf(" of the Realm of Zot ");
- break;
-
- case BRANCH_ECUMENICAL_TEMPLE:
- env.floor_colour = LIGHTGREY;
- env.rock_colour = LIGHTGREY;
- cprintf(" of the Temple ");
- break;
- case BRANCH_SNAKE_PIT:
- env.floor_colour = LIGHTGREEN;
- env.rock_colour = YELLOW;
- cprintf(" of the Snake Pit ");
- break;
- case BRANCH_ELVEN_HALLS:
- env.floor_colour = DARKGREY;
- env.rock_colour = LIGHTGREY;
- cprintf(" of the Elven Halls ");
- break;
- case BRANCH_TOMB:
- env.floor_colour = YELLOW;
- env.rock_colour = LIGHTGREY;
- cprintf(" of the Tomb ");
- break;
- case BRANCH_SWAMP:
- env.floor_colour = BROWN;
- env.rock_colour = BROWN;
- cprintf(" of the Swamp ");
- break;
- }
- } // end else
-} // end new_level()
-
-static void dart_trap( bool trap_known, int trapped, struct bolt &pbolt,
- bool poison )
-{
- int damage_taken = 0;
- int trap_hit, your_dodge;
-
- if (random2(10) < 2 || (trap_known && !one_chance_in(4)))
- {
- snprintf( info, INFO_SIZE, "You avoid triggering a%s trap.",
- pbolt.beam_name );
- mpr(info);
- return;
- }
-
- if (you.equip[EQ_SHIELD] != -1 && one_chance_in(3))
- exercise( SK_SHIELDS, 1 );
-
- snprintf( info, INFO_SIZE, "A%s shoots out and ", pbolt.beam_name );
-
- if (random2( 20 + 5 * you.shield_blocks * you.shield_blocks )
- < player_shield_class())
- {
- you.shield_blocks++;
- strcat( info, "hits your shield." );
- mpr(info);
- goto out_of_trap;
- }
-
- // note that this uses full ( not random2limit(foo,40) ) player_evasion.
- trap_hit = (20 + (you.your_level * 2)) * random2(200) / 100;
-
- your_dodge = player_evasion() + random2(you.dex) / 3
- - 2 + (you.duration[DUR_REPEL_MISSILES] * 10);
-
- if (trap_hit >= your_dodge && you.duration[DUR_DEFLECT_MISSILES] == 0)
- {
- strcat( info, "hits you!" );
- mpr(info);
-
- if (poison && random2(100) < 50 - (3 * player_AC()) / 2
- && !player_res_poison())
- {
- poison_player( 1 + random2(3) );
- }
-
- damage_taken = roll_dice( pbolt.damage );
- damage_taken -= random2( player_AC() + 1 );
-
- if (damage_taken > 0)
- ouch( damage_taken, 0, KILLED_BY_TRAP, pbolt.beam_name );
- }
- else
- {
- strcat( info, "misses you." );
- mpr(info);
- }
-
- if (player_light_armour() && coinflip())
- exercise( SK_DODGING, 1 );
-
- out_of_trap:
-
- pbolt.target_x = you.x_pos;
- pbolt.target_y = you.y_pos;
-
- if (coinflip())
- itrap( pbolt, trapped );
-} // end dart_trap()
-
-//
-// itrap takes location from target_x, target_y of bolt strcture.
-//
-
-void itrap( struct bolt &pbolt, int trapped )
-{
- int base_type = OBJ_MISSILES;
- int sub_type = MI_DART;
-
- switch (env.trap[trapped].type)
- {
- case TRAP_DART:
- base_type = OBJ_MISSILES;
- sub_type = MI_DART;
- break;
- case TRAP_ARROW:
- base_type = OBJ_MISSILES;
- sub_type = MI_ARROW;
- break;
- case TRAP_BOLT:
- base_type = OBJ_MISSILES;
- sub_type = MI_BOLT;
- break;
- case TRAP_SPEAR:
- base_type = OBJ_WEAPONS;
- sub_type = WPN_SPEAR;
- break;
- case TRAP_AXE:
- base_type = OBJ_WEAPONS;
- sub_type = WPN_HAND_AXE;
- break;
- case TRAP_NEEDLE:
- base_type = OBJ_MISSILES;
- sub_type = MI_NEEDLE;
- break;
- default:
- return;
- }
-
- trap_item( base_type, sub_type, pbolt.target_x, pbolt.target_y );
-
- return;
-} // end itrap()
-
-void handle_traps(char trt, int i, bool trap_known)
-{
- struct bolt beam;
-
- switch (trt)
- {
- case TRAP_DART:
- strcpy(beam.beam_name, " dart");
- beam.damage = dice_def( 1, 4 + (you.your_level / 2) );
- dart_trap(trap_known, i, beam, false);
- break;
-
- case TRAP_NEEDLE:
- strcpy(beam.beam_name, " needle");
- beam.damage = dice_def( 1, 0 );
- dart_trap(trap_known, i, beam, true);
- break;
-
- case TRAP_ARROW:
- strcpy(beam.beam_name, "n arrow");
- beam.damage = dice_def( 1, 7 + you.your_level );
- dart_trap(trap_known, i, beam, false);
- break;
-
- case TRAP_BOLT:
- strcpy(beam.beam_name, " bolt");
- beam.damage = dice_def( 1, 13 + you.your_level );
- dart_trap(trap_known, i, beam, false);
- break;
-
- case TRAP_SPEAR:
- strcpy(beam.beam_name, " spear");
- beam.damage = dice_def( 1, 10 + you.your_level );
- dart_trap(trap_known, i, beam, false);
- break;
-
- case TRAP_AXE:
- strcpy(beam.beam_name, "n axe");
- beam.damage = dice_def( 1, 15 + you.your_level );
- dart_trap(trap_known, i, beam, false);
- break;
-
- case TRAP_TELEPORT:
- mpr("You enter a teleport trap!");
-
- if (scan_randarts(RAP_PREVENT_TELEPORTATION))
- mpr("You feel a weird sense of stasis.");
- else
- you_teleport2( true );
- break;
-
- case TRAP_AMNESIA:
- mpr("You feel momentarily disoriented.");
- if (!wearing_amulet(AMU_CLARITY))
- forget_map(random2avg(100, 2));
- break;
-
- case TRAP_BLADE:
- if (trap_known && one_chance_in(3))
- mpr("You avoid triggering a blade trap.");
- else if (random2limit(player_evasion(), 40)
- + (random2(you.dex) / 3) + (trap_known ? 3 : 0) > 8)
- {
- mpr("A huge blade swings just past you!");
- }
- else
- {
- mpr("A huge blade swings out and slices into you!");
- ouch( (you.your_level * 2) + random2avg(29, 2)
- - random2(1 + player_AC()), 0, KILLED_BY_TRAP, " blade" );
- }
- break;
-
- case TRAP_ZOT:
- default:
- mpr((trap_known) ? "You enter the Zot trap."
- : "Oh no! You have blundered into a Zot trap!");
- miscast_effect( SPTYP_RANDOM, random2(30) + you.your_level,
- 75 + random2(100), 3, "a Zot trap" );
- break;
- }
-} // end handle_traps()
-
-void disarm_trap( struct dist &disa )
-{
- if (you.berserker)
- {
- canned_msg(MSG_TOO_BERSERK);
- return;
- }
-
- int i, j;
-
- for (i = 0; i < MAX_TRAPS; i++)
- {
- if (env.trap[i].x == you.x_pos + disa.dx
- && env.trap[i].y == you.y_pos + disa.dy)
- {
- break;
- }
-
- if (i == MAX_TRAPS - 1)
- {
- mpr("Error - couldn't find that trap.");
- return;
- }
- }
-
- if (trap_category(env.trap[i].type) == DNGN_TRAP_MAGICAL)
- {
- mpr("You can't disarm that trap.");
- return;
- }
-
- if (random2(you.skills[SK_TRAPS_DOORS] + 2) <= random2(you.your_level + 5))
- {
- mpr("You failed to disarm the trap.");
-
- you.turn_is_over = 1;
-
- if (random2(you.dex) > 5 + random2(5 + you.your_level))
- exercise(SK_TRAPS_DOORS, 1 + random2(you.your_level / 5));
- else
- {
- handle_traps(env.trap[i].type, i, false);
-
- if (coinflip())
- exercise(SK_TRAPS_DOORS, 1);
- }
-
- return;
- }
-
- mpr("You have disarmed the trap.");
-
- struct bolt beam;
-
- beam.target_x = you.x_pos + disa.dx;
- beam.target_y = you.y_pos + disa.dy;
-
- if (env.trap[i].type != TRAP_BLADE
- && trap_category(env.trap[i].type) == DNGN_TRAP_MECHANICAL)
- {
- for (j = 0; j < 20; j++)
- {
- // places items (eg darts), which will automatically stack
- itrap(beam, i);
-
- if (j > 10 && one_chance_in(3))
- break;
- }
- }
-
- grd[you.x_pos + disa.dx][you.y_pos + disa.dy] = DNGN_FLOOR;
- env.trap[i].type = TRAP_UNASSIGNED;
- you.turn_is_over = 1;
-
- // reduced from 5 + random2(5)
- exercise(SK_TRAPS_DOORS, 1 + random2(5) + (you.your_level / 5));
-} // end disarm_trap()
-
-void manage_clouds(void)
-{
- // amount which cloud dissipates - must be unsigned! {dlb}
- unsigned int dissipate = 0;
-
- for (unsigned char cc = 0; cc < MAX_CLOUDS; cc++)
- {
- if (env.cloud[cc].type == CLOUD_NONE) // no cloud -> next iteration
- continue;
-
- dissipate = you.time_taken;
-
- // water -> flaming clouds:
- // lava -> freezing clouds:
- if ((env.cloud[cc].type == CLOUD_FIRE
- || env.cloud[cc].type == CLOUD_FIRE_MON)
- && grd[env.cloud[cc].x][env.cloud[cc].y] == DNGN_DEEP_WATER)
- {
- dissipate *= 4;
- }
- else if ((env.cloud[cc].type == CLOUD_COLD
- || env.cloud[cc].type == CLOUD_COLD_MON)
- && grd[env.cloud[cc].x][env.cloud[cc].y] == DNGN_LAVA)
- {
- dissipate *= 4;
- }
-
- // double the amount when slowed - must be applied last(!):
- if (you.slow)
- dissipate *= 2;
-
- // apply calculated rate to the actual cloud:
- env.cloud[cc].decay -= dissipate;
-
- // check for total dissipatation and handle accordingly:
- if (env.cloud[cc].decay < 1)
- delete_cloud( cc );
- }
-
- return;
-} // end manage_clouds()
-
-void weird_writing(char stringy[40])
-{
- int temp_rand = 0; // for probability determinations {dlb}
-
- temp_rand = random2(15);
-
- // you'll see why later on {dlb}
- strcpy(stringy, (temp_rand == 0) ? "writhing" :
- (temp_rand == 1) ? "bold" :
- (temp_rand == 2) ? "faint" :
- (temp_rand == 3) ? "spidery" :
- (temp_rand == 4) ? "blocky" :
- (temp_rand == 5) ? "angular" :
- (temp_rand == 6) ? "shimmering" :
- (temp_rand == 7) ? "glowing" : "");
-
- if (temp_rand < 8)
- strcat(stringy, " "); // see above for reasoning {dlb}
-
- temp_rand = random2(14);
-
- strcat(stringy, (temp_rand == 0) ? "yellow" :
- (temp_rand == 1) ? "brown" :
- (temp_rand == 2) ? "black" :
- (temp_rand == 3) ? "purple" :
- (temp_rand == 4) ? "orange" :
- (temp_rand == 5) ? "lime-green" :
- (temp_rand == 6) ? "blue" :
- (temp_rand == 7) ? "grey" :
- (temp_rand == 8) ? "silver" :
- (temp_rand == 9) ? "gold" :
- (temp_rand == 10) ? "umber" :
- (temp_rand == 11) ? "charcoal" :
- (temp_rand == 12) ? "pastel" :
- (temp_rand == 13) ? "mauve"
- : "colourless");
-
- strcat(stringy, " ");
-
- temp_rand = random2(14);
-
- strcat(stringy, (temp_rand == 0) ? "writing" :
- (temp_rand == 1) ? "scrawl" :
- (temp_rand == 2) ? "sigils" :
- (temp_rand == 3) ? "runes" :
- (temp_rand == 4) ? "hieroglyphics" :
- (temp_rand == 5) ? "scrawl" :
- (temp_rand == 6) ? "print-out" :
- (temp_rand == 7) ? "binary code" :
- (temp_rand == 8) ? "glyphs" :
- (temp_rand == 9) ? "symbols"
- : "text");
-
- return;
-} // end weird_writing()
-
-// must be a better name than 'place' for the first parameter {dlb}
-void fall_into_a_pool(bool place, unsigned char terrain)
-{
- bool escape = false;
- FixedVector< char, 2 > empty;
-
- if (you.species == SP_MERFOLK && terrain == DNGN_DEEP_WATER)
- {
- // These can happen when we enter deep water directly -- bwr
- merfolk_start_swimming();
- return;
- }
-
- strcpy(info, "You fall into the ");
-
- strcat(info, (terrain == DNGN_LAVA) ? "lava" :
- (terrain == DNGN_DEEP_WATER) ? "water"
- : "programming rift");
-
- strcat(info, "!");
- mpr(info);
-
- more();
- mesclr();
-
- if (terrain == DNGN_LAVA)
- {
- const int resist = player_res_fire();
-
- if (resist <= 0)
- {
- mpr( "The lava burns you to a cinder!" );
- ouch( -9999, 0, KILLED_BY_LAVA );
- }
- else
- {
- // should boost # of bangs per damage in the future {dlb}
- mpr( "The lava burns you!" );
- ouch( (10 + random2avg(100, 2)) / resist, 0, KILLED_BY_LAVA );
- }
-
- if (you.duration[DUR_CONDENSATION_SHIELD] > 0)
- {
- mpr("Your icy shield dissipates!", MSGCH_DURATION);
- you.duration[DUR_CONDENSATION_SHIELD] = 0;
- you.redraw_armour_class = 1;
- }
- }
-
- // a distinction between stepping and falling from you.levitation
- // prevents stepping into a thin stream of lava to get to the other side.
- if (scramble())
- {
- if (place)
- {
- if (empty_surrounds(you.x_pos, you.y_pos, DNGN_FLOOR, false, empty))
- {
- you.x_pos = empty[0];
- you.y_pos = empty[1];
- escape = true;
- }
- else
- escape = false;
- }
- else
- escape = true;
- }
- else
- {
- // that is, don't display following when fall from levitating
- if (!place)
- mpr("You try to escape, but your burden drags you down!");
- }
-
- if (escape)
- {
- mpr("You manage to scramble free!");
-
- if (terrain == DNGN_LAVA)
- scrolls_burn(10, OBJ_SCROLLS);
-
- return;
- }
-
- mpr("You drown...");
-
- if (terrain == DNGN_LAVA)
- ouch(-9999, 0, KILLED_BY_LAVA);
- else if (terrain == DNGN_DEEP_WATER)
- ouch(-9999, 0, KILLED_BY_WATER);
-
- // Okay, so you don't trigger a trap when you scramble onto it.
- //I really can't be bothered right now.
-} // end fall_into_a_pool()
-
-bool scramble(void)
-{
- int max_carry = carrying_capacity();
-
- if ((max_carry / 2) + random2(max_carry / 2) <= you.burden)
- return false;
- else
- return true;
-} // end scramble()
-
-void weird_colours(unsigned char coll, char wc[30])
-{
- unsigned char coll_div16 = coll / 16; // conceivable max is then 16 {dlb}
-
- // Must start with a consonant!
- strcpy(wc, (coll_div16 == 0 || coll_div16 == 7) ? "brilliant" :
- (coll_div16 == 1 || coll_div16 == 8) ? "pale" :
- (coll_div16 == 2 || coll_div16 == 9) ? "mottled" :
- (coll_div16 == 3 || coll_div16 == 10) ? "shimmering" :
- (coll_div16 == 4 || coll_div16 == 11) ? "bright" :
- (coll_div16 == 5 || coll_div16 == 12) ? "dark" :
- (coll_div16 == 6 || coll_div16 == 13) ? "shining"
- : "faint");
-
- strcat(wc, " ");
-
- while (coll > 17)
- coll -= 10;
-
- strcat(wc, (coll == 0) ? "red" :
- (coll == 1) ? "purple" :
- (coll == 2) ? "green" :
- (coll == 3) ? "orange" :
- (coll == 4) ? "magenta" :
- (coll == 5) ? "black" :
- (coll == 6) ? "grey" :
- (coll == 7) ? "silver" :
- (coll == 8) ? "gold" :
- (coll == 9) ? "pink" :
- (coll == 10) ? "yellow" :
- (coll == 11) ? "white" :
- (coll == 12) ? "brown" :
- (coll == 13) ? "aubergine" :
- (coll == 14) ? "ochre" :
- (coll == 15) ? "leaf green" :
- (coll == 16) ? "mauve" :
- (coll == 17) ? "azure"
- : "colourless");
-
- return;
-} // end weird_colours()
-
-bool go_berserk(bool intentional)
-{
- if (you.berserker)
- {
- if (intentional)
- mpr("You're already berserk!");
- // or else you won't notice -- no message here.
- return false;
- }
-
- if (you.exhausted)
- {
- if (intentional)
- mpr("You're too exhausted to go berserk.");
- // or else they won't notice -- no message here
- return false;
- }
-
- if (you.is_undead)
- {
- if (intentional)
- mpr("You cannot raise a blood rage in your lifeless body.");
- // or else you won't notice -- no message here
- return false;
- }
-
- mpr("A red film seems to cover your vision as you go berserk!");
- mpr("You feel yourself moving faster!");
- mpr("You feel mighty!");
-
- you.berserker += 20 + random2avg(19, 2);
-
- calc_hp();
- you.hp *= 15;
- you.hp /= 10;
-
- deflate_hp(you.hp_max, false);
-
- if (!you.might)
- modify_stat( STAT_STRENGTH, 5, true );
-
- you.might += you.berserker;
- haste_player( you.berserker );
-
- if (you.berserk_penalty != NO_BERSERK_PENALTY)
- you.berserk_penalty = 0;
-
- return true;
-} // end go_berserk()
-
-bool trap_item(char base_type, char sub_type, char beam_x, char beam_y)
-{
- item_def item;
-
- item.base_type = base_type;
- item.sub_type = sub_type;
- item.plus = 0;
- item.plus2 = 0;
- item.flags = 0;
- item.special = 0;
- item.quantity = 1;
- item.colour = LIGHTCYAN;
-
- if (base_type == OBJ_MISSILES)
- {
- if (sub_type == MI_NEEDLE)
- {
- set_item_ego_type( item, OBJ_MISSILES, SPMSL_POISONED );
- item.colour = WHITE;
- }
- else
- {
- set_item_ego_type( item, OBJ_MISSILES, SPMSL_NORMAL );
-
- if (sub_type == MI_ARROW)
- item.colour = BROWN;
- }
- }
- else
- {
- set_item_ego_type( item, OBJ_WEAPONS, SPWPN_NORMAL );
- }
-
- if (igrd[beam_x][beam_y] != NON_ITEM)
- {
- if (items_stack( item, mitm[ igrd[beam_x][beam_y] ] ))
- {
- inc_mitm_item_quantity( igrd[beam_x][beam_y], 1 );
- return (false);
- }
-
- // don't want to go overboard here. Will only generate up to three
- // separate trap items, or less if there are other items present.
- if (mitm[ igrd[beam_x][beam_y] ].link != NON_ITEM)
- {
- if (mitm[ mitm[ igrd[beam_x][beam_y] ].link ].link != NON_ITEM)
- return (false);
- }
- } // end of if igrd != NON_ITEM
-
- return (!copy_item_to_grid( item, beam_x, beam_y, 1 ));
-} // end trap_item()
-
-// returns appropriate trap symbol for a given trap type {dlb}
-unsigned char trap_category(unsigned char trap_type)
-{
- switch (trap_type)
- {
- case TRAP_TELEPORT:
- case TRAP_AMNESIA:
- case TRAP_ZOT:
- return (DNGN_TRAP_MAGICAL);
-
- case TRAP_DART:
- case TRAP_ARROW:
- case TRAP_SPEAR:
- case TRAP_AXE:
- case TRAP_BLADE:
- case TRAP_BOLT:
- case TRAP_NEEDLE:
- default: // what *would* be the default? {dlb}
- return (DNGN_TRAP_MECHANICAL);
- }
-} // end trap_category()
-
-// returns index of the trap for a given (x,y) coordinate pair {dlb}
-int trap_at_xy(int which_x, int which_y)
-{
-
- for (int which_trap = 0; which_trap < MAX_TRAPS; which_trap++)
- {
- if (env.trap[which_trap].x == which_x
- && env.trap[which_trap].y == which_y)
- {
- return (which_trap);
- }
- }
-
- // no idea how well this will be handled elsewhere: {dlb}
- return (-1);
-} // end trap_at_xy()
-
-// A constructor for bolt to help guarantee that we start clean (this has
-// caused way too many bugs). Putting it here since there's no good place to
-// put it, and it doesn't do anything other than initialize it's members.
-//
-// TODO: Eventually it'd be nice to have a proper factory for these things
-// (extended from setup_mons_cast() and zapping() which act as limited ones).
-bolt::bolt() : range(0), rangeMax(0), type(SYM_ZAP), colour(BLACK),
- flavour(BEAM_MAGIC), source_x(0), source_y(0), damage(0,0),
- ench_power(0), hit(0), target_x(0), target_y(0),
- thrower(KILL_MISC), ex_size(0), beam_source(MHITNOT),
- beam_name(),
- is_beam(false), is_explosion(false), is_big_cloud(false),
- is_enchant(false), is_energy(false),
- is_launched(false), is_thrown(false), target_first(false),
- aux_source(NULL), obvious_effect(false),
- fr_count(0), foe_count(0), fr_power(0), foe_power(0),
- is_tracer(false), aimed_at_feet(false), msg_generated(false),
- in_explosion_phase(false), smart_monster(false),
- can_see_invis(false), is_friendly(false), foe_ratio(0)
-{ }
diff --git a/stone_soup/crawl-ref/source/misc.h b/stone_soup/crawl-ref/source/misc.h
deleted file mode 100644
index 3f109eed6b..0000000000
--- a/stone_soup/crawl-ref/source/misc.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * File: misc.cc
- * Summary: Misc functions.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef MISC_H
-#define MISC_H
-
-
-#include "externs.h"
-
-// last updated 08jan2001 {gdl}
-/* ***********************************************************************
- * called from: ability - decks - fight - it_use2 - spells1
- * *********************************************************************** */
-bool go_berserk(bool intentional);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void search_around(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void manage_clouds(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void disarm_trap(struct dist &disa);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - effects - spells3
- * *********************************************************************** */
-void down_stairs(bool remove_stairs, int old_level, bool force = false);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void fall_into_a_pool(bool place, unsigned char grype);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - misc
- * *********************************************************************** */
-void handle_traps(char trt, int i, bool trap_known);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void in_a_cloud(void);
-
-// Created Sept 1, 2000 -- bwr
-/* ***********************************************************************
- * called from: acr misc
- * *********************************************************************** */
-void merfolk_start_swimming(void);
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: misc - mstuff2
- * *********************************************************************** */
-void itrap(struct bolt &pbolt, int trapped);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - misc - player - stuff
- * *********************************************************************** */
-void new_level(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: delay
- * *********************************************************************** */
-void turn_corpse_into_chunks( item_def &item );
-
-
-// last updated 3jun2000 {dlb}
-/* ***********************************************************************
- * called from: acr - misc - mstuff2 - spells3
- * *********************************************************************** */
-int trap_at_xy(int which_x, int which_y);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void up_stairs(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - effects
- * *********************************************************************** */
-void weird_colours(unsigned char coll, char wc[30]);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: it_use3
- * *********************************************************************** */
-void weird_writing(char stringy[40]);
-
-
-// last updated 3jun2000 {dlb}
-/* ***********************************************************************
- * called from: acr - misc - mstuff2 - spells2 - spells3
- * *********************************************************************** */
-unsigned char trap_category(unsigned char trap_type);
-
-bool grid_is_opaque(int grid);
-bool grid_is_solid(int grid);
-bool grid_is_water(int grid);
-bool grid_destroys_items( int grid );
-
-const char *grid_item_destruction_message( unsigned char grid );
-
-void curare_hits_player(int agent, int degree);
-
-#endif
diff --git a/stone_soup/crawl-ref/source/misc/header b/stone_soup/crawl-ref/source/misc/header
deleted file mode 100644
index 9f91952461..0000000000
--- a/stone_soup/crawl-ref/source/misc/header
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * File:
- * Summary:
- * Written by:
- *
- * Change History (most recent first):
- *
- * <1> --/--/-- --- Created
- */
-
diff --git a/stone_soup/crawl-ref/source/misc/pfix6.pl b/stone_soup/crawl-ref/source/misc/pfix6.pl
deleted file mode 100644
index 66bf29bef5..0000000000
--- a/stone_soup/crawl-ref/source/misc/pfix6.pl
+++ /dev/null
@@ -1,312 +0,0 @@
-#!/usr/bin/perl -w
-
-use Term::ReadKey;
-
-use Term::ANSIColor qw(:constants);
-#$Term::ANSIColor::AUTORESET = 1;
-
-use Getopt::Std;
-local( $opt_p, $opt_P );
-getopts( "p:P:" );
-
-$light_pattern = $opt_p || "";
-$heavy_pattern = $opt_P || "\\b";
-
-
-
-
-$infile = "enum.h";
-open( DATA, $infile ) || die "can't open $infile: $!\n";
-
-$category = "";
-
-
-while( <DATA> )
-{
- chop;
-
- s#/.*##; # strip comments
- s#\*.*##; # strip comments
- s/#.*//;
- next unless /\S/; # skip empty lines
- next unless /\w/; # skip special chars
-
- if ( m/^enum\s+(\S+)/ )
- {
- $category = $1;
- $data{ $category }{ i } = 0;
- }
- else
- {
- s/,//; # usually a comma
-
- # possibly a number on the line
- ( $term, undef, $i ) = split;
- $string = $term;
-
- if ( defined $i && $i =~ m/^\d+$/ )
- {
- $data{ $category }{ i } = $i;
- }
- else
- {
- $i = $data{ $category }{ i };
- }
-
- $data{ $category }{ array }{ $i } = $string;
- $data{ $category }{ i }++;
- }
-}
-
-
-$let = "0";
-foreach $cat ( sort keys %data )
-{
- $letters{ $let } = $cat;
- $let++;
- $let = "A" if $let eq "10";
- $let = "a" if $let eq "AA";
-}
-
-# @sort_lets = sort { ($b ge "a") <=> ($a ge "a") || $a cmp $b } keys %letters;
-@sort_lets = sort keys %letters;
-foreach $let ( @sort_lets )
-{
- push @key, "$let - $letters{ $let }";
-}
-
-$klen = 0;
-foreach $k ( @key )
-{
- $lk = length $k;
- $klen = $lk if $lk > $klen;
-}
-
-$klen += 1;
-$klen = 20 if $klen > 20;
-
-@bkey = @key;
-foreach $k ( @bkey )
-{
- if ( length $k < $klen )
- {
- $k .= " " x ($klen - length $k);
- }
- else
- {
- $k = substr( $k, 0, $klen - 1 );
- $k .= " ";
- }
-}
-
-$ntpl = int 80/$klen;
-while ( @bkey )
-{
- push @kd, join "", @bkey[0..$ntpl-1], "\n";
- splice @bkey, 0, $ntpl;
-}
-
-foreach $file ( @ARGV )
-{
- open IN, $file or die "can't open $file: $!\n";
-
- @buff = <IN>;
- $numlines = @buff;
-
- @save_buff = @buff;
-
- @lines_changed = ();
-
-LINE:
- for( $line = 0; $line < $numlines; $line++ )
- {
- if ( $light_pattern && $buff[ $line ] !~ m/$light_pattern/io )
- {
- next LINE;
- }
-
- $target = $buff[ $line ];
- %poslist = ();
-
- while ( $target =~ m/$heavy_pattern(\d+)\b/go )
- {
-
- $number = $1;
- $pos = pos( $target ) - length $number;
-
- $pre = $`;
-
- next if $pre =~ m#//#;
-
- next if $pre =~ m#[\-+*/%] ?$#;
-
- # skip some unlikely numbers
- # you[0]
- next if $number eq "0" && $pre =~ m/you ?\[ ?$/;
- # arithmetic
- next if $number eq "1" && $pre =~ m/\D-$/;
-
-
- $poslist{ $pos } = $number;
- }
-
- $longer = 0;
- foreach $pos ( sort { $a <=> $b } keys %poslist )
- {
- $number = $poslist{ $pos };
-
- $nl = length $number;
-
- print "\n";
- print YELLOW, @buff[ $line-8..$line-1];
-
- #print "-" x ($pos+$longer);
- #print "v" x $nl;
- #print "-" x (60 - ($nl+$pos+$longer));
- #print "\n";
-
- # print $target;
- print GREEN, substr( $target, 0, $pos+$longer );
- print CYAN, substr( $target, $pos+$longer, $nl );
- print GREEN, substr( $target, $pos+$longer+$nl );
-
-
- #print "-" x ($pos+$longer);
- #print "^" x $nl;
- #print "-" x (60 - ($nl+$pos+$longer));
- #print "\n";
-
- print YELLOW, @buff[ $line+1..$line+8];
-
- print "\n";
- print RESET;
- print @kd;
-
- print "\n";
- print GREEN, "$file ", BLUE, "$line ", YELLOW, "replace? ";
- print RESET;
-
- if ( ! $do_all )
- {
- ReadMode('cbreak');
- $ans = ReadKey(0);
- ReadMode('normal');
-
- print $ans;
- }
- else
- {
- $ans = $do_all;
- }
-
- if ( defined $letters{ $ans } )
- {
- print "\n";
-
- # get busy
- $list = $letters{ $ans };
- # $rep = ${$data{$list}}[ $number ];
- $rep = $data{$list}{array}{ $number };
-
- if ( $rep )
- {
- substr( $target, $pos+$longer, $nl ) = $rep;
- $longer += length( $rep );
- $longer -= $nl;
-
- print RED, $target;
- print RESET;
-
- push @lines_changed, $line;
- }
- else
- {
- print BLINK, RED, "###### trouble! ######\n";
- print RESET;
- }
- }
- elsif ( $ans eq "#" )
- {
- $more = <STDIN>;
- print $more;
- chop $more;
-
- $cmd = substr $more, 0, 1;
- if ( $cmd eq "u" )
- {
- print "\n";
- if ( @lines_changed )
- {
- $line_changed = pop @lines_changed;
-
- $buff[ $line_changed ] = $save_buff[ $line_changed ];
- $line = $line_changed;
- redo LINE;
- }
- else
- {
- redo;
- }
- }
- elsif ( $cmd eq "l" )
- {
- $newline = substr $more, 1;
- $newline += 0;
- $line = $newline if $newline;
- redo LINE;
- }
- elsif ( $cmd eq "s" )
- {
- $saving = 1;
- last LINE;
- }
- elsif ( $cmd eq "a" )
- {
- $do_all = substr $more, 1;
- print "Really answer with $do_all? ";
- $yn = <STDIN>;
- if ( $yn !~ m/^yes$/ )
- {
- $do_all = "";
- }
- redo;
- }
- elsif ( $cmd eq "q" )
- {
- exit;
- }
- }
- else
- {
- if ( $ans =~ m/\S/ )
- {
- redo;
- }
- }
- }
- $buff[ $line ] = $target;
- }
- close IN;
-
- if ( @lines_changed )
- {
- $bak = "$file.bak";
-
- if ( rename( $file, $bak ) )
- {
- $outfile = $file;
- }
- else
- {
- $outfile = "Z$file";
- print "***** printing changes to $outfile *****\n";
- }
-
- open OUT, "> $outfile" or die "can't open $outfile: $!\n";
- print OUT @buff;
- close OUT;
-
- }
- exit if $saving;
-}
-
diff --git a/stone_soup/crawl-ref/source/mon-data.h b/stone_soup/crawl-ref/source/mon-data.h
deleted file mode 100644
index f51df5b096..0000000000
--- a/stone_soup/crawl-ref/source/mon-data.h
+++ /dev/null
@@ -1,4379 +0,0 @@
-#ifndef MONDATA_H
-#define MONDATA_H
-
-#include "enum.h"
-
-/*
- This whole file was very generously condensed from its initial ugly form
- by Wladimir van der Laan ($pellbinder).
- */
-
-
-/* ******************************************************************
-
- (see "mon-util.h" for the gory details)
-
- - ordering does not matter, because seekmonster() searches the entire
- array ... probably not to most efficient thing to do, but so it goes
-
- - Here are the rows:
- - row 1: monster id, display character, display colour, name
- - row 2: monster flags
- - row 3: mass, experience modifier, charclass, holiness, resist magic
- - row 4: damage for each of four attacks
- - row 5: hit dice, described by four parameters
- - row 6: AC, evasion, speed, speed_inc, sec(spell), corpse_thingy,
- zombie size, shouts, intel
- - row 6: gmon_use class
-
- - Some further explanations:
-
- - colour: if BLACK, monster uses value of mons_sec
- - name: if an empty string, name generated automagically (see moname)
- - mass: if zero, the monster never leaves a corpse
- - charclass: base monster "type" for a classed monsters
- - holiness: holy - irritates some gods when killed, immunity from
- holy wrath weapons
- natural - baseline monster type
- undead - immunity from draining, pain, torment; extra
- damage from hoyl wrath/disruption; affected by
- repel undead and holy word
- demonic - similar to undead, but holy wrath does even
- more damage and disruption and repel undead
- effects are ignored -- *no* automatic hellfire
- resistance
-
-
- exp_mod
- - the experience given for killing this monster is calculated something
- like this:
- experience = hp_max * HD * HD * exp_mod / 10
- I think.
-
-
- resist_magic
- - If -3, = 3 (5?) * hit dice
-
- damage [4]
- - up to 4 different attacks
-
- hp_dice [4]
- - hit dice, min hp per HD, extra random hp per HD, fixed HP (unique mons)
-
- speed
- - less = slower. 5 = half, 20 = double speed.
-
- speed_inc
- - this is unnecessary and should be removed. 7 for all monsters.
-
- corpse_thingy
- - err, bad name. Describes effects of eating corpses.
-
- zombie_size
- - 0 = no zombie possibly, 1 = small zombie (z), 2 = large zombie (Z)
-
- shouts
- - various things monsters can do upon seeing you
- #define S_RANDOM -1
- #define S_SILENT 0
- #define S_SHOUT 1 //1=shout
- #define S_BARK 2 //2=bark
- #define S_SHOUT2 3 //3=shout twice - eg 2-headed ogres
- #define S_ROAR 4 //4=roar
- #define S_SCREAM 5 //5=scream
- #define S_BELLOW 6 //6=bellow (?)
- #define S_SCREECH 7 //7=screech
- #define S_BUZZ 8 //8=buzz
- #define S_MOAN 9 //9=moan
-
- intel explanation:
- - How smart it is. So far, differences here have little effects except
- for monster's chance of seeing you if stealthy, and really stupid monsters
- will walk through clouds
-
- gmon_use explanation:
- 0 = uses nothing
- 1 = opens doors
- 2 = gets and can use its starting equipment
- 3 = can use weapons/armour
-
- */
-
-
-// monster 250: The Thing That Should Not Be(tm)
-// do not remove, or seekmonster will crash on unknown mc request
-// it is also a good prototype for new monstersst
-{
- MONS_PROGRAM_BUG, 'B', LIGHTRED, "program bug",
- M_NO_EXP_GAIN,
- MR_NO_FLAGS,
- 0, 10, MONS_PROGRAM_BUG, MONS_PROGRAM_BUG, MH_NATURAL, -3,
- { 0, 0, 0, 0 },
- { 0, 0, 0, 0 },
- 0, 0, 0, 0, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-// real monsters begin here {dlb}:
-{
- MONS_GIANT_ANT, 'a', DARKGREY, "giant ant",
- M_NO_FLAGS,
- MR_VUL_POISON,
- 700, 10, MONS_GIANT_ANT, MONS_GIANT_ANT, MH_NATURAL, -3,
- { 8, 0, 0, 0 },
- { 3, 3, 5, 0 },
- 4, 10, 12, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_INSECT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_GIANT_BAT, 'b', DARKGREY, "giant bat",
- M_FLIES | M_SEE_INVIS | M_WARM_BLOOD,
- MR_NO_FLAGS,
- 150, 4, MONS_GIANT_BAT, MONS_GIANT_BAT, MH_NATURAL, -1,
- { 1, 0, 0, 0 },
- { 1, 2, 3, 0 },
- 1, 14, 30, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_ANIMAL,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_CENTAUR, 'c', BROWN, "centaur",
- M_WARM_BLOOD,
- MR_NO_FLAGS,
- 1500, 10, MONS_CENTAUR, MONS_CENTAUR, MH_NATURAL, -3,
- { 10, 0, 0, 0 },
- { 4, 3, 5, 0 },
- 3, 7, 15, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_RED_DEVIL, '4', RED, "red devil",
- M_FLIES | M_EVIL,
- MR_RES_POISON | MR_RES_HELLFIRE | MR_VUL_COLD,
- 0, 10, MONS_RED_DEVIL, MONS_RED_DEVIL, MH_DEMONIC, -7,
- { 18, 0, 0, 0 },
- { 5, 3, 5, 0 },
- 10, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_ETTIN, 'C', BROWN, "ettin",
- M_WARM_BLOOD | M_EVIL,
- MR_NO_FLAGS,
- 0, 10, MONS_HILL_GIANT, MONS_ETTIN, MH_NATURAL, -3,
- { 18, 12, 0, 0 },
- { 7, 3, 5, 0 },
- 3, 4, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT2, I_NORMAL,
- MONUSE_STARTING_EQUIPMENT
-}
-,
-
-{
- MONS_FUNGUS, 'f', LIGHTGREY, "fungus",
- M_NO_EXP_GAIN,
- MR_RES_POISON,
- 0, 10, MONS_PLANT, MONS_FUNGUS, MH_PLANT, 5000,
- { 0, 0, 0, 0 },
- { 8, 3, 5, 0 },
- 1, 0, 0, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_GOBLIN, 'g', LIGHTGREY, "goblin",
- M_WARM_BLOOD | M_EVIL,
- MR_NO_FLAGS,
- 400, 10, MONS_GOBLIN, MONS_GOBLIN, MH_NATURAL, -1,
- { 4, 0, 0, 0 },
- { 1, 2, 4, 0 },
- 0, 12, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_HOUND, 'h', BROWN, "hound",
- M_SEE_INVIS | M_WARM_BLOOD,
- MR_NO_FLAGS,
- 300, 10, MONS_HOUND, MONS_HOUND, MH_NATURAL, -3,
- { 6, 0, 0, 0 },
- { 3, 3, 5, 0 },
- 2, 13, 15, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_BARK, I_ANIMAL,
- MONUSE_NOTHING
-}
-,
-
-// note: these things regenerate
-{
- MONS_IMP, '5', RED, "imp",
- M_FLIES | M_SEE_INVIS | M_SPEAKS | M_EVIL | M_SPECIAL_ABILITY,
- MR_RES_POISON | MR_RES_HELLFIRE | MR_VUL_COLD,
- 0, 13, MONS_IMP, MONS_IMP, MH_DEMONIC, -9,
- { 4, 0, 0, 0 },
- { 3, 3, 3, 0 },
- 3, 14, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SHOUT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_JACKAL, 'j', YELLOW, "jackal",
- M_WARM_BLOOD,
- MR_NO_FLAGS,
- 200, 10, MONS_HOUND, MONS_JACKAL, MH_NATURAL, -1,
- { 3, 0, 0, 0 },
- { 1, 3, 5, 0 },
- 2, 12, 14, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_BARK, I_ANIMAL,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_KILLER_BEE, 'k', YELLOW, "killer bee",
- M_FLIES,
- MR_VUL_POISON,
- 150, 11, MONS_KILLER_BEE, MONS_KILLER_BEE, MH_NATURAL, -3,
- { 10, 0, 0, 0 },
- { 3, 3, 5, 0 },
- 2, 18, 20, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_BUZZ, I_INSECT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_KILLER_BEE_LARVA, 'w', LIGHTGREY, "killer bee larva",
- M_NO_SKELETON,
- MR_VUL_POISON,
- 150, 5, MONS_KILLER_BEE_LARVA, MONS_KILLER_BEE_LARVA, MH_NATURAL, -3,
- { 3, 0, 0, 0 },
- { 1, 3, 5, 0 },
- 1, 5, 5, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_MANTICORE, 'm', BROWN, "manticore",
- M_WARM_BLOOD | M_SPECIAL_ABILITY,
- MR_NO_FLAGS,
- 1800, 10, MONS_MANTICORE, MONS_MANTICORE, MH_NATURAL, -3,
- { 14, 8, 8, 0 },
- { 9, 3, 5, 0 },
- 5, 7, 7, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SILENT, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-// this thing doesn't have nr. 13 for nothing, has it? ($pellbinder)
-{
- MONS_NECROPHAGE, 'n', DARKGREY, "necrophage",
- M_EVIL,
- MR_RES_POISON | MR_RES_COLD,
- 500, 10, MONS_GHOUL, MONS_NECROPHAGE, MH_UNDEAD, -5,
- { 8, 0, 0, 0 },
- { 5, 3, 5, 0 },
- 2, 10, 10, 7, MST_NO_SPELLS, CE_HCL, Z_NOZOMBIE, S_SILENT, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_ORC, 'o', LIGHTRED, "orc",
- M_WARM_BLOOD | M_EVIL,
- MR_NO_FLAGS,
- 600, 10, MONS_ORC, MONS_ORC, MH_NATURAL, -3,
- { 5, 0, 0, 0 },
- { 1, 4, 6, 0 },
- 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-// XP modifier is 5 for these, because they really aren't all that
-// dangerous, but still come out at 200+ XP
-{
- MONS_PHANTOM, 'p', BLUE, "phantom",
- M_EVIL | M_SPECIAL_ABILITY,
- MR_RES_POISON | MR_RES_COLD,
- 0, 5, MONS_PHANTOM, MONS_PHANTOM, MH_UNDEAD, -4,
- { 10, 0, 0, 0 },
- { 7, 3, 5, 0 },
- 3, 13, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_QUASIT, 'q', LIGHTGREY, "quasit",
- M_EVIL,
- MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD,
- 0, 10, MONS_QUASIT, MONS_QUASIT, MH_DEMONIC, 50,
- { 3, 2, 2, 0 },
- { 3, 2, 6, 0 },
- 5, 17, 15, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_INSECT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_RAT, 'r', BROWN, "rat",
- M_WARM_BLOOD,
- MR_NO_FLAGS,
- 200, 10, MONS_RAT, MONS_RAT, MH_NATURAL, -1,
- { 3, 0, 0, 0 },
- { 1, 1, 3, 0 },
- 1, 10, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_ANIMAL,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_SCORPION, 's', DARKGREY, "scorpion",
- M_NO_FLAGS,
- MR_VUL_POISON,
- 500, 10, MONS_SCORPION, MONS_SCORPION, MH_NATURAL, -3,
- { 10, 0, 0, 0 },
- { 3, 3, 5, 0 },
- 5, 10, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT,
- MONUSE_NOTHING
-}
-,
-
-/* ******************************************************************
-// the tunneling worm is no more ...
-// not until it can be reimplemented safely {dlb}
-{
- MONS_TUNNELING_WORM, 't', LIGHTRED, "tunneling worm",
- M_NO_FLAGS,
- MR_RES_POISON,
- 0, 10, 19, MH_NATURAL, 5000,
- { 50, 0, 0, 0 },
- { 10, 5, 5, 0 },
- 3, 3, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_REPTILE,
- MONUSE_NOTHING
-}
-,
-****************************************************************** */
-
-{
- MONS_UGLY_THING, 'u', BROWN, "ugly thing",
- M_WARM_BLOOD | M_AMPHIBIOUS,
- MR_NO_FLAGS,
- 600, 10, MONS_UGLY_THING, MONS_UGLY_THING, MH_NATURAL, -3,
- { 12, 0, 0, 0 },
- { 8, 3, 5, 0 },
- 3, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_FIRE_VORTEX, 'v', RED, "fire vortex",
- M_LEVITATE | M_CONFUSED,
- MR_RES_POISON | MR_RES_FIRE | MR_VUL_COLD | MR_RES_ELEC,
- 0, 5, MONS_FIRE_VORTEX, MONS_FIRE_VORTEX, MH_NONLIVING, 5000,
- { 30, 0, 0, 0 },
- { 3, 3, 5, 0 },
- 0, 5, 15, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_WORM, 'w', LIGHTRED, "worm",
- M_NO_SKELETON,
- MR_NO_FLAGS,
- 350, 4, MONS_WORM, MONS_WORM, MH_NATURAL, -2,
- { 12, 0, 0, 0 },
- { 5, 3, 5, 0 },
- 1, 5, 6, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_INSECT,
- MONUSE_NOTHING
-}
-,
-
-// random
-{
- MONS_ABOMINATION_SMALL, 'x', BLACK, "abomination",
- M_EVIL,
- MR_NO_FLAGS,
- 0, 10, MONS_ABOMINATION_SMALL, MONS_ABOMINATION_SMALL, MH_DEMONIC, -5,
- { 23, 0, 0, 0 },
- { 6, 2, 5, 0 },
- 0, 0, 0, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_YELLOW_WASP, 'y', YELLOW, "yellow wasp",
- M_FLIES,
- MR_VUL_POISON,
- 220, 12, MONS_YELLOW_WASP, MONS_YELLOW_WASP, MH_NATURAL, -3,
- { 13, 0, 0, 0 },
- { 4, 3, 5, 0 },
- 5, 14, 15, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_INSECT,
- MONUSE_NOTHING
-}
-,
-
-// small zombie
-{
- MONS_ZOMBIE_SMALL, 'z', BROWN, "",
- M_EVIL,
- MR_RES_POISON | MR_RES_COLD,
- 0, 6, MONS_ZOMBIE_SMALL, MONS_ZOMBIE_SMALL, MH_UNDEAD, -1,
- { 10, 0, 0, 0 },
- { 1, 5, 5, 0 },
- 0, 4, 5, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_ANGEL, 'A', WHITE, "Angel",
- M_FLIES | M_SPELLCASTER,
- MR_RES_POISON | MR_RES_ELEC,
- 0, 10, MONS_ANGEL, MONS_ANGEL, MH_HOLY, -8,
- { 20, 0, 0, 0 },
- { 9, 3, 5, 0 },
- 10, 10, 10, 7, MST_ANGEL, CE_NOCORPSE, Z_NOZOMBIE, S_SHOUT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_GIANT_BEETLE, 'B', DARKGREY, "giant beetle",
- M_NO_FLAGS,
- MR_VUL_POISON,
- 1000, 10, MONS_GIANT_BEETLE, MONS_GIANT_BEETLE, MH_NATURAL, -3,
- { 20, 0, 0, 0 },
- { 5, 7, 6, 0 },
- 10, 3, 5, 7, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_SILENT, I_INSECT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_CYCLOPS, 'C', BROWN, "cyclops",
- M_WARM_BLOOD | M_EVIL,
- MR_NO_FLAGS,
- 2500, 10, MONS_HILL_GIANT, MONS_CYCLOPS, MH_NATURAL, -3,
- { 35, 0, 0, 0 },
- { 9, 3, 5, 0 },
- 5, 3, 7, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SHOUT, I_NORMAL,
- MONUSE_STARTING_EQUIPMENT
-}
-,
-
-{
- MONS_DRAGON, 'D', GREEN, "dragon",
- M_FLIES | M_SPECIAL_ABILITY, //jmf: warm blood?
- MR_RES_POISON | MR_RES_FIRE | MR_VUL_COLD,
- 2200, 12, MONS_DRAGON, MONS_DRAGON, MH_NATURAL, -4,
- { 20, 13, 13, 0 },
- { 12, 5, 5, 0 },
- 10, 8, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SILENT, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-// These guys get understated because the experience code can't see
-// that they wield two weapons... I'm raising their xp modifier. -- bwr
-{
- MONS_TWO_HEADED_OGRE, 'O', LIGHTRED, "two-headed ogre",
- M_WARM_BLOOD | M_EVIL,
- MR_NO_FLAGS,
- 1500, 15, MONS_OGRE, MONS_TWO_HEADED_OGRE, MH_NATURAL, -4,
- { 17, 13, 0, 0 },
- { 6, 3, 5, 0 },
- 1, 4, 8, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT2, I_NORMAL,
- MONUSE_STARTING_EQUIPMENT
-}
-,
-
-{
- MONS_FIEND, '1', LIGHTRED, "Fiend", //jmf: was RED, like Balrog
- M_FLIES | M_SEE_INVIS | M_EVIL,
- MR_RES_POISON | MR_RES_HELLFIRE | MR_VUL_COLD,
- 0, 18, MONS_FIEND, MONS_FIEND, MH_DEMONIC, -12,
- { 25, 15, 15, 0 },
- { 18, 3, 5, 0 },
- 15, 6, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_ROAR, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_GIANT_SPORE, 'G', GREEN, "giant spore",
- M_LEVITATE,
- MR_RES_POISON,
- 0, 10, MONS_PLANT, MONS_GIANT_SPORE, MH_NATURAL, -3,
- { 1, 0, 0, 0 },
- { 1, 0, 0, 1 },
- 0, 10, 15, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_HOBGOBLIN, 'g', BROWN, "hobgoblin",
- M_WARM_BLOOD | M_EVIL,
- MR_NO_FLAGS,
- 500, 10, MONS_GOBLIN, MONS_HOBGOBLIN, MH_NATURAL, -1,
- { 5, 0, 0, 0 },
- { 1, 4, 5, 0 },
- 2, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_ICE_BEAST, 'I', WHITE, "ice beast",
- M_NO_FLAGS,
- MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD,
- 0, 12, MONS_ICE_BEAST, MONS_ICE_BEAST, MH_NATURAL, -3,
- { 5, 0, 0, 0 },
- { 5, 3, 5, 0 },
- 5, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_ANIMAL_LIKE,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_JELLY, 'J', LIGHTRED, "jelly",
- M_SEE_INVIS | M_SPLITS | M_AMPHIBIOUS,
- MR_RES_POISON,
- 0, 13, MONS_JELLY, MONS_JELLY, MH_NATURAL, -3,
- { 8, 0, 0, 0 },
- { 3, 5, 5, 0 },
- 0, 2, 9, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_EATS_ITEMS
-}
-,
-
-{
- MONS_KOBOLD, 'K', BROWN, "kobold",
- M_WARM_BLOOD,
- MR_NO_FLAGS,
- 400, 10, MONS_KOBOLD, MONS_KOBOLD, MH_NATURAL, -1,
- { 4, 0, 0, 0 },
- { 1, 2, 3, 0 },
- 2, 12, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_LICH, 'L', WHITE, "lich",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_EVIL,
- MR_RES_POISON | MR_RES_COLD | MR_RES_ELEC,
- 0, 16, MONS_LICH, MONS_LICH, MH_UNDEAD, -11,
- { 15, 0, 0, 0 },
- { 20, 2, 4, 0 },
- 10, 10, 10, 7, MST_LICH_I, CE_NOCORPSE, Z_NOZOMBIE, S_SHOUT, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_MUMMY, 'M', WHITE, "mummy",
- M_EVIL,
- MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD,
- 0, 10, MONS_MUMMY, MONS_MUMMY, MH_UNDEAD, -5,
- { 20, 0, 0, 0 },
- { 3, 5, 3, 0 },
- 3, 6, 6, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_ANIMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_GUARDIAN_NAGA, 'N', LIGHTGREEN, "guardian naga",
- M_SPELLCASTER | M_SEE_INVIS | M_ACTUAL_SPELLS | M_WARM_BLOOD,
- MR_RES_POISON,
- 350, 10, MONS_NAGA, MONS_GUARDIAN_NAGA, MH_NATURAL, -6,
- { 19, 0, 0, 0 },
- { 8, 3, 5, 0 },
- 6, 14, 15, 7, MST_GUARDIAN_NAGA, CE_MUTAGEN_RANDOM, Z_SMALL, S_SHOUT, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_OGRE, 'O', BROWN, "ogre",
- M_WARM_BLOOD | M_EVIL,
- MR_NO_FLAGS,
- 1300, 10, MONS_OGRE, MONS_OGRE, MH_NATURAL, -3,
- { 17, 0, 0, 0 },
- { 5, 3, 5, 0 },
- 1, 6, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_NORMAL,
- MONUSE_STARTING_EQUIPMENT
-}
-,
-
-{
- MONS_PLANT, 'P', GREEN, "plant",
- M_NO_EXP_GAIN,
- MR_NO_FLAGS,
- 0, 10, MONS_PLANT, MONS_PLANT, MH_PLANT, 5000,
- { 0, 0, 0, 0 },
- { 10, 3, 5, 0 },
- 10, 0, 0, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_QUEEN_BEE, 'Q', YELLOW, "queen bee",
- M_FLIES,
- MR_VUL_POISON,
- 200, 14, MONS_KILLER_BEE, MONS_QUEEN_BEE, MH_NATURAL, -3,
- { 20, 0, 0, 0 },
- { 7, 3, 5, 0 },
- 10, 10, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_RAKSHASA, 'R', YELLOW, "rakshasa",
- M_SPELLCASTER | M_SEE_INVIS | M_EVIL,
- MR_RES_POISON,
- 0, 15, MONS_RAKSHASA, MONS_RAKSHASA, MH_NATURAL, -10,
- { 20, 0, 0, 0 },
- { 10, 3, 5, 0 },
- 10, 14, 10, 7, MST_RAKSHASA, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_SNAKE, 'S', GREEN, "snake",
- M_COLD_BLOOD | M_AMPHIBIOUS,
- MR_NO_FLAGS,
- 200, 10, MONS_SNAKE, MONS_SNAKE, MH_NATURAL, -3,
- { 5, 0, 0, 0 },
- { 2, 3, 5, 0 },
- 1, 15, 13, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_REPTILE,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_TROLL, 'T', BROWN, "troll",
- M_WARM_BLOOD | M_EVIL,
- MR_NO_FLAGS,
- 1500, 10, MONS_TROLL, MONS_TROLL, MH_NATURAL, -3,
- { 20, 15, 15, 0 },
- { 7, 3, 5, 0 },
- 3, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_UNSEEN_HORROR, 'x', MAGENTA, "unseen horror",
- M_LEVITATE | M_SEE_INVIS | M_INVIS,
- MR_RES_ELEC,
- 0, 12, MONS_UNSEEN_HORROR, MONS_UNSEEN_HORROR, MH_NATURAL, -3,
- { 12, 0, 0, 0 },
- { 7, 3, 5, 0 },
- 5, 10, 30, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_ANIMAL_LIKE,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_VAMPIRE, 'V', RED, "vampire",
- M_SPELLCASTER | M_SEE_INVIS | M_EVIL,
- MR_RES_POISON | MR_RES_COLD,
- 0, 11, MONS_VAMPIRE, MONS_VAMPIRE, MH_UNDEAD, -6,
- { 22, 0, 0, 0 },
- { 6, 3, 5, 0 },
- 10, 10, 10, 7, MST_VAMPIRE, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_WRAITH, 'W', DARKGREY, "wraith",
- M_LEVITATE | M_SEE_INVIS | M_EVIL,
- MR_RES_POISON | MR_RES_COLD,
- 0, 11, MONS_WRAITH, MONS_WRAITH, MH_UNDEAD, -7,
- { 13, 0, 0, 0 },
- { 6, 3, 5, 0 },
- 10, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-// Large abom: (the previous one was small)
-{
- MONS_ABOMINATION_LARGE, 'X', BLACK, "abomination",
- M_EVIL,
- MR_NO_FLAGS,
- 0, 10, MONS_ABOMINATION_SMALL, MONS_ABOMINATION_LARGE, MH_DEMONIC, -7,
- { 40, 0, 0, 0 },
- { 11, 2, 5, 0 },
- 0, 0, 0, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_YAK, 'Y', BROWN, "yak",
- M_WARM_BLOOD,
- MR_NO_FLAGS,
- 1200, 10, MONS_YAK, MONS_YAK, MH_NATURAL, -3,
- { 18, 0, 0, 0 },
- { 7, 3, 5, 0 },
- 4, 7, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_BELLOW, I_ANIMAL,
- MONUSE_NOTHING
-}
-,
-
-// big zombie
-{
- MONS_ZOMBIE_LARGE, 'Z', BROWN, "",
- M_EVIL,
- MR_RES_POISON | MR_RES_COLD,
- 0, 6, MONS_ZOMBIE_SMALL, MONS_ZOMBIE_LARGE, MH_UNDEAD, -1,
- { 23, 0, 0, 0 },
- { 6, 3, 5, 0 },
- 8, 5, 5, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_ORC_WARRIOR, 'o', YELLOW, "orc warrior",
- M_WARM_BLOOD | M_EVIL,
- MR_NO_FLAGS,
- 0, 10, MONS_ORC, MONS_ORC, MH_NATURAL, -3,
- { 20, 0, 0, 0 },
- { 4, 4, 6, 0 },
- 0, 13, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_KOBOLD_DEMONOLOGIST, 'K', MAGENTA, "kobold demonologist",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_EVIL,
- MR_NO_FLAGS,
- 0, 10, MONS_KOBOLD, MONS_KOBOLD, MH_NATURAL, -5,
- { 4, 0, 0, 0 },
- { 4, 3, 5, 0 },
- 2, 13, 10, 7, MST_KOBOLD_DEMONOLOGIST, CE_POISONOUS, Z_NOZOMBIE, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_ORC_WIZARD, 'o', MAGENTA, "orc wizard",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_EVIL,
- MR_NO_FLAGS,
- 0, 10, MONS_ORC, MONS_ORC, MH_NATURAL, -5,
- { 5, 0, 0, 0 },
- { 3, 3, 4, 0 },
- 1, 12, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_ORC_KNIGHT, 'o', LIGHTCYAN, "orc knight",
- M_WARM_BLOOD | M_EVIL,
- MR_NO_FLAGS,
- 0, 10, MONS_ORC, MONS_ORC, MH_NATURAL, -3,
- { 25, 0, 0, 0 },
- { 9, 4, 7, 0 },
- 2, 13, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-/* ******************************************************************
-// the tunneling worm is no more ...
-// not until it can be reimplemented safely {dlb}
-{
- MONS_WORM_TAIL, '~', LIGHTRED, "worm tail",
- M_NO_EXP_GAIN,
- MR_RES_POISON,
- 0, 10, 56, MH_NATURAL, 5000,
- { 0, 0, 0, 0 },
- { 10, 5, 5, 0 },
- 3, 3, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_NOTHING
-}
-,
-****************************************************************** */
-
-{
- MONS_WYVERN, 'D', LIGHTRED, "wyvern",
- M_NO_FLAGS, //jmf: warm blood?
- MR_NO_FLAGS,
- 2000, 10, MONS_WYVERN, MONS_WYVERN, MH_NATURAL, -3,
- { 20, 0, 0, 0 },
- { 5, 3, 5, 0 },
- 5, 10, 15, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_ANIMAL,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_BIG_KOBOLD, 'K', RED, "big kobold",
- M_WARM_BLOOD | M_EVIL,
- MR_NO_FLAGS,
- 0, 10, MONS_KOBOLD, MONS_BIG_KOBOLD, MH_NATURAL, -3,
- { 7, 0, 0, 0 },
- { 5, 3, 5, 0 },
- 3, 12, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_GIANT_EYEBALL, 'G', WHITE, "giant eyeball",
- M_NO_SKELETON | M_LEVITATE,
- MR_NO_FLAGS,
- 400, 10, MONS_GIANT_EYEBALL, MONS_GIANT_EYEBALL, MH_NATURAL, -3,
- { 0, 0, 0, 0 },
- { 3, 3, 5, 0 },
- 0, 1, 3, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_WIGHT, 'W', LIGHTGREY, "wight",
- M_EVIL,
- MR_RES_POISON | MR_RES_COLD,
- 0, 10, MONS_WRAITH, MONS_WIGHT, MH_UNDEAD, -4,
- { 8, 0, 0, 0 },
- { 3, 3, 5, 0 },
- 4, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_OKLOB_PLANT, 'P', GREEN, "oklob plant",
- M_SPECIAL_ABILITY,
- MR_RES_POISON,
- 0, 10, MONS_PLANT, MONS_OKLOB_PLANT, MH_PLANT, -3,
- { 0, 0, 0, 0 },
- { 10, 3, 5, 0 },
- 10, 0, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_WOLF_SPIDER, 's', BROWN, "wolf spider",
- M_NO_FLAGS,
- MR_VUL_POISON,
- 800, 10, MONS_WOLF_SPIDER, MONS_WOLF_SPIDER, MH_NATURAL, -3,
- { 20, 0, 0, 0 },
- { 8, 3, 5, 0 },
- 3, 10, 15, 7, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_SILENT, I_INSECT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_SHADOW, ' ', BLACK, "shadow",
- M_SEE_INVIS | M_EVIL,
- MR_RES_POISON | MR_RES_COLD,
- 0, 10, MONS_WRAITH, MONS_SHADOW, MH_UNDEAD, -5,
- { 5, 0, 0, 0 },
- { 3, 3, 5, 0 },
- 12, 10, 10, 7, BLACK, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_ANIMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_HUNGRY_GHOST, 'p', GREEN, "hungry ghost",
- M_SEE_INVIS | M_FLIES | M_EVIL,
- MR_RES_POISON | MR_RES_COLD,
- 0, 10, MONS_PHANTOM, MONS_HUNGRY_GHOST, MH_UNDEAD, -4,
- { 5, 0, 0, 0 },
- { 7, 3, 5, 0 },
- 0, 17, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_EYE_OF_DRAINING, 'G', LIGHTGREY, "eye of draining",
- M_NO_SKELETON | M_LEVITATE | M_SEE_INVIS,
- MR_NO_FLAGS,
- 400, 10, MONS_GIANT_EYEBALL, MONS_EYE_OF_DRAINING, MH_NATURAL, 5000,
- { 0, 0, 0, 0 },
- { 7, 3, 5, 0 },
- 3, 1, 5, 7, MST_NO_SPELLS, CE_MUTAGEN_RANDOM, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_BUTTERFLY, 'b', BLACK, "butterfly",
- M_FLIES | M_CONFUSED,
- MR_VUL_POISON,
- 150, 10, MONS_BUTTERFLY, MONS_BUTTERFLY, MH_NATURAL, -3,
- { 0, 0, 0, 0 },
- { 1, 3, 5, 0 },
- 0, 25, 25, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_INSECT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_WANDERING_MUSHROOM, 'f', BROWN, "wandering mushroom",
- M_NO_FLAGS,
- MR_RES_POISON,
- 0, 10, MONS_PLANT, MONS_WANDERING_MUSHROOM, MH_PLANT, -3,
- { 20, 0, 0, 0 },
- { 8, 3, 5, 0 },
- 5, 0, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_EFREET, 'E', RED, "efreet",
- M_SPELLCASTER | M_LEVITATE | M_EVIL,
- MR_RES_POISON | MR_RES_FIRE | MR_VUL_COLD,
- 0, 12, MONS_EFREET, MONS_EFREET, MH_DEMONIC, -3,
- { 12, 0, 0, 0 },
- { 7, 3, 5, 0 },
- 10, 5, 10, 7, MST_EFREET, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_BRAIN_WORM, 'w', LIGHTMAGENTA, "brain worm",
- M_SPELLCASTER,
- MR_NO_FLAGS,
- 150, 10, MONS_WORM, MONS_BRAIN_WORM, MH_NATURAL, -3,
- { 0, 0, 0, 0 },
- { 5, 3, 3, 0 },
- 1, 5, 10, 7, MST_BRAIN_WORM, CE_POISONOUS, Z_SMALL, S_SILENT, I_REPTILE,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_GIANT_ORANGE_BRAIN, 'G', LIGHTRED, "giant orange brain",
- M_NO_SKELETON | M_SPELLCASTER | M_LEVITATE | M_SEE_INVIS,
- MR_NO_FLAGS,
- 1000, 13, MONS_GIANT_ORANGE_BRAIN, MONS_GIANT_ORANGE_BRAIN, MH_NATURAL, -8,
- { 0, 0, 0, 0 },
- { 10, 3, 5, 0 },
- 2, 4, 10, 7, MST_GIANT_ORANGE_BRAIN, CE_MUTAGEN_RANDOM, Z_NOZOMBIE, S_SILENT, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_BOULDER_BEETLE, 'B', LIGHTGREY, "boulder beetle",
- M_NO_FLAGS,
- MR_VUL_POISON,
- 2500, 10, MONS_GIANT_BEETLE, MONS_BOULDER_BEETLE, MH_NATURAL, -3,
- { 35, 0, 0, 0 },
- { 9, 3, 5, 0 },
- 20, 2, 3, 7, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_SILENT, I_INSECT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_FLYING_SKULL, 'z', WHITE, "flying skull",
- M_LEVITATE,
- MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC,
- 0, 10, MONS_SKELETON_SMALL, MONS_FLYING_SKULL, MH_UNDEAD, -3,
- { 7, 0, 0, 0 },
- { 2, 3, 5, 0 },
- 10, 17, 15, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SCREAM, I_ANIMAL,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_HELL_HOUND, 'h', DARKGREY, "hell hound",
- M_SEE_INVIS | M_EVIL | M_SPECIAL_ABILITY,
- MR_RES_POISON | MR_RES_HELLFIRE | MR_VUL_COLD,
- 0, 10, MONS_HOUND, MONS_HELL_HOUND, MH_DEMONIC, -3,
- { 13, 0, 0, 0 },
- { 5, 3, 5, 0 },
- 6, 13, 15, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_BARK, I_NORMAL,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_MINOTAUR, 'm', LIGHTRED, "minotaur",
- M_WARM_BLOOD,
- MR_NO_FLAGS,
- 1500, 10, MONS_MINOTAUR, MONS_MINOTAUR, MH_NATURAL, -3,
- { 35, 0, 0, 0 },
- { 13, 3, 5, 0 },
- 5, 7, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_BELLOW, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_ICE_DRAGON, 'D', WHITE, "ice dragon",
- M_FLIES | M_SPECIAL_ABILITY,
- MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD,
- 2200, 10, MONS_DRAGON, MONS_ICE_DRAGON, MH_NATURAL, -3,
- { 17, 17, 17, 0 },
- { 12, 5, 5, 0 },
- 10, 8, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SILENT, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_SLIME_CREATURE, 'J', GREEN, "slime creature",
- M_AMPHIBIOUS,
- MR_RES_POISON,
- 0, 5, MONS_SLIME_CREATURE, MONS_SLIME_CREATURE, MH_NATURAL, -3,
- { 22, 0, 0, 0 },
- { 11, 3, 5, 0 },
- 1, 4, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_FREEZING_WRAITH, 'W', LIGHTBLUE, "freezing wraith",
- M_LEVITATE | M_SEE_INVIS | M_EVIL,
- MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD,
- 0, 10, MONS_WRAITH, MONS_FREEZING_WRAITH, MH_UNDEAD, -4,
- { 19, 0, 0, 0 },
- { 8, 3, 5, 0 },
- 12, 10, 8, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-// fake R - conjured by the R's illusion spell.
-{
- MONS_RAKSHASA_FAKE, 'R', YELLOW, "rakshasa",
- M_EVIL,
- MR_RES_POISON,
- 0, 10, MONS_RAKSHASA_FAKE, MONS_RAKSHASA_FAKE, MH_NATURAL, 5000,
- { 0, 0, 0, 0 },
- { 1, 0, 0, 1 },
- 0, 30, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_ROAR, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_GREAT_ORB_OF_EYES, 'G', LIGHTGREEN, "great orb of eyes",
- M_NO_SKELETON | M_SPELLCASTER | M_LEVITATE | M_SEE_INVIS,
- MR_RES_POISON,
- 900, 13, MONS_GIANT_EYEBALL, MONS_GREAT_ORB_OF_EYES, MH_NATURAL, 5000,
- { 20, 0, 0, 0 },
- { 12, 3, 5, 0 },
- 10, 3, 10, 7, MST_GREAT_ORB_OF_EYES, CE_MUTAGEN_RANDOM, Z_NOZOMBIE, S_SILENT, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_HELLION, '3', BLACK, "hellion",
- M_SPELLCASTER | M_ON_FIRE | M_EVIL,
- MR_RES_POISON | MR_RES_HELLFIRE | MR_VUL_COLD,
- 0, 11, MONS_HELLION, MONS_HELLION, MH_DEMONIC, -7,
- { 10, 0, 0, 0 },
- { 7, 3, 5, 0 },
- 5, 10, 13, 7, RED, CE_NOCORPSE, Z_NOZOMBIE, S_SCREAM, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_ROTTING_DEVIL, '4', GREEN, "rotting devil",
- M_EVIL,
- MR_RES_POISON | MR_RES_COLD,
- 0, 10, MONS_ROTTING_DEVIL, MONS_ROTTING_DEVIL, MH_DEMONIC, -7,
- { 8, 0, 0, 0 },
- { 5, 3, 5, 0 },
- 2, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_TORMENTOR, '3', YELLOW, "tormentor",
- M_SPELLCASTER | M_FLIES | M_SPEAKS | M_EVIL,
- MR_RES_POISON | MR_RES_FIRE,
- 0, 10, MONS_TORMENTOR, MONS_TORMENTOR, MH_DEMONIC, -6,
- { 8, 8, 0, 0 },
- { 7, 3, 5, 0 },
- 12, 12, 13, 7, MST_TORMENTOR, CE_NOCORPSE, Z_NOZOMBIE, S_ROAR, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_REAPER, '2', LIGHTGREY, "reaper",
- M_SEE_INVIS | M_EVIL,
- MR_RES_POISON | MR_RES_COLD,
- 0, 10, MONS_REAPER, MONS_REAPER, MH_DEMONIC, 5000,
- { 32, 0, 0, 0 },
- { 8, 3, 5, 0 },
- 15, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH,
- MONUSE_STARTING_EQUIPMENT
-}
-,
-
-{
- MONS_SOUL_EATER, '2', DARKGREY, "soul eater",
- M_LEVITATE | M_SEE_INVIS | M_EVIL,
- MR_RES_POISON | MR_RES_COLD,
- 0, 12, MONS_SOUL_EATER, MONS_SOUL_EATER, MH_DEMONIC, -10,
- { 25, 0, 0, 0 },
- { 11, 3, 5, 0 },
- 18, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_HAIRY_DEVIL, '4', LIGHTRED, "hairy devil",
- M_EVIL,
- MR_RES_POISON,
- 0, 10, MONS_HAIRY_DEVIL, MONS_HAIRY_DEVIL, MH_DEMONIC, -4,
- { 9, 9, 0, 0 },
- { 6, 3, 5, 0 },
- 7, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SHOUT, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_ICE_DEVIL, '2', WHITE, "ice devil",
- M_SEE_INVIS | M_EVIL,
- MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD,
- 0, 11, MONS_ICE_DEVIL, MONS_ICE_DEVIL, MH_DEMONIC, -6,
- { 16, 0, 0, 0 },
- { 11, 3, 5, 0 },
- 12, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_BLUE_DEVIL, '3', BLUE, "blue devil",
- M_FLIES | M_EVIL,
- MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD,
- 0, 10, MONS_BLUE_DEVIL, MONS_BLUE_DEVIL, MH_DEMONIC, -5,
- { 21, 0, 0, 0 },
- { 7, 3, 5, 0 },
- 14, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-// random
-{
- MONS_BEAST, '4', BROWN, "beast",
- M_EVIL,
- MR_NO_FLAGS,
- 0, 10, MONS_BEAST, MONS_BEAST, MH_DEMONIC, -3,
- { 12, 0, 0, 0 },
- { 5, 3, 5, 0 },
- 0, 0, 0, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_RANDOM, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_IRON_DEVIL, '3', CYAN, "iron devil",
- M_EVIL,
- MR_RES_ELEC | MR_RES_POISON | MR_RES_HELLFIRE | MR_RES_COLD,
- 0, 10, MONS_IRON_DEVIL, MONS_IRON_DEVIL, MH_DEMONIC, -6,
- { 14, 14, 0, 0 },
- { 8, 3, 5, 0 },
- 16, 8, 8, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SCREECH, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_GLOWING_SHAPESHIFTER, '@', RED, "glowing shapeshifter",
- M_NO_FLAGS,
- MR_NO_FLAGS,
- 600, 10, MONS_SHAPESHIFTER, MONS_GLOWING_SHAPESHIFTER, MH_NATURAL, -6,
- { 15, 0, 0, 0 },
- { 10, 3, 5, 0 },
- 0, 10, 10, 7, MST_NO_SPELLS, CE_MUTAGEN_RANDOM, Z_NOZOMBIE, S_SILENT, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_SHAPESHIFTER, '@', LIGHTRED, "shapeshifter",
- M_NO_FLAGS,
- MR_NO_FLAGS,
- 600, 10, MONS_SHAPESHIFTER, MONS_SHAPESHIFTER, MH_NATURAL, -6,
- { 5, 0, 0, 0 },
- { 7, 3, 5, 0 },
- 0, 10, 10, 7, MST_NO_SPELLS, CE_MUTAGEN_RANDOM, Z_NOZOMBIE, S_SILENT, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_GIANT_MITE, 's', LIGHTRED, "giant mite",
- M_NO_FLAGS,
- MR_VUL_POISON,
- 350, 10, MONS_GIANT_MITE, MONS_GIANT_MITE, MH_NATURAL, -1,
- { 5, 0, 0, 0 },
- { 2, 3, 5, 0 },
- 1, 7, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_STEAM_DRAGON, 'D', LIGHTGREY, "steam dragon",
- M_SPELLCASTER | M_FLIES,
- MR_NO_FLAGS,
- 1000, 10, MONS_DRAGON, MONS_STEAM_DRAGON, MH_NATURAL, -3,
- { 12, 0, 0, 0 },
- { 4, 5, 5, 0 },
- 5, 10, 10, 7, MST_STEAM_DRAGON, CE_CLEAN, Z_BIG, S_SILENT, I_ANIMAL_LIKE,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_VERY_UGLY_THING, 'u', RED, "very ugly thing",
- M_WARM_BLOOD | M_AMPHIBIOUS,
- MR_NO_FLAGS,
- 750, 10, MONS_UGLY_THING, MONS_VERY_UGLY_THING, MH_NATURAL, -3,
- { 17, 0, 0, 0 },
- { 12, 3, 5, 0 },
- 4, 8, 8, 7, MST_NO_SPELLS, CE_MUTAGEN_RANDOM, Z_BIG, S_SHOUT, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_ORC_SORCERER, 'o', DARKGREY, "orc sorcerer",
- M_SPELLCASTER | M_SEE_INVIS | M_SPEAKS | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_EVIL,
- MR_RES_FIRE,
- 600, 12, MONS_ORC, MONS_ORC, MH_NATURAL, -3,
- { 7, 0, 0, 0 },
- { 8, 2, 3, 0 },
- 5, 12, 10, 7, MST_ORC_SORCERER, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_HIPPOGRIFF, 'H', BROWN, "hippogriff",
- M_FLIES | M_WARM_BLOOD,
- MR_NO_FLAGS,
- 1000, 10, MONS_HIPPOGRIFF, MONS_HIPPOGRIFF, MH_NATURAL, -3,
- { 10, 8, 8, 0 },
- { 7, 3, 5, 0 },
- 2, 7, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SCREECH, I_ANIMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_GRIFFON, 'H', YELLOW, "griffon",
- M_FLIES | M_WARM_BLOOD,
- MR_NO_FLAGS,
- 1800, 10, MONS_GRIFFON, MONS_GRIFFON, MH_NATURAL, -3,
- { 18, 10, 10, 0 },
- { 12, 3, 5, 0 },
- 4, 6, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SCREECH, I_ANIMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_HYDRA, 'D', LIGHTGREEN, "hydra",
- M_AMPHIBIOUS, // because it likes the swamp -- bwr
- MR_RES_POISON,
- 1800, 11, MONS_HYDRA, MONS_HYDRA, MH_NATURAL, -3,
- { 18, 0, 0, 0 },
- { 13, 3, 5, 0 },
- 0, 5, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_ROAR, I_REPTILE,
- MONUSE_OPEN_DOORS
-}
-,
-
-// small skeleton
-{
- MONS_SKELETON_SMALL, 'z', LIGHTGREY, "",
- M_EVIL,
- MR_RES_POISON | MR_RES_COLD,
- 0, 10, MONS_SKELETON_SMALL, MONS_SKELETON_SMALL, MH_UNDEAD, -1,
- { 0, 0, 0, 0 },
- { 0, 0, 0, 0 },
- 0, 0, 0, 0, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-// large skeleton
-{
- MONS_SKELETON_LARGE, 'Z', LIGHTGREY, "",
- M_EVIL,
- MR_RES_POISON | MR_RES_COLD,
- 0, 10, MONS_SKELETON_SMALL, MONS_SKELETON_LARGE, MH_UNDEAD, -1,
- { 0, 0, 0, 0 },
- { 0, 0, 0, 0 },
- 0, 0, 0, 0, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-
-{
- MONS_HELL_KNIGHT, '@', RED, "hell knight",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_EVIL,
- MR_RES_FIRE,
- 550, 10, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -3,
- { 13, 0, 0, 0 },
- { 10, 3, 6, 0 },
- 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_NECROMANCER, '@', DARKGREY, "necromancer",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_EVIL,
- MR_NO_FLAGS,
- 550, 10, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -4,
- { 6, 0, 0, 0 },
- { 10, 2, 4, 0 },
- 0, 13, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_WIZARD, '@', MAGENTA, "wizard",
- M_SPELLCASTER | M_SPEAKS | M_ACTUAL_SPELLS | M_WARM_BLOOD,
- MR_RES_ELEC,
- 550, 10, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -4,
- { 6, 0, 0, 0 },
- { 10, 2, 4, 0 },
- 0, 13, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_ORC_PRIEST, 'o', LIGHTGREEN, "orc priest",
- M_SPELLCASTER | M_PRIEST | M_WARM_BLOOD | M_EVIL,
- MR_NO_FLAGS,
- 600, 10, MONS_ORC, MONS_ORC, MH_NATURAL, -4,
- { 6, 0, 0, 0 },
- { 3, 3, 4, 0 },
- 1, 10, 10, 7, MST_ORC_PRIEST, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_ORC_HIGH_PRIEST, 'o', GREEN, "orc high priest",
- M_SPELLCASTER | M_SEE_INVIS | M_SPEAKS | M_PRIEST | M_WARM_BLOOD | M_EVIL,
- MR_RES_HELLFIRE,
- 600, 10, MONS_ORC, MONS_ORC, MH_NATURAL, -4,
- { 7, 0, 0, 0 },
- { 11, 3, 4, 0 },
- 1, 12, 10, 7, MST_ORC_HIGH_PRIEST, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-// this is a dummy monster, used for corpses
-// mv:but it can be generated by polymorph spells and because IMO it's
-// logical polymorph target so complete monster statistics should exist.
-// Same thing for elf dummy monster.
-
-{
- MONS_HUMAN, '@', LIGHTGRAY, "human",
- M_WARM_BLOOD,
- MR_NO_FLAGS,
- 550, 10, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -3,
- { 10, 0, 0, 0 },
- { 1, 3, 5, 0 },
- 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_GNOLL, 'g', YELLOW, "gnoll",
- M_WARM_BLOOD,
- MR_NO_FLAGS,
- 750, 10, MONS_GNOLL, MONS_GNOLL, MH_NATURAL, -3,
- { 9, 0, 0, 0 },
- { 2, 4, 5, 0 },
- 2, 9, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_CLAY_GOLEM, '8', BROWN, "clay golem",
- M_SEE_INVIS,
- MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC,
- 0, 10, MONS_CLAY_GOLEM, MONS_CLAY_GOLEM, MH_NONLIVING, 5000,
- { 11, 11, 0, 0 },
- { 8, 7, 3, 0 },
- 7, 5, 8, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_WOOD_GOLEM, '8', YELLOW, "wood golem",
- M_NO_FLAGS,
- MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD | MR_RES_ELEC,
- 0, 10, MONS_CLAY_GOLEM, MONS_WOOD_GOLEM, MH_NONLIVING, 5000,
- { 10, 0, 0, 0 },
- { 6, 6, 3, 0 },
- 5, 6, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_STONE_GOLEM, '8', LIGHTGREY, "stone golem",
- M_NO_FLAGS,
- MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC,
- 0, 10, MONS_CLAY_GOLEM, MONS_STONE_GOLEM, MH_NONLIVING, 5000,
- { 28, 0, 0, 0 },
- { 12, 7, 4, 0 },
- 12, 4, 7, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_IRON_GOLEM, '8', CYAN, "iron golem",
- M_SEE_INVIS,
- MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC,
- 0, 10, MONS_CLAY_GOLEM, MONS_IRON_GOLEM, MH_NONLIVING, 5000,
- { 35, 0, 0, 0 },
- { 15, 7, 4, 0 },
- 15, 3, 7, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_CRYSTAL_GOLEM, '8', WHITE, "crystal golem",
- M_SEE_INVIS,
- MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC,
- 0, 10, MONS_CLAY_GOLEM, MONS_CRYSTAL_GOLEM, MH_NONLIVING, 5000,
- { 40, 0, 0, 0 },
- { 13, 7, 4, 0 },
- 22, 3, 7, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_TOENAIL_GOLEM, '8', LIGHTGREY, "toenail golem",
- M_NO_FLAGS,
- MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC,
- 0, 10, MONS_CLAY_GOLEM, MONS_TOENAIL_GOLEM, MH_NONLIVING, 5000,
- { 13, 0, 0, 0 },
- { 9, 5, 3, 0 },
- 8, 5, 8, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_MOTTLED_DRAGON, 'D', RED, "mottled dragon",
- M_SPELLCASTER | M_FLIES,
- MR_RES_POISON | MR_RES_FIRE,
- 1100, 10, MONS_DRAGON, MONS_MOTTLED_DRAGON, MH_NATURAL, -3,
- { 15, 0, 0, 0 },
- { 5, 3, 5, 0 },
- 5, 10, 10, 7, MST_MOTTLED_DRAGON, CE_POISONOUS, Z_BIG, S_SILENT, I_ANIMAL_LIKE,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_EARTH_ELEMENTAL, '#', BROWN, "earth elemental",
- M_NO_FLAGS,
- MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC,
- 0, 10, MONS_EARTH_ELEMENTAL, MONS_EARTH_ELEMENTAL, MH_NONLIVING, 5000,
- { 40, 0, 0, 0 },
- { 6, 5, 5, 0 },
- 14, 4, 6, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_FIRE_ELEMENTAL, '#', YELLOW, "fire elemental",
- M_FLIES,
- MR_RES_POISON | MR_RES_HELLFIRE | MR_VUL_COLD | MR_RES_ELEC,
- 0, 10, MONS_EARTH_ELEMENTAL, MONS_FIRE_ELEMENTAL, MH_NONLIVING, 5000,
- { 5, 0, 0, 0 },
- { 6, 3, 5, 0 },
- 4, 12, 13, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_AIR_ELEMENTAL, 'v', LIGHTGREY, "air elemental",
- M_LEVITATE | M_SEE_INVIS | M_FLIES,
- MR_RES_ELEC | MR_RES_POISON,
- 0, 5, MONS_EARTH_ELEMENTAL, MONS_AIR_ELEMENTAL, MH_NONLIVING, 5000,
- { 15, 0, 0, 0 },
- { 6, 3, 5, 0 },
- 2, 18, 25, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_OPEN_DOORS
-}
-,
-
-// water elementals are later (with the other water monsters)
-
-{
- MONS_ICE_FIEND, '1', WHITE, "Ice Fiend",
- M_SPELLCASTER | M_FLIES | M_SEE_INVIS | M_FROZEN | M_EVIL,
- MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD,
- 0, 10, MONS_FIEND, MONS_ICE_FIEND, MH_DEMONIC, -12,
- { 25, 25, 0, 0 },
- { 18, 3, 5, 0 },
- 15, 6, 10, 7, MST_ICE_FIEND, CE_CONTAMINATED, Z_NOZOMBIE, S_ROAR, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_SHADOW_FIEND, '1', DARKGREY, "Shadow Fiend",
- M_SPELLCASTER | M_LEVITATE | M_SEE_INVIS | M_EVIL,
- MR_RES_POISON | MR_RES_COLD | MR_RES_ELEC,
- 0, 10, MONS_FIEND, MONS_SHADOW_FIEND, MH_DEMONIC, -13,
- { 25, 15, 15, 0 },
- { 18, 3, 5, 0 },
- 15, 6, 10, 7, MST_SHADOW_FIEND, CE_CONTAMINATED, Z_NOZOMBIE, S_ROAR, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_BROWN_SNAKE, 'S', BROWN, "brown snake",
- M_COLD_BLOOD | M_AMPHIBIOUS,
- MR_RES_POISON,
- 300, 10, MONS_SNAKE, MONS_BROWN_SNAKE, MH_NATURAL, -3,
- { 10, 0, 0, 0 },
- { 4, 3, 5, 0 },
- 2, 15, 14, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_HISS, I_REPTILE,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_GIANT_LIZARD, 'l', GREEN, "giant lizard",
- M_COLD_BLOOD,
- MR_NO_FLAGS,
- 600, 10, MONS_GIANT_LIZARD, MONS_GIANT_LIZARD, MH_NATURAL, -3,
- { 20, 0, 0, 0 },
- { 5, 3, 5, 0 },
- 4, 10, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_REPTILE,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_SPECTRAL_WARRIOR, 'W', LIGHTGREEN, "spectral warrior",
- M_LEVITATE | M_SEE_INVIS | M_EVIL,
- MR_RES_POISON | MR_RES_COLD,
- 0, 13, MONS_WRAITH, MONS_SPECTRAL_WARRIOR, MH_UNDEAD, -6,
- { 18, 0, 0, 0 },
- { 9, 3, 5, 0 },
- 12, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_PULSATING_LUMP, 'J', RED, "pulsating lump",
- M_SEE_INVIS,
- MR_RES_POISON,
- 0, 3, MONS_JELLY, MONS_PULSATING_LUMP, MH_NATURAL, -3,
- { 13, 0, 0, 0 },
- { 10, 3, 5, 0 },
- 2, 6, 5, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_STORM_DRAGON, 'D', LIGHTBLUE, "storm dragon",
- M_SPELLCASTER | M_FLIES,
- MR_RES_ELEC | MR_RES_COLD,
- 2800, 12, MONS_DRAGON, MONS_STORM_DRAGON, MH_NATURAL, -5,
- { 25, 15, 15, 0 },
- { 14, 5, 5, 0 },
- 13, 10, 12, 7, MST_STORM_DRAGON, CE_CLEAN, Z_BIG, S_ROAR, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_YAKTAUR, 'c', LIGHTRED, "yaktaur",
- M_WARM_BLOOD,
- MR_NO_FLAGS,
- 2000, 10, MONS_YAKTAUR, MONS_YAKTAUR, MH_NATURAL, -3,
- { 15, 0, 0, 0 },
- { 8, 3, 5, 0 },
- 4, 4, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_DEATH_YAK, 'Y', DARKGREY, "death yak",
- M_WARM_BLOOD | M_EVIL,
- MR_NO_FLAGS,
- 1500, 10, MONS_YAK, MONS_DEATH_YAK, MH_NATURAL, -5,
- { 30, 0, 0, 0 },
- { 14, 3, 5, 0 },
- 9, 5, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_BELLOW, I_ANIMAL,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_ROCK_TROLL, 'T', LIGHTGREY, "rock troll",
- M_WARM_BLOOD | M_EVIL,
- MR_NO_FLAGS,
- 2200, 11, MONS_TROLL, MONS_ROCK_TROLL, MH_NATURAL, -4,
- { 30, 20, 20, 0 },
- { 11, 3, 5, 0 },
- 13, 6, 8, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_STONE_GIANT, 'C', LIGHTGREY, "stone giant",
- M_WARM_BLOOD | M_EVIL,
- MR_NO_FLAGS,
- 3000, 10, MONS_HILL_GIANT, MONS_STONE_GIANT, MH_NATURAL, -4,
- { 45, 0, 0, 0 },
- { 16, 3, 5, 0 },
- 12, 2, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_NORMAL,
- MONUSE_STARTING_EQUIPMENT
-}
-,
-
-{
- MONS_FLAYED_GHOST, 'p', RED, "flayed ghost",
- M_FLIES | M_EVIL,
- MR_RES_POISON,
- 0, 10, MONS_PHANTOM, MONS_FLAYED_GHOST, MH_UNDEAD, -4,
- { 30, 0, 0, 0 },
- { 11, 3, 5, 0 },
- 0, 14, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_BUMBLEBEE, 'k', RED, "bumblebee",
- M_FLIES,
- MR_VUL_POISON,
- 300, 10, MONS_KILLER_BEE, MONS_BUMBLEBEE, MH_NATURAL, -3,
- { 20, 0, 0, 0 },
- { 7, 3, 5, 0 },
- 4, 15, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_BUZZ, I_INSECT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_REDBACK, 's', RED, "redback",
- M_NO_FLAGS,
- MR_VUL_POISON,
- 1000, 14, MONS_WOLF_SPIDER, MONS_REDBACK, MH_NATURAL, -3,
- { 18, 0, 0, 0 },
- { 6, 3, 5, 0 },
- 2, 12, 15, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_INSUBSTANTIAL_WISP, 'p', LIGHTGREY, "insubstantial wisp",
- M_LEVITATE | M_SPECIAL_ABILITY,
- MR_RES_ELEC | MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD,
- 0, 17, MONS_INSUBSTANTIAL_WISP, MONS_INSUBSTANTIAL_WISP, MH_NONLIVING, 5000,
- { 12, 0, 0, 0 },
- { 6, 1, 2, 0 },
- 20, 20, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_MOAN, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_VAPOUR, '#', LIGHTGREY, "vapour",
- M_SPELLCASTER | M_LEVITATE | M_SEE_INVIS | M_INVIS | M_CONFUSED,
- MR_RES_ELEC | MR_RES_POISON,
- 0, 21, MONS_VAPOUR, MONS_VAPOUR, MH_NONLIVING, 5000,
- { 0, 0, 0, 0 },
- { 12, 2, 3, 0 },
- 0, 12, 10, 7, MST_STORM_DRAGON, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_OGRE_MAGE, 'O', MAGENTA, "ogre-mage",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_WARM_BLOOD | M_EVIL,
- MR_RES_ELEC,
- 0, 16, MONS_OGRE, MONS_OGRE, MH_NATURAL, -6,
- { 12, 0, 0, 0 },
- { 10, 3, 5, 0 },
- 1, 7, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_SPINY_WORM, 'w', DARKGREY, "spiny worm",
- M_NO_FLAGS,
- MR_VUL_POISON,
- 1300, 13, MONS_WORM, MONS_SPINY_WORM, MH_NATURAL, -3,
- { 32, 0, 0, 0 },
- { 12, 3, 5, 0 },
- 10, 6, 9, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-// these are named more explicitly when they attack, also when you use 'x'
-// to examine them.
-{
- MONS_DANCING_WEAPON, '(', BLACK, "dancing weapon",
- M_LEVITATE,
- MR_RES_POISON | MR_RES_HELLFIRE | MR_RES_COLD | MR_RES_ELEC,
- 0, 10, MONS_DANCING_WEAPON, MONS_DANCING_WEAPON, MH_NONLIVING, 5000,
- { 30, 0, 0, 0 },
- { 15, 0, 0, 15 },
- 10, 20, 15, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_TITAN, 'C', MAGENTA, "titan",
- M_SPELLCASTER | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL,
- MR_RES_ELEC,
- 3500, 12, MONS_HILL_GIANT, MONS_TITAN, MH_NATURAL, -7,
- { 55, 0, 0, 0 },
- { 20, 3, 5, 0 },
- 10, 3, 10, 7, MST_TITAN, CE_CLEAN, Z_BIG, S_SHOUT, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_GOLDEN_DRAGON, 'D', YELLOW, "golden dragon",
- M_SPELLCASTER | M_FLIES | M_SEE_INVIS,
- MR_RES_ELEC | MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD,
- 3000, 17, MONS_DRAGON, MONS_GOLDEN_DRAGON, MH_NATURAL, -8,
- { 40, 20, 20, 0 },
- { 18, 4, 4, 0 },
- 15, 7, 10, 7, MST_GOLDEN_DRAGON, CE_POISONOUS, Z_BIG, S_ROAR, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-// 147 - dummy monster, used for corpses etc.
-//mv: have to exist because it's (and should be) valid polymorph target.
-{
- MONS_ELF, 'e', DARKGREY, "elf",
- M_WARM_BLOOD,
- MR_NO_FLAGS,
- 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -3,
- { 10, 0, 0, 0 },
- { 3, 3, 3, 0 },
- 0, 12, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SILENT, I_PLANT,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-
-// Used to be "lindworm" and a GREEN 'l'... I'm hoping that by
-// making it a 'd' and using an alternate spelling people will
-// more intuitively know that this isn't a regular lizard. -- bwr
-{
- MONS_LINDWURM, 'd', LIGHTGREEN, "lindwurm",
- M_SPECIAL_ABILITY,
- MR_NO_FLAGS,
- 1000, 11, MONS_DRAGON, MONS_LINDWURM, MH_NATURAL, -3,
- { 20, 10, 10, 0 },
- { 9, 3, 5, 0 },
- 8, 6, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_ROAR, I_REPTILE,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_ELEPHANT_SLUG, 'm', LIGHTGREY, "elephant slug",
- M_NO_SKELETON,
- MR_VUL_POISON,
- 1500, 10, MONS_GIANT_SLUG, MONS_ELEPHANT_SLUG, MH_NATURAL, -3,
- { 40, 0, 0, 0 },
- { 20, 5, 3, 0 },
- 2, 1, 4, 10, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_SILENT, I_INSECT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_WAR_DOG, 'h', CYAN, "war dog",
- M_SEE_INVIS | M_WARM_BLOOD,
- MR_NO_FLAGS,
- 350, 10, MONS_HOUND, MONS_WAR_DOG, MH_NATURAL, -3,
- { 12, 0, 0, 0 },
- { 4, 3, 5, 0 },
- 4, 15, 17, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_BARK, I_ANIMAL,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_GREY_RAT, 'r', LIGHTGREY, "grey rat",
- M_WARM_BLOOD,
- MR_NO_FLAGS,
- 250, 10, MONS_RAT, MONS_GREY_RAT, MH_NATURAL, -3,
- { 5, 0, 0, 0 },
- { 1, 3, 6, 0 },
- 2, 12, 12, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SILENT, I_ANIMAL,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_GREEN_RAT, 'r', LIGHTGREEN, "green rat",
- M_WARM_BLOOD,
- MR_NO_FLAGS,
- 250, 10, MONS_RAT, MONS_GREEN_RAT, MH_NATURAL, -3,
- { 10, 0, 0, 0 },
- { 2, 3, 5, 0 },
- 5, 11, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_ANIMAL,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_ORANGE_RAT, 'r', LIGHTRED, "orange rat",
- M_WARM_BLOOD,
- MR_NO_FLAGS,
- 250, 10, MONS_RAT, MONS_ORANGE_RAT, MH_NATURAL, -3,
- { 20, 0, 0, 0 },
- { 3, 3, 5, 0 },
- 7, 10, 12, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_ROAR, I_ANIMAL,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_BLACK_SNAKE, 'S', DARKGREY, "black snake",
- M_COLD_BLOOD,
- MR_RES_POISON,
- 500, 12, MONS_SNAKE, MONS_BLACK_SNAKE, MH_NATURAL, -3,
- { 20, 0, 0, 0 },
- { 7, 3, 5, 0 },
- 4, 15, 18, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_HISS, I_REPTILE,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_SHEEP, 'Y', LIGHTGREY, "sheep",
- M_WARM_BLOOD,
- MR_NO_FLAGS,
- 1200, 10, MONS_SHEEP, MONS_SHEEP, MH_NATURAL, -3,
- { 13, 0, 0, 0 },
- { 3, 3, 5, 0 },
- 2, 7, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_BELLOW, I_ANIMAL,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_GHOUL, 'n', RED, "ghoul",
- M_EVIL,
- MR_RES_POISON | MR_RES_COLD,
- 500, 12, MONS_GHOUL, MONS_GHOUL, MH_UNDEAD, -5,
- { 9, 0, 0, 0 },
- { 4, 3, 5, 0 },
- 4, 10, 10, 7, MST_NO_SPELLS, CE_HCL, Z_NOZOMBIE, S_SILENT, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_HOG, 'h', LIGHTRED, "hog",
- M_WARM_BLOOD,
- MR_NO_FLAGS,
- 700, 10, MONS_HOG, MONS_HOG, MH_NATURAL, -3,
- { 14, 0, 0, 0 },
- { 6, 3, 5, 0 },
- 2, 9, 13, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_ANIMAL,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_GIANT_MOSQUITO, 'y', DARKGREY, "giant mosquito",
- M_FLIES,
- MR_VUL_POISON,
- 100, 10, MONS_GIANT_MOSQUITO, MONS_GIANT_MOSQUITO, MH_NATURAL, -3,
- { 10, 0, 0, 0 },
- { 1, 3, 5, 0 },
- 0, 13, 12, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_WHINE, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_GIANT_CENTIPEDE, 's', GREEN, "giant centipede",
- M_NO_FLAGS,
- MR_VUL_POISON,
- 350, 10, MONS_GIANT_CENTIPEDE, MONS_GIANT_CENTIPEDE, MH_NATURAL, -3,
- { 2, 0, 0, 0 },
- { 2, 3, 3, 0 },
- 2, 14, 13, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT,
- MONUSE_NOTHING
-}
-,
-
-
-
-{
- MONS_IRON_TROLL, 'T', CYAN, "iron troll",
- M_WARM_BLOOD | M_EVIL,
- MR_RES_FIRE | MR_RES_COLD,
- 2400, 10, MONS_TROLL, MONS_IRON_TROLL, MH_NATURAL, -5,
- { 35, 25, 25, 0 },
- { 16, 3, 5, 0 },
- 20, 4, 7, 7, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_ROAR, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_NAGA, 'N', GREEN, "naga",
- M_SPELLCASTER | M_SEE_INVIS | M_WARM_BLOOD,
- MR_RES_POISON,
- 750, 10, MONS_NAGA, MONS_NAGA, MH_NATURAL, -6,
- { 13, 0, 0, 0 },
- { 5, 3, 5, 0 },
- 6, 10, 8, 7, MST_NAGA, CE_POISONOUS, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_FIRE_GIANT, 'C', RED, "fire giant",
- M_SPELLCASTER | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL,
- MR_RES_FIRE,
- 2400, 11, MONS_HILL_GIANT, MONS_FIRE_GIANT, MH_NATURAL, -4,
- { 30, 0, 0, 0 },
- { 16, 3, 6, 0 },
- 8, 4, 10, 7, MST_EFREET, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_FROST_GIANT, 'C', LIGHTBLUE, "frost giant",
- M_SPELLCASTER | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL,
- MR_RES_COLD,
- 2600, 11, MONS_HILL_GIANT, MONS_FROST_GIANT, MH_NATURAL, -4,
- { 35, 0, 0, 0 },
- { 16, 4, 5, 0 },
- 9, 3, 10, 7, MST_FROST_GIANT, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_FIREDRAKE, 'l', RED, "firedrake",
- M_FLIES | M_SPECIAL_ABILITY,
- MR_RES_FIRE,
- 900, 10, MONS_FIREDRAKE, MONS_FIREDRAKE, MH_NATURAL, -3,
- { 8, 0, 0, 0 },
- { 6, 3, 5, 0 },
- 3, 12, 12, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SILENT, I_ANIMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_SHADOW_DRAGON, 'D', DARKGREY, "shadow dragon",
- M_SPELLCASTER | M_FLIES | M_SEE_INVIS,
- MR_RES_POISON | MR_RES_COLD,
- 2000, 12, MONS_DRAGON, MONS_SHADOW_DRAGON, MH_NATURAL, -5,
- { 20, 15, 15, 0 },
- { 17, 5, 5, 0 },
- 15, 10, 10, 7, MST_SHADOW_DRAGON, CE_CLEAN, Z_BIG, S_ROAR, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-{
- MONS_YELLOW_SNAKE, 'S', YELLOW, "yellow snake",
- M_COLD_BLOOD,
- MR_RES_POISON,
- 400, 10, MONS_SNAKE, MONS_YELLOW_SNAKE, MH_NATURAL, -3,
- { 15, 0, 0, 0 },
- { 6, 3, 5, 0 },
- 4, 14, 13, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_HISS, I_REPTILE,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_GREY_SNAKE, 'S', LIGHTGREY, "grey snake",
- M_COLD_BLOOD,
- MR_NO_FLAGS,
- 600, 10, MONS_SNAKE, MONS_GREY_SNAKE, MH_NATURAL, -3,
- { 30, 0, 0, 0 },
- { 11, 3, 5, 0 },
- 4, 16, 18, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_HISS, I_REPTILE,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_DEEP_TROLL, 'T', DARKGREY, "deep troll",
- M_WARM_BLOOD | M_SEE_INVIS | M_EVIL,
- MR_NO_FLAGS,
- 1500, 12, MONS_TROLL, MONS_DEEP_TROLL, MH_NATURAL, -3,
- { 27, 20, 20, 0 },
- { 10, 3, 5, 0 },
- 6, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_GIANT_BLOWFLY, 'y', LIGHTGREY, "giant blowfly",
- M_FLIES,
- MR_VUL_POISON,
- 200, 10, MONS_GIANT_BLOWFLY, MONS_GIANT_BLOWFLY, MH_NATURAL, -3,
- { 13, 0, 0, 0 },
- { 5, 3, 5, 0 },
- 2, 15, 19, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_BUZZ, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_RED_WASP, 'y', RED, "red wasp",
- M_FLIES,
- MR_VUL_POISON,
- 400, 14, MONS_YELLOW_WASP, MONS_RED_WASP, MH_NATURAL, -3,
- { 23, 0, 0, 0 },
- { 8, 3, 5, 0 },
- 7, 14, 15, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_BUZZ, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_SWAMP_DRAGON, 'D', BROWN, "swamp dragon",
- M_SPELLCASTER | M_FLIES,
- MR_RES_POISON,
- 1900, 11, MONS_DRAGON, MONS_SWAMP_DRAGON, MH_NATURAL, -3,
- { 18, 9, 9, 0 },
- { 9, 5, 5, 0 },
- 7, 7, 10, 7, MST_SWAMP_DRAGON, CE_CONTAMINATED, Z_BIG, S_ROAR, I_ANIMAL_LIKE,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_SWAMP_DRAKE, 'l', BROWN, "swamp drake",
- M_SPELLCASTER | M_FLIES | M_EVIL,
- MR_RES_POISON,
- 900, 11, MONS_DRAGON, MONS_SWAMP_DRAKE, MH_NATURAL, -3,
- { 14, 0, 0, 0 },
- { 4, 5, 5, 0 },
- 3, 11, 11, 7, MST_SWAMP_DRAKE, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_ANIMAL_LIKE,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_DEATH_DRAKE, 'l', DARKGREY, "death drake",
- M_SPELLCASTER | M_FLIES | M_EVIL,
- MR_RES_POISON,
- 900, 11, MONS_DRAGON, MONS_DEATH_DRAKE, MH_NATURAL, 3,
- { 12, 0, 0, 0 },
- { 9, 5, 7, 0 },
- 6, 14, 13, 10, MST_DEATH_DRAKE, CE_HCL, Z_BIG, S_ROAR, I_ANIMAL_LIKE,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_SOLDIER_ANT, 'a', LIGHTGREY, "soldier ant",
- M_NO_FLAGS,
- MR_VUL_POISON,
- 900, 10, MONS_GIANT_ANT, MONS_SOLDIER_ANT, MH_NATURAL, -3,
- { 14, 0, 0, 0 },
- { 6, 3, 5, 0 },
- 8, 10, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_HILL_GIANT, 'C', LIGHTRED, "hill giant",
- M_WARM_BLOOD | M_EVIL,
- MR_NO_FLAGS,
- 1600, 10, MONS_HILL_GIANT, MONS_HILL_GIANT, MH_NATURAL, -3,
- { 30, 0, 0, 0 },
- { 11, 3, 5, 0 },
- 3, 4, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_QUEEN_ANT, 'Q', DARKGREY, "queen ant",
- M_NO_FLAGS,
- MR_VUL_POISON,
- 1200, 10, MONS_GIANT_ANT, MONS_QUEEN_ANT, MH_NATURAL, -3,
- { 20, 0, 0, 0 },
- { 13, 3, 5, 0 },
- 14, 3, 7, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_ANT_LARVA, 'w', LIGHTGREY, "ant larva",
- M_NO_SKELETON,
- MR_VUL_POISON,
- 350, 5, MONS_GIANT_ANT, MONS_ANT_LARVA, MH_NATURAL, -3,
- { 5, 0, 0, 0 },
- { 2, 3, 5, 0 },
- 2, 6, 6, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT,
- MONUSE_NOTHING
-}
-,
-
-
-{
- MONS_GIANT_FROG, 'F', GREEN, "giant frog",
- M_COLD_BLOOD | M_AMPHIBIOUS,
- MR_NO_FLAGS,
- 500, 10, MONS_GIANT_FROG, MONS_GIANT_FROG, MH_NATURAL, -3,
- { 9, 0, 0, 0 },
- { 4, 3, 5, 0 },
- 0, 12, 15, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_CROAK, I_ANIMAL,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_GIANT_BROWN_FROG, 'F', BROWN, "giant brown frog",
- M_COLD_BLOOD | M_AMPHIBIOUS,
- MR_NO_FLAGS,
- 890, 10, MONS_GIANT_FROG, MONS_GIANT_BROWN_FROG, MH_NATURAL, -3,
- { 14, 0, 0, 0 },
- { 8, 3, 5, 0 },
- 2, 11, 13, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_CROAK, I_ANIMAL,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_SPINY_FROG, 'F', YELLOW, "spiny frog",
- M_COLD_BLOOD | M_AMPHIBIOUS,
- MR_RES_POISON,
- 1000, 10, MONS_GIANT_FROG, MONS_SPINY_FROG, MH_NATURAL, -3,
- { 26, 0, 0, 0 },
- { 7, 3, 5, 0 },
- 6, 9, 12, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_CROAK, I_ANIMAL,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_BLINK_FROG, 'F', LIGHTGREEN, "blink frog",
- M_COLD_BLOOD | M_AMPHIBIOUS | M_SPECIAL_ABILITY,
- MR_NO_FLAGS,
- 800, 12, MONS_GIANT_FROG, MONS_BLINK_FROG, MH_NATURAL, -5,
- { 20, 0, 0, 0 },
- { 6, 3, 5, 0 },
- 3, 12, 14, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_CROAK, I_ANIMAL,
- MONUSE_NOTHING
-}
-,
-{
- MONS_GIANT_COCKROACH, 'a', BROWN, "giant cockroach",
- M_NO_FLAGS,
- MR_NO_FLAGS,
- 250, 10, MONS_GIANT_COCKROACH, MONS_GIANT_COCKROACH, MH_NATURAL, -1,
- { 2, 0, 0, 0 },
- { 1, 3, 4, 0 },
- 3, 10, 12, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SILENT, I_INSECT,
- MONUSE_NOTHING
-}
-,
-{
- MONS_SMALL_SNAKE, 'S', LIGHTGREEN, "small snake",
- M_COLD_BLOOD,
- MR_NO_FLAGS,
- 100, 13, MONS_SNAKE, MONS_SMALL_SNAKE, MH_NATURAL, -1,
- { 2, 0, 0, 0 },
- { 1, 2, 3, 0 },
- 0, 11, 12, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_REPTILE,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_WHITE_IMP, '5', WHITE, "white imp",
- M_SPELLCASTER | M_FLIES | M_SPEAKS | M_EVIL,
- MR_RES_COLD,
- 0, 10, MONS_IMP, MONS_WHITE_IMP, MH_DEMONIC, -3,
- { 4, 0, 0, 0 },
- { 2, 3, 5, 0 },
- 4, 10, 10, 7, MST_WHITE_IMP, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_LEMURE, '5', YELLOW, "lemure",
- M_EVIL,
- MR_RES_POISON,
- 0, 10, MONS_LEMURE, MONS_LEMURE, MH_DEMONIC, -3,
- { 12, 0, 0, 0 },
- { 2, 3, 5, 0 },
- 1, 12, 12, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_MOAN, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_UFETUBUS, '5', LIGHTCYAN, "ufetubus",
- M_EVIL,
- MR_VUL_FIRE | MR_RES_COLD,
- 0, 10, MONS_UFETUBUS, MONS_UFETUBUS, MH_DEMONIC, -3,
- { 5, 5, 0, 0 },
- { 1, 4, 6, 0 },
- 2, 15, 15, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_MANES, '5', LIGHTRED, "manes",
- M_EVIL,
- MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD | MR_RES_POISON,
- 0, 10, MONS_MANES, MONS_MANES, MH_DEMONIC, -3,
- { 5, 3, 3, 0 },
- { 3, 3, 5, 0 },
- 2, 8, 8, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_MIDGE, '5', LIGHTGREEN, "midge",
- M_FLIES | M_EVIL,
- MR_RES_POISON,
- 0, 10, MONS_MIDGE, MONS_MIDGE, MH_DEMONIC, -3,
- { 8, 0, 0, 0 },
- { 2, 3, 5, 0 },
- 4, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_NEQOXEC, '3', MAGENTA, "neqoxec",
- M_SPELLCASTER | M_LEVITATE | M_EVIL,
- MR_RES_POISON,
- 0, 12, MONS_NEQOXEC, MONS_NEQOXEC, MH_DEMONIC, -6,
- { 15, 0, 0, 0 },
- { 6, 3, 5, 0 },
- 4, 12, 10, 7, MST_NEQOXEC, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_ORANGE_DEMON, '3', LIGHTRED, "orange demon",
- M_EVIL,
- MR_NO_FLAGS,
- 0, 12, MONS_ORANGE_DEMON, MONS_ORANGE_DEMON, MH_DEMONIC, -6,
- { 10, 5, 0, 0 },
- { 8, 4, 5, 0 },
- 3, 7, 7, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SCREECH, I_NORMAL,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_HELLWING, '3', LIGHTGREY, "hellwing",
- M_SPELLCASTER | M_FLIES | M_EVIL,
- MR_RES_POISON,
- 0, 12, MONS_HELLWING, MONS_HELLWING, MH_DEMONIC, -6,
- { 17, 10, 0, 0 },
- { 7, 4, 5, 0 },
- 8, 10, 10, 7, MST_HELLWING, CE_CONTAMINATED, Z_NOZOMBIE, S_MOAN, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_SMOKE_DEMON, '4', LIGHTGREY, "smoke demon",
- M_SPELLCASTER | M_FLIES | M_EVIL,
- MR_RES_POISON | MR_RES_FIRE,
- 0, 12, MONS_SMOKE_DEMON, MONS_SMOKE_DEMON, MH_DEMONIC, -6,
- { 8, 5, 5, 0 },
- { 7, 3, 5, 0 },
- 5, 9, 9, 7, MST_SMOKE_DEMON, CE_CONTAMINATED, Z_NOZOMBIE, S_ROAR, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_YNOXINUL, '3', CYAN, "ynoxinul",
- M_SPELLCASTER | M_FLIES | M_SEE_INVIS | M_EVIL,
- MR_RES_ELEC | MR_RES_POISON | MR_RES_COLD,
- 0, 12, MONS_YNOXINUL, MONS_YNOXINUL, MH_DEMONIC, -6,
- { 12, 0, 0, 0 },
- { 6, 3, 5, 0 },
- 3, 10, 10, 7, MST_YNOXINUL, CE_CONTAMINATED, Z_NOZOMBIE, S_BELLOW, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_EXECUTIONER, '1', LIGHTGREY, "Executioner",
- M_SPELLCASTER | M_SEE_INVIS | M_EVIL,
- MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD | MR_RES_POISON,
- 0, 14, MONS_EXECUTIONER, MONS_EXECUTIONER, MH_DEMONIC, -9,
- { 30, 10, 10, 0 },
- { 12, 3, 5, 0 },
- 10, 15, 20, 7, MST_HELL_KNIGHT_I, CE_CONTAMINATED, Z_NOZOMBIE, S_SCREAM, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_GREEN_DEATH, '1', GREEN, "Green Death",
- M_SPELLCASTER | M_SEE_INVIS | M_EVIL,
- MR_RES_POISON,
- 0, 14, MONS_GREEN_DEATH, MONS_GREEN_DEATH, MH_DEMONIC, -9,
- { 32, 0, 0, 0 },
- { 13, 3, 5, 0 },
- 5, 7, 12, 7, MST_GREEN_DEATH, CE_POISONOUS, Z_NOZOMBIE, S_ROAR, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_BLUE_DEATH, '1', BLUE, "Blue Death",
- M_SPELLCASTER | M_FLIES | M_SEE_INVIS | M_EVIL,
- MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD | MR_RES_ELEC,
- 0, 14, MONS_BLUE_DEATH, MONS_BLUE_DEATH, MH_DEMONIC, -9,
- { 20, 20, 0, 0 },
- { 12, 3, 5, 0 },
- 10, 10, 12, 7, MST_BLUE_DEATH, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_BALRUG, '1', RED, "Balrug",
- M_SPELLCASTER | M_FLIES | M_SEE_INVIS | M_EVIL,
- MR_RES_POISON | MR_RES_HELLFIRE | MR_VUL_COLD,
- 0, 14, MONS_BALRUG, MONS_BALRUG, MH_DEMONIC, -9,
- { 25, 0, 0, 0 },
- { 14, 3, 5, 0 },
- 5, 12, 12, 7, MST_BALRUG, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_CACODEMON, '1', YELLOW, "Cacodemon",
- M_SPELLCASTER | M_LEVITATE | M_SEE_INVIS | M_EVIL,
- MR_RES_POISON | MR_RES_ELEC,
- 0, 14, MONS_CACODEMON, MONS_CACODEMON, MH_DEMONIC, -9,
- { 22, 0, 0, 0 },
- { 13, 3, 5, 0 },
- 11, 10, 10, 7, MST_CACODEMON, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-
-{
- MONS_DEMONIC_CRAWLER, '3', DARKGREY, "demonic crawler",
- M_SEE_INVIS | M_EVIL,
- MR_RES_ELEC | MR_RES_POISON | MR_RES_COLD | MR_RES_FIRE,
- 0, 12, MONS_DEMONIC_CRAWLER, MONS_DEMONIC_CRAWLER, MH_DEMONIC, -6,
- { 13, 13, 13, 13 },
- { 9, 3, 5, 0 },
- 10, 6, 9, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SCREAM, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_SUN_DEMON, '2', YELLOW, "sun demon",
- M_SEE_INVIS | M_LEVITATE | M_EVIL,
- MR_RES_ELEC | MR_RES_POISON | MR_VUL_COLD | MR_RES_HELLFIRE,
- 0, 14, MONS_SUN_DEMON, MONS_SUN_DEMON, MH_DEMONIC, -6,
- { 30, 0, 0, 0 },
- { 10, 3, 5, 0 },
- 10, 12, 12, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_SHADOW_IMP, '5', DARKGREY, "shadow imp",
- M_SPELLCASTER | M_FLIES | M_SPEAKS | M_EVIL,
- MR_RES_COLD | MR_RES_POISON,
- 0, 11, MONS_IMP, MONS_SHADOW_IMP, MH_DEMONIC, -3,
- { 6, 0, 0, 0 },
- { 2, 3, 5, 0 },
- 3, 11, 10, 7, MST_SHADOW_IMP, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_SHADOW_DEMON, '3', DARKGREY, "shadow demon",
- M_SEE_INVIS | M_INVIS | M_EVIL,
- MR_RES_POISON | MR_RES_COLD,
- 0, 12, MONS_SHADOW_DEMON, MONS_SHADOW_DEMON, MH_DEMONIC, -7,
- { 21, 0, 0, 0 },
- { 6, 3, 5, 0 },
- 7, 12, 11, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_CROAK, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_LOROCYPROCA, '2', BLUE, "Lorocyproca",
- M_SEE_INVIS | M_INVIS | M_EVIL,
- MR_RES_POISON | MR_RES_COLD | MR_RES_FIRE | MR_RES_ELEC,
- 0, 12, MONS_LOROCYPROCA, MONS_LOROCYPROCA, MH_DEMONIC, -7,
- { 25, 25, 0, 0 },
- { 12, 3, 5, 0 },
- 10, 12, 9, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_MOAN, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_SHADOW_WRAITH, 'W', BLUE, "shadow wraith",
- M_LEVITATE | M_SEE_INVIS | M_INVIS | M_EVIL,
- MR_RES_POISON,
- 0, 15, MONS_WRAITH, MONS_SHADOW_WRAITH, MH_UNDEAD, -8,
- { 20, 0, 0, 0 },
- { 10, 3, 5, 0 },
- 7, 7, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_MOAN, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_GIANT_AMOEBA, 'J', BLUE, "giant amoeba",
- M_NO_SKELETON | M_SEE_INVIS | M_AMPHIBIOUS,
- MR_RES_POISON,
- 1000, 10, MONS_GIANT_AMOEBA, MONS_GIANT_AMOEBA, MH_NATURAL, -3,
- { 25, 0, 0, 0 },
- { 12, 3, 5, 0 },
- 0, 4, 10, 10, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_GIANT_SLUG, 'm', GREEN, "giant slug",
- M_NO_SKELETON | M_AMPHIBIOUS,
- MR_NO_FLAGS,
- 700, 10, MONS_GIANT_SLUG, MONS_GIANT_SLUG, MH_NATURAL, -3,
- { 23, 0, 0, 0 },
- { 10, 5, 3, 0 },
- 0, 2, 6, 10, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_SILENT, I_INSECT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_GIANT_SNAIL, 'm', LIGHTGREEN, "giant snail",
- M_NO_SKELETON | M_AMPHIBIOUS,
- MR_NO_FLAGS,
- 900, 10, MONS_GIANT_SLUG, MONS_GIANT_SNAIL, MH_NATURAL, -3,
- { 18, 0, 0, 0 },
- { 14, 5, 3, 0 },
- 7, 2, 4, 10, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_SILENT, I_INSECT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_SPATIAL_VORTEX, 'v', BLACK, "spatial vortex",
- M_LEVITATE | M_CONFUSED,
- MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC,
- 0, 5, MONS_FIRE_VORTEX, MONS_SPATIAL_VORTEX, MH_NONLIVING, 5000,
- { 50, 0, 0, 0 },
- { 6, 6, 6, 0 },
- 0, 5, 15, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_PIT_FIEND, '1', BROWN, "Pit Fiend",
- M_FLIES | M_SEE_INVIS | M_EVIL | M_SPECIAL_ABILITY,
- MR_RES_POISON | MR_RES_HELLFIRE | MR_RES_COLD | MR_RES_ELEC,
- 0, 18, MONS_FIEND, MONS_PIT_FIEND, MH_DEMONIC, -12,
- { 28, 21, 21, 0 },
- { 19, 4, 5, 0 },
- 17, 5, 8, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_ROAR, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_BORING_BEETLE, 'B', BROWN, "boring beetle",
- M_NO_FLAGS,
- MR_VUL_POISON,
- 1300, 10, MONS_GIANT_BEETLE, MONS_BORING_BEETLE, MH_NATURAL, -3,
- { 26, 0, 0, 0 },
- { 8, 3, 5, 0 },
- 13, 4, 6, 7, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_SILENT, I_INSECT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_GARGOYLE, 'g', DARKGREY, "gargoyle",
- M_FLIES,
- MR_RES_POISON | MR_RES_ELEC,
- 0, 12, MONS_GARGOYLE, MONS_GARGOYLE, MH_NONLIVING, -6,
- { 10, 6, 6, 0 },
- { 4, 3, 5, 0 },
- 18, 6, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-// only appear in Dis castle
-{
- MONS_METAL_GARGOYLE, 'g', CYAN, "metal gargoyle",
- M_FLIES,
- MR_RES_POISON | MR_RES_ELEC,
- 0, 12, MONS_GARGOYLE, MONS_METAL_GARGOYLE, MH_NONLIVING, -6,
- { 19, 10, 10, 0 },
- { 8, 3, 5, 0 },
- 20, 4, 7, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-// only appear in Gehenna castle & one minivault
-{
- MONS_MOLTEN_GARGOYLE, 'g', RED, "molten gargoyle",
- M_FLIES,
- MR_RES_POISON | MR_RES_ELEC | MR_RES_FIRE,
- 0, 12, MONS_GARGOYLE, MONS_MOLTEN_GARGOYLE, MH_NONLIVING, -6,
- { 12, 8, 8, 0 },
- { 5, 3, 5, 0 },
- 14, 7, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-
-// 250 can't exist
-
-
-{
- MONS_MNOLEG, '&', LIGHTGREEN, "Mnoleg",
- M_SEE_INVIS | M_SPELLCASTER | M_SPEAKS | M_EVIL,
- MR_RES_ELEC | MR_RES_POISON | MR_RES_FIRE,
- 0, 25, MONS_MNOLEG, MONS_MNOLEG, MH_DEMONIC, 5000,
- { 23, 23, 0, 0 },
- { 17, 0, 0, 199 },
- 10, 13, 13, 7, MST_MNOLEG, CE_CONTAMINATED, Z_NOZOMBIE, S_BUZZ, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_LOM_LOBON, '&', LIGHTBLUE, "Lom Lobon",
- M_LEVITATE | M_SEE_INVIS | M_SPELLCASTER | M_SPEAKS | M_EVIL,
- MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC,
- 0, 25, MONS_LOM_LOBON, MONS_LOM_LOBON, MH_DEMONIC, 5000,
- { 40, 0, 0, 0 },
- { 19, 0, 0, 223 },
- 10, 7, 8, 7, MST_LOM_LOBON, CE_CONTAMINATED, Z_NOZOMBIE, S_SCREAM, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_CEREBOV, '&', RED, "Cerebov",
- M_SPELLCASTER | M_SEE_INVIS | M_SPEAKS | M_EVIL,
- MR_RES_ELEC | MR_RES_POISON | MR_RES_HELLFIRE,
- 0, 25, MONS_CEREBOV, MONS_CEREBOV, MH_DEMONIC, -6,
- { 50, 0, 0, 0 },
- { 21, 0, 0, 253 },
- 15, 8, 10, 7, MST_CEREBOV, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_GLOORX_VLOQ, '&', DARKGREY, "Gloorx Vloq",
- M_LEVITATE | M_SEE_INVIS | M_SPELLCASTER | M_SPEAKS | M_EVIL,
- MR_RES_POISON | MR_RES_COLD | MR_RES_ELEC,
- 0, 25, MONS_GLOORX_VLOQ, MONS_GLOORX_VLOQ, MH_DEMONIC, -14,
- { 20, 0, 0, 0 },
- { 16, 0, 0, 234 },
- 10, 10, 10, 7, MST_GLOORX_VLOQ, CE_CONTAMINATED, Z_NOZOMBIE, S_MOAN, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-/* ******************************************************************
-{MONS_MOLLUSC_LORD, 'U', GREEN, "The Mollusc Lord", M_NO_FLAGS,
- MR_RES_POISON,
- 0, 25, 255, MH_DEMONIC, -3, {30,0,0,0},
- {16,0,0,100}, 10, 10, 10, 7, 93, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_HIGH, 1},
-****************************************************************** */
-
-{
- MONS_NAGA_MAGE, 'N', LIGHTRED, "naga mage",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_WARM_BLOOD,
- MR_RES_POISON,
- 750, 13, MONS_NAGA, MONS_NAGA, MH_NATURAL, -6,
- { 10, 0, 0, 0 },
- { 7, 3, 5, 0 },
- 6, 10, 8, 7, MST_NAGA_MAGE, CE_POISONOUS, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_NAGA_WARRIOR, 'N', BLUE, "naga warrior",
- M_SPELLCASTER | M_SEE_INVIS | M_WARM_BLOOD,
- MR_RES_POISON,
- 750, 12, MONS_NAGA, MONS_NAGA, MH_NATURAL, -6,
- { 20, 0, 0, 0 },
- { 10, 5, 5, 0 },
- 6, 10, 8, 7, MST_NAGA, CE_POISONOUS, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_ORC_WARLORD, 'o', RED, "orc warlord",
- M_WARM_BLOOD | M_EVIL,
- MR_NO_FLAGS,
- 600, 15, MONS_ORC, MONS_ORC, MH_NATURAL, -3,
- { 32, 0, 0, 0 },
- { 15, 4, 7, 0 },
- 3, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_DEEP_ELF_SOLDIER, 'e', CYAN, "deep elf soldier",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD,
- MR_NO_FLAGS,
- 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6,
- { 6, 0, 0, 0 },
- { 3, 3, 3, 0 },
- 0, 12, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_DEEP_ELF_FIGHTER, 'e', LIGHTBLUE, "deep elf fighter",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD,
- MR_NO_FLAGS,
- 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6,
- { 9, 0, 0, 0 },
- { 6, 3, 3, 0 },
- 0, 13, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_DEEP_ELF_KNIGHT, 'e', BLUE, "deep elf knight",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD,
- MR_NO_FLAGS,
- 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6,
- { 14, 0, 0, 0 },
- { 11, 3, 3, 0 },
- 0, 15, 11, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_DEEP_ELF_MAGE, 'e', LIGHTRED, "deep elf mage",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD,
- MR_RES_ELEC,
- 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6,
- { 5, 0, 0, 0 },
- { 4, 3, 3, 0 },
- 0, 13, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_DEEP_ELF_SUMMONER, 'e', YELLOW, "deep elf summoner",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD,
- MR_NO_FLAGS,
- 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6,
- { 5, 0, 0, 0 },
- { 6, 3, 3, 0 },
- 0, 13, 10, 7, MST_DEEP_ELF_SUMMONER, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_DEEP_ELF_CONJURER, 'e', LIGHTGREEN, "deep elf conjurer",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD,
- MR_RES_ELEC,
- 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6,
- { 5, 0, 0, 0 },
- { 6, 3, 3, 0 },
- 0, 13, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_DEEP_ELF_PRIEST, 'e', LIGHTGREY, "deep elf priest",
- M_SPELLCASTER | M_PRIEST | M_WARM_BLOOD,
- MR_NO_FLAGS,
- 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6,
- { 9, 0, 0, 0 },
- { 5, 3, 3, 0 },
- 0, 13, 10, 7, MST_DEEP_ELF_PRIEST, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_DEEP_ELF_HIGH_PRIEST, 'e', DARKGREY, "deep elf high priest",
- M_SPELLCASTER | M_SPEAKS | M_PRIEST | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL,
- MR_NO_FLAGS,
- 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6,
- { 14, 0, 0, 0 },
- { 11, 3, 3, 0 },
- 3, 13, 10, 7, MST_DEEP_ELF_HIGH_PRIEST, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_DEEP_ELF_DEMONOLOGIST, 'e', MAGENTA, "deep elf demonologist",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL,
- MR_NO_FLAGS,
- 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6,
- { 12, 0, 0, 0 },
- { 12, 3, 3, 0 },
- 0, 13, 10, 7, MST_DEEP_ELF_DEMONOLOGIST, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_DEEP_ELF_ANNIHILATOR, 'e', GREEN, "deep elf annihilator",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_SEE_INVIS,
- MR_RES_ELEC,
- 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6,
- { 12, 0, 0, 0 },
- { 15, 3, 3, 0 },
- 0, 13, 10, 7, MST_DEEP_ELF_ANNIHILATOR, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_DEEP_ELF_SORCERER, 'e', RED, "deep elf sorcerer",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_SEE_INVIS | M_SPEAKS,
- MR_NO_FLAGS,
- 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6,
- { 12, 0, 0, 0 },
- { 14, 3, 3, 0 },
- 0, 13, 10, 7, MST_DEEP_ELF_SORCERER, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_DEEP_ELF_DEATH_MAGE, 'e', WHITE, "deep elf death mage",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL,
- MR_NO_FLAGS,
- 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6,
- { 12, 0, 0, 0 },
- { 15, 3, 3, 0 },
- 0, 13, 10, 7, MST_DEEP_ELF_DEATH_MAGE, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_BROWN_OOZE, 'J', BROWN, "brown ooze",
- M_NO_SKELETON | M_SEE_INVIS,
- MR_RES_POISON,
- 0, 11, MONS_JELLY, MONS_BROWN_OOZE, MH_NATURAL, -7,
- { 25, 0, 0, 0 },
- { 7, 3, 5, 0 },
- 10, 1, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_EATS_ITEMS
-}
-,
-
-{
- MONS_AZURE_JELLY, 'J', LIGHTBLUE, "azure jelly",
- M_NO_SKELETON | M_SEE_INVIS,
- MR_RES_POISON | MR_RES_COLD | MR_VUL_FIRE | MR_RES_ELEC,
- 0, 11, MONS_JELLY, MONS_AZURE_JELLY, MH_NATURAL, -4,
- { 12, 12, 12, 12 },
- { 15, 3, 5, 0 },
- 5, 10, 12, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_EATS_ITEMS
-}
-,
-
-{
- MONS_DEATH_OOZE, 'J', DARKGREY, "death ooze",
- M_NO_SKELETON | M_SEE_INVIS | M_EVIL,
- MR_RES_POISON | MR_RES_COLD,
- 0, 13, MONS_JELLY, MONS_DEATH_OOZE, MH_UNDEAD, -8,
- { 32, 32, 0, 0 },
- { 11, 3, 3, 0 },
- 2, 4, 12, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_EATS_ITEMS
-}
-,
-
-{
- MONS_ACID_BLOB, 'J', LIGHTGREEN, "acid blob",
- M_NO_SKELETON | M_SEE_INVIS | M_SPECIAL_ABILITY,
- MR_RES_POISON,
- 0, 12, MONS_JELLY, MONS_ACID_BLOB, MH_NATURAL, -7,
- { 42, 0, 0, 0 },
- { 18, 3, 5, 0 },
- 1, 3, 14, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_EATS_ITEMS
-}
-,
-
-{
- MONS_ROYAL_JELLY, 'J', YELLOW, "royal jelly",
- M_NO_SKELETON | M_SEE_INVIS,
- MR_RES_POISON,
- 0, 20, MONS_JELLY, MONS_ROYAL_JELLY, MH_NATURAL, -7,
- { 50, 0, 0, 0 },
- { 21, 0, 0, 111 },
- 8, 4, 12, 7, MST_NO_SPELLS, CE_CLEAN, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_EATS_ITEMS
-}
-,
-
-{
- MONS_TERENCE, '@', LIGHTCYAN, "Terence",
- M_WARM_BLOOD | M_SPEAKS,
- MR_NO_FLAGS,
- 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -3,
- { 3, 0, 0, 0 },
- { 1, 0, 0, 14 },
- 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_JESSICA, '@', LIGHTGREY, "Jessica",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD,
- MR_NO_FLAGS,
- 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -3,
- { 4, 0, 0, 0 },
- { 1, 0, 0, 10 },
- 0, 10, 10, 7, MST_ORC_WIZARD_I, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_IJYB, 'g', BLUE, "Ijyb",
- M_WARM_BLOOD | M_SPEAKS,
- MR_NO_FLAGS,
- 0, 5, MONS_GOBLIN, MONS_GOBLIN, MH_NATURAL, -3,
- { 4, 0, 0, 0 },
- { 3, 0, 0, 28 },
- 2, 12, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_SIGMUND, '@', YELLOW, "Sigmund",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD,
- MR_NO_FLAGS,
- 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -3,
- { 5, 0, 0, 0 },
- { 3, 0, 0, 25 },
- 0, 11, 10, 7, MST_ORC_WIZARD_II, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_BLORK_THE_ORC, 'o', BROWN, "Blork the orc",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD,
- MR_NO_FLAGS,
- 0, 20, MONS_ORC, MONS_ORC, MH_NATURAL, -4,
- { 7, 0, 0, 0 },
- { 3, 0, 0, 32 },
- 0, 9, 8, 7, MST_ORC_WIZARD_III, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_EDMUND, '@', RED, "Edmund",
- M_WARM_BLOOD | M_SPEAKS,
- MR_NO_FLAGS,
- 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -4,
- { 6, 0, 0, 0 },
- { 4, 0, 0, 27 },
- 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_PSYCHE, '@', LIGHTMAGENTA, "Psyche",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD,
- MR_NO_FLAGS,
- 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -4,
- { 7, 0, 0, 0 },
- { 5, 0, 0, 24 },
- 0, 12, 13, 7, MST_ORC_WIZARD_III, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_EROLCHA, 'O', LIGHTBLUE, "Erolcha",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_WARM_BLOOD | M_SPEAKS | M_EVIL,
- MR_RES_ELEC,
- 0, 20, MONS_OGRE, MONS_OGRE, MH_NATURAL, -7,
- { 20, 0, 0, 0 },
- { 6, 0, 0, 45 },
- 3, 7, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_DONALD, '@', BLUE, "Donald",
- M_WARM_BLOOD | M_SPEAKS,
- MR_NO_FLAGS,
- 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5,
- { 8, 0, 0, 0 },
- { 5, 0, 0, 33 },
- 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_URUG, 'o', RED, "Urug",
- M_WARM_BLOOD | M_SPEAKS,
- MR_NO_FLAGS,
- 0, 20, MONS_ORC, MONS_ORC, MH_NATURAL, -5,
- { 12, 0, 0, 0 },
- { 6, 0, 0, 38 },
- 0, 11, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_MICHAEL, '@', LIGHTGREY, "Michael",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD,
- MR_NO_FLAGS,
- 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5,
- { 9, 0, 0, 0 },
- { 6, 0, 0, 36 },
- 0, 10, 10, 7, MST_ORC_WIZARD_III, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_JOSEPH, '@', CYAN, "Joseph",
- M_WARM_BLOOD | M_SPEAKS,
- MR_NO_FLAGS,
- 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5,
- { 9, 0, 0, 0 },
- { 7, 0, 0, 42 },
- 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_SNORG, 'T', GREEN, "Snorg",
- M_WARM_BLOOD | M_SPEAKS | M_EVIL,
- MR_NO_FLAGS,
- 0, 20, MONS_TROLL, MONS_TROLL, MH_NATURAL, -6,
- { 20, 15, 15, 0 },
- { 8, 0, 0, 45 },
- 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_ERICA, '@', MAGENTA, "Erica",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD,
- MR_NO_FLAGS,
- 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5,
- { 10, 0, 0, 0 },
- { 9, 0, 0, 43 },
- 0, 11, 11, 7, MST_WIZARD_II, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_JOSEPHINE, '@', WHITE, "Josephine",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD,
- MR_NO_FLAGS,
- 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5,
- { 11, 0, 0, 0 },
- { 9, 0, 0, 47 },
- 0, 10, 10, 7, MST_NECROMANCER_I, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_HAROLD, '@', LIGHTGREEN, "Harold",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD,
- MR_NO_FLAGS,
- 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5,
- { 12, 0, 0, 0 },
- { 9, 0, 0, 51 },
- 0, 8, 10, 7, MST_HELL_KNIGHT_II, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_NORBERT, '@', BROWN, "Norbert",
- M_WARM_BLOOD | M_SPEAKS,
- MR_NO_FLAGS,
- 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5,
- { 14, 0, 0, 0 },
- { 10, 0, 0, 53 },
- 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_JOZEF, '@', LIGHTMAGENTA, "Jozef",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD,
- MR_NO_FLAGS,
- 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5,
- { 14, 0, 0, 0 },
- { 11, 0, 0, 60 },
- 0, 9, 10, 7, MST_GUARDIAN_NAGA, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_AGNES, '@', LIGHTBLUE, "Agnes",
- M_WARM_BLOOD | M_SPEAKS,
- MR_NO_FLAGS,
- 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5,
- { 11, 0, 0, 0 },
- { 11, 0, 0, 64 },
- 0, 10, 15, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_MAUD, '@', RED, "Maud",
- M_WARM_BLOOD | M_SPEAKS,
- MR_NO_FLAGS,
- 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5,
- { 14, 0, 0, 0 },
- { 13, 0, 0, 55 },
- 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_LOUISE, '@', BLUE, "Louise",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD,
- MR_RES_ELEC,
- 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5,
- { 12, 0, 0, 0 },
- { 13, 0, 0, 52 },
- 0, 10, 10, 7, MST_WIZARD_IV, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_FRANCIS, '@', YELLOW, "Francis",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL,
- MR_NO_FLAGS,
- 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5,
- { 12, 0, 0, 0 },
- { 14, 0, 0, 67 },
- 0, 10, 10, 7, MST_ORC_HIGH_PRIEST, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_FRANCES, '@', YELLOW, "Frances",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL,
- MR_NO_FLAGS,
- 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5,
- { 11, 0, 0, 0 },
- { 14, 0, 0, 70 },
- 0, 10, 10, 7, MST_ORC_HIGH_PRIEST, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_RUPERT, '@', RED, "Rupert",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_SEE_INVIS,
- MR_RES_ELEC,
- 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5,
- { 13, 0, 0, 0 },
- { 16, 0, 0, 80 },
- 0, 10, 10, 7, MST_WIZARD_IV, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_WAYNE, '@', YELLOW, "Wayne",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_SEE_INVIS,
- MR_NO_FLAGS,
- 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5,
- { 14, 0, 0, 0 },
- { 17, 0, 0, 78 },
- 1, 10, 7, 7, MST_ORC_PRIEST, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_DUANE, '@', YELLOW, "Duane",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_SEE_INVIS,
- MR_NO_FLAGS,
- 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5,
- { 14, 0, 0, 0 },
- { 18, 0, 0, 83 },
- 0, 10, 10, 7, MST_ORC_WIZARD_I, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_XTAHUA, 'D', RED, "Xtahua",
- M_SPEAKS | M_SEE_INVIS | M_FLIES | M_SPECIAL_ABILITY,
- MR_RES_POISON | MR_RES_FIRE | MR_VUL_COLD,
- 0, 20, MONS_DRAGON, MONS_DRAGON, MH_NATURAL, -7,
- { 29, 17, 17, 0 },
- { 19, 0, 0, 133 },
- 15, 7, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_NORRIS, '@', LIGHTRED, "Norris",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL,
- MR_NO_FLAGS,
- 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5,
- { 16, 0, 0, 0 },
- { 20, 0, 0, 95 },
- 1, 9, 9, 7, MST_MYSTIC, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_ADOLF, '@', DARKGREY, "Adolf",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL,
- MR_NO_FLAGS,
- 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5,
- { 17, 0, 0, 0 },
- { 21, 0, 0, 105 },
- 0, 10, 10, 7, MST_LICH_IV, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_MARGERY, '@', RED, "Margery",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_SEE_INVIS,
- MR_NO_FLAGS,
- 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5,
- { 18, 0, 0, 0 },
- { 22, 0, 0, 119 },
- 0, 10, 10, 7, MST_EFREET, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_BORIS, 'L', RED, "Boris",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_SPEAKS | M_EVIL,
- MR_RES_POISON | MR_RES_COLD | MR_RES_ELEC,
- 0, 23, MONS_LICH, MONS_LICH, MH_UNDEAD, -11,
- { 15, 0, 0, 0 },
- { 22, 0, 0, 99 },
- 12, 10, 10, 7, MST_LICH_IV, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH,
- MONUSE_STARTING_EQUIPMENT
-}
-,
-
-
-{
- MONS_GERYON, '&', GREEN, "Geryon",
- M_SPELLCASTER | M_SEE_INVIS | M_SPEAKS | M_EVIL,
- MR_NO_FLAGS,
- 0, 25, MONS_GERYON, MONS_GERYON, MH_DEMONIC, -6,
- { 30, 0, 0, 0 },
- { 15, 0, 0, 240 },
- 15, 6, 10, 7, MST_GERYON, CE_CONTAMINATED, Z_NOZOMBIE, S_ROAR, I_NORMAL,
- MONUSE_STARTING_EQUIPMENT
-}
-,
-
-{
- MONS_DISPATER, '&', MAGENTA, "Dispater",
- M_SPELLCASTER | M_SEE_INVIS | M_SPEAKS | M_EVIL,
- MR_RES_ELEC | MR_RES_POISON | MR_RES_HELLFIRE | MR_RES_COLD,
- 0, 25, MONS_DISPATER, MONS_DISPATER, MH_DEMONIC, -10,
- { 15, 0, 0, 0 },
- { 16, 0, 0, 222 },
- 15, 3, 6, 7, MST_DISPATER, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_ASMODEUS, '&', LIGHTMAGENTA, "Asmodeus",
- M_SPELLCASTER | M_FLIES | M_SEE_INVIS | M_SPEAKS | M_EVIL,
- MR_RES_ELEC | MR_RES_POISON | MR_RES_HELLFIRE,
- 0, 25, MONS_ASMODEUS, MONS_ASMODEUS, MH_DEMONIC, -12,
- { 20, 0, 0, 0 },
- { 17, 0, 0, 245 },
- 12, 7, 9, 7, MST_ASMODEUS, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-// Antaeus is now demonic so that he'll resist torment. -- bwr
-{
- MONS_ANTAEUS, 'C', LIGHTCYAN, "Antaeus",
- M_SPELLCASTER | M_SPEAKS,
- MR_RES_ELEC | MR_VUL_FIRE | MR_RES_COLD,
- 0, 25, MONS_HILL_GIANT, MONS_ANTAEUS, MH_DEMONIC, -9,
- { 30, 0, 0, 0 },
- { 22, 0, 0, 250 },
- 10, 4, 7, 7, MST_ANTAEUS, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_ERESHKIGAL, '&', WHITE, "Ereshkigal",
- M_SPELLCASTER | M_SEE_INVIS | M_SPEAKS | M_EVIL,
- MR_RES_ELEC | MR_RES_POISON | MR_RES_COLD,
- 0, 25, MONS_ERESHKIGAL, MONS_ERESHKIGAL, MH_DEMONIC, -10,
- { 20, 0, 0, 0 },
- { 18, 0, 0, 238 },
- 15, 6, 9, 7, MST_ERESHKIGAL, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_ANCIENT_LICH, 'L', DARKGREY, "ancient lich",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_EVIL,
- MR_RES_POISON | MR_RES_COLD | MR_RES_FIRE | MR_RES_ELEC,
- 0, 20, MONS_LICH, MONS_LICH, MH_UNDEAD, -14,
- { 20, 0, 0, 0 },
- { 27, 2, 4, 0 },
- 20, 10, 12, 7, MST_LICH_I, CE_NOCORPSE, Z_NOZOMBIE, S_SHOUT, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-/* number is set in define_monster */
-
-{
- MONS_OOZE, 'J', LIGHTGREY, "ooze",
- M_NO_SKELETON | M_SEE_INVIS,
- MR_RES_POISON,
- 0, 5, MONS_JELLY, MONS_OOZE, MH_NATURAL, -6,
- { 5, 0, 0, 0 },
- { 3, 3, 5, 0 },
- 1, 3, 8, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_VAULT_GUARD, '@', CYAN, "vault guard",
- M_WARM_BLOOD | M_SEE_INVIS,
- MR_NO_FLAGS,
- 0, 12, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -3,
- { 20, 0, 0, 0 },
- { 13, 3, 5, 0 },
- 1, 13, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-/* These nasties are never randomly generated, only sometimes specially
- placed in the Crypt. */
-{
- MONS_CURSE_SKULL, 'z', DARKGREY, "curse skull",
- M_LEVITATE | M_SPELLCASTER | M_SEE_INVIS | M_EVIL,
- MR_RES_ELEC | MR_RES_POISON | MR_RES_HELLFIRE | MR_RES_COLD,
- 0, 50, MONS_LICH, MONS_CURSE_SKULL, MH_UNDEAD, 5000,
- { 0, 0, 0, 0 },
- { 13, 0, 0, 66 },
- 40, 3, 10, 7, MST_CURSE_SKULL, CE_NOCORPSE, Z_NOZOMBIE, S_MOAN, I_HIGH,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_VAMPIRE_KNIGHT, 'V', CYAN, "vampire knight",
- M_SPELLCASTER | M_SEE_INVIS | M_EVIL,
- MR_RES_POISON | MR_RES_COLD,
- 0, 13, MONS_VAMPIRE, MONS_VAMPIRE, MH_UNDEAD, -6,
- { 33, 0, 0, 0 },
- { 11, 3, 7, 0 },
- 10, 10, 10, 7, MST_VAMPIRE_KNIGHT, CE_NOCORPSE, Z_NOZOMBIE, S_SHOUT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_VAMPIRE_MAGE, 'V', MAGENTA, "vampire mage",
- M_SPELLCASTER | M_SEE_INVIS | M_FLIES | M_EVIL,
- MR_RES_POISON | MR_RES_COLD,
- 0, 15, MONS_VAMPIRE, MONS_VAMPIRE, MH_UNDEAD, -6,
- { 22, 0, 0, 0 },
- { 8, 3, 4, 0 },
- 10, 10, 10, 7, MST_VAMPIRE_MAGE, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_SHINING_EYE, 'G', LIGHTMAGENTA, "shining eye",
- M_NO_SKELETON | M_LEVITATE | M_SPELLCASTER | M_SEE_INVIS,
- MR_NO_FLAGS,
- 0, 14, MONS_SHINING_EYE, MONS_SHINING_EYE, MH_NATURAL, 5000,
- { 0, 0, 0, 0 },
- { 10, 3, 5, 0 },
- 3, 1, 7, 7, MST_SHINING_EYE, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_ORB_GUARDIAN, 'X', MAGENTA, "Orb Guardian",
- M_NO_SKELETON | M_SEE_INVIS,
- MR_NO_FLAGS,
- 0, 20, MONS_ORB_GUARDIAN, MONS_ORB_GUARDIAN, MH_NATURAL, -6,
- { 45, 0, 0, 0 },
- { 15, 3, 5, 0 },
- 13, 13, 14, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_DAEVA, 'A', YELLOW, "Daeva",
- M_LEVITATE | M_SPELLCASTER,
- MR_RES_POISON,
- 0, 12, MONS_ANGEL, MONS_DAEVA, MH_HOLY, -8,
- { 25, 0, 0, 0 },
- { 12, 3, 5, 0 },
- 10, 13, 13, 7, MST_DAEVA, CE_NOCORPSE, Z_NOZOMBIE, S_SHOUT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-/* spectral thing - similar to zombies/skeletons */
-{
- MONS_SPECTRAL_THING, 'W', GREEN, "",
- M_LEVITATE | M_SEE_INVIS,
- MR_RES_POISON | MR_RES_COLD,
- 0, 11, MONS_WRAITH, MONS_SPECTRAL_THING, MH_UNDEAD, 5000,
- { 20, 0, 0, 0 },
- { 8, 3, 5, 0 },
- 8, 5, 7, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_GREATER_NAGA, 'N', RED, "greater naga",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_WARM_BLOOD,
- MR_RES_POISON,
- 750, 10, MONS_NAGA, MONS_NAGA, MH_NATURAL, 5000,
- { 24, 0, 0, 0 },
- { 15, 3, 5, 0 },
- 6, 10, 8, 7, MST_NAGA_MAGE, CE_POISONOUS, Z_SMALL, S_SHOUT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_SKELETAL_DRAGON, 'D', LIGHTGREY, "skeletal dragon",
- M_SEE_INVIS | M_EVIL,
- MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC,
- 0, 12, MONS_SKELETAL_WARRIOR, MONS_SKELETAL_DRAGON, MH_UNDEAD, -4,
- { 30, 20, 20, 0 },
- { 20, 8, 8, 0 },
- 20, 4, 8, 7, MST_NO_SPELLS, CE_CLEAN, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_TENTACLED_MONSTROSITY, 'X', GREEN, "tentacled monstrosity",
- M_SEE_INVIS | M_AMPHIBIOUS,
- MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC,
- 0, 10, MONS_TENTACLED_MONSTROSITY, MONS_TENTACLED_MONSTROSITY, MH_NATURAL, -5,
- { 22, 17, 13, 19 },
- { 25, 3, 5, 0 },
- 5, 5, 9, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_SPHINX, 'H', LIGHTGREY, "sphinx",
- M_FLIES | M_SEE_INVIS | M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD,
- MR_NO_FLAGS,
- 0, 10, MONS_SPHINX, MONS_SPHINX, MH_NATURAL, -3,
- { 25, 12, 12, 0 },
- { 16, 3, 5, 0 },
- 5, 5, 13, 7, MST_SPHINX, CE_CLEAN, Z_NOZOMBIE, S_SHOUT, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_ROTTING_HULK, 'n', BROWN, "rotting hulk",
- M_EVIL,
- MR_RES_POISON | MR_RES_COLD,
- 0, 12, MONS_GHOUL, MONS_ROTTING_HULK, MH_UNDEAD, -5,
- { 25, 0, 0, 0 },
- { 10, 3, 5, 0 },
- 5, 7, 8, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_GUARDIAN_MUMMY, 'M', YELLOW, "guardian mummy",
- M_SEE_INVIS | M_EVIL,
- MR_RES_POISON | MR_RES_COLD,
- 0, 13, MONS_MUMMY, MONS_GUARDIAN_MUMMY, MH_UNDEAD, -5,
- { 30, 0, 0, 0 },
- { 7, 5, 3, 0 },
- 6, 9, 9, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_GREATER_MUMMY, 'M', DARKGREY, "greater mummy",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_EVIL,
- MR_RES_POISON | MR_RES_COLD | MR_RES_ELEC,
- 0, 20, MONS_MUMMY, MONS_MUMMY, MH_UNDEAD, 5000,
- { 35, 0, 0, 0 },
- { 15, 5, 3, 100 },
- 10, 6, 10, 7, MST_MUMMY, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_MUMMY_PRIEST, 'M', RED, "mummy priest",
- M_SPELLCASTER | M_PRIEST | M_SEE_INVIS | M_EVIL,
- MR_RES_POISON | MR_RES_COLD | MR_RES_ELEC,
- 0, 16, MONS_MUMMY, MONS_MUMMY, MH_UNDEAD, 5000,
- { 30, 0, 0, 0 },
- { 10, 5, 3, 0 },
- 8, 7, 9, 7, MST_MUMMY, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_CENTAUR_WARRIOR, 'c', YELLOW, "centaur warrior",
- M_WARM_BLOOD,
- MR_NO_FLAGS,
- 1500, 12, MONS_CENTAUR, MONS_CENTAUR, MH_NATURAL, -3,
- { 16, 0, 0, 0 },
- { 9, 3, 5, 0 },
- 4, 8, 15, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SHOUT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_YAKTAUR_CAPTAIN, 'c', RED, "yaktaur captain",
- M_WARM_BLOOD,
- MR_NO_FLAGS,
- 2000, 10, MONS_YAKTAUR, MONS_YAKTAUR, MH_NATURAL, -3,
- { 23, 0, 0, 0 },
- { 14, 3, 5, 0 },
- 5, 5, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SHOUT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{ // Base draconian -- for use like MONS_HUMAN, MONS_ELF although we
- // now store the draconian subspecies in the high byte of mon->number
- // for those listed as species MONS_DRACONIAN.
- MONS_DRACONIAN, 'd', BROWN, "draconian",
- M_HUMANOID | M_FLIES | M_COLD_BLOOD,
- MR_NO_FLAGS,
- 900, 10, MONS_DRACONIAN, MONS_DRACONIAN, MH_NATURAL, 3,
- { 15, 0, 0, 0 },
- { 3, 6, 4, 0 },
- 7, 8, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH,
- MONUSE_STARTING_EQUIPMENT
-}
-,
-
-{
- MONS_BLACK_DRACONIAN, 'd', DARKGREY, "black draconian",
- M_HUMANOID | M_FLIES | M_COLD_BLOOD,
- MR_RES_ELEC,
- 900, 10, MONS_DRACONIAN, MONS_BLACK_DRACONIAN, MH_NATURAL, 3,
- { 20, 0, 0, 0 },
- { 14, 6, 4, 0 },
- 9, 10, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH,
- MONUSE_STARTING_EQUIPMENT
-}
-,
-
-{
- MONS_YELLOW_DRACONIAN, 'd', YELLOW, "yellow draconian",
- M_FLIES | M_HUMANOID | M_COLD_BLOOD | M_SPECIAL_ABILITY,
- MR_NO_FLAGS,
- 900, 10, MONS_DRACONIAN, MONS_YELLOW_DRACONIAN, MH_NATURAL, 3,
- { 20, 0, 0, 0 },
- { 14, 6, 4, 0 },
- 9, 10, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH,
- MONUSE_STARTING_EQUIPMENT
-}
-,
-
-{
- MONS_PALE_DRACONIAN, 'd', LIGHTGREY, "pale draconian",
- M_HUMANOID | M_FLIES | M_COLD_BLOOD,
- MR_RES_FIRE,
- 900, 10, MONS_DRACONIAN, MONS_PALE_DRACONIAN, MH_NATURAL, 3,
- { 20, 0, 0, 0 },
- { 14, 6, 4, 0 },
- 9, 14, 12, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH,
- MONUSE_STARTING_EQUIPMENT
-}
-,
-
-{
- MONS_GREEN_DRACONIAN, 'd', LIGHTGREEN, "green draconian",
- M_HUMANOID | M_FLIES | M_COLD_BLOOD,
- MR_RES_POISON,
- 900, 10, MONS_DRACONIAN, MONS_GREEN_DRACONIAN, MH_NATURAL, 3,
- { 20, 0, 0, 0 },
- { 14, 6, 4, 0 },
- 9, 10, 10, 10, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_ROAR, I_HIGH,
- MONUSE_STARTING_EQUIPMENT
-}
-,
-
-{
- MONS_PURPLE_DRACONIAN, 'd', MAGENTA, "purple draconian",
- M_HUMANOID | M_FLIES | M_COLD_BLOOD,
- MR_NO_FLAGS,
- 900, 10, MONS_DRACONIAN, MONS_PURPLE_DRACONIAN, MH_NATURAL, 6,
- { 20, 0, 0, 0 },
- { 14, 6, 4, 0 },
- 8, 10, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH,
- MONUSE_STARTING_EQUIPMENT
-}
-,
-
-{
- MONS_RED_DRACONIAN, 'd', RED, "red draconian",
- M_HUMANOID | M_FLIES | M_COLD_BLOOD | M_SPECIAL_ABILITY,
- MR_RES_FIRE,
- 900, 10, MONS_DRACONIAN, MONS_RED_DRACONIAN, MH_NATURAL, 3,
- { 20, 0, 0, 0 },
- { 14, 6, 4, 0 },
- 9, 10, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH,
- MONUSE_STARTING_EQUIPMENT
-}
-,
-
-{
- MONS_WHITE_DRACONIAN, 'd', WHITE, "white draconian",
- M_HUMANOID | M_FLIES | M_COLD_BLOOD | M_SPECIAL_ABILITY,
- MR_RES_COLD,
- 900, 10, MONS_DRACONIAN, MONS_WHITE_DRACONIAN, MH_NATURAL, 3,
- { 20, 0, 0, 0 },
- { 14, 6, 4, 0 },
- 9, 10, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH,
- MONUSE_STARTING_EQUIPMENT
-}
-,
-
-{
- MONS_MOTTLED_DRACONIAN, 'd', LIGHTMAGENTA, "mottled draconian",
- M_HUMANOID | M_FLIES | M_COLD_BLOOD,
- MR_RES_FIRE,
- 900, 10, MONS_DRACONIAN, MONS_MOTTLED_DRACONIAN, MH_NATURAL, 3,
- { 20, 0, 0, 0 },
- { 14, 6, 4, 0 },
- 9, 10, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH,
- MONUSE_STARTING_EQUIPMENT
-}
-,
-
-{
- MONS_DRACONIAN_CALLER, 'd', BROWN, "draconian caller",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_HUMANOID | M_FLIES | M_COLD_BLOOD,
- MR_NO_FLAGS,
- 900, 10, MONS_DRACONIAN, MONS_DRACONIAN, MH_NATURAL, 3,
- { 20, 0, 0, 0 },
- { 16, 5, 5, 0 },
- 9, 10, 10, 10, MST_DRAC_CALLER, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH,
- MONUSE_STARTING_EQUIPMENT
-}
-,
-
-{
- MONS_DRACONIAN_MONK, 'd', BLUE, "draconian monk",
- M_FIGHTER | M_HUMANOID | M_FLIES | M_COLD_BLOOD,
- MR_NO_FLAGS,
- 900, 10, MONS_DRACONIAN, MONS_DRACONIAN, MH_NATURAL, 3,
- { 15, 15, 15, 0 },
- { 16, 6, 4, 0 },
- 6, 20, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH,
- MONUSE_STARTING_EQUIPMENT
-}
-,
-
-{
- MONS_DRACONIAN_ZEALOT, 'd', LIGHTBLUE, "draconian zealot",
- M_SPELLCASTER | M_HUMANOID | M_PRIEST | M_FLIES | M_COLD_BLOOD,
- MR_NO_FLAGS,
- 900, 10, MONS_DRACONIAN, MONS_DRACONIAN, MH_NATURAL, 3,
- { 15, 0, 0, 0 },
- { 16, 6, 4, 0 },
- 12, 10, 10, 10, MST_DEEP_ELF_HIGH_PRIEST, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH,
- MONUSE_STARTING_EQUIPMENT
-}
-,
-
-{
- MONS_DRACONIAN_SHIFTER, 'd', LIGHTCYAN, "draconian shifter",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_HUMANOID | M_FLIES | M_COLD_BLOOD,
- MR_NO_FLAGS,
- 900, 10, MONS_DRACONIAN, MONS_DRACONIAN, MH_NATURAL, 4,
- { 15, 0, 0, 0 },
- { 16, 5, 5, 0 },
- 8, 16, 10, 10, MST_DRAC_SHIFTER, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH,
- MONUSE_STARTING_EQUIPMENT
-}
-,
-
-{
- MONS_DRACONIAN_ANNIHILATOR, 'd', GREEN, "draconian annihilator",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_HUMANOID | M_FLIES | M_COLD_BLOOD,
- MR_NO_FLAGS,
- 900, 10, MONS_DRACONIAN, MONS_DRACONIAN, MH_NATURAL, 4,
- { 15, 0, 0, 0 },
- { 16, 5, 5, 0 },
- 8, 10, 10, 10, MST_DEEP_ELF_ANNIHILATOR, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH,
- MONUSE_STARTING_EQUIPMENT
-}
-,
-
-{
- MONS_DRACONIAN_KNIGHT, 'd', CYAN, "draconian knight",
- M_SPELLCASTER | M_HUMANOID | M_PRIEST | M_FIGHTER | M_FLIES | M_COLD_BLOOD,
- MR_NO_FLAGS,
- 900, 10, MONS_DRACONIAN, MONS_DRACONIAN, MH_NATURAL, 4,
- { 15, 0, 0, 0 },
- { 16, 6, 4, 0 },
- 12, 12, 10, 6, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH,
- MONUSE_STARTING_EQUIPMENT
-}
-,
-
-{
- MONS_DRACONIAN_SCORCHER, 'd', LIGHTRED, "draconian scorcher",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_HUMANOID | M_FLIES | M_COLD_BLOOD,
- MR_RES_FIRE | MR_RES_HELLFIRE,
- 900, 10, MONS_DRACONIAN, MONS_DRACONIAN, MH_NATURAL, 4,
- { 15, 0, 0, 0 },
- { 16, 5, 5, 0 },
- 8, 12, 10, 10, MST_DRAC_SCORCHER, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH,
- MONUSE_STARTING_EQUIPMENT
-}
-,
-
-{
- MONS_KILLER_KLOWN, '@', BLACK, "Killer Klown",
- M_SEE_INVIS | M_SPEAKS | M_WARM_BLOOD | M_SPECIAL_ABILITY,
- MR_RES_FIRE | MR_RES_COLD | MR_RES_POISON,
- 0, 15, MONS_HUMAN, MONS_KILLER_KLOWN, MH_NATURAL, 5000,
- { 30, 0, 0, 0 },
- { 20, 5, 5, 0 },
- 10, 15, 15, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_ELECTRIC_GOLEM, '8', LIGHTCYAN, "electric golem",
- M_SPELLCASTER | M_SEE_INVIS,
- MR_RES_ELEC | MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD,
- 0, 10, MONS_CLAY_GOLEM, MONS_ELECTRIC_GOLEM, MH_NONLIVING, 5000,
- { 12, 12, 12, 12 },
- { 15, 7, 4, 0 },
- 5, 20, 20, 7, MST_ELECTRIC_GOLEM, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_BALL_LIGHTNING, '*', LIGHTCYAN, "ball lightning",
- M_FLIES | M_CONFUSED | M_SPELLCASTER | M_SPECIAL_ABILITY,
- MR_RES_ELEC,
- 0, 20, MONS_BALL_LIGHTNING, MONS_BALL_LIGHTNING, MH_NONLIVING, 5000,
- { 5, 0, 0, 0 },
- { 12, 0, 0, 1 },
- 0, 10, 20, 7, MST_STORM_DRAGON, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_PLANT,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_ORB_OF_FIRE, '*', RED, "orb of fire",
- M_SPELLCASTER | M_FLIES | M_SEE_INVIS,
- MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD | MR_RES_POISON,
- 0, 10, MONS_ORB_OF_FIRE, MONS_ORB_OF_FIRE, MH_NONLIVING, 5000,
- { 0, 0, 0, 0 },
- { 30, 0, 0, 150 },
- 20, 20, 20, 7, MST_ORB_OF_FIRE, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_QUOKKA, 'r', LIGHTGREY, "quokka",
- M_WARM_BLOOD,
- MR_NO_FLAGS,
- 300, 10, MONS_QUOKKA, MONS_QUOKKA, MH_NATURAL, -1,
- { 5, 0, 0, 0 },
- { 1, 3, 5, 0 },
- 2, 13, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_NORMAL,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_EYE_OF_DEVASTATION, 'G', YELLOW, "eye of devastation",
- M_NO_SKELETON | M_LEVITATE | M_SPELLCASTER | M_SEE_INVIS,
- MR_NO_FLAGS,
- 0, 11, MONS_GIANT_EYEBALL, MONS_EYE_OF_DEVASTATION, MH_NATURAL, 5000,
- { 0, 0, 0, 0 },
- { 10, 3, 5, 0 },
- 12, 1, 7, 7, MST_EYE_OF_DEVASTATION, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_MOTH_OF_WRATH, 'y', BROWN, "moth of wrath",
- M_FLIES,
- MR_NO_FLAGS,
- 0, 10, MONS_MOTH_OF_WRATH, MONS_MOTH_OF_WRATH, MH_NATURAL, -3,
- { 25, 0, 0, 0 },
- { 9, 3, 5, 0 },
- 0, 10, 12, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_DEATH_COB, '%', YELLOW, "death cob",
- M_SPEAKS | M_EVIL,
- MR_RES_POISON | MR_RES_COLD,
- 0, 10, MONS_DEATH_COB, MONS_DEATH_COB, MH_UNDEAD, -3,
- { 20, 0, 0, 0 },
- { 10, 4, 5, 0 },
- 10, 15, 25, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_MOAN, I_NORMAL,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_CURSE_TOE, 'z', DARKGREY, "curse toe",
- M_LEVITATE | M_SPELLCASTER | M_SEE_INVIS | M_EVIL,
- MR_RES_ELEC | MR_RES_POISON | MR_RES_HELLFIRE | MR_RES_COLD,
- 0, 60, MONS_LICH, MONS_CURSE_TOE, MH_UNDEAD, 5000,
- { 0, 0, 0, 0 },
- { 14, 0, 0, 77 },
- 50, 1, 12, 7, MST_CURSE_SKULL, CE_NOCORPSE, Z_NOZOMBIE, S_MOAN, I_HIGH,
- MONUSE_NOTHING
-}
-,
-
-{
- // gold mimics are the only mimics that actually use their name -- bwr
- MONS_GOLD_MIMIC, '$', YELLOW, "pile of gold coins",
- M_NO_SKELETON,
- MR_RES_POISON | MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD,
- 0, 13, MONS_GOLD_MIMIC, MONS_GOLD_MIMIC, MH_NONLIVING, -3,
- { 12, 12, 12, 0 },
- { 8, 3, 5, 0 },
- 5, 1, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_WEAPON_MIMIC, ')', BLACK, "mimic",
- M_NO_SKELETON,
- MR_RES_POISON | MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD,
- 0, 13, MONS_GOLD_MIMIC, MONS_GOLD_MIMIC, MH_NONLIVING, -3,
- { 17, 17, 17, 0 },
- { 8, 3, 5, 0 },
- 5, 1, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_ARMOUR_MIMIC, '[', BLACK, "mimic",
- M_NO_SKELETON,
- MR_RES_POISON | MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD,
- 0, 13, MONS_GOLD_MIMIC, MONS_GOLD_MIMIC, MH_NONLIVING, -3,
- { 12, 12, 12, 0 },
- { 8, 3, 5, 0 },
- 15, 1, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_SCROLL_MIMIC, '?', LIGHTGREY, "mimic",
- M_NO_SKELETON,
- MR_RES_POISON | MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD,
- 0, 13, MONS_GOLD_MIMIC, MONS_GOLD_MIMIC, MH_NONLIVING, -3,
- { 12, 12, 12, 0 },
- { 8, 3, 5, 0 },
- 5, 1, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_POTION_MIMIC, '!', BLACK, "mimic",
- M_NO_SKELETON,
- MR_RES_POISON | MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD,
- 0, 13, MONS_GOLD_MIMIC, MONS_GOLD_MIMIC, MH_NONLIVING, -3,
- { 12, 12, 12, 0 },
- { 8, 3, 5, 0 },
- 5, 1, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_HELL_HOG, 'h', RED, "hell-hog",
- M_SPELLCASTER | M_THICK_SKIN | M_EVIL,
- MR_NO_FLAGS,
- 0, 10, MONS_HELL_HOG, MONS_HELL_HOG, MH_DEMONIC, -3,
- { 20, 0, 0, 0 },
- { 11, 3, 5, 0 },
- 2, 9, 14, 7, MST_HELL_HOG, CE_CLEAN, Z_NOZOMBIE, S_SILENT, I_ANIMAL,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_SERPENT_OF_HELL, 'D', RED, "Serpent of Hell",
- M_SPELLCASTER | M_FLIES | M_SEE_INVIS | M_EVIL,
- MR_RES_POISON | MR_RES_HELLFIRE,
- 0, 18, MONS_SERPENT_OF_HELL, MONS_SERPENT_OF_HELL, MH_DEMONIC, -13,
- { 35, 15, 15, 0 },
- { 20, 4, 4, 0 },
- 12, 9, 14, 7, MST_SERPENT_OF_HELL, CE_CLEAN, Z_NOZOMBIE, S_ROAR, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_BOGGART, 'g', DARKGREY, "boggart",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS,
- MR_NO_FLAGS,
- 0, 14, MONS_BOGGART, MONS_BOGGART, MH_NATURAL, -7,
- { 5, 0, 0, 0 },
- { 2, 3, 5, 0 },
- 0, 12, 12, 7, MST_BOGGART, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-{
- MONS_QUICKSILVER_DRAGON, 'D', LIGHTCYAN, "quicksilver dragon",
- M_SPELLCASTER | M_FLIES | M_SEE_INVIS,
- MR_NO_FLAGS,
- 0, 14, MONS_DRAGON, MONS_QUICKSILVER_DRAGON, MH_NATURAL, -7,
- { 45, 0, 0, 0 },
- { 16, 3, 5, 0 },
- 10, 15, 15, 7, MST_QUICKSILVER_DRAGON, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_IRON_DRAGON, 'D', CYAN, "iron dragon",
- M_SPELLCASTER | M_SEE_INVIS,
- MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD,
- 0, 14, MONS_DRAGON, MONS_IRON_DRAGON, MH_NATURAL, -7,
- { 25, 25, 25, 0 },
- { 18, 5, 3, 0 },
- 20, 6, 8, 7, MST_IRON_DRAGON, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_SKELETAL_WARRIOR, 'z', CYAN, "skeletal warrior",
- M_SPELLCASTER | M_ACTUAL_SPELLS | M_EVIL,
- MR_RES_POISON | MR_RES_COLD,
- 0, 10, MONS_SKELETAL_WARRIOR, MONS_SKELETAL_WARRIOR, MH_UNDEAD, -7,
- { 25, 0, 0, 0 },
- { 10, 5, 3, 0 },
- 15, 10, 10, 7, MST_SKELETAL_WARRIOR, CE_CONTAMINATED, Z_SMALL, S_SILENT, I_NORMAL,
- MONUSE_WEAPONS_ARMOUR
-}
-,
-
-
-/* player ghost - only one per level. stats are stored in ghost struct */
-{
- MONS_PLAYER_GHOST, 'p', DARKGREY, "",
- M_SPEAKS | M_SPELLCASTER | M_ACTUAL_SPELLS | M_FLIES,
- MR_RES_POISON,
- 0, 15, MONS_PHANTOM, MONS_PLAYER_GHOST, MH_UNDEAD, -5,
- { 5, 0, 0, 0 },
- { 4, 2, 3, 0 },
- 1, 2, 10, 7, MST_GHOST, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-/* random demon in pan - only one per level. stats are stored in ghost struct */
-{
- MONS_PANDEMONIUM_DEMON, '&', BLACK, "&",
- M_SPELLCASTER | M_SPEAKS | M_EVIL,
- MR_RES_POISON,
- 0, 14, MONS_PANDEMONIUM_DEMON, MONS_PANDEMONIUM_DEMON, MH_DEMONIC, -5,
- { 5, 0, 0, 0 },
- { 4, 2, 3, 0 },
- 1, 2, 10, 7, MST_GHOST, CE_CONTAMINATED, Z_NOZOMBIE, S_RANDOM, I_HIGH,
- MONUSE_OPEN_DOORS
-}
-,
-
-// begin lava monsters {dlb}
-{
- MONS_LAVA_WORM, 'w', RED, "lava worm",
- M_NO_FLAGS,
- MR_RES_FIRE | MR_VUL_COLD,
- 0, 10, MONS_LAVA_WORM, MONS_LAVA_WORM, MH_NATURAL, -3,
- { 15, 0, 0, 0 },
- { 6, 3, 5, 0 },
- 1, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_ANIMAL_LIKE,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_LAVA_FISH, ';', RED, "lava fish",
- M_NO_FLAGS,
- MR_RES_FIRE | MR_VUL_COLD,
- 0, 10, MONS_BIG_FISH, MONS_LAVA_FISH, MH_NATURAL, -3,
- { 10, 0, 0, 0 },
- { 4, 3, 5, 0 },
- 4, 15, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_ANIMAL_LIKE,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_LAVA_SNAKE, 'S', RED, "lava snake",
- M_SPECIAL_ABILITY,
- MR_RES_FIRE | MR_VUL_COLD,
- 0, 10, MONS_SNAKE, MONS_LAVA_SNAKE, MH_NATURAL, -3,
- { 7, 0, 0, 0 },
- { 3, 3, 5, 0 },
- 2, 17, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_HISS, I_ANIMAL_LIKE,
- MONUSE_NOTHING
-}
-,
-
-{ // mv: was another lava thing
- MONS_SALAMANDER, 'S', LIGHTRED, "salamander",
- M_WARM_BLOOD,
- MR_RES_FIRE | MR_VUL_COLD,
- 0, 10, MONS_SALAMANDER, MONS_SALAMANDER, MH_NATURAL, -3,
- { 23, 0, 0, 0 },
- { 14, 3, 5, 0 },
- 5, 5, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_HIGH,
- MONUSE_WEAPONS_ARMOUR
-}
-
-,
-// end lava monsters {dlb}
-
-// begin water monsters {dlb}
-{
- MONS_BIG_FISH, ';', LIGHTGREEN, "big fish",
- M_COLD_BLOOD,
- MR_NO_FLAGS,
- 0, 10, MONS_BIG_FISH, MONS_BIG_FISH, MH_NATURAL, -3,
- { 8, 0, 0, 0 },
- { 4, 3, 5, 0 },
- 1, 12, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_ANIMAL_LIKE,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_GIANT_GOLDFISH, ';', LIGHTRED, "giant goldfish",
- M_COLD_BLOOD,
- MR_NO_FLAGS,
- 0, 10, MONS_BIG_FISH, MONS_GIANT_GOLDFISH, MH_NATURAL, -3,
- { 15, 0, 0, 0 },
- { 7, 3, 5, 0 },
- 5, 7, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_ANIMAL_LIKE,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_ELECTRICAL_EEL, ';', LIGHTBLUE, "electrical eel",
- M_COLD_BLOOD | M_SPECIAL_ABILITY,
- MR_RES_ELEC,
- 0, 10, MONS_ELECTRICAL_EEL, MONS_ELECTRICAL_EEL, MH_NATURAL, -3,
- { 0, 0, 0, 0 },
- { 3, 3, 5, 0 },
- 1, 15, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_ANIMAL_LIKE,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_JELLYFISH, 'J', CYAN, "jellyfish",
- M_NO_FLAGS,
- MR_RES_POISON,
- 0, 10, MONS_JELLYFISH, MONS_JELLYFISH, MH_NATURAL, -3,
- { 1, 1, 0, 0 },
- { 4, 3, 5, 0 },
- 0, 5, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_WATER_ELEMENTAL, '{', LIGHTBLUE, "water elemental",
- M_FLIES,
- MR_RES_POISON | MR_VUL_FIRE | MR_RES_ELEC,
- 0, 10, MONS_EARTH_ELEMENTAL, MONS_WATER_ELEMENTAL, MH_NONLIVING, 5000,
- { 25, 0, 0, 0 },
- { 6, 5, 3, 0 },
- 0, 7, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_OPEN_DOORS
-}
-,
-
-{
- MONS_SWAMP_WORM, 'w', BROWN, "swamp worm",
- M_AMPHIBIOUS,
- MR_NO_FLAGS,
- 0, 10, MONS_WORM, MONS_SWAMP_WORM, MH_NATURAL, -3,
- { 20, 0, 0, 0 },
- { 5, 5, 5, 0 },
- 3, 12, 12, 0, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_PLANT,
- MONUSE_NOTHING
-},
-// end water monsters {dlb}
-
-/* ************************************************************************
-Josh added the following, but they just won't work in the game just yet ...
-besides, four bear types !?!?! isn't that a *bit* excessive given the
-limited diversity of existing monster types?
-
-I'm still far from happy about the inclusion of "Shuggoths" -- I just do
-not think it fits into Crawl ... {dlb}
-************************************************************************ */
- //jmf: it's never created anywhere yet, so you can save the punctuation.
- // as to bears & wolves: the lair needs more variety.
-
-#if 0
-{
- MONS_SHUGGOTH, 'A', LIGHTGREEN, "shuggoth",
- M_NO_SKELETON | M_SEE_INVIS,
- MR_RES_ELEC | MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD,
- 1000, 10, MONS_SHUGGOTH, MONS_SHUGGOTH, MH_DEMONIC, 300,
- { 5, 5, 5, 0 },
- { 10, 4, 4, 0 },
- 10, 10, 20, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, -1, I_NORMAL,
- MONUSE_NOTHING
-}
-,
-#endif
-
-{
- MONS_WOLF, 'h', LIGHTGREY, "wolf",
- M_WARM_BLOOD | M_SEE_INVIS, //jmf: until smell exists
- MR_NO_FLAGS,
- 450, 10, MONS_HOUND, MONS_WOLF, MH_NATURAL, -3,
- { 8, 2, 2, 0 },
- { 4, 3, 5, 0 },
- 3, 15, 17, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_BARK, I_ANIMAL,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_WARG, 'h', DARKGREY, "warg",
- M_SEE_INVIS | M_WARM_BLOOD,
- MR_RES_POISON,
- 600, 12, MONS_HOUND, MONS_WARG, MH_NATURAL, -6,
- { 12, 3, 3, 0 },
- { 4, 4, 5, 0 },
- 4, 12, 13, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_BARK, I_ANIMAL,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_BEAR, 'U', BROWN, "bear",
- M_WARM_BLOOD,
- MR_NO_FLAGS,
- 2000, 10, MONS_BEAR, MONS_BEAR, MH_NATURAL, -3,
- { 10, 6, 6, 0 },
- { 7, 3, 3, 0 },
- 4, 4, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_GROWL, I_ANIMAL,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_GRIZZLY_BEAR, 'U', LIGHTGREY, "grizzly bear",
- M_WARM_BLOOD,
- MR_NO_FLAGS,
- 2500, 10, MONS_BEAR, MONS_GRIZZLY_BEAR, MH_NATURAL, -3,
- { 12, 8, 8, 0 },
- { 7, 4, 4, 0 },
- 5, 8, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_GROWL, I_ANIMAL,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_POLAR_BEAR, 'U', WHITE, "polar bear",
- M_WARM_BLOOD | M_AMPHIBIOUS,
- MR_RES_COLD,
- 2500, 10, MONS_BEAR, MONS_POLAR_BEAR, MH_NATURAL, -3,
- { 20, 5, 5, 0 }, //jmf: polar bears have very strong jaws & necks
- { 7, 5, 3, 0 },
- 7, 8, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_GROWL, I_ANIMAL,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_BLACK_BEAR, 'U', DARKGREY, "black bear",
- M_WARM_BLOOD,
- MR_NO_FLAGS,
- 1800, 10, MONS_BEAR, MONS_BLACK_BEAR, MH_NATURAL, -3,
- { 4, 4, 4, 0 },
- { 6, 3, 3, 0 },
- 2, 8, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_GROWL, I_ANIMAL,
- MONUSE_NOTHING
-}
-,
-
-// small simulacrum
-{
- MONS_SIMULACRUM_SMALL, 'z', WHITE, "",
- M_EVIL,
- MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD,
- 0, 6, MONS_SIMULACRUM_SMALL, MONS_SIMULACRUM_SMALL, MH_UNDEAD, -1,
- { 6, 0, 0, 0 },
- { 2, 3, 5, 0 },
- 10, 4, 7, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-// large simulacrum
-{
- MONS_SIMULACRUM_LARGE, 'Z', WHITE, "",
- M_EVIL,
- MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD,
- 0, 6, MONS_SIMULACRUM_SMALL, MONS_SIMULACRUM_LARGE, MH_UNDEAD, -1,
- { 14, 0, 0, 0 },
- { 5, 3, 5, 0 },
- 10, 5, 7, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_GIANT_NEWT, 'l', LIGHTGREEN, "giant newt",
- M_COLD_BLOOD | M_AMPHIBIOUS,
- MR_NO_FLAGS,
- 150, 10, MONS_GIANT_LIZARD, MONS_GIANT_NEWT, MH_NATURAL, -3,
- { 3, 0, 0, 0 },
- { 1, 1, 2, 0 },
- 0, 15, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_REPTILE,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_GIANT_GECKO, 'l', YELLOW, "giant gecko",
- M_COLD_BLOOD,
- MR_NO_FLAGS,
- 250, 10, MONS_GIANT_LIZARD, MONS_GIANT_GECKO, MH_NATURAL, -3,
- { 5, 0, 0, 0 },
- { 1, 3, 5, 0 },
- 1, 14, 12, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_REPTILE,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_GIANT_IGUANA, 'l', BLUE, "giant iguana",
- M_COLD_BLOOD,
- MR_NO_FLAGS,
- 400, 10, MONS_GIANT_LIZARD, MONS_GIANT_IGUANA, MH_NATURAL, -3,
- { 15, 0, 0, 0 },
- { 3, 3, 5, 0 },
- 5, 9, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_HISS, I_REPTILE,
- MONUSE_NOTHING
-}
-,
-
-{
- // gila monsters colours: lightmagenta, magenta, lightred, red, yellow
- MONS_GILA_MONSTER, 'l', BLACK, "gila monster",
- M_COLD_BLOOD,
- MR_NO_FLAGS,
- 500, 10, MONS_GIANT_LIZARD, MONS_GILA_MONSTER, MH_NATURAL, -3,
- { 20, 0, 0, 0 },
- { 5, 4, 4, 0 },
- 3, 12, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_HISS, I_REPTILE,
- MONUSE_NOTHING
-}
-,
-
-{
- MONS_KOMODO_DRAGON, 'l', LIGHTRED, "komodo dragon",
- M_COLD_BLOOD | M_AMPHIBIOUS,
- MR_NO_FLAGS,
- 800, 10, MONS_GIANT_LIZARD, MONS_KOMODO_DRAGON, MH_NATURAL, -3,
- { 30, 0, 0, 0 },
- { 8, 3, 5, 0 },
- 7, 8, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_HISS, I_REPTILE,
- MONUSE_NOTHING
-}
-,
-
-#endif
diff --git a/stone_soup/crawl-ref/source/mon-pick.cc b/stone_soup/crawl-ref/source/mon-pick.cc
deleted file mode 100644
index 79fc29f1fc..0000000000
--- a/stone_soup/crawl-ref/source/mon-pick.cc
+++ /dev/null
@@ -1,2827 +0,0 @@
-/*
- * File: mon-pick.cc
- * Summary: Functions used to help determine which monsters should appear.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <2> 08-Mar-2000 DLB enumeration & clean-up
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "mon-pick.h"
-
-#include "externs.h"
-
-static int mons_cocytus_level(int mcls);
-static int mons_cocytus_rare(int mcls);
-static int mons_crypt_level(int mcls);
-static int mons_crypt_rare(int mcls);
-static int mons_dis_level(int mcls);
-static int mons_dis_rare(int mcls);
-static int mons_gehenna_level(int mcls);
-static int mons_gehenna_rare(int mcls);
-static int mons_hallblade_level(int mcls);
-static int mons_hallblade_rare(int mcls);
-static int mons_hallelf_level(int mcls);
-static int mons_hallelf_rare(int mcls);
-static int mons_hallzot_level(int mcls);
-static int mons_hallzot_rare(int mcls);
-static int mons_hive_level(int mcls);
-static int mons_hive_rare(int mcls);
-static int mons_lair_level(int mcls);
-static int mons_lair_rare(int mcls);
-static int mons_mineorc_level(int mcls);
-static int mons_mineorc_rare(int mcls);
-static int mons_pitslime_level(int mcls);
-static int mons_pitslime_rare(int mcls);
-static int mons_pitsnake_level(int mcls);
-static int mons_pitsnake_rare(int mcls);
-static int mons_standard_level(int mcls);
-static int mons_standard_rare(int mcls);
-static int mons_swamp_level(int mcls);
-static int mons_swamp_rare(int mcls);
-static int mons_tartarus_level(int mcls);
-static int mons_tartarus_rare(int mcls);
-static int mons_tomb_level(int mcls);
-static int mons_tomb_rare(int mcls);
-static int mons_caverns_level(int mcls);
-static int mons_caverns_rare(int mcls);
-
-/* ******************* BEGIN EXTERNAL FUNCTIONS ******************* */
-int branch_depth(int branch)
-{
- switch (branch)
- {
- case STAIRS_LAIR:
- return 10;
-
- case STAIRS_VAULTS:
- return 8;
-
- case STAIRS_ELVEN_HALLS:
- return 7;
-
- case STAIRS_SLIME_PITS:
- return 6;
-
- case STAIRS_CRYPT:
- case STAIRS_HALL_OF_ZOT:
- case STAIRS_SNAKE_PIT:
- case STAIRS_SWAMP:
- return 5;
-
- case STAIRS_HIVE:
- case STAIRS_ORCISH_MINES:
- return 4;
-
- case STAIRS_TOMB:
- return 3;
-
- case STAIRS_ECUMENICAL_TEMPLE:
- case STAIRS_HALL_OF_BLADES:
- return 1;
-
- default:
- return 0;
- }
-} // end branch_depth()
-
-// NB - When adding new branches or levels above 50, you must
-// change pre-game deletion routine in new_game in newgame.cc
-
-int mons_level(int mcls)
-{
- int monster_level = 0;
- int (*fnc_level) (int) = 0;
-
- if (you.level_type == LEVEL_ABYSS)
- monster_level = ((mons_abyss(mcls)) ? 51 : 0);
- else if (you.level_type == LEVEL_PANDEMONIUM)
- monster_level = ((mons_pan(mcls)) ? 52 : 0);
- else
- {
- fnc_level =
- ((you.where_are_you == BRANCH_DIS) ? mons_dis_level :
- (you.where_are_you == BRANCH_GEHENNA) ? mons_gehenna_level :
- (you.where_are_you == BRANCH_COCYTUS) ? mons_cocytus_level :
- (you.where_are_you == BRANCH_TARTARUS) ? mons_tartarus_level :
- (you.where_are_you == BRANCH_ORCISH_MINES) ? mons_mineorc_level :
- (you.where_are_you == BRANCH_HIVE) ? mons_hive_level :
- (you.where_are_you == BRANCH_LAIR) ? mons_lair_level :
- (you.where_are_you == BRANCH_SLIME_PITS) ? mons_pitslime_level :
- (you.where_are_you == BRANCH_CRYPT) ? mons_crypt_level :
- (you.where_are_you == BRANCH_HALL_OF_BLADES)?mons_hallblade_level :
- (you.where_are_you == BRANCH_HALL_OF_ZOT) ? mons_hallzot_level :
- (you.where_are_you == BRANCH_SNAKE_PIT) ? mons_pitsnake_level :
- (you.where_are_you == BRANCH_ELVEN_HALLS) ? mons_hallelf_level :
- (you.where_are_you == BRANCH_TOMB) ? mons_tomb_level :
- (you.where_are_you == BRANCH_SWAMP) ? mons_swamp_level :
- (you.where_are_you == BRANCH_VAULTS) ? mons_standard_level :
- (you.where_are_you == BRANCH_CAVERNS) ? mons_caverns_level
- : mons_standard_level);
-
- monster_level = fnc_level(mcls);
- }
-
- return (monster_level);
-} // end mons_level()
-
-// higher values returned means the monster is "more common"
-// a return value of zero means the monster will never appear {dlb}
-int mons_rarity(int mcls)
-{
- int monster_rarity = 0;
- int (*fnc_rarity) (int) = 0;
-
- // now, what about pandemonium ??? {dlb}
- if (you.level_type == LEVEL_ABYSS)
- return mons_rare_abyss(mcls);
- else
- {
- fnc_rarity =
- ((you.where_are_you == BRANCH_DIS) ? mons_dis_rare :
- (you.where_are_you == BRANCH_GEHENNA) ? mons_gehenna_rare :
- (you.where_are_you == BRANCH_COCYTUS) ? mons_cocytus_rare :
- (you.where_are_you == BRANCH_TARTARUS) ? mons_tartarus_rare :
- (you.where_are_you == BRANCH_ORCISH_MINES) ? mons_mineorc_rare :
- (you.where_are_you == BRANCH_HIVE) ? mons_hive_rare :
- (you.where_are_you == BRANCH_LAIR) ? mons_lair_rare :
- (you.where_are_you == BRANCH_SLIME_PITS) ? mons_pitslime_rare :
- (you.where_are_you == BRANCH_CRYPT) ? mons_crypt_rare :
- (you.where_are_you == BRANCH_HALL_OF_BLADES)?mons_hallblade_rare :
- (you.where_are_you == BRANCH_HALL_OF_ZOT) ? mons_hallzot_rare :
- (you.where_are_you == BRANCH_SNAKE_PIT) ? mons_pitsnake_rare :
- (you.where_are_you == BRANCH_ELVEN_HALLS) ? mons_hallelf_rare :
- (you.where_are_you == BRANCH_TOMB) ? mons_tomb_rare :
- (you.where_are_you == BRANCH_SWAMP) ? mons_swamp_rare :
- (you.where_are_you == BRANCH_VAULTS) ? mons_standard_rare :
- (you.where_are_you == BRANCH_CAVERNS) ? mons_caverns_rare
- : mons_standard_rare);
-
- monster_rarity = fnc_rarity(mcls);
- }
-
- return (monster_rarity);
-} // end mons_rarity()
-
-bool mons_abyss(int mcls)
-{
- switch (mcls)
- {
- case MONS_ABOMINATION_LARGE:
- case MONS_ABOMINATION_SMALL:
- case MONS_AIR_ELEMENTAL:
- case MONS_ANCIENT_LICH:
- case MONS_BALRUG:
- case MONS_BLUE_DEATH:
- case MONS_BLUE_DEVIL:
- case MONS_BRAIN_WORM:
- case MONS_CACODEMON:
- case MONS_CLAY_GOLEM:
- case MONS_CRYSTAL_GOLEM:
- case MONS_DANCING_WEAPON:
- case MONS_DEMONIC_CRAWLER:
- case MONS_EARTH_ELEMENTAL:
- case MONS_EFREET:
- case MONS_EXECUTIONER:
- case MONS_EYE_OF_DEVASTATION:
- case MONS_EYE_OF_DRAINING:
- case MONS_FIRE_ELEMENTAL:
- case MONS_FLAYED_GHOST:
- case MONS_FLYING_SKULL:
- case MONS_FREEZING_WRAITH:
- case MONS_DEATH_DRAKE:
- case MONS_FUNGUS:
- case MONS_GIANT_EYEBALL:
- case MONS_GIANT_ORANGE_BRAIN:
- case MONS_GIANT_SPORE:
- case MONS_GREAT_ORB_OF_EYES:
- case MONS_GREEN_DEATH:
- case MONS_GUARDIAN_NAGA:
- case MONS_HAIRY_DEVIL:
- case MONS_HELLION:
- case MONS_HELLWING:
- case MONS_HELL_HOUND:
- case MONS_HELL_KNIGHT:
- case MONS_HUNGRY_GHOST:
- case MONS_ICE_BEAST:
- case MONS_ICE_DEVIL:
- case MONS_IMP:
- case MONS_INSUBSTANTIAL_WISP:
- case MONS_IRON_DEVIL:
- case MONS_IRON_GOLEM:
- case MONS_JELLY:
- case MONS_SKELETON_LARGE:
- case MONS_LEMURE:
- case MONS_LICH:
- case MONS_LOROCYPROCA:
- case MONS_MANES:
- case MONS_MIDGE:
- case MONS_MUMMY:
- case MONS_NAGA_MAGE:
- case MONS_NAGA_WARRIOR:
- case MONS_NECROMANCER:
- case MONS_NECROPHAGE:
- case MONS_NEQOXEC:
- case MONS_ORANGE_DEMON:
- case MONS_PHANTOM:
- case MONS_PIT_FIEND:
- case MONS_RAKSHASA:
- case MONS_REAPER:
- case MONS_RED_DEVIL:
- case MONS_ROTTING_DEVIL:
- case MONS_SHADOW:
- case MONS_SHADOW_DEMON:
- case MONS_SHADOW_IMP:
- case MONS_SHINING_EYE:
- case MONS_SKELETAL_DRAGON:
- case MONS_SKELETAL_WARRIOR:
- case MONS_SKELETON_SMALL:
- case MONS_SMOKE_DEMON:
- case MONS_SOUL_EATER:
- case MONS_SPECTRAL_WARRIOR:
- case MONS_SPINY_WORM:
- case MONS_STONE_GOLEM:
- case MONS_SUN_DEMON:
- case MONS_TENTACLED_MONSTROSITY:
- case MONS_TOENAIL_GOLEM:
- case MONS_TORMENTOR:
- case MONS_UFETUBUS:
- case MONS_UGLY_THING:
- case MONS_UNSEEN_HORROR:
- case MONS_VAMPIRE:
- case MONS_VAPOUR:
- case MONS_VERY_UGLY_THING:
- case MONS_WHITE_IMP:
- case MONS_WIGHT:
- case MONS_WIZARD:
- case MONS_WOOD_GOLEM:
- case MONS_WRAITH:
- case MONS_YNOXINUL:
- case MONS_ZOMBIE_LARGE:
- case MONS_ZOMBIE_SMALL:
- case MONS_SIMULACRUM_LARGE:
- case MONS_SIMULACRUM_SMALL:
- return true;
- default:
- return false;
- }
-} // end mons_abyss()
-
-int mons_rare_abyss(int mcls)
-{
- switch (mcls)
- {
- case MONS_ABOMINATION_LARGE:
- case MONS_ABOMINATION_SMALL:
- return 99;
-
- case MONS_LEMURE:
- case MONS_MANES:
- case MONS_MIDGE:
- case MONS_UFETUBUS:
- case MONS_WHITE_IMP:
- return 80;
-
- case MONS_HELLWING:
- case MONS_NEQOXEC:
- case MONS_ORANGE_DEMON:
- case MONS_SMOKE_DEMON:
- case MONS_YNOXINUL:
- return 50;
-
- case MONS_SKELETON_LARGE:
- case MONS_SKELETAL_WARRIOR:
- case MONS_SKELETON_SMALL:
- return 40;
-
- case MONS_ZOMBIE_LARGE:
- case MONS_ZOMBIE_SMALL:
- return 35;
-
- case MONS_SKELETAL_DRAGON:
- return 20;
-
- case MONS_EFREET:
- return 18;
-
- case MONS_RAKSHASA:
- return 17;
-
- case MONS_BRAIN_WORM:
- return 16;
-
- case MONS_FLYING_SKULL:
- case MONS_FREEZING_WRAITH:
- case MONS_GIANT_ORANGE_BRAIN:
- case MONS_VERY_UGLY_THING:
- case MONS_WRAITH:
- return 15;
-
- case MONS_EYE_OF_DRAINING:
- case MONS_LICH:
- return 14;
-
- case MONS_INSUBSTANTIAL_WISP:
- case MONS_UNSEEN_HORROR:
- return 12;
-
- case MONS_HELL_HOUND:
- case MONS_HUNGRY_GHOST:
- case MONS_SHADOW:
- return 11;
-
- case MONS_BALRUG:
- case MONS_BLUE_DEATH:
- case MONS_BLUE_DEVIL:
- case MONS_CACODEMON:
- case MONS_DEMONIC_CRAWLER:
- case MONS_EXECUTIONER:
- case MONS_GREEN_DEATH:
- case MONS_GUARDIAN_NAGA:
- case MONS_HAIRY_DEVIL:
- case MONS_HELLION:
- case MONS_ICE_DEVIL:
- case MONS_IMP:
- case MONS_LOROCYPROCA:
- case MONS_MUMMY:
- case MONS_NECROPHAGE:
- case MONS_ROTTING_DEVIL:
- case MONS_SHADOW_DEMON:
- case MONS_SHADOW_IMP:
- case MONS_SUN_DEMON:
- case MONS_WIGHT:
- return 10;
-
- case MONS_ICE_BEAST:
- case MONS_JELLY:
- case MONS_TORMENTOR:
- case MONS_VAMPIRE:
- case MONS_VAPOUR:
- case MONS_SIMULACRUM_LARGE:
- case MONS_SIMULACRUM_SMALL:
- return 9;
-
- case MONS_FUNGUS:
- case MONS_GIANT_EYEBALL:
- case MONS_PHANTOM:
- case MONS_REAPER:
- return 8;
-
- case MONS_SOUL_EATER:
- return 7;
-
- case MONS_IRON_DEVIL:
- return 6;
-
- case MONS_ANCIENT_LICH:
- case MONS_CLAY_GOLEM:
- case MONS_GREAT_ORB_OF_EYES:
- case MONS_IRON_GOLEM:
- case MONS_NAGA_MAGE:
- case MONS_NAGA_WARRIOR:
- case MONS_PIT_FIEND:
- case MONS_RED_DEVIL:
- case MONS_SHINING_EYE:
- case MONS_SPECTRAL_WARRIOR:
- case MONS_SPINY_WORM:
- case MONS_STONE_GOLEM:
- case MONS_TENTACLED_MONSTROSITY:
- case MONS_WIZARD:
- case MONS_WOOD_GOLEM:
- return 5;
-
- case MONS_AIR_ELEMENTAL:
- case MONS_EARTH_ELEMENTAL:
- case MONS_FIRE_ELEMENTAL:
- case MONS_FLAYED_GHOST:
- return 4;
-
- case MONS_CRYSTAL_GOLEM:
- case MONS_EYE_OF_DEVASTATION:
- case MONS_HELL_KNIGHT:
- case MONS_NECROMANCER:
- case MONS_UGLY_THING:
- return 3;
-
- case MONS_DANCING_WEAPON:
- case MONS_GIANT_SPORE:
- return 2;
-
- case MONS_TOENAIL_GOLEM:
- return 1;
-
- default:
- return 0;
- }
-} // end mons_rare_abyss()
-
-bool mons_pan(int mcls)
-{
- switch (mcls)
- {
- // icky monsters
- case MONS_BRAIN_WORM:
- case MONS_FUNGUS:
- case MONS_GIANT_ORANGE_BRAIN:
- case MONS_JELLY:
- case MONS_SLIME_CREATURE:
- // undead
- case MONS_FLAYED_GHOST:
- case MONS_FLYING_SKULL:
- case MONS_FREEZING_WRAITH:
- case MONS_HUNGRY_GHOST:
- case MONS_SKELETON_LARGE:
- case MONS_LICH:
- case MONS_MUMMY:
- case MONS_NECROPHAGE:
- case MONS_PHANTOM:
- case MONS_SHADOW:
- case MONS_SKELETON_SMALL:
- case MONS_SPECTRAL_WARRIOR:
- case MONS_VAMPIRE:
- case MONS_WIGHT:
- case MONS_WRAITH:
- case MONS_ZOMBIE_LARGE:
- case MONS_ZOMBIE_SMALL:
- case MONS_SIMULACRUM_LARGE:
- case MONS_SIMULACRUM_SMALL:
- // "things"
- case MONS_ABOMINATION_LARGE:
- case MONS_ABOMINATION_SMALL:
- case MONS_INSUBSTANTIAL_WISP:
- case MONS_PULSATING_LUMP:
- case MONS_UNSEEN_HORROR:
- // eyes
- case MONS_EYE_OF_DRAINING:
- case MONS_GIANT_EYEBALL:
- case MONS_GREAT_ORB_OF_EYES:
- // malign beings
- case MONS_EFREET:
- case MONS_RAKSHASA:
- //case MONS_RAKSHASA_FAKE: //jmf: FIXME: really create these?
- // I'm guessing not -- bwr
- // golems
- case MONS_CLAY_GOLEM:
- case MONS_CRYSTAL_GOLEM:
- case MONS_IRON_GOLEM:
- case MONS_STONE_GOLEM:
- case MONS_TOENAIL_GOLEM:
- case MONS_WOOD_GOLEM:
- // dragon(s)
- case MONS_MOTTLED_DRAGON:
- // elementals
- case MONS_AIR_ELEMENTAL:
- case MONS_EARTH_ELEMENTAL:
- case MONS_FIRE_ELEMENTAL:
- // humanoids
- case MONS_NECROMANCER:
- case MONS_STONE_GIANT:
- case MONS_WIZARD:
- // demons
- case MONS_BALRUG:
- case MONS_BLUE_DEATH:
- case MONS_CACODEMON:
- case MONS_EXECUTIONER:
- case MONS_GREEN_DEATH:
- case MONS_HELLWING:
- case MONS_LEMURE:
- case MONS_MANES:
- case MONS_MIDGE:
- case MONS_NEQOXEC:
- case MONS_ORANGE_DEMON:
- case MONS_SMOKE_DEMON:
- case MONS_UFETUBUS:
- case MONS_WHITE_IMP:
- case MONS_YNOXINUL:
- return true;
- default:
- return false;
- }
-} // end mons_pan()
-
-/* ******************** END EXTERNAL FUNCTIONS ******************** */
-
-static int mons_dis_level(int mcls)
-{
- int mlev = 26;
-
- switch (mcls)
- {
- case MONS_CLAY_GOLEM:
- case MONS_IMP:
- case MONS_NECROPHAGE:
- case MONS_RED_DEVIL:
- case MONS_SKELETAL_WARRIOR:
- case MONS_ZOMBIE_LARGE:
- mlev++;
- break;
-
- case MONS_HELL_HOUND:
- case MONS_HELL_KNIGHT:
- case MONS_SKELETON_LARGE:
- case MONS_PHANTOM:
- case MONS_ROTTING_DEVIL:
- case MONS_SHADOW:
- case MONS_SKELETON_SMALL:
- case MONS_STONE_GOLEM:
- case MONS_TORMENTOR:
- case MONS_WIGHT:
- case MONS_ZOMBIE_SMALL:
- mlev += 2;
- break;
-
- case MONS_EFREET:
- case MONS_FLYING_SKULL:
- case MONS_HELLION:
- case MONS_HELL_HOG:
- case MONS_IRON_GOLEM:
- case MONS_MUMMY:
- mlev += 3;
- break;
-
- case MONS_FLAYED_GHOST:
- case MONS_FREEZING_WRAITH:
- case MONS_DEATH_DRAKE:
- case MONS_HAIRY_DEVIL:
- case MONS_IRON_DEVIL:
- case MONS_VAMPIRE:
- case MONS_WRAITH:
- mlev += 3;
- break;
-
- case MONS_BLUE_DEVIL:
- case MONS_DANCING_WEAPON:
- case MONS_ICE_DEVIL:
- case MONS_ICE_DRAGON:
- case MONS_LICH:
- case MONS_REAPER:
- case MONS_SOUL_EATER:
- case MONS_SPECTRAL_WARRIOR:
- mlev += 5;
- break;
-
- case MONS_ANCIENT_LICH:
- case MONS_FIEND:
- case MONS_IRON_DRAGON:
- case MONS_SKELETAL_DRAGON:
- mlev += 6;
- break;
-
- default:
- return 0;
- }
-
- return (mlev);
-} // end mons_dis_level()
-
-static int mons_dis_rare(int mcls)
-{
- switch (mcls)
- {
- case MONS_IMP:
- case MONS_IRON_DEVIL:
- case MONS_ZOMBIE_LARGE:
- case MONS_ZOMBIE_SMALL:
- return 99;
-
- case MONS_REAPER:
- return 77;
-
- case MONS_TORMENTOR:
- return 66;
-
- case MONS_RED_DEVIL:
- case MONS_SKELETAL_WARRIOR:
- return 50;
-
- case MONS_WRAITH:
- return 48;
-
- case MONS_SHADOW:
- return 56;
-
- case MONS_HELL_HOUND:
- return 46;
-
- case MONS_MUMMY:
- case MONS_WIGHT:
- return 45;
-
- case MONS_HELLION:
- case MONS_BLUE_DEVIL:
- return 40;
-
- case MONS_FLYING_SKULL:
- return 35;
-
- case MONS_FREEZING_WRAITH:
- case MONS_ICE_DEVIL:
- return 30;
-
- case MONS_FLAYED_GHOST:
- case MONS_SKELETON_LARGE:
- case MONS_NECROPHAGE:
- case MONS_SKELETON_SMALL:
- return 25;
-
- case MONS_HELL_HOG:
- case MONS_SKELETAL_DRAGON:
- return 20;
-
- case MONS_VAMPIRE:
- return 19;
-
- case MONS_PHANTOM:
- return 17;
-
- case MONS_HAIRY_DEVIL:
- return 15;
-
- case MONS_CLAY_GOLEM:
- case MONS_DANCING_WEAPON:
- case MONS_EFREET:
- case MONS_HELL_KNIGHT:
- case MONS_IRON_GOLEM:
- case MONS_LICH:
- case MONS_ROTTING_DEVIL:
- case MONS_SOUL_EATER:
- case MONS_SPECTRAL_WARRIOR:
- case MONS_STONE_GOLEM:
- return 10;
-
- case MONS_IRON_DRAGON:
- return 5;
-
- case MONS_ANCIENT_LICH:
- case MONS_FIEND:
- return 3;
-
- default:
- return 0;
- }
-} // end mons_dis_rare()
-
-static int mons_gehenna_level(int mcls)
-{
- int mlev = 26;
-
- switch (mcls)
- {
- case MONS_CLAY_GOLEM:
- case MONS_SKELETON_LARGE:
- case MONS_RED_DEVIL:
- case MONS_SKELETON_SMALL:
- case MONS_ZOMBIE_LARGE:
- case MONS_ZOMBIE_SMALL:
- mlev++;
- break;
-
- case MONS_HELL_HOG:
- case MONS_HELL_HOUND:
- case MONS_IMP:
- case MONS_NECROPHAGE:
- case MONS_STONE_GOLEM:
- mlev += 2;
- break;
-
- case MONS_FLYING_SKULL:
- case MONS_IRON_GOLEM:
- case MONS_MUMMY:
- case MONS_PHANTOM:
- case MONS_ROTTING_DEVIL:
- case MONS_SHADOW:
- case MONS_WIGHT:
- mlev += 3;
- break;
-
- case MONS_HAIRY_DEVIL:
- case MONS_HELL_KNIGHT:
- case MONS_VAMPIRE:
- case MONS_WRAITH:
- mlev += 4;
- break;
-
- case MONS_EFREET:
- case MONS_FLAYED_GHOST:
- case MONS_HELLION:
- case MONS_TORMENTOR:
- mlev += 5;
- break;
-
- case MONS_ANCIENT_LICH:
- case MONS_FIEND:
- case MONS_LICH:
- case MONS_PIT_FIEND:
- case MONS_REAPER:
- case MONS_SERPENT_OF_HELL:
- case MONS_SKELETAL_DRAGON:
- case MONS_SOUL_EATER:
- case MONS_SPECTRAL_WARRIOR:
- mlev += 6;
- break;
-
- default:
- return 0;
- }
-
- return (mlev);
-} // end mons_gehenna_level()
-
-static int mons_gehenna_rare(int mcls)
-{
- switch (mcls)
- {
- case MONS_SKELETON_LARGE:
- case MONS_SKELETON_SMALL:
- case MONS_ZOMBIE_LARGE:
- case MONS_ZOMBIE_SMALL:
- return 99;
-
- case MONS_MUMMY:
- return 70;
-
- case MONS_SHADOW:
- return 61;
-
- case MONS_RED_DEVIL:
- case MONS_WIGHT:
- return 60;
-
- case MONS_HELLION:
- return 54;
-
- case MONS_WRAITH:
- return 53;
-
- case MONS_NECROPHAGE:
- case MONS_ROTTING_DEVIL:
- return 50;
-
- case MONS_VAMPIRE:
- return 44;
-
- case MONS_FLYING_SKULL:
- case MONS_REAPER:
- return 43;
-
- case MONS_TORMENTOR:
- return 42;
-
- case MONS_HELL_HOUND:
- return 41;
-
- case MONS_FLAYED_GHOST:
- case MONS_PHANTOM:
- return 32;
-
- case MONS_HELL_HOG:
- case MONS_IMP:
- case MONS_IRON_DEVIL:
- return 30;
-
- case MONS_LICH:
- return 25;
-
- case MONS_HELL_KNIGHT:
- return 21;
-
- case MONS_HAIRY_DEVIL:
- case MONS_SPECTRAL_WARRIOR:
- return 20;
-
- case MONS_CLAY_GOLEM:
- case MONS_SKELETAL_DRAGON:
- return 10;
-
- case MONS_STONE_GOLEM:
- return 8;
-
- case MONS_PIT_FIEND:
- return 7;
-
- case MONS_EFREET:
- case MONS_FIEND:
- case MONS_IRON_GOLEM:
- case MONS_SOUL_EATER:
- return 5;
-
- case MONS_ANCIENT_LICH:
- case MONS_SERPENT_OF_HELL:
- return 4;
-
- default:
- return 0;
- }
-} // end mons_gehenna_rare()
-
-static int mons_cocytus_level(int mcls)
-{
- int mlev = 26;
-
- switch (mcls)
- {
- case MONS_SKELETON_LARGE:
- case MONS_NECROPHAGE:
- case MONS_SKELETAL_WARRIOR:
- case MONS_SKELETON_SMALL:
- case MONS_ZOMBIE_LARGE:
- case MONS_ZOMBIE_SMALL:
- case MONS_SIMULACRUM_LARGE:
- case MONS_SIMULACRUM_SMALL:
- mlev++;
- break;
-
- case MONS_BLUE_DEVIL:
- case MONS_ICE_BEAST:
- case MONS_PHANTOM:
- case MONS_SHADOW:
- mlev += 2;
- break;
-
- case MONS_FLYING_SKULL:
- case MONS_ROTTING_DEVIL:
- case MONS_VAMPIRE:
- case MONS_WIGHT:
- mlev += 3;
- break;
-
- case MONS_FREEZING_WRAITH:
- case MONS_HAIRY_DEVIL:
- case MONS_HUNGRY_GHOST:
- case MONS_MUMMY:
- case MONS_SPECTRAL_WARRIOR:
- case MONS_WRAITH:
- mlev += 4;
- break;
-
- case MONS_ICE_DEVIL:
- case MONS_ICE_DRAGON:
- case MONS_TORMENTOR:
- mlev += 5;
- break;
-
- case MONS_ANCIENT_LICH:
- case MONS_LICH:
- case MONS_REAPER:
- case MONS_SKELETAL_DRAGON:
- case MONS_SOUL_EATER:
- mlev += 6;
- break;
-
- default:
- return 0;
- }
-
- return (mlev);
-} // end mons_cocytus_level()
-
-static int mons_cocytus_rare(int mcls)
-{
- switch (mcls)
- {
- case MONS_FREEZING_WRAITH:
- return 87;
-
- case MONS_ICE_BEAST:
- case MONS_SKELETON_LARGE:
- case MONS_SKELETON_SMALL:
- case MONS_ZOMBIE_LARGE:
- case MONS_ZOMBIE_SMALL:
- return 85;
-
- case MONS_BLUE_DEVIL:
- case MONS_ICE_DEVIL:
- return 76;
-
- case MONS_FLYING_SKULL:
- return 57;
-
- case MONS_SHADOW:
- return 56;
-
- case MONS_SKELETAL_WARRIOR:
- return 50;
-
- case MONS_REAPER:
- return 47;
-
- case MONS_WIGHT:
- case MONS_WRAITH:
- return 45;
-
- case MONS_ICE_DRAGON:
- return 38;
-
- case MONS_ROTTING_DEVIL:
- case MONS_TORMENTOR:
- return 37;
-
- case MONS_MUMMY:
- return 35;
-
- case MONS_VAMPIRE:
- return 34;
-
- case MONS_HAIRY_DEVIL:
- case MONS_HUNGRY_GHOST:
- return 26;
-
- case MONS_NECROPHAGE:
- case MONS_PHANTOM:
- return 25;
-
- case MONS_SPECTRAL_WARRIOR:
- return 20;
-
- case MONS_SOUL_EATER:
- return 19;
-
- case MONS_LICH:
- case MONS_SKELETAL_DRAGON:
- case MONS_SIMULACRUM_LARGE:
- case MONS_SIMULACRUM_SMALL:
- return 12;
-
- case MONS_ANCIENT_LICH:
- return 5;
-
- default:
- return 0;
- }
-} // end mons_cocytus_rare()
-
-static int mons_tartarus_level(int mcls)
-{
- int mlev = 26;
-
- switch (mcls)
- {
- case MONS_IMP:
- case MONS_SKELETON_LARGE:
- case MONS_RED_DEVIL:
- case MONS_SHADOW_IMP:
- case MONS_SKELETAL_WARRIOR:
- case MONS_SKELETON_SMALL:
- mlev++;
- break;
-
- case MONS_HELL_KNIGHT:
- case MONS_NECROPHAGE:
- case MONS_PHANTOM:
- case MONS_WIGHT:
- case MONS_ZOMBIE_LARGE:
- case MONS_ZOMBIE_SMALL:
- mlev += 2;
- break;
-
- case MONS_FREEZING_WRAITH:
- case MONS_HELL_HOUND:
- case MONS_NECROMANCER:
- case MONS_SHADOW:
- case MONS_SHADOW_DEMON:
- case MONS_WRAITH:
- mlev += 3;
- break;
-
- case MONS_BLUE_DEVIL:
- case MONS_FLAYED_GHOST:
- case MONS_HUNGRY_GHOST:
- case MONS_ICE_DEVIL:
- case MONS_MUMMY:
- case MONS_SKELETAL_DRAGON:
- case MONS_SPECTRAL_WARRIOR:
- case MONS_TORMENTOR:
- case MONS_SIMULACRUM_LARGE:
- case MONS_SIMULACRUM_SMALL:
- mlev += 4;
- break;
-
- case MONS_FLYING_SKULL:
- case MONS_HELLION:
- case MONS_REAPER:
- case MONS_ROTTING_DEVIL:
- case MONS_SHADOW_DRAGON:
- case MONS_VAMPIRE:
- mlev += 5;
- break;
-
- case MONS_ANCIENT_LICH:
- case MONS_HAIRY_DEVIL:
- case MONS_LICH:
- case MONS_SOUL_EATER:
- mlev += 6;
- break;
-
- default:
- return 0;
- }
-
- return (mlev);
-} // end mons_tartarus_level()
-
-static int mons_tartarus_rare(int mcls)
-{
- switch (mcls)
- {
- case MONS_SKELETON_LARGE:
- case MONS_SHADOW_IMP:
- case MONS_SKELETAL_WARRIOR:
- case MONS_SKELETON_SMALL:
- case MONS_ZOMBIE_LARGE:
- case MONS_ZOMBIE_SMALL:
- return 99;
-
- case MONS_SHADOW:
- return 92;
-
- case MONS_REAPER:
- return 73;
-
- case MONS_NECROPHAGE:
- return 72;
-
- case MONS_WIGHT:
- return 71;
-
- case MONS_ROTTING_DEVIL:
- return 62;
-
- case MONS_FREEZING_WRAITH:
- return 60;
-
- case MONS_FLYING_SKULL:
- return 53;
-
- case MONS_HELL_HOUND:
- case MONS_PHANTOM:
- case MONS_WRAITH:
- return 52;
-
- case MONS_SHADOW_DEMON:
- return 50;
-
- case MONS_SPECTRAL_WARRIOR:
- return 45;
-
- case MONS_VAMPIRE:
- return 44;
-
- case MONS_HELLION:
- case MONS_TORMENTOR:
- return 42;
-
- case MONS_SKELETAL_DRAGON:
- return 40;
-
- case MONS_SOUL_EATER:
- return 35;
-
- case MONS_ICE_DEVIL: // not really appropriate for a fiery hell
- return 34;
-
- case MONS_MUMMY:
- return 33;
-
- case MONS_BLUE_DEVIL:
- case MONS_HUNGRY_GHOST:
- return 32;
-
- case MONS_FLAYED_GHOST:
- case MONS_HAIRY_DEVIL:
- return 30;
-
- case MONS_LICH:
- return 24;
-
- case MONS_IMP:
- case MONS_SHADOW_DRAGON:
- case MONS_DEATH_DRAKE:
- return 20;
-
- case MONS_RED_DEVIL:
- return 13;
-
- case MONS_HELL_KNIGHT:
- return 14;
-
- case MONS_NECROMANCER:
- case MONS_SIMULACRUM_LARGE:
- case MONS_SIMULACRUM_SMALL:
- return 12;
-
- case MONS_ANCIENT_LICH:
- return 6;
-
- default:
- return 0;
- }
-}
-
-static int mons_mineorc_level(int mcls)
-{
- int mlev = you.branch_stairs[STAIRS_ORCISH_MINES] + 1;
-
- switch (mcls)
- {
- case MONS_HOBGOBLIN:
- case MONS_ORC_PRIEST:
- case MONS_ORC_WARRIOR:
- mlev++;
- break;
-
- case MONS_GNOLL:
- case MONS_OGRE:
- case MONS_WARG:
- case MONS_ORC_KNIGHT:
- case MONS_ORC_WIZARD:
- mlev += 2;
- break;
-
- case MONS_CYCLOPS:
- case MONS_IRON_TROLL:
- case MONS_OGRE_MAGE:
- case MONS_ORC_HIGH_PRIEST:
- case MONS_ORC_SORCERER:
- case MONS_ORC_WARLORD:
- case MONS_ROCK_TROLL:
- case MONS_STONE_GIANT:
- case MONS_TROLL:
- case MONS_TWO_HEADED_OGRE:
- case MONS_ETTIN:
- mlev += 3;
- break;
-
- case MONS_FUNGUS:
- case MONS_GOBLIN:
- case MONS_ORC:
- default:
- mlev += 0;
- }
-
- return (mlev);
-} // end mons_mineorc_level()
-
-static int mons_mineorc_rare(int mcls)
-{
- switch (mcls)
- {
- case MONS_ORC:
- return 300;
-
- case MONS_GOBLIN:
- case MONS_ORC_WARRIOR:
- return 30;
-
- case MONS_HOBGOBLIN:
- case MONS_OGRE:
- return 20;
-
- case MONS_TROLL:
- case MONS_WARG:
- return 13;
-
- case MONS_FUNGUS:
- case MONS_ORC_KNIGHT:
- case MONS_ORC_PRIEST:
- case MONS_ORC_SORCERER:
- case MONS_ORC_WIZARD:
- return 10;
-
- case MONS_ORC_WARLORD:
- case MONS_ORC_HIGH_PRIEST:
- case MONS_CYCLOPS:
- case MONS_TWO_HEADED_OGRE:
- return 5;
-
- case MONS_ETTIN:
- case MONS_IRON_TROLL:
- case MONS_ROCK_TROLL:
- case MONS_STONE_GIANT:
- return 3;
-
- case MONS_GNOLL:
- return 2;
-
- case MONS_OGRE_MAGE:
- return 1;
-
- default:
- return 0;
- }
-} // end mons_mineorc_rare()
-
-static int mons_hive_level(int mcls)
-{
- int mlev = you.branch_stairs[STAIRS_HIVE] + 1;
-
- switch (mcls)
- {
- case MONS_PLANT:
- case MONS_KILLER_BEE:
- mlev += 0;
- break;
-
- case MONS_KILLER_BEE_LARVA:
- mlev += 2;
- break;
-
- default:
- return 99;
- }
-
- return (mlev);
-} // end mons_hive_level()
-
-static int mons_hive_rare(int mcls)
-{
- switch (mcls)
- {
- case MONS_KILLER_BEE:
- return 300;
-
- case MONS_PLANT:
- return 100;
-
- case MONS_KILLER_BEE_LARVA:
- return 50;
-
- default:
- return 0;
- }
-} // end mons_hive_rare()
-
-static int mons_lair_level(int mcls)
-{
- int mlev = you.branch_stairs[STAIRS_LAIR] + 1;
-
- switch (mcls)
- {
- case MONS_GIANT_GECKO:
- case MONS_GIANT_BAT:
- case MONS_JACKAL:
- case MONS_GIANT_NEWT:
- case MONS_RAT:
- case MONS_QUOKKA:
- mlev += 0;
- break;
-
- case MONS_GIANT_CENTIPEDE:
- case MONS_GIANT_IGUANA:
- mlev++;
- break;
-
- case MONS_GIANT_FROG:
- case MONS_GILA_MONSTER:
- case MONS_GREY_RAT:
- case MONS_HOUND:
- case MONS_BLACK_BEAR:
- mlev += 2;
- break;
-
- case MONS_WORM:
- case MONS_WOLF:
- mlev += 3;
- break;
-
- case MONS_FUNGUS:
- case MONS_GIANT_BROWN_FROG:
- case MONS_GIANT_LIZARD:
- case MONS_GIANT_MITE:
- case MONS_GREEN_RAT:
- case MONS_SCORPION:
- case MONS_SNAKE:
- mlev += 4;
- break;
-
- case MONS_BROWN_SNAKE:
- case MONS_BUTTERFLY:
- case MONS_GIANT_BEETLE:
- case MONS_GIANT_SLUG:
- case MONS_HIPPOGRIFF:
- case MONS_PLANT:
- case MONS_SPINY_FROG:
- case MONS_WAR_DOG:
- case MONS_YELLOW_WASP:
- case MONS_BEAR:
- mlev += 5;
- break;
-
- case MONS_BLINK_FROG:
- case MONS_GIANT_SNAIL:
- case MONS_GIANT_SPORE:
- case MONS_KOMODO_DRAGON:
- case MONS_ORANGE_RAT:
- case MONS_SHEEP:
- case MONS_STEAM_DRAGON:
- case MONS_WOLF_SPIDER:
- case MONS_YAK:
- case MONS_GRIZZLY_BEAR:
- mlev += 6;
- break;
-
- case MONS_BLACK_SNAKE:
- case MONS_BRAIN_WORM:
- case MONS_BUMBLEBEE:
- case MONS_FIREDRAKE:
- case MONS_HYDRA:
- case MONS_OKLOB_PLANT:
- case MONS_WYVERN:
- mlev += 7;
- break;
-
- case MONS_ELEPHANT_SLUG:
- case MONS_POLAR_BEAR:
- case MONS_GRIFFON:
- case MONS_LINDWURM:
- case MONS_REDBACK:
- case MONS_WANDERING_MUSHROOM:
- mlev += 8;
- break;
-
- case MONS_BORING_BEETLE:
- case MONS_BOULDER_BEETLE:
- case MONS_DEATH_YAK:
- case MONS_SPINY_WORM:
- mlev += 9;
- break;
-
- default:
- return 99;
- }
-
- return (mlev);
-} // end mons_lair_level()
-
-static int mons_lair_rare(int mcls)
-{
- switch (mcls)
- {
- case MONS_RAT:
- return 200;
-
- case MONS_GIANT_BAT:
- case MONS_GIANT_BROWN_FROG:
- case MONS_GIANT_FROG:
- case MONS_GREY_RAT:
- case MONS_QUOKKA:
- return 99;
-
- case MONS_BROWN_SNAKE:
- case MONS_GIANT_LIZARD:
- return 90;
-
- case MONS_PLANT:
- case MONS_SNAKE:
- return 80;
-
- case MONS_SPINY_FROG:
- return 75;
-
- case MONS_JACKAL:
- case MONS_GIANT_IGUANA:
- case MONS_GILA_MONSTER:
- return 70;
-
- case MONS_GREEN_RAT:
- return 64;
-
- case MONS_HOUND:
- return 60;
-
- case MONS_GIANT_SNAIL:
- return 56;
-
- case MONS_GIANT_SLUG:
- return 55;
-
- case MONS_FUNGUS:
- case MONS_GIANT_GECKO:
- case MONS_GIANT_CENTIPEDE:
- case MONS_HIPPOGRIFF:
- case MONS_HYDRA:
- case MONS_KOMODO_DRAGON:
- case MONS_YAK:
- return 50;
-
- case MONS_BLACK_SNAKE:
- return 47;
-
- case MONS_BLINK_FROG:
- return 45;
-
- case MONS_SHEEP:
- case MONS_FIREDRAKE:
- return 36;
-
- case MONS_WAR_DOG:
- return 35;
-
- case MONS_WORM:
- case MONS_GIANT_MITE:
- case MONS_GRIFFON:
- case MONS_DEATH_YAK:
- case MONS_ELEPHANT_SLUG:
- return 30;
-
- case MONS_BORING_BEETLE:
- return 29;
-
- case MONS_BOULDER_BEETLE:
- case MONS_GIANT_NEWT:
- case MONS_WOLF:
- case MONS_WYVERN:
- return 20;
-
- case MONS_BLACK_BEAR:
- case MONS_BEAR:
- case MONS_GRIZZLY_BEAR:
- case MONS_POLAR_BEAR:
- return 15;
-
- case MONS_GIANT_BEETLE:
- case MONS_SCORPION:
- case MONS_OKLOB_PLANT:
- case MONS_STEAM_DRAGON:
- case MONS_LINDWURM:
- case MONS_ORANGE_RAT:
- return 10;
-
- case MONS_SPINY_WORM:
- return 9;
-
- case MONS_WANDERING_MUSHROOM:
- case MONS_REDBACK:
- return 8;
-
- case MONS_BRAIN_WORM:
- case MONS_BUMBLEBEE:
- return 7;
-
- case MONS_WOLF_SPIDER:
- return 6;
-
- case MONS_YELLOW_WASP:
- case MONS_BUTTERFLY:
- return 5;
-
- case MONS_GIANT_SPORE:
- return 2;
-
- default:
- return 0;
- }
-} // end mons_lair_rare()
-
-static int mons_pitslime_level(int mcls)
-{
- int mlev = you.branch_stairs[STAIRS_SLIME_PITS] + 1;
-
-
- switch (mcls)
- {
- case MONS_JELLY:
- case MONS_OOZE:
- case MONS_ACID_BLOB:
- case MONS_GIANT_SPORE:
- case MONS_GIANT_EYEBALL:
- mlev++;
- break;
-
- case MONS_BROWN_OOZE:
- case MONS_SLIME_CREATURE:
- case MONS_EYE_OF_DRAINING:
- mlev += 2;
- break;
-
- case MONS_GIANT_AMOEBA:
- case MONS_AZURE_JELLY:
- case MONS_SHINING_EYE:
- mlev += 3;
- break;
-
- case MONS_PULSATING_LUMP:
- case MONS_GREAT_ORB_OF_EYES:
- case MONS_EYE_OF_DEVASTATION:
- mlev += 4;
- break;
-
- case MONS_DEATH_OOZE:
- case MONS_TENTACLED_MONSTROSITY:
- case MONS_GIANT_ORANGE_BRAIN:
- mlev += 5;
- break;
-
- default:
- mlev += 0;
- break;
- }
-
- return (mlev);
-} // end mons_pitslime_level()
-
-static int mons_pitslime_rare(int mcls)
-{
- switch (mcls)
- {
- case MONS_JELLY:
- return 300;
-
- case MONS_SLIME_CREATURE:
- return 200;
-
- case MONS_BROWN_OOZE:
- return 150;
-
- case MONS_GIANT_AMOEBA:
- case MONS_ACID_BLOB:
- return 100;
-
- case MONS_OOZE:
- case MONS_AZURE_JELLY:
- case MONS_GIANT_SPORE:
- case MONS_GIANT_EYEBALL:
- case MONS_EYE_OF_DRAINING:
- case MONS_SHINING_EYE:
- return 50;
-
- case MONS_DEATH_OOZE:
- case MONS_GREAT_ORB_OF_EYES:
- case MONS_EYE_OF_DEVASTATION:
- return 30;
-
- case MONS_PULSATING_LUMP:
- case MONS_GIANT_ORANGE_BRAIN:
- return 20;
-
- case MONS_TENTACLED_MONSTROSITY:
- return 2;
-
- default:
- return 0;
- }
-} // end mons_pitslime_rare()
-
-static int mons_crypt_level(int mcls)
-{
- int mlev = you.branch_stairs[STAIRS_CRYPT] + 1;
-
- switch (mcls)
- {
- case MONS_ZOMBIE_SMALL:
- mlev += 0;
- break;
-
- case MONS_PHANTOM:
- case MONS_SKELETON_SMALL:
- case MONS_SKELETON_LARGE:
- case MONS_ZOMBIE_LARGE:
- case MONS_WIGHT:
- mlev++;
- break;
-
- case MONS_SHADOW:
- case MONS_HUNGRY_GHOST:
- case MONS_NECROPHAGE:
- case MONS_SKELETAL_WARRIOR:
- case MONS_SIMULACRUM_SMALL:
- case MONS_SIMULACRUM_LARGE:
- mlev += 2;
- break;
-
- case MONS_NECROMANCER:
- case MONS_PULSATING_LUMP:
- case MONS_FLAYED_GHOST:
- case MONS_GHOUL:
- case MONS_ROTTING_HULK:
- case MONS_WRAITH:
- case MONS_FLYING_SKULL:
- mlev += 3;
- break;
-
- case MONS_SPECTRAL_WARRIOR:
- case MONS_SHADOW_WRAITH:
- case MONS_VAMPIRE_KNIGHT:
- case MONS_VAMPIRE_MAGE:
- case MONS_SKELETAL_DRAGON:
- case MONS_ABOMINATION_SMALL:
- case MONS_MUMMY:
- case MONS_VAMPIRE:
- case MONS_ABOMINATION_LARGE:
- mlev += 4;
- break;
-
- case MONS_REAPER:
- case MONS_ANCIENT_LICH:
- case MONS_LICH:
- mlev += 5;
- break;
-
- default:
- mlev += 99;
- }
-
- return (mlev);
-} // end mons_crypt_level()
-
-static int mons_crypt_rare(int mcls)
-{
- switch (mcls)
- {
- case MONS_ZOMBIE_SMALL:
- case MONS_SKELETON_SMALL:
- case MONS_SKELETON_LARGE:
- return 410;
-
- case MONS_ZOMBIE_LARGE:
- return 300;
-
- case MONS_SKELETAL_WARRIOR:
- return 75;
-
- case MONS_NECROPHAGE:
- return 50;
-
- case MONS_WIGHT:
- return 35;
-
- case MONS_WRAITH:
- return 33;
-
- case MONS_SHADOW:
- return 30;
-
- case MONS_NECROMANCER:
- case MONS_GHOUL:
- return 25;
-
- case MONS_MUMMY:
- case MONS_SKELETAL_DRAGON:
- return 24;
-
- case MONS_VAMPIRE:
- case MONS_PHANTOM:
- return 21;
-
- case MONS_VAMPIRE_KNIGHT:
- case MONS_VAMPIRE_MAGE:
- return 20;
-
- case MONS_ROTTING_HULK:
- return 17;
-
- case MONS_SPECTRAL_WARRIOR:
- return 14;
-
- case MONS_FLYING_SKULL:
- case MONS_FLAYED_GHOST:
- return 13;
-
- case MONS_HUNGRY_GHOST:
- return 12;
-
- case MONS_SHADOW_WRAITH:
- case MONS_SIMULACRUM_SMALL:
- case MONS_SIMULACRUM_LARGE:
- return 10;
-
- case MONS_ANCIENT_LICH:
- return 8;
-
- case MONS_ABOMINATION_SMALL:
- case MONS_LICH:
- case MONS_REAPER:
- return 5;
-
- case MONS_ABOMINATION_LARGE:
- return 4;
-
- case MONS_PULSATING_LUMP:
- return 3;
-
- default:
- return 0;
- }
-} // end mons_crypt_rare()
-
-static int mons_pitsnake_level(int mcls)
-{
- int mlev = you.branch_stairs[STAIRS_SNAKE_PIT] + 1;
-
- switch (mcls)
- {
- case MONS_SMALL_SNAKE:
- case MONS_SNAKE:
- mlev++;
- break;
-
- case MONS_BROWN_SNAKE:
- case MONS_BLACK_SNAKE:
- case MONS_YELLOW_SNAKE:
- case MONS_GREY_SNAKE:
- case MONS_NAGA:
- mlev += 2;
- break;
-
- case MONS_NAGA_WARRIOR:
- case MONS_NAGA_MAGE:
- mlev += 3;
- break;
-
- case MONS_GUARDIAN_NAGA:
- mlev += 4;
- break;
-
- case MONS_GREATER_NAGA:
- mlev += 5;
- break;
-
- default:
- mlev += 99;
- }
-
- return (mlev);
-} // end mons_pitsnake_level()
-
-static int mons_pitsnake_rare(int mcls)
-{
- switch (mcls)
- {
- case MONS_SNAKE:
- case MONS_BROWN_SNAKE:
- return 99;
-
- case MONS_BLACK_SNAKE:
- return 72;
-
- case MONS_NAGA:
- return 53;
-
- case MONS_NAGA_WARRIOR:
- case MONS_NAGA_MAGE:
- return 34;
-
- case MONS_YELLOW_SNAKE:
- case MONS_GREY_SNAKE:
- return 32;
-
- case MONS_GREATER_NAGA:
- case MONS_GUARDIAN_NAGA:
- case MONS_SMALL_SNAKE:
- return 15;
-
- default:
- return 0;
- }
-} // end mons_pitsnake_rare()
-
-static int mons_hallelf_level(int mcls)
-{
- int mlev = you.branch_stairs[STAIRS_ELVEN_HALLS] + 1;
-
- switch (mcls)
- {
- case MONS_DEEP_ELF_SOLDIER:
- case MONS_DEEP_ELF_FIGHTER:
- case MONS_ORC:
- case MONS_ORC_WARRIOR:
- mlev++;
- break;
-
- case MONS_ORC_WIZARD:
- case MONS_DEEP_ELF_MAGE:
- case MONS_DEEP_ELF_SUMMONER:
- mlev += 2;
- break;
-
- case MONS_FUNGUS:
- case MONS_DEEP_ELF_CONJURER:
- case MONS_SHAPESHIFTER:
- case MONS_ORC_KNIGHT:
- mlev += 3;
- break;
-
- case MONS_ORC_SORCERER:
- case MONS_DEEP_ELF_PRIEST:
- case MONS_GLOWING_SHAPESHIFTER:
- case MONS_DEEP_ELF_KNIGHT:
- mlev += 4;
- break;
-
- case MONS_ORC_PRIEST:
- case MONS_ORC_HIGH_PRIEST:
- mlev += 5;
- break;
-
- case MONS_DEEP_ELF_HIGH_PRIEST:
- case MONS_DEEP_ELF_DEMONOLOGIST:
- case MONS_DEEP_ELF_ANNIHILATOR:
- case MONS_DEEP_ELF_SORCERER:
- case MONS_DEEP_ELF_DEATH_MAGE:
- mlev += 7;
- break;
-
- default:
- mlev += 99;
- break;
- }
-
- return (mlev);
-} // end mons_hallelf_level()
-
-static int mons_hallelf_rare(int mcls)
-{
- switch (mcls)
- {
- case MONS_FUNGUS:
- return 300;
-
- case MONS_DEEP_ELF_SOLDIER:
- case MONS_DEEP_ELF_FIGHTER:
- case MONS_DEEP_ELF_MAGE:
- return 100;
-
- case MONS_DEEP_ELF_KNIGHT:
- return 80;
-
- case MONS_DEEP_ELF_SUMMONER:
- return 72;
-
- case MONS_DEEP_ELF_CONJURER:
- return 63;
-
- case MONS_DEEP_ELF_PRIEST:
- return 44;
-
- case MONS_SHAPESHIFTER:
- return 25;
-
- case MONS_ORC:
- return 20;
-
- case MONS_DEEP_ELF_DEMONOLOGIST:
- case MONS_DEEP_ELF_SORCERER:
- return 17;
-
- case MONS_DEEP_ELF_ANNIHILATOR:
- case MONS_DEEP_ELF_DEATH_MAGE:
- case MONS_ORC_WIZARD:
- return 13;
-
- case MONS_ORC_WARRIOR:
- return 11;
-
- case MONS_DEEP_ELF_HIGH_PRIEST:
- case MONS_ORC_SORCERER:
- case MONS_GLOWING_SHAPESHIFTER:
- return 10;
-
- case MONS_ORC_KNIGHT:
- case MONS_ORC_PRIEST:
- case MONS_ORC_HIGH_PRIEST:
- return 5;
-
- default:
- return 0;
- }
-} // end mons_hallelf_rare()
-
-static int mons_tomb_level(int mcls)
-{
- int mlev = you.branch_stairs[STAIRS_CRYPT] + 1;
-
- switch (mcls)
- {
- case MONS_ZOMBIE_SMALL:
- mlev += 0;
- break;
-
- case MONS_MUMMY:
- case MONS_ZOMBIE_LARGE:
- case MONS_SKELETON_SMALL:
- case MONS_SKELETON_LARGE:
- mlev++;
- break;
-
- case MONS_GUARDIAN_MUMMY:
- case MONS_FLYING_SKULL:
- case MONS_SIMULACRUM_SMALL:
- case MONS_SIMULACRUM_LARGE:
- mlev += 2;
- break;
-
- case MONS_LICH:
- case MONS_ANCIENT_LICH:
- case MONS_MUMMY_PRIEST:
- mlev += 3;
- break;
-
- default:
- mlev += 99;
- }
-
- return (mlev);
-} // end mons_tomb_level()
-
-static int mons_tomb_rare(int mcls)
-{
- switch (mcls)
- {
- case MONS_MUMMY:
- return 300;
-
- case MONS_GUARDIAN_MUMMY:
- return 202;
-
- case MONS_MUMMY_PRIEST:
- return 40;
-
- case MONS_FLYING_SKULL:
- return 33;
-
- case MONS_ZOMBIE_LARGE:
- case MONS_SKELETON_SMALL:
- case MONS_SKELETON_LARGE:
- return 21;
-
- case MONS_ZOMBIE_SMALL:
- return 20;
-
- case MONS_SIMULACRUM_SMALL:
- case MONS_SIMULACRUM_LARGE:
- return 10;
-
- case MONS_LICH:
- return 4;
-
- case MONS_ANCIENT_LICH:
- return 2;
-
- default:
- return 0;
- }
-} // end mons_tomb_rare()
-
-static int mons_swamp_level(int mcls)
-{
- int mlev = you.branch_stairs[STAIRS_SWAMP] + 1;
-
- switch (mcls)
- {
- case MONS_GIANT_BAT:
- case MONS_GIANT_BLOWFLY:
- case MONS_GIANT_FROG:
- case MONS_GIANT_AMOEBA:
- case MONS_GIANT_SLUG:
- case MONS_GIANT_NEWT:
- case MONS_GIANT_GECKO:
- case MONS_RAT:
- case MONS_SWAMP_DRAKE:
- case MONS_WORM:
- mlev++;
- break;
-
- case MONS_GIANT_BROWN_FROG:
- case MONS_FUNGUS:
- case MONS_NECROPHAGE:
- case MONS_PLANT:
- case MONS_SNAKE:
- case MONS_BUTTERFLY:
- case MONS_GIANT_LIZARD:
- case MONS_GIANT_MOSQUITO:
- case MONS_GIANT_SNAIL:
- case MONS_HYDRA:
- mlev += 2;
- break;
-
- case MONS_BROWN_SNAKE:
- case MONS_HUNGRY_GHOST:
- case MONS_INSUBSTANTIAL_WISP:
- case MONS_JELLY:
- case MONS_KOMODO_DRAGON:
- case MONS_PHANTOM:
- case MONS_RED_WASP:
- case MONS_SPINY_FROG:
- case MONS_SWAMP_DRAGON:
- case MONS_UGLY_THING:
- mlev += 3;
- break;
-
- case MONS_BLINK_FROG:
- case MONS_SLIME_CREATURE:
- case MONS_VERY_UGLY_THING:
- case MONS_VAPOUR:
- case MONS_TENTACLED_MONSTROSITY:
- mlev += 4;
- break;
-
- default:
- mlev += 99;
- }
-
- return (mlev);
-} // end mons_swamp_level()
-
-static int mons_swamp_rare(int mcls)
-{
- switch (mcls)
- {
- case MONS_GIANT_MOSQUITO:
- return 250;
-
- case MONS_PLANT:
- return 200;
-
- case MONS_GIANT_FROG:
- return 150;
-
- case MONS_GIANT_BLOWFLY:
- return 100;
-
- case MONS_GIANT_BAT:
- case MONS_FUNGUS:
- return 99;
-
- case MONS_GIANT_BROWN_FROG:
- return 90;
-
- case MONS_SWAMP_DRAKE:
- return 80;
-
- case MONS_HYDRA:
- return 70;
-
- case MONS_RAT:
- return 61;
-
- case MONS_SLIME_CREATURE:
- return 54;
-
- case MONS_SNAKE:
- return 52;
-
- case MONS_INSUBSTANTIAL_WISP:
- return 43;
-
- case MONS_BROWN_SNAKE:
- return 33;
-
- case MONS_RED_WASP:
- case MONS_SWAMP_DRAGON:
- case MONS_SPINY_FROG:
- return 30;
-
- case MONS_JELLY:
- case MONS_BUTTERFLY:
- case MONS_GIANT_LIZARD:
- return 25;
-
- case MONS_WORM:
- return 20;
-
- case MONS_KOMODO_DRAGON:
- case MONS_VERY_UGLY_THING:
- case MONS_VAPOUR:
- return 15;
-
- case MONS_PHANTOM:
- case MONS_UGLY_THING:
- case MONS_HUNGRY_GHOST:
- return 13;
-
- case MONS_NECROPHAGE:
- return 12;
-
- case MONS_BLINK_FROG:
- case MONS_GIANT_AMOEBA:
- case MONS_GIANT_GECKO:
- case MONS_GIANT_NEWT:
- case MONS_GIANT_SLUG:
- case MONS_GIANT_SNAIL:
- return 10;
-
- case MONS_TENTACLED_MONSTROSITY:
- return 5;
-
- default:
- return 0;
- }
-} // end mons_swamp_rare()
-
-static int mons_hallblade_level(int mcls)
-{
- if (mcls == MONS_DANCING_WEAPON)
- return (you.branch_stairs[STAIRS_HALL_OF_BLADES] + 1);
- else
- return 0;
-} // end mons_hallblade_level
-
-static int mons_hallblade_rare(int mcls)
-{
- return ((mcls == MONS_DANCING_WEAPON) ? 1000 : 0);
-} // end mons_hallblade_rare()
-
-// New branch must be added in:
-// - new_game stair location
-// - down/up stairs (to and back) misc.cc
-// - new_level (2 places) (misc.cc)
-// - item_check items.cc
-// - look_around (direct.cc)
-// - ouch ouch.cc (death message)
-// - and here...
-
-static int mons_hallzot_level(int mcls)
-{
- int mlev = you.branch_stairs[STAIRS_HALL_OF_ZOT];
-
- switch (mcls)
- {
- case MONS_GOLDEN_DRAGON:
- case MONS_GUARDIAN_MUMMY:
- mlev += 6;
- break;
- case MONS_KILLER_KLOWN:
- case MONS_SHADOW_DRAGON:
- case MONS_SKELETAL_DRAGON:
- case MONS_STORM_DRAGON:
- mlev += 5;
- break;
- case MONS_DEATH_COB:
- case MONS_DRAGON:
- case MONS_ICE_DRAGON:
- mlev += 4;
- break;
- case MONS_DEEP_ELF_ANNIHILATOR:
- case MONS_DEEP_ELF_DEATH_MAGE:
- case MONS_DEEP_ELF_DEMONOLOGIST:
- case MONS_DEEP_ELF_HIGH_PRIEST:
- case MONS_DEEP_ELF_SORCERER:
- case MONS_TENTACLED_MONSTROSITY:
- mlev += 3;
- break;
- case MONS_MOTH_OF_WRATH:
- mlev += 2;
- break;
- case MONS_ORB_OF_FIRE:
- case MONS_ELECTRIC_GOLEM:
- mlev += 1;
- break;
- default:
- mlev += 99; // I think this won't be a problem {dlb}
- break;
- }
-
- return (mlev);
-} // end mons_hallzot_level()
-
-static int mons_hallzot_rare(int mcls)
-{
- switch (mcls)
- {
- case MONS_MOTH_OF_WRATH:
- return 88;
- case MONS_STORM_DRAGON:
- case MONS_TENTACLED_MONSTROSITY:
- return 50;
- case MONS_GOLDEN_DRAGON:
- return 42;
- case MONS_DEATH_COB:
- case MONS_DRAGON:
- case MONS_ICE_DRAGON:
- case MONS_SKELETAL_DRAGON:
- return 40;
- case MONS_SHADOW_DRAGON:
- case MONS_DEATH_DRAKE:
- return 30;
- case MONS_DEEP_ELF_ANNIHILATOR:
- case MONS_DEEP_ELF_DEATH_MAGE:
- case MONS_DEEP_ELF_DEMONOLOGIST:
- case MONS_DEEP_ELF_HIGH_PRIEST:
- case MONS_DEEP_ELF_SORCERER:
- return 29;
- case MONS_GUARDIAN_MUMMY:
- case MONS_ELECTRIC_GOLEM:
- return 20;
- case MONS_KILLER_KLOWN:
- case MONS_ORB_OF_FIRE:
- return 15;
- default:
- return 0;
- }
-} // end mons_hallzot_rare()
-
-static int mons_caverns_level( int mcls )
-{
-
- int mlev = you.branch_stairs[STAIRS_CAVERNS] + 1;
-
- switch (mcls)
- {
- case MONS_YELLOW_DRACONIAN:
- case MONS_BLACK_DRACONIAN:
- case MONS_WHITE_DRACONIAN:
- case MONS_RED_DRACONIAN:
- case MONS_PURPLE_DRACONIAN:
- case MONS_PALE_DRACONIAN:
- case MONS_GREEN_DRACONIAN:
- case MONS_MOTTLED_DRACONIAN:
- mlev++;
- break;
-
- case MONS_DRACONIAN_CALLER:
- case MONS_DRACONIAN_MONK:
- case MONS_DRACONIAN_SCORCHER:
- case MONS_DRACONIAN_KNIGHT:
- case MONS_DRACONIAN_ANNIHILATOR:
- case MONS_DRACONIAN_ZEALOT:
- case MONS_DRACONIAN_SHIFTER:
- mlev += 3;
- break;
-
- default:
- mlev += 99;
- break;
- }
-
- return (mlev);
-}
-
-static int mons_caverns_rare( int mcls )
-{
- switch (mcls)
- {
- case MONS_YELLOW_DRACONIAN:
- case MONS_BLACK_DRACONIAN:
- case MONS_WHITE_DRACONIAN:
- case MONS_RED_DRACONIAN:
- case MONS_PURPLE_DRACONIAN:
- case MONS_PALE_DRACONIAN:
- case MONS_GREEN_DRACONIAN:
- case MONS_MOTTLED_DRACONIAN:
- case MONS_DRACONIAN_CALLER:
- case MONS_DRACONIAN_MONK:
- case MONS_DRACONIAN_SCORCHER:
- case MONS_DRACONIAN_KNIGHT:
- case MONS_DRACONIAN_ANNIHILATOR:
- case MONS_DRACONIAN_ZEALOT:
- case MONS_DRACONIAN_SHIFTER:
- return (500);
-
- default:
- return (0);
- }
-}
-
-static int mons_standard_level(int mcls)
-{
- switch (mcls)
- {
- case MONS_GOBLIN:
- case MONS_GIANT_NEWT:
- return 1;
-
- case MONS_GIANT_COCKROACH:
- case MONS_OOZE:
- case MONS_SMALL_SNAKE:
- return 2;
-
- case MONS_GIANT_BAT:
- case MONS_KOBOLD:
- case MONS_RAT:
- return 4;
-
- case MONS_GIANT_GECKO:
- case MONS_GIANT_MITE:
- case MONS_GNOLL:
- case MONS_HOBGOBLIN:
- case MONS_JACKAL:
- case MONS_KILLER_BEE_LARVA:
- return 5;
-
- case MONS_WORM:
- case MONS_SNAKE:
- case MONS_QUOKKA:
- return 6;
-
- case MONS_ORC:
- return 7;
-
- case MONS_FUNGUS:
- case MONS_GIANT_ANT:
- case MONS_GIANT_EYEBALL:
- case MONS_HOUND:
- case MONS_GIANT_IGUANA:
- case MONS_OGRE:
- case MONS_ORC_WIZARD:
- case MONS_PHANTOM:
- case MONS_SCORPION:
- return 8;
-
- case MONS_BROWN_SNAKE:
- case MONS_CENTAUR:
- case MONS_ICE_BEAST:
- case MONS_IMP:
- case MONS_JELLY:
- case MONS_NECROPHAGE:
- case MONS_QUASIT:
- case MONS_ZOMBIE_SMALL:
- return 9;
-
- case MONS_DEEP_ELF_SOLDIER:
- case MONS_GIANT_BEETLE:
- case MONS_GIANT_FROG:
- case MONS_GIANT_SPORE:
- case MONS_MUMMY:
- case MONS_ORC_WARRIOR:
- case MONS_STEAM_DRAGON:
- case MONS_WIGHT:
- return 10;
-
- case MONS_GIANT_LIZARD:
- case MONS_HIPPOGRIFF:
- case MONS_HUNGRY_GHOST:
- case MONS_KILLER_BEE:
- case MONS_SHADOW:
- case MONS_YELLOW_WASP:
- return 11;
-
- case MONS_EYE_OF_DRAINING:
- case MONS_GILA_MONSTER:
- case MONS_MANTICORE:
- case MONS_PLANT:
- case MONS_UNSEEN_HORROR:
- case MONS_WYVERN:
- return 12;
-
- case MONS_BIG_KOBOLD:
- case MONS_GIANT_BROWN_FROG:
- case MONS_GIANT_CENTIPEDE:
- case MONS_OKLOB_PLANT:
- case MONS_TROLL:
- case MONS_TWO_HEADED_OGRE:
- case MONS_WOOD_GOLEM:
- case MONS_YAK:
- return 13;
-
- case MONS_HILL_GIANT:
- case MONS_KOMODO_DRAGON:
- case MONS_SOLDIER_ANT:
- case MONS_WOLF_SPIDER:
- case MONS_WRAITH:
- return 14;
-
- case MONS_ARMOUR_MIMIC:
- case MONS_BRAIN_WORM:
- case MONS_CYCLOPS:
- case MONS_EFREET:
- case MONS_ETTIN:
- case MONS_EYE_OF_DEVASTATION:
- case MONS_GOLD_MIMIC:
- case MONS_HYDRA:
- case MONS_MOTTLED_DRAGON:
- case MONS_ORC_PRIEST:
- case MONS_POTION_MIMIC:
- case MONS_SCROLL_MIMIC:
- case MONS_SKELETAL_WARRIOR:
- case MONS_WEAPON_MIMIC:
- return 15;
-
- case MONS_BLINK_FROG:
- case MONS_BUTTERFLY:
- case MONS_GIANT_BLOWFLY:
- case MONS_GUARDIAN_NAGA:
- case MONS_RAKSHASA:
- case MONS_SLIME_CREATURE:
- case MONS_STONE_GOLEM:
- case MONS_VAMPIRE:
- case MONS_WANDERING_MUSHROOM:
- case MONS_ZOMBIE_LARGE:
- return 16;
-
- case MONS_BOGGART:
- case MONS_CENTAUR_WARRIOR:
- case MONS_CLAY_GOLEM:
- case MONS_GRIFFON:
- case MONS_SHAPESHIFTER:
- case MONS_UGLY_THING:
- case MONS_WIZARD:
- case MONS_SIMULACRUM_SMALL:
- case MONS_SIMULACRUM_LARGE:
- return 17;
-
- case MONS_DRAGON:
- case MONS_GARGOYLE:
- case MONS_GIANT_AMOEBA:
- case MONS_KOBOLD_DEMONOLOGIST:
- case MONS_YELLOW_DRACONIAN:
- case MONS_BLACK_DRACONIAN:
- case MONS_WHITE_DRACONIAN:
- case MONS_RED_DRACONIAN:
- case MONS_PURPLE_DRACONIAN:
- case MONS_PALE_DRACONIAN:
- case MONS_GREEN_DRACONIAN:
- case MONS_MOTTLED_DRACONIAN:
- return 18;
-
- case MONS_GIANT_SLUG:
- case MONS_IRON_GOLEM:
- case MONS_OGRE_MAGE:
- case MONS_ROCK_TROLL:
- case MONS_TOENAIL_GOLEM:
- case MONS_YAKTAUR:
- return 19;
-
- case MONS_AIR_ELEMENTAL:
- case MONS_DEEP_ELF_FIGHTER:
- case MONS_DEEP_ELF_KNIGHT:
- case MONS_DEEP_ELF_MAGE:
- case MONS_DEEP_ELF_SUMMONER:
- case MONS_EARTH_ELEMENTAL:
- case MONS_FIRE_ELEMENTAL:
- case MONS_GIANT_ORANGE_BRAIN:
- case MONS_GIANT_SNAIL:
- case MONS_GREAT_ORB_OF_EYES:
- case MONS_ICE_DRAGON:
- case MONS_SKELETON_LARGE:
- case MONS_NAGA_MAGE:
- case MONS_NAGA_WARRIOR:
- case MONS_NECROMANCER:
- case MONS_ORC_KNIGHT:
- case MONS_QUEEN_BEE:
- case MONS_RED_WASP:
- case MONS_SHADOW_WRAITH:
- case MONS_SKELETON_SMALL:
- case MONS_SPINY_WORM:
- case MONS_VERY_UGLY_THING:
- return 20;
-
- case MONS_BOULDER_BEETLE:
- case MONS_ORC_HIGH_PRIEST:
- case MONS_PULSATING_LUMP:
- return 21;
-
- case MONS_BORING_BEETLE:
- case MONS_CRYSTAL_GOLEM:
- case MONS_FLAYED_GHOST:
- case MONS_FREEZING_WRAITH:
- case MONS_REDBACK:
- case MONS_SPHINX:
- case MONS_VAPOUR:
- case MONS_DRACONIAN_CALLER:
- case MONS_DRACONIAN_MONK:
- case MONS_DRACONIAN_SCORCHER:
- case MONS_DRACONIAN_KNIGHT:
- case MONS_DRACONIAN_ANNIHILATOR:
- case MONS_DRACONIAN_ZEALOT:
- case MONS_DRACONIAN_SHIFTER:
- return 22;
-
- case MONS_ORC_SORCERER:
- case MONS_SHINING_EYE:
- return 23;
-
- case MONS_BUMBLEBEE:
- case MONS_ORC_WARLORD:
- case MONS_IRON_TROLL:
- case MONS_YAKTAUR_CAPTAIN:
- return 24;
-
- case MONS_DANCING_WEAPON:
- case MONS_DEEP_TROLL:
- case MONS_FIRE_GIANT:
- case MONS_FROST_GIANT:
- case MONS_HELL_KNIGHT:
- case MONS_INSUBSTANTIAL_WISP:
- case MONS_LICH:
- case MONS_STONE_GIANT:
- return 25;
-
- case MONS_DEEP_ELF_CONJURER:
- case MONS_SPECTRAL_WARRIOR:
- case MONS_STORM_DRAGON:
- return 26;
-
- case MONS_DEEP_ELF_PRIEST:
- case MONS_GLOWING_SHAPESHIFTER:
- case MONS_TENTACLED_MONSTROSITY:
- return 27;
-
- case MONS_ANCIENT_LICH:
- case MONS_DEEP_ELF_ANNIHILATOR:
- case MONS_DEEP_ELF_DEATH_MAGE:
- case MONS_DEEP_ELF_DEMONOLOGIST:
- case MONS_DEEP_ELF_HIGH_PRIEST:
- case MONS_DEEP_ELF_SORCERER:
- case MONS_GOLDEN_DRAGON:
- case MONS_IRON_DRAGON:
- case MONS_QUICKSILVER_DRAGON:
- case MONS_SHADOW_DRAGON:
- case MONS_SKELETAL_DRAGON:
- case MONS_TITAN:
- return 30;
-
- case MONS_BIG_FISH:
- case MONS_ELECTRICAL_EEL:
- case MONS_GIANT_GOLDFISH:
- case MONS_JELLYFISH:
- case MONS_LAVA_FISH:
- case MONS_LAVA_SNAKE:
- case MONS_LAVA_WORM:
- case MONS_SWAMP_WORM:
- case MONS_WATER_ELEMENTAL:
- return 500;
-
- default:
- return 99;
- }
-} // end mons_standard_level()
-
-static int mons_standard_rare(int mcls)
-{
- switch (mcls)
- {
-// "another lava thing" has no stats! (GDL)
-// case MONS_ANOTHER_LAVA_THING:
- case MONS_BIG_FISH:
- case MONS_ELECTRICAL_EEL:
- case MONS_GIANT_GOLDFISH:
- case MONS_JELLYFISH:
- case MONS_LAVA_FISH:
- case MONS_LAVA_SNAKE:
- case MONS_LAVA_WORM:
- case MONS_SWAMP_WORM:
- case MONS_WATER_ELEMENTAL:
- case MONS_SALAMANDER:
- return 500;
-
- case MONS_GIANT_BAT:
- case MONS_GIANT_FROG:
- case MONS_GOBLIN:
- case MONS_HILL_GIANT:
- case MONS_HOBGOBLIN:
- case MONS_IMP:
- case MONS_KOBOLD:
- case MONS_SKELETON_LARGE:
- case MONS_ORC:
- case MONS_RAT:
- case MONS_RED_DEVIL:
- case MONS_SKELETON_SMALL:
- case MONS_UGLY_THING:
- case MONS_ZOMBIE_LARGE:
- case MONS_ZOMBIE_SMALL:
- return 99;
-
- case MONS_CENTAUR_WARRIOR:
- case MONS_GIANT_ANT:
- case MONS_SNAKE:
- return 80;
-
- case MONS_FLYING_SKULL:
- case MONS_SLIME_CREATURE:
- return 75;
-
- case MONS_HELL_HOUND:
- return 71;
-
- case MONS_CENTAUR:
- case MONS_CYCLOPS:
- case MONS_GIANT_BROWN_FROG:
- case MONS_HELLION:
- case MONS_HOUND:
- case MONS_OGRE:
- case MONS_ORC_WARRIOR:
- case MONS_TROLL:
- case MONS_YAK:
- case MONS_YAKTAUR_CAPTAIN:
- return 70;
-
- case MONS_JELLY:
- case MONS_ORC_KNIGHT:
- case MONS_ROTTING_DEVIL:
- return 60;
-
- case MONS_SHAPESHIFTER:
- return 59;
-
- case MONS_STONE_GIANT:
- return 53;
-
- case MONS_BIG_KOBOLD:
- case MONS_GIANT_BEETLE:
- case MONS_GIANT_BLOWFLY:
- case MONS_GIANT_COCKROACH:
- case MONS_GIANT_GECKO:
- case MONS_GIANT_IGUANA:
- case MONS_GIANT_NEWT:
- case MONS_HIPPOGRIFF:
- case MONS_HYDRA:
- case MONS_ICE_BEAST:
- case MONS_KILLER_BEE:
- case MONS_ORC_WIZARD:
- case MONS_QUOKKA:
- case MONS_SCORPION:
- case MONS_TORMENTOR:
- case MONS_UNSEEN_HORROR:
- case MONS_WORM:
- return 50;
-
- case MONS_ROCK_TROLL:
- return 48;
-
- case MONS_MANTICORE:
- case MONS_OGRE_MAGE:
- return 45;
-
- case MONS_HUNGRY_GHOST:
- case MONS_SHADOW:
- return 41;
-
- case MONS_GIANT_CENTIPEDE:
- case MONS_GIANT_EYEBALL:
- case MONS_GIANT_SPORE:
- case MONS_GRIFFON:
- case MONS_HAIRY_DEVIL:
- case MONS_JACKAL:
- case MONS_MOTTLED_DRAGON:
- case MONS_PHANTOM:
- case MONS_REAPER:
- case MONS_TWO_HEADED_OGRE:
- case MONS_WIGHT:
- case MONS_WRAITH:
- case MONS_WYVERN:
- case MONS_YAKTAUR:
- return 40;
-
- case MONS_WOLF_SPIDER:
- return 36;
-
- case MONS_FREEZING_WRAITH:
- case MONS_GIANT_AMOEBA:
- case MONS_GILA_MONSTER:
- case MONS_GLOWING_SHAPESHIFTER:
- case MONS_SOLDIER_ANT:
- return 35;
-
- case MONS_BOULDER_BEETLE:
- return 34;
-
- case MONS_EYE_OF_DRAINING:
- return 33;
-
- case MONS_GIANT_SLUG:
- return 32;
-
- case MONS_ARMOUR_MIMIC:
- case MONS_BROWN_SNAKE:
- case MONS_DRAGON:
- case MONS_ETTIN:
- case MONS_FIRE_VORTEX:
- case MONS_GIANT_LIZARD:
- case MONS_GIANT_MITE:
- case MONS_GNOLL:
- case MONS_GOLD_MIMIC:
- case MONS_KOMODO_DRAGON:
- case MONS_MUMMY:
- case MONS_NECROPHAGE:
- case MONS_POTION_MIMIC:
- case MONS_SCROLL_MIMIC:
- case MONS_SKELETAL_WARRIOR:
- case MONS_SMALL_SNAKE:
- case MONS_SOUL_EATER:
- case MONS_SPINY_WORM:
- case MONS_VAMPIRE:
- case MONS_WEAPON_MIMIC:
- case MONS_YELLOW_WASP:
- return 30;
-
- case MONS_FLAYED_GHOST:
- return 29;
-
- case MONS_BRAIN_WORM:
- return 26;
-
- case MONS_BOGGART:
- case MONS_DEEP_ELF_FIGHTER:
- case MONS_DEEP_ELF_KNIGHT:
- case MONS_DEEP_TROLL:
- case MONS_FIRE_GIANT:
- case MONS_FROST_GIANT:
- case MONS_GREAT_ORB_OF_EYES:
- case MONS_IRON_TROLL:
- case MONS_OOZE:
- case MONS_ORC_PRIEST:
- case MONS_PLANT:
- case MONS_RED_WASP:
- case MONS_SIMULACRUM_SMALL:
- case MONS_SIMULACRUM_LARGE:
- case MONS_YELLOW_DRACONIAN:
- case MONS_BLACK_DRACONIAN:
- case MONS_WHITE_DRACONIAN:
- case MONS_RED_DRACONIAN:
- case MONS_PURPLE_DRACONIAN:
- case MONS_PALE_DRACONIAN:
- case MONS_GREEN_DRACONIAN:
- return 25;
-
- case MONS_BUTTERFLY:
- case MONS_FUNGUS:
- case MONS_GIANT_SNAIL:
- case MONS_ICE_DRAGON:
- case MONS_INSUBSTANTIAL_WISP:
- case MONS_RAKSHASA:
- case MONS_REDBACK:
- case MONS_SHADOW_DRAGON:
- case MONS_SPECTRAL_WARRIOR:
- case MONS_SPHINX:
- case MONS_STEAM_DRAGON:
- case MONS_STORM_DRAGON:
- case MONS_VERY_UGLY_THING:
- case MONS_WIZARD:
- case MONS_DRACONIAN_CALLER:
- case MONS_DRACONIAN_MONK:
- case MONS_DRACONIAN_SCORCHER:
- case MONS_DRACONIAN_KNIGHT:
- case MONS_DRACONIAN_ANNIHILATOR:
- case MONS_DRACONIAN_ZEALOT:
- case MONS_DRACONIAN_SHIFTER:
- case MONS_MOTTLED_DRACONIAN:
- return 20;
-
- case MONS_BORING_BEETLE:
- case MONS_LICH:
- case MONS_TENTACLED_MONSTROSITY:
- return 17;
-
- case MONS_BLINK_FROG:
- case MONS_CLAY_GOLEM:
- case MONS_EFREET:
- case MONS_EYE_OF_DEVASTATION:
- case MONS_NECROMANCER:
- case MONS_WOOD_GOLEM:
- return 15;
-
- case MONS_KOBOLD_DEMONOLOGIST:
- return 13;
-
- case MONS_BUMBLEBEE:
- case MONS_ORC_HIGH_PRIEST:
- return 12;
-
- case MONS_DEEP_ELF_SOLDIER:
- case MONS_GIANT_ORANGE_BRAIN:
- case MONS_HELL_KNIGHT:
- case MONS_IRON_GOLEM:
- case MONS_OKLOB_PLANT:
- case MONS_ORC_SORCERER:
- case MONS_SHADOW_WRAITH:
- case MONS_STONE_GOLEM:
- case MONS_TITAN:
- case MONS_WANDERING_MUSHROOM:
- return 10;
-
- case MONS_GOLDEN_DRAGON:
- case MONS_ORC_WARLORD:
- return 7;
-
- case MONS_GARGOYLE:
- return 6;
-
- case MONS_CRYSTAL_GOLEM:
- case MONS_DANCING_WEAPON:
- case MONS_DEEP_ELF_HIGH_PRIEST:
- case MONS_DEEP_ELF_MAGE:
- case MONS_DEEP_ELF_SUMMONER:
- case MONS_IRON_DRAGON:
- case MONS_NAGA_MAGE:
- case MONS_NAGA_WARRIOR:
- case MONS_SKELETAL_DRAGON:
- case MONS_QUICKSILVER_DRAGON:
- case MONS_VAPOUR:
- return 5;
-
- case MONS_AIR_ELEMENTAL:
- case MONS_DEEP_ELF_CONJURER:
- case MONS_EARTH_ELEMENTAL:
- case MONS_FIRE_ELEMENTAL:
- return 4;
-
- case MONS_ANCIENT_LICH:
- case MONS_DEEP_ELF_ANNIHILATOR:
- case MONS_DEEP_ELF_DEATH_MAGE:
- case MONS_DEEP_ELF_DEMONOLOGIST:
- case MONS_DEEP_ELF_PRIEST:
- case MONS_DEEP_ELF_SORCERER:
- case MONS_GUARDIAN_NAGA:
- return 3;
-
- case MONS_PULSATING_LUMP:
- case MONS_SHINING_EYE:
- case MONS_TOENAIL_GOLEM:
- return 2;
-
- default:
- return 0;
- }
-} // end mons_standard_rare()
diff --git a/stone_soup/crawl-ref/source/mon-pick.h b/stone_soup/crawl-ref/source/mon-pick.h
deleted file mode 100644
index 79312e6043..0000000000
--- a/stone_soup/crawl-ref/source/mon-pick.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * File: mon-pick.h
- * Summary: Functions used to help determine which monsters should appear.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef MONPICK_H
-#define MONPICK_H
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: dungeon - fight
- * *********************************************************************** */
-int mons_rarity(int mcls);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: dungeon
- * *********************************************************************** */
-int mons_level(int mcls);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: dungeon - mon-pick
- * *********************************************************************** */
-bool mons_abyss(int mcls);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: dungeon - mon-pick
- * *********************************************************************** */
-int mons_rare_abyss(int mcls);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: dungeon - spells3
- * *********************************************************************** */
-int branch_depth(int branch);
-
-
-// last updated 10jun2000 {dlb}
-/* ***********************************************************************
- * called from: levels - mon-pick
- * *********************************************************************** */
-bool mons_pan(int mcls);
-
-
-#endif
diff --git a/stone_soup/crawl-ref/source/mon-spll.h b/stone_soup/crawl-ref/source/mon-spll.h
deleted file mode 100644
index 03d2f2fdcc..0000000000
--- a/stone_soup/crawl-ref/source/mon-spll.h
+++ /dev/null
@@ -1,773 +0,0 @@
-#ifndef MON_SPLL_H
-#define MON_SPLL_H
-
-
-/* *********************************************************************
-
- this will do as long as ( 0 >= (template/sec numbers) <= 255 )
-
- !!!NOTE!!! for simplicity, these templates assume that most monsters
- capable of casting more powerful summonings can also cast Abjuration.
-
- Template Format:
-
- { WHICH TEMPLATE,
- bolt spell,
- enchantment,
- self-enchantment, // 50% tried after others fail
- misc(1) spell,
- misc(2) spell, // MS_DIG must be here to work!
- emergency spell // only when fleeing
- }
-
- see: mon-util::mons_spell_list() and
- monstuff::handle_spell() for usage details.
-
-********************************************************************* */
-
-
- { MST_ORC_WIZARD_I,
- MS_MMISSILE,
- MS_SLOW,
- MS_HASTE,
- MS_MMISSILE,
- MS_BLINK,
- MS_BLINK },
-
- { MST_ORC_WIZARD_II,
- MS_FLAME,
- MS_CONFUSE,
- MS_INVIS,
- MS_MMISSILE,
- MS_NO_SPELL,
- MS_CONFUSE },
-
- { MST_ORC_WIZARD_III,
- MS_FROST,
- MS_CANTRIP,
- MS_HASTE,
- MS_FLAME,
- MS_MMISSILE,
- MS_INVIS },
-
- { MST_GUARDIAN_NAGA,
- MS_TELEPORT_OTHER,
- MS_TELEPORT_OTHER,
- MS_HEAL,
- MS_VENOM_BOLT,
- MS_SLOW,
- MS_HEAL },
-
- { MST_LICH_I,
- MS_COLD_BOLT,
- MS_PARALYSIS,
- MS_SUMMON_DEMON_GREATER,
- MS_ANIMATE_DEAD,
- MS_IRON_BOLT,
- MS_TELEPORT },
-
- { MST_LICH_II,
- MS_FIRE_BOLT,
- MS_CONFUSE,
- MS_HASTE,
- MS_NEGATIVE_BOLT,
- MS_SUMMON_DEMON_GREATER,
- MS_BANISHMENT },
-
- { MST_LICH_III,
- MS_NEGATIVE_BOLT,
- MS_ANIMATE_DEAD,
- MS_SUMMON_UNDEAD,
- MS_FROST,
- MS_CRYSTAL_SPEAR,
- MS_SUMMON_UNDEAD },
-
- { MST_LICH_IV,
- MS_ORB_ENERGY,
- MS_COLD_BOLT,
- MS_INVIS,
- MS_ANIMATE_DEAD,
- MS_IRON_BOLT,
- MS_INVIS },
-
- { MST_BURNING_DEVIL,
- MS_HELLFIRE_BURST,
- MS_HELLFIRE_BURST,
- MS_NO_SPELL,
- MS_HELLFIRE_BURST,
- MS_HELLFIRE_BURST,
- MS_HELLFIRE_BURST },
-
- { MST_VAMPIRE,
- MS_VAMPIRE_SUMMON,
- MS_CONFUSE,
- MS_INVIS,
- MS_NO_SPELL,
- MS_VAMPIRE_SUMMON,
- MS_VAMPIRE_SUMMON },
-
- { MST_VAMPIRE_KNIGHT,
- MS_VAMPIRE_SUMMON,
- MS_PARALYSIS,
- MS_HASTE,
- MS_INVIS,
- MS_VAMPIRE_SUMMON,
- MS_HEAL },
-
- { MST_VAMPIRE_MAGE,
- MS_NEGATIVE_BOLT,
- MS_SUMMON_UNDEAD,
- MS_INVIS,
- MS_ANIMATE_DEAD,
- MS_ANIMATE_DEAD,
- MS_TELEPORT },
-
- { MST_EFREET,
- MS_FIRE_BOLT,
- MS_NO_SPELL,
- MS_NO_SPELL,
- MS_FIREBALL,
- MS_NO_SPELL,
- MS_NO_SPELL },
-
- { MST_BRAIN_WORM,
- MS_BRAIN_FEED,
- MS_NO_SPELL,
- MS_NO_SPELL,
- MS_BRAIN_FEED,
- MS_NO_SPELL,
- MS_NO_SPELL },
-
- { MST_GIANT_ORANGE_BRAIN,
- MS_BRAIN_FEED,
- MS_MUTATION,
- MS_LEVEL_SUMMON,
- MS_CONFUSE,
- MS_BLINK,
- MS_TELEPORT },
-
- { MST_RAKSHASA,
- MS_FAKE_RAKSHASA_SUMMON,
- MS_BLINK,
- MS_INVIS,
- MS_FAKE_RAKSHASA_SUMMON,
- MS_BLINK,
- MS_TELEPORT },
-
- { MST_GREAT_ORB_OF_EYES,
- MS_PARALYSIS,
- MS_DISINTEGRATE,
- MS_NO_SPELL,
- MS_SLOW,
- MS_CONFUSE,
- MS_TELEPORT_OTHER },
-
- { MST_ORC_SORCERER,
- MS_FIRE_BOLT,
- MS_NEGATIVE_BOLT,
- MS_SUMMON_DEMON,
- MS_PARALYSIS,
- MS_ANIMATE_DEAD,
- MS_TELEPORT },
-
- { MST_STEAM_DRAGON,
- MS_STEAM_BALL,
- MS_STEAM_BALL,
- MS_NO_SPELL,
- MS_STEAM_BALL,
- MS_STEAM_BALL,
- MS_NO_SPELL },
-
- { MST_HELL_KNIGHT_I,
- MS_NO_SPELL,
- MS_PAIN,
- MS_HASTE,
- MS_NO_SPELL,
- MS_NO_SPELL,
- MS_HASTE },
-
- { MST_HELL_KNIGHT_II,
- MS_NO_SPELL,
- MS_FIRE_BOLT,
- MS_NO_SPELL,
- MS_NO_SPELL,
- MS_NO_SPELL,
- MS_BLINK },
-
- { MST_NECROMANCER_I,
- MS_COLD_BOLT,
- MS_NEGATIVE_BOLT,
- MS_NO_SPELL,
- MS_ANIMATE_DEAD,
- MS_ANIMATE_DEAD,
- MS_TELEPORT },
-
- { MST_NECROMANCER_II,
- MS_FIRE_BOLT,
- MS_PAIN,
- MS_INVIS,
- MS_ANIMATE_DEAD,
- MS_ANIMATE_DEAD,
- MS_BLINK },
-
- { MST_WIZARD_I,
- MS_MMISSILE,
- MS_PARALYSIS,
- MS_HASTE,
- MS_LIGHTNING_BOLT,
- MS_CONFUSE,
- MS_TELEPORT },
-
- { MST_WIZARD_II,
- MS_VENOM_BOLT,
- MS_ORB_ENERGY,
- MS_INVIS,
- MS_CONFUSE,
- MS_SLOW,
- MS_TELEPORT },
-
- { MST_WIZARD_III,
- MS_PARALYSIS,
- MS_CRYSTAL_SPEAR,
- MS_BLINK,
- MS_FIRE_BOLT,
- MS_COLD_BOLT,
- MS_HEAL },
-
- { MST_WIZARD_IV,
- MS_STONE_ARROW,
- MS_STING,
- MS_BLINK,
- MS_LIGHTNING_BOLT,
- MS_BANISHMENT,
- MS_HEAL },
-
- { MST_WIZARD_V,
- MS_PARALYSIS,
- MS_FLAME,
- MS_INVIS,
- MS_TELEPORT_OTHER,
- MS_FIREBALL,
- MS_TELEPORT_OTHER },
-
- { MST_ORC_PRIEST,
- MS_PAIN,
- MS_NO_SPELL,
- MS_CANTRIP,
- MS_SMITE,
- MS_NO_SPELL,
- MS_HEAL },
-
- { MST_ORC_HIGH_PRIEST,
- MS_PAIN,
- MS_SUMMON_DEMON,
- MS_SUMMON_DEMON,
- MS_SMITE,
- MS_ANIMATE_DEAD,
- MS_HEAL },
-
- { MST_MOTTLED_DRAGON,
- MS_STICKY_FLAME,
- MS_STICKY_FLAME,
- MS_NO_SPELL,
- MS_STICKY_FLAME,
- MS_STICKY_FLAME,
- MS_NO_SPELL },
-
- { MST_ICE_FIEND,
- MS_COLD_BOLT,
- MS_COLD_BOLT,
- MS_NO_SPELL,
- MS_TORMENT,
- MS_NO_SPELL,
- MS_SUMMON_DEMON },
-
- { MST_SHADOW_FIEND,
- MS_COLD_BOLT,
- MS_NEGATIVE_BOLT,
- MS_NO_SPELL,
- MS_TORMENT,
- MS_NO_SPELL,
- MS_SUMMON_DEMON },
-
- { MST_TORMENTOR,
- MS_PAIN,
- MS_NO_SPELL,
- MS_NO_SPELL,
- MS_PAIN,
- MS_NO_SPELL,
- MS_TORMENT },
-
- { MST_STORM_DRAGON,
- MS_LIGHTNING_BOLT,
- MS_LIGHTNING_BOLT,
- MS_NO_SPELL,
- MS_LIGHTNING_BOLT,
- MS_LIGHTNING_BOLT,
- MS_NO_SPELL },
-
- { MST_WHITE_IMP,
- MS_FROST,
- MS_NO_SPELL,
- MS_NO_SPELL,
- MS_NO_SPELL,
- MS_NO_SPELL,
- MS_NO_SPELL },
-
- { MST_YNOXINUL,
- MS_NO_SPELL,
- MS_IRON_BOLT,
- MS_SUMMON_UFETUBUS,
- MS_NO_SPELL,
- MS_SUMMON_UFETUBUS,
- MS_NO_SPELL },
-
- { MST_NEQOXEC,
- MS_MUTATION,
- MS_NO_SPELL,
- MS_NO_SPELL,
- MS_BRAIN_FEED,
- MS_SUMMON_DEMON_LESSER,
- MS_NO_SPELL },
-
- { MST_HELLWING,
- MS_NO_SPELL,
- MS_NO_SPELL,
- MS_NO_SPELL,
- MS_TELEPORT_OTHER,
- MS_ANIMATE_DEAD,
- MS_TELEPORT },
-
- { MST_SMOKE_DEMON,
- MS_STICKY_FLAME,
- MS_STEAM_BALL,
- MS_NO_SPELL,
- MS_SMITE,
- MS_NO_SPELL,
- MS_NO_SPELL },
-
- { MST_CACODEMON,
- MS_SUMMON_DEMON_LESSER,
- MS_SUMMON_DEMON_LESSER,
- MS_SUMMON_DEMON_LESSER,
- MS_MUTATION,
- MS_DIG,
- MS_SUMMON_DEMON },
-
- { MST_GREEN_DEATH,
- MS_POISON_ARROW,
- MS_POISON_BLAST,
- MS_NO_SPELL,
- MS_VENOM_BOLT,
- MS_SUMMON_DEMON_LESSER,
- MS_BLINK },
-
- { MST_BALRUG,
- MS_FIRE_BOLT,
- MS_FIREBALL,
- MS_NO_SPELL,
- MS_STICKY_FLAME,
- MS_SMITE,
- MS_TELEPORT },
-
- { MST_BLUE_DEATH,
- MS_LIGHTNING_BOLT,
- MS_COLD_BOLT,
- MS_NO_SPELL,
- MS_SUMMON_DEMON_LESSER,
- MS_LEVEL_SUMMON,
- MS_TELEPORT_OTHER },
-
- { MST_GERYON,
- MS_SUMMON_BEAST,
- MS_SUMMON_BEAST,
- MS_NO_SPELL,
- MS_SUMMON_BEAST,
- MS_NO_SPELL,
- MS_SUMMON_BEAST },
-
- { MST_DISPATER,
- MS_SUMMON_DEMON_GREATER,
- MS_IRON_BOLT,
- MS_SUMMON_DEMON,
- MS_LIGHTNING_BOLT,
- MS_HELLFIRE,
- MS_SUMMON_DEMON_GREATER },
-
- { MST_ASMODEUS,
- MS_FIRE_BOLT,
- MS_HELLFIRE,
- MS_SUMMON_DEMON,
- MS_SUMMON_DEMON_GREATER,
- MS_NEGATIVE_BOLT,
- MS_TELEPORT },
-
- { MST_ERESHKIGAL,
- MS_NEGATIVE_BOLT,
- MS_COLD_BOLT,
- MS_SUMMON_DEMON,
- MS_PAIN,
- MS_PARALYSIS,
- MS_HEAL },
-
- { MST_ANTAEUS,
- MS_COLD_BOLT,
- MS_LIGHTNING_BOLT,
- MS_NO_SPELL,
- MS_NO_SPELL,
- MS_NO_SPELL,
- MS_NO_SPELL },
-
- { MST_MNOLEG,
- MS_SUMMON_DEMON,
- MS_SMITE,
- MS_INVIS,
- MS_MUTATION,
- MS_LEVEL_SUMMON,
- MS_TELEPORT },
-
- { MST_LOM_LOBON,
- MS_LIGHTNING_BOLT,
- MS_COLD_BOLT,
- MS_HEAL,
- MS_SUMMON_DEMON,
- MS_TELEPORT,
- MS_TELEPORT },
-
- { MST_CEREBOV,
- MS_FIRE_BOLT,
- MS_IRON_BOLT,
- MS_NO_SPELL,
- MS_FIREBALL,
- MS_SUMMON_DEMON_LESSER,
- MS_NO_SPELL },
-
- { MST_GLOORX_VLOQ,
- MS_POISON_ARROW,
- MS_SLOW,
- MS_SUMMON_DEMON,
- MS_NEGATIVE_BOLT,
- MS_SUMMON_DEMON,
- MS_NO_SPELL },
-
- { MST_TITAN,
- MS_LIGHTNING_BOLT,
- MS_NO_SPELL,
- MS_HEAL,
- MS_NO_SPELL,
- MS_NO_SPELL,
- MS_HEAL },
-
- { MST_GOLDEN_DRAGON,
- MS_FIRE_BOLT,
- MS_COLD_BOLT,
- MS_NO_SPELL,
- MS_NO_SPELL,
- MS_POISON_BLAST,
- MS_NO_SPELL },
-
- { MST_DEEP_ELF_SUMMONER,
- MS_BLINK,
- MS_SUMMON_DEMON_LESSER,
- MS_SUMMON_UFETUBUS,
- MS_VAMPIRE_SUMMON,
- MS_SUMMON_DEMON,
- MS_TELEPORT },
-
- { MST_DEEP_ELF_CONJURER_I,
- MS_FIRE_BOLT,
- MS_COLD_BOLT,
- MS_CANTRIP,
- MS_LIGHTNING_BOLT,
- MS_STICKY_FLAME,
- MS_TELEPORT },
-
- { MST_DEEP_ELF_CONJURER_II,
- MS_STICKY_FLAME,
- MS_ORB_ENERGY,
- MS_INVIS,
- MS_STONE_ARROW,
- MS_NEGATIVE_BOLT,
- MS_TELEPORT },
-
- { MST_DEEP_ELF_PRIEST,
- MS_PAIN,
- MS_CANTRIP,
- MS_HEAL,
- MS_SMITE,
- MS_ANIMATE_DEAD,
- MS_HEAL },
-
- { MST_DEEP_ELF_HIGH_PRIEST,
- MS_SUMMON_DEMON,
- MS_HELLFIRE_BURST,
- MS_HEAL,
- MS_SMITE,
- MS_ANIMATE_DEAD,
- MS_HEAL },
-
- { MST_DEEP_ELF_DEMONOLOGIST,
- MS_SUMMON_DEMON,
- MS_BANISHMENT,
- MS_SUMMON_DEMON,
- MS_SUMMON_DEMON_GREATER,
- MS_SUMMON_DEMON_LESSER,
- MS_TELEPORT },
-
- { MST_DEEP_ELF_ANNIHILATOR,
- MS_LIGHTNING_BOLT,
- MS_CRYSTAL_SPEAR,
- MS_BLINK,
- MS_IRON_BOLT,
- MS_POISON_ARROW,
- MS_TELEPORT },
-
- { MST_DEEP_ELF_SORCERER,
- MS_NEGATIVE_BOLT,
- MS_BANISHMENT,
- MS_HASTE,
- MS_SUMMON_DEMON,
- MS_HELLFIRE,
- MS_TELEPORT },
-
- { MST_DEEP_ELF_DEATH_MAGE,
- MS_NEGATIVE_BOLT,
- MS_NEGATIVE_BOLT,
- MS_HEAL,
- MS_ANIMATE_DEAD,
- MS_ANIMATE_DEAD,
- MS_TELEPORT },
-
- { MST_KOBOLD_DEMONOLOGIST,
- MS_SUMMON_DEMON_LESSER,
- MS_SUMMON_DEMON,
- MS_CANTRIP,
- MS_SUMMON_DEMON_LESSER,
- MS_SUMMON_DEMON,
- MS_CANTRIP }, // this should be cute -- bwr
-
- { MST_NAGA,
- MS_POISON_SPLASH,
- MS_POISON_SPLASH,
- MS_NO_SPELL,
- MS_NO_SPELL,
- MS_NO_SPELL,
- MS_NO_SPELL },
-
- { MST_NAGA_MAGE,
- MS_VENOM_BOLT,
- MS_ORB_ENERGY,
- MS_HASTE,
- MS_POISON_ARROW,
- MS_TELEPORT_OTHER,
- MS_TELEPORT },
-
- { MST_CURSE_SKULL,
- MS_SUMMON_UNDEAD,
- MS_SUMMON_UNDEAD,
- MS_NO_SPELL,
- MS_TORMENT,
- MS_SUMMON_UNDEAD,
- MS_NO_SPELL },
-
- { MST_SHINING_EYE,
- MS_MUTATION,
- MS_MUTATION,
- MS_NO_SPELL,
- MS_NO_SPELL,
- MS_NO_SPELL,
- MS_NO_SPELL },
-
- { MST_FROST_GIANT,
- MS_COLD_BOLT,
- MS_COLD_BOLT,
- MS_NO_SPELL,
- MS_NO_SPELL,
- MS_NO_SPELL,
- MS_NO_SPELL },
-
- { MST_ANGEL,
- MS_NO_SPELL,
- MS_NO_SPELL,
- MS_HEAL,
- MS_NO_SPELL,
- MS_HEAL,
- MS_HEAL },
-
- { MST_DAEVA,
- MS_SMITE,
- MS_NO_SPELL,
- MS_NO_SPELL,
- MS_SMITE,
- MS_SMITE,
- MS_NO_SPELL },
-
- { MST_SHADOW_DRAGON,
- MS_NEGATIVE_BOLT,
- MS_NEGATIVE_BOLT,
- MS_NO_SPELL,
- MS_NO_SPELL,
- MS_NEGATIVE_BOLT,
- MS_NO_SPELL },
-
- { MST_SPHINX,
- MS_CONFUSE,
- MS_PARALYSIS,
- MS_HEAL,
- MS_SMITE,
- MS_SLOW,
- MS_HEAL },
-
- { MST_MUMMY,
- MS_SUMMON_DEMON,
- MS_SMITE,
- MS_NO_SPELL,
- MS_TORMENT,
- MS_SUMMON_UNDEAD,
- MS_SUMMON_UNDEAD },
-
- { MST_ELECTRIC_GOLEM,
- MS_LIGHTNING_BOLT,
- MS_LIGHTNING_BOLT,
- MS_BLINK,
- MS_LIGHTNING_BOLT,
- MS_LIGHTNING_BOLT,
- MS_BLINK },
-
- { MST_ORB_OF_FIRE,
- MS_FIRE_BOLT,
- MS_FIRE_BOLT,
- MS_NO_SPELL,
- MS_MUTATION,
- MS_FIREBALL,
- MS_FIREBALL },
-
- { MST_SHADOW_IMP,
- MS_PAIN,
- MS_NO_SPELL,
- MS_ANIMATE_DEAD,
- MS_ANIMATE_DEAD,
- MS_NO_SPELL,
- MS_NO_SPELL },
-
- { MST_GHOST, // actual spells taken from struct (see mon-util.cc),
- MS_NO_SPELL, // this line: splist[x] = ghost.values[x + 14] -- dlb
- MS_NO_SPELL,
- MS_NO_SPELL,
- MS_NO_SPELL,
- MS_NO_SPELL,
- MS_NO_SPELL },
-
- { MST_HELL_HOG,
- MS_STICKY_FLAME,
- MS_STICKY_FLAME,
- MS_NO_SPELL,
- MS_NO_SPELL,
- MS_NO_SPELL,
- MS_NO_SPELL },
-
- { MST_SWAMP_DRAGON,
- MS_POISON_BLAST,
- MS_POISON_BLAST,
- MS_NO_SPELL,
- MS_POISON_BLAST,
- MS_POISON_BLAST,
- MS_NO_SPELL },
-
- { MST_SWAMP_DRAKE,
- MS_MARSH_GAS,
- MS_MARSH_GAS,
- MS_NO_SPELL,
- MS_MARSH_GAS,
- MS_MARSH_GAS,
- MS_NO_SPELL },
-
- { MST_SERPENT_OF_HELL,
- MS_HELLFIRE,
- MS_HELLFIRE,
- MS_NO_SPELL,
- MS_HELLFIRE,
- MS_HELLFIRE,
- MS_NO_SPELL },
-
- { MST_BOGGART,
- MS_CONFUSE,
- MS_SLOW,
- MS_INVIS,
- MS_BLINK,
- MS_LEVEL_SUMMON,
- MS_LEVEL_SUMMON },
-
- { MST_EYE_OF_DEVASTATION,
- MS_ENERGY_BOLT,
- MS_ENERGY_BOLT,
- MS_NO_SPELL,
- MS_ENERGY_BOLT,
- MS_ENERGY_BOLT,
- MS_NO_SPELL },
-
- { MST_QUICKSILVER_DRAGON,
- MS_QUICKSILVER_BOLT,
- MS_QUICKSILVER_BOLT,
- MS_NO_SPELL,
- MS_QUICKSILVER_BOLT,
- MS_QUICKSILVER_BOLT,
- MS_NO_SPELL },
-
- { MST_IRON_DRAGON,
- MS_METAL_SPLINTERS,
- MS_METAL_SPLINTERS,
- MS_NO_SPELL,
- MS_METAL_SPLINTERS,
- MS_METAL_SPLINTERS,
- MS_NO_SPELL },
-
- { MST_SKELETAL_WARRIOR,
- MS_ANIMATE_DEAD,
- MS_NO_SPELL,
- MS_ANIMATE_DEAD,
- MS_NO_SPELL,
- MS_NO_SPELL,
- MS_NO_SPELL },
-
- { MST_MYSTIC,
- MS_BRAIN_FEED,
- MS_SMITE,
- MS_INVIS,
- MS_CONFUSE,
- MS_PARALYSIS,
- MS_HEAL },
-
- { MST_DEATH_DRAKE,
- MS_MIASMA,
- MS_MIASMA,
- MS_NO_SPELL,
- MS_MIASMA,
- MS_MIASMA,
- MS_NO_SPELL },
-
- { MST_DRAC_SCORCHER,
- MS_FIRE_BOLT,
- MS_STICKY_FLAME,
- MS_NO_SPELL,
- MS_FIREBALL,
- MS_HELLFIRE,
- MS_HELLFIRE_BURST },
-
- { MST_DRAC_CALLER,
- MS_NO_SPELL,
- MS_SUMMON_LIZARDS,
- MS_SUMMON_LIZARDS,
- MS_NO_SPELL,
- MS_NO_SPELL,
- MS_SUMMON_LIZARDS },
-
- { MST_DRAC_SHIFTER,
- MS_NO_SPELL,
- MS_BLINK_OTHER,
- MS_BLINK,
- MS_NO_SPELL,
- MS_BLINK_OTHER,
- MS_CONTROLLED_BLINK },
-
-#endif
diff --git a/stone_soup/crawl-ref/source/mon-util.cc b/stone_soup/crawl-ref/source/mon-util.cc
deleted file mode 100644
index 7ce15b9660..0000000000
--- a/stone_soup/crawl-ref/source/mon-util.cc
+++ /dev/null
@@ -1,2209 +0,0 @@
-/*
- * File: mon-util.cc
- * Summary: Misc monster related functions.
- * Written by: Linley Henzell
- *
- * Modified for Crawl Reference by $Author$ on $Date$
- *
- * Change History (most recent first):
- *
- * <2> 11/04/99 cdl added a break to spell selection
- * for kobold Summoners
- * print just "[Ii]t" for invisible undead
- * renamed params to monam()
- * <1> -/--/-- LRH Created
- */
-
-// $pellbinder: (c) D.G.S.E 1998
-// some routines snatched from former monsstat.cc
-
-#include "AppHdr.h"
-#include "mon-util.h"
-#include "monstuff.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "externs.h"
-
-#include "debug.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "mstuff2.h"
-#include "player.h"
-#include "randart.h"
-#include "stuff.h"
-#include "view.h"
-
-//jmf: moved from inside function
-static FixedVector < int, NUM_MONSTERS > mon_entry;
-
-// really important extern -- screen redraws suck w/o it {dlb}
-FixedVector < unsigned short, 1000 > mcolour;
-
-static struct monsterentry mondata[] = {
-#include "mon-data.h"
-};
-
-#define MONDATASIZE (sizeof(mondata)/sizeof(struct monsterentry))
-
-static int mspell_list[][7] = {
-#include "mon-spll.h"
-};
-
-#if DEBUG_DIAGNOSTICS
-static const char *monster_spell_name[] = {
- "Magic Missile",
- "Throw Flame",
- "Throw Frost",
- "Paralysis",
- "Slow",
- "Haste",
- "Confuse",
- "Venom Bolt",
- "Fire Bolt",
- "Cold Bolt",
- "Lightning Bolt",
- "Invisibility",
- "Fireball",
- "Heal",
- "Teleport",
- "Teleport Other",
- "Blink",
- "Crystal Spear",
- "Dig",
- "Negative Bolt",
- "Hellfire Burst",
- "Vampire Summon",
- "Orb Energy",
- "Brain Feed",
- "Level Summon",
- "Fake Rakshasa Summon",
- "Steam Ball",
- "Summon Demon",
- "Animate Dead",
- "Pain",
- "Smite",
- "Sticky Flame",
- "Poison Blast",
- "Summon Demon Lesser",
- "Summon Ufetubus",
- "Purple Blast",
- "Summon Beast",
- "Energy Bolt",
- "Sting",
- "Iron Bolt",
- "Stone Arrow",
- "Poison Splash",
- "Summon Undead",
- "Mutation",
- "Cantrip",
- "Disintegrate",
- "Marsh Gas",
- "Quicksilver Bolt",
- "Torment",
- "Hellfire",
- "Metal Splinters",
- "Summon Demon Greater",
- "Banishment",
-};
-#endif
-
-static int mons_exp_mod(int mclass);
-static monsterentry *seekmonster(int p_monsterid);
-
-// macro that saves some typing, nothing more
-#define smc seekmonster(mc)
-
-/* ******************** BEGIN PUBLIC FUNCTIONS ******************** */
-void init_monsters(FixedVector < unsigned short, 1000 > &colour)
-{
- unsigned int x; // must be unsigned to match size_t {dlb}
-
- for (x = 0; x < MONDATASIZE; x++)
- colour[mondata[x].mc] = mondata[x].colour;
-
- //unsigned int x = 0; // must be unsigned to match size_t {dlb}
-
- // first, fill static array with dummy values {dlb};
- for (x = 0; x < NUM_MONSTERS; x++)
- mon_entry[x] = -1;
-
- // next, fill static array with location of entry in mondata[] {dlb}:
- for (x = 0; x < MONDATASIZE; x++)
- mon_entry[mondata[x].mc] = x;
-
- // finally, monsters yet with dummy entries point to TTTSNB(tm) {dlb}:
- for (x = 0; x < NUM_MONSTERS; x++)
- {
- if (mon_entry[x] == -1)
- mon_entry[x] = mon_entry[MONS_PROGRAM_BUG];
- }
- //return (monsterentry *) 0; // return value should not matter here {dlb}
-} // end mons_init()
-
-unsigned long get_mons_class_resists(int mc)
-{
- return (smc->resists);
-}
-
-unsigned long mons_class_resist(int mc, unsigned long flags)
-{
- return (smc->resists & flags);
-}
-
-bool mons_class_flag(int mc, int bf)
-{
- return ((smc->bitfields & bf) != 0);
-} // end mons_class_flag()
-
-static int scan_mon_inv_randarts( struct monsters *mon, int ra_prop )
-{
- int ret = 0;
-
- if (mons_itemuse( mon->type ) >= MONUSE_STARTING_EQUIPMENT)
- {
- const int weapon = mon->inv[MSLOT_WEAPON];
- const int second = mon->inv[MSLOT_MISSILE]; // ettins/two-head oges
- const int armour = mon->inv[MSLOT_ARMOUR];
-
- if (weapon != NON_ITEM && mitm[weapon].base_type == OBJ_WEAPONS
- && is_random_artefact( mitm[weapon] ))
- {
- ret += randart_wpn_property( mitm[weapon], ra_prop );
- }
-
- if (second != NON_ITEM && mitm[second].base_type == OBJ_WEAPONS
- && is_random_artefact( mitm[second] ))
- {
- ret += randart_wpn_property( mitm[second], ra_prop );
- }
-
- if (armour != NON_ITEM && mitm[armour].base_type == OBJ_ARMOUR
- && is_random_artefact( mitm[armour] ))
- {
- ret += randart_wpn_property( mitm[armour], ra_prop );
- }
- }
-
- return (ret);
-}
-
-mon_holy_type mons_holiness(const monsters *mon)
-{
- return (mons_class_holiness(mon->type));
-}
-
-mon_holy_type mons_class_holiness(int mc)
-{
- return (smc->holiness);
-} // end mons_holiness()
-
-bool mons_is_stationary(const monsters *mons)
-{
- return (mons->type == MONS_OKLOB_PLANT
- || mons->type == MONS_PLANT
- || mons->type == MONS_FUNGUS
- || mons->type == MONS_CURSE_SKULL
- || (mons->type >= MONS_CURSE_TOE
- && mons->type <= MONS_POTION_MIMIC));
-}
-
-bool invalid_monster(const monsters *mons)
-{
- return (!mons || mons->type == -1);
-}
-
-bool mons_is_mimic( int mc )
-{
- return (mons_species( mc ) == MONS_GOLD_MIMIC);
-}
-
-bool mons_is_demon( int mc )
-{
- const int show_char = mons_char( mc );
-
- // Not every demonic monster is a demon (ie hell hog, hell hound)
- if (mons_class_holiness( mc ) == MH_DEMONIC
- && (isdigit( show_char ) || show_char == '&'))
- {
- return (true);
- }
-
- return (false);
-}
-
-// Used for elven Glamour ability. -- bwr
-bool mons_is_humanoid( int mc )
-{
- switch (mons_char( mc))
- {
- case 'o': // orcs
- case 'e': // elvens (deep)
- case 'c': // centaurs
- case 'C': // giants
- case 'O': // ogres
- case 'K': // kobolds
- case 'N': // nagas
- case '@': // adventuring humans
- case 'T': // trolls
- return (true);
-
- case 'g': // goblines, hobgoblins, gnolls, boggarts -- but not gargoyles
- if (mc != MONS_GARGOYLE
- && mc != MONS_METAL_GARGOYLE
- && mc != MONS_MOLTEN_GARGOYLE)
- {
- return (true);
- }
-
- default:
- break;
- }
-
- return (false);
-}
-
-int mons_zombie_size(int mc)
-{
- return (smc->zombie_size);
-} // end mons_zombie_size()
-
-
-int mons_weight(int mc)
-{
- return (smc->weight);
-} // end mons_weight()
-
-corpse_effect_type mons_corpse_effect(int mc)
-{
- return (smc->corpse_thingy);
-} // end mons_corpse_effect()
-
-
-monster_type mons_species( int mc )
-{
- return (smc->species);
-} // end mons_species()
-
-monster_type mons_genus( int mc )
-{
- return (smc->genus);
-}
-
-monster_type draco_subspecies( const monsters *mon )
-{
- ASSERT( mons_genus( mon->type ) == MONS_DRACONIAN );
-
- monster_type ret = mons_species( mon->type );
-
- if (ret == MONS_DRACONIAN && mon->type != MONS_DRACONIAN)
- ret = static_cast<monster_type>( mon->number );
-
- return (ret);
-}
-
-int mons_shouts(int mc)
-{
- int u = smc->shouts;
-
- if (u == -1)
- u = random2(12);
-
- return (u);
-} // end mons_shouts()
-
-bool mons_is_unique( int mc )
-{
- if (mc <= MONS_PROGRAM_BUG
- || (mc >= MONS_NAGA_MAGE && mc <= MONS_ROYAL_JELLY)
- || (mc >= MONS_DRACONIAN && mc <= MONS_DRACONIAN_SCORCHER)
- || (mc >= MONS_ANCIENT_LICH
- && (mc != MONS_PLAYER_GHOST && mc != MONS_PANDEMONIUM_DEMON)))
- {
- return (false);
- }
-
- return (true);
-}
-
-char mons_see_invis( struct monsters *mon )
-{
- if (mon->type == MONS_PLAYER_GHOST || mon->type == MONS_PANDEMONIUM_DEMON)
- return (ghost.values[ GVAL_SEE_INVIS ]);
- else if (((seekmonster(mon->type))->bitfields & M_SEE_INVIS) != 0)
- return (1);
- else if (scan_mon_inv_randarts( mon, RAP_EYESIGHT ) > 0)
- return (1);
-
- return (0);
-} // end mons_see_invis()
-
-
-// This does NOT do line of sight! It checks the targ's visibility
-// with respect to mon's perception, but doesn't do walls or range.
-bool mons_monster_visible( struct monsters *mon, struct monsters *targ )
-{
- if (mons_has_ench(targ, ENCH_SUBMERGED)
- || (mons_has_ench(targ, ENCH_INVIS) && !mons_see_invis(mon)))
- {
- return (false);
- }
-
- return (true);
-}
-
-// This does NOT do line of sight! It checks the player's visibility
-// with respect to mon's perception, but doesn't do walls or range.
-bool mons_player_visible( struct monsters *mon )
-{
- if (you.invis)
- {
- if (player_in_water())
- return (true);
-
- if (mons_see_invis( mon ))
- return (true);
-
- return (false);
- }
-
- return (true);
-}
-
-unsigned char mons_char(int mc)
-{
- return (unsigned char) smc->showchar;
-} // end mons_char()
-
-
-char mons_itemuse(int mc)
-{
- return (smc->gmon_use);
-} // end mons_itemuse()
-
-unsigned char mons_colour(int mc)
-{
- return (smc->colour);
-} // end mons_colour()
-
-
-int mons_damage(int mc, int rt)
-{
- ASSERT(rt >= 0);
- ASSERT(rt <= 3);
-
- if (rt < 0 || rt > 3) // make it fool-proof
- return (0);
-
- if (rt == 0 && (mc == MONS_PLAYER_GHOST || mc == MONS_PANDEMONIUM_DEMON))
- return (ghost.values[ GVAL_DAMAGE ]);
-
- return (smc->damage[rt]);
-} // end mons_damage()
-
-int mons_resist_magic( struct monsters *mon )
-{
- int u = (seekmonster(mon->type))->resist_magic;
-
- // negative values get multiplied with mhd
- if (u < 0)
- u = mon->hit_dice * (-u * 2);
-
- u += scan_mon_inv_randarts( mon, RAP_MAGIC );
-
- // ego armour resistance
- const int armour = mon->inv[MSLOT_ARMOUR];
-
- if (armour != NON_ITEM
- && get_armour_ego_type( mitm[armour] ) == SPARM_MAGIC_RESISTANCE )
- {
- u += 30;
- }
-
- return (u);
-} // end mon_resist_magic()
-
-
-// Returns true if the monster made its save against hostile
-// enchantments/some other magics.
-bool check_mons_resist_magic( struct monsters *monster, int pow )
-{
- int mrs = mons_resist_magic(monster);
-
- if (mrs == 5000)
- return (true);
-
- // Evil, evil hack to make weak one hd monsters easier for first
- // level characters who have resistable 1st level spells. Six is
- // a very special value because mrs = hd * 2 * 3 for most monsters,
- // and the weak, low level monsters have been adjusted so that the
- // "3" is typically a 1. There are some notable one hd monsters
- // that shouldn't fall under this, so we do < 6, instead of <= 6...
- // or checking monster->hit_dice. The goal here is to make the
- // first level easier for these classes and give them a better
- // shot at getting to level two or three and spells that can help
- // them out (or building a level or two of their base skill so they
- // aren't resisted as often). -- bwr
- if (mrs < 6 && coinflip())
- return (false);
-
- pow = stepdown_value( pow, 30, 40, 100, 120 );
-
- const int mrchance = (100 + mrs) - pow;
- const int mrch2 = random2(100) + random2(101);
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE,
- "Power: %d, monster's MR: %d, target: %d, roll: %d",
- pow, mrs, mrchance, mrch2 );
-
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- return ((mrch2 < mrchance) ? true : false);
-} // end check_mons_resist_magic()
-
-
-int mons_res_elec( struct monsters *mon )
-{
- int mc = mon->type;
-
- if (mc == MONS_PLAYER_GHOST || mc == MONS_PANDEMONIUM_DEMON)
- return (ghost.values[ GVAL_RES_ELEC ]);
-
- /* this is a variable, not a player_xx() function, so can be above 1 */
- int u = 0;
-
- if (mons_class_resist( mon->type, MR_RES_ELEC))
- u++;
-
- // don't bother checking equipment if the monster can't use it
- if (mons_itemuse(mc) >= MONUSE_STARTING_EQUIPMENT)
- {
- u += scan_mon_inv_randarts( mon, RAP_ELECTRICITY );
-
- // no ego armour, but storm dragon.
- const int armour = mon->inv[MSLOT_ARMOUR];
- if (armour != NON_ITEM && mitm[armour].base_type == OBJ_ARMOUR
- && mitm[armour].sub_type == ARM_STORM_DRAGON_ARMOUR)
- {
- u += 1;
- }
- }
-
- return (u);
-} // end mons_res_elec()
-
-bool mons_res_asphyx( const monsters *mon )
-{
- const int holiness = mons_holiness( mon );
- return (holiness == MH_UNDEAD
- || holiness == MH_DEMONIC
- || holiness == MH_NONLIVING);
-}
-
-int mons_res_poison( struct monsters *mon )
-{
- int mc = mon->type;
-
- int u = 0, f = get_mons_class_resists(mc);
-
- if (f & MR_RES_POISON)
- u++;
-
- if (f & MR_VUL_POISON)
- u--;
-
- if (mons_itemuse(mc) >= MONUSE_STARTING_EQUIPMENT)
- {
- u += scan_mon_inv_randarts( mon, RAP_POISON );
-
- const int armour = mon->inv[MSLOT_ARMOUR];
- if (armour != NON_ITEM && mitm[armour].base_type == OBJ_ARMOUR)
- {
- // intrinsic armour abilities
- switch (mitm[armour].sub_type)
- {
- case ARM_SWAMP_DRAGON_ARMOUR: u += 1; break;
- case ARM_GOLD_DRAGON_ARMOUR: u += 1; break;
- default: break;
- }
-
- // ego armour resistance
- if (get_armour_ego_type( mitm[armour] ) == SPARM_POISON_RESISTANCE)
- u += 1;
- }
- }
-
- return (u);
-} // end mons_res_poison()
-
-
-int mons_res_fire( struct monsters *mon )
-{
- int mc = mon->type;
-
- if (mc == MONS_PLAYER_GHOST || mc == MONS_PANDEMONIUM_DEMON)
- return (ghost.values[ GVAL_RES_FIRE ]);
-
- int u = 0, f = get_mons_class_resists(mc);
-
- // no Big Prize (tm) here either if you set all three flags. It's a pity uh?
- //
- // Note that natural monster resistance is two levels, this is duplicate
- // the fact that having this flag used to be a lot better than armour
- // for monsters (it used to make them immune in a lot of cases) -- bwr
- if (f & MR_RES_HELLFIRE)
- u += 3;
- else if (f & MR_RES_FIRE)
- u += 2;
- else if (f & MR_VUL_FIRE)
- u--;
-
- if (mons_itemuse(mc) >= MONUSE_STARTING_EQUIPMENT)
- {
- u += scan_mon_inv_randarts( mon, RAP_POISON );
-
- const int armour = mon->inv[MSLOT_ARMOUR];
- if (armour != NON_ITEM && mitm[armour].base_type == OBJ_ARMOUR)
- {
- // intrinsic armour abilities
- switch (mitm[armour].sub_type)
- {
- case ARM_DRAGON_ARMOUR: u += 2; break;
- case ARM_GOLD_DRAGON_ARMOUR: u += 1; break;
- case ARM_ICE_DRAGON_ARMOUR: u -= 1; break;
- default: break;
- }
-
- // check ego resistance
- const int ego = get_armour_ego_type( mitm[armour] );
- if (ego == SPARM_FIRE_RESISTANCE || ego == SPARM_RESISTANCE)
- u += 1;
- }
- }
-
- return (u);
-} // end mons_res_fire()
-
-
-int mons_res_cold( struct monsters *mon )
-{
- int mc = mon->type;
-
- if (mc == MONS_PLAYER_GHOST || mc == MONS_PANDEMONIUM_DEMON)
- return (ghost.values[ GVAL_RES_COLD ]);
-
- int u = 0, f = get_mons_class_resists(mc);
-
- // Note that natural monster resistance is two levels, this is duplicate
- // the fact that having this flag used to be a lot better than armour
- // for monsters (it used to make them immune in a lot of cases) -- bwr
- if (f & MR_RES_COLD)
- u += 2;
- else if (f & MR_VUL_COLD)
- u--;
-
- if (mons_itemuse(mc) >= MONUSE_STARTING_EQUIPMENT)
- {
- u += scan_mon_inv_randarts( mon, RAP_POISON );
-
- const int armour = mon->inv[MSLOT_ARMOUR];
- if (armour != NON_ITEM && mitm[armour].base_type == OBJ_ARMOUR)
- {
- // intrinsic armour abilities
- switch (mitm[armour].sub_type)
- {
- case ARM_ICE_DRAGON_ARMOUR: u += 2; break;
- case ARM_GOLD_DRAGON_ARMOUR: u += 1; break;
- case ARM_DRAGON_ARMOUR: u -= 1; break;
- default: break;
- }
-
- // check ego resistance
- const int ego = get_armour_ego_type( mitm[armour] );
- if (ego == SPARM_COLD_RESISTANCE || ego == SPARM_RESISTANCE)
- u += 1;
- }
- }
-
- return (u);
-} // end mons_res_cold()
-
-int mons_res_negative_energy( struct monsters *mon )
-{
- int mc = mon->type;
-
- if (mons_holiness(mon) == MH_UNDEAD
- || mons_holiness(mon) == MH_DEMONIC
- || mons_holiness(mon) == MH_NONLIVING
- || mons_holiness(mon) == MH_PLANT
- || mon->type == MONS_SHADOW_DRAGON
- || mon->type == MONS_DEATH_DRAKE)
- {
- return (3); // to match the value for players
- }
-
- int u = 0;
-
- if (mons_itemuse(mc) >= MONUSE_STARTING_EQUIPMENT)
- {
- u += scan_mon_inv_randarts( mon, RAP_NEGATIVE_ENERGY );
-
- const int armour = mon->inv[MSLOT_ARMOUR];
- if (armour != NON_ITEM && mitm[armour].base_type == OBJ_ARMOUR)
- {
- // check for ego resistance
- if (get_armour_ego_type( mitm[armour] ) == SPARM_POSITIVE_ENERGY)
- u += 1;
- }
- }
-
- return (u);
-} // end mons_res_negative_energy()
-
-bool mons_is_evil( const monsters *mon )
-{
- return (mons_class_flag( mon->type, M_EVIL ));
-}
-
-bool mons_is_unholy( const monsters *mon )
-{
- const mon_holy_type holy = mons_holiness( mon );
-
- return (holy == MH_UNDEAD || holy == MH_DEMONIC);
-}
-
-bool mons_has_lifeforce( const monsters *mon )
-{
- const int holy = mons_holiness( mon );
-
- return (holy == MH_NATURAL || holy == MH_PLANT);
- // && !mons_has_ench( mon, ENCH_PETRIFY ));
-}
-
-int mons_skeleton(int mc)
-{
- if (mons_zombie_size(mc) == 0
- || mons_weight(mc) == 0 || ((smc->bitfields & M_NO_SKELETON) != 0))
- {
- return (0);
- }
-
- return (1);
-} // end mons_skeleton()
-
-char mons_class_flies(int mc)
-{
- if (mc == MONS_PANDEMONIUM_DEMON)
- return (ghost.values[ GVAL_DEMONLORD_FLY ]);
-
- int f = smc->bitfields;
-
- if (f & M_FLIES)
- return (1);
-
- if (f & M_LEVITATE)
- return (2);
-
- return (0);
-}
-
-char mons_flies( struct monsters *mon )
-{
- char ret = mons_class_flies( mon->type );
-
- return (ret ? ret : (scan_mon_inv_randarts(mon, RAP_LEVITATE) > 0) ? 2 : 0);
-} // end mons_flies()
-
-
-// this nice routine we keep in exactly the way it was
-int hit_points(int hit_dice, int min_hp, int rand_hp)
-{
- int hrolled = 0;
-
- for (int hroll = 0; hroll < hit_dice; hroll++)
- {
- hrolled += random2(1 + rand_hp);
- hrolled += min_hp;
- }
-
- return (hrolled);
-} // end hit_points()
-
-// This function returns the standard number of hit dice for a type
-// of monster, not a pacticular monsters current hit dice. -- bwr
-int mons_type_hit_dice( int type )
-{
- struct monsterentry *mon_class = seekmonster( type );
-
- if (mon_class)
- return (mon_class->hpdice[0]);
-
- return (0);
-}
-
-
-int exper_value( struct monsters *monster )
-{
- long x_val = 0;
-
- // these three are the original arguments:
- const int mclass = monster->type;
- const int mHD = monster->hit_dice;
- const int maxhp = monster->max_hit_points;
-
- // these are some values we care about:
- const int speed = mons_speed(mclass);
- const int modifier = mons_exp_mod(mclass);
- const int item_usage = mons_itemuse(mclass);
-
- // XXX: shapeshifters can qualify here, even though they can't cast:
- const bool spellcaster = mons_class_flag( mclass, M_SPELLCASTER );
-
- // early out for no XP monsters
- if (mons_class_flag(mclass, M_NO_EXP_GAIN))
- return (0);
-
- // These undead take damage to maxhp, so we use only HD. -- bwr
- if (mclass == MONS_ZOMBIE_SMALL
- || mclass == MONS_ZOMBIE_LARGE
- || mclass == MONS_SIMULACRUM_SMALL
- || mclass == MONS_SIMULACRUM_LARGE
- || mclass == MONS_SKELETON_SMALL
- || mclass == MONS_SKELETON_LARGE)
- {
- x_val = (16 + mHD * 4) * (mHD * mHD) / 10;
- }
- else
- {
- x_val = (16 + maxhp) * (mHD * mHD) / 10;
- }
-
-
- // Let's calculate a simple difficulty modifier -- bwr
- int diff = 0;
-
- // Let's look for big spells:
- if (spellcaster)
- {
- const int msecc = ((mclass == MONS_HELLION) ? MST_BURNING_DEVIL :
- (mclass == MONS_PANDEMONIUM_DEMON) ? MST_GHOST
- : monster->number);
-
- int hspell_pass[6] = { MS_NO_SPELL, MS_NO_SPELL, MS_NO_SPELL,
- MS_NO_SPELL, MS_NO_SPELL, MS_NO_SPELL };
-
- mons_spell_list( msecc, hspell_pass );
-
- for (int i = 0; i < 6; i++)
- {
- switch (hspell_pass[i])
- {
- case MS_PARALYSIS:
- case MS_SMITE:
- case MS_HELLFIRE_BURST:
- case MS_HELLFIRE:
- case MS_TORMENT:
- case MS_IRON_BOLT:
- diff += 25;
- break;
-
- case MS_LIGHTNING_BOLT:
- case MS_NEGATIVE_BOLT:
- case MS_VENOM_BOLT:
- case MS_STICKY_FLAME:
- case MS_DISINTEGRATE:
- case MS_SUMMON_DEMON_GREATER:
- case MS_BANISHMENT:
- case MS_CRYSTAL_SPEAR:
- case MS_TELEPORT:
- case MS_TELEPORT_OTHER:
- diff += 10;
- break;
-
- default:
- break;
- }
- }
- }
-
- // let's look at regeneration
- if (monster_descriptor( mclass, MDSC_REGENERATES ))
- diff += 15;
-
- // Monsters at normal or fast speed with big melee damage
- if (speed >= 10)
- {
- int max_melee = 0;
- for (int i = 0; i < 4; i++)
- max_melee += mons_damage( mclass, i );
-
- if (max_melee > 30)
- diff += (max_melee / ((speed == 10) ? 2 : 1));
- }
-
- // Monsters who can use equipment (even if only the equipment
- // they are given) can be considerably enhanced because of
- // the way weapons work for monsters. -- bwr
- if (item_usage == MONUSE_STARTING_EQUIPMENT
- || item_usage == MONUSE_WEAPONS_ARMOUR)
- {
- diff += 30;
- }
-
- // Set a reasonable range on the difficulty modifier...
- // Currently 70% - 200% -- bwr
- if (diff > 100)
- diff = 100;
- else if (diff < -30)
- diff = -30;
-
- // Apply difficulty
- x_val *= (100 + diff);
- x_val /= 100;
-
- // Basic speed modification
- if (speed > 0)
- {
- x_val *= speed;
- x_val /= 10;
- }
-
- // Slow monsters without spells and items often have big HD which
- // cause the experience value to be overly large... this tries
- // to reduce the inappropriate amount of XP that results. -- bwr
- if (speed < 10 && !spellcaster && item_usage < MONUSE_STARTING_EQUIPMENT)
- {
- x_val /= 2;
- }
-
- // Apply the modifier in the monster's definition
- if (modifier > 0)
- {
- x_val *= modifier;
- x_val /= 10;
- }
-
- // Reductions for big values. -- bwr
- if (x_val > 100)
- x_val = 100 + ((x_val - 100) * 3) / 4;
- if (x_val > 1000)
- x_val = 1000 + (x_val - 1000) / 2;
-
- // guarantee the value is within limits
- if (x_val <= 0)
- x_val = 1;
- else if (x_val > 15000)
- x_val = 15000;
-
- return (x_val);
-} // end exper_value()
-
-void mons_spell_list(const monsters *monster, int splist[6])
-{
- int msecc = ((monster->type == MONS_HELLION) ? MST_BURNING_DEVIL :
- (monster->type == MONS_PANDEMONIUM_DEMON) ? MST_GHOST
- : monster->number);
- return mons_spell_list(msecc, splist);
-}
-
-// this needs to be rewritten a la the monsterseek rewrite {dlb}:
-void mons_spell_list( int sec, int splist[6] )
-{
- unsigned int x;
-
- for (x = 0; x < NUM_MSTYPES; x++)
- {
- if (mspell_list[x][0] == sec)
- break;
- }
-
- if (x >= NUM_MSTYPES)
- return;
-
- // I *KNOW* this can easily be done in a loop
- splist[0] = mspell_list[x][1]; // bolt spell
- splist[1] = mspell_list[x][2]; // enchantment
- splist[2] = mspell_list[x][3]; // self_ench
- splist[3] = mspell_list[x][4]; // misc
- splist[4] = mspell_list[x][5]; // misc2
- splist[5] = mspell_list[x][6]; // emergency
-
- if (sec == MST_GHOST) /* ghost */
- {
- for (x = 0; x < 6; x++)
- splist[x] = ghost.values[ GVAL_SPELL_1 + x ];
- }
-} // end mons_spell_list()
-
-#if DEBUG_DIAGNOSTICS
-const char *mons_spell_name( int spell )
-{
- if (spell == MS_NO_SPELL || spell >= NUM_MONSTER_SPELLS || spell < 0)
- return ("No spell");
-
- return (monster_spell_name[ spell ]);
-}
-#endif
-
-// generate a shiny new and unscarred monster
-void define_monster(int k)
-{
- int temp_rand = 0; // probability determination {dlb}
- int m2_class = menv[k].type;
- int m2_HD, m2_hp, m2_hp_max, m2_AC, m2_ev, m2_speed;
- int m2_sec = menv[k].number;
- struct monsterentry *m = seekmonster(m2_class);
-
- m2_HD = m->hpdice[0];
-
- // misc
- m2_AC = m->AC;
- m2_ev = m->ev;
-
- // speed
- m2_speed = m->speed;
-
- // some monsters are randomized:
- // did I get them all? // I don't think so {dlb}
- if (mons_is_mimic( m2_class ))
- m2_sec = get_mimic_colour( &menv[k] );
- else
- {
- switch (m2_class)
- {
- case MONS_ABOMINATION_SMALL:
- m2_HD = 4 + random2(4);
- m2_AC = 3 + random2(7);
- m2_ev = 7 + random2(6);
- m2_speed = 7 + random2avg(9, 2);
-
- if (m2_sec == 250)
- m2_sec = random_colour();
- break;
-
- case MONS_ZOMBIE_SMALL:
- m2_HD = (coinflip() ? 1 : 2);
- break;
-
- case MONS_ZOMBIE_LARGE:
- m2_HD = 3 + random2(5);
- break;
-
- case MONS_ABOMINATION_LARGE:
- m2_HD = 8 + random2(4);
- m2_AC = 5 + random2avg(9, 2);
- m2_ev = 3 + random2(5);
- m2_speed = 6 + random2avg(7, 2);
-
- if (m2_sec == 250)
- m2_sec = random_colour();
- break;
-
- case MONS_BEAST:
- m2_HD = 4 + random2(4);
- m2_AC = 2 + random2(5);
- m2_ev = 7 + random2(5);
- m2_speed = 8 + random2(5);
- break;
-
- case MONS_HYDRA:
- m2_sec = 4 + random2(5);
- break;
-
- case MONS_DEEP_ELF_FIGHTER:
- case MONS_DEEP_ELF_KNIGHT:
- case MONS_DEEP_ELF_SOLDIER:
- case MONS_ORC_WIZARD:
- m2_sec = MST_ORC_WIZARD_I + random2(3);
- break;
-
- case MONS_LICH:
- case MONS_ANCIENT_LICH:
- m2_sec = MST_LICH_I + random2(4);
- break;
-
- case MONS_HELL_KNIGHT:
- m2_sec = (coinflip() ? MST_HELL_KNIGHT_I : MST_HELL_KNIGHT_II);
- break;
-
- case MONS_NECROMANCER:
- m2_sec = (coinflip() ? MST_NECROMANCER_I : MST_NECROMANCER_II);
- break;
-
- case MONS_WIZARD:
- case MONS_OGRE_MAGE:
- case MONS_EROLCHA:
- case MONS_DEEP_ELF_MAGE:
- m2_sec = MST_WIZARD_I + random2(5);
- break;
-
- case MONS_DEEP_ELF_CONJURER:
- m2_sec = (coinflip()? MST_DEEP_ELF_CONJURER_I : MST_DEEP_ELF_CONJURER_II);
- break;
-
- case MONS_BUTTERFLY:
- case MONS_SPATIAL_VORTEX:
- case MONS_KILLER_KLOWN:
- m2_sec = random_colour();
- break;
-
- case MONS_GILA_MONSTER:
- temp_rand = random2(7);
-
- m2_sec = (temp_rand >= 5 ? LIGHTRED : // 2/7
- temp_rand >= 3 ? LIGHTMAGENTA : // 2/7
- temp_rand == 2 ? RED : // 1/7
- temp_rand == 1 ? MAGENTA // 1/7
- : YELLOW); // 1/7
- break;
-
- case MONS_HUMAN:
- case MONS_ELF:
- // these are supposed to only be created by polymorph
- m2_HD += random2(10);
- m2_AC += random2(5);
- m2_ev += random2(5);
- break;
-
- default:
- break;
- }
- }
-
- // some calculations
- m2_hp = hit_points(m2_HD, m->hpdice[1], m->hpdice[2]);
- m2_hp += m->hpdice[3];
- m2_hp_max = m2_hp;
-
- if (m2_sec == 250)
- m2_sec = m->sec;
-
- // so let it be written, so let it be done
- menv[k].hit_dice = m2_HD;
- menv[k].hit_points = m2_hp;
- menv[k].max_hit_points = m2_hp_max;
- menv[k].armour_class = m2_AC;
- menv[k].evasion = m2_ev;
- menv[k].speed = m2_speed;
- menv[k].speed_increment = 70;
- menv[k].number = m2_sec;
- menv[k].flags = 0;
-
- // reset monster enchantments
- for (int i = 0; i < NUM_MON_ENCHANTS; i++)
- menv[k].enchantment[i] = ENCH_NONE;
-} // end define_monster()
-
-
-/* ------------------------- monam/moname ------------------------- */
-const char *ptr_monam( struct monsters *mon, char desc )
-{
- // We give an item type description for mimics now, note that
- // since gold mimics only have one description (to match the
- // examine code in direct.cc), we won't bother going through
- // this for them. -- bwr
- if (mons_is_mimic( mon->type ) && mon->type != MONS_GOLD_MIMIC)
- {
- static char mimic_name_buff[ ITEMNAME_SIZE ];
-
- item_def item;
- get_mimic_item( mon, item );
- item_name( item, desc, mimic_name_buff );
-
- return (mimic_name_buff);
- }
-
- return (monam( mon->number, mon->type, player_monster_visible( mon ),
- desc, mon->inv[MSLOT_WEAPON] ));
-}
-
-const char *monam( int mons_num, int mons, bool vis, char desc, int mons_wpn )
-{
- static char gmo_n[ ITEMNAME_SIZE ];
- char gmo_n2[ ITEMNAME_SIZE ] = "";
-
- gmo_n[0] = '\0';
-
- // If you can't see the critter, let moname() print [Ii]t.
- if (!vis)
- {
- moname( mons, vis, desc, gmo_n );
- return (gmo_n);
- }
-
- // These need their description level handled here instead of
- // in monam().
- if (mons == MONS_SPECTRAL_THING)
- {
- switch (desc)
- {
- case DESC_CAP_THE:
- strcpy(gmo_n, "The");
- break;
- case DESC_NOCAP_THE:
- strcpy(gmo_n, "the");
- break;
- case DESC_CAP_A:
- strcpy(gmo_n, "A");
- break;
- case DESC_NOCAP_A:
- strcpy(gmo_n, "a");
- break;
- case DESC_PLAIN: /* do nothing */ ;
- break;
- //default: DEBUGSTR("bad desc flag");
- }
- }
-
- switch (mons)
- {
- case MONS_ZOMBIE_SMALL:
- case MONS_ZOMBIE_LARGE:
- moname(mons_num, vis, desc, gmo_n);
- strcat(gmo_n, " zombie");
- break;
-
- case MONS_SKELETON_SMALL:
- case MONS_SKELETON_LARGE:
- moname(mons_num, vis, desc, gmo_n);
- strcat(gmo_n, " skeleton");
- break;
-
- case MONS_SIMULACRUM_SMALL:
- case MONS_SIMULACRUM_LARGE:
- moname(mons_num, vis, desc, gmo_n);
- strcat(gmo_n, " simulacrum");
- break;
-
- case MONS_SPECTRAL_THING:
- strcat(gmo_n, " spectral ");
- moname(mons_num, vis, DESC_PLAIN, gmo_n2);
- strcat(gmo_n, gmo_n2);
- break;
-
- case MONS_DANCING_WEAPON:
- // safety check -- if we don't have/know the weapon use default name
- if (mons_wpn == NON_ITEM)
- moname( mons, vis, desc, gmo_n );
- else
- {
- item_def item = mitm[mons_wpn];
- unset_ident_flags( item, ISFLAG_KNOW_CURSE | ISFLAG_KNOW_PLUSES );
- item_name( item, desc, gmo_n );
- }
- break;
-
- case MONS_PLAYER_GHOST:
- strcpy(gmo_n, ghost.name);
- strcat(gmo_n, "'s ghost");
- break;
-
- case MONS_PANDEMONIUM_DEMON:
- strcpy(gmo_n, ghost.name);
- break;
-
- default:
- moname(mons, vis, desc, gmo_n);
- break;
- }
-
- return (gmo_n);
-} // end monam()
-
-const char *moname(int mons_num, bool vis, char descrip, char glog[ ITEMNAME_SIZE ])
-{
- glog[0] = '\0';
-
- char gmon_name[ ITEMNAME_SIZE ] = "";
- strcpy( gmon_name, seekmonster( mons_num )->name );
-
- if (!vis)
- {
- switch (descrip)
- {
- case DESC_CAP_THE:
- case DESC_CAP_A:
- strcpy(glog, "It");
- break;
- case DESC_NOCAP_THE:
- case DESC_NOCAP_A:
- case DESC_PLAIN:
- strcpy(glog, "it");
- break;
- }
-
- strcpy(gmon_name, glog);
- return (glog);
- }
-
- if (!mons_is_unique( mons_num ))
- {
- switch (descrip)
- {
- case DESC_CAP_THE:
- strcpy(glog, "The ");
- break;
- case DESC_NOCAP_THE:
- strcpy(glog, "the ");
- break;
- case DESC_CAP_A:
- strcpy(glog, "A");
- break;
- case DESC_NOCAP_A:
- strcpy(glog, "a");
- break;
- case DESC_PLAIN:
- break;
- // default: DEBUGSTR("bad monster descrip flag");
- }
-
- if (descrip == DESC_CAP_A || descrip == DESC_NOCAP_A)
- {
- switch (toupper(gmon_name[0]))
- {
- case 'A':
- case 'E':
- case 'I':
- case 'O':
- case 'U':
- strcat(glog, "n ");
- break;
-
- default:
- strcat(glog, " ");
- break;
- }
- }
- }
-
- strcat(glog, gmon_name);
-
- return (glog);
-} // end moname()
-
-/* ********************* END PUBLIC FUNCTIONS ********************* */
-
-// see mons_init for initialization of mon_entry array.
-static monsterentry *seekmonster(int p_monsterid)
-{
- int me = mon_entry[p_monsterid];
-
- if (me >= 0) // PARANOIA
- return (&mondata[me]);
- else
- return (NULL);
-} // end seekmonster()
-
-static int mons_exp_mod(int mc)
-{
- return (smc->exp_mod);
-} // end mons_exp_mod()
-
-
-int mons_speed(int mc)
-{
- return (smc->speed);
-} // end mons_speed()
-
-
-int mons_intel(int mc) //jmf: "fixed" to work with new I_ types
-{
- switch (smc->intel)
- {
- case I_PLANT:
- return (I_PLANT);
- case I_INSECT:
- case I_REPTILE:
- return (I_INSECT);
- case I_ANIMAL:
- case I_ANIMAL_LIKE:
- return (I_ANIMAL);
- case I_NORMAL:
- return (I_NORMAL);
- case I_HIGH:
- return (I_HIGH);
- default:
- return (I_NORMAL);
- }
-} // ens mons_intel()
-
-
-int mons_intel_type(int mc) //jmf: new, used by my spells
-{
- return (smc->intel);
-} // end mons_intel_type()
-
-int mons_power(int mc)
-{
- // for now, just return monster hit dice.
- return (smc->hpdice[0]);
-}
-
-bool mons_aligned(int m1, int m2)
-{
- bool fr1, fr2;
- struct monsters *mon1, *mon2;
-
- if (m1 == MHITNOT || m2 == MHITNOT)
- return (true);
-
- if (m1 == MHITYOU)
- fr1 = true;
- else
- {
- mon1 = &menv[m1];
- fr1 = (mon1->attitude == ATT_FRIENDLY) || mons_has_ench(mon1, ENCH_CHARM);
- }
-
- if (m2 == MHITYOU)
- fr2 = true;
- else
- {
- mon2 = &menv[m2];
- fr2 = (mon2->attitude == ATT_FRIENDLY) || mons_has_ench(mon2, ENCH_CHARM);
- }
-
- return (fr1 == fr2);
-}
-
-bool mons_friendly(const monsters *m)
-{
- return (m->attitude == ATT_FRIENDLY || mons_has_ench(m, ENCH_CHARM));
-}
-
-bool mons_is_paralysed(const monsters *m)
-{
- return (m->speed_increment == 0);
-}
-
-bool mons_is_confused(const monsters *m)
-{
- return (mons_has_ench(m, ENCH_CONFUSION) &&
- !mons_class_flag(m->type, M_CONFUSED));
-}
-
-bool mons_is_fleeing(const monsters *m)
-{
- return (m->behaviour == BEH_FLEE);
-}
-
-bool mons_is_sleeping(const monsters *m)
-{
- return (m->behaviour == BEH_SLEEP);
-}
-
-bool mons_is_batty(const monsters *m)
-{
- return testbits(m->flags, MF_BATTY);
-}
-
-bool mons_looks_stabbable(const monsters *m)
-{
- // Make sure oklob plants are never highlighted. That'll defeat the
- // point of making them look like normal plants.
- return (!mons_class_flag(m->type, M_NO_EXP_GAIN)
- && m->type != MONS_OKLOB_PLANT
- && !mons_is_mimic(m->type)
- && !mons_friendly(m)
- && mons_is_sleeping(m));
-}
-
-bool mons_looks_distracted(const monsters *m)
-{
- return (!mons_class_flag(m->type, M_NO_EXP_GAIN)
- && m->type != MONS_OKLOB_PLANT
- && !mons_is_mimic(m->type)
- && !mons_friendly(m)
- && ((m->foe != MHITYOU && !mons_is_batty(m))
- || mons_is_confused(m)
- || mons_is_fleeing(m)));
-}
-
-/* ******************************************************************
-
-// In the name of England, I declare this function wasteful! {dlb}
-
-static monsterentry *seekmonster( int mc )
-{
-
- ASSERT(mc >= 0);
-
- int x = 0;
-
- while (x < mondatasize)
- {
- if (mondata[x].mc == mc)
- return &mondata[x];
-
- x++;
- }
-
- ASSERT(false);
-
- return seekmonster(MONS_PROGRAM_BUG); // see the disasters coming if there is no 250?
-
-} // end seekmonster()
-****************************************************************** */
-
-
-/* ******************************************************************
-
-// only used once, and internal to this file, to boot {dlb}:
-
-// These are easy to implement here. The difficult (dull!) work of converting
-// the data structures is finally finished now!
-inline char *mons_name( int mc )
-{
-
- return smc->name;
-
-} // end mons_name()
-****************************************************************** */
-
-/*****************************************************************
-
- Used to determine whether or not a monster should fire a beam (MUST be
- called _after_ fire_tracer() for meaningful result.
-
-*/
-
-bool mons_should_fire(struct bolt &beam)
-{
- // use of foeRatio:
- // the higher this number, the more monsters
- // will _avoid_ collateral damage to their friends.
- // setting this to zero will in fact have all
- // monsters ignore their friends when considering
- // collateral damage.
-
- // quick check - did we in fact get any foes?
- if (beam.foe_count == 0)
- return (false);
-
- // if we either hit no friends, or monster too dumb to care
- if (beam.fr_count == 0 || !beam.smart_monster)
- return (true);
-
- // only fire if they do acceptably low collateral damage
- // the default for this is 50%; in other words, don't
- // hit a foe unless you hit 2 or fewer friends.
- if (beam.foe_power >= (beam.foe_ratio * beam.fr_power) / 100)
- return (true);
-
- return (false);
-}
-
-int mons_has_ench(const monsters *mon, unsigned int ench, unsigned int ench2)
-{
- // silliness
- if (ench == ENCH_NONE)
- return (ench);
-
- if (ench2 == ENCH_NONE)
- ench2 = ench;
-
- for (int p = 0; p < NUM_MON_ENCHANTS; p++)
- {
- if (mon->enchantment[p] >= ench && mon->enchantment[p] <= ench2)
- return (mon->enchantment[p]);
- }
-
- return (ENCH_NONE);
-}
-
-// Returning the deleted enchantment is important! See abjuration. -- bwr
-int mons_del_ench( struct monsters *mon, unsigned int ench, unsigned int ench2,
- bool quiet )
-{
- unsigned int p;
- int ret_val = ENCH_NONE;
-
- // silliness
- if (ench == ENCH_NONE)
- return (ENCH_NONE);
-
- if (ench2 == ENCH_NONE)
- ench2 = ench;
-
- for (p = 0; p < NUM_MON_ENCHANTS; p++)
- {
- if (mon->enchantment[p] >= ench && mon->enchantment[p] <= ench2)
- break;
- }
-
- if (p == NUM_MON_ENCHANTS)
- return (ENCH_NONE);
-
- ret_val = mon->enchantment[p];
- mon->enchantment[p] = ENCH_NONE;
-
- // check for slow/haste
- if (ench == ENCH_HASTE)
- {
- if (mon->speed >= 100)
- mon->speed = 100 + ((mon->speed - 100) / 2);
- else
- mon->speed /= 2;
- }
-
- if (ench == ENCH_SLOW)
- {
- if (mon->speed >= 100)
- mon->speed = 100 + ((mon->speed - 100) * 2);
- else
- mon->speed *= 2;
- }
-
- if (ench == ENCH_FEAR)
- {
- if (!quiet)
- simple_monster_message(mon, " seems to regain its courage.");
-
- // reevaluate behaviour
- behaviour_event(mon, ME_EVAL);
- }
-
- if (ench == ENCH_CONFUSION)
- {
- if (!quiet)
- simple_monster_message(mon, " seems less confused.");
-
- // reevaluate behaviour
- behaviour_event(mon, ME_EVAL);
- }
-
- if (ench == ENCH_INVIS)
- {
- // invisible monsters stay invisible
- if (mons_class_flag(mon->type, M_INVIS))
- {
- mon->enchantment[p] = ENCH_INVIS;
- }
- else if (mons_near(mon) && !player_see_invis()
- && !mons_has_ench( mon, ENCH_SUBMERGED ))
- {
- if (!quiet)
- {
- strcpy( info, ptr_monam( mon, DESC_CAP_A ) );
- strcat( info, " appears!" );
- mpr( info );
- }
- }
- }
-
- if (ench == ENCH_CHARM)
- {
- if (!quiet)
- simple_monster_message(mon, " is no longer charmed.");
-
- // reevaluate behaviour
- behaviour_event(mon, ME_EVAL);
- }
-
- if (ench == ENCH_BACKLIGHT_I)
- {
- if (!quiet)
- simple_monster_message(mon, " stops glowing.");
- }
-
- if (ench == ENCH_STICKY_FLAME_I || ench == ENCH_YOUR_STICKY_FLAME_I)
- {
- if (!quiet)
- simple_monster_message(mon, " stops burning.");
- }
-
- if (ench == ENCH_POISON_I || ench == ENCH_YOUR_POISON_I)
- {
- if (!quiet)
- simple_monster_message(mon, " looks more healthy.");
- }
-
- if (ench == ENCH_YOUR_ROT_I)
- {
- if (!quiet)
- simple_monster_message(mon, " is no longer rotting.");
- }
-
- return (ret_val);
-}
-
-bool mons_add_ench(struct monsters *mon, unsigned int ench)
-{
- // silliness
- if (ench == ENCH_NONE)
- return (false);
-
- int newspot = -1;
-
- // don't double-add
- for (int p = 0; p < NUM_MON_ENCHANTS; p++)
- {
- if (mon->enchantment[p] == ench)
- return (true);
-
- if (mon->enchantment[p] == ENCH_NONE && newspot < 0)
- newspot = p;
- }
-
- if (newspot < 0)
- return (false);
-
- mon->enchantment[newspot] = ench;
-// if ench == ENCH_FEAR //mv: withou this fear & repel undead spell doesn't work
-
-
- // check for slow/haste
- if (ench == ENCH_HASTE)
- {
- if (mon->speed >= 100)
- mon->speed = 100 + ((mon->speed - 100) * 2);
- else
- mon->speed *= 2;
- }
-
- if (ench == ENCH_SLOW)
- {
- if (mon->speed >= 100)
- mon->speed = 100 + ((mon->speed - 100) / 2);
- else
- mon->speed /= 2;
- }
-
- return (true);
-}
-
-// used to determine whether or not a monster should always
-// fire this spell if selected. If not, we should use a
-// tracer.
-
-// note - this function assumes that the monster is "nearby"
-// its target!
-
-bool ms_requires_tracer(int monspell)
-{
- bool requires = false;
-
- switch(monspell)
- {
- case MS_BANISHMENT:
- case MS_COLD_BOLT:
- case MS_CONFUSE:
- case MS_CRYSTAL_SPEAR:
- case MS_DISINTEGRATE:
- case MS_ENERGY_BOLT:
- case MS_FIRE_BOLT:
- case MS_FIREBALL:
- case MS_FLAME:
- case MS_FROST:
- case MS_HELLFIRE:
- case MS_IRON_BOLT:
- case MS_LIGHTNING_BOLT:
- case MS_MARSH_GAS:
- case MS_MIASMA:
- case MS_METAL_SPLINTERS:
- case MS_MMISSILE:
- case MS_NEGATIVE_BOLT:
- case MS_ORB_ENERGY:
- case MS_PAIN:
- case MS_PARALYSIS:
- case MS_POISON_BLAST:
- case MS_POISON_ARROW:
- case MS_POISON_SPLASH:
- case MS_QUICKSILVER_BOLT:
- case MS_SLOW:
- case MS_STEAM_BALL:
- case MS_STICKY_FLAME:
- case MS_STING:
- case MS_STONE_ARROW:
- case MS_TELEPORT_OTHER:
- case MS_VENOM_BOLT:
- requires = true;
- break;
-
- // self-niceties and direct effects
- case MS_ANIMATE_DEAD:
- case MS_BLINK:
- case MS_BRAIN_FEED:
- case MS_DIG:
- case MS_FAKE_RAKSHASA_SUMMON:
- case MS_HASTE:
- case MS_HEAL:
- case MS_HELLFIRE_BURST:
- case MS_INVIS:
- case MS_LEVEL_SUMMON:
- case MS_MUTATION:
- case MS_SMITE:
- case MS_SUMMON_BEAST:
- case MS_SUMMON_DEMON_LESSER:
- case MS_SUMMON_DEMON:
- case MS_SUMMON_DEMON_GREATER:
- case MS_SUMMON_UFETUBUS:
- case MS_TELEPORT:
- case MS_TORMENT:
- case MS_VAMPIRE_SUMMON:
- case MS_CANTRIP:
-
- // meaningless, but sure, why not?
- case MS_NO_SPELL:
- break;
-
- default:
- break;
-
- }
-
- return (requires);
-}
-
-// returns true if the spell is something you wouldn't want done if
-// you had a friendly target.. only returns a meaningful value for
-// non-beam spells
-
-bool ms_direct_nasty(int monspell)
-{
- bool nasty = true;
-
- switch(monspell)
- {
- // self-niceties/summonings
- case MS_ANIMATE_DEAD:
- case MS_BLINK:
- case MS_DIG:
- case MS_FAKE_RAKSHASA_SUMMON:
- case MS_HASTE:
- case MS_HEAL:
- case MS_INVIS:
- case MS_LEVEL_SUMMON:
- case MS_SUMMON_BEAST:
- case MS_SUMMON_DEMON_LESSER:
- case MS_SUMMON_DEMON:
- case MS_SUMMON_DEMON_GREATER:
- case MS_SUMMON_UFETUBUS:
- case MS_TELEPORT:
- case MS_VAMPIRE_SUMMON:
- nasty = false;
- break;
-
- case MS_BRAIN_FEED:
- case MS_HELLFIRE_BURST:
- case MS_MUTATION:
- case MS_SMITE:
- case MS_TORMENT:
-
- // meaningless, but sure, why not?
- case MS_NO_SPELL:
- break;
-
- default:
- break;
-
- }
-
- return (nasty);
-}
-
-// Spells a monster may want to cast if fleeing from the player, and
-// the player is not in sight.
-bool ms_useful_fleeing_out_of_sight( struct monsters *mon, int monspell )
-{
- if (ms_waste_of_time( mon, monspell ))
- return (false);
-
- switch (monspell)
- {
- case MS_HASTE:
- case MS_INVIS:
- case MS_HEAL:
- case MS_ANIMATE_DEAD:
- return (true);
-
- case MS_VAMPIRE_SUMMON:
- case MS_SUMMON_UFETUBUS:
- case MS_FAKE_RAKSHASA_SUMMON:
- case MS_LEVEL_SUMMON:
- case MS_SUMMON_DEMON:
- case MS_SUMMON_DEMON_LESSER:
- case MS_SUMMON_BEAST:
- case MS_SUMMON_UNDEAD:
- case MS_SUMMON_DEMON_GREATER:
- if (one_chance_in(10)) // only summon friends some of the time
- return (true);
- break;
-
- default:
- break;
- }
-
- return (false);
-}
-
-bool ms_low_hitpoint_cast( struct monsters *mon, int monspell )
-{
- bool ret = false;
-
- bool targ_adj = false;
-
- if (mon->foe == MHITYOU || mon->foe == MHITNOT)
- {
- if (adjacent(you.x_pos, you.y_pos, mon->x, mon->y))
- targ_adj = true;
- }
- else if (adjacent( menv[mon->foe].x, menv[mon->foe].y, mon->x, mon->y ))
- {
- targ_adj = true;
- }
-
- switch (monspell)
- {
- case MS_TELEPORT:
- case MS_TELEPORT_OTHER:
- case MS_HEAL:
- ret = true;
- break;
-
- case MS_BLINK:
- if (targ_adj)
- ret = true;
- break;
-
- case MS_VAMPIRE_SUMMON:
- case MS_SUMMON_UFETUBUS:
- case MS_FAKE_RAKSHASA_SUMMON:
- if (!targ_adj)
- ret = true;
- break;
- }
-
- return (ret);
-}
-
-// Checks to see if a particular spell is worth casting in the first place.
-bool ms_waste_of_time( struct monsters *mon, int monspell )
-{
- bool ret = false;
- int intel, est_magic_resist, power, diff;
- struct monsters *targ;
-
-
- // Eventually, we'll probably want to be able to have monsters
- // learn which of their elemental bolts were resisted and have those
- // handled here as well. -- bwr
- switch (monspell)
- {
- case MS_HASTE:
- if (mons_has_ench( mon, ENCH_HASTE ))
- ret = true;
- break;
-
- case MS_INVIS:
- if (mons_has_ench( mon, ENCH_INVIS ))
- ret = true;
- break;
-
- case MS_HEAL:
- if (mon->hit_points > mon->max_hit_points / 2)
- ret = true;
- break;
-
- case MS_TELEPORT:
- // Monsters aren't smart enough to know when to cancel teleport.
- if (mons_has_ench( mon, ENCH_TP_I, ENCH_TP_IV ))
- ret = true;
- break;
-
- case MS_TELEPORT_OTHER:
- // Monsters aren't smart enough to know when to cancel teleport.
- if (mon->foe == MHITYOU)
- {
- if (you.duration[DUR_TELEPORT])
- return (true);
- }
- else if (mon->foe != MHITNOT)
- {
- if (mons_has_ench( &menv[mon->foe], ENCH_TP_I, ENCH_TP_IV))
- return (true);
- }
- // intentional fall-through
-
- case MS_SLOW:
- case MS_CONFUSE:
- case MS_PAIN:
- case MS_BANISHMENT:
- case MS_DISINTEGRATE:
- case MS_PARALYSIS:
- // occasionally we don't estimate... just fire and see:
- if (one_chance_in(5))
- return (false);
-
- // Only intelligent monsters estimate.
- intel = mons_intel( mon->type );
- if (intel != I_NORMAL && intel != I_HIGH)
- return (false);
-
- // We'll estimate the target's resistance to magic, by first getting
- // the actual value and then randomizing it.
- est_magic_resist = (mon->foe == MHITNOT) ? 10000 : 0;
-
- if (mon->foe != MHITNOT)
- {
- if (mon->foe == MHITYOU)
- est_magic_resist = player_res_magic();
- else
- {
- targ = &menv[ mon->foe ];
- est_magic_resist = mons_resist_magic( targ );
- }
-
- // now randomize (normal intels less accurate than high):
- if (intel == I_NORMAL)
- est_magic_resist += random2(80) - 40;
- else
- est_magic_resist += random2(30) - 15;
- }
-
- power = 12 * mon->hit_dice * (monspell == MS_PAIN ? 2 : 1);
- power = stepdown_value( power, 30, 40, 100, 120 );
-
- // Determine the amount of chance allowed by the benefit from
- // the spell. The estimated difficulty is the probability
- // of rolling over 100 + diff on 2d100. -- bwr
- diff = (monspell == MS_PAIN
- || monspell == MS_SLOW
- || monspell == MS_CONFUSE) ? 0 : 50;
-
- if (est_magic_resist - power > diff)
- ret = true;
-
- break;
-
- default:
- break;
- }
-
- return (ret);
-}
-
-static bool ms_ranged_spell( int monspell )
-{
- switch (monspell)
- {
- case MS_HASTE:
- case MS_HEAL:
- case MS_TELEPORT:
- case MS_INVIS:
- case MS_BLINK:
- return (false);
-
- default:
- break;
- }
-
- return (true);
-}
-
-bool mons_has_ranged_spell( struct monsters *mon )
-{
- const int mclass = mon->type;
-
- if (mons_class_flag( mclass, M_SPELLCASTER ))
- {
- const int msecc = ((mclass == MONS_HELLION) ? MST_BURNING_DEVIL :
- (mclass == MONS_PANDEMONIUM_DEMON) ? MST_GHOST
- : mon->number);
-
- int hspell_pass[6] = { MS_NO_SPELL, MS_NO_SPELL, MS_NO_SPELL,
- MS_NO_SPELL, MS_NO_SPELL, MS_NO_SPELL };
-
- mons_spell_list( msecc, hspell_pass );
-
- for (int i = 0; i < 6; i++)
- {
- if (ms_ranged_spell( hspell_pass[i] ))
- return (true);
- }
- }
-
- return (false);
-}
-
-bool mons_has_ranged_attack( struct monsters *mon )
-{
- const int weapon = mon->inv[MSLOT_WEAPON];
- const int ammo = mon->inv[MSLOT_MISSILE];
-
- const int lnchClass = (weapon != NON_ITEM) ? mitm[weapon].base_type : -1;
- const int lnchType = (weapon != NON_ITEM) ? mitm[weapon].sub_type : 0;
-
- const int ammoClass = (ammo != NON_ITEM) ? mitm[ammo].base_type : -1;
- const int ammoType = (ammo != NON_ITEM) ? mitm[ammo].sub_type : 0;
-
- bool launched = false;
- bool thrown = false;
-
- throw_type( lnchClass, lnchType, ammoClass, ammoType, launched, thrown );
-
- if (launched || thrown)
- return (true);
-
- return (false);
-}
-
-
-// use of variant:
-// 0 : She is tap dancing.
-// 1 : It seems she is tap dancing. (lower case pronoun)
-// 2 : Her sword explodes! (upper case possessive)
-// 3 : It sticks to her sword! (lower case possessive)
-// ... as needed
-
-const char *mons_pronoun(int mon_type, int variant)
-{
- int gender = GENDER_NEUTER;
-
- if (mons_is_unique( mon_type ))
- {
- switch(mon_type)
- {
- case MONS_JESSICA:
- case MONS_PSYCHE:
- case MONS_JOSEPHINE:
- case MONS_AGNES:
- case MONS_MAUD:
- case MONS_LOUISE:
- case MONS_FRANCES:
- case MONS_MARGERY:
- case MONS_EROLCHA:
- case MONS_ERICA:
- gender = GENDER_FEMALE;
- break;
- default:
- gender = GENDER_MALE;
- break;
- }
- }
-
- switch(variant)
- {
- case PRONOUN_CAP:
- return ((gender == 0) ? "It" :
- (gender == 1) ? "He" : "She");
-
- case PRONOUN_NOCAP:
- return ((gender == 0) ? "it" :
- (gender == 1) ? "he" : "she");
-
- case PRONOUN_CAP_POSSESSIVE:
- return ((gender == 0) ? "Its" :
- (gender == 1) ? "His" : "Her");
-
- case PRONOUN_NOCAP_POSSESSIVE:
- return ((gender == 0) ? "its" :
- (gender == 1) ? "his" : "her");
-
- case PRONOUN_REFLEXIVE: // awkward at start of sentence, always lower
- return ((gender == 0) ? "itself" :
- (gender == 1) ? "himself" : "herself");
- }
-
- return ("");
-}
-
-/*
- * Checks if the monster can use smiting/torment to attack without unimpeded
- * LOS to the player.
- */
-static bool mons_can_smite(const monsters *monster)
-{
- if (monster->type == MONS_FIEND)
- return (true);
-
- int hspell_pass[6] = { MS_NO_SPELL, MS_NO_SPELL, MS_NO_SPELL,
- MS_NO_SPELL, MS_NO_SPELL, MS_NO_SPELL };
- mons_spell_list(monster, hspell_pass);
- for (unsigned i = 0; i < sizeof(hspell_pass) / sizeof(hspell_pass[0]); ++i)
- if (hspell_pass[i] == MS_TORMENT || hspell_pass[i] == MS_SMITE)
- return (true);
-
- return (false);
-}
-
-/*
- * Determines if a monster is smart and pushy enough to displace other monsters.
- * A shover should not cause damage to the shovee by displacing it, so monsters
- * that trail clouds of badness are ineligible. The shover should also benefit
- * from shoving, so monsters that can smite/torment are ineligible.
- *
- * (Smiters would be eligible for shoving when fleeing if the AI allowed for
- * smart monsters to flee.)
- */
-bool monster_shover(const monsters *m)
-{
- const monsterentry *me = seekmonster(m->type);
- if (!me)
- return (false);
-
- // Efreet and fire elementals are disqualified because they leave behind
- // clouds of flame.
- if (m->type == MONS_EFREET || m->type == MONS_FIRE_ELEMENTAL
- || m->type == MONS_ROTTING_DEVIL)
- return (false);
-
- if (mons_can_smite(m))
- return (false);
-
- int mchar = me->showchar;
- // Somewhat arbitrary: giants and dragons are too big to get past anything,
- // beetles are too dumb (arguable), dancing weapons can't communicate, eyes
- // aren't pushers and shovers, zombies are zombies. Worms and elementals
- // are on the list because all 'w' are currently unrelated.
- return (mchar != 'C' && mchar != 'B' && mchar != '(' && mchar != 'D'
- && mchar != 'G' && mchar != 'Z' && mchar != 'z'
- && mchar != 'w' && mchar != '#');
-}
-
-// Returns true if m1 and m2 are related, and m1 is higher up the totem pole
-// than m2. The criteria for being related are somewhat loose, as you can see
-// below.
-bool monster_senior(const monsters *m1, const monsters *m2)
-{
- const monsterentry *me1 = seekmonster(m1->type),
- *me2 = seekmonster(m2->type);
-
- if (!me1 || !me2)
- return (false);
-
- int mchar1 = me1->showchar,
- mchar2 = me2->showchar;
-
- // If both are demons, the smaller number is the nastier demon.
- if (isdigit(mchar1) && isdigit(mchar2))
- return (mchar1 < mchar2);
-
- // &s are the evillest demons of all, well apart from Geryon, who really
- // profits from *not* pushing past beasts.
- if (mchar1 == '&' && isdigit(mchar2) && m1->type != MONS_GERYON)
- return (m1->hit_dice > m2->hit_dice);
-
- // Skeletal warriors can push past zombies large and small.
- if (m1->type == MONS_SKELETAL_WARRIOR && (mchar2 == 'z' || mchar2 == 'Z'))
- return (m1->hit_dice > m2->hit_dice);
-
- if (m1->type == MONS_QUEEN_BEE
- && (m2->type == MONS_KILLER_BEE
- || m2->type == MONS_KILLER_BEE_LARVA))
- return (true);
-
- if (m1->type == MONS_KILLER_BEE && m2->type == MONS_KILLER_BEE_LARVA)
- return (true);
-
- // Special-case gnolls so they can't get past (hob)goblins
- if (m1->type == MONS_GNOLL && m2->type != MONS_GNOLL)
- return (false);
-
- return (mchar1 == mchar2 && m1->hit_dice > m2->hit_dice);
-}
diff --git a/stone_soup/crawl-ref/source/mon-util.h b/stone_soup/crawl-ref/source/mon-util.h
deleted file mode 100644
index c3f55c8d50..0000000000
--- a/stone_soup/crawl-ref/source/mon-util.h
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
- * File: mon-util.h
- * Summary: Misc monster related functions.
- * Written by: Linley Henzell
- *
- * Modified for Crawl Reference by $Author$ on $Date$
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef MONUTIL_H
-#define MONUTIL_H
-
-#include "externs.h"
-#include "enum.h"
-
-// ($pellbinder) (c) D.G.S.E. 1998
-
-// zombie size
-#define Z_NOZOMBIE 0 // no zombie (and no skeleton)
-#define Z_SMALL 1
-#define Z_BIG 2
-// Note - this should be set to 0 for classed monsters, eg orc wizard
-
-// shout
-#define S_RANDOM -1
-#define S_SILENT 0
-#define S_SHOUT 1 //1=shout
-#define S_BARK 2 //2=bark
-#define S_SHOUT2 3 //3=shout twice
-#define S_ROAR 4 //4=roar
-#define S_SCREAM 5 //5=scream
-#define S_BELLOW 6 //6=bellow (?)
-#define S_SCREECH 7 //7=screech
-#define S_BUZZ 8 //8=buzz
-#define S_MOAN 9 //9=moan
-#define S_WHINE 10 //10=irritating whine (mosquito)
-#define S_CROAK 11 //11=frog croak
-#define S_GROWL 12 //jmf: for bears
-#define S_HISS 13 //bwr: for snakes and lizards
-
-// ai
-// So far this only affects a) chance to see stealthy player and b) chance to
-// walk through damaging clouds (LRH)
-//jmf: now has relevence to mind-affecting spells, maybe soon behaviour
-#define I_PLANT 0
-#define I_INSECT 1
-#define I_ANIMAL 2
-#define I_NORMAL 3
-#define I_HIGH 4
-#define I_ANIMAL_LIKE 5
-#define I_REPTILE 6
-
-
-// [dshaligram] PACKED is *not* relevant; the amount of padding space it
-// saves is not enough to merit it.
-struct monsterentry
-{
- short mc; // monster number
-
- unsigned char showchar, colour;
- const char *name /*[32]*/; //longest is 23 till now (31 is max alowed here)
-
- unsigned long bitfields;
- unsigned long resists;
-
- short weight;
- // experience is calculated like this:
- // ((((max_hp / 7) + 1) * (mHD * mHD) + 1) * exp_mod) / 10
- // ^^^^^^ see below at hpdice
- // Note that this may make draining attacks less attractive (LRH)
- char exp_mod;
-
- monster_type genus, // "team" the monster plays for
- species; // corpse type of the monster
-
- mon_holy_type holiness; // -1=holy,0=normal,1=undead,2=very very evil
-
- short resist_magic; // (positive is ??)
- // max damage in a turn is total of these four?
-
- unsigned char damage[4];
-
-// hpdice[4]: [0]=HD [1]=min_hp [2]=rand_hp [3]=add_hp
-// min hp = [0]*[1]+[3] & max hp = [0]*([1]+[2])+[3])
-// example: the Iron Golem, hpdice={15,7,4,0}
-// 15*7 < hp < 15*(7+4),
-// 105 < hp < 165
-// hp will be around 135 each time. (assuming an good random number generator)
-// !!!!!!! The system is exactly the same as before, only the way of writing changed !!!!
- unsigned char hpdice[4]; // until we have monsters with 32767 hp,this is easily possible
-
- char AC; // armour class
-
- char ev; // evasion
-
- char speed, speed_inc; // duh!
-
- short sec; // not used (250) most o/t time
-
- // eating the corpse: 1=clean,2=might be contaminated,3=poison,4=very bad
- corpse_effect_type corpse_thingy;
- // 0=no zombie, 1=small zombie (z) 107, 2=_BIG_ zombie (Z) 108
- char zombie_size;
- // 0-12: see above, -1=random one of (0-7)
- char shouts;
- // AI things?
- char intel; // 0=none, 1=worst...4=best
-
- char gmon_use;
-}; // mondata[] - again, no idea why this was externed {dlb}
-
-
-// wow. this struct is only about 48 bytes, (excluding the name)
-
-
-// last updated 10jun2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void init_monsters( FixedVector<unsigned short, 1000>& colour );
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: bang - beam - debug - direct - effects - fight - item_use -
- * monstuff - mstuff2 - ouch - spells1 - spells2 - spells3 -
- * spells4
- * *********************************************************************** */
-// mons_wpn only important for dancing weapons -- bwr
-const char *monam(int mons_num, int mons, bool vis, char desc, int mons_wpn = NON_ITEM);
-
-// these front for monam
-const char *ptr_monam( struct monsters *mon, char desc );
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: beam - direct - fight - monstuff - mstuff2 - spells4 - view
- * *********************************************************************** */
-char mons_class_flies( int mc );
-char mons_flies( struct monsters *mon );
-
-
-// last updated XXmay2000 {dlb}
-/* ***********************************************************************
- * called from: dungeon - monstuff
- * *********************************************************************** */
-char mons_itemuse(int mc);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: beam - fight - monstuff - view
- * *********************************************************************** */
-char mons_see_invis( struct monsters *mon );
-
-bool mons_monster_visible( struct monsters *mon, struct monsters *targ );
-bool mons_player_visible( struct monsters *mon );
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: view
- * *********************************************************************** */
-int mons_shouts(int mclass);
-
-bool mons_is_unique(int mclass);
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: describe - fight
- * *********************************************************************** */
-// int exper_value(int mclass, int mHD, int maxhp);
-int exper_value( struct monsters *monster );
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: dungeon - mon-util
- * *********************************************************************** */
-int hit_points(int hit_dice, int min_hp, int rand_hp);
-
-int mons_type_hit_dice( int type );
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: beam - effects
- * *********************************************************************** */
-int mons_resist_magic( struct monsters *mon );
-int mons_resist_turn_undead( struct monsters *mon );
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: fight - monstuff
- * *********************************************************************** */
-int mons_damage(int mc, int rt);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: food - spells4
- * *********************************************************************** */
-corpse_effect_type mons_corpse_effect(int mc);
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: dungeon - fight - monstuff - mon-util
- * *********************************************************************** */
-bool mons_class_flag(int mc, int bf);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: beam - effects - fight - monstuff - mstuff2 - spells2 -
- * spells3 - spells4
- * *********************************************************************** */
-mon_holy_type mons_class_holiness(int mclass);
-mon_holy_type mons_holiness(const monsters *);
-
-bool mons_is_mimic( int mc );
-bool mons_is_demon( int mc );
-bool mons_is_humanoid( int mc );
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: monstuff - spells4 - view
- * *********************************************************************** */
-int mons_intel(int mclass);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: spells4
- * *********************************************************************** */
-int mons_intel_type(int mclass); //jmf: added 20mar2000
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: beam - fight - monstuff
- * *********************************************************************** */
-int mons_res_cold( struct monsters *mon );
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: beam - fight - spells4
- * *********************************************************************** */
-int mons_res_elec( struct monsters *mon );
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: beam - fight - monstuff
- * *********************************************************************** */
-int mons_res_fire( struct monsters *mon );
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: beam - monstuff - spells4
- * *********************************************************************** */
-int mons_res_poison( struct monsters *mon );
-
-int mons_res_negative_energy( struct monsters *mon );
-
-bool mons_res_asphyx( const monsters *mon );
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: dungeon - items - spells2 - spells4
- * *********************************************************************** */
-int mons_skeleton(int mcls);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: describe - fight - items - misc - monstuff - mon-util -
- * player - spells2 - spells3
- * *********************************************************************** */
-int mons_weight(int mclass);
-
-
-// last updated 08may2001 {gdl}
-/* ***********************************************************************
- * called from: monplace mon-util
- * *********************************************************************** */
-int mons_speed(int mclass);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: dungeon - mon-util - spells2
- * *********************************************************************** */
-int mons_zombie_size(int mclass);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: bang - beam - monstuff - mstuff2 - spells4 - view
- * *********************************************************************** */
-// unsigned char mons_category(int which_mons);
-
-
-// last updated 07jan2001 (gdl)
-/* ***********************************************************************
- * called from: beam
- * *********************************************************************** */
-int mons_power(int mclass);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: spells2 - view
- * *********************************************************************** */
-unsigned char mons_char(int mc);
-
-
-// last updated 10jun2000 {dlb}
-/* ***********************************************************************
- * called from: dungeon - fight - misc
- * *********************************************************************** */
-unsigned char mons_colour(int mc);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: dungeon - fight
- * *********************************************************************** */
-void define_monster(int mid);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: debug - itemname - mon-util
- * *********************************************************************** */
-const char *moname(int mcl, bool vis, char descrip, char glog[ ITEMNAME_SIZE ]);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: monstuff
- * *********************************************************************** */
-void mons_spell_list(int sec, int splist[6]);
-void mons_spell_list(const monsters *monster, int splist[6]);
-
-#if DEBUG_DIAGNOSTICS
-// last updated 25sep2001 {dlb}
-/* ***********************************************************************
- * called from: describe
- * *********************************************************************** */
-const char *mons_spell_name( int spell );
-#endif
-
-// last updated 4jan2001 (gdl)
-/* ***********************************************************************
- * called from: monstuff
- * *********************************************************************** */
-bool mons_should_fire(struct bolt &beam);
-
-
-// last updated 23mar2001 (gdl)
-/* ***********************************************************************
- * called from: monstuff
- * *********************************************************************** */
-bool ms_direct_nasty(int monspell);
-
-// last updated 14jan2001 (gdl)
-/* ***********************************************************************
- * called from: monstuff
- * *********************************************************************** */
-bool ms_requires_tracer(int mons_spell);
-
-bool ms_useful_fleeing_out_of_sight( struct monsters *mon, int monspell );
-bool ms_waste_of_time( struct monsters *mon, int monspell );
-bool ms_low_hitpoint_cast( struct monsters *mon, int monspell );
-
-bool mons_has_ranged_spell( struct monsters *mon );
-bool mons_has_ranged_attack( struct monsters *mon );
-
-// last updated 06mar2001 (gdl)
-/* ***********************************************************************
- * called from:
- * *********************************************************************** */
-const char *mons_pronoun(int mon_type, int variant);
-
-// last updated 14mar2001 (gdl)
-/* ***********************************************************************
- * called from: monstuff
- * *********************************************************************** */
-bool mons_aligned(int m1, int m2);
-
-// last updated 14mar2001 (gdl)
-/* ***********************************************************************
- * called from: monstuff acr
- * *********************************************************************** */
-bool mons_friendly(const monsters *m);
-
-bool mons_is_confused(const monsters *m);
-bool mons_is_fleeing(const monsters *m);
-bool mons_is_sleeping(const monsters *m);
-bool mons_is_batty(const monsters *m);
-bool mons_is_evil( const monsters *mon );
-bool mons_is_unholy( const monsters *mon );
-bool mons_has_lifeforce( const monsters *mon );
-monster_type mons_genus( int mc );
-monster_type mons_species( int mc );
-
-int mons_has_ench( const monsters *mon, unsigned int ench,
- unsigned int ench2 = ENCH_NONE );
-
-int mons_del_ench( struct monsters *mon, unsigned int ench,
- unsigned int ench2 = ENCH_NONE, bool quiet = false );
-
-bool mons_add_ench( struct monsters *mon, unsigned int ench );
-
-bool mons_looks_stabbable(const monsters *m);
-
-bool mons_looks_distracted(const monsters *m);
-
-bool check_mons_resist_magic( struct monsters *monster, int pow );
-
-bool mons_is_stationary(const monsters *mons);
-
-bool invalid_monster(const monsters *mons);
-
-bool monster_shover(const monsters *m);
-bool mons_is_paralysed(const monsters *m);
-
-bool monster_senior(const monsters *first, const monsters *second);
-monster_type draco_subspecies( const monsters *mon );
-
-#endif
diff --git a/stone_soup/crawl-ref/source/monplace.cc b/stone_soup/crawl-ref/source/monplace.cc
deleted file mode 100644
index 0d1013e3f2..0000000000
--- a/stone_soup/crawl-ref/source/monplace.cc
+++ /dev/null
@@ -1,1405 +0,0 @@
-/*
- * File: monplace.cc
- * Summary: Functions used when placing monsters in the dungeon.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "monplace.h"
-
-#include "externs.h"
-#include "dungeon.h"
-#include "monstuff.h"
-#include "mon-pick.h"
-#include "mon-util.h"
-#include "misc.h"
-#include "player.h"
-#include "stuff.h"
-#include "spells4.h"
-
-// NEW place_monster -- note that power should be set to:
-// 51 for abyss
-// 52 for pandemonium
-// x otherwise
-
-// proximity is the same as for mons_place:
-// 0 is no restrictions
-// 1 attempts to place near player
-// 2 attempts to avoid player LOS
-
-#define BIG_BAND 20
-
-static int band_member(int band, int power);
-static int choose_band( int mon_type, int power, int &band_size );
-static int place_monster_aux(int mon_type, char behaviour, int target,
- int px, int py, int power, int extra, bool first_band_member,
- int dur = 0);
-
-bool place_monster(int &id, int mon_type, int power, char behaviour,
- int target, bool summoned, int px, int py, bool allow_bands,
- int proximity, int extra, int dur)
-{
- int band_size = 0;
- int band_monsters[BIG_BAND]; // band monster types
- int lev_mons = power; // final 'power'
- int count;
- int i;
-
- // set initial id to -1 (unsuccessful create)
- id = -1;
-
- // (1) early out (summoned to occupied grid)
- if (summoned && mgrd[px][py] != NON_MONSTER)
- return (false);
-
- // (2) take care of random monsters
- if (mon_type == RANDOM_MONSTER
- && player_in_branch( BRANCH_HALL_OF_BLADES ))
- {
- mon_type = MONS_DANCING_WEAPON;
- }
-
- if (mon_type == RANDOM_MONSTER)
- {
- if (player_in_branch( BRANCH_MAIN_DUNGEON )
- && lev_mons != 51 && one_chance_in(4))
- {
- lev_mons = random2(power);
- }
-
- if (player_in_branch( BRANCH_MAIN_DUNGEON ) && lev_mons < 28)
- {
- // potentially nasty surprise, but very rare
- if (one_chance_in(5000))
- lev_mons = random2(27);
-
- // slightly out of depth monsters are more common:
- if (one_chance_in(50))
- lev_mons += random2(6);
-
- if (lev_mons > 27)
- lev_mons = 27;
- }
-
- /* Abyss or Pandemonium. Almost never called from Pan;
- probably only if a rand demon gets summon anything spell */
- if (lev_mons == 51
- || you.level_type == LEVEL_PANDEMONIUM
- || you.level_type == LEVEL_ABYSS)
- {
- do
- {
- count = 0;
-
- do
- {
- // was: random2(400) {dlb}
- mon_type = random2(NUM_MONSTERS);
- count++;
- }
- while (mons_abyss(mon_type) == 0 && count < 2000);
-
- if (count == 2000)
- return (false);
- }
- while (random2avg(100, 2) > mons_rare_abyss(mon_type)
- && !one_chance_in(100));
- }
- else
- {
- int level, diff, chance;
-
- if (lev_mons > 30)
- lev_mons = 30;
-
- for (i = 0; i < 10000; i++)
- {
- count = 0;
-
- do
- {
- mon_type = random2(NUM_MONSTERS);
- count++;
- }
- while (mons_rarity(mon_type) == 0 && count < 2000);
-
- if (count == 2000)
- return (false);
-
- level = mons_level( mon_type );
- diff = level - lev_mons;
- chance = mons_rarity( mon_type ) - (diff * diff);
-
- if ((lev_mons >= level - 5 && lev_mons <= level + 5)
- && random2avg(100, 2) <= chance)
- {
- break;
- }
- }
-
- if (i == 10000)
- return (false);
- }
- }
-
- // (3) decide on banding (good lord!)
- band_size = 1;
- band_monsters[0] = mon_type;
-
- if (allow_bands)
- {
- int band = choose_band(mon_type, power, band_size);
- band_size ++;
-
- for (i = 1; i < band_size; i++)
- band_monsters[i] = band_member( band, power );
- }
-
- // Monsters that can't move shouldn't be taking the stairs -- bwr
- if (proximity == PROX_NEAR_STAIRS && mons_speed( mon_type ) == 0)
- proximity = PROX_AWAY_FROM_PLAYER;
-
- // (4) for first monster, choose location. This is pretty intensive.
- bool proxOK;
- bool close_to_player;
-
- // player shoved out of the way?
- bool shoved = false;
- unsigned char stair_gfx = 0;
- int pval = 0;
-
- if (!summoned)
- {
- int tries = 0;
- // try to pick px, py that is
- // a) not occupied
- // b) compatible
- // c) in the 'correct' proximity to the player
- unsigned char grid_wanted = monster_habitat(mon_type);
- while(true)
- {
- tries ++;
- // give up on stair placement?
- if (proximity == PROX_NEAR_STAIRS)
- {
- if (tries > 320)
- {
- proximity = PROX_AWAY_FROM_PLAYER;
- tries = 0;
- }
- }
- else if (tries > 60)
- return (false);
-
- px = 5 + random2(GXM - 10);
- py = 5 + random2(GYM - 10);
-
- // occupied?
- if (mgrd[px][py] != NON_MONSTER
- || (px == you.x_pos && py == you.y_pos))
- {
- continue;
- }
-
- // compatible - floor?
- if (grid_wanted == DNGN_FLOOR && grd[px][py] < DNGN_FLOOR)
- continue;
-
- // compatible - others (must match, except for deep water monsters
- // generated in shallow water)
- if ((grid_wanted != DNGN_FLOOR && grd[px][py] != grid_wanted)
- && (grid_wanted != DNGN_DEEP_WATER || grd[px][py] != DNGN_SHALLOW_WATER))
- {
- continue;
- }
-
- // don't generate monsters on top of teleport traps
- // (how did they get there?)
- int trap = trap_at_xy(px, py);
- if (trap >= 0)
- {
- if (env.trap[trap].type == TRAP_TELEPORT)
- continue;
- }
-
- // check proximity to player
- proxOK = true;
-
- switch (proximity)
- {
- case PROX_ANYWHERE:
- if (grid_distance( you.x_pos, you.y_pos, px, py ) < 2 + random2(3))
- {
- proxOK = false;
- }
- break;
-
- case PROX_CLOSE_TO_PLAYER:
- case PROX_AWAY_FROM_PLAYER:
- close_to_player = (distance(you.x_pos, you.y_pos, px, py) < 64);
-
- if ((proximity == PROX_CLOSE_TO_PLAYER && !close_to_player)
- || (proximity == PROX_AWAY_FROM_PLAYER && close_to_player))
- {
- proxOK = false;
- }
- break;
-
- case PROX_NEAR_STAIRS:
- pval = near_stairs(px, py, 1, stair_gfx);
- if (pval == 2)
- {
- // 0 speed monsters can't shove player out of their way.
- if (mons_speed(mon_type) == 0)
- {
- proxOK = false;
- break;
- }
- // swap the monster and the player spots, unless the
- // monster was generated in lava or deep water.
- if (grd[px][py] == DNGN_LAVA || grd[px][py] == DNGN_DEEP_WATER)
- {
- proxOK = false;
- break;
- }
- shoved = true;
- int tpx = px;
- int tpy = py;
- px = you.x_pos;
- py = you.y_pos;
- you.x_pos = tpx;
- you.y_pos = tpy;
- }
-
- proxOK = (pval > 0);
- break;
- default:
- break;
- }
-
- if (!proxOK)
- continue;
-
- // cool.. passes all tests
- break;
- } // end while.. place first monster
- }
-
- id = place_monster_aux( mon_type, behaviour, target, px, py, lev_mons,
- extra, true );
-
- // now, forget about banding if the first placement failed, or there's too
- // many monsters already, or we successfully placed by stairs
- if (id < 0 || id+30 > MAX_MONSTERS)
- return false;
-
- // message to player from stairwell/gate appearance?
- if (see_grid(px, py) && proximity == PROX_NEAR_STAIRS)
- {
- info[0] = '\0';
-
- if (player_monster_visible( &menv[id] ))
- strcpy(info, ptr_monam( &menv[id], DESC_CAP_A ));
- else if (shoved)
- strcpy(info, "Something");
-
- if (shoved)
- {
- strcat(info, " shoves you out of the ");
- strcat(info, (stair_gfx == '>' || stair_gfx == '<') ? "stairwell!"
- : "gateway!");
- mpr(info);
- }
- else if (info[0] != '\0')
- {
- strcat(info, (stair_gfx == '>') ? " comes up the stairs." :
- (stair_gfx == '<') ? " comes down the stairs."
- : " comes through the gate.");
- mpr(info);
- }
-
- // special case: must update the view for monsters created in player LOS
- viewwindow(1, false);
- }
-
- // monsters placed by stairs don't bring the whole band up/down/through
- // with them
- if (proximity == PROX_NEAR_STAIRS)
- return (true);
-
- // (5) for each band monster, loop call to place_monster_aux().
- for(i = 1; i < band_size; i++)
- {
- place_monster_aux( band_monsters[i], behaviour, target, px, py,
- lev_mons, extra, false, dur );
- }
-
- // placement of first monster, at least, was a success.
- return (true);
-}
-
-static int place_monster_aux( int mon_type, char behaviour, int target,
- int px, int py, int power, int extra,
- bool first_band_member, int dur )
-{
- int id, i;
- char grid_wanted;
- int fx=0, fy=0; // final x,y
-
- // gotta be able to pick an ID
- for (id = 0; id < MAX_MONSTERS; id++)
- {
- if (menv[id].type == -1)
- break;
- }
-
- if (id == MAX_MONSTERS)
- return -1;
-
- // scrap monster inventory
- for (i = 0; i < NUM_MONSTER_SLOTS; i++)
- menv[id].inv[i] = NON_ITEM;
-
- // scrap monster enchantments
- for (i = 0; i < NUM_MON_ENCHANTS; i++)
- menv[id].enchantment[i] = ENCH_NONE;
-
- // setup habitat and placement
- if (first_band_member)
- {
- fx = px;
- fy = py;
- }
- else
- {
- grid_wanted = monster_habitat(mon_type);
-
- // we'll try 1000 times for a good spot
- for (i = 0; i < 1000; i++)
- {
- fx = px + random2(7) - 3;
- fy = py + random2(7) - 3;
-
- // occupied?
- if (mgrd[fx][fy] != NON_MONSTER)
- continue;
-
- // compatible - floor?
- if (grid_wanted == DNGN_FLOOR && grd[fx][fy] < DNGN_FLOOR)
- continue;
-
- // compatible - others (must match, except for deep water monsters
- // generated in shallow water)
- if ((grid_wanted != DNGN_FLOOR && grd[fx][fy] != grid_wanted)
- && (grid_wanted != DNGN_DEEP_WATER || grd[fx][fy] != DNGN_SHALLOW_WATER))
- continue;
-
- // don't generate monsters on top of teleport traps
- // (how do they get there?)
- int trap = trap_at_xy(fx, fy);
- if (trap >= 0)
- if (env.trap[trap].type == TRAP_TELEPORT)
- continue;
-
- // cool.. passes all tests
- break;
- }
-
- // did we really try 1000 times?
- if (i == 1000)
- return (-1);
- }
-
- // now, actually create the monster (wheeee!)
- menv[id].type = mon_type;
- menv[id].number = 250;
-
- menv[id].x = fx;
- menv[id].y = fy;
-
- // link monster into monster grid
- mgrd[fx][fy] = id;
-
- // generate a brand shiny new monster, or zombie
- if (mon_type == MONS_ZOMBIE_SMALL
- || mon_type == MONS_ZOMBIE_LARGE
- || mon_type == MONS_SIMULACRUM_SMALL
- || mon_type == MONS_SIMULACRUM_LARGE
- || mon_type == MONS_SKELETON_SMALL
- || mon_type == MONS_SKELETON_LARGE
- || mon_type == MONS_SPECTRAL_THING)
- {
- define_zombie( id, extra, mon_type, power );
- }
- else
- {
- define_monster(id);
- }
-
- // The return of Boris is now handled in monster_die()...
- // not setting this for Boris here allows for multiple Borises
- // in the dungeon at the same time. -- bwr
- if (mon_type >= MONS_TERENCE && mon_type <= MONS_BORIS)
- you.unique_creatures[mon_type - 280] = 1;
-
- if (extra != 250)
- menv[id].number = extra;
-
- if (mons_class_flag(mon_type, M_INVIS))
- mons_add_ench(&menv[id], ENCH_INVIS);
-
- if (mons_class_flag(mon_type, M_CONFUSED))
- mons_add_ench(&menv[id], ENCH_CONFUSION);
-
- if (mon_type == MONS_SHAPESHIFTER)
- mons_add_ench(&menv[id], ENCH_SHAPESHIFTER);
-
- if (mon_type == MONS_GLOWING_SHAPESHIFTER)
- mons_add_ench(&menv[id], ENCH_GLOWING_SHAPESHIFTER);
-
- if (mon_type == MONS_GIANT_BAT || mon_type == MONS_UNSEEN_HORROR
- || mon_type == MONS_GIANT_BLOWFLY)
- {
- menv[id].flags |= MF_BATTY;
- }
-
- if ((mon_type == MONS_BIG_FISH
- || mon_type == MONS_GIANT_GOLDFISH
- || mon_type == MONS_ELECTRICAL_EEL
- || mon_type == MONS_JELLYFISH
- || mon_type == MONS_WATER_ELEMENTAL
- || mon_type == MONS_SWAMP_WORM)
- && grd[fx][fy] == DNGN_DEEP_WATER
- && !one_chance_in(5))
- {
- mons_add_ench( &menv[id], ENCH_SUBMERGED );
- }
-
- if ((mon_type == MONS_LAVA_WORM
- || mon_type == MONS_LAVA_FISH
- || mon_type == MONS_LAVA_SNAKE
- || mon_type == MONS_SALAMANDER)
- && grd[fx][fy] == DNGN_LAVA
- && !one_chance_in(5))
- {
- mons_add_ench( &menv[id], ENCH_SUBMERGED );
- }
-
- menv[id].flags |= MF_JUST_SUMMONED;
-
- if (mon_type == MONS_DANCING_WEAPON && extra != 1) // ie not from spell
- {
- give_item( id, power );
-
- if (menv[id].inv[MSLOT_WEAPON] != NON_ITEM)
- menv[id].number = mitm[ menv[id].inv[MSLOT_WEAPON] ].colour;
- }
- else if (mons_itemuse(mon_type) >= MONUSE_STARTING_EQUIPMENT)
- {
- give_item( id, power );
-
- // Give these monsters a second weapon -- bwr
- if (mon_type == MONS_TWO_HEADED_OGRE || mon_type == MONS_ETTIN)
- {
- give_item( id, power );
- }
- }
-
-
- // give manticores 8 to 16 spike volleys.
- // they're not spellcasters so this doesn't screw anything up.
- if (mon_type == MONS_MANTICORE)
- menv[id].number = 8 + random2(9);
-
- // set attitude, behaviour and target
- menv[id].attitude = ATT_HOSTILE;
- menv[id].behaviour = behaviour;
- menv[id].foe_memory = 0;
-
- // setting attitude will always make the
- // monster wander.. if you want sleeping
- // hostiles, use BEH_SLEEP since the default
- // attitude is hostile.
- if (behaviour > NUM_BEHAVIOURS)
- {
- if (behaviour == BEH_FRIENDLY || behaviour == BEH_GOD_GIFT)
- menv[id].attitude = ATT_FRIENDLY;
-
- menv[id].behaviour = BEH_WANDER;
- }
-
- // dur should always be ENCH_ABJ_xx
- if (dur >= ENCH_ABJ_I && dur <= ENCH_ABJ_VI)
- mons_add_ench(&menv[id], dur );
-
- menv[id].foe = target;
-
- return (id);
-} // end place_monster_aux()
-
-
-static int choose_band( int mon_type, int power, int &band_size )
-{
- // init
- band_size = 0;
- int band = BAND_NO_BAND;
-
- switch (mon_type)
- {
- case MONS_ORC:
- if (coinflip())
- break;
- // intentional fall-through {dlb}
- case MONS_ORC_WARRIOR:
- band = BAND_ORCS; // orcs
- band_size = 2 + random2(3);
- break;
-
- case MONS_BIG_KOBOLD:
- if (power > 3)
- {
- band = BAND_KOBOLDS;
- band_size = 2 + random2(6);
- }
- break;
-
- case MONS_ORC_WARLORD:
- band_size = 5 + random2(5); // warlords have large bands
- // intentional fall through
- case MONS_ORC_KNIGHT:
- band = BAND_ORC_KNIGHT; // orcs + knight
- band_size += 3 + random2(4);
- break;
-
- case MONS_KILLER_BEE:
- band = BAND_KILLER_BEES; // killer bees
- band_size = 2 + random2(4);
- break;
-
- case MONS_FLYING_SKULL:
- band = BAND_FLYING_SKULLS; // flying skulls
- band_size = 2 + random2(4);
- break;
- case MONS_SLIME_CREATURE:
- band = BAND_SLIME_CREATURES; // slime creatures
- band_size = 2 + random2(4);
- break;
- case MONS_YAK:
- band = BAND_YAKS; // yaks
- band_size = 2 + random2(4);
- break;
- case MONS_UGLY_THING:
- band = BAND_UGLY_THINGS; // ugly things
- band_size = 2 + random2(4);
- break;
- case MONS_HELL_HOUND:
- band = BAND_HELL_HOUNDS; // hell hound
- band_size = 2 + random2(3);
- break;
- case MONS_JACKAL:
- band = BAND_JACKALS; // jackal
- band_size = 1 + random2(3);
- break;
- case MONS_HELL_KNIGHT:
- case MONS_MARGERY:
- band = BAND_HELL_KNIGHTS; // hell knight
- band_size = 4 + random2(4);
- break;
- case MONS_JOSEPHINE:
- case MONS_NECROMANCER:
- case MONS_VAMPIRE_MAGE:
- band = BAND_NECROMANCER; // necromancer
- band_size = 4 + random2(4);
- break;
- case MONS_ORC_HIGH_PRIEST:
- band = BAND_ORC_HIGH_PRIEST; // orc high priest
- band_size = 4 + random2(4);
- break;
- case MONS_GNOLL:
- band = BAND_GNOLLS; // gnoll
- band_size = ((coinflip())? 3 : 2);
- break;
- case MONS_BUMBLEBEE:
- band = BAND_BUMBLEBEES; // bumble bees
- band_size = 2 + random2(4);
- break;
- case MONS_CENTAUR:
- case MONS_CENTAUR_WARRIOR:
- if (power > 9 && one_chance_in(3))
- {
- band = BAND_CENTAURS; // centaurs
- band_size = 2 + random2(4);
- }
- break;
-
- case MONS_YAKTAUR:
- case MONS_YAKTAUR_CAPTAIN:
- if (coinflip())
- {
- band = BAND_YAKTAURS; // yaktaurs
- band_size = 2 + random2(3);
- }
- break;
-
- case MONS_DEATH_YAK:
- band = BAND_DEATH_YAKS; // death yaks
- band_size = 2 + random2(4);
- break;
- case MONS_INSUBSTANTIAL_WISP:
- band = BAND_INSUBSTANTIAL_WISPS; // wisps
- band_size = 4 + random2(5);
- break;
- case MONS_OGRE_MAGE:
- band = BAND_OGRE_MAGE; // ogre mage
- band_size = 4 + random2(4);
- break;
- case MONS_BALRUG:
- band = BAND_BALRUG; // RED gr demon
- band_size = 2 + random2(3);
- break;
- case MONS_CACODEMON:
- band = BAND_CACODEMON; // BROWN gr demon
- band_size = 1 + random2(3);
- break;
-
- case MONS_EXECUTIONER:
- if (coinflip())
- {
- band = BAND_EXECUTIONER; // DARKGREY gr demon
- band_size = 1 + random2(3);
- }
- break;
-
- case MONS_HELLWING:
- if (coinflip())
- {
- band = BAND_HELLWING; // LIGHTGREY gr demon
- band_size = 1 + random2(4);
- }
- break;
-
- case MONS_DEEP_ELF_FIGHTER:
- if (coinflip())
- {
- band = BAND_DEEP_ELF_FIGHTER; // deep elf warrior
- band_size = 3 + random2(4);
- }
- break;
-
- case MONS_DEEP_ELF_KNIGHT:
- if (coinflip())
- {
- band = BAND_DEEP_ELF_KNIGHT; // deep elf knight
- band_size = 3 + random2(4);
- }
- break;
-
- case MONS_DEEP_ELF_HIGH_PRIEST:
- if (coinflip())
- {
- band = BAND_DEEP_ELF_HIGH_PRIEST; // deep elf high priest
- band_size = 3 + random2(4);
- }
- break;
-
- case MONS_KOBOLD_DEMONOLOGIST:
- if (coinflip())
- {
- band = BAND_KOBOLD_DEMONOLOGIST; // kobold demonologist
- band_size = 3 + random2(6);
- }
- break;
-
- case MONS_NAGA_MAGE:
- case MONS_NAGA_WARRIOR:
- band = BAND_NAGAS; // Nagas
- band_size = 3 + random2(4);
- break;
- case MONS_WAR_DOG:
- band = BAND_WAR_DOGS; // war dogs
- band_size = 2 + random2(4);
- break;
- case MONS_GREY_RAT:
- band = BAND_GREY_RATS; // grey rats
- band_size = 4 + random2(6);
- break;
- case MONS_GREEN_RAT:
- band = BAND_GREEN_RATS; // green rats
- band_size = 4 + random2(6);
- break;
- case MONS_ORANGE_RAT:
- band = BAND_ORANGE_RATS; // orange rats
- band_size = 3 + random2(4);
- break;
- case MONS_SHEEP:
- band = BAND_SHEEP; // sheep
- band_size = 3 + random2(5);
- break;
- case MONS_GHOUL:
- band = BAND_GHOULS; // ghoul
- band_size = 2 + random2(3);
- break;
- case MONS_HOG:
- band = BAND_HOGS; // hog
- band_size = 1 + random2(3);
- break;
- case MONS_GIANT_MOSQUITO:
- band = BAND_GIANT_MOSQUITOES; // mosquito
- band_size = 1 + random2(3);
- break;
- case MONS_DEEP_TROLL:
- band = BAND_DEEP_TROLLS; // deep troll
- band_size = 3 + random2(3);
- break;
- case MONS_HELL_HOG:
- band = BAND_HELL_HOGS; // hell-hog
- band_size = 1 + random2(3);
- break;
- case MONS_BOGGART:
- band = BAND_BOGGARTS; // boggart
- band_size = 2 + random2(3);
- break;
- case MONS_BLINK_FROG:
- band = BAND_BLINK_FROGS; // blink frog
- band_size = 2 + random2(3);
- break;
- case MONS_SKELETAL_WARRIOR:
- band = BAND_SKELETAL_WARRIORS; // skeletal warrior
- band_size = 2 + random2(3);
- break;
- // Journey -- Added Draconian Packs
- case MONS_WHITE_DRACONIAN:
- case MONS_RED_DRACONIAN:
- case MONS_PURPLE_DRACONIAN:
- case MONS_MOTTLED_DRACONIAN:
- case MONS_YELLOW_DRACONIAN:
- case MONS_BLACK_DRACONIAN:
- case MONS_GREEN_DRACONIAN:
- case MONS_PALE_DRACONIAN:
- if (power > 18 && one_chance_in(3))
- {
- band = BAND_DRACONIAN;
- band_size = 2 + random2(3);
- }
- break;
- case MONS_DRACONIAN_CALLER:
- case MONS_DRACONIAN_MONK:
- case MONS_DRACONIAN_SCORCHER:
- case MONS_DRACONIAN_KNIGHT:
- case MONS_DRACONIAN_ANNIHILATOR:
- case MONS_DRACONIAN_ZEALOT:
- case MONS_DRACONIAN_SHIFTER:
- if (power > 20)
- {
- band = BAND_DRACONIAN;
- band_size = 3 + random2(4);
- }
- break;
- } // end switch
-
- if (band != BAND_NO_BAND && band_size == 0)
- band = BAND_NO_BAND;
-
- if (band_size >= BIG_BAND)
- band_size = BIG_BAND-1;
-
- return (band);
-}
-
-static int band_member(int band, int power)
-{
- int mon_type = -1;
- int temp_rand;
-
- if (band == BAND_NO_BAND)
- return -1;
-
- switch (band)
- {
- case BAND_KOBOLDS:
- mon_type = MONS_KOBOLD;
- break;
-
- case BAND_ORC_KNIGHT:
- case BAND_ORC_HIGH_PRIEST:
- temp_rand = random2(30);
- mon_type = ((temp_rand > 17) ? MONS_ORC : // 12 in 30
- (temp_rand > 8) ? MONS_ORC_WARRIOR : // 9 in 30
- (temp_rand > 6) ? MONS_WARG : // 2 in 30
- (temp_rand > 4) ? MONS_ORC_WIZARD : // 2 in 30
- (temp_rand > 2) ? MONS_ORC_PRIEST : // 2 in 30
- (temp_rand > 1) ? MONS_OGRE : // 1 in 30
- (temp_rand > 0) ? MONS_TROLL // 1 in 30
- : MONS_ORC_SORCERER); // 1 in 30
- break;
-
- case BAND_KILLER_BEES:
- mon_type = MONS_KILLER_BEE;
- break;
-
- case BAND_FLYING_SKULLS:
- mon_type = MONS_FLYING_SKULL;
- break;
-
- case BAND_SLIME_CREATURES:
- mon_type = MONS_SLIME_CREATURE;
- break;
-
- case BAND_YAKS:
- mon_type = MONS_YAK;
- break;
-
- case BAND_UGLY_THINGS:
- mon_type = ((power > 21 && one_chance_in(4)) ?
- MONS_VERY_UGLY_THING : MONS_UGLY_THING);
- break;
-
- case BAND_HELL_HOUNDS:
- mon_type = MONS_HELL_HOUND;
- break;
-
- case BAND_JACKALS:
- mon_type = MONS_JACKAL;
- break;
-
- case BAND_GNOLLS:
- mon_type = MONS_GNOLL;
- break;
-
- case BAND_BUMBLEBEES:
- mon_type = MONS_BUMBLEBEE;
- break;
-
- case BAND_CENTAURS:
- mon_type = MONS_CENTAUR;
- break;
-
- case BAND_YAKTAURS:
- mon_type = MONS_YAKTAUR;
- break;
-
- case BAND_INSUBSTANTIAL_WISPS:
- mon_type = MONS_INSUBSTANTIAL_WISP;
- break;
-
- case BAND_DEATH_YAKS:
- mon_type = MONS_DEATH_YAK;
- break;
-
- case BAND_NECROMANCER: // necromancer
- temp_rand = random2(13);
- mon_type = ((temp_rand > 9) ? MONS_ZOMBIE_SMALL : // 3 in 13
- (temp_rand > 6) ? MONS_ZOMBIE_LARGE : // 3 in 13
- (temp_rand > 3) ? MONS_SKELETON_SMALL : // 3 in 13
- (temp_rand > 0) ? MONS_SKELETON_LARGE // 3 in 13
- : MONS_NECROPHAGE); // 1 in 13
- break;
-
- case BAND_BALRUG:
- mon_type = (coinflip()? MONS_NEQOXEC : MONS_ORANGE_DEMON);
- break;
-
- case BAND_CACODEMON:
- mon_type = MONS_LEMURE;
- break;
-
- case BAND_EXECUTIONER:
- mon_type = (coinflip() ? MONS_ABOMINATION_SMALL : MONS_ABOMINATION_LARGE);
- break;
-
- case BAND_HELLWING:
- mon_type = (coinflip() ? MONS_HELLWING : MONS_SMOKE_DEMON);
- break;
-
- case BAND_DEEP_ELF_FIGHTER: // deep elf fighter
- temp_rand = random2(11);
- mon_type = ((temp_rand > 4) ? MONS_DEEP_ELF_SOLDIER : // 6 in 11
- (temp_rand == 4) ? MONS_DEEP_ELF_FIGHTER : // 1 in 11
- (temp_rand == 3) ? MONS_DEEP_ELF_KNIGHT : // 1 in 11
- (temp_rand == 2) ? MONS_DEEP_ELF_CONJURER :// 1 in 11
- (temp_rand == 1) ? MONS_DEEP_ELF_MAGE // 1 in 11
- : MONS_DEEP_ELF_PRIEST); // 1 in 11
- break;
-
- case BAND_ORCS:
- mon_type = MONS_ORC;
- if (one_chance_in(5))
- mon_type = MONS_ORC_WIZARD;
- if (one_chance_in(7))
- mon_type = MONS_ORC_PRIEST;
- break;
-
- case BAND_HELL_KNIGHTS:
- mon_type = MONS_HELL_KNIGHT;
- if (one_chance_in(4))
- mon_type = MONS_NECROMANCER;
- break;
-
- //case 12 is orc high priest
-
- case BAND_OGRE_MAGE:
- mon_type = MONS_OGRE;
- if (one_chance_in(3))
- mon_type = MONS_TWO_HEADED_OGRE;
- break; // ogre mage
-
- // comment does not match value (30, TWO_HEADED_OGRE) prior to
- // enum replacement [!!!] 14jan2000 {dlb}
-
- case BAND_DEEP_ELF_KNIGHT: // deep elf knight
- temp_rand = random2(208);
- mon_type =
- ((temp_rand > 159) ? MONS_DEEP_ELF_SOLDIER : // 23.08%
- (temp_rand > 111) ? MONS_DEEP_ELF_FIGHTER : // 23.08%
- (temp_rand > 79) ? MONS_DEEP_ELF_KNIGHT : // 15.38%
- (temp_rand > 51) ? MONS_DEEP_ELF_MAGE : // 13.46%
- (temp_rand > 35) ? MONS_DEEP_ELF_PRIEST : // 7.69%
- (temp_rand > 19) ? MONS_DEEP_ELF_CONJURER : // 7.69%
- (temp_rand > 3) ? MONS_DEEP_ELF_SUMMONER : // 7.69%
- (temp_rand == 3) ? MONS_DEEP_ELF_DEMONOLOGIST :// 0.48%
- (temp_rand == 2) ? MONS_DEEP_ELF_ANNIHILATOR : // 0.48%
- (temp_rand == 1) ? MONS_DEEP_ELF_SORCERER // 0.48%
- : MONS_DEEP_ELF_DEATH_MAGE); // 0.48%
- break;
-
- case BAND_DEEP_ELF_HIGH_PRIEST: // deep elf high priest
- temp_rand = random2(16);
- mon_type =
- ((temp_rand > 12) ? MONS_DEEP_ELF_SOLDIER : // 3 in 16
- (temp_rand > 9) ? MONS_DEEP_ELF_FIGHTER : // 3 in 16
- (temp_rand > 6) ? MONS_DEEP_ELF_PRIEST : // 3 in 16
- (temp_rand == 6) ? MONS_DEEP_ELF_MAGE : // 1 in 16
- (temp_rand == 5) ? MONS_DEEP_ELF_SUMMONER : // 1 in 16
- (temp_rand == 4) ? MONS_DEEP_ELF_CONJURER : // 1 in 16
- (temp_rand == 3) ? MONS_DEEP_ELF_DEMONOLOGIST :// 1 in 16
- (temp_rand == 2) ? MONS_DEEP_ELF_ANNIHILATOR : // 1 in 16
- (temp_rand == 1) ? MONS_DEEP_ELF_SORCERER // 1 in 16
- : MONS_DEEP_ELF_DEATH_MAGE); // 1 in 16
- break;
-
- case BAND_KOBOLD_DEMONOLOGIST:
- temp_rand = random2(13);
- mon_type = ((temp_rand > 4) ? MONS_KOBOLD : // 8 in 13
- (temp_rand > 0) ? MONS_BIG_KOBOLD // 4 in 13
- : MONS_KOBOLD_DEMONOLOGIST);// 1 in 13
- break;
-
- case BAND_NAGAS:
- mon_type = MONS_NAGA;
- break;
- case BAND_WAR_DOGS:
- mon_type = MONS_WAR_DOG;
- break;
- case BAND_GREY_RATS:
- mon_type = MONS_GREY_RAT;
- break;
- case BAND_GREEN_RATS:
- mon_type = MONS_GREEN_RAT;
- break;
- case BAND_ORANGE_RATS:
- mon_type = MONS_ORANGE_RAT;
- break;
- case BAND_SHEEP:
- mon_type = MONS_SHEEP;
- break;
- case BAND_GHOULS:
- mon_type = (coinflip() ? MONS_GHOUL : MONS_NECROPHAGE);
- break;
- case BAND_DEEP_TROLLS:
- mon_type = MONS_DEEP_TROLL;
- break;
- case BAND_HOGS:
- mon_type = MONS_HOG;
- break;
- case BAND_HELL_HOGS:
- mon_type = MONS_HELL_HOG;
- break;
- case BAND_GIANT_MOSQUITOES:
- mon_type = MONS_GIANT_MOSQUITO;
- break;
- case BAND_BOGGARTS:
- mon_type = MONS_BOGGART;
- break;
- case BAND_BLINK_FROGS:
- mon_type = MONS_BLINK_FROG;
- break;
- case BAND_SKELETAL_WARRIORS:
- mon_type = MONS_SKELETAL_WARRIOR;
- break;
- case BAND_DRACONIAN:
- {
- const int temp_rand = random2( (power < 24) ? 24 : 37 );
- mon_type =
- ((temp_rand > 35) ? MONS_DRACONIAN_CALLER : // 1 in 34
- (temp_rand > 33) ? MONS_DRACONIAN_KNIGHT : // 2 in 34
- (temp_rand > 31) ? MONS_DRACONIAN_MONK : // 2 in 34
- (temp_rand > 29) ? MONS_DRACONIAN_SHIFTER : // 2 in 34
- (temp_rand > 27) ? MONS_DRACONIAN_ANNIHILATOR :// 2 in 34
- (temp_rand > 25) ? MONS_DRACONIAN_SCORCHER : // 2 in 34
- (temp_rand > 23) ? MONS_DRACONIAN_ZEALOT : // 2 in 34
- (temp_rand > 20) ? MONS_YELLOW_DRACONIAN : // 3 in 34
- (temp_rand > 17) ? MONS_GREEN_DRACONIAN : // 3 in 34
- (temp_rand > 14) ? MONS_BLACK_DRACONIAN : // 3 in 34
- (temp_rand > 11) ? MONS_WHITE_DRACONIAN : // 3 in 34
- (temp_rand > 8) ? MONS_PALE_DRACONIAN : // 3 in 34
- (temp_rand > 5) ? MONS_PURPLE_DRACONIAN : // 3 in 34
- (temp_rand > 2) ? MONS_MOTTLED_DRACONIAN : // 3 in 34
- MONS_RED_DRACONIAN ); // 3 in 34
- break;
- }
- }
-
- return (mon_type);
-}
-
-// PUBLIC FUNCTION -- mons_place().
-
-int mons_place( int mon_type, char behaviour, int target, bool summoned,
- int px, int py, int level_type, int proximity, int extra,
- int dur )
-{
- int mon_count = 0;
- int temp_rand; // probabilty determination {dlb}
- bool permit_bands = false;
-
- for (int il = 0; il < MAX_MONSTERS; il++)
- {
- if (menv[il].type != -1)
- mon_count++;
- }
-
- if (mon_type == WANDERING_MONSTER)
- {
- if (mon_count > 150)
- return (-1);
-
- mon_type = RANDOM_MONSTER;
- }
-
- // all monsters have been assigned? {dlb}
- if (mon_count > MAX_MONSTERS - 2)
- return (-1);
-
- // this gives a slight challenge to the player as they ascend the
- // dungeon with the Orb
- if (you.char_direction == DIR_ASCENDING && mon_type == RANDOM_MONSTER
- && you.level_type == LEVEL_DUNGEON)
- {
- temp_rand = random2(276);
-
- mon_type = ((temp_rand > 184) ? MONS_WHITE_IMP + random2(15) : // 33.33%
- (temp_rand > 104) ? MONS_HELLION + random2(10) : // 28.99%
- (temp_rand > 78) ? MONS_HELL_HOUND : // 9.06%
- (temp_rand > 54) ? MONS_ABOMINATION_LARGE : // 8.70%
- (temp_rand > 33) ? MONS_ABOMINATION_SMALL : // 7.61%
- (temp_rand > 13) ? MONS_RED_DEVIL // 7.25%
- : MONS_PIT_FIEND); // 5.07%
- }
-
- if (mon_type == RANDOM_MONSTER || level_type == LEVEL_PANDEMONIUM)
- permit_bands = true;
-
- int mid = -1;
-
- // translate level_type
- int power;
-
- switch (level_type)
- {
- case LEVEL_PANDEMONIUM:
- power = 52; // sigh..
- break;
- case LEVEL_ABYSS:
- power = 51;
- break;
- case LEVEL_DUNGEON: // intentional fallthrough
- default:
- power = you.your_level;
- break;
- }
-
- if (place_monster( mid, mon_type, power, behaviour, target, summoned,
- px, py, permit_bands, proximity, extra, dur ) == false)
- {
- return (-1);
- }
-
- if (mid != -1)
- {
- struct monsters *const creation = &menv[mid];
-
- // look at special cases: CHARMED, FRIENDLY, HOSTILE, GOD_GIFT
- // alert summoned being to player's presence
- if (behaviour > NUM_BEHAVIOURS)
- {
- if (behaviour == BEH_FRIENDLY || behaviour == BEH_GOD_GIFT)
- creation->flags |= MF_CREATED_FRIENDLY;
-
- if (behaviour == BEH_GOD_GIFT)
- creation->flags |= MF_GOD_GIFT;
-
- if (behaviour == BEH_CHARMED)
- {
- creation->attitude = ATT_HOSTILE;
- mons_add_ench(creation, ENCH_CHARM);
- }
-
- // make summoned being aware of player's presence
- behaviour_event(creation, ME_ALERT, MHITYOU);
- }
- }
-
- return (mid);
-} // end mons_place()
-
-
-int create_monster( int cls, int dur, int beha, int cr_x, int cr_y,
- int hitting, int zsec )
-{
- int summd = -1;
- FixedVector < char, 2 > empty;
-
- unsigned char spcw = ((cls == RANDOM_MONSTER) ? DNGN_FLOOR
- : monster_habitat( cls ));
-
- empty[0] = 0;
- empty[1] = 0;
-
- // Might be better if we chose a space and tried to match the monster
- // to it in the case of RANDOM_MONSTER, that way if the target square
- // is surrounded by water of lava this function would work. -- bwr
- if (empty_surrounds( cr_x, cr_y, spcw, true, empty ))
- {
- summd = mons_place( cls, beha, hitting, true, empty[0], empty[1],
- you.level_type, 0, zsec, dur );
- }
-
- // determine whether creating a monster is successful (summd != -1) {dlb}:
- // then handle the outcome {dlb}:
- if (summd == -1)
- {
- if (see_grid( cr_x, cr_y ))
- mpr("You see a puff of smoke.");
- }
- else
- {
- struct monsters *const creation = &menv[summd];
-
- // dur should always be ENCH_ABJ_xx
- if (dur >= ENCH_ABJ_I && dur <= ENCH_ABJ_VI)
- mons_add_ench(creation, dur );
-
- // look at special cases: CHARMED, FRIENDLY, HOSTILE, GOD_GIFT
- // alert summoned being to player's presence
- if (beha > NUM_BEHAVIOURS)
- {
- if (beha == BEH_FRIENDLY || beha == BEH_GOD_GIFT)
- creation->flags |= MF_CREATED_FRIENDLY;
-
- if (beha == BEH_GOD_GIFT)
- creation->flags |= MF_GOD_GIFT;
-
- if (beha == BEH_CHARMED)
- {
- creation->attitude = ATT_HOSTILE;
- mons_add_ench(creation, ENCH_CHARM);
- }
-
- // make summoned being aware of player's presence
- behaviour_event(creation, ME_ALERT, MHITYOU);
- }
-
- if (creation->type == MONS_RAKSHASA_FAKE && !one_chance_in(3))
- mons_add_ench(creation, ENCH_INVIS);
- }
-
- // the return value is either -1 (failure of some sort)
- // or the index of the monster placed (if I read things right) {dlb}
- return (summd);
-} // end create_monster()
-
-
-bool empty_surrounds(int emx, int emy, unsigned char spc_wanted,
- bool allow_centre, FixedVector < char, 2 > &empty)
-{
- bool success;
- // assume all player summoning originates from player x,y
- bool playerSummon = (emx == you.x_pos && emy == you.y_pos);
-
- int xpos[25]; // good x pos
- int ypos[25]; // good y pos
- int good_count = 0;
- int count_x, count_y;
-
- char minx = -2;
- char maxx = 2;
- char miny = -2;
- char maxy = 2;
-
- for (count_x = minx; count_x <= maxx; count_x++)
- {
- for (count_y = miny; count_y <= maxy; count_y++)
- {
- success = false;
-
- if (!allow_centre && count_x == 0 && count_y == 0)
- continue;
-
- int tx = emx + count_x;
- int ty = emy + count_y;
-
- if (tx == you.x_pos && ty == you.y_pos)
- continue;
-
- if (mgrd[tx][ty] != NON_MONSTER)
- continue;
-
- // players won't summon out of LOS
- if (!see_grid(tx, ty) && playerSummon)
- continue;
-
- if (grd[tx][ty] == spc_wanted)
- success = true;
-
- // those seeking ground can stand in shallow water or better
- if (spc_wanted == DNGN_FLOOR && grd[tx][ty] >= DNGN_SHALLOW_WATER)
- success = true;
-
- // water monsters can be created in shallow as well as deep water
- if (spc_wanted == DNGN_DEEP_WATER && grd[tx][ty] == DNGN_SHALLOW_WATER)
- success = true;
-
- if (success)
- {
- // add point to list of good points
- xpos[good_count] = tx;
- ypos[good_count] = ty;
- good_count ++;
- }
- } // end "for count_y"
- } // end "for count_x"
-
- if (good_count > 0)
- {
- int pick = random2(good_count);
- empty[0] = xpos[pick];
- empty[1] = ypos[pick];
- }
-
- return (good_count > 0);
-} // end empty_surrounds()
-
-int summon_any_demon(char demon_class)
-{
- int summoned; // error trapping {dlb}
- int temp_rand; // probability determination {dlb}
-
- switch (demon_class)
- {
- case DEMON_LESSER:
- temp_rand = random2(60);
- summoned = ((temp_rand > 49) ? MONS_IMP : // 10 in 60
- (temp_rand > 40) ? MONS_WHITE_IMP : // 9 in 60
- (temp_rand > 31) ? MONS_LEMURE : // 9 in 60
- (temp_rand > 22) ? MONS_UFETUBUS : // 9 in 60
- (temp_rand > 13) ? MONS_MANES : // 9 in 60
- (temp_rand > 4) ? MONS_MIDGE // 9 in 60
- : MONS_SHADOW_IMP); // 5 in 60
- break;
-
- case DEMON_COMMON:
- temp_rand = random2(3948);
- summoned = ((temp_rand > 3367) ? MONS_NEQOXEC : // 14.69%
- (temp_rand > 2787) ? MONS_ORANGE_DEMON : // 14.69%
- (temp_rand > 2207) ? MONS_HELLWING : // 14.69%
- (temp_rand > 1627) ? MONS_SMOKE_DEMON : // 14.69%
- (temp_rand > 1047) ? MONS_YNOXINUL : // 14.69%
- (temp_rand > 889) ? MONS_RED_DEVIL : // 4.00%
- (temp_rand > 810) ? MONS_HELLION : // 2.00%
- (temp_rand > 731) ? MONS_ROTTING_DEVIL : // 2.00%
- (temp_rand > 652) ? MONS_TORMENTOR : // 2.00%
- (temp_rand > 573) ? MONS_REAPER : // 2.00%
- (temp_rand > 494) ? MONS_SOUL_EATER : // 2.00%
- (temp_rand > 415) ? MONS_HAIRY_DEVIL : // 2.00%
- (temp_rand > 336) ? MONS_ICE_DEVIL : // 2.00%
- (temp_rand > 257) ? MONS_BLUE_DEVIL : // 2.00%
- (temp_rand > 178) ? MONS_BEAST : // 2.00%
- (temp_rand > 99) ? MONS_IRON_DEVIL : // 2.00%
- (temp_rand > 49) ? MONS_SUN_DEMON // 1.26%
- : MONS_SHADOW_IMP); // 1.26%
- break;
-
- case DEMON_GREATER:
- temp_rand = random2(1000);
- summoned = ((temp_rand > 868) ? MONS_CACODEMON : // 13.1%
- (temp_rand > 737) ? MONS_BALRUG : // 13.1%
- (temp_rand > 606) ? MONS_BLUE_DEATH : // 13.1%
- (temp_rand > 475) ? MONS_GREEN_DEATH : // 13.1%
- (temp_rand > 344) ? MONS_EXECUTIONER : // 13.1%
- (temp_rand > 244) ? MONS_FIEND : // 10.0%
- (temp_rand > 154) ? MONS_ICE_FIEND : // 9.0%
- (temp_rand > 73) ? MONS_SHADOW_FIEND // 8.1%
- : MONS_PIT_FIEND); // 7.4%
- break;
-
- default:
- summoned = MONS_GIANT_ANT; // this was the original behaviour {dlb}
- break;
- }
-
- return summoned;
-} // end summon_any_demon()
-
-monster_type rand_dragon( dragon_class_type type )
-{
- monster_type summoned = MONS_PROGRAM_BUG;
- int temp_rand;
-
- switch (type)
- {
- case DRAGON_LIZARD:
- temp_rand = random2(100);
- summoned = ((temp_rand > 85) ? MONS_GIANT_GECKO :
- (temp_rand > 59) ? MONS_GIANT_LIZARD :
- (temp_rand > 34) ? MONS_GIANT_IGUANA :
- (temp_rand > 22) ? MONS_GILA_MONSTER :
- (temp_rand > 11) ? MONS_KOMODO_DRAGON :
- (temp_rand > 8) ? MONS_FIREDRAKE :
- (temp_rand > 2) ? MONS_SWAMP_DRAKE
- : MONS_DEATH_DRAKE );
- break;
-
- case DRAGON_DRACONIAN:
- temp_rand = random2(70);
- summoned = ((temp_rand > 60) ? MONS_YELLOW_DRACONIAN :
- (temp_rand > 50) ? MONS_BLACK_DRACONIAN :
- (temp_rand > 40) ? MONS_PALE_DRACONIAN :
- (temp_rand > 30) ? MONS_GREEN_DRACONIAN :
- (temp_rand > 20) ? MONS_PURPLE_DRACONIAN :
- (temp_rand > 10) ? MONS_RED_DRACONIAN
- : MONS_WHITE_DRACONIAN);
- break;
-
- case DRAGON_DRAGON:
- temp_rand = random2(90);
- summoned = ((temp_rand > 80) ? MONS_MOTTLED_DRAGON :
- (temp_rand > 70) ? MONS_LINDWURM :
- (temp_rand > 60) ? MONS_STORM_DRAGON :
- (temp_rand > 50) ? MONS_MOTTLED_DRAGON :
- (temp_rand > 40) ? MONS_STEAM_DRAGON :
- (temp_rand > 30) ? MONS_DRAGON :
- (temp_rand > 20) ? MONS_ICE_DRAGON :
- (temp_rand > 10) ? MONS_SWAMP_DRAGON
- : MONS_SHADOW_DRAGON);
- break;
-
- default:
- break;
- }
-
- return (summoned);
-}
diff --git a/stone_soup/crawl-ref/source/monplace.h b/stone_soup/crawl-ref/source/monplace.h
deleted file mode 100644
index ba45fe36d2..0000000000
--- a/stone_soup/crawl-ref/source/monplace.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * File: monsplace.cc
- * Summary: Functions used when placing monsters in the dungeon.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef MONPLACE_H
-#define MONPLACE_H
-
-#include "enum.h"
-#include "FixVec.h"
-
-// last updated 13mar2001 {gdl}
-/* ***********************************************************************
- * called from: acr - lev-pand - monplace - dungeon
- *
- * Usage:
- * mon_type WANDERING_MONSTER, RANDOM_MONSTER, or monster type
- * behaviour standard behaviours (BEH_ENSLAVED, etc)
- * target MHITYOU, MHITNOT, or monster id
- * extra various things like skeleton/zombie types, colours, etc
- * summoned monster is summoned?
- * px placement x
- * py placement y
- * level_type LEVEL_DUNGEON, LEVEL_ABYSS, LEVEL_PANDEMONIUM.
- * LEVEL_DUNGEON will generate appropriate power monsters
- * proximity 0 = no extra restrictions on monster placement
- * 1 = try to place the monster near the player
- * 2 = don't place the monster near the player
- * 3 = place the monster near stairs (regardless of player pos)
- * *********************************************************************** */
-int mons_place( int mon_type, char behaviour, int target, bool summoned,
- int px, int py, int level_type = LEVEL_DUNGEON,
- int proximity = PROX_ANYWHERE, int extra = 250,
- int dur = 0 );
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - debug - decks - effects - fight - it_use3 - item_use -
- * items - monstuff - mstuff2 - religion - spell - spells -
- * spells2 - spells3 - spells4
- * *********************************************************************** */
-int create_monster( int cls, int dur, int beha, int cr_x, int cr_y,
- int hitting, int zsec );
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: misc - monplace - spells3
- * *********************************************************************** */
-bool empty_surrounds( int emx, int emy, unsigned char spc_wanted,
- bool allow_centre, FixedVector<char, 2>& empty );
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: ability - acr - items - maps - mstuff2 - spell - spells
- * *********************************************************************** */
-int summon_any_demon( char demon_class );
-
-
-// last update 13mar2001 {gdl}
-/* ***********************************************************************
- * called from: dungeon monplace
- *
- * This isn't really meant to be a public function. It is a low level
- * monster placement function used by dungeon building routines and
- * mons_place(). If you need to put a monster somewhere, use mons_place().
- * Summoned creatures can be created with create_monster().
- * *********************************************************************** */
-bool place_monster( int &id, int mon_type, int power, char behaviour,
- int target, bool summoned, int px, int py, bool allow_bands,
- int proximity = PROX_ANYWHERE, int extra = 250,
- int dur = 0 );
-
-monster_type rand_dragon( dragon_class_type type );
-
-#endif // MONPLACE_H
diff --git a/stone_soup/crawl-ref/source/monspeak.cc b/stone_soup/crawl-ref/source/monspeak.cc
deleted file mode 100644
index dd1b9b6ad8..0000000000
--- a/stone_soup/crawl-ref/source/monspeak.cc
+++ /dev/null
@@ -1,2325 +0,0 @@
-/*
- * File: monspeak.cc
- * Summary: Functions to handle speaking monsters
- *
- * Change History (most recent first):
- *
- * <1> 01/09/00 BWR Created
- */
-
-#include "AppHdr.h"
-#include "monspeak.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-#ifdef DOS
-#include <conio.h>
-#endif
-
-#include "externs.h"
-
-#include "beam.h"
-#include "debug.h"
-#include "fight.h"
-#include "insult.h"
-#include "itemname.h"
-#include "misc.h"
-#include "monplace.h"
-#include "monstuff.h"
-#include "mon-util.h"
-#include "mstuff2.h"
-#include "player.h"
-#include "spells2.h"
-#include "spells4.h"
-#include "stuff.h"
-#include "view.h"
-
-// returns true if something is said
-bool mons_speaks(struct monsters *monster)
-{
- int temp_rand; // probability determination
-
- // This function is a little bit of a problem for the message channels
- // since some of the messages it generates are "fake" warning to
- // scare the player. In order to accomidate this intent, we're
- // falsely categorizing various things in the function as spells and
- // danger warning... everything else just goes into the talk channel -- bwr
- int msg_type = MSGCH_TALK;
-
- const char *m_name = ptr_monam(monster, DESC_CAP_THE);
- strcpy(info, m_name);
-
- if (mons_has_ench(monster, ENCH_INVIS))
- return false;
- // invisible monster tries to remain unnoticed
-
- //mv: if it's also invisible, program never gets here
- if (silenced(monster->x, monster->y))
- {
- if (!one_chance_in(3))
- return false; // while silenced, don't bother so often
-
- if (mons_has_ench(monster, ENCH_CONFUSION))
- {
- temp_rand = random2(10);
- strcat(info, (temp_rand < 4) ? " gestures wildly." :
- (temp_rand == 4) ? " looks confused." :
- (temp_rand == 5) ? " grins evilly." :
- (temp_rand == 6) ? " smiles happily." :
- (temp_rand == 7) ? " cries."
- : " says something but you don't hear anything.");
- }
- else if (monster->behaviour == BEH_FLEE)
- {
- temp_rand = random2(10);
- strcat(info,
- (temp_rand < 3) ? " glances furtively about." :
- (temp_rand == 3) ? " opens its mouth, as if shouting." :
- (temp_rand == 4) ? " looks around." :
- (temp_rand == 5) ? " appears indecisive." :
- (temp_rand == 6) ? " ponders the situation."
- : " seems to says something.");
- }
- // disregard charmed critters.. they're not too expressive
- else if (monster->attitude == ATT_FRIENDLY)
- {
- temp_rand = random2(10);
- strcat(info, (temp_rand < 3) ? " gives you a thumbs up." :
- (temp_rand == 3) ? " looks at you." :
- (temp_rand == 4) ? " waves at you." :
- (temp_rand == 5) ? " smiles happily.":
- (temp_rand == 6) ? " winks at you."
- : " says something you can't hear.");
- }
- else
- {
- temp_rand = random2(10);
- strcat(info, (temp_rand < 3) ? " gestures." :
- (temp_rand == 3) ? " gestures obscenely." :
- (temp_rand == 4) ? " grins." :
- (temp_rand == 5) ? " looks angry." :
- (temp_rand == 6) ? " seems to be listening."
- : " says something but you don't hear anything.");
- } //end switch silenced monster's behaviour
-
- mpr(info, MSGCH_TALK);
- return true;
- } // end silenced monster
-
- // charmed monsters aren't too expressive
- if (mons_has_ench(monster, ENCH_CHARM))
- return false;
-
- if (mons_has_ench(monster, ENCH_CONFUSION))
- {
- if (mons_holiness( monster ) == MH_DEMONIC
- && monster->type != MONS_IMP)
- {
- return (false);
- }
-
- if (mons_friendly(monster))
- {
- switch (random2(18)) // speaks for friendly confused monsters
- {
- case 0:
- strcat(info, " prays for help.");
- break;
- case 1:
- strcat(info, " screams, \"Help!\"");
- break;
- case 2:
- strcat(info, " shouts, \"I'm losing control!\"");
- break;
- case 3:
- strcat(info, " shouts, \"What's happening?\"");
- break;
- case 4:
- case 5:
- strcat(info, " gestures wildly.");
- break;
- case 6:
- strcat(info, " cries.");
- break;
- case 7:
- strcat(info, " shouts, \"Yeah!\"");
- break;
- case 8:
- strcat(info, " sings.");
- break;
- case 9:
- strcat(info, " laughs crazily.");
- break;
- case 10:
- strcat(info, " ponders the situation.");
- break;
- case 11:
- strcat(info, " grins madly.");
- break;
- case 12:
- strcat(info, " looks very confused.");
- break;
- case 13:
- strcat(info, " mumbles something.");
- break;
- case 14:
- strcat(info, " giggles crazily.");
- break;
- case 15:
- strcat(info, " screams, \"");
- strcat(info, you.your_name);
- strcat(info, "! Help!\"");
- break;
- case 16:
- strcat(info, " screams, \"");
- strcat(info, you.your_name);
- strcat(info, "! What's going on?\"");
- break;
- case 17:
- strcat(info, " says, \"");
- strcat(info, you.your_name);
- strcat(info, ", I'm little bit confused.\"");
- break;
- }
- }
- else
- {
- switch (random2(23)) // speaks for unfriendly confused monsters
- {
- case 0:
- strcat(info, " yells, \"Get them off of me!\"");
- break;
- case 1:
- strcat(info, " screams, \"I will kill you anyway!\"");
- break;
- case 2:
- strcat(info, " shouts, \"What's happening?\"");
- break;
- case 3:
- case 4:
- case 5:
- strcat(info, " gestures wildly.");
- break;
- case 6:
- strcat(info, " cries.");
- break;
- case 7:
- strcat(info, " shouts, \"NO!\"");
- break;
- case 8:
- strcat(info, " shouts, \"YES!\"");
- break;
- case 9:
- strcat(info, " laughs crazily.");
- break;
- case 10:
- strcat(info, " ponders the situation.");
- break;
- case 11:
- strcat(info, " grins madly.");
- break;
- case 12:
- strcat(info, " looks very confused.");
- break;
- case 13:
- strcat(info, " mumbles something.");
- break;
- case 14:
- strcat(info, " says, \"I'm little bit confused.\"");
- break;
- case 15:
- strcat(info, " asks, \"Where am I?\"");
- break;
- case 16:
- strcat(info, " shakes.");
- break;
- case 17:
- strcat(info, " asks, \"Who are you?\"");
- break;
- case 18:
- strcat(info, " asks, \"What the hell are we doing here? Mmm, I see...\"");
- break;
- case 19:
- strcat(info, " cries, \"My head! MY HEAD!!!\"");
- break;
- case 20:
- strcat(info, " says, \"Why is everything spinning?\"");
- break;
- case 21:
- strcat(info, " screams, \"NO! I can't bear up that noise!\"");
- break;
- case 22:
- strcat(info, " is trying to cover his eyes.");
- break;
- }
- }
-
- }
- else if (monster->behaviour == BEH_FLEE)
- {
- if (mons_holiness( monster ) == MH_DEMONIC
- && monster->type != MONS_IMP)
- {
- return (false);
- }
-
- if (mons_friendly(monster))
- {
- switch (random2(11))
- {
- case 0:
- snprintf( info, INFO_SIZE, "%s %s, \"WAIT FOR ME!\"", m_name,
- coinflip() ? "shouts" : "yells");
- strcat(info, you.your_name);
- strcat(info, ", could you help me?\"");
- break;
- case 1:
- strcat(info, " screams, \"Help!\"");
- break;
- case 2:
- strcat(info, " shouts, \"Cover me!\"");
- break;
- case 3:
- strcat(info, " screams, \"");
- strcat(info, you.your_name);
- strcat(info, "! Help me!\"");
- break;
- case 4:
- case 5:
- case 6:
- strcat(info, " tries to hide somewhere.");
- break;
- case 7:
- strcat(info, " prays for help.");
- break;
- case 8:
- strcat(info, " looks at you beseechingly.");
- break;
- case 9:
- strcat(info, " shouts, \"Protect me!\"");
- break;
- case 10:
- strcat(info, " cries, \"Don't forget your friends!\"");
- break;
- }
- }
- else
- {
- switch (random2(20)) // speaks for unfriendly fleeing monsters
- {
- case 0:
- snprintf( info, INFO_SIZE, "%s %s, \"Help!\"", m_name, coinflip()? "yells" : "wails");
- break;
- case 1:
- snprintf( info, INFO_SIZE, "%s %s, \"Help!\"", m_name,
- coinflip() ? "cries" : "screams"); break;
- case 2:
- snprintf( info, INFO_SIZE, "%s %s, \"Why can't we all just get along?\"",
- m_name, coinflip() ? "begs" : "pleads");
- break;
- case 3:
- snprintf( info, INFO_SIZE, "%s %s trips in trying to escape.", m_name,
- coinflip() ? "nearly" : "almost");
- break;
- case 4:
- snprintf( info, INFO_SIZE, "%s %s, \"Of all the rotten luck!\"", m_name,
- coinflip() ? "mutters" : "mumbles");
- break;
- case 5:
- snprintf( info, INFO_SIZE, "%s %s, \"Oh dear! Oh dear!\"", m_name,
- coinflip() ? "moans" : "wails");
- case 6:
- snprintf( info, INFO_SIZE, "%s %s, \"Damn and blast!\"", m_name,
- coinflip() ? "mutters" : "mumbles");
- break;
- case 7:
- strcat(info, " prays for help.");
- break;
- case 8:
- strcat(info, " shouts, \"No! I'll never do that again!\"");
- break;
- case 9:
- snprintf( info, INFO_SIZE, "%s %s", m_name,
- coinflip() ? "begs for mercy." : "cries, \"Mercy!\"");
- break;
- case 10:
- snprintf( info, INFO_SIZE, "%s %s, \"%s!\"", m_name,
- coinflip() ? "blubbers" : "cries",
- coinflip() ? "Mommeee" : "Daddeee");
- break;
- case 11:
- snprintf( info, INFO_SIZE, "%s %s, \"Please don't kill me!\"", m_name,
- coinflip() ? "begs" : "pleads");
- break;
- case 12:
- snprintf( info, INFO_SIZE, "%s %s, \"Please don't hurt me!\"", m_name,
- coinflip() ? "begs" : "pleads");
- break;
- case 13:
- snprintf( info, INFO_SIZE, "%s %s, \"Please, I have a lot of children...\"",
- m_name, coinflip() ? "begs" : "pleads");
- break;
- case 14:
- strcat(info, " tries to recover lost courage.");
- break;
- case 15:
- case 16:
- case 17:
- strcat(info, " gives up.");
- break;
- case 19:
- snprintf( info, INFO_SIZE, "%s looks really %s.", m_name,
- coinflip() ? "scared stiff" : "rattled");
- break;
- }
- }
- }
- else if (mons_friendly(monster))
- {
- if (mons_holiness( monster ) == MH_DEMONIC
- && monster->type != MONS_IMP)
- {
- return (false);
- }
-
- // friendly imps are too common so they speak very very rarely
- if ((monster->type == MONS_IMP) && (random2(10)))
- return (false);
-
- switch (random2(18))
- {
- case 0:
- strcat(info, " yells, \"Run! I'll cover you!\"");
- break;
- case 1:
- strcat(info, " shouts, \"Die, monster!\"");
- break;
- case 2:
- strcat(info, " says, \"It's nice to have friends.\"");
- break;
-
- case 3:
- strcat(info, " looks at you.");
- break;
- case 4:
- strcat(info, " smiles at you.");
- break;
- case 5:
- strcat(info, " says, \"");
- strcat(info, you.your_name);
- strcat(info, ", you are my only friend.\"");
- break;
- case 6:
- strcat(info, " says, \"");
- strcat(info, you.your_name);
- strcat(info, ", I like you.\"");
- break;
-
- case 7:
- strcat(info, " waves at you.");
- break;
- case 8:
- strcat(info, " says, \"Be careful!\"");
- break;
- case 9:
- strcat(info, " says, \"Don't worry. I'm here with you.\"");
- break;
- case 10:
- strcat(info, " smiles happily.");
- break;
- case 11:
- strcat(info, " shouts, \"No mercy! Kill them all!");
- break;
- case 12:
- strcat(info, " winks at you.");
- break;
- case 13:
- strcat(info, " says, \"Me and you. It sounds cool.\"");
- break;
- case 14:
- strcat(info, " says, \"I'll never leave you.\"");
- break;
- case 15:
- strcat(info, " says, \"I would die for you.\"");
- break;
- case 16:
- strcat(info, " shouts, \"Beware of monsters!\"");
- break;
- case 17:
- strcat(info, " looks friendly.");
- break;
- }
- }
- else
- {
- switch (monster->type)
- {
- case MONS_TERENCE: // fighter who likes to kill
- switch (random2(15))
- {
- case 0:
- strcat(info, " screams, \"I'm going to kill you! \"");
- break;
- case 1:
- strcat(info, " shouts, \"Now you die.\"");
- break;
- case 2:
- strcat(info, " says, \"Rest in peace.\"");
- break;
- case 3:
- snprintf( info, INFO_SIZE, "%s shouts, \"%s!!!\"",
- m_name, coinflip() ? "ATTACK" : "DIE");
- break;
- case 4:
- strcat(info, " says, \"How do you enjoy it?\"");
- break;
- case 5:
- strcat(info, " shouts, \"Get ready for death!\"");
- break;
- case 6:
- strcat(info, " says, \"You are history.\"");
- break;
- case 7:
- strcat(info, " says, \"Do you want it fast or slow?.\"");
- break;
- case 8:
- strcat(info, " says, \"Did you write a testament? You should...\"");
- break;
- case 9:
- strcat(info, " says, \"Time to say good-bye...\"");
- break;
- case 10:
- snprintf( info, INFO_SIZE, "%s says, \"Don't try to defend, it's %s.\"",
- m_name, coinflip() ? "pointless" : "senseless");
- break;
- case 11:
- strcat(info, " bares his teeth.");
- break;
- case 12:
- snprintf( info, INFO_SIZE, "%s says, \"I'll show you few %s.\"",
- m_name, coinflip() ? "tricks" : "ploys.");
- break;
- case 13:
- strcat(info, " screams, \"I want your blood.\"");
- break;
- case 14:
- strcat(info, " looks scornfully at you.");
- break;
- }
- break; // end Terence
-
- case MONS_EDMUND: // mercenaries guarding dungeon
- case MONS_LOUISE:
- case MONS_FRANCES:
- case MONS_DUANE:
- case MONS_ADOLF:
- switch (random2(17))
- {
- case 0:
- strcat(info, " screams, \"I'm going to kill you! Now!\"");
- break;
- case 1:
- strcat(info,
- " shouts, \"Return immediately or I'll kill you!\"");
- break;
- case 2:
- strcat(info,
- " says, \"Now you've reached the end of your journey!\"");
- break;
- case 3:
- strcat(info,
- " screams, \"One false step and I'll kill you!\"");
- break;
- case 4:
- strcat(info, " says, \"Drop everything you've found here and return home.\"");
- break;
- case 5:
- strcat(info, " shouts, \"You will never get the Orb.\"");
- break;
- case 6:
- strcat(info, " looks very unfriendly.");
- break;
- case 7:
- strcat(info, " looks very cold.");
- break;
- case 8:
- strcat(info, " shouts, \"It's the end of the party!\"");
- break;
- case 9:
- strcat(info, " says, \"Return every stolen item!\"");
- break;
- case 10:
- strcat(info, " says, \"No trespassing is allowed here.\"");
- break;
- case 11:
- strcat(info, " grins evilly.");
- break;
- case 12:
- strcat(info, " screams, \"You must be punished!\"");
- break;
- case 13:
- strcat(info, " says, \"It's nothing personal...\"");
- break;
- case 14:
- strcat(info, " says, \"A dead adventurer is good adventurer.\"");
- break;
- case 15:
- strcat(info, " says, \"Coming here was your last mistake.\"");
- break;
- case 16:
- strcat(info, " shouts, \"Intruder!\"");
- break;
- }
- break; // end Edmund & Co
-
- case MONS_JOSEPH:
- switch (random2(16))
- {
- case 0:
- strcat(info, " smiles happily.");
- break;
- case 1:
- strcat(info, " says, \"I'm happy to see you. And I'll be happy to kill you.\"");
- break;
- case 2:
- strcat(info, " says, \"I've waited for this moment for such a long time.\"");
- break;
- case 3:
- strcat(info,
- " says, \"It's nothing personal but I have kill you.\"");
- break;
- case 5:
- strcat(info, " says, \"You will never get the Orb, sorry.\"");
- break;
- case 9:
- strcat(info, " shouts, \"I love to fight! I love killing!\"");
- break;
- case 10:
- strcat(info,
- " says, \"I'm here to kill trespassers. I like my job.\"");
- break;
- case 11:
- strcat(info, " tries to grin evilly.");
- break;
- case 12:
- strcat(info,
- " says, \"You must be punished! Or... I want to punish you!\"");
- break;
- case 13:
- strcat(info,
- " sighs, \"Being guard is usually so boring...\"");
- break;
- case 14:
- strcat(info, " shouts, \"At last some action!\"");
- break;
- case 15:
- strcat(info, " shouts, \"Wow!\"");
- break;
- }
- break; // end Joseph
-
- case MONS_ORC_HIGH_PRIEST: // priest, servants of dark ancient god
- case MONS_DEEP_ELF_HIGH_PRIEST:
- switch (random2(9))
- {
- case 0:
- case 1:
- strcat(info, " prays.");
- msg_type = MSGCH_MONSTER_SPELL;
- break;
-
- case 2:
- strcat(info, " mumbles some strange prayers.");
- msg_type = MSGCH_MONSTER_SPELL;
- break;
-
- case 3:
- strcat(info,
- " shouts, \"You are a heretic and must be destroyed.\"");
- break;
- case 4:
- strcat(info, " says, \"All sinners must die.\"");
- break;
-
- case 5:
- strcat(info, " looks excited.");
- break;
- case 6:
- strcat(info, " says, \"You will make a fine sacrifice.\"");
- break;
- case 7:
- strcat(info, " starts to sing a prayer.");
- break;
- case 8:
- strcat(info, " shouts, \"You must be punished.\"");
- break;
- }
- break; // end priests
-
- case MONS_ORC_SORCERER: // hateful wizards, using strange powers
- case MONS_DEEP_ELF_SORCERER:
- case MONS_WIZARD:
- switch (random2(19))
- {
- case 0:
- case 1:
- case 2:
- strcat(info, " wildly gestures.");
- mpr( info, MSGCH_MONSTER_SPELL );
- if (coinflip())
- canned_msg( MSG_NOTHING_HAPPENS );
- else
- canned_msg( MSG_YOU_RESIST );
- return (true);
-
- case 3:
- case 4:
- case 5:
- strcat(info, " mumbles some strange words.");
- mpr( info, MSGCH_MONSTER_SPELL );
- if (coinflip())
- canned_msg( MSG_NOTHING_HAPPENS );
- else
- canned_msg( MSG_YOU_RESIST );
- return (true);
-
- case 6:
- strcat(info, " shouts, \"You can't withstand my power!\"");
- break;
-
- case 7:
- strcat(info, " shouts, \"You are history.\"");
- break;
-
- case 8:
- simple_monster_message( monster, " casts a spell.",
- MSGCH_MONSTER_SPELL );
-
- strcat(info, " becomes transparent for a moment.");
- msg_type = MSGCH_MONSTER_ENCHANT;
- break;
-
- case 9:
- strcat(info, " throws some strange powder towards you.");
- msg_type = MSGCH_MONSTER_SPELL;
- break;
-
- case 10:
- simple_monster_message( monster, " casts a spell.",
- MSGCH_MONSTER_SPELL );
-
- strcat(info, " glows brightly for a moment.");
- msg_type = MSGCH_MONSTER_ENCHANT;
- break;
-
- case 11:
- strcat(info, " says, \"argatax netranoch dertex\"");
- msg_type = MSGCH_MONSTER_SPELL;
- break;
-
- case 12:
- strcat(info, " says, \"dogrw nutew berg\"");
- msg_type = MSGCH_MONSTER_SPELL;
- break;
-
- case 13:
- strcat(info, " shouts, \"Entram moth deg ulag!\"");
- msg_type = MSGCH_MONSTER_SPELL;
- break;
-
- case 14:
- strcat(info, " casts a spell.");
- mpr(info, MSGCH_MONSTER_SPELL);
-
- strcpy(info, m_name);
- strcat(info, " becomes larger for a moment.");
- msg_type = MSGCH_MONSTER_ENCHANT;
- break;
-
- case 15:
- strcat(info, " casts a spell.");
- mpr(info, MSGCH_MONSTER_SPELL);
-
- strcpy(info, m_name);
- strcat(info, "'s fingertips starts to glow.");
- msg_type = MSGCH_MONSTER_ENCHANT;
- break;
-
- case 16:
- strcat(info, "'s eyes starts to glow.");
- msg_type = MSGCH_MONSTER_SPELL;
- break;
-
- case 17:
- strcat(info, " tries to paralyze you with his gaze.");
- msg_type = MSGCH_MONSTER_SPELL;
- break;
-
- case 18:
- strcat(info, " casts a spell.");
- mpr(info, MSGCH_MONSTER_SPELL);
- canned_msg( MSG_YOU_RESIST );
- return (true);
- }
- break; // end wizards
-
- case MONS_JESSICA: // sorceress disturbed by player
- switch (random2(10))
- {
- case 0:
- strcat(info, " grins evilly.");
- break;
- case 1:
- strcat(info, " says, \"I'm really upset.\"");
- break;
- case 2:
- strcat(info, " shouts, \"I don't like beings like you.\"");
- break;
- case 3:
- strcat(info,
- " shouts, \"Stop bothering me, or I'll kill you!\"");
- break;
- case 4:
- strcat(info, " very coldly says, \"I hate your company.\"");
- break;
- case 5:
- strcat(info, " mumbles something strange.");
- msg_type = MSGCH_MONSTER_SPELL;
- break;
- case 6:
- strcat(info, " looks very angry.");
- break;
- case 7:
- strcat(info,
- " shouts, \"You're disturbing me. I'll have kill you.\"");
- break;
- case 8:
- strcat(info, " screams, \"You are a ghastly nuisance!\"");
- break;
- case 9:
- strcat(info, " gestures wildly.");
- msg_type = MSGCH_MONSTER_SPELL;
- break;
- }
- break; // end Jessica
-
- case MONS_SIGMUND: // mad old wizard
- switch (random2(19))
- {
- case 0:
- case 1:
- case 2:
- strcat(info, " laughs crazily.");
- break;
- case 3:
- strcat(info, " says, \"Don't worry, I'll kill you fast.\"");
- break;
- case 4:
- strcat(info, " grinds his teeth.");
- break;
- case 5:
- strcat(info, " asks, \"Do you like me?\"");
- break;
- case 6:
- strcat(info, " screams, \"Die, monster!\"");
- break;
- case 7:
- strcat(info, " says, \"You will soon forget everything.\"");
- break;
- case 8:
- strcat(info, " screams, \"You will never... NEVER!\"");
- break;
-
- case 9:
- simple_monster_message( monster, " casts a spell.",
- MSGCH_MONSTER_SPELL );
-
- strcat(info, "'s eyes starts to glow with a red light. ");
- msg_type = MSGCH_MONSTER_ENCHANT;
- break;
-
- case 10:
- strcat(info, " says, \"Look in to my eyes.\"");
- break;
- case 11:
- strcat(info, " says, \"I'm your fate.\"");
- break;
-
- case 12:
- simple_monster_message( monster, " casts a spell.",
- MSGCH_MONSTER_SPELL );
-
- strcat(info, " is suddenly surrounded by pale blue light.");
- msg_type = MSGCH_MONSTER_ENCHANT;
- break;
-
- case 13:
- strcat(info, " tries to bite you.");
- break;
-
- case 14:
- simple_monster_message( monster, " casts a spell.",
- MSGCH_MONSTER_SPELL );
-
- strcat(info, " is suddenly surrounded by pale green light.");
- msg_type = MSGCH_MONSTER_ENCHANT;
- break;
-
- case 15:
- strcat(info, " screams, \"I am the angel of Death!\"");
- break;
- case 16:
- strcat(info, " screams, \"Only death can liberate you!\"");
- break;
- case 17:
- strcat(info, " whispers, \"You'll know eternity soon...\"");
- break;
- case 18:
- strcat(info, " screams, \"Don't try to resist!\"");
- break;
- }
- break; // end Sigmund
-
- case MONS_IMP: // small demon
- case MONS_WHITE_IMP:
- case MONS_SHADOW_IMP:
- if (one_chance_in(3))
- {
- imp_taunt( monster );
- return (true);
- }
- else
- {
- switch (random2(11))
- {
- case 0:
- strcat(info, " laughs crazily.");
- break;
- case 1:
- strcat(info, " grins evilly.");
- break;
- case 2:
- strcat(info, " breathes a bit of smoke at you.");
- break;
- case 3:
- strcat(info, " lashes with his tail.");
- break;
- case 4:
- strcat(info, " grinds his teeth.");
- break;
- case 5:
- strcat(info, " sputters.");
- break;
- case 6:
- strcat(info, " breathes some steam toward you.");
- break;
- case 7:
- strcat(info, " spits at you.");
- break;
- case 8:
- strcat(info, " disappears for a moment.");
- break;
- case 9:
- strcat(info, " summons a swarm of flies.");
- break;
- case 10:
- strcat(info, " picks up some beetle and eats it.");
- break;
- }
- }
- break; // end imp
-
- case MONS_TORMENTOR: // cruel devil
- if (one_chance_in(10))
- {
- demon_taunt( monster );
- return (true);
- }
- else
- {
- switch (random2(18))
- {
- case 0:
- strcat(info, " laughs crazily.");
- break;
- case 1:
- strcat(info, " grins evilly.");
- break;
- case 2:
- strcat(info, " says, \"I am all your nightmares come true.\"");
- break;
- case 3:
- strcat(info, " says, \"I will show you what pain is.\"");
- break;
- case 4:
- strcat(info, " shouts, \"I'll tear you apart.\"");
- break;
- case 5:
- strcat(info,
- " says, \"You will wish to die when I get to you.\"");
- break;
- case 6:
- strcat(info, " says, \"I will drown you in your own blood.\"");
- break;
- case 7:
- strcat(info,
- " screams, \"You will die horribly!\"");
- break;
- case 8:
- strcat(info, " says, \"I will eat your liver.\"");
- break;
- case 9:
- strcat(info, " grins madly.");
- break;
- case 10:
- strcat(info, " shouts, \"Prepare for my thousand needles of pain!\"");
- break;
- case 11:
- strcat(info,
- " says, \"I know thousand and one way to kill you.\"");
- break;
- case 12:
- strcat(info,
- " says, \"I'll show you my torture chamber!\"");
- break;
- case 13:
- case 14:
- strcat(info,
- " says, \"I'll crush your bones, one by one.\"");
- break;
- case 15:
- strcat(info, " says, \"I know your fate. It's pain.\"");
- break;
- case 16:
- strcat(info, " says, \"Get ready! Throes await you.\"");
- break;
- case 17:
- strcat(info, " grins malevolently.");
- break;
- }
- }
- break; // end tormentor
-
- case MONS_PANDEMONIUM_DEMON: // named demons
- case MONS_GERYON:
- case MONS_ASMODEUS:
- case MONS_DISPATER:
- case MONS_ANTAEUS:
- case MONS_ERESHKIGAL:
- case MONS_MNOLEG:
- case MONS_LOM_LOBON:
- case MONS_CEREBOV:
- case MONS_GLOORX_VLOQ:
- demon_taunt( monster );
- return (true);
-
- case MONS_PLAYER_GHOST: // ghost of unsuccesful player
- switch (random2(24))
- {
- case 0:
- strcat(info, " laughs crazily.");
- break;
-
- case 1:
- strcat(info, " grins evilly.");
- break;
-
- case 2:
- strcat(info, " shouts, \"You will never get the ORB!\"");
- break;
-
- case 3: // mv: ghosts are usually wailing, aren't ?
- case 4:
- case 5:
- case 6:
- case 7:
- case 8:
- case 9:
- case 10:
- case 11:
- strcat(info, " wails.");
- break;
-
- case 12:
- strcat(info, " stares at you.");
- mpr(info, MSGCH_MONSTER_SPELL);
- mpr("You feel cold.", MSGCH_WARN);
- return (true);
-
- case 13:
- strcat(info, " screams, \"You will join me soon!\"");
- break;
- case 14:
- strcat(info, " wails, \"To die, to sleep, no more.\"");
- break; //Hamlet
- case 15:
- strcat(info,
- " screams, \"You must not succeed where I failed.\"");
- break;
- case 16:
- strcat(info,
- " screams, \"I'll kill anyone who wants the ORB.\"");
- break;
- case 17:
- strcat(info, " whispers, \"Meet emptiness of death!\"");
- break;
- case 18:
- strcat(info, " whispers, \"Death is liberation.\"");
- break;
- case 19:
- strcat(info,
- " whispers, \"Everlasting silence awaits you.\"");
- break;
- case 20:
- strcat(info,
- " screams, \"Don't try to defend. You have no chance!\"");
- break;
- case 21:
- strcat(info,
- " whispers, \"Death doesn't hurt. What you feel is life.\"");
- break;
- case 22:
- strcat(info, " whispers, \"The ORB doesn't exist.\"");
- break;
- case 23:
- strcat(info, " wails, \"Death is your only future.\"");
- break;
- }
- break; // end players ghost
-
- case MONS_PSYCHE: // insane girl
- switch (random2(20))
- {
- case 0:
- strcat(info, " smiles happily.");
- break;
- case 1:
- strcat(info, " giggles crazily.");
- break;
- case 2:
- strcat(info, " cries.");
- break;
- case 3:
- strcat(info, " stares at you for a moment.");
- break;
- case 4:
- strcat(info, " sings.");
- break;
- case 5:
- strcat(info,
- " says, \"Please, could you die a little faster?\"");
- break;
- case 6:
- strcat(info,
- " says, \"I'm bad girl. But I can't do anything about it.\"");
- break;
- case 7:
- strcat(info,
- " screams, \"YOU ARE VIOLATING AREA SECURITY!\"");
- break;
- case 8:
- strcat(info, " cries, \"I hate blood and violence.\"");
- break;
- case 9:
- strcat(info,
- " screams, \"Peace! Flowers! Freedom! Dead adventurers!\"");
- break;
- case 10:
- strcat(info,
- " says, \"I'm so lonely. Only corpses are my friends.\"");
- break;
- case 11:
- strcat(info, " cries, \"You've killed my pet.\"");
- break;
- case 12:
- strcat(info,
- " cries, \"You want to steal my orb collection?!\"");
- break;
- case 13:
- strcat(info, " sings some strange song.");
- break;
- case 14:
- strcat(info, " bursts in tears.");
- break;
- case 15:
- strcat(info, " sucks her thumb.");
- break;
- case 16:
- strcat(info,
- " whispers, \"Hold me, thrill me, kiss me, kill me.\"");
- break; //(c) U2 ?
- case 17:
- strcat(info, " says, \"I'll kill you and take you home.\"");
- break;
- case 18:
- strcat(info,
- " shouts, \"Well, maybe I'm nutty, but who cares?\"");
- break;
- case 19:
- strcat(info,
- " shouts, \"I hope that you are sorry for that.\"");
- break;
- }
- break; // end Psyche
-
- case MONS_DONALD: // adventurers hating competition
- case MONS_WAYNE:
- switch (random2(11))
- {
- case 0:
- strcat(info, " screams, \"Return home!\"");
- break;
- case 1:
- strcat(info, " screams, \"The Orb is mine!\"");
- break;
- case 2:
- strcat(info, " screams, \"Give me all your treasure!\"");
- break;
- case 3:
- strcat(info, " screams, \"You will never get the Orb!\"");
- break;
- case 4:
- strcat(info, " screams, \"I was here first!\"");
- break;
- case 5:
- strcat(info, " frowns.\"");
- break;
- case 6:
- strcat(info, " looks very upset.");
- break;
- case 7:
- strcat(info, " screams, \"Get away or die!\"");
- break;
- case 8:
- strcat(info, " screams, \"Die!\"");
- break;
- case 9:
- strcat(info, " screams, \"First you have to pass me!\"");
- break;
- case 10:
- strcat(info, " screams, \"I hate you!\"");
- break;
- }
- break; // end Donald
-
- case MONS_MICHAEL: // spellcaster who wanted to be alone
- switch (random2(11))
- {
- case 0:
- strcat(info, " looks very angry.");
- break;
- case 1:
- strcat(info, " frowns.");
- break;
- case 2:
- strcat(info, " screams, \"I want to be alone!\"");
- break;
- case 3:
- strcat(info, " says, \"You are really nuisance.\"");
- break;
- case 4:
- strcat(info,
- " screams, \"I wanted to be alone. And you...\"");
- break;
- case 5:
- strcat(info, " screams, \"Get away! Or better yet, die!\"");
- break;
- case 6:
- strcat(info, " mumbles some strange words.");
- msg_type = MSGCH_MONSTER_SPELL;
- break;
-
- case 7:
- strcat(info, " points at you.");
- mpr(info, MSGCH_MONSTER_SPELL);
- canned_msg(MSG_YOU_RESIST);
- return (true);
-
- case 8:
- strcat(info, " shakes with wrath.");
- break;
- case 9:
- strcat(info, " drinks a potion.");
- break;
- case 10:
- strcat(info, " gestures wildly.");
- msg_type = MSGCH_MONSTER_SPELL;
- break;
- }
- break; // end Michael
-
- case MONS_ERICA: // wild tempered adventuress
- switch (random2(12))
- {
- case 0:
- strcat(info, " screams, \"Die!\"");
- break;
- case 1:
- strcat(info, " screams, \"Do you want it fast or slow?\"");
- break;
- case 2:
- strcat(info, " looks angry.");
- break;
- case 3:
- strcat(info, " drinks a potion.");
- break;
- case 4:
- strcat(info, " says, \"I'm so much better than you.\"");
- break;
- case 5:
- strcat(info,
- " says, \"Fast and perfect. Such is my way of killing.\"");
- break;
- case 6:
- strcat(info, " screams, \"Hurry! Death awaits!\"");
- break;
- case 7:
- strcat(info, " laughs wildly.");
- break;
- case 8:
- strcat(info, " screams, \"I'll never tell where it is!\"");
- break;
- case 9:
- strcat(info, " screams, \"You'll never get it!\"");
- break;
- case 10:
- strcat(info, " screams, \"Coming here was suicide!\"");
- break;
- case 11:
- strcat(info,
- " says, \"I love to fight, but killing is better.\"");
- break;
- }
- break; // end Erica
-
- case MONS_JOSEPHINE: // ugly old witch looking for somone to kill
- switch (random2(13))
- {
- case 0:
- case 1:
- case 2:
- strcat(info, " grins evilly.");
- break;
- case 3:
- case 4:
- strcat(info, " screams, \"I will kill you!\"");
- break;
- case 5:
- strcat(info, " grinds her teeth.");
- break;
- case 6:
- strcat(info, " grins malevolently.");
- break;
- case 7:
- strcat(info, " laughs insanely.");
- break;
- case 8:
- strcat(info, " screams, \"Die!\"");
- break;
- case 9:
- strcat(info,
- " screams, \"I have something special for you!\"");
- break;
- case 10:
- strcat(info,
- " screams, \"I'll use your head as decoration in my hut!\"");
- break;
- case 11:
- strcat(info, " says, \"I'll make a rug of your skin.\"");
- break;
- case 12:
- strcat(info, " says, \"How about some decapitation?\"");
- break;
- }
- break; // end Josephine
-
- case MONS_HAROLD: // middle aged man, hired to kill you. He is in a hurry.
- switch (random2(11))
- {
- case 0:
- strcat(info, " looks nervous.");
- break;
- case 1:
- strcat(info, " screams, \"Hurry up!\"");
- break;
- case 2:
- strcat(info, " screams, \"Could you die faster?\"");
- break;
- case 3:
- strcat(info,
- " says, \"Stand still. I'm trying to kill you.\"");
- break;
- case 4:
- strcat(info, " screams, \"Die!\"");
- break;
- case 5:
- strcat(info, " says, \"I hope you die soon!\"");
- break;
- case 6:
- strcat(info,
- " says, \"Only few hits and it's over.\".");
- break;
- case 7:
- strcat(info, " says, \"You know, I'm in a hurry.\"");
- break;
- case 8:
- strcat(info, " screams, \"I'll finish you soon!\"");
- break;
- case 9:
- strcat(info, " screams, \"Don't delay it.\"");
- break;
- case 11:
- strcat(info, " says, \"Mine is not to reason why. Mine's to do, yours to die.\"" );
- }
- break; // end Harold
-
- // skilled warrior looking for some fame. More deads = more fame
- case MONS_NORBERT:
- switch (random2(13))
- {
- case 0:
- strcat(info, " smiles happily.");
- break;
- case 1:
- strcat(info, " screams, \"Die, monster!\"");
- break;
- case 2:
- strcat(info, " screams, \"I'm a hero!\"");
- break;
- case 3:
- strcat(info, " shouts, \"YES! Another notch!\"");
- break;
- case 4:
- strcat(info, " says, \"A pity your head will make such an ugly trophy.\"");
- break;
- case 5:
- strcat(info,
- " screams, \"Pray, because you'll die soon!\"");
- break;
- case 6:
- strcat(info,
- " asks \"Did you write a will? You should.\".");
- break;
- case 7:
- strcat(info,
- " says, \"I love killing ugly monsters like you.\"");
- break;
- case 8:
- strcat(info, " screams, \"Blood and destruction!\"");
- break;
- case 9:
- strcat(info, " says, \"You know, it's honour to die by my hand.\"");
- break;
- case 10:
- strcat(info, " shouts, \"Your time has come!\"");
- break;
- case 11:
- strcat(info,
- " says, \"I'm sorry but you don't have a chance.\"");
- break;
- case 12:
- strcat(info,
- " says, \"Another dead monster... It must be my lucky day!\"");
- break;
- }
- break; // end Norbert
-
- case MONS_JOZEF: // bounty hunter
- switch (random2(14))
- {
- case 0:
- strcat(info, " looks satisfied.");
- break;
- case 1:
- strcat(info, " screams, \"Die!\"");
- break;
- case 2:
- strcat(info, " screams, \"At last I found you!\"");
- break;
- case 3:
- strcat(info, " shouts, \"I'll get 500 for your head!\"");
- break;
- case 4:
- strcat(info,
- " says, \"You don't look worth for that money.\"");
- break;
- case 5:
- strcat(info,
- " says, \"It's nothing personal. I'm paid for it!\"");
- break;
- case 6:
- strcat(info,
- " asks \"Did you write a testament? You should.\"");
- break;
- case 7:
- strcat(info, " says, \"You are ");
- strcat(info, you.your_name);
- strcat(info, ", aren't you?.\"");
- break;
- case 8:
- strcat(info, " says, \"I suppose that you are ");
- strcat(info, you.your_name);
- strcat(info, ". Sorry, if I'm wrong.\"");
- break;
- case 9:
- strcat(info, " says, \"One dead ");
- strcat(info, you.your_name);
- strcat(info, ", 500 gold pieces. It's in my contract.\"");
- break;
- case 10:
- strcat(info, " shouts, \"Your time has come!\"");
- break;
- case 11:
- strcat(info,
- " says, \"My job is sometimes very exciting. Sometimes...\"");
- break;
- case 12:
- strcat(info, " says, \"I think I deserve my money.\"");
- break;
- case 13:
- strcat(info,
- " screams, \"Die! I've got more contracts today.\"");
- break;
- }
- break; // end Jozef
-
- case MONS_AGNES: // she is trying to get money and treasure
- switch (random2(10))
- {
- case 0:
- strcat(info, " screams, \"Give me all your money!\"");
- break;
- case 1:
- strcat(info, " screams, \"All treasure is mine!\"");
- break;
- case 2:
- strcat(info, " screams, \"You'll never get my money!\"");
- break;
- case 3:
- strcat(info, " grins evilly.");
- break;
- case 4:
- strcat(info,
- " screams, \"Give me everything and get away!\"");
- break;
- case 5:
- strcat(info,
- " says, \"I need new robe. I'll buy it from your money.\"");
- break;
- case 6:
- strcat(info,
- " screams, \"I want your rings! And amulets! And... EVERYTHING!\"");
- break;
- case 7:
- strcat(info,
- " screams, \"I hate dirty adventurers like you.\"");
- break;
- case 8:
- strcat(info, " says, \"How can you wear that ugly dress?\"");
- break;
- case 9:
- strcat(info, " screams, \"Die, beast!\"");
- break;
- }
- break; // end Agnes
-
- case MONS_MAUD: // warrior princess looking for sword "Entarex"
- switch (random2(11))
- {
- case 0:
- strcat(info, " screams, \"Submit or die!\"");
- break;
- case 1:
- strcat(info, " screams, \"Give me \"Entarex\"!\"");
- break;
- case 2:
- strcat(info,
- " screams, \"If you give me \"Entarex\", I'll let you live!\"");
- break;
- case 3:
- strcat(info, " frowns.");
- break;
- case 4:
- strcat(info, " looks upset.");
- break;
- case 5:
- strcat(info, " screams, \"You can't face my power!\"");
- break;
- case 6:
- strcat(info,
- " screams, \"Give me that sword! Immediately!\"");
- break;
- case 7:
- strcat(info,
- " screams, \"Your life or \"Entarex\"! You must choose.\"");
- break;
- case 8:
- strcat(info, " screams, \"I want it!\"");
- break;
- case 9:
- strcat(info, " screams, \"Die, you thief!\"");
- break;
- case 10:
- // needed at least one in here to tie to the amnesia
- // scroll reference -- bwr
- strcat(info, " asks \"Will you think of me as you die?\"");
- break;
- }
- break; // end Maud
-
- // wizard looking for bodyparts as spell components
- case MONS_FRANCIS:
- switch (random2(15))
- {
- case 0:
- strcat(info,
- " says, \"You've nice eyes. I could use them.\"");
- break;
- case 1:
- strcat(info, " says, \"Excuse me, but I need your head.\"");
- break;
- case 2:
- strcat(info, " says, \"I only need a few of your organs!\"");
- break;
- case 3:
- strcat(info, " ponders the situation.");
- break;
- case 4:
- strcat(info, " looks for scalpel.");
- break;
-
- case 5:
- simple_monster_message( monster, " casts a spell",
- MSGCH_MONSTER_SPELL );
-
- strcat(info, "'s hands started to glow with soft light.");
- msg_type = MSGCH_MONSTER_ENCHANT;
- break;
-
- case 6:
- strcat(info, " says, \"This won't hurt a bit.\"");
- break;
- case 7:
- strcat(info, " throws something at you.");
- break;
- case 8:
- strcat(info, " says, \"I want you in my laboratory!\"");
- break;
- case 9:
- strcat(info, " says, \"What about little dissection?\"");
- break;
- case 10:
- strcat(info,
- " says, \"I have something special for you.\"");
- break;
- case 11:
- strcat(info,
- " screams, \"Don't move! I want to cut your ear!\"");
- break;
- case 12:
- strcat(info,
- " says, \"What about your heart? Do you need it?\"");
- break;
- case 13:
- strcat(info,
- " says, \"Did you know that corpses are an important natural resource?\"");
- break;
- case 14:
- strcat(info,
- " says, \"Don't worry, I'll only take what I need.\"");
- break;
- }
- break; // end Francis
-
- case MONS_RUPERT: // crazy adventurer
- switch (random2(11))
- {
- case 0:
- strcat(info, " says, \"You are a monster, aren't you?\"");
- break;
- case 1:
- strcat(info, " screams, \"Die, monster!\"");
- break;
- case 2:
- strcat(info, " screams, \"Give me Holy Grail!\"");
- break;
- case 3:
- strcat(info, " screams, \"Red! No, blue!\"");
- break;
- case 4:
- strcat(info, " looks confused.");
- break;
- case 5:
- strcat(info, " looks excited.");
- break;
- case 6:
- strcat(info, " shouts, \"I'm great and powerful hero!\"");
- break;
- case 7:
- strcat(info,
- " screams, \"Get ready! I'll kill you! Or something like it...\"");
- break;
- case 8:
- strcat(info,
- " says, \"My Mom always said, kill them all.\"");
- break;
- case 9:
- strcat(info,
- " screams, \"You killed all those lovely monsters, you murderer!\"");
- break;
- case 10:
- strcat(info, " screams, \"Hurray!\"");
- break;
- }
- break; // end Rupert
-
- case MONS_NORRIS: // enlighten but crazy man
- switch (random2(24))
- {
- case 0:
- strcat(info, " sings \"Hare Rama, Hare Krishna!\"");
- break;
- case 1:
- strcat(info, " smiles at you.");
- break;
- case 2:
- strcat(info,
- " says, \"After death you'll find inner peace.\"");
- break;
- case 3:
- strcat(info,
- " says, \"Life is just suffering. I'll help you.\"");
- break;
- case 4:
- strcat(info, " is surrounded with aura of peace.");
- break;
- case 5:
- strcat(info, " looks very balanced.");
- break;
- case 6:
- strcat(info, " says, \"Don't resist. I'll do it for you.\"");
- break;
- case 7:
- strcat(info, " screams, \"Enter NIRVANA! Now!\"");
- break;
- case 8:
- strcat(info, " says, \"Death is just a liberation!\"");
- break;
- case 9:
- strcat(info,
- " says, \"Feel free to die. It's great thing.\"");
- break;
- case 10:
- strcat(info, " says, \"OHM MANI PADME HUM!\"");
- break;
-
- case 11:
- strcat(info, " mumbles some mantras.");
- msg_type = MSGCH_MONSTER_SPELL;
- break;
-
- case 12:
- strcat(info, " says, \"Breath deeply.\"");
- break;
- case 13:
- strcat(info, " screams, \"Love! Eternal love!\"");
- break;
- case 14:
- strcat(info,
- " screams, \"Peace! I bring you eternal peace!\"");
- break;
- case 15:
- strcat(info,
- " sighs \"Enlightenment is such responsibility.\"");
- break;
- case 16:
- strcat(info, " looks relaxed.");
- break;
- case 17:
- strcat(info, " screams, \"Free your soul! Die!\"");
- break;
- case 18:
- strcat(info, " screams, \"Blow your mind!\"");
- break;
- case 19:
- strcat(info,
- " says, \"The Orb is only a myth. Forget about it.\"");
- break;
- case 20:
- strcat(info, " says, \"It's all maya.\"");
- break;
- case 21:
- strcat(info, " says, \"Drop out!\"");
- break;
- case 22:
- strcat(info,
- " sings, \"Peace now, freedom now! Peace now, freedom now!\"");
- break;
- case 23:
- strcat(info, " says, \"This is called Combat Meditation.\"");
- break;
- }
- break; // end Norris
-
- case MONS_MARGERY: // powerful sorceress, guarding the ORB
- switch (random2(22))
- {
- case 0:
- strcat(info, " says, \"You are dead.\"");
- break;
- case 1:
- strcat(info, " looks very self-confident.");
- break;
- case 2:
- strcat(info, " screams, \"You must be punished!\"");
- break;
- case 3:
- strcat(info, " screams, \"You can't withstand my power!\"");
- break;
-
- case 4:
- simple_monster_message( monster, " casts a spell.",
- MSGCH_MONSTER_SPELL );
-
- strcat(info, " is surrounded with aura of power.");
- msg_type = MSGCH_MONSTER_ENCHANT;
- break;
-
- case 5:
- strcat(info, "'s eyes starts to glow with a red light.");
- break;
- case 6:
- strcat(info,
- "'s eyes starts to glow with a green light.");
- break;
- case 7:
- strcat(info, "'s eyes starts to glow with a blue light.");
- break;
- case 8:
- strcat(info, " screams, \"All trespassers must die!\"");
- break;
- case 9:
- strcat(info, " says, \"Die!\"");
- break;
- case 10:
- strcat(info, " screams, \"You'll have to get past me!\"");
- break;
-
- case 11:
- simple_monster_message( monster, " casts a spell.",
- MSGCH_MONSTER_SPELL );
-
- strcat(info, " becomes transparent for a moment.");
- msg_type = MSGCH_MONSTER_ENCHANT;
- break;
-
- case 12:
- strcat(info, " gestures.");
- msg_type = MSGCH_MONSTER_SPELL;
- break;
-
- case 13:
- simple_monster_message( monster, " casts a spell.",
- MSGCH_MONSTER_SPELL );
-
- strcat(info, "'s hands start to glow.");
- msg_type = MSGCH_MONSTER_ENCHANT;
- break;
-
- case 14:
- strcat(info, " screams, \"Ergichanteg reztahaw!\"");
- mpr(info, MSGCH_MONSTER_SPELL);
- mpr("You feel really bad.", MSGCH_WARN);
- return (true);
-
- case 15:
- strcat(info, " screams, \"You are doomed!\"");
- break;
- case 16:
- strcat(info, " screams, \"Nothing can help you.\"");
- break;
- case 17:
- strcat(info, " screams, \"Death is my middle name!\"");
- break;
-
- case 18:
- strcat(info, " gestures.");
- mpr(info, MSGCH_MONSTER_SPELL);
- mpr("You feel doomed.", MSGCH_WARN);
- return (true);
-
- case 19:
- strcat(info, " gestures.");
- mpr(info, MSGCH_MONSTER_SPELL);
- mpr("You feel weakened.", MSGCH_WARN);
- return (true);
-
- case 20:
- strcat(info, " throws some purple powder towards you.");
- mpr(info, MSGCH_MONSTER_SPELL);
- mpr("You feel cursed.", MSGCH_WARN);
- return (true);
-
- case 21:
- strcat(info,
- " screams, \"The ORB is only a tale, but I will kill you anyway!");
- break;
- }
- break; // end Margery
-
- case MONS_IJYB: // twisted goblin
- switch (random2(14))
- {
- case 0:
- strcat(info, " screams, \"Die!\"");
- break;
- case 1:
- strcat(info, " screams, \"Me kill you!\"");
- break;
- case 2:
- strcat(info, " screams, \"Me stronger than you!\"");
- break;
- case 3:
- case 4:
- strcat(info, " grins evilly.");
- break;
- case 5:
- strcat(info, " screams, \"It's all mine!\"");
- break;
- case 6:
- strcat(info, " screams, \"Get away!\"");
- break;
- case 7:
- strcat(info, " screams, \"Level is mine! All mine!\"");
- break;
- case 8:
- strcat(info, " screams, \"I cut your head off!\"");
- break;
- case 9:
- strcat(info, " screams, \"I dance on your bones!\"");
- break;
- case 10:
- strcat(info, " screams, \"Me very upset!\"");
- break;
- case 11:
- strcat(info, " screams, \"You nasty! Big nasty!\"");
- break;
- case 12:
- strcat(info, " screams, \"No! No, no, no, no!\"");
- break;
- case 13:
- strcat(info, " screams, \"I no like you!\"");
- break;
- }
- break; // end IJYB
-
- case MONS_BLORK_THE_ORC: // unfriendly orc
- switch (random2(21))
- {
- case 0:
- strcat(info, " screams, \"I don't like you!\"");
- break;
- case 1:
- strcat(info, " screams, \"I'm going to kill you!\"");
- break;
- case 2:
- strcat(info,
- " screams, \"I'm much stronger than you!\"");
- break;
- case 3:
- case 4:
- strcat(info, " grins evilly.");
- break;
- case 5:
- strcat(info, " frowns.");
- break;
- case 6:
- case 7:
- case 8:
- case 9:
- strcat(info, " looks angry.");
- break;
- case 10:
- strcat(info,
- " screams, \"I'll eat your brain! And then I'll vomit it back up!\"");
- break;
- case 11:
- strcat(info,
- " screams, \"You are the ugliest creature I've ever seen!\"");
- break;
- case 12:
- strcat(info, " screams, \"I'll cut your head off!\"");
- break;
- case 13:
- strcat(info, " screams, \"I'll break your legs!\"");
- break;
- case 14:
- strcat(info, " screams, \"I'll break your arms!\"");
- break;
- case 15:
- strcat(info,
- " screams, \"I'll crush all your ribs! One by one!\"");
- break;
- case 16:
- strcat(info,
- " screams, \"I'll make a cloak from your skin!\"");
- break;
- case 17:
- strcat(info,
- " screams, \"I'll decorate my home with your organs!\"");
- break;
- case 18:
- strcat(info, " screams, \"Die!\"");
- break;
- case 19:
- strcat(info,
- " screams, \"I'll cover the dungeon with your blood!\"");
- break;
- case 20:
- strcat(info, " screams, \"I'll drink your blood! Soon!\"");
- break;
- }
- break; // end Blork
-
- case MONS_EROLCHA: // ugly ogre
- switch (random2(11))
- {
- case 0:
- strcat(info, " tries to grin evilly.");
- break;
- case 1:
- strcat(info, " screams, \"Eat!\"");
- break;
- case 2:
- strcat(info, " screams, \"Stand! Erolcha hit you!\"");
- break;
- case 3:
- strcat(info, " screams, \"Blood!\"");
- break;
- case 4:
- strcat(info, " screams, \"Erolcha kill you!\"");
- break;
- case 5:
- strcat(info,
- " screams, \"Erolcha crush your head!\"");
- break;
- case 6:
- strcat(info, " roars.");
- break;
- case 7:
- strcat(info, " growls.");
- break;
- case 8:
- strcat(info, " screams, \"Lunch!\"");
- break;
- case 9:
- strcat(info, " screams, \"Erolcha happy to kill you!\"");
- break;
- case 10:
- strcat(info, " screams, \"Erolcha angry!\"");
- break;
- }
- break; // end Erolcha
-
- case MONS_URUG: // orc hired to kill you
- switch (random2(11))
- {
- case 0:
- strcat(info, " grins evilly.");
- break;
- case 1:
- strcat(info, " screams, \"Die!\"");
- break;
- case 2:
- strcat(info, " screams, \"I'm going to kill you! Now!\"");
- break;
- case 3:
- strcat(info, " screams, \"Blood and destruction!\"");
- break;
- case 4:
- strcat(info,
- " sneers, \"Innocent? I'll kill you anyway.\"");
- break;
- case 5:
- strcat(info,
- " screams, \"I'll get 30 silver pieces for your head!\"");
- break;
- case 6:
- strcat(info, " roars.");
- break;
- case 7:
- strcat(info, " howls with blood-lust.");
- break;
- case 8:
- strcat(info, " screams, \"You are already dead.\"");
- break;
- case 9:
- strcat(info, " says, \"Maybe you aren't ");
- strcat(info, you.your_name);
- strcat(info, ". It doesn't matter.\"");
- break;
- case 10:
- strcat(info, " screams, \"I love blood!\"");
- break;
- }
- break; // end Urug
-
- case MONS_SNORG: // troll
- switch (random2(16))
- {
- case 0:
- strcat(info, " grins.");
- break;
- case 1:
- case 2:
- case 3:
- strcat(info, " smells terrible.");
- break;
- case 4:
- case 5:
- case 6:
- strcat(info, " looks very hungry.");
- break;
- case 7:
- strcat(info, " screams, \"Snack!\"");
- break;
- case 8:
- strcat(info, " roars.");
- break;
- case 9:
- strcat(info, " says, \"Food!\"");
- break;
- case 10:
- strcat(info, " screams, \"Snorg hungry!\"");
- break;
- case 11:
- strcat(info, " screams, \"Snorg very, very hungry!\"");
- case 12:
- strcat(info, " says, \"Snorg eat you.\"");
- break;
- case 13:
- strcat(info, " says, \"You food?\"");
- break;
- case 14:
- strcat(info, " says, \"Yum, yum.\"");
- break;
- case 15:
- strcat(info, " burps.");
- break;
- }
- break; // end Snorg
-
- case MONS_XTAHUA: // ancient dragon
- switch (random2(13))
- {
- case 0:
- strcat(info, " roars, \"DIE, PUNY ONE!\"");
- break;
- case 1:
- strcat(info, " growls, \"YOU BORE ME SO.\"");
- break;
- case 2:
- strcat(info, " rumbles, \"YOU'RE BARELY A SNACK.\"");
- break;
- case 3:
- strcat(info, " roars, \"I HATE BEING BOTHERED!\"");
- break;
- case 4:
- strcat(info, " roars, \"I HOPE YOU'RE TASTY!\"");
- break;
- case 5:
- strcat(info, " roars, \"BAH! BLOODY ADVENTURERS.\"");
- break;
- case 6:
- strcat(info, " roars, \"FACE MY WRATH!\"");
- break;
- case 7:
- strcat(info, " glares at you.");
- break;
- case 8:
- strcat(info,
- " roars, \"COMING HERE WAS YOUR LAST MISTAKE!\"");
- break;
- case 9:
- strcat(info,
- " roars, \"I'VE KILLED HUNDREDS OF ADVENTURERS!\"");
- break;
- case 10:
- case 11:
- case 12:
- strcat(info, " roars horribly.");
- mpr(info, MSGCH_TALK);
- mpr("You are afraid.", MSGCH_WARN);
- return (true);
- }
- break; // end Xtahua
-
- case MONS_BORIS: // ancient lich
- switch (random2(24))
- {
- case 0:
- strcat(info, " says, \"I didn't invite you.\"");
- break;
- case 1:
- strcat(info, " says, \"You can't imagine my power.\"");
- break;
- case 2:
- strcat(info,
- " says, \"Orb? You want the Orb? You'll never get it.\"");
- break;
-
- case 3:
- strcat(info, " says, \"The world, the flesh, and the devil.\"");
- break;
-
- case 4:
- strcat(info, " gestures.");
- break;
-
- case 5:
- strcat(info, " stares at you.");
- mpr(info, MSGCH_MONSTER_SPELL);
- mpr("You feel drained.", MSGCH_WARN);
- return (true);
-
- case 6:
- strcat(info, " stares at you.");
- mpr(info, MSGCH_MONSTER_SPELL);
- mpr("You feel weakened.", MSGCH_WARN);
- return (true);
-
- case 7:
- strcat(info, " stares at you.");
- mpr(info, MSGCH_MONSTER_SPELL);
- mpr("You feel troubled.", MSGCH_WARN);
- return (true);
-
- case 8:
- strcat(info, " says \"Magic. You know nothing about it.\"");
- break;
-
- case 9:
- strcat(info, " says, \"My power is unlimited.\"");
- break;
- case 10:
- strcat(info, " says, \"You can't kill me. I'm immortal.\"");
- break;
-
- case 11:
- strcat(info, " casts a spell.");
- mpr(info, MSGCH_MONSTER_SPELL);
- mpr("Your equipment suddenly seems to weigh more.", MSGCH_WARN);
- return (true);
-
- case 12:
- strcat(info,
- " says, \"I know the secret of eternal life. Do you?\"");
- break;
- case 13:
- strcat(info, " says, \"I'll be back.\"");
- break;
-
- case 14:
- strcat(info, " casts a spell.");
- mpr(info, MSGCH_MONSTER_SPELL);
- canned_msg( MSG_YOU_RESIST );
- return (true);
-
- case 15:
- strcat(info, " casts a spell.");
- mpr(info, MSGCH_MONSTER_SPELL);
- mpr("Suddenly you are surrounded with pale green light.", MSGCH_WARN);
- return (true);
-
- case 16:
- strcat(info, " casts a spell.");
- mpr(info, MSGCH_MONSTER_SPELL);
- mpr("You have terrible head-ache.", MSGCH_WARN);
- return (true);
-
- case 17:
- strcat(info,
- " says, \"I know your future. Your future is death.\"");
- break;
- case 18:
- strcat(info, " says, \"Who wants to live forever? Me.\"");
- break;
- case 19:
- strcat(info, " laughs.");
- break;
- case 20:
- strcat(info, " says, \"Join the legion of my servants.\"");
- break;
- case 21:
- strcat(info, " says, \"There's only one solution for you. To die.\"");
- break;
- case 22:
- strcat(info, " says, \"You can never win.\"");
- break;
- case 23:
- simple_monster_message( monster, " casts a spell.",
- MSGCH_MONSTER_SPELL );
-
- strcat( info, " speeds up." );
- msg_type = MSGCH_MONSTER_ENCHANT;
- break;
- }
- break; // end BORIS
-
-
- case MONS_DEATH_COB:
- if (one_chance_in(2000))
- {
- mpr("The death cob makes a corny joke.", MSGCH_TALK);
- return (true);
- }
- return (false);
-
- case MONS_KILLER_KLOWN: // Killer Klown - guess!
- switch (random2(10))
- {
- case 0:
- strcat(info, " giggles crazily.");
- break;
- case 1:
- strcat(info, " laughs merrily.");
- break;
- case 2:
- strcat(info, " beckons to you.");
- break;
- case 3:
- strcat(info, " does a flip.");
- break;
- case 4:
- strcat(info, " does a somersault.");
- break;
- case 5:
- strcat(info, " smiles at you.");
- break;
- case 6:
- strcat(info, " grins with merry abandon.");
- break;
- case 7:
- strcat(info, " howls with blood-lust!");
- break;
- case 8:
- strcat(info, " pokes out its tongue.");
- break;
- case 9:
- strcat(info, " says, \"Come and play with me!\"");
- break;
- }
- break; // end Killer Klown
-
- default:
- strcat(info,
- " says, \"I don't know what to say. It's a bug.\"");
- break;
- } // end monster->type - monster type switch
- } // end default
-
- mpr(info, msg_type);
- return true;
-} // end mons_speaks = end of routine
diff --git a/stone_soup/crawl-ref/source/monspeak.h b/stone_soup/crawl-ref/source/monspeak.h
deleted file mode 100644
index 7a6559b04e..0000000000
--- a/stone_soup/crawl-ref/source/monspeak.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef MONSPEAK_H
-#define MONSPEAK_H
-
-#include "externs.h"
-
-bool mons_speaks(struct monsters *monster);
-
-#endif
diff --git a/stone_soup/crawl-ref/source/monstuff.cc b/stone_soup/crawl-ref/source/monstuff.cc
deleted file mode 100644
index f8305f5e4d..0000000000
--- a/stone_soup/crawl-ref/source/monstuff.cc
+++ /dev/null
@@ -1,5235 +0,0 @@
-/*
- * File: monstuff.cc
- * Summary: Misc monster related functions.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <8> 7 Aug 2001 MV Inteligent monsters now pick up gold
- * <7> 26 Mar 2001 GDL Fixed monster reaching
- * <6> 13 Mar 2001 GDL Rewrite of monster AI
- * <5> 31 July 2000 GDL More Manticore fixes.
- * <4> 29 July 2000 JDJ Fixed a bunch of places in handle_pickup where MSLOT_WEAPON
- * was being erroneously used.
- * <3> 25 July 2000 GDL Fixed Manticores
- * <2> 11/23/99 LRH Upgraded monster AI
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "monstuff.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-#ifdef DOS
-#include <conio.h>
-#endif
-
-#include "externs.h"
-
-#include "beam.h"
-#include "cloud.h"
-#include "debug.h"
-#include "dungeon.h"
-#include "fight.h"
-#include "itemname.h"
-#include "items.h"
-#include "itemprop.h"
-#include "misc.h"
-#include "monplace.h"
-#include "monspeak.h"
-#include "mon-util.h"
-#include "mstuff2.h"
-#include "player.h"
-#include "randart.h"
-#include "religion.h"
-#include "spl-cast.h"
-#include "spells2.h"
-#include "spells4.h"
-#include "stuff.h"
-#include "view.h"
-
-static bool handle_special_ability(struct monsters *monster, bolt & beem);
-static bool handle_pickup(struct monsters *monster);
-static void handle_behaviour(struct monsters *monster);
-static void mons_in_cloud(struct monsters *monster);
-static void monster_move(struct monsters *monster);
-static bool plant_spit(struct monsters *monster, struct bolt &pbolt);
-static int map_wand_to_mspell(int wand_type);
-
-// [dshaligram] Doesn't need to be extern.
-static int mmov_x, mmov_y;
-
-static int compass_x[8] = { -1, 0, 1, 1, 1, 0, -1, -1 };
-static int compass_y[8] = { -1, -1, -1, 0, 1, 1, 1, 0 };
-
-static bool immobile_monster[MAX_MONSTERS];
-
-#define FAR_AWAY 1000000 // used in monster_move()
-
-// This function creates an arteficial item to represent a mimic's appearance.
-// Eventually, mimics could be redone to be more like Dancing wepaons...
-// there'd only be one type and it would look like the item it carries. -- bwr
-void get_mimic_item( const struct monsters *mimic, item_def &item )
-{
- ASSERT( mimic != NULL && mons_is_mimic( mimic->type ) );
-
- item.base_type = OBJ_UNASSIGNED;
- item.sub_type = 0;
- item.special = 0;
- item.colour = 0;
- item.flags = 0;
- item.quantity = 1;
- item.plus = 0;
- item.plus2 = 0;
- item.x = mimic->x;
- item.y = mimic->y;
- item.link = NON_ITEM;
-
- int prop = 127 * mimic->x + 269 * mimic->y;
-
- switch (mimic->type)
- {
- case MONS_WEAPON_MIMIC:
- item.base_type = OBJ_WEAPONS;
- item.sub_type = (59 * mimic->x + 79 * mimic->y) % NUM_WEAPONS;
-
- prop %= 100;
-
- if (prop < 20)
- {
- item.flags |= ISFLAG_RANDART;
- item.special = ((mimic->x << 8 + mimic->y) & RANDART_SEED_MASK);
- }
- else if (prop < 50)
- set_equip_desc( item, ISFLAG_GLOWING );
- else if (prop < 80)
- set_equip_desc( item, ISFLAG_RUNED );
- else if (prop < 85)
- set_equip_race( item, ISFLAG_ORCISH );
- else if (prop < 90)
- set_equip_race( item, ISFLAG_DWARVEN );
- else if (prop < 95)
- set_equip_race( item, ISFLAG_ELVEN );
- break;
-
- case MONS_ARMOUR_MIMIC:
- item.base_type = OBJ_ARMOUR;
- item.sub_type = (59 * mimic->x + 79 * mimic->y) % NUM_ARMOURS;
-
- prop %= 100;
-
- if (prop < 20)
- {
- item.flags |= ISFLAG_RANDART;
- item.special = ((mimic->x << 8 + mimic->y) & RANDART_SEED_MASK);
- }
- else if (prop < 40)
- set_equip_desc( item, ISFLAG_GLOWING );
- else if (prop < 60)
- set_equip_desc( item, ISFLAG_RUNED );
- else if (prop < 80)
- set_equip_desc( item, ISFLAG_EMBROIDERED_SHINY );
- else if (prop < 85)
- set_equip_race( item, ISFLAG_ORCISH );
- else if (prop < 90)
- set_equip_race( item, ISFLAG_DWARVEN );
- else if (prop < 95)
- set_equip_race( item, ISFLAG_ELVEN );
- break;
-
- case MONS_SCROLL_MIMIC:
- item.base_type = OBJ_SCROLLS;
- item.sub_type = prop % NUM_SCROLLS;
- break;
-
- case MONS_POTION_MIMIC:
- item.base_type = OBJ_POTIONS;
- item.sub_type = prop % NUM_POTIONS;
- break;
-
- case MONS_GOLD_MIMIC:
- default:
- item.base_type = OBJ_GOLD;
- item.quantity = 5 + prop % 30;
- break;
- }
-
- item_colour( item ); // also sets special vals for scrolls/poitions
-}
-
-// Sets the colour of a mimic to match its description... should be called
-// whenever a mimic is created or teleported. -- bwr
-int get_mimic_colour( struct monsters *mimic )
-{
- ASSERT( mimic != NULL && mons_is_mimic( mimic->type ) );
-
- if (mimic->type == MONS_SCROLL_MIMIC)
- return (LIGHTGREY);
- else if (mimic->type == MONS_GOLD_MIMIC)
- return (YELLOW);
-
- item_def item;
- get_mimic_item( mimic, item );
-
- return (item.colour);
-}
-
-// monster curses a random player inventory item:
-bool curse_an_item( char which, char power )
-{
- UNUSED( power );
-
- /* use which later, if I want to curse weapon/gloves whatever
- which, for now: 0 = non-mummy, 1 = mummy (potions as well)
- don't change mitm.special of !odecay */
-
- int count = 0;
- int item = ENDOFPACK;
-
- for (int i = 0; i < ENDOFPACK; i++)
- {
- if (!is_valid_item( you.inv[i] ))
- continue;
-
- if (you.inv[i].base_type == OBJ_WEAPONS
- || you.inv[i].base_type == OBJ_ARMOUR
- || you.inv[i].base_type == OBJ_JEWELLERY
- || you.inv[i].base_type == OBJ_POTIONS)
- {
- if (item_cursed( you.inv[i] ))
- continue;
-
- if (you.inv[i].base_type == OBJ_POTIONS
- && (which != 1 || you.inv[i].sub_type == POT_DECAY))
- {
- continue;
- }
-
- // item is valid for cursing, so we'll give it a chance
- count++;
- if (one_chance_in( count ))
- item = i;
- }
- }
-
- // any item to curse?
- if (item == ENDOFPACK)
- return (false);
-
- // curse item:
-
- /* problem: changes large piles of potions */
- /* don't change you.inv_special (just for fun) */
- if (you.inv[item].base_type == OBJ_POTIONS)
- {
- you.inv[item].sub_type = POT_DECAY;
- unset_ident_flags( you.inv[item], ISFLAG_IDENT_MASK ); // all different
- }
- else
- do_curse_item( you.inv[item] );
-
- return (true);
-}
-
-static void monster_drop_ething(struct monsters *monster,
- bool mark_item_origins = false)
-{
- /* drop weapons & missiles last (ie on top) so others pick up */
- int i; // loop variable {dlb}
- bool destroyed = false;
- bool hostile_grid = false;
-
- if (grd[monster->x][monster->y] == DNGN_LAVA ||
- grd[monster->x][monster->y] == DNGN_DEEP_WATER)
- {
- hostile_grid = true;
- }
-
- for (i = MSLOT_GOLD; i >= MSLOT_WEAPON; i--)
- {
- int item = monster->inv[i];
-
- if (item != NON_ITEM)
- {
- if (hostile_grid)
- {
- destroyed = true;
- destroy_item( item );
- }
- else
- {
- move_item_to_grid( &item, monster->x, monster->y );
- if (mark_item_origins && is_valid_item(mitm[item]))
- {
- origin_set_monster(mitm[item], monster);
- }
- }
-
- monster->inv[i] = NON_ITEM;
- }
- }
-
- if (destroyed)
- {
- if (grd[monster->x][monster->y] == DNGN_LAVA)
- mpr("You hear a hissing sound.", MSGCH_SOUND);
- else
- mpr("You hear a splashing sound.", MSGCH_SOUND);
- }
-} // end monster_drop_ething()
-
-static void place_monster_corpse(struct monsters *monster)
-{
- int corpse_class = mons_species(monster->type);
-
- if (mons_has_ench(monster, ENCH_SHAPESHIFTER))
- corpse_class = MONS_SHAPESHIFTER;
- else if (mons_has_ench(monster, ENCH_GLOWING_SHAPESHIFTER))
- corpse_class = MONS_GLOWING_SHAPESHIFTER;
-
- if (mons_weight(corpse_class) == 0
- || grd[monster->x][monster->y] == DNGN_LAVA
- || grd[monster->x][monster->y] == DNGN_DEEP_WATER || coinflip())
- {
- return;
- }
-
- int o = get_item_slot();
- if (o == NON_ITEM)
- return;
-
- mitm[o].flags = 0;
- mitm[o].base_type = OBJ_CORPSES;
- mitm[o].plus = corpse_class;
- mitm[o].plus2 = 0; // butcher work done
- mitm[o].sub_type = CORPSE_BODY;
- mitm[o].special = 210; // rot time
- mitm[o].colour = mons_colour(corpse_class);
- mitm[o].quantity = 1;
-
- if (mitm[o].colour == BLACK)
- mitm[o].colour = monster->number;
-
- // Don't care if 'o' is changed, and it shouldn't be (corpses don't stack)
- move_item_to_grid( &o, monster->x, monster->y );
-} // end place_monster_corpse()
-
-void monster_die(struct monsters *monster, char killer, int i)
-{
- int dmi; // dead monster's inventory
- int monster_killed = monster_index(monster);
- bool death_message = mons_near(monster) && player_monster_visible(monster);
-
- // From time to time Trog gives you a little bonus
- if (killer == KILL_YOU && you.berserker)
- {
- if (you.religion == GOD_TROG
- && (!player_under_penance() && you.piety > random2(1000)))
- {
- int bonus = 3 + random2avg( 10, 2 );
-
- you.berserker += bonus;
- you.might += bonus;
- haste_player( bonus );
-
- mpr( "You feel the power of Trog in you as your rage grows.",
- MSGCH_GOD, GOD_TROG );
- }
- else if (wearing_amulet( AMU_RAGE ) && one_chance_in(30))
- {
- int bonus = 2 + random2(4);
-
- you.berserker += bonus;
- you.might += bonus;
- haste_player( bonus );
-
- mpr( "Your amulet glows a violent red." );
- }
- }
-
- if (you.prev_targ == monster_killed)
- you.prev_targ = MHITNOT;
-
- const bool pet_kill = (MON_KILL(killer) && ((i >= 0 && i < 200)
- && mons_friendly(&menv[i])));
-
- if (monster->type == MONS_GIANT_SPORE
- || monster->type == MONS_BALL_LIGHTNING)
- {
- if (monster->hit_points < 1 && monster->hit_points > -15)
- return;
- }
- else if (monster->type == MONS_FIRE_VORTEX
- || monster->type == MONS_SPATIAL_VORTEX)
- {
- simple_monster_message( monster, " dissipates!", MSGCH_MONSTER_DAMAGE,
- MDAM_DEAD );
-
- if (!testbits(monster->flags, MF_CREATED_FRIENDLY))
- {
- if (YOU_KILL(killer))
- gain_exp( exper_value( monster ) );
- else if (pet_kill)
- gain_exp( exper_value( monster ) / 2 + 1 );
- }
-
- if (monster->type == MONS_FIRE_VORTEX)
- place_cloud(CLOUD_FIRE_MON, monster->x, monster->y, 2 + random2(4));
- }
- else if (monster->type == MONS_SIMULACRUM_SMALL
- || monster->type == MONS_SIMULACRUM_LARGE)
- {
- simple_monster_message( monster, " vaporizes!", MSGCH_MONSTER_DAMAGE,
- MDAM_DEAD );
-
- if (!testbits(monster->flags, MF_CREATED_FRIENDLY))
- {
- if (YOU_KILL(killer))
- gain_exp( exper_value( monster ) );
- else if (pet_kill)
- gain_exp( exper_value( monster ) / 2 + 1 );
- }
-
- place_cloud(CLOUD_COLD_MON, monster->x, monster->y, 2 + random2(4));
- }
- else if (monster->type == MONS_DANCING_WEAPON)
- {
- simple_monster_message(monster, " falls from the air.",
- MSGCH_MONSTER_DAMAGE, MDAM_DEAD);
-
- if (!testbits(monster->flags, MF_CREATED_FRIENDLY))
- {
- if (YOU_KILL(killer))
- gain_exp( exper_value( monster ) );
- else if (pet_kill)
- gain_exp( exper_value( monster ) / 2 + 1 );
- }
- }
- else
- {
- switch (killer)
- {
- case KILL_YOU: /* You kill in combat. */
- case KILL_YOU_MISSILE: /* You kill by missile or beam. */
- {
- bool created_friendly =
- testbits(monster->flags, MF_CREATED_FRIENDLY);
-
- strcpy(info, "You ");
- strcat(info, (wounded_damaged(monster->type)) ? "destroy" : "kill");
- strcat(info, " ");
- strcat(info, ptr_monam(monster, DESC_NOCAP_THE));
- strcat(info, "!");
-
- if (death_message)
- mpr(info, MSGCH_MONSTER_DAMAGE, MDAM_DEAD);
-
- if (!created_friendly)
- {
- gain_exp(exper_value( monster ));
- }
- else
- {
- if (death_message)
- mpr("That felt strangely unrewarding.");
- }
-
- // Xom doesn't care who you killed:
- if (you.religion == GOD_XOM
- && random2(70) <= 10 + monster->hit_dice)
- {
- Xom_acts(true, 1 + random2(monster->hit_dice), false);
- }
-
- // Trying to prevent summoning abuse here, so we're trying to
- // prevent summoned creatures from being being done_good kills,
- // Only affects monsters friendly when created.
- if (!created_friendly)
- {
- if (you.duration[DUR_PRAYER])
- {
- if (mons_holiness(monster) == MH_NATURAL)
- did_god_conduct(DID_DEDICATED_KILL_LIVING,
- monster->hit_dice);
-
- if (mons_holiness(monster) == MH_UNDEAD)
- did_god_conduct(DID_DEDICATED_KILL_UNDEAD,
- monster->hit_dice);
-
- if (mons_holiness(monster) == MH_DEMONIC)
- did_god_conduct(DID_DEDICATED_KILL_DEMON,
- monster->hit_dice);
-
- //jmf: Trog hates wizards
- if (mons_class_flag(monster->type, M_ACTUAL_SPELLS))
- did_god_conduct(DID_DEDICATED_KILL_WIZARD,
- monster->hit_dice);
-
- //jmf: maybe someone hates priests?
- if (mons_class_flag(monster->type, M_PRIEST))
- did_god_conduct(DID_DEDICATED_KILL_PRIEST,
- monster->hit_dice);
- }
-
- if (mons_holiness(monster) == MH_HOLY)
- did_god_conduct(DID_KILL_ANGEL, monster->hit_dice);
- }
-
- // Divine health and mp restoration doesn't happen when killing
- // born-friendly monsters. The mutation still applies, however.
- if (you.mutation[MUT_DEATH_STRENGTH]
- || (!created_friendly &&
- you.religion == GOD_MAKHLEB && you.duration[DUR_PRAYER] &&
- (!player_under_penance() && random2(you.piety) >= 30)))
- {
- if (you.hp < you.hp_max)
- {
- mpr("You feel a little better.");
- inc_hp(monster->hit_dice + random2(monster->hit_dice),
- false);
- }
- }
-
- if (!created_friendly
- && (you.religion == GOD_MAKHLEB || you.religion == GOD_VEHUMET)
- && you.duration[DUR_PRAYER]
- && (!player_under_penance() && random2(you.piety) >= 30))
- {
- if (you.magic_points < you.max_magic_points)
- {
- mpr("You feel your power returning.");
- inc_mp( 1 + random2(monster->hit_dice / 2), false );
- }
- }
-
- if (you.duration[DUR_DEATH_CHANNEL]
- && mons_holiness(monster) == MH_NATURAL
- && mons_weight(mons_species(monster->type)))
- {
- if (create_monster( MONS_SPECTRAL_THING, 0, BEH_FRIENDLY,
- monster->x, monster->y, you.pet_target,
- mons_species(monster->type)) != -1)
- {
- if (death_message)
- mpr("A glowing mist starts to gather...");
- }
- }
- break;
- }
-
- case KILL_MON: /* Monster kills in combat */
- case KILL_MON_MISSILE: /* Monster kills by missile or beam */
- simple_monster_message(monster, " dies!", MSGCH_MONSTER_DAMAGE,
- MDAM_DEAD);
-
- // no piety loss if god gifts killed by other monsters
- if (mons_friendly(monster) && !testbits(monster->flags,MF_GOD_GIFT))
- did_god_conduct(DID_FRIEND_DIES, 1 + (monster->hit_dice / 2));
-
- // Trying to prevent summoning abuse here, so we're trying to
- // prevent summoned creatures from being being done_good kills.
- // Only affects creatures which were friendly when summoned.
- if (!testbits(monster->flags, MF_CREATED_FRIENDLY) && pet_kill)
- {
- bool notice = false;
-
- gain_exp(exper_value( monster ) / 2 + 1);
-
- int targ_holy = mons_holiness(monster),
- attacker_holy = mons_holiness(&menv[i]);
-
- if (attacker_holy == MH_UNDEAD)
- {
- if (targ_holy == MH_NATURAL)
- notice |=
- did_god_conduct(DID_LIVING_KILLED_BY_UNDEAD_SLAVE,
- monster->hit_dice);
- }
- else if (you.religion == GOD_VEHUMET
- || testbits( menv[i].flags, MF_GOD_GIFT ))
- {
- // Yes, we are splitting undead pets from the others
- // as a way to focus Necomancy vs Summoning (ignoring
- // Summon Wraith here)... at least we're being nice and
- // putting the natural creature Summons together with
- // the Demon ones. Note that Vehumet gets a free
- // pass here since those followers are assumed to
- // come from Summoning spells... the others are
- // from invocations (Zin, TSO, Makh, Kiku). -- bwr
-
- if (targ_holy == MH_NATURAL)
- {
- notice |= did_god_conduct( DID_LIVING_KILLED_BY_SERVANT,
- monster->hit_dice );
-
- if (mons_class_flag( monster->type, M_EVIL ))
- {
- notice |=
- did_god_conduct(
- DID_NATURAL_EVIL_KILLED_BY_SERVANT,
- monster->hit_dice );
- }
- }
- else if (targ_holy == MH_DEMONIC)
- {
- notice |= did_god_conduct( DID_DEMON_KILLED_BY_SERVANT,
- monster->hit_dice );
- }
- else if (targ_holy == MH_UNDEAD)
- {
- notice |= did_god_conduct( DID_UNDEAD_KILLED_BY_SERVANT,
- monster->hit_dice );
- }
- }
-
- // Angel kills are always noticed.
- if (targ_holy == MH_HOLY)
- {
- notice |= did_god_conduct( DID_ANGEL_KILLED_BY_SERVANT,
- monster->hit_dice );
- }
-
- if (you.religion == GOD_VEHUMET
- && notice
- && (!player_under_penance() && random2(you.piety) >= 30))
- {
- /* Vehumet - only for non-undead servants (coding
- convenience, no real reason except that Vehumet
- prefers demons) */
- if (you.magic_points < you.max_magic_points)
- {
- mpr("You feel your power returning.");
- inc_mp( 1 + random2(monster->hit_dice / 2), false );
- }
- }
- }
- break;
-
- /* Monster killed by trap/inanimate thing/itself/poison not from you */
- case KILL_MISC:
- simple_monster_message(monster, " dies!", MSGCH_MONSTER_DAMAGE,
- MDAM_DEAD);
- break;
-
- case KILL_RESET:
- /* Monster doesn't die, just goes back to wherever it came from
- This must only be called by monsters running out of time (or
- abjuration), because it uses the beam variables! Or does it??? */
- simple_monster_message( monster,
- " disappears in a puff of smoke!" );
-
- place_cloud( CLOUD_GREY_SMOKE_MON + random2(3), monster->x,
- monster->y, 1 + random2(3) );
-
- // fall-through
-
- case KILL_DISMISSED:
- for (dmi = MSLOT_GOLD; dmi >= MSLOT_WEAPON; dmi--)
- { /* takes whatever it's carrying back home */
- if (monster->inv[dmi] != NON_ITEM)
- destroy_item(monster->inv[dmi]);
-
- monster->inv[dmi] = NON_ITEM;
- }
- break;
- }
- }
-
- if (monster->type == MONS_MUMMY)
- {
- if (YOU_KILL(killer))
- {
- if (curse_an_item(1, 0))
- mpr("You feel nervous for a moment...", MSGCH_MONSTER_SPELL);
- }
- }
- else if (monster->type == MONS_GUARDIAN_MUMMY
- || monster->type == MONS_GREATER_MUMMY
- || monster->type == MONS_MUMMY_PRIEST)
- {
- if (YOU_KILL(killer))
- {
- mpr("You feel extremely nervous for a moment...",
- MSGCH_MONSTER_SPELL);
-
- miscast_effect( SPTYP_NECROMANCY,
- 3 + (monster->type == MONS_GREATER_MUMMY) * 8
- + (monster->type == MONS_MUMMY_PRIEST) * 5,
- random2avg(88, 3), 100, "a mummy death curse" );
- }
- }
- else if (monster->type == MONS_BORIS)
- {
- // XXX: actual blood curse effect for Boris? -- bwr
-
- if (one_chance_in(5))
- mons_speaks( monster );
- else
- {
- // Provide the player with an ingame clue to Boris' return. -- bwr
- const int tmp = random2(6);
- simple_monster_message( monster,
- (tmp == 0) ? " says, \"You haven't seen the last of me!\"" :
- (tmp == 1) ? " says, \"I'll get you next time!\"" :
- (tmp == 2) ? " says, \"This isn't over yet!\"" :
- (tmp == 3) ? " says, \"I'll be back!\"" :
- (tmp == 4) ? " says, \"This isn't the end, its only just beginning!\"" :
- (tmp == 5) ? " says, \"Kill me? I think not!\""
- : " says, \"You cannot defeat me so easily!\"",
- MSGCH_TALK );
- }
-
- // Now that Boris is dead, he's a valid target for monster
- // creation again. -- bwr
- you.unique_creatures[ monster->type - 280 ] = 0;
- }
-
- if (killer != KILL_RESET && killer != KILL_DISMISSED)
- {
- you.kills.record_kill(monster, killer, pet_kill);
-
- if (mons_has_ench(monster, ENCH_ABJ_I, ENCH_ABJ_VI))
- {
- if (mons_weight(mons_species(monster->type)))
- {
- if (monster->type == MONS_SIMULACRUM_SMALL
- || monster->type == MONS_SIMULACRUM_LARGE)
- {
- simple_monster_message( monster, " vaporizes!" );
-
- place_cloud( CLOUD_COLD_MON, monster->x, monster->y,
- 1 + random2(3) );
- }
- else
- {
- simple_monster_message(monster,
- "'s corpse disappears in a puff of smoke!");
-
- place_cloud( CLOUD_GREY_SMOKE_MON + random2(3),
- monster->x, monster->y, 1 + random2(3) );
- }
- }
- }
- else
- {
- // have to add case for disintegration effect here? {dlb}
- place_monster_corpse(monster);
- }
- }
-
- monster_drop_ething(monster,
- killer == KILL_YOU_MISSILE
- || killer == KILL_YOU
- || pet_kill);
- monster_cleanup(monster);
-} // end monster_die
-
-void monster_cleanup(struct monsters *monster)
-{
- unsigned int monster_killed = monster_index(monster);
- int dmi = 0;
-
- for (unsigned char j = 0; j < NUM_MON_ENCHANTS; j++)
- monster->enchantment[j] = ENCH_NONE;
-
- monster->flags = 0;
- monster->type = -1;
- monster->hit_points = 0;
- monster->max_hit_points = 0;
- monster->hit_dice = 0;
- monster->armour_class = 0;
- monster->evasion = 0;
- monster->speed_increment = 0;
- monster->attitude = ATT_HOSTILE;
- monster->behaviour = BEH_SLEEP;
- monster->foe = MHITNOT;
-
- mgrd[monster->x][monster->y] = NON_MONSTER;
-
- for (dmi = MSLOT_GOLD; dmi >= MSLOT_WEAPON; dmi--)
- {
- monster->inv[dmi] = NON_ITEM;
- }
-
- for (dmi = 0; dmi < MAX_MONSTERS; dmi++)
- {
- if (menv[dmi].foe == monster_killed)
- menv[dmi].foe = MHITNOT;
- }
-
- if (you.pet_target == monster_killed)
- you.pet_target = MHITNOT;
-
-} // end monster_cleanup()
-
-static bool jelly_divide(struct monsters * parent)
-{
- int jex = 0, jey = 0; // loop variables {dlb}
- bool foundSpot = false; // to rid code of hideous goto {dlb}
- struct monsters *child = 0; // NULL - value determined with loop {dlb}
-
- if (!mons_class_flag( parent->type, M_SPLITS ) || parent->hit_points == 1)
- return (false);
-
- // first, find a suitable spot for the child {dlb}:
- for (jex = -1; jex < 3; jex++)
- {
- // loop moves beyond those tiles contiguous to parent {dlb}:
- if (jex > 1)
- return (false);
-
- for (jey = -1; jey < 2; jey++)
- {
- // 10-50 for now - must take clouds into account:
- if (mgrd[parent->x + jex][parent->y + jey] == NON_MONSTER
- && !grid_is_solid(grd[parent->x + jex][parent->y + jey])
- && (parent->x + jex != you.x_pos || parent->y + jey != you.y_pos))
- {
- foundSpot = true;
- break;
- }
- }
-
- if (foundSpot)
- break;
- } /* end of for jex */
-
- int k = 0; // must remain outside loop that follows {dlb}
-
- // now that we have a spot, find a monster slot {dlb}:
- for (k = 0; k < MAX_MONSTERS; k++)
- {
- child = &menv[k];
-
- if (child->type == -1)
- break;
- else if (k == MAX_MONSTERS - 1)
- return (false);
- }
-
- // handle impact of split on parent {dlb}:
- parent->max_hit_points /= 2;
-
- if (parent->hit_points > parent->max_hit_points)
- parent->hit_points = parent->max_hit_points;
-
- // create child {dlb}:
- // this is terribly partial and really requires
- // more thought as to generation ... {dlb}
- child->type = parent->type;
- child->hit_dice = parent->hit_dice;
- child->hit_points = parent->hit_points;
- child->max_hit_points = child->hit_points;
- child->armour_class = parent->armour_class;
- child->evasion = parent->evasion;
- child->speed = parent->speed;
- child->speed_increment = 70 + random2(5);
- child->behaviour = parent->behaviour; /* Look at this! */
- child->foe = parent->foe;
- child->attitude = parent->attitude;
-
- child->x = parent->x + jex;
- child->y = parent->y + jey;
-
- mgrd[child->x][child->y] = k;
-
- if (!simple_monster_message(parent, " splits in two!"))
- {
- if (!silenced(parent->x, parent->y) || !silenced(child->x, child->y))
- mpr("You hear a squelching noise.", MSGCH_SOUND);
- }
-
- return (true);
-} // end jelly_divde()
-
-// if you're invis and throw/zap whatever, alerts menv to your position
-void alert_nearby_monsters(void)
-{
- struct monsters *monster = 0; // NULL {dlb}
-
- for (int it = 0; it < MAX_MONSTERS; it++)
- {
- monster = &menv[it];
-
- // Judging from the above comment, this function isn't
- // intended to wake up monsters, so we're only going to
- // alert monsters that aren't sleeping. For cases where an
- // event should wake up monsters and alert them, I'd suggest
- // calling noisy() before calling this function. -- bwr
- if (monster->type != -1
- && monster->behaviour != BEH_SLEEP
- && mons_near(monster))
- {
- behaviour_event( monster, ME_ALERT, MHITYOU );
- }
- }
-} // end alert_nearby_monsters()
-
-static bool valid_morph( struct monsters *monster, int new_mclass )
-{
- unsigned char current_tile = grd[monster->x][monster->y];
-
- // morph targets are _always_ "base" classes, not derived ones.
- new_mclass = mons_species(new_mclass);
-
- /* various inappropriate polymorph targets */
- if (mons_class_holiness( new_mclass ) != mons_holiness( monster )
- || mons_class_flag( new_mclass, M_NO_EXP_GAIN ) // not helpless
- || new_mclass == mons_species( monster->type ) // must be different
- || new_mclass == MONS_PROGRAM_BUG
- || new_mclass == MONS_SHAPESHIFTER
- || new_mclass == MONS_GLOWING_SHAPESHIFTER
-
- // These shouldn't happen anyways (demons unaffected + holiness check),
- // but if we ever do have polydemon, these will be needed:
- || new_mclass == MONS_PLAYER_GHOST
- || new_mclass == MONS_PANDEMONIUM_DEMON
- || (new_mclass >= MONS_GERYON && new_mclass <= MONS_ERESHKIGAL))
- {
- return (false);
- }
-
- /* Not fair to instakill a monster like this --
- order of evaluation of inner conditional important */
- if (current_tile == DNGN_LAVA || current_tile == DNGN_DEEP_WATER)
- {
- if (!mons_class_flies(new_mclass)
- || monster_habitat(new_mclass) != current_tile)
- {
- return (false);
- }
- }
-
- // not fair to strand a water monster on dry land, either. :)
- if (monster_habitat(new_mclass) == DNGN_DEEP_WATER
- && current_tile != DNGN_DEEP_WATER
- && current_tile != DNGN_SHALLOW_WATER)
- {
- return (false);
- }
-
- // and putting lava monsters on non-lava sqaures is a no-no, too
- if (monster_habitat(new_mclass) == DNGN_LAVA && current_tile != DNGN_LAVA)
- return (false);
-
- return (true);
-} // end valid_morph()
-
-// note that power is (as of yet) unused within this function -
-// may be worthy of consideration of later implementation, though,
-// so I'll still let the parameter exist for the time being {dlb}
-bool monster_polymorph( struct monsters *monster, int targetc, int power )
-{
- char str_polymon[INFO_SIZE] = ""; // cannot use info[] here {dlb}
- bool player_messaged = false;
- int source_power, target_power, relax;
- int tries = 1000;
-
- UNUSED( power );
-
- // Used to be mons_power, but that just returns hit_dice
- // for the monster class. By using the current hit dice
- // the player gets the opportunity to use draining more
- // effectively against shapeshifters. -- bwr
- source_power = monster->hit_dice;
- relax = 2;
-
- if (targetc == RANDOM_MONSTER)
- {
- do
- {
- targetc = random2( NUM_MONSTERS );
-
- // valid targets are always base classes
- targetc = mons_species( targetc );
-
- target_power = mons_power( targetc );
-
- if (one_chance_in(100))
- relax++;
-
- if (relax > 50)
- return (simple_monster_message( monster, " shudders." ));
- }
- while (tries-- && (!valid_morph( monster, targetc )
- || target_power < source_power - relax
- || target_power > source_power + (relax * 3) / 2));
- }
-
- if(!valid_morph( monster, targetc )) {
- strcat( str_polymon, " looks momentarily different.");
- player_messaged = simple_monster_message( monster, str_polymon );
- return (player_messaged);
- }
-
- // messaging: {dlb}
- bool invis = mons_class_flag( targetc, M_INVIS )
- || mons_has_ench( monster, ENCH_INVIS );
-
- if (mons_has_ench( monster, ENCH_GLOWING_SHAPESHIFTER, ENCH_SHAPESHIFTER ))
- strcat( str_polymon, " changes into " );
- else if (targetc == MONS_PULSATING_LUMP)
- strcat( str_polymon, " degenerates into " );
- else
- strcat( str_polymon, " evaporates and reforms as " );
-
- if (invis && !player_see_invis())
- strcat( str_polymon, "something you cannot see!" );
- else
- {
- strcat( str_polymon, monam( 250, targetc, !invis, DESC_NOCAP_A ) );
-
- if (targetc == MONS_PULSATING_LUMP)
- strcat( str_polymon, " of flesh" );
-
- strcat( str_polymon, "!" );
- }
-
- player_messaged = simple_monster_message( monster, str_polymon );
-
- // the actual polymorphing:
- int old_hp = monster->hit_points;
- int old_hp_max = monster->max_hit_points;
-
- /* deal with mons_sec */
- monster->type = targetc;
- monster->number = 250;
-
- int abj = mons_has_ench( monster, ENCH_ABJ_I, ENCH_ABJ_VI );
- int shifter = mons_has_ench( monster, ENCH_GLOWING_SHAPESHIFTER,
- ENCH_SHAPESHIFTER );
-
- // Note: define_monster() will clear out all enchantments! -- bwr
- define_monster( monster_index(monster) );
-
- // put back important enchantments:
- if (abj != ENCH_NONE)
- mons_add_ench( monster, abj );
-
- if (shifter != ENCH_NONE)
- mons_add_ench( monster, shifter );
-
- if (mons_class_flag( monster->type, M_INVIS ))
- mons_add_ench( monster, ENCH_INVIS );
-
- monster->hit_points = monster->max_hit_points
- * ((old_hp * 100) / old_hp_max) / 100
- + random2(monster->max_hit_points);
-
- if (monster->hit_points > monster->max_hit_points)
- monster->hit_points = monster->max_hit_points;
-
- monster->speed_increment = 67 + random2(6);
-
- monster_drop_ething(monster);
-
- return (player_messaged);
-} // end monster_polymorph()
-
-void monster_blink(struct monsters *monster)
-{
- int nx, ny;
-
- if (!random_near_space(monster->x, monster->y, nx, ny,
- false, false))
- return;
-
- mgrd[monster->x][monster->y] = NON_MONSTER;
-
- monster->x = nx;
- monster->y = ny;
-
- mgrd[nx][ny] = monster_index(monster);
-} // end monster_blink()
-
-// allow_adjacent: allow target to be adjacent to origin
-// restrict_LOS: restict target to be within PLAYER line of sight
-bool random_near_space(int ox, int oy, int &tx, int &ty, bool allow_adjacent,
- bool restrict_LOS)
-{
- int tries = 0;
-
- do
- {
- tx = ox - 6 + random2(14);
- ty = oy - 6 + random2(14);
-
- // origin is not 'near'
- if (tx == ox && ty == oy)
- continue;
-
- tries++;
-
- if (tries > 149)
- break;
- }
- while ((!see_grid(tx, ty) && restrict_LOS)
- || grd[tx][ty] < DNGN_SHALLOW_WATER
- || mgrd[tx][ty] != NON_MONSTER
- || (!allow_adjacent && distance(ox, oy, tx, ty) <= 2));
-
- return (tries < 150);
-} // end random_near_space()
-
-static bool habitat_okay( struct monsters *monster, int targ )
-{
- bool ret = false;
- const int habitat = monster_habitat( monster->type );
-
- if (mons_flies( monster ))
- {
- // flying monsters don't care
- ret = true;
- }
- else if (mons_class_flag( monster->type, M_AMPHIBIOUS )
- && (targ == DNGN_DEEP_WATER || targ == DNGN_SHALLOW_WATER))
- {
- // Amphibious creatures are "land" by default in mon-data,
- // we allow them to swim here. -- bwr
- ret = true;
- }
- else if (monster->type == MONS_WATER_ELEMENTAL && targ >= DNGN_DEEP_WATER)
- {
- // water elementals can crawl out over the land
- ret = true;
- }
- else if (habitat == DNGN_FLOOR
- && (targ >= DNGN_FLOOR || targ == DNGN_SHALLOW_WATER))
- {
- // FLOOR habitat monster going to a non-bad place
- ret = true;
- }
- else if (habitat == DNGN_DEEP_WATER
- && (targ == DNGN_DEEP_WATER || targ == DNGN_SHALLOW_WATER))
- {
- // Water monster to water
- ret = true;
- }
- else if (habitat == DNGN_LAVA && targ == DNGN_LAVA)
- {
- // Lava monster to lava
- ret = true;
- }
-
- return (ret);
-}
-
-// This doesn't really swap places, it just sets the monster's
-// position equal to the player (the player has to be moved afterwards).
-// It also has a slight problem with the fact the if the player is
-// levitating over an inhospitable habitat for the monster the monster
-// will be put in a place it normally couldn't go (this could be a
-// feature because it prevents insta-killing). In order to prevent
-// that little problem, we go looking for a square for the monster
-// to "scatter" to instead... and if we can't find one the monster
-// just refuses to be swapped (not a bug, this is intentionally
-// avoiding the insta-kill). Another option is to look a bit
-// wider for a vaild square (either by a last attempt blink, or
-// by looking at a wider radius)... insta-killing should be a
-// last resort in this function (especially since Tome, Dig, and
-// Summoning can be used to set up death traps). If worse comes
-// to worse, at least consider making the Swap spell not work
-// when the player is over lava or water (if the player want's to
-// swap pets to their death, we can let that go). -- bwr
-bool swap_places(struct monsters *monster)
-{
- bool swap;
-
- int loc_x = you.x_pos;
- int loc_y = you.y_pos;
-
- swap = habitat_okay( monster, grd[loc_x][loc_y] );
-
- // chose an appropiate habitat square at random around the target.
- if (!swap)
- {
- int num_found = 0;
- int temp_x, temp_y;
-
- for (int x = -1; x <= 1; x++)
- {
- temp_x = you.x_pos + x;
- if (temp_x < 0 || temp_x >= GXM)
- continue;
-
- for (int y = -1; y <= 1; y++)
- {
- if (x == 0 && y == 0)
- continue;
-
- temp_y = you.y_pos + y;
- if (temp_y < 0 || temp_y >= GYM)
- continue;
-
- if (mgrd[temp_x][temp_y] == NON_MONSTER
- && habitat_okay( monster, grd[temp_x][temp_y] ))
- {
- // Found an appropiate space... check if we
- // switch the current choice to this one.
- num_found++;
- if (one_chance_in(num_found))
- {
- loc_x = temp_x;
- loc_y = temp_y;
- }
- }
- }
- }
-
- if (num_found)
- swap = true;
- }
-
- if (swap)
- {
- mpr("You swap places.");
-
- mgrd[monster->x][monster->y] = NON_MONSTER;
-
- monster->x = loc_x;
- monster->y = loc_y;
-
- mgrd[monster->x][monster->y] = monster_index(monster);
- }
- else
- {
- // Might not be ideal, but it's better that insta-killing
- // the monster... maybe try for a short blinki instead? -- bwr
- simple_monster_message( monster, " resists." );
- }
-
- return (swap);
-} // end swap_places()
-
-void print_wounds(struct monsters *monster)
-{
- // prevents segfault -- cannot use info[] here {dlb}
- char str_wound[INFO_SIZE];
- int dam_level;
-
- if (monster->type == -1)
- return;
-
- if (monster->hit_points == monster->max_hit_points
- || monster->hit_points < 1)
- {
- return;
- }
-
- if (monster_descriptor(monster->type, MDSC_NOMSG_WOUNDS))
- return;
-
- strcpy(str_wound, " is ");
-
- if (monster->hit_points <= monster->max_hit_points / 6)
- {
- strcat(str_wound, "almost ");
- strcat(str_wound, wounded_damaged(monster->type) ? "destroyed"
- : "dead");
- dam_level = MDAM_ALMOST_DEAD;
- }
- else
- {
- if (monster->hit_points <= monster->max_hit_points / 6)
- {
- strcat(str_wound, "horribly ");
- dam_level = MDAM_HORRIBLY_DAMAGED;
- }
- else if (monster->hit_points <= monster->max_hit_points / 3)
- {
- strcat(str_wound, "heavily " );
- dam_level = MDAM_HEAVILY_DAMAGED;
- }
- else if (monster->hit_points <= 3 * (monster-> max_hit_points / 4))
- {
- strcat(str_wound, "moderately ");
- dam_level = MDAM_MODERATELY_DAMAGED;
- }
- else
- {
- strcat(str_wound, "lightly ");
- dam_level = MDAM_LIGHTLY_DAMAGED;
- }
-
- strcat(str_wound, wounded_damaged(monster->type) ? "damaged"
- : "wounded");
- }
-
- strcat(str_wound, ".");
- simple_monster_message(monster, str_wound, MSGCH_MONSTER_DAMAGE, dam_level);
-} // end print_wounds()
-
-// (true == 'damaged') [constructs, undead, etc.]
-// and (false == 'wounded') [living creatures, etc.] {dlb}
-bool wounded_damaged(int wound_class)
-{
- // this schema needs to be abstracted into real categories {dlb}:
- const int holy = mons_class_holiness(wound_class);
- if (holy == MH_UNDEAD || holy == MH_NONLIVING || holy == MH_PLANT)
- return (true);
-
- return (false);
-} // end wounded_damaged()
-
-//---------------------------------------------------------------
-//
-// behaviour_event
-//
-// 1. Change any of: monster state, foe, and attitude
-// 2. Call handle_behaviour to re-evaluate AI state and target x,y
-//
-//---------------------------------------------------------------
-void behaviour_event( struct monsters *mon, int event, int src,
- int src_x, int src_y )
-{
- bool isSmart = (mons_intel(mon->type) > I_ANIMAL);
- bool isFriendly = mons_friendly(mon);
- bool sourceFriendly = false;
- bool setTarget = false;
- bool breakCharm = false;
-
- if (src == MHITYOU)
- sourceFriendly = true;
- else if (src != MHITNOT)
- sourceFriendly = mons_friendly( &menv[src] );
-
- switch(event)
- {
- case ME_DISTURB:
- // assumes disturbed by noise...
- if (mon->behaviour == BEH_SLEEP)
- mon->behaviour = BEH_WANDER;
-
- // A bit of code to make Project Noise actually so
- // something again. Basically, dumb monsters and
- // monsters who aren't otherwise occupied will at
- // least consider the (apparent) source of the noise
- // interesting for a moment. -- bwr
- if (!isSmart || mon->foe == MHITNOT || mon->behaviour == BEH_WANDER)
- {
- mon->target_x = src_x;
- mon->target_y = src_y;
- }
- break;
-
- case ME_WHACK:
- case ME_ANNOY:
- // will turn monster against <src>, unless they
- // are BOTH friendly and stupid. Hitting someone
- // over the head, of course, always triggers this code.
- if (isFriendly != sourceFriendly || isSmart || event == ME_WHACK)
- {
- mon->foe = src;
-
- if (mon->behaviour != BEH_CORNERED)
- mon->behaviour = BEH_SEEK;
-
- if (src == MHITYOU)
- {
- mon->attitude = ATT_HOSTILE;
- breakCharm = true;
- }
- }
-
- // now set target x,y so that monster can whack
- // back (once) at an invisible foe
- if (event == ME_WHACK)
- setTarget = true;
- break;
-
- case ME_ALERT:
- // will alert monster to <src> and turn them
- // against them, unless they have a current foe.
- // it won't turn friends hostile either.
- if (mon->behaviour != BEH_CORNERED)
- mon->behaviour = BEH_SEEK;
-
- if (mon->foe == MHITNOT)
- mon->foe = src;
- break;
-
- case ME_SCARE:
- mon->foe = src;
- mon->behaviour = BEH_FLEE;
- // assume monsters know where to run from, even
- // if player is invisible.
- setTarget = true;
- break;
-
- case ME_CORNERED:
- // just set behaviour.. foe doesn't change.
- if (mon->behaviour != BEH_CORNERED && !mons_has_ench(mon,ENCH_FEAR))
- simple_monster_message(mon, " turns to fight!");
-
- mon->behaviour = BEH_CORNERED;
- break;
-
- case ME_EVAL:
- default:
- break;
- }
-
- if (setTarget)
- {
- if (src == MHITYOU)
- {
- mon->target_x = you.x_pos;
- mon->target_y = you.y_pos;
- mon->attitude = ATT_HOSTILE;
- }
- else if (src != MHITNOT)
- {
- mon->target_x = menv[src].x;
- mon->target_y = menv[src].y;
- }
- }
-
- // now, break charms if appropriate
- if (breakCharm)
- mons_del_ench( mon, ENCH_CHARM );
-
- // do any resultant foe or state changes
- handle_behaviour( mon );
-}
-
-//---------------------------------------------------------------
-//
-// handle_behaviour
-//
-// 1. Evalutates current AI state
-// 2. Sets monster targetx,y based on current foe
-//
-//---------------------------------------------------------------
-static void handle_behaviour(struct monsters *mon)
-{
- bool changed = true;
- bool isFriendly = mons_friendly(mon);
- bool proxPlayer = mons_near(mon);
- bool proxFoe;
- bool isHurt = (mon->hit_points <= mon->max_hit_points / 4 - 1);
- bool isHealthy = (mon->hit_points > mon->max_hit_points / 2);
- bool isSmart = (mons_intel(mon->type) > I_ANIMAL);
- bool isScared = mons_has_ench(mon, ENCH_FEAR);
-
- // immobility logic stolen from later on in handle_monster().. argh! --gdl
- bool isMobile = !(mon->type == MONS_OKLOB_PLANT
- || mon->type == MONS_CURSE_SKULL
- || (mon->type >= MONS_CURSE_TOE
- && mon->type <= MONS_POTION_MIMIC));
-
- // check for confusion -- early out.
- if (mons_has_ench(mon, ENCH_CONFUSION))
- {
- mon->target_x = 10 + random2(GXM - 10);
- mon->target_y = 10 + random2(GYM - 10);
- return;
- }
-
- // validate current target exists
- if (mon->foe != MHITNOT && mon->foe != MHITYOU)
- {
- if (menv[mon->foe].type == -1)
- mon->foe = MHITNOT;
- }
-
- // change proxPlayer depending on invisibility and standing
- // in shallow water
- if (proxPlayer && you.invis)
- {
- if (!mons_player_visible( mon ))
- proxPlayer = false;
-
- // must be able to see each other
- if (!see_grid(mon->x, mon->y))
- proxPlayer = false;
-
- // now, the corollary to that is that sometimes, if a
- // player is right next to a monster, they will 'see'
- if (grid_distance( you.x_pos, you.y_pos, mon->x, mon->y ) == 1
- && one_chance_in(3))
- {
- proxPlayer = true;
- }
- }
-
- // set friendly target, if they don't already have one
- if (isFriendly
- && you.pet_target != MHITNOT
- && (mon->foe == MHITNOT || mon->foe == MHITYOU))
- {
- mon->foe = you.pet_target;
- }
-
- // monsters do not attack themselves {dlb}
- if (mon->foe == monster_index(mon))
- mon->foe = MHITNOT;
-
- // friendly monsters do not attack other friendly monsters
- if (mon->foe != MHITNOT && mon->foe != MHITYOU)
- {
- if (isFriendly && mons_friendly(&menv[mon->foe]))
- mon->foe = MHITNOT;
- }
-
- // unfriendly monsters fighting other monsters will usually
- // target the player, if they're healthy
- if (!isFriendly && mon->foe != MHITYOU && mon->foe != MHITNOT
- && proxPlayer && !one_chance_in(3) && isHealthy)
- {
- mon->foe = MHITYOU;
- }
-
- // validate target again
- if (mon->foe != MHITNOT && mon->foe != MHITYOU)
- {
- if (menv[mon->foe].type == -1)
- mon->foe = MHITNOT;
- }
-
- while (changed)
- {
- int foe_x = you.x_pos;
- int foe_y = you.y_pos;
-
- // evaluate these each time; they may change
- if (mon->foe == MHITNOT)
- proxFoe = false;
- else
- {
- if (mon->foe == MHITYOU)
- {
- foe_x = you.x_pos;
- foe_y = you.y_pos;
- proxFoe = proxPlayer; // take invis into account
- }
- else
- {
- proxFoe = mons_near(mon, mon->foe);
-
- if (!mons_monster_visible( mon, &menv[mon->foe] ))
- proxFoe = false;
-
- // XXX monsters will rely on player LOS -- GDL
- if (!see_grid(menv[mon->foe].x, menv[mon->foe].y))
- proxFoe = false;
-
- foe_x = menv[mon->foe].x;
- foe_y = menv[mon->foe].y;
- }
- }
-
- // track changes to state; attitude never changes here.
- unsigned int new_beh = mon->behaviour;
- unsigned int new_foe = mon->foe;
-
- // take care of monster state changes
- switch(mon->behaviour)
- {
- case BEH_SLEEP:
- // default sleep state
- mon->target_x = mon->x;
- mon->target_y = mon->y;
- new_foe = MHITNOT;
- break;
-
- case BEH_SEEK:
- // no foe? then wander or seek the player
- if (mon->foe == MHITNOT)
- {
- if (!proxPlayer)
- new_beh = BEH_WANDER;
- else
- {
- new_foe = MHITYOU;
- mon->target_x = you.x_pos;
- mon->target_y = you.y_pos;
- }
-
- break;
- }
-
- // foe gone out of LOS?
- if (!proxFoe)
- {
- if (isFriendly)
- {
- new_foe = MHITYOU;
- mon->target_x = foe_x;
- mon->target_y = foe_y;
- break;
- }
-
- if (mon->foe_memory > 0 && mon->foe != MHITNOT)
- {
- // if we've arrived at our target x,y
- // do a stealth check. If the foe
- // fails, monster will then start
- // tracking foe's CURRENT position,
- // but only for a few moves (smell and
- // intuition only go so far)
-
- if (mon->x == mon->target_x &&
- mon->y == mon->target_y)
- {
- if (mon->foe == MHITYOU)
- {
- if (check_awaken(monster_index(mon)))
- {
- mon->target_x = you.x_pos;
- mon->target_y = you.y_pos;
- }
- else
- mon->foe_memory = 1;
- }
- else
- {
- if (coinflip()) // XXX: cheesy!
- {
- mon->target_x = menv[mon->foe].x;
- mon->target_y = menv[mon->foe].y;
- }
- else
- mon->foe_memory = 1;
- }
- }
-
- // either keep chasing, or start
- // wandering.
- if (mon->foe_memory < 2)
- {
- mon->foe_memory = 0;
- new_beh = BEH_WANDER;
- }
- break;
- }
-
- // hack: smarter monsters will
- // tend to pursue the player longer.
- int memory;
- switch(mons_intel(monster_index(mon)))
- {
- case I_HIGH:
- memory = 100 + random2(200);
- break;
- case I_NORMAL:
- memory = 50 + random2(100);
- break;
- case I_ANIMAL:
- default:
- memory = 25 + random2(75);
- break;
- case I_INSECT:
- memory = 10 + random2(50);
- break;
- }
-
- mon->foe_memory = memory;
- break; // from case
- }
-
- // monster can see foe: continue 'tracking'
- // by updating target x,y
- if (mon->foe == MHITYOU)
- {
- // sometimes, your friends will wander a bit.
- if (isFriendly && one_chance_in(8))
- {
- mon->target_x = 10 + random2(GXM - 10);
- mon->target_y = 10 + random2(GYM - 10);
- mon->foe = MHITNOT;
- new_beh = BEH_WANDER;
- }
- else
- {
- mon->target_x = you.x_pos;
- mon->target_y = you.y_pos;
- }
- }
- else
- {
- mon->target_x = menv[mon->foe].x;
- mon->target_y = menv[mon->foe].y;
- }
-
- if (isHurt && !isSmart && isMobile)
- new_beh = BEH_FLEE;
- break;
-
- case BEH_WANDER:
- // is our foe in LOS?
- // Batty monsters don't automatically reseek so that
- // they'll flitter away, we'll reset them just before
- // they get movement in handle_monsters() instead. -- bwr
- if (proxFoe && !testbits( mon->flags, MF_BATTY ))
- {
- new_beh = BEH_SEEK;
- break;
- }
-
- // default wander behaviour
- //
- // XXX: This is really dumb wander behaviour... instead of
- // changing the goal square every turn, better would be to
- // have the monster store a direction and have the monster
- // head in that direction for a while, then shift the
- // direction to the left or right. We're changing this so
- // wandering monsters at least appear to have some sort of
- // attention span. -- bwr
- if ((mon->x == mon->target_x && mon->y == mon->target_y)
- || one_chance_in(20)
- || testbits( mon->flags, MF_BATTY ))
- {
- mon->target_x = 10 + random2(GXM - 10);
- mon->target_y = 10 + random2(GYM - 10);
- }
-
- // during their wanderings, monsters will
- // eventually relax their guard (stupid
- // ones will do so faster, smart monsters
- // have longer memories
- if (!proxFoe && mon->foe != MHITNOT)
- {
- if (one_chance_in( isSmart ? 60 : 20 ))
- new_foe = MHITNOT;
- }
- break;
-
- case BEH_FLEE:
- // check for healed
- if (isHealthy && !isScared)
- new_beh = BEH_SEEK;
- // smart monsters flee until they can
- // flee no more... possible to get a
- // 'CORNERED' event, at which point
- // we can jump back to WANDER if the foe
- // isn't present.
-
- if (proxFoe)
- {
- // try to flee _from_ the correct position
- mon->target_x = foe_x;
- mon->target_y = foe_y;
- }
- break;
-
- case BEH_CORNERED:
- if (isHealthy)
- new_beh = BEH_SEEK;
-
- // foe gone out of LOS?
- if (!proxFoe)
- {
- if (isFriendly || proxPlayer)
- new_foe = MHITYOU;
- else
- new_beh = BEH_WANDER;
- }
- else
- {
- mon->target_x = foe_x;
- mon->target_y = foe_y;
- }
- break;
-
- default:
- return; // uh oh
- }
-
- changed = (new_beh != mon->behaviour || new_foe != mon->foe);
- mon->behaviour = new_beh;
-
- if (mon->foe != new_foe)
- mon->foe_memory = 0;
-
- mon->foe = new_foe;
- }
-} // end handle_behaviour()
-
-// note that this function *completely* blocks messaging for monsters
-// distant or invisible to the player ... look elsewhere for a function
-// permitting output of "It" messages for the invisible {dlb}
-// INtentionally avoids info and str_pass now. -- bwr
-bool simple_monster_message(struct monsters *monster, const char *event,
- int channel, int param)
-{
- char buff[INFO_SIZE];
-
- if (mons_near( monster )
- && (channel == MSGCH_MONSTER_SPELL || player_monster_visible(monster)))
- {
- snprintf( buff, sizeof(buff), "%s%s",
- ptr_monam(monster, DESC_CAP_THE), event );
-
- mpr( buff, channel, param );
- return (true);
- }
-
- return (false);
-} // end simple_monster_message()
-
-// used to adjust time durations in handle_enchantment() for monster speed
-static inline int mod_speed( int val, int speed )
-{
- return (speed ? (val * 10) / speed : val);
-}
-
-static bool handle_enchantment(struct monsters *monster)
-{
- const int habitat = monster_habitat( monster->type );
- bool died = false;
- int grid;
- int poisonval;
- int dam;
- int tmp;
-
- // Yes, this is the speed we want. This function will be called in
- // two curcumstances: (1) the monster can move and have enough energy,
- // and (2) the monster cannot move (speed == 0) and the monster loop
- // is running.
- //
- // In the first case we don't have to figure in the player's time,
- // since the rate of call to this function already does that (ie.
- // a bat would get here 6 times in 2 normal player turns, and if
- // the player was twice as fast it would be 6 times every four player
- // moves. So the only speed we care about is the monster vs the
- // absolute time frame.
- //
- // In the second case, we're hacking things so that plants can suffer
- // from sticky flame. The rate of call in this case is once every
- // player action... so the time_taken by the player is the ratio to
- // the absolute time frame.
- //
- // This will be used below for poison and sticky flame so that the
- // damage is apparently in the absolute time frame. This is done
- // by scaling the damage and the chance that the effect goes away.
- // The result is that poison on a regular monster will be doing
- // 1d3 damage every two rounds, and last eight rounds, and on
- // a bat the same poison will be doing 1/3 the damage each action
- // it gets (the mod fractions are randomized in), will have three
- // turns to the other monster's one, and the effect will survive
- // 3 times as many calls to this function (ie 8 rounds * 3 calls).
- //
- // -- bwr
- const int speed = (monster->speed == 0) ? you.time_taken : monster->speed;
-
- for (int p = 0; p < NUM_MON_ENCHANTS && !died; p++)
- {
- switch (monster->enchantment[p])
- {
- case ENCH_SLOW:
- if (random2(250) <= mod_speed( monster->hit_dice + 10, speed ))
- mons_del_ench(monster, ENCH_SLOW);
- break;
-
- case ENCH_HASTE:
- if (random2(1000) < mod_speed( 25, speed ))
- mons_del_ench(monster, ENCH_HASTE);
- break;
-
- case ENCH_FEAR:
- if (random2(150) <= mod_speed( monster->hit_dice + 5, speed ))
- mons_del_ench(monster, ENCH_FEAR);
- break;
-
- case ENCH_CONFUSION:
- if (random2(120) < mod_speed( monster->hit_dice + 5, speed ))
- {
- // don't delete perma-confusion
- if (!mons_class_flag(monster->type, M_CONFUSED))
- mons_del_ench(monster, ENCH_CONFUSION);
- }
- break;
-
- case ENCH_INVIS:
- if (random2(1000) < mod_speed( 25, speed ))
- {
- // don't delete perma-invis
- if (!mons_class_flag( monster->type, M_INVIS ))
- mons_del_ench(monster, ENCH_INVIS);
- }
- break;
-
- case ENCH_SUBMERGED:
- // not even air elementals unsubmerge into clouds
- if (env.cgrid[monster->x][monster->y] != EMPTY_CLOUD)
- break;
-
- // Air elementals are a special case, as their
- // submerging in air isn't up to choice. -- bwr
- if (monster->type == MONS_AIR_ELEMENTAL)
- {
- heal_monster( monster, 1, one_chance_in(5) );
-
- if (one_chance_in(5))
- mons_del_ench( monster, ENCH_SUBMERGED );
-
- break;
- }
-
- // Now we handle the others:
- grid = grd[monster->x][monster->y];
-
- // Badly injured monsters prefer to stay submerged...
- // electrical eels and lava snakes have ranged attacks
- // and are more likely to surface. -- bwr
- if (habitat == DNGN_FLOOR || habitat != grid)
- mons_del_ench( monster, ENCH_SUBMERGED ); // forced to surface
- else if (monster->hit_points <= monster->max_hit_points / 2)
- break;
- else if (((monster->type == MONS_ELECTRICAL_EEL
- || monster->type == MONS_LAVA_SNAKE)
- && (random2(1000) < mod_speed( 20, speed )
- || (mons_near(monster)
- && monster->hit_points == monster->max_hit_points
- && !one_chance_in(10))))
- || random2(5000) < mod_speed( 10, speed ))
- {
- mons_del_ench( monster, ENCH_SUBMERGED );
- }
- break;
-
- case ENCH_POISON_I:
- case ENCH_POISON_II:
- case ENCH_POISON_III:
- case ENCH_POISON_IV:
- case ENCH_YOUR_POISON_I:
- case ENCH_YOUR_POISON_II:
- case ENCH_YOUR_POISON_III:
- case ENCH_YOUR_POISON_IV:
- poisonval = monster->enchantment[p] - ENCH_POISON_I;
-
- if (poisonval < 0 || poisonval > 3)
- poisonval = monster->enchantment[p] - ENCH_YOUR_POISON_I;
-
- dam = (poisonval >= 3) ? 1 : 0;
-
- if (coinflip())
- dam += roll_dice( 1, poisonval + 2 );
-
- if (mons_res_poison(monster) < 0)
- dam += roll_dice( 2, poisonval ) - 1;
-
- // We adjust damage for monster speed (since this is applied
- // only when the monster moves), and we handle the factional
- // part as well (so that speed 30 creatures will take damage).
- dam *= 10;
- dam = (dam / speed) + ((random2(speed) < (dam % speed)) ? 1 : 0);
-
- if (dam > 0)
- {
- hurt_monster( monster, dam );
-
-#if DEBUG_DIAGNOSTICS
- // for debugging, we don't have this silent.
- simple_monster_message( monster, " takes poison damage.",
- MSGCH_DIAGNOSTICS );
- snprintf( info, INFO_SIZE, "poison damage: %d", dam );
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- if (monster->hit_points < 1)
- {
- monster_die(monster,
- ((monster->enchantment[p] < ENCH_POISON_I)
- ? KILL_YOU : KILL_MISC), 0);
- died = true;
- }
- }
-
- // chance to get over poison (1 in 8, modified for speed)
- if (random2(1000) < mod_speed( 125, speed ))
- {
- if (monster->enchantment[p] == ENCH_POISON_I)
- mons_del_ench(monster, ENCH_POISON_I);
- else if (monster->enchantment[p] == ENCH_YOUR_POISON_I)
- mons_del_ench(monster, ENCH_YOUR_POISON_I);
- else
- monster->enchantment[p]--;
- }
- break;
-
- case ENCH_YOUR_ROT_I:
- if (random2(1000) < mod_speed( 250, speed ))
- mons_del_ench(monster, ENCH_YOUR_ROT_I);
- else if (monster->hit_points > 1
- && random2(1000) < mod_speed( 333, speed ))
- {
- hurt_monster(monster, 1);
- }
- break;
-
- //jmf: FIXME: if (undead) make_small_rot_cloud();
- case ENCH_YOUR_ROT_II:
- case ENCH_YOUR_ROT_III:
- case ENCH_YOUR_ROT_IV:
- if (monster->hit_points > 1
- && random2(1000) < mod_speed( 333, speed ))
- {
- hurt_monster(monster, 1);
- }
-
- if (random2(1000) < mod_speed( 250, speed ))
- monster->enchantment[p]--;
- break;
-
- case ENCH_BACKLIGHT_I:
- if (random2(1000) < mod_speed( 100, speed ))
- mons_del_ench( monster, ENCH_BACKLIGHT_I );
- break;
-
- case ENCH_BACKLIGHT_II:
- case ENCH_BACKLIGHT_III:
- case ENCH_BACKLIGHT_IV:
- if (random2(1000) < mod_speed( 200, speed ))
- monster->enchantment[p]--;
- break;
-
- // assumption: mons_res_fire has already been checked
- case ENCH_STICKY_FLAME_I:
- case ENCH_STICKY_FLAME_II:
- case ENCH_STICKY_FLAME_III:
- case ENCH_STICKY_FLAME_IV:
- case ENCH_YOUR_STICKY_FLAME_I:
- case ENCH_YOUR_STICKY_FLAME_II:
- case ENCH_YOUR_STICKY_FLAME_III:
- case ENCH_YOUR_STICKY_FLAME_IV:
- dam = roll_dice( 2, 4 ) - 1;
-
- if (mons_res_fire( monster ) < 0)
- dam += roll_dice( 2, 5 ) - 1;
-
- // We adjust damage for monster speed (since this is applied
- // only when the monster moves), and we handle the factional
- // part as well (so that speed 30 creatures will take damage).
- dam *= 10;
- dam = (dam / speed) + ((random2(speed) < (dam % speed)) ? 1 : 0);
-
- if (dam > 0)
- {
- hurt_monster( monster, dam );
- simple_monster_message(monster, " burns!");
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "sticky flame damage: %d", dam );
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- if (monster->hit_points < 1)
- {
- monster_die(monster,
- ((monster->enchantment[p] < ENCH_STICKY_FLAME_I)
- ? KILL_YOU : KILL_MISC), 0);
- died = true;
- }
- }
-
- // chance to get over sticky flame (1 in 5, modified for speed)
- if (random2(1000) < mod_speed( 200, speed ))
- {
- if (monster->enchantment[p] == ENCH_STICKY_FLAME_I)
- mons_del_ench( monster, ENCH_STICKY_FLAME_I );
- else if (monster->enchantment[p] == ENCH_YOUR_STICKY_FLAME_I)
- mons_del_ench( monster, ENCH_YOUR_STICKY_FLAME_I );
- else
- monster->enchantment[p]--;
- }
- break;
-
- case ENCH_SHORT_LIVED:
- // This should only be used for ball lightning -- bwr
- if (random2(1000) < mod_speed( 200, speed ))
- monster->hit_points = -1;
- break;
-
- // 19 is taken by summoning:
- // If these are changed, must also change abjuration
- case ENCH_ABJ_I:
- case ENCH_ABJ_II:
- case ENCH_ABJ_III:
- case ENCH_ABJ_IV:
- if (random2(1000) < mod_speed( 100, speed ))
- monster->enchantment[p]--;
-
- if (monster->enchantment[p] < ENCH_ABJ_I)
- {
- monster_die(monster, KILL_RESET, 0);
- died = true;
- }
- break;
-
- case ENCH_ABJ_V:
- if (random2(1000) < mod_speed( 20, speed ))
- monster->enchantment[p] = ENCH_ABJ_IV;
- break;
-
- case ENCH_ABJ_VI:
- if (random2(1000) < mod_speed( 10, speed ))
- monster->enchantment[p] = ENCH_ABJ_V;
- break;
-
- case ENCH_CHARM:
- if (random2(500) <= mod_speed( monster->hit_dice + 10, speed ))
- mons_del_ench(monster, ENCH_CHARM);
- break;
-
- case ENCH_GLOWING_SHAPESHIFTER: // this ench never runs out
- // number of actions is fine for shapeshifters
- if (monster->type == MONS_GLOWING_SHAPESHIFTER
- || random2(1000) < mod_speed( 250, speed ))
- {
- monster_polymorph(monster, RANDOM_MONSTER, 0);
- }
- break;
-
- case ENCH_SHAPESHIFTER: // this ench never runs out
- if (monster->type == MONS_SHAPESHIFTER
- || random2(1000) < mod_speed( 1000 / ((15 * monster->hit_dice) / 5), speed ))
- {
- monster_polymorph(monster, RANDOM_MONSTER, 0);
- }
- break;
-
- case ENCH_TP_I:
- mons_del_ench( monster, ENCH_TP_I );
- monster_teleport( monster, true );
- break;
-
- case ENCH_TP_II:
- case ENCH_TP_III:
- case ENCH_TP_IV:
- tmp = mod_speed( 1000, speed );
-
- if (tmp < 1000 && random2(1000) < tmp)
- monster->enchantment[p]--;
- else if (monster->enchantment[p] - tmp / 1000 >= ENCH_TP_I)
- {
- monster->enchantment[p] -= tmp / 1000;
- tmp %= 1000;
-
- if (random2(1000) < tmp)
- {
- if (monster->enchantment[p] > ENCH_TP_I)
- monster->enchantment[p]--;
- else
- {
- mons_del_ench( monster, ENCH_TP_I, ENCH_TP_IV );
- monster_teleport( monster, true );
- }
- }
- }
- else
- {
- mons_del_ench( monster, ENCH_TP_I, ENCH_TP_IV );
- monster_teleport( monster, true );
- }
- break;
-
- case ENCH_SLEEP_WARY:
- if (random2(1000) < mod_speed( 50, speed ))
- mons_del_ench(monster, ENCH_SLEEP_WARY);
- break;
- }
- }
-
- return (died);
-} // end handle_enchantment()
-
-//---------------------------------------------------------------
-//
-// handle_movement
-//
-// Move the monster closer to its target square.
-//
-//---------------------------------------------------------------
-static void handle_movement(struct monsters *monster)
-{
- int dx, dy;
-
- // some calculations
- if (monster->type == MONS_BORING_BEETLE && monster->foe == MHITYOU)
- {
- dx = you.x_pos - monster->x;
- dy = you.y_pos - monster->y;
- }
- else
- {
- dx = monster->target_x - monster->x;
- dy = monster->target_y - monster->y;
- }
-
- // move the monster:
- mmov_x = (dx > 0) ? 1 : ((dx < 0) ? -1 : 0);
- mmov_y = (dy > 0) ? 1 : ((dy < 0) ? -1 : 0);
-
- if (monster->behaviour == BEH_FLEE)
- {
- mmov_x *= -1;
- mmov_y *= -1;
- }
-
- // bounds check: don't let fleeing monsters try to run
- // off the map
- if (monster->target_x + mmov_x < 0 || monster->target_x + mmov_x >= GXM)
- mmov_x = 0;
-
- if (monster->target_y + mmov_y < 0 || monster->target_y + mmov_y >= GYM)
- mmov_y = 0;
-
- // now quit if we're can't move
- if (mmov_x == 0 && mmov_y == 0)
- return;
-
- // reproduced here is some semi-legacy code that makes monsters
- // move somewhat randomly along oblique paths. It is an exceedingly
- // good idea, given crawl's unique line of sight properties.
- //
- // Added a check so that oblique movement paths aren't used when
- // close to the target square. -- bwr
- if (grid_distance( dx, dy, 0, 0 ) > 3)
- {
- if (abs(dx) > abs(dy))
- {
- // sometimes we'll just move parallel the x axis
- if (coinflip())
- mmov_y = 0;
- }
-
- if (abs(dy) > abs(dx))
- {
- // sometimes we'll just move parallel the y axis
- if (coinflip())
- mmov_x = 0;
- }
- }
-} // end handle_movement()
-
-//---------------------------------------------------------------
-//
-// handle_nearby_ability
-//
-// Gives monsters a chance to use a special ability when they're
-// next to the player.
-//
-//---------------------------------------------------------------
-static void handle_nearby_ability(struct monsters *monster)
-{
- if (!mons_near( monster )
- || monster->behaviour == BEH_SLEEP
- || mons_has_ench( monster, ENCH_SUBMERGED ))
- {
- return;
- }
-
- if (mons_class_flag(monster->type, M_SPEAKS) && one_chance_in(21)
- && monster->behaviour != BEH_WANDER)
- {
- mons_speaks(monster);
- }
-
- switch (monster->type)
- {
- case MONS_SPATIAL_VORTEX:
- case MONS_KILLER_KLOWN:
- // used for colour (butterflies too, but they don't change)
- monster->number = random_colour();
- break;
-
- case MONS_GIANT_EYEBALL:
- if (coinflip() && !mons_friendly(monster)
- && monster->behaviour != BEH_WANDER)
- {
- simple_monster_message(monster, " stares at you.");
-
- if (you.paralysis < 10)
- you.paralysis += 2 + random2(3);
- }
- break;
-
- case MONS_EYE_OF_DRAINING:
- if (coinflip() && !mons_friendly(monster)
- && monster->behaviour != BEH_WANDER)
- {
- simple_monster_message(monster, " stares at you.");
-
- dec_mp(5 + random2avg(13, 3));
-
- heal_monster(monster, 10, true); // heh heh {dlb}
- }
- break;
-
- case MONS_LAVA_WORM:
- case MONS_LAVA_FISH:
- case MONS_LAVA_SNAKE:
- case MONS_SALAMANDER:
- case MONS_BIG_FISH:
- case MONS_GIANT_GOLDFISH:
- case MONS_ELECTRICAL_EEL:
- case MONS_JELLYFISH:
- case MONS_WATER_ELEMENTAL:
- case MONS_SWAMP_WORM:
- // XXX: We're being a bit player-centric here right now...
- // really we should replace the grid_distance() check
- // with one that checks for unaligned monsters as well. -- bwr
- if (mons_has_ench( monster, ENCH_SUBMERGED))
- {
- if (grd[monster->x][monster->y] == DNGN_SHALLOW_WATER
- || grd[monster->x][monster->y] == DNGN_BLUE_FOUNTAIN
- || (!mons_friendly(monster)
- && grid_distance( monster->x, monster->y,
- you.x_pos, you.y_pos ) == 1
- && (monster->hit_points == monster->max_hit_points
- || (monster->hit_points > monster->max_hit_points / 2
- && coinflip()))))
- {
- mons_del_ench( monster, ENCH_SUBMERGED );
- }
- }
- else if (monster_habitat(monster->type) == grd[monster->x][monster->y]
- && (one_chance_in(5)
- || (grid_distance( monster->x, monster->y,
- you.x_pos, you.y_pos ) > 1
- && monster->type != MONS_ELECTRICAL_EEL
- && monster->type != MONS_LAVA_SNAKE
- && !one_chance_in(20))
- || monster->hit_points <= monster->max_hit_points / 2)
- || env.cgrid[monster->x][monster->y] != EMPTY_CLOUD)
- {
- mons_add_ench( monster, ENCH_SUBMERGED );
- }
- break;
-
- case MONS_AIR_ELEMENTAL:
- if (one_chance_in(5))
- mons_add_ench( monster, ENCH_SUBMERGED );
- break;
-
- case MONS_PANDEMONIUM_DEMON:
- if (ghost.values[ GVAL_DEMONLORD_CYCLE_COLOUR ])
- monster->number = random_colour();
- break;
- }
-} // end handle_nearby_ability()
-
-//---------------------------------------------------------------
-//
-// handle_special_ability
-//
-// $$$ not sure what to say here...
-//
-//---------------------------------------------------------------
-static bool handle_special_ability(struct monsters *monster, bolt & beem)
-{
- bool used = false;
-
- FixedArray < unsigned int, 19, 19 > show;
-
- const monster_type mclass = (mons_genus( monster->type ) == MONS_DRACONIAN)
- ? draco_subspecies( monster )
- : static_cast<monster_type>( monster->type );
-
- if (!mons_near( monster )
- || monster->behaviour == BEH_SLEEP
- || mons_has_ench( monster, ENCH_SUBMERGED ))
- {
- return (false);
- }
-
-// losight(show, grd, you.x_pos, you.y_pos);
-
- switch (mclass)
- {
- case MONS_BALL_LIGHTNING:
- if (monster->attitude == ATT_HOSTILE
- && distance( you.x_pos, you.y_pos, monster->x, monster->y ) <= 5)
- {
- monster->hit_points = -1;
- used = true;
- break;
- }
-
- for (int i = 0; i < MAX_MONSTERS; i++)
- {
- struct monsters *targ = &menv[i];
-
- if (targ->type == -1 || targ->type == NON_MONSTER)
- continue;
-
- if (distance( monster->x, monster->y, targ->x, targ->y ) >= 5)
- continue;
-
- if (monster->attitude == targ->attitude)
- continue;
-
- // faking LOS by checking the neighbouring square
- int dx = targ->x - monster->x;
- if (dx)
- dx /= dx;
-
- int dy = targ->y - monster->y;
- if (dy)
- dy /= dy;
-
- const int tx = monster->x + dx;
- const int ty = monster->y + dy;
-
- if (tx < 0 || tx > GXM || ty < 0 || ty > GYM)
- continue;
-
- if (!grid_is_solid(grd[tx][ty]))
- {
- monster->hit_points = -1;
- used = true;
- break;
- }
- }
- break;
-
- case MONS_LAVA_SNAKE:
- if (mons_has_ench(monster, ENCH_CONFUSION))
- break;
-
- if (!mons_player_visible( monster ))
- break;
-
- if (coinflip())
- break;
-
- // setup tracer
- strcpy(beem.beam_name, "glob of lava");
- beem.range = 4;
- beem.rangeMax = 13;
- beem.damage = dice_def( 3, 10 );
- beem.colour = RED;
- beem.type = SYM_ZAP;
- beem.flavour = BEAM_LAVA;
- beem.hit = 20;
- beem.beam_source = monster_index(monster);
- beem.thrower = KILL_MON;
- beem.aux_source = "glob of lava";
-
- // fire tracer
- fire_tracer(monster, beem);
-
- // good idea?
- if (mons_should_fire(beem))
- {
- simple_monster_message(monster, " spits lava!");
- fire_beam(beem);
- used = true;
- }
- break;
-
- case MONS_ELECTRICAL_EEL:
- if (mons_has_ench(monster, ENCH_CONFUSION))
- break;
-
- if (!mons_player_visible( monster ))
- break;
-
- if (coinflip())
- break;
-
- // setup tracer
- strcpy(beem.beam_name, "bolt of electricity");
- beem.damage = dice_def( 3, 6 );
- beem.colour = LIGHTCYAN;
- beem.type = SYM_ZAP;
- beem.flavour = BEAM_ELECTRICITY;
- beem.hit = 150;
- beem.beam_source = monster_index(monster);
- beem.thrower = KILL_MON;
- beem.aux_source = "bolt of electricity";
- beem.range = 4;
- beem.rangeMax = 13;
- beem.is_beam = true;
-
- // fire tracer
- fire_tracer(monster, beem);
-
- // good idea?
- if (mons_should_fire(beem))
- {
- simple_monster_message(monster, " shoots out a bolt of electricity!");
- fire_beam(beem);
- used = true;
- }
- break;
-
- case MONS_ACID_BLOB:
- case MONS_OKLOB_PLANT:
- case MONS_YELLOW_DRACONIAN:
- if (mons_has_ench(monster, ENCH_CONFUSION))
- break;
-
- if (!mons_player_visible( monster ))
- break;
-
- if (one_chance_in(3))
- used = plant_spit(monster, beem);
-
- break;
-
- case MONS_PIT_FIEND:
- if (one_chance_in(3))
- break;
- // deliberate fall through
- case MONS_FIEND:
- if (mons_has_ench(monster, ENCH_CONFUSION))
- break;
-
- // friendly fiends won't use torment, preferring hellfire
- // (right now there is no way a monster can predict how
- // badly they'll damage the player with torment) -- GDL
- if (one_chance_in(4))
- {
- int spell_cast;
-
- switch (random2(4))
- {
- case 0:
- if (!mons_friendly(monster))
- {
- spell_cast = MS_TORMENT;
- mons_cast(monster, beem, spell_cast);
- used = true;
- break;
- }
- // deliberate fallthrough -- see above
- case 1:
- case 2:
- case 3:
- spell_cast = MS_HELLFIRE;
- setup_mons_cast(monster, beem, spell_cast);
-
- // fire tracer
- fire_tracer(monster, beem);
-
- // good idea?
- if (mons_should_fire(beem))
- {
- simple_monster_message( monster, " makes a gesture!",
- MSGCH_MONSTER_SPELL );
-
- mons_cast(monster, beem, spell_cast);
- used = true;
- }
- break;
- }
-
- mmov_x = 0;
- mmov_y = 0;
- }
- break;
-
- case MONS_IMP:
- case MONS_PHANTOM:
- case MONS_INSUBSTANTIAL_WISP:
- case MONS_BLINK_FROG:
- case MONS_KILLER_KLOWN:
- if (one_chance_in(7))
- {
- simple_monster_message(monster, " blinks.");
- monster_blink(monster);
- }
- break;
-
- case MONS_MANTICORE:
- if (!mons_player_visible( monster ))
- break;
-
- if (mons_has_ench(monster, ENCH_CONFUSION))
- break;
-
- if (!mons_near(monster))
- break;
-
- // the fewer spikes the manticore has left, the less
- // likely it will use them.
- if (random2(16) >= static_cast<int>(monster->number))
- break;
-
- // do the throwing right here, since the beam is so
- // easy to set up and doesn't involve inventory.
-
- // set up the beam
- strcpy(beem.beam_name, "volley of spikes");
- beem.range = 9;
- beem.rangeMax = 9;
- beem.hit = 14;
- beem.damage = dice_def( 2, 10 );
- beem.beam_source = monster_index(monster);
- beem.type = SYM_MISSILE;
- beem.colour = LIGHTGREY;
- beem.flavour = BEAM_MISSILE;
- beem.thrower = KILL_MON;
- beem.aux_source = "volley of spikes";
- beem.is_beam = false;
-
- // fire tracer
- fire_tracer(monster, beem);
-
- // good idea?
- if (mons_should_fire(beem))
- {
- simple_monster_message(monster, " flicks its tail!");
- fire_beam(beem);
- used = true;
- // decrement # of volleys left
- monster->number -= 1;
- }
- break;
-
- // dragon breath weapon:
- case MONS_DRAGON:
- case MONS_HELL_HOUND:
- case MONS_ICE_DRAGON:
- case MONS_LINDWURM:
- case MONS_FIREDRAKE:
- case MONS_XTAHUA:
- case MONS_WHITE_DRACONIAN:
- case MONS_RED_DRACONIAN:
- if (!mons_player_visible( monster ))
- break;
-
- if (mons_has_ench(monster, ENCH_CONFUSION))
- break;
-
- if ((monster->type != MONS_HELL_HOUND && random2(13) < 3)
- || one_chance_in(10))
- {
- setup_dragon(monster, beem);
-
- // fire tracer
- fire_tracer(monster, beem);
-
- // good idea?
- if (mons_should_fire(beem))
- {
- simple_monster_message(monster, " breathes.",
- MSGCH_MONSTER_SPELL);
- fire_beam(beem);
- mmov_x = 0;
- mmov_y = 0;
- used = true;
- }
- }
- break;
-
- default:
- break;
- }
-
- return (used);
-} // end handle_special_ability()
-
-//---------------------------------------------------------------
-//
-// handle_potion
-//
-// Give the monster a chance to quaff a potion. Returns true if
-// the monster imbibed.
-//
-//---------------------------------------------------------------
-static bool handle_potion(struct monsters *monster, bolt & beem)
-{
-
- // yes, there is a logic to this ordering {dlb}:
- if (monster->behaviour == BEH_SLEEP)
- return (false);
- else if (monster->inv[MSLOT_POTION] == NON_ITEM)
- return (false);
- else if (!one_chance_in(3))
- return (false);
- else
- {
- bool imbibed = false;
-
- switch (mitm[monster->inv[MSLOT_POTION]].sub_type)
- {
- case POT_HEALING:
- case POT_HEAL_WOUNDS:
- if (monster->hit_points <= monster->max_hit_points / 2
- && mons_holiness(monster) != MH_UNDEAD
- && mons_holiness(monster) != MH_NONLIVING
- && mons_holiness(monster) != MH_PLANT)
- {
- simple_monster_message(monster, " drinks a potion.");
-
- if (heal_monster(monster, 5 + random2(7), false))
- simple_monster_message(monster, " is healed!");
-
- if (mitm[monster->inv[MSLOT_POTION]].sub_type
- == POT_HEAL_WOUNDS)
- {
- heal_monster(monster, 10 + random2avg(28, 3), false);
- }
-
- imbibed = true;
- }
- break;
-
- case POT_SPEED:
- // notice that these are the same odd colours used in
- // mons_ench_f2() {dlb}
- beem.colour = BLUE;
- // intentional fall through
- case POT_INVISIBILITY:
- if (mitm[monster->inv[MSLOT_POTION]].sub_type == POT_INVISIBILITY)
- beem.colour = MAGENTA;
-
- // why only drink these if not near player? {dlb}
- if (!mons_near(monster))
- {
- simple_monster_message(monster, " drinks a potion.");
-
- mons_ench_f2(monster, beem);
-
- imbibed = true;
- }
- break;
- }
-
- if (imbibed)
- {
- if (dec_mitm_item_quantity( monster->inv[MSLOT_POTION], 1 ))
- monster->inv[MSLOT_POTION] = NON_ITEM;
- }
-
- return (imbibed);
- }
-} // end handle_potion()
-
-static bool handle_reaching(struct monsters *monster)
-{
- bool ret = false;
- const int wpn = monster->inv[MSLOT_WEAPON];
-
- if (mons_aligned(monster_index(monster), monster->foe))
- return (false);
-
- if (mons_has_ench( monster, ENCH_SUBMERGED ))
- return (false);
-
- if (wpn != NON_ITEM && get_weapon_brand( mitm[wpn] ) == SPWPN_REACHING )
- {
- if (monster->foe == MHITYOU)
- {
- // this check isn't redundant -- player may be invisible.
- if (monster->target_x == you.x_pos && monster->target_y == you.y_pos)
- {
- int dx = abs(monster->x - you.x_pos);
- int dy = abs(monster->y - you.y_pos);
-
- if ((dx == 2 && dy <= 2) || (dy == 2 && dx <= 2))
- {
- ret = true;
- monster_attack( monster_index(monster) );
- }
- }
- }
- else if (monster->foe != MHITNOT)
- {
- // same comments as to invisibility as above.
- if (monster->target_x == menv[monster->foe].x
- && monster->target_y == menv[monster->foe].y)
- {
- int dx = abs(monster->x - menv[monster->foe].x);
- int dy = abs(monster->y - menv[monster->foe].y);
- if ((dx == 2 && dy <= 2) || (dy == 2 && dx <= 2))
- {
- ret = true;
- monsters_fight( monster_index(monster), monster->foe );
- }
- }
- }
- }
-
- return ret;
-} // end handle_reaching()
-
-//---------------------------------------------------------------
-//
-// handle_scroll
-//
-// Give the monster a chance to read a scroll. Returns true if
-// the monster read something.
-//
-//---------------------------------------------------------------
-static bool handle_scroll(struct monsters *monster)
-{
- // yes, there is a logic to this ordering {dlb}:
- if (mons_has_ench(monster, ENCH_CONFUSION)
- || monster->behaviour == BEH_SLEEP
- || mons_has_ench( monster, ENCH_SUBMERGED ))
- {
- return (false);
- }
- else if (monster->inv[MSLOT_SCROLL] == NON_ITEM)
- return (false);
- else if (!one_chance_in(3))
- return (false);
- else
- {
- bool read = false;
-
- // notice how few cases are actually accounted for here {dlb}:
- switch (mitm[monster->inv[MSLOT_SCROLL]].sub_type)
- {
- case SCR_TELEPORTATION:
- if (!mons_has_ench(monster, ENCH_TP_I))
- {
- if (monster->behaviour == BEH_FLEE)
- {
- simple_monster_message(monster, " reads a scroll.");
- monster_teleport(monster, false);
- read = true;
- }
- }
- break;
-
- case SCR_BLINKING:
- if (monster->behaviour == BEH_FLEE)
- {
- if (mons_near(monster))
- {
- simple_monster_message(monster, " reads a scroll.");
- simple_monster_message(monster, " blinks!");
- monster_blink(monster);
- read = true;
- }
- }
- break;
-
- case SCR_SUMMONING:
- if (mons_near(monster))
- {
- simple_monster_message(monster, " reads a scroll.");
- create_monster( MONS_ABOMINATION_SMALL, ENCH_ABJ_II,
- SAME_ATTITUDE(monster), monster->x, monster->y,
- monster->foe, 250 );
- read = true;
- }
- break;
- }
-
- if (read)
- {
- if (dec_mitm_item_quantity( monster->inv[MSLOT_SCROLL], 1 ))
- monster->inv[MSLOT_SCROLL] = NON_ITEM;
- }
-
- return read;
- }
-} // end handle_scroll()
-
-//---------------------------------------------------------------
-//
-// handle_wand
-//
-// Give the monster a chance to zap a wand. Returns true if the
-// monster zapped.
-//
-//---------------------------------------------------------------
-static bool handle_wand(struct monsters *monster, bolt &beem)
-{
- // yes, there is a logic to this ordering {dlb}:
- if (monster->behaviour == BEH_SLEEP)
- return (false);
- else if (!mons_near(monster))
- return (false);
- else if (mons_has_ench( monster, ENCH_SUBMERGED ))
- return (false);
- else if (monster->inv[MSLOT_WAND] == NON_ITEM
- || mitm[monster->inv[MSLOT_WAND]].plus <= 0)
- {
- return (false);
- }
- else if (coinflip())
- {
- bool niceWand = false;
- bool zap = false;
-
- // map wand type to monster spell type
- int mzap = map_wand_to_mspell(mitm[monster->inv[MSLOT_WAND]].sub_type);
- if (mzap == 0)
- return (false);
-
- // set up the beam
- int power = 30 + monster->hit_dice;
- bolt theBeam = mons_spells(mzap, power);
-
- // XXX: ugly hack this:
- static char wand_buff[ ITEMNAME_SIZE ];
-
- strcpy( beem.beam_name, theBeam.beam_name );
- beem.beam_source = monster_index(monster);
- beem.source_x = monster->x;
- beem.source_y = monster->y;
- beem.colour = theBeam.colour;
- beem.range = theBeam.range;
- beem.rangeMax = theBeam.rangeMax;
- beem.damage = theBeam.damage;
- beem.ench_power = theBeam.ench_power;
- beem.hit = theBeam.hit;
- beem.type = theBeam.type;
- beem.flavour = theBeam.flavour;
- beem.thrower = theBeam.thrower;
- beem.is_beam = theBeam.is_beam;
-
- item_def item = mitm[ monster->inv[MSLOT_WAND] ];
-
-#if HISCORE_WEAPON_DETAIL
- set_ident_flags( item, ISFLAG_IDENT_MASK );
-#else
- unset_ident_flags( item, ISFLAG_IDENT_MASK );
- set_ident_flags( item, ISFLAG_KNOW_TYPE );
-#endif
-
- item_name( item, DESC_PLAIN, wand_buff );
-
- beem.aux_source = wand_buff;
-
- switch (mitm[monster->inv[MSLOT_WAND]].sub_type)
- {
- // these have been deemed "too tricky" at this time {dlb}:
- case WAND_POLYMORPH_OTHER:
- case WAND_ENSLAVEMENT:
- case WAND_DIGGING:
- case WAND_RANDOM_EFFECTS:
- return (false);
-
- // these are wands that monsters will aim at themselves {dlb}:
- case WAND_HASTING:
- if (!mons_has_ench(monster, ENCH_HASTE))
- {
- beem.target_x = monster->x;
- beem.target_y = monster->y;
-
- niceWand = true;
- break;
- }
- return (false);
-
- case WAND_HEALING:
- if (monster->hit_points <= monster->max_hit_points / 2)
- {
- beem.target_x = monster->x;
- beem.target_y = monster->y;
-
- niceWand = true;
- break;
- }
- return (false);
-
- case WAND_INVISIBILITY:
- if (!mons_has_ench( monster, ENCH_INVIS )
- && !mons_has_ench( monster, ENCH_SUBMERGED ))
- {
- beem.target_x = monster->x;
- beem.target_y = monster->y;
-
- niceWand = true;
- break;
- }
- return (false);
-
- case WAND_TELEPORTATION:
- if (monster->hit_points <= monster->max_hit_points / 2)
- {
- if (!mons_has_ench(monster, ENCH_TP_I) && !one_chance_in(20))
- {
- beem.target_x = monster->x;
- beem.target_y = monster->y;
-
- niceWand = true;
- break;
- }
- // this break causes the wand to be tried on the player:
- break;
- }
- return (false);
- }
-
- // fire tracer, if necessary
- if (!niceWand)
- {
- fire_tracer( monster, beem );
-
- // good idea?
- zap = mons_should_fire( beem );
- }
-
- if (niceWand || zap)
- {
- if (!simple_monster_message(monster, " zaps a wand."))
- {
- if (!silenced(you.x_pos, you.y_pos))
- mpr("You hear a zap.", MSGCH_SOUND);
- }
-
- // charge expenditure {dlb}
- mitm[monster->inv[MSLOT_WAND]].plus--;
- beem.is_tracer = false;
- fire_beam( beem );
-
- return (true);
- }
- }
-
- return (false);
-} // end handle_wand()
-
-static int get_draconian_breath_spell( struct monsters *monster )
-{
- int draco_breath = MS_NO_SPELL;
-
- if (mons_genus( monster->type ) == MONS_DRACONIAN)
- {
- switch (draco_subspecies( monster ))
- {
- case MONS_BLACK_DRACONIAN:
- draco_breath = MS_LIGHTNING_BOLT;
- break;
-
- case MONS_PALE_DRACONIAN:
- draco_breath = MS_STEAM_BALL;
- break;
-
- case MONS_GREEN_DRACONIAN:
- draco_breath = MS_POISON_BLAST;
- break;
-
- case MONS_PURPLE_DRACONIAN:
- draco_breath = MS_ORB_ENERGY;
- break;
-
- case MONS_MOTTLED_DRACONIAN:
- draco_breath = MS_STICKY_FLAME;
- break;
-
- case MONS_DRACONIAN:
- case MONS_YELLOW_DRACONIAN: // already handled as ability
- case MONS_RED_DRACONIAN: // already handled as ability
- case MONS_WHITE_DRACONIAN: // already handled as ability
- default:
- break;
- }
- }
-
- return (draco_breath);
-}
-
-//---------------------------------------------------------------
-//
-// handle_spell
-//
-// Give the monster a chance to cast a spell. Returns true if
-// a spell was cast.
-//
-//---------------------------------------------------------------
-static bool handle_spell( struct monsters *monster, bolt & beem )
-{
- bool monsterNearby = mons_near(monster);
- bool finalAnswer = false; // as in: "Is that your...?" {dlb}
- const int draco_breath = get_draconian_breath_spell(monster);
-
- // yes, there is a logic to this ordering {dlb}:
- if (monster->behaviour == BEH_SLEEP
- || (!mons_class_flag(monster->type, M_SPELLCASTER)
- && draco_breath == MS_NO_SPELL)
- || mons_has_ench( monster, ENCH_SUBMERGED ))
- {
- return (false);
- }
-
- if ((mons_class_flag(monster->type, M_ACTUAL_SPELLS)
- || mons_class_flag(monster->type, M_PRIEST))
- && (mons_has_ench(monster, ENCH_GLOWING_SHAPESHIFTER, ENCH_SHAPESHIFTER)))
- {
- return (false); //jmf: shapeshiftes don't get spells, just
- // physical powers.
- }
- else if (mons_has_ench(monster, ENCH_CONFUSION)
- && !mons_class_flag(monster->type, M_CONFUSED))
- {
- return (false);
- }
- else if (monster->type == MONS_PANDEMONIUM_DEMON
- && !ghost.values[ GVAL_DEMONLORD_SPELLCASTER ])
- {
- return (false);
- }
- else if (random2(200) > monster->hit_dice + 50
- || (monster->type == MONS_BALL_LIGHTNING && coinflip()))
- {
- return (false);
- }
- else
- {
- int spell_cast = MS_NO_SPELL;
- int hspell_pass[6] = { MS_NO_SPELL, MS_NO_SPELL, MS_NO_SPELL,
- MS_NO_SPELL, MS_NO_SPELL, MS_NO_SPELL };
-
- mons_spell_list(monster, hspell_pass);
-
- // forces the casting of dig when player not visible - this is EVIL!
- if (!monsterNearby)
- {
- if (hspell_pass[4] == MS_DIG && monster->behaviour == BEH_SEEK)
- {
- spell_cast = MS_DIG;
- finalAnswer = true;
- }
- else if (hspell_pass[2] == MS_HEAL
- && monster->hit_points < monster->max_hit_points)
- {
- // The player's out of sight!
- // Quick, let's take a turn to heal ourselves. -- bwr
- spell_cast = MS_HEAL;
- finalAnswer = true;
- }
- else if (monster->behaviour == BEH_FLEE)
- {
- // Since the player isn't around, we'll extend the monster's
- // normal fleeing choices to include the self-enchant slot.
- if (ms_useful_fleeing_out_of_sight(monster,hspell_pass[5]))
- {
- spell_cast = hspell_pass[5];
- finalAnswer = true;
- }
- else if (ms_useful_fleeing_out_of_sight(monster,hspell_pass[2]))
- {
- spell_cast = hspell_pass[2];
- finalAnswer = true;
- }
- }
- else if (monster->foe == MHITYOU)
- {
- return (false);
- }
- }
-
- // Promote the casting of useful spells for low-HP monsters.
- if (!finalAnswer
- && monster->hit_points < monster->max_hit_points / 4
- && !one_chance_in(4))
- {
- // Note: There should always be at least some chance we don't
- // get here... even if the monster is on it's last HP. That
- // way we don't have to worry about monsters infinitely casting
- // Healing on themselves (ie orc priests).
- if (monster->behaviour == BEH_FLEE
- && ms_low_hitpoint_cast( monster, hspell_pass[5] ))
- {
- spell_cast = hspell_pass[5];
- finalAnswer = true;
- }
- else if (ms_low_hitpoint_cast( monster, hspell_pass[2] ))
- {
- spell_cast = hspell_pass[2];
- finalAnswer = true;
- }
- }
-
- if (!finalAnswer)
- {
- // should monster not have selected dig by now, it never will:
- if (hspell_pass[4] == MS_DIG)
- hspell_pass[4] = MS_NO_SPELL;
-
- // remove healing/invis/haste if we don't need them
- int num_no_spell = 0;
-
- for (int i = 0; i < 6; i++)
- {
- if (hspell_pass[i] == MS_NO_SPELL)
- num_no_spell++;
- else if (ms_waste_of_time( monster, hspell_pass[i] ))
- {
- hspell_pass[i] = MS_NO_SPELL;
- num_no_spell++;
- }
- }
-
- // If no useful spells... cast no spell.
- if (num_no_spell == 6 && draco_breath == MS_NO_SPELL)
- return (false);
-
- // up to four tries to pick a spell.
- for (int loopy = 0; loopy < 4; loopy ++)
- {
- bool spellOK = false;
-
- // setup spell - fleeing monsters will always try to
- // choose their emergency spell.
- if (monster->behaviour == BEH_FLEE)
- {
- spell_cast = (one_chance_in(5) ? MS_NO_SPELL
- : hspell_pass[5]);
- }
- else
- {
- // Randomly picking one of the non-emergency spells:
- spell_cast = hspell_pass[random2(5)];
- }
-
- if (spell_cast == MS_NO_SPELL)
- continue;
-
- // setup the spell
- setup_mons_cast(monster, beem, spell_cast);
-
- // beam-type spells requiring tracers
- if (ms_requires_tracer(spell_cast))
- {
- fire_tracer(monster, beem);
- // good idea?
- if (mons_should_fire(beem))
- spellOK = true;
- }
- else
- {
- // all direct-effect/summoning/self-enchantments/etc
- spellOK = true;
-
- if (ms_direct_nasty(spell_cast)
- && mons_aligned(monster_index(monster), monster->foe))
- {
- spellOK = false;
- }
- else if (monster->foe == MHITYOU || monster->foe == MHITNOT)
- {
- // XXX: Note the crude hack so that monsters can
- // use ME_ALERT to target (we should really have
- // a measure of time instead of peeking to see
- // if the player is still there). -- bwr
- if (!mons_player_visible( monster )
- && (monster->target_x != you.x_pos
- || monster->target_y != you.y_pos
- || coinflip()))
- {
- spellOK = false;
- }
- }
- else if (!mons_monster_visible( monster, &menv[monster->foe] ))
- {
- spellOK = false;
- }
- }
-
- // if not okay, then maybe we'll cast a defensive spell
- if (!spellOK)
- spell_cast = (coinflip() ? hspell_pass[2] : MS_NO_SPELL);
-
- if (spell_cast != MS_NO_SPELL)
- break;
- }
- }
-
- if (spell_cast == MS_NO_SPELL && draco_breath != MS_NO_SPELL)
- {
- spell_cast = draco_breath;
- finalAnswer = true;
- }
-
- // should the monster *still* not have a spell, well, too bad {dlb}:
- if (spell_cast == MS_NO_SPELL)
- return (false);
-
- // Try to animate dead: if nothing rises, pretend we didn't cast it
- if (spell_cast == MS_ANIMATE_DEAD
- && !animate_dead( 100, SAME_ATTITUDE(monster), monster->foe, 0 ))
- {
- return (false);
- }
-
- if (monsterNearby) // handle monsters within range of player
- {
- if (monster->type == MONS_GERYON)
- {
- if (silenced(monster->x, monster->y))
- return (false);
-
- simple_monster_message( monster, " winds a great silver horn.",
- MSGCH_MONSTER_SPELL );
- }
- else if (mons_is_demon( monster->type ))
- {
- simple_monster_message( monster, " gestures.",
- MSGCH_MONSTER_SPELL );
- }
- else
- {
- switch (monster->type)
- {
- default:
- if (spell_cast == draco_breath)
- {
- if (!simple_monster_message(monster, " breathes.",
- MSGCH_MONSTER_SPELL))
- {
- if (!silenced(monster->x, monster->y)
- && !silenced(you.x_pos, you.y_pos))
- {
- mpr("You hear a roar.", MSGCH_SOUND);
- }
- }
- break;
- }
-
- if (silenced(monster->x, monster->y))
- return (false);
-
- if (mons_class_flag(monster->type, M_PRIEST))
- {
- switch (random2(3))
- {
- case 0:
- simple_monster_message( monster,
- " prays.",
- MSGCH_MONSTER_SPELL );
- break;
- case 1:
- simple_monster_message( monster,
- " mumbles some strange prayers.",
- MSGCH_MONSTER_SPELL );
- break;
- case 2:
- default:
- simple_monster_message( monster,
- " utters an invocation.",
- MSGCH_MONSTER_SPELL );
- break;
- }
- }
- else
- {
- switch (random2(3))
- {
- case 0:
- // XXX: could be better, chosen to match the
- // ones in monspeak.cc... has the problem
- // that it doesn't suggest a vocal component. -- bwr
- simple_monster_message( monster,
- " gestures wildly.",
- MSGCH_MONSTER_SPELL );
- break;
- case 1:
- simple_monster_message( monster,
- " mumbles some strange words.",
- MSGCH_MONSTER_SPELL );
- break;
- case 2:
- default:
- simple_monster_message( monster,
- " casts a spell.",
- MSGCH_MONSTER_SPELL );
- break;
- }
- }
- break;
-
- case MONS_BALL_LIGHTNING:
- monster->hit_points = -1;
- break;
-
- case MONS_STEAM_DRAGON:
- case MONS_MOTTLED_DRAGON:
- case MONS_STORM_DRAGON:
- case MONS_GOLDEN_DRAGON:
- case MONS_SHADOW_DRAGON:
- case MONS_SWAMP_DRAGON:
- case MONS_SWAMP_DRAKE:
- case MONS_DEATH_DRAKE:
- case MONS_HELL_HOG:
- case MONS_SERPENT_OF_HELL:
- case MONS_QUICKSILVER_DRAGON:
- case MONS_IRON_DRAGON:
- if (!simple_monster_message(monster, " breathes.",
- MSGCH_MONSTER_SPELL))
- {
- if (!silenced(monster->x, monster->y)
- && !silenced(you.x_pos, you.y_pos))
- {
- mpr("You hear a roar.", MSGCH_SOUND);
- }
- }
- break;
-
- case MONS_VAPOUR:
- mons_add_ench( monster, ENCH_SUBMERGED );
- break;
-
- case MONS_BRAIN_WORM:
- case MONS_ELECTRIC_GOLEM:
- // These don't show any signs that they're casting a spell.
- break;
-
- case MONS_GREAT_ORB_OF_EYES:
- case MONS_SHINING_EYE:
- case MONS_EYE_OF_DEVASTATION:
- simple_monster_message(monster, " gazes.", MSGCH_MONSTER_SPELL);
- break;
-
- case MONS_GIANT_ORANGE_BRAIN:
- simple_monster_message(monster, " pulsates.",
- MSGCH_MONSTER_SPELL);
- break;
-
- case MONS_NAGA:
- case MONS_NAGA_WARRIOR:
- simple_monster_message(monster, " spits poison.",
- MSGCH_MONSTER_SPELL);
- break;
- }
- }
- }
- else // handle far-away monsters
- {
- if (monster->type == MONS_GERYON
- && !silenced(you.x_pos, you.y_pos))
- {
- mpr("You hear a weird and mournful sound.", MSGCH_SOUND);
- }
- }
-
- // FINALLY! determine primary spell effects {dlb}:
- if (spell_cast == MS_BLINK && monsterNearby)
- // why only cast blink if nearby? {dlb}
- {
- simple_monster_message(monster, " blinks!");
- monster_blink(monster);
- }
- else
- {
- mons_cast(monster, beem, spell_cast);
- mmov_x = 0;
- mmov_y = 0;
- }
- } // end "if mons_class_flag(monster->type, M_SPELLCASTER) ...
-
- return (true);
-} // end handle_spell()
-
-//---------------------------------------------------------------
-//
-// handle_throw
-//
-// Give the monster a chance to throw something. Returns true if
-// the monster hurled.
-//
-//---------------------------------------------------------------
-static bool handle_throw(struct monsters *monster, bolt & beem)
-{
- // yes, there is a logic to this ordering {dlb}:
- if (mons_has_ench(monster, ENCH_CONFUSION)
- || monster->behaviour == BEH_SLEEP
- || mons_has_ench( monster, ENCH_SUBMERGED ))
- {
- return (false);
- }
-
- if (mons_itemuse(monster->type) < MONUSE_OPEN_DOORS)
- return (false);
-
- const int mon_item = monster->inv[MSLOT_MISSILE];
- if (mon_item == NON_ITEM || !is_valid_item( mitm[mon_item] ))
- return (false);
-
- // don't allow offscreen throwing.. for now.
- if (monster->foe == MHITYOU && !mons_near(monster))
- return (false);
-
- // poor 2-headed ogres {dlb}
- if (monster->type == MONS_TWO_HEADED_OGRE || monster->type == MONS_ETTIN)
- return (false);
-
- // recent addition {GDL} - monsters won't throw if they can do melee.
- // wastes valuable ammo, and most monsters are better at melee anyway.
- if (adjacent( beem.target_x, beem.target_y, monster->x, monster->y ))
- return (false);
-
- if (one_chance_in(5))
- return (false);
-
- // new (GDL) - don't throw idiotic stuff. It's a waste of time.
- int wepClass = mitm[mon_item].base_type;
- int wepType = mitm[mon_item].sub_type;
-
- int weapon = monster->inv[MSLOT_WEAPON];
-
- int lnchClass = (weapon != NON_ITEM) ? mitm[weapon].base_type : -1;
- int lnchType = (weapon != NON_ITEM) ? mitm[weapon].sub_type : 0;
-
- bool thrown = false;
- bool launched = false;
-
- throw_type( lnchClass, lnchType, wepClass, wepType, launched, thrown );
-
- if (!launched && !thrown)
- return (false);
-
- // ok, we'll try it.
- setup_generic_throw( monster, beem );
-
- // fire tracer
- fire_tracer( monster, beem );
-
- // good idea?
- if (mons_should_fire( beem ))
- {
- beem.beam_name[0] = '\0';
- return (mons_throw( monster, beem, mon_item ));
- }
-
- return (false);
-} // end handle_throw()
-
-static void handle_monster_move(int i, monsters *monster)
-{
- bool brkk = false;
- struct bolt beem;
- FixedArray <unsigned int, 19, 19> show;
-
- if (monster->hit_points > monster->max_hit_points)
- monster->hit_points = monster->max_hit_points;
-
- // monster just summoned (or just took stairs), skip this action
- if (testbits( monster->flags, MF_JUST_SUMMONED ))
- {
- monster->flags &= ~MF_JUST_SUMMONED;
- return;
- }
-
- monster->speed_increment += (monster->speed * you.time_taken) / 10;
-
- if (you.slow > 0)
- {
- monster->speed_increment += (monster->speed * you.time_taken) / 10;
- }
-
- // Handle enchantments and clouds on nonmoving monsters:
- if (monster->speed == 0)
- {
- if (env.cgrid[monster->x][monster->y] != EMPTY_CLOUD
- && !mons_has_ench( monster, ENCH_SUBMERGED ))
- {
- mons_in_cloud( monster );
- }
-
- handle_enchantment( monster );
- }
-
- // memory is decremented here for a reason -- we only want it
- // decrementing once per monster "move"
- if (monster->foe_memory > 0)
- monster->foe_memory--;
-
- if (monster->type == MONS_GLOWING_SHAPESHIFTER)
- mons_add_ench( monster, ENCH_GLOWING_SHAPESHIFTER );
-
- // otherwise there are potential problems with summonings
- if (monster->type == MONS_SHAPESHIFTER)
- mons_add_ench( monster, ENCH_SHAPESHIFTER );
-
- // We reset batty monsters from wander to seek here, instead
- // of in handle_behaviour() since that will be called with
- // every single movement, and we want these monsters to
- // hit and run. -- bwr
- if (monster->foe != MHITNOT
- && monster->behaviour == BEH_WANDER
- && testbits( monster->flags, MF_BATTY ))
- {
- monster->behaviour = BEH_SEEK;
- }
-
- while (monster->speed_increment >= 80)
- { // The continues & breaks are WRT this.
- if (monster->type != -1 && monster->hit_points < 1)
- break;
-
- monster->speed_increment -= 10;
-
- if (env.cgrid[monster->x][monster->y] != EMPTY_CLOUD)
- {
- if (mons_has_ench( monster, ENCH_SUBMERGED ))
- break;
-
- if (monster->type == -1)
- break; // problem with vortices
-
- mons_in_cloud(monster);
-
- if (monster->type == -1)
- {
- monster->speed_increment = 1;
- break;
- }
- }
-
- handle_behaviour(monster);
-
- if (handle_enchantment(monster))
- continue;
-
- // submerging monsters will hide from clouds
- const int habitat = monster_habitat( monster->type );
- if (habitat != DNGN_FLOOR
- && habitat == grd[monster->x][monster->y]
- && env.cgrid[monster->x][monster->y] != EMPTY_CLOUD)
- {
- mons_add_ench( monster, ENCH_SUBMERGED );
- }
-
- // regenerate:
- if (monster_descriptor(monster->type, MDSC_REGENERATES)
-
- || (monster->type == MONS_FIRE_ELEMENTAL
- && (grd[monster->x][monster->y] == DNGN_LAVA
- || env.cgrid[monster->x][monster->y] == CLOUD_FIRE
- || env.cgrid[monster->x][monster->y] == CLOUD_FIRE_MON))
-
- || (monster->type == MONS_WATER_ELEMENTAL
- && (grd[monster->x][monster->y] == DNGN_SHALLOW_WATER
- || grd[monster->x][monster->y] == DNGN_DEEP_WATER))
-
- || (monster->type == MONS_AIR_ELEMENTAL
- && env.cgrid[monster->x][monster->y] == EMPTY_CLOUD
- && one_chance_in(3))
-
- || one_chance_in(25))
- {
- heal_monster(monster, 1, false);
- }
-
- if (monster->speed >= 100)
- continue;
-
- if (monster->type == MONS_ZOMBIE_SMALL
- || monster->type == MONS_ZOMBIE_LARGE
- || monster->type == MONS_SIMULACRUM_SMALL
- || monster->type == MONS_SIMULACRUM_LARGE
- || monster->type == MONS_SKELETON_SMALL
- || monster->type == MONS_SKELETON_LARGE)
- {
- monster->max_hit_points = monster->hit_points;
- }
-
- if (igrd[monster->x][monster->y] != NON_ITEM
- && (mons_itemuse(monster->type) == MONUSE_WEAPONS_ARMOUR
- || mons_itemuse(monster->type) == MONUSE_EATS_ITEMS
- || monster->type == MONS_NECROPHAGE
- || monster->type == MONS_GHOUL))
- {
- if (handle_pickup(monster))
- continue;
- }
-
- // calculates mmov_x, mmov_y based on monster target.
- handle_movement(monster);
-
- brkk = false;
-
- if (mons_has_ench( monster, ENCH_CONFUSION )
- || (monster->type == MONS_AIR_ELEMENTAL
- && mons_has_ench( monster, ENCH_SUBMERGED )))
- {
- mmov_x = random2(3) - 1;
- mmov_y = random2(3) - 1;
-
- // bounds check: don't let confused monsters try to run
- // off the map
- if (monster->target_x + mmov_x < 0
- || monster->target_x + mmov_x >= GXM)
- {
- mmov_x = 0;
- }
-
- if (monster->target_y + mmov_y < 0
- || monster->target_y + mmov_y >= GYM)
- {
- mmov_y = 0;
- }
-
- if (mgrd[monster->x + mmov_x][monster->y + mmov_y] != NON_MONSTER
- && (mmov_x != 0 || mmov_y != 0))
- {
- mmov_x = 0;
- mmov_y = 0;
-
- if (monsters_fight(i, mgrd[monster->x + mmov_x][monster->y + mmov_y]))
- {
- brkk = true;
- }
- }
- }
-
- if (brkk)
- continue;
-
- handle_nearby_ability( monster );
-
- beem.target_x = monster->target_x;
- beem.target_y = monster->target_y;
-
- if (monster->behaviour != BEH_SLEEP
- && monster->behaviour != BEH_WANDER)
- {
- // prevents unfriendlies from nuking you from offscreen.
- // How nice!
- if (mons_friendly(monster) || mons_near(monster))
- {
- if (handle_special_ability(monster, beem))
- continue;
-
- if (handle_potion(monster, beem))
- continue;
-
- if (handle_scroll(monster))
- continue;
-
- // shapeshifters don't get spells
- if (!mons_has_ench( monster, ENCH_GLOWING_SHAPESHIFTER,
- ENCH_SHAPESHIFTER )
- || !mons_class_flag( monster->type, M_ACTUAL_SPELLS ))
- {
- if (handle_spell(monster, beem))
- continue;
- }
-
- if (handle_wand(monster, beem))
- continue;
-
- if (handle_reaching(monster))
- continue;
- }
-
- if (handle_throw(monster, beem))
- continue;
- }
-
- // see if we move into (and fight) an unfriendly monster
- int targmon = mgrd[monster->x + mmov_x][monster->y + mmov_y];
- if (targmon != NON_MONSTER
- && targmon != i
- && !mons_aligned(i, targmon))
- {
- // figure out if they fight
- if (monsters_fight(i, targmon))
- {
- if (testbits(monster->flags, MF_BATTY))
- {
- monster->behaviour = BEH_WANDER;
- monster->target_x = 10 + random2(GXM - 10);
- monster->target_y = 10 + random2(GYM - 10);
- // monster->speed_increment -= monster->speed;
- }
-
- mmov_x = 0;
- mmov_y = 0;
- brkk = true;
- }
- }
-
- if (brkk)
- continue;
-
- if (monster->x + mmov_x == you.x_pos
- && monster->y + mmov_y == you.y_pos)
- {
- bool isFriendly = mons_friendly(monster);
- bool attacked = false;
-
- if (!isFriendly)
- {
- monster_attack(i);
- attacked = true;
-
- if (testbits(monster->flags, MF_BATTY))
- {
- monster->behaviour = BEH_WANDER;
- monster->target_x = 10 + random2(GXM - 10);
- monster->target_y = 10 + random2(GYM - 10);
- }
- }
-
- if ((monster->type == MONS_GIANT_SPORE
- || monster->type == MONS_BALL_LIGHTNING)
- && monster->hit_points < 1)
- {
-
- // detach monster from the grid first, so it
- // doesn't get hit by its own explosion (GDL)
- mgrd[monster->x][monster->y] = NON_MONSTER;
-
- spore_goes_pop(monster);
- monster_cleanup(monster);
- continue;
- }
-
- if (attacked)
- {
- mmov_x = 0;
- mmov_y = 0;
- continue; //break;
- }
- }
-
- if (invalid_monster(monster) || mons_is_stationary(monster))
- continue;
-
- monster_move(monster);
-
- // reevaluate behaviour, since the monster's
- // surroundings have changed (it may have moved,
- // or died for that matter. Don't bother for
- // dead monsters. :)
- if (monster->type != -1)
- handle_behaviour(monster);
-
- } // end while
-
- if (monster->type != -1 && monster->hit_points < 1)
- {
- if (monster->type == MONS_GIANT_SPORE
- || monster->type == MONS_BALL_LIGHTNING)
- {
- // detach monster from the grid first, so it
- // doesn't get hit by its own explosion (GDL)
- mgrd[monster->x][monster->y] = NON_MONSTER;
-
- spore_goes_pop( monster );
- monster_cleanup( monster );
- return;
- }
- else
- {
- monster_die( monster, KILL_MISC, 0 );
- }
- }
-}
-
-//---------------------------------------------------------------
-//
-// handle_monsters
-//
-// This is the routine that controls monster AI.
-//
-//---------------------------------------------------------------
-void handle_monsters(void)
-{
- // Keep track of monsters that have already moved and don't allow
- // them to move again.
- memset(immobile_monster, 0, sizeof immobile_monster);
-
- for (int i = 0; i < MAX_MONSTERS; i++)
- {
- struct monsters *monster = &menv[i];
-
- if (monster->type == -1 || immobile_monster[i])
- continue;
-
- const int mx = monster->x,
- my = monster->y;
- handle_monster_move(i, monster);
-
- if (!invalid_monster(monster)
- && (monster->x != mx || monster->y != my))
- immobile_monster[i] = true;
- } // end of for loop
-
- // Clear any summoning flags so that lower indiced
- // monsters get their actions in the next round.
- for (int i = 0; i < MAX_MONSTERS; i++)
- {
- menv[i].flags &= ~MF_JUST_SUMMONED;
- }
-} // end handle_monster()
-
-
-//---------------------------------------------------------------
-//
-// handle_pickup
-//
-// Returns false if monster doesn't spend any time pickup up
-//
-//---------------------------------------------------------------
-static bool handle_pickup(struct monsters *monster)
-{
- // single calculation permissible {dlb}
- char str_pass[ ITEMNAME_SIZE ];
- bool monsterNearby = mons_near(monster);
- int item = NON_ITEM;
-
- if (mons_has_ench( monster, ENCH_SUBMERGED ))
- return (false);
-
- if (monster->behaviour == BEH_SLEEP)
- return (false);
-
- if (monster->type == MONS_JELLY
- || monster->type == MONS_BROWN_OOZE
- || monster->type == MONS_ACID_BLOB
- || monster->type == MONS_ROYAL_JELLY)
- {
- int hps_gained = 0;
- int max_eat = roll_dice( 1, 10 );
- int eaten = 0;
-
- for (item = igrd[monster->x][monster->y];
- item != NON_ITEM && eaten < max_eat && hps_gained < 50;
- item = mitm[item].link)
- {
- int quant = mitm[item].quantity;
-
- // don't eat fixed artefacts
- if (is_fixed_artefact( mitm[item] ))
- continue;
-
- // shouldn't eat stone things
- // - but what about wands and rings?
- if (mitm[item].base_type == OBJ_MISSILES
- && (mitm[item].sub_type == MI_STONE
- || mitm[item].sub_type == MI_LARGE_ROCK))
- {
- continue;
- }
-
- // don't eat special game items
- if (mitm[item].base_type == OBJ_ORBS
- || (mitm[item].base_type == OBJ_MISCELLANY
- && mitm[item].sub_type == MISC_RUNE_OF_ZOT))
- {
- continue;
- }
-
- if (mitm[igrd[monster->x][monster->y]].base_type != OBJ_GOLD)
- {
- if (quant > max_eat - eaten)
- quant = max_eat - eaten;
-
- hps_gained += (quant * item_mass( mitm[item] )) / 20 + quant;
- eaten += quant;
- }
- else
- {
- // shouldn't be much trouble to digest a huge pile of gold!
- if (quant > 500)
- quant = 500 + roll_dice( 2, (quant - 500) / 2 );
-
- hps_gained += quant / 10 + 1;
- eaten++;
- }
-
- dec_mitm_item_quantity( item, quant );
- }
-
- if (eaten)
- {
- if (hps_gained < 1)
- hps_gained = 1;
- else if (hps_gained > 50)
- hps_gained = 50;
-
- // This is done manually instead of using heal_monster(),
- // because that function doesn't work quite this way. -- bwr
- monster->hit_points += hps_gained;
-
- if (monster->max_hit_points < monster->hit_points)
- monster->max_hit_points = monster->hit_points;
-
- if (!silenced(you.x_pos, you.y_pos)
- && !silenced(monster->x, monster->y))
- {
- strcpy(info, "You hear a");
- if (!monsterNearby)
- strcat(info, " distant");
- strcat(info, " slurping noise.");
- mpr(info, MSGCH_SOUND);
- }
-
- if (mons_class_flag( monster->type, M_SPLITS ))
- {
- const int reqd = (monster->hit_dice <= 6)
- ? 50 : monster->hit_dice * 8;
-
- if (monster->hit_points >= reqd)
- jelly_divide(monster);
- }
- }
-
- return (false);
- } // end "if jellies"
-
- // Note: Monsters only look at top of stacks.
- item = igrd[monster->x][monster->y];
-
- switch (mitm[item].base_type)
- {
- case OBJ_WEAPONS:
- if (monster->inv[MSLOT_WEAPON] != NON_ITEM)
- return (false);
-
- if (is_fixed_artefact( mitm[item] ))
- return (false);
-
- if (is_random_artefact( mitm[item] ))
- return (false);
-
- // wimpy monsters (Kob, gob) shouldn't pick up halberds etc
- // of course, this also block knives {dlb}:
- if ((mons_species(monster->type) == MONS_KOBOLD
- || mons_species(monster->type) == MONS_GOBLIN)
- && property( mitm[item], PWPN_HIT ) <= 0)
- {
- return (false);
- }
-
- // Nobody picks up giant clubs:
- if (mitm[item].sub_type == WPN_GIANT_CLUB
- || mitm[item].sub_type == WPN_GIANT_SPIKED_CLUB)
- {
- return (false);
- }
-
- monster->inv[MSLOT_WEAPON] = item;
-
- if (get_weapon_brand(mitm[monster->inv[MSLOT_WEAPON]]) == SPWPN_PROTECTION)
- {
- monster->armour_class += 3;
- }
-
- if (monsterNearby)
- {
- strcpy(info, ptr_monam(monster, DESC_CAP_THE));
- strcat(info, " picks up ");
- it_name(monster->inv[MSLOT_WEAPON], DESC_NOCAP_A, str_pass);
- strcat(info, str_pass);
- strcat(info, ".");
- mpr(info);
- }
- break;
-
- case OBJ_MISSILES:
- // don't pick up if we're in combat, and there isn't much there
- if (mitm[item].quantity < 5 || monster->behaviour != BEH_WANDER)
- return (false);
-
- if (monster->inv[MSLOT_MISSILE] != NON_ITEM
- && mitm[monster->inv[MSLOT_MISSILE]].sub_type == mitm[item].sub_type
- && mitm[monster->inv[MSLOT_MISSILE]].plus == mitm[item].plus
- && mitm[monster->inv[MSLOT_MISSILE]].special == mitm[item].special)
- {
- if (monsterNearby)
- {
- strcpy(info, ptr_monam(monster, DESC_CAP_THE));
- strcat(info, " picks up ");
- it_name(item, DESC_NOCAP_A, str_pass);
- strcat(info, str_pass);
- strcat(info, ".");
- mpr(info);
- }
-
- inc_mitm_item_quantity( monster->inv[MSLOT_MISSILE],
- mitm[item].quantity );
-
- dec_mitm_item_quantity( item, mitm[item].quantity );
- return (true);
- }
-
- // nobody bothers to pick up rocks if they don't already have some:
- if (mitm[item].sub_type == MI_LARGE_ROCK)
- return (false);
-
- // monsters with powerful melee attacks don't bother
- if (mons_damage(monster->type, 0) > 5)
- return (false);
-
- monster->inv[MSLOT_MISSILE] = item;
-
- if (monsterNearby)
- {
- strcpy(info, ptr_monam(monster, DESC_CAP_THE));
- strcat(info, " picks up ");
- it_name(monster->inv[MSLOT_MISSILE], DESC_NOCAP_A, str_pass);
- strcat(info, str_pass);
- strcat(info, ".");
- mpr(info);
- }
- break;
-
- case OBJ_WANDS:
- if (monster->inv[MSLOT_WAND] != NON_ITEM)
- return (false);
-
- monster->inv[MSLOT_WAND] = item;
-
- if (monsterNearby)
- {
- strcpy(info, ptr_monam(monster, DESC_CAP_THE));
- strcat(info, " picks up ");
- it_name(monster->inv[MSLOT_WAND], DESC_NOCAP_A, str_pass);
- strcat(info, str_pass);
- strcat(info, ".");
- mpr(info);
- }
- break;
-
- case OBJ_SCROLLS:
- if (monster->inv[MSLOT_SCROLL] != NON_ITEM)
- return (false);
-
- monster->inv[MSLOT_SCROLL] = item;
-
- if (monsterNearby)
- {
- strcpy(info, ptr_monam(monster, DESC_CAP_THE));
- strcat(info, " picks up ");
- it_name(monster->inv[MSLOT_SCROLL], DESC_NOCAP_A, str_pass);
- strcat(info, str_pass);
- strcat(info, ".");
- mpr(info);
- }
- break;
-
- case OBJ_POTIONS:
- if (monster->inv[MSLOT_POTION] != NON_ITEM)
- return (false);
-
- monster->inv[MSLOT_POTION] = item;
-
- if (monsterNearby)
- {
- strcpy(info, ptr_monam(monster, DESC_CAP_THE));
- strcat(info, " picks up ");
- it_name(monster->inv[MSLOT_POTION], DESC_NOCAP_A, str_pass);
- strcat(info, str_pass);
- strcat(info, ".");
- mpr(info);
- }
- break;
-
- case OBJ_CORPSES:
- if (monster->type != MONS_NECROPHAGE && monster->type != MONS_GHOUL)
- return (false);
-
- monster->hit_points += 1 + random2(mons_weight(mitm[item].plus)) / 100;
-
- // limited growth factor here -- should 77 really be the cap? {dlb}:
- if (monster->hit_points > 100)
- monster->hit_points = 100;
-
- if (monster->hit_points > monster->max_hit_points)
- monster->max_hit_points = monster->hit_points;
-
- if (monsterNearby)
- {
- strcpy(info, ptr_monam(monster, DESC_CAP_THE));
- strcat(info, " eats ");
- it_name(item, DESC_NOCAP_THE, str_pass);
- strcat(info, str_pass);
- strcat(info, ".");
- mpr(info);
- }
-
- destroy_item( item );
- return (true);
-
- case OBJ_GOLD: //mv - monsters now pick up gold (19 May 2001)
- if (monsterNearby)
- {
-
- strcpy(info, monam( monster->number, monster->type,
- player_monster_visible( monster ),
- DESC_CAP_THE ));
-
- strcat(info, " picks up some gold.");
- mpr(info);
- }
-
- if (monster->inv[MSLOT_GOLD] != NON_ITEM)
- {
- // transfer gold to monster's object, destroy ground object
- inc_mitm_item_quantity( monster->inv[MSLOT_GOLD],
- mitm[item].quantity );
-
- destroy_item( item );
- return (true);
- }
- else
- {
- monster->inv[MSLOT_GOLD] = item;
- }
- break;
-
- default:
- return (false);
- }
-
- // Item has been picked-up, move to monster inventory.
- mitm[item].x = 0;
- mitm[item].y = 0;
-
- // Monster's only take the top item of stacks, so relink the
- // top item, and unlink the item.
- igrd[monster->x][monster->y] = mitm[item].link;
- mitm[item].link = NON_ITEM;
-
- if (monster->speed_increment > 25)
- monster->speed_increment -= monster->speed;
-
- return (true);
-} // end handle_pickup()
-
-static void jelly_grows(monsters *monster)
-{
- if (!silenced(you.x_pos, you.y_pos)
- && !silenced(monster->x, monster->y))
- {
- strcpy(info, "You hear a");
- if (!mons_near(monster))
- strcat(info, " distant");
- strcat(info, " slurping noise.");
- mpr(info, MSGCH_SOUND);
- }
-
- monster->hit_points += 5;
-
- // note here, that this makes jellies "grow" {dlb}:
- if (monster->hit_points > monster->max_hit_points)
- monster->max_hit_points = monster->hit_points;
-
- if (mons_class_flag( monster->type, M_SPLITS ))
- {
- // and here is where the jelly might divide {dlb}
- const int reqd = (monster->hit_dice < 6) ? 50
- : monster->hit_dice * 8;
-
- if (monster->hit_points >= reqd)
- jelly_divide(monster);
- }
-}
-
-static bool mons_can_displace(const monsters *mpusher, const monsters *mpushee)
-{
- if (invalid_monster(mpusher) || invalid_monster(mpushee))
- return (false);
-
- const int ipushee = monster_index(mpushee);
- if (ipushee < 0 || ipushee >= MAX_MONSTERS)
- return (false);
-
- if (immobile_monster[ipushee])
- return (false);
-
- // Confused monsters can't be pushed past, sleeping monsters
- // can't push. Note that sleeping monsters can't be pushed
- // past, either, but they may be woken up by a crowd trying to
- // elbow past them, and the wake-up check happens downstream.
- if (mons_is_confused(mpusher) || mons_is_confused(mpushee)
- || mons_is_paralysed(mpusher) || mons_is_paralysed(mpushee)
- || mons_is_sleeping(mpusher))
- return (false);
-
- // Batty monsters are unpushable
- if (mons_is_batty(mpusher) || mons_is_batty(mpushee))
- return (false);
-
- if (!monster_shover(mpusher))
- return (false);
-
- if (!monster_senior(mpusher, mpushee))
- return (false);
-
- return (true);
-}
-
-static bool monster_swaps_places( monsters *mon, int mx, int my )
-{
- if (!mx && !my)
- return (false);
-
- int targmon = mgrd[mon->x + mx][mon->y + my];
- if (targmon == MHITNOT || targmon == MHITYOU)
- return (false);
-
- monsters *m2 = &menv[targmon];
- if (!mons_can_displace(mon, m2))
- return (false);
-
- if (mons_is_sleeping(m2))
- {
- if (one_chance_in(2))
- {
-#ifdef DEBUG_DIAGNOSTICS
- char mname[ITEMNAME_SIZE];
- moname(m2->type, true, DESC_PLAIN, mname);
- mprf(MSGCH_DIAGNOSTICS,
- "Alerting monster %s at (%d,%d)", mname, m2->x, m2->y);
-#endif
- behaviour_event( m2, ME_ALERT, MHITNOT );
- }
- return (false);
- }
-
- // Check that both monsters will be happy at their proposed new locations.
- const int cx = mon->x, cy = mon->y,
- nx = mon->x + mx, ny = mon->y + my;
- if (!habitat_okay(mon, grd[nx][ny])
- || !habitat_okay(m2, grd[cx][cy]))
- return (false);
-
- // Okay, do the swap!
-#ifdef DEBUG_DIAGNOSTICS
- char mname[ITEMNAME_SIZE];
- moname(mon->type, true, DESC_PLAIN, mname);
- mprf(MSGCH_DIAGNOSTICS,
- "Swap: %s (%d,%d)->(%d,%d) (%d;%d)",
- mname, mon->x, mon->y, nx, ny, mon->speed_increment, mon->speed);
-#endif
- mon->x = nx;
- mon->y = ny;
- mgrd[nx][ny] = monster_index(mon);
-
-#ifdef DEBUG_DIAGNOSTICS
- moname(m2->type, true, DESC_PLAIN, mname);
- mprf(MSGCH_DIAGNOSTICS,
- "Swap: %s (%d,%d)->(%d,%d) (%d;%d)",
- mname, m2->x, m2->y, cx, cy, mon->speed_increment, mon->speed);
-#endif
- m2->x = cx;
- m2->y = cy;
- const int m2i = monster_index(m2);
- ASSERT(m2i >= 0 && m2i < MAX_MONSTERS);
- mgrd[cx][cy] = m2i;
- immobile_monster[m2i] = true;
-
- mons_trap(mon);
- mons_trap(m2);
-
- return (false);
-}
-
-static void monster_move(struct monsters *monster)
-{
- FixedArray < bool, 3, 3 > good_move;
- int count_x, count_y, count;
- int okmove = DNGN_SHALLOW_WATER;
-
- const int habitat = monster_habitat( monster->type );
- bool deep_water_available = false;
-
- // let's not even bother with this if mmov_x and mmov_y are zero.
- if (mmov_x == 0 && mmov_y == 0)
- return;
-
- // effectively slows down monster movement across water.
- // Fire elementals can't cross at all.
- if (monster->type == MONS_FIRE_ELEMENTAL || one_chance_in(5))
- okmove = DNGN_WATER_STUCK;
-
- if (mons_flies(monster) > 0
- || habitat != DNGN_FLOOR
- || mons_class_flag( monster->type, M_AMPHIBIOUS ))
- {
- okmove = MINMOVE;
- }
-
- for (count_x = 0; count_x < 3; count_x++)
- {
- for (count_y = 0; count_y < 3; count_y++)
- {
- good_move[count_x][count_y] = true;
- const int targ_x = monster->x + count_x - 1;
- const int targ_y = monster->y + count_y - 1;
- int target_grid = grd[targ_x][targ_y];
-
- const int targ_cloud = env.cgrid[ targ_x ][ targ_y ];
- const int curr_cloud = env.cgrid[ monster->x ][ monster->y ];
-
- // bounds check - don't consider moving out of grid!
- if (targ_x < 0 || targ_x >= GXM || targ_y < 0 || targ_y >= GYM)
- {
- good_move[count_x][count_y] = false;
- continue;
- }
-
- if (target_grid == DNGN_DEEP_WATER)
- deep_water_available = true;
-
- if (monster->type == MONS_BORING_BEETLE
- && target_grid == DNGN_ROCK_WALL)
- {
- // don't burrow out of bounds
- if (targ_x <= 7 || targ_x >= (GXM - 8)
- || targ_y <= 7 || targ_y >= (GYM - 8))
- {
- good_move[count_x][count_y] = false;
- continue;
- }
-
- // don't burrow at an angle (legacy behaviour)
- if (count_x != 1 && count_y != 1)
- {
- good_move[count_x][count_y] = false;
- continue;
- }
- }
- else if (grd[ targ_x ][ targ_y ] < okmove)
- {
- good_move[count_x][count_y] = false;
- continue;
- }
- else if (!habitat_okay( monster, target_grid ))
- {
- good_move[count_x][count_y] = false;
- continue;
- }
-
- if (monster->type == MONS_WANDERING_MUSHROOM
- && see_grid(targ_x, targ_y))
- {
- good_move[count_x][count_y] = false;
- continue;
- }
-
- // Water elementals avoid fire and heat
- if (monster->type == MONS_WATER_ELEMENTAL
- && (target_grid == DNGN_LAVA
- || targ_cloud == CLOUD_FIRE
- || targ_cloud == CLOUD_FIRE_MON
- || targ_cloud == CLOUD_STEAM
- || targ_cloud == CLOUD_STEAM_MON))
- {
- good_move[count_x][count_y] = false;
- continue;
- }
-
- // Fire elementals avoid water and cold
- if (monster->type == MONS_FIRE_ELEMENTAL
- && (target_grid == DNGN_DEEP_WATER
- || target_grid == DNGN_SHALLOW_WATER
- || target_grid == DNGN_BLUE_FOUNTAIN
- || targ_cloud == CLOUD_COLD
- || targ_cloud == CLOUD_COLD_MON))
- {
- good_move[count_x][count_y] = false;
- continue;
- }
-
- // Submerged water creatures avoid the shallows where
- // they would be forced to surface. -- bwr
- if (habitat == DNGN_DEEP_WATER
- && (targ_x != you.x_pos || targ_y != you.y_pos)
- && target_grid != DNGN_DEEP_WATER
- && grd[monster->x][monster->y] == DNGN_DEEP_WATER
- && (mons_has_ench( monster, ENCH_SUBMERGED )
- || monster->hit_points < (monster->max_hit_points * 3) / 4))
- {
- good_move[count_x][count_y] = false;
- continue;
- }
-
- // smacking the player is always a good move if
- // we're hostile (even if we're heading somewhere
- // else)
-
- // smacking another monster is good, if the monsters
- // are aligned differently
- if (mgrd[targ_x][targ_y] != NON_MONSTER)
- {
- const int thismonster = monster_index(monster),
- targmonster = mgrd[targ_x][targ_y];
- if (mons_aligned(thismonster, targmonster)
- && targmonster != MHITNOT
- && targmonster != MHITYOU
- && !mons_can_displace(monster, &menv[targmonster]))
- {
- good_move[count_x][count_y] = false;
- continue;
- }
- }
-
- // wandering through a trap is OK if we're pretty healthy, or
- // really stupid.
- if (trap_at_xy(targ_x,targ_y) >= 0
- && mons_intel(monster->type) != I_PLANT)
- {
- if (monster->hit_points < monster->max_hit_points / 2)
- {
- good_move[count_x][count_y] = false;
- continue;
- }
- }
-
- if (targ_cloud != EMPTY_CLOUD)
- {
- if (curr_cloud != EMPTY_CLOUD
- && env.cloud[targ_cloud].type == env.cloud[curr_cloud].type)
- {
- continue;
- }
-
- switch (env.cloud[ targ_cloud ].type)
- {
- case CLOUD_FIRE:
- case CLOUD_FIRE_MON:
- if (mons_res_fire(monster) > 0)
- continue;
-
- if (monster->hit_points >= 15 + random2avg(46, 5))
- continue;
- break;
-
- case CLOUD_STINK:
- case CLOUD_STINK_MON:
- if (mons_res_poison(monster) > 0)
- continue;
- if (1 + random2(5) < monster->hit_dice)
- continue;
- if (monster->hit_points >= random2avg(19, 2))
- continue;
- break;
-
- case CLOUD_COLD:
- case CLOUD_COLD_MON:
- if (mons_res_cold(monster) > 0)
- continue;
-
- if (monster->hit_points >= 15 + random2avg(46, 5))
- continue;
- break;
-
- case CLOUD_POISON:
- case CLOUD_POISON_MON:
- if (mons_res_poison(monster) > 0)
- continue;
-
- if (monster->hit_points >= random2avg(37, 4))
- continue;
- break;
-
- // this isn't harmful, but dumb critters might think so.
- case CLOUD_GREY_SMOKE:
- case CLOUD_GREY_SMOKE_MON:
- if (mons_intel(monster->type) > I_ANIMAL || coinflip())
- continue;
-
- if (mons_res_fire(monster) > 0)
- continue;
-
- if (monster->hit_points >= random2avg(19, 2))
- continue;
- break;
-
- default:
- continue; // harmless clouds
- }
-
- // if we get here, the cloud is potentially harmful.
- // exceedingly dumb creatures will still wander in.
- if (mons_intel(monster->type) != I_PLANT)
- good_move[count_x][count_y] = false;
- }
- }
- } // now we know where we _can_ move.
-
- // normal/smart monsters know about secret doors (they _live_ in the
- // dungeon!)
- if (grd[monster->x + mmov_x][monster->y + mmov_y] == DNGN_CLOSED_DOOR
- || (grd[monster->x + mmov_x][monster->y + mmov_y] == DNGN_SECRET_DOOR
- && (mons_intel(monster_index(monster)) == I_HIGH
- || mons_intel(monster_index(monster)) == I_NORMAL)))
- {
- if (monster->type == MONS_ZOMBIE_SMALL
- || monster->type == MONS_ZOMBIE_LARGE
- || monster->type == MONS_SIMULACRUM_SMALL
- || monster->type == MONS_SIMULACRUM_LARGE
- || monster->type == MONS_SKELETON_SMALL
- || monster->type == MONS_SKELETON_LARGE
- || monster->type == MONS_SPECTRAL_THING)
- {
- // for zombies, monster type is kept in mon->number
- if (mons_itemuse(monster->number) >= MONUSE_OPEN_DOORS)
- {
- grd[monster->x + mmov_x][monster->y + mmov_y] = DNGN_OPEN_DOOR;
- return;
- }
- }
- else if (mons_itemuse(monster->type) >= MONUSE_OPEN_DOORS)
- {
- grd[monster->x + mmov_x][monster->y + mmov_y] = DNGN_OPEN_DOOR;
- return;
- }
- } // endif - secret/closed doors
-
- // jellies eat doors. Yum!
- if ((grd[monster->x + mmov_x][monster->y + mmov_y] == DNGN_CLOSED_DOOR
- || grd[monster->x + mmov_x][monster->y + mmov_y] == DNGN_OPEN_DOOR)
- && mons_itemuse(monster->type) == MONUSE_EATS_ITEMS)
- {
- grd[monster->x + mmov_x][monster->y + mmov_y] = DNGN_FLOOR;
-
- jelly_grows(monster);
- } // done door-eating jellies
-
-
- // water creatures have a preferance for water they can hide in -- bwr
- if (habitat == DNGN_DEEP_WATER
- && deep_water_available
- && grd[monster->x][monster->y] != DNGN_DEEP_WATER
- && grd[monster->x + mmov_x][monster->y + mmov_y] != DNGN_DEEP_WATER
- && (monster->x + mmov_x != you.x_pos
- || monster->y + mmov_y != you.y_pos)
- && (coinflip()
- || monster->hit_points <= (monster->max_hit_points * 3) / 4))
- {
- count = 0;
-
- for (count_x = 0; count_x < 3; count_x++)
- {
- for (count_y = 0; count_y < 3; count_y++)
- {
- if (good_move[count_x][count_y]
- && grd[monster->x + count_x - 1][monster->y + count_y - 1]
- == DNGN_DEEP_WATER)
- {
- count++;
-
- if (one_chance_in( count ))
- {
- mmov_x = count_x - 1;
- mmov_y = count_y - 1;
- }
- }
- }
- }
- }
-
-
- // now, if a monster can't move in its intended direction, try
- // either side. If they're both good, move in whichever dir
- // gets it closer(farther for fleeing monsters) to its target.
- // If neither does, do nothing.
- if (good_move[mmov_x + 1][mmov_y + 1] == false)
- {
- int current_distance = grid_distance( monster->x, monster->y,
- monster->target_x,
- monster->target_y );
-
- int dir = -1;
- int i, mod, newdir;
-
- for (i = 0; i < 8; i++)
- {
- if (compass_x[i] == mmov_x && compass_y[i] == mmov_y)
- {
- dir = i;
- break;
- }
- }
-
- if (dir < 0)
- goto forget_it;
-
- int dist[2];
-
- // first 1 away, then 2 (3 is silly)
- for (int j = 1; j <= 2; j++)
- {
- int sdir, inc;
-
- if (coinflip())
- {
- sdir = -j;
- inc = 2*j;
- }
- else
- {
- sdir = j;
- inc = -2*j;
- }
-
- // try both directions
- for (mod = sdir, i = 0; i < 2; mod += inc, i++)
- {
- newdir = (dir + 8 + mod) % 8;
- if (good_move[compass_x[newdir] + 1][compass_y[newdir] + 1])
- {
- dist[i] = grid_distance( monster->x + compass_x[newdir],
- monster->y + compass_y[newdir],
- monster->target_x,
- monster->target_y );
- }
- else
- {
- dist[i] = (monster->behaviour == BEH_FLEE) ? (-FAR_AWAY)
- : FAR_AWAY;
- }
- }
-
- // now choose
- if (dist[0] == dist[1] && abs(dist[0]) == FAR_AWAY)
- continue;
-
- // which one was better? -- depends on FLEEING or not
- if (monster->behaviour == BEH_FLEE)
- {
- if (dist[0] >= dist[1] && dist[0] >= current_distance)
- {
- mmov_x = compass_x[((dir+8)+sdir)%8];
- mmov_y = compass_y[((dir+8)+sdir)%8];
- break;
- }
- if (dist[1] >= dist[0] && dist[1] >= current_distance)
- {
- mmov_x = compass_x[((dir+8)-sdir)%8];
- mmov_y = compass_y[((dir+8)-sdir)%8];
- break;
- }
- }
- else
- {
- if (dist[0] <= dist[1] && dist[0] <= current_distance)
- {
- mmov_x = compass_x[((dir+8)+sdir)%8];
- mmov_y = compass_y[((dir+8)+sdir)%8];
- break;
- }
- if (dist[1] <= dist[0] && dist[1] <= current_distance)
- {
- mmov_x = compass_x[((dir+8)-sdir)%8];
- mmov_y = compass_y[((dir+8)-sdir)%8];
- break;
- }
- }
- }
- } // end - try to find good alternate move
-
-forget_it:
-
- // ------------------------------------------------------------------
- // if we haven't found a good move by this point, we're not going to.
- // ------------------------------------------------------------------
-
- // take care of beetle burrowing
- if (monster->type == MONS_BORING_BEETLE)
- {
- if (grd[monster->x + mmov_x][monster->y + mmov_y] == DNGN_ROCK_WALL
- && good_move[mmov_x + 1][mmov_y + 1] == true)
- {
- grd[monster->x + mmov_x][monster->y + mmov_y] = DNGN_FLOOR;
-
- if (!silenced(you.x_pos, you.y_pos))
- mpr("You hear a grinding noise.", MSGCH_SOUND);
- }
- }
-
- mgrd[monster->x][monster->y] = NON_MONSTER;
-
- if (good_move[mmov_x + 1][mmov_y + 1] && !(mmov_x == 0 && mmov_y == 0))
- {
- // check for attacking player
- if (monster->x + mmov_x == you.x_pos
- && monster->y + mmov_y == you.y_pos)
- {
- monster_attack( monster_index(monster) );
- mmov_x = 0;
- mmov_y = 0;
- }
-
- // If we're following the player through stairs, the only valid
- // movement is towards the player. -- bwr
- if (testbits( monster->flags, MF_TAKING_STAIRS ))
- {
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "%s is skipping movement in order to follow.",
- ptr_monam( monster, DESC_CAP_THE ) );
-
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
- mmov_x = 0;
- mmov_y = 0;
- }
-
- // check for attacking another monster
- int targmon = mgrd[monster->x + mmov_x][monster->y + mmov_y];
- if (targmon != NON_MONSTER)
- {
- if (mons_aligned(monster_index(monster), targmon))
- monster_swaps_places(monster, mmov_x, mmov_y);
- else
- monsters_fight(monster_index(monster), targmon);
-
- // If the monster swapped places, the work's already done.
- mmov_x = 0;
- mmov_y = 0;
- }
-
- if (monster->type == MONS_EFREET
- || monster->type == MONS_FIRE_ELEMENTAL)
- {
- place_cloud( CLOUD_FIRE_MON, monster->x, monster->y,
- 2 + random2(4) );
- }
-
- if (monster->type == MONS_ROTTING_DEVIL)
- {
- place_cloud( CLOUD_MIASMA_MON, monster->x, monster->y,
- 2 + random2(3) );
- }
-
- /* this appears to be the real one, ie where the movement occurs: */
- monster->x += mmov_x;
- monster->y += mmov_y;
- }
- else
- {
- // fleeing monsters that can't move will panic and possibly
- // turn to face their attacker
- if (monster->behaviour == BEH_FLEE)
- behaviour_event(monster, ME_CORNERED);
- }
-
- /* need to put in something so that monster picks up multiple
- items (eg ammunition) identical to those it's carrying. */
- mgrd[monster->x][monster->y] = monster_index(monster);
-
- // monsters stepping on traps:
- if (mmov_x != 0 || mmov_y != 0)
- {
- mons_trap(monster);
- }
-} // end monster_move()
-
-
-static bool plant_spit(struct monsters *monster, struct bolt &pbolt)
-{
- bool didSpit = false;
-
- char spit_string[INFO_SIZE];
-
- // setup plant spit
- strcpy( pbolt.beam_name, "acid" );
- pbolt.type = SYM_ZAP;
- pbolt.range = 9;
- pbolt.rangeMax = 9;
- pbolt.colour = YELLOW;
- pbolt.flavour = BEAM_ACID;
- pbolt.beam_source = monster_index(monster);
- pbolt.damage = dice_def( 3, 7 );
- pbolt.hit = 20 + (3 * monster->hit_dice);
- pbolt.thrower = KILL_MON_MISSILE;
- pbolt.aux_source = NULL;
-
- // fire tracer
- fire_tracer(monster, pbolt);
-
- if (mons_should_fire(pbolt))
- {
- strcpy( spit_string, " spits" );
- if (pbolt.target_x == you.x_pos && pbolt.target_y == you.y_pos)
- strcat( spit_string, " at you" );
-
- strcat( spit_string, "." );
- simple_monster_message( monster, spit_string );
-
- fire_beam( pbolt );
- didSpit = true;
- }
-
- return (didSpit);
-} // end plant_spit()
-
-static void mons_in_cloud(struct monsters *monster)
-{
- int wc = env.cgrid[monster->x][monster->y];
- int hurted = 0;
- struct bolt beam;
-
- const int speed = ((monster->speed > 0) ? monster->speed : 10);
- bool wake = false;
-
- if (mons_is_mimic( monster->type ))
- {
- mimic_alert(monster);
- return;
- }
-
- switch (env.cloud[wc].type)
- {
- case CLOUD_DEBUGGING:
- cprintf("Fatal error: monster steps on nonexistent cloud!");
- exit(0);
- return;
-
- case CLOUD_FIRE:
- case CLOUD_FIRE_MON:
- if (monster->type == MONS_FIRE_VORTEX
- || monster->type == MONS_EFREET
- || monster->type == MONS_FIRE_ELEMENTAL)
- {
- return;
- }
-
- simple_monster_message(monster, " is engulfed in flame!");
-
- if (mons_res_fire(monster) > 0)
- return;
-
- hurted += ((random2avg(16, 3) + 6) * 10) / speed;
-
- if (mons_res_fire(monster) < 0)
- hurted += (random2(15) * 10) / speed;
-
- // remember that the above is in addition to the other you.damage.
- hurted -= random2(1 + monster->armour_class);
- break; // to damage routine at end {dlb}
-
- case CLOUD_STINK:
- case CLOUD_STINK_MON:
- simple_monster_message(monster, " is engulfed in noxious gasses!");
-
- if (mons_res_poison(monster) > 0)
- return;
-
- beam.flavour = BEAM_CONFUSION;
-
- if (1 + random2(27) >= monster->hit_dice)
- mons_ench_f2(monster, beam);
-
- hurted += (random2(3) * 10) / speed;
- break; // to damage routine at end {dlb}
-
- case CLOUD_COLD:
- case CLOUD_COLD_MON:
- simple_monster_message(monster, " is engulfed in freezing vapours!");
-
- if (mons_res_cold(monster) > 0)
- return;
-
- hurted += ((6 + random2avg(16, 3)) * 10) / speed;
-
- if (mons_res_cold(monster) < 0)
- hurted += (random2(15) * 10) / speed;
-
- // remember that the above is in addition to the other damage.
- hurted -= random2(1 + monster->armour_class);
- break; // to damage routine at end {dlb}
-
- // what of armour of poison resistance here? {dlb}
- case CLOUD_POISON:
- case CLOUD_POISON_MON:
- simple_monster_message(monster, " is engulfed in a cloud of poison!");
-
- if (mons_res_poison(monster) > 0)
- return;
-
- poison_monster(monster, (env.cloud[wc].type == CLOUD_POISON));
- // If the monster got poisoned, wake it up.
- wake = true;
-
- hurted += (random2(8) * 10) / speed;
-
- if (mons_res_poison(monster) < 0)
- hurted += (random2(4) * 10) / speed;
- break; // to damage routine at end {dlb}
-
- case CLOUD_STEAM:
- case CLOUD_STEAM_MON:
- // couldn't be bothered coding for armour of res fire
-
- // what of whether it is wearing steam dragon armour? {dlb}
- if (monster->type == MONS_STEAM_DRAGON)
- return;
-
- simple_monster_message(monster, " is engulfed in steam!");
-
- if (mons_res_fire(monster) > 0)
- return;
-
- hurted += (random2(6) * 10) / speed;
-
- if (mons_res_fire(monster) < 0)
- hurted += (random2(6) * 10) / speed;
-
- hurted -= random2(1 + monster->armour_class);
- break; // to damage routine at end {dlb}
-
- case CLOUD_MIASMA:
- case CLOUD_MIASMA_MON:
- simple_monster_message(monster, " is engulfed in a dark miasma!");
-
- if (mons_holiness(monster) != MH_NATURAL
- || monster->type == MONS_DEATH_DRAKE)
- return;
-
- poison_monster(monster, (env.cloud[wc].type == CLOUD_MIASMA));
-
- if (monster->max_hit_points > 4 && coinflip())
- monster->max_hit_points--;
-
- beam.flavour = BEAM_SLOW;
-
- if (one_chance_in(3))
- mons_ench_f2(monster, beam);
-
- hurted += (10 * random2avg(12, 3)) / speed; // 3
- break; // to damage routine at end {dlb}
-
- default: // 'harmless' clouds -- colored smoke, etc {dlb}.
- return;
- }
-
- // A sleeping monster that sustains damage will wake up.
- if ((wake || hurted > 0) && monster->behaviour == BEH_SLEEP)
- {
- // We have no good coords to give the monster as the source of the
- // disturbance other than the cloud itself.
- behaviour_event(monster, ME_DISTURB, MHITNOT, monster->x, monster->y);
- }
-
- if (hurted < 0)
- hurted = 0;
- else if (hurted > 0)
- {
- hurt_monster(monster, hurted);
-
- if (monster->hit_points < 1)
- {
- switch (env.cloud[wc].type)
- {
- case CLOUD_FIRE_MON:
- case CLOUD_STINK_MON:
- case CLOUD_COLD_MON:
- case CLOUD_POISON_MON:
- case CLOUD_STEAM_MON:
- case CLOUD_MIASMA_MON:
- monster_die(monster, KILL_MISC, 0);
- break;
- default:
- monster_die(monster, KILL_YOU, 0);
- }
-
- switch (env.cloud[wc].type)
- {
- case CLOUD_FIRE:
- case CLOUD_FIRE_MON:
- case CLOUD_COLD:
- case CLOUD_COLD_MON:
- case CLOUD_STEAM:
- case CLOUD_STEAM_MON:
- monster->speed_increment = 1;
- }
- }
- }
-} // end mons_in_cloud()
-
-unsigned char monster_habitat(int which_class)
-{
- switch (which_class)
- {
- case MONS_BIG_FISH:
- case MONS_GIANT_GOLDFISH:
- case MONS_ELECTRICAL_EEL:
- case MONS_JELLYFISH:
- case MONS_SWAMP_WORM:
- case MONS_WATER_ELEMENTAL:
- return (DNGN_DEEP_WATER); // no shallow water (only) monsters? {dlb}
- // must remain DEEP_WATER for now, else breaks code {dlb}
-
- case MONS_LAVA_WORM:
- case MONS_LAVA_FISH:
- case MONS_LAVA_SNAKE:
- case MONS_SALAMANDER:
- return (DNGN_LAVA);
-
- default:
- return (DNGN_FLOOR); // closest match to terra firma {dlb}
- }
-} // end monster_habitat()
-
-bool monster_descriptor(int which_class, unsigned char which_descriptor)
-{
- if (which_descriptor == MDSC_LEAVES_HIDE)
- {
- switch (which_class)
- {
- case MONS_DRAGON:
- case MONS_TROLL:
- case MONS_ICE_DRAGON:
- case MONS_STEAM_DRAGON:
- case MONS_MOTTLED_DRAGON:
- case MONS_STORM_DRAGON:
- case MONS_GOLDEN_DRAGON:
- case MONS_SWAMP_DRAGON:
- return (true);
- default:
- return (false);
- }
- }
-
- if (which_descriptor == MDSC_REGENERATES)
- {
- switch (which_class)
- {
- case MONS_CACODEMON:
- case MONS_DEEP_TROLL:
- case MONS_HELLWING:
- case MONS_IMP:
- case MONS_IRON_TROLL:
- case MONS_LEMURE:
- case MONS_ROCK_TROLL:
- case MONS_SLIME_CREATURE:
- case MONS_SNORG:
- case MONS_TROLL:
- case MONS_HYDRA:
- case MONS_KILLER_KLOWN:
- return (true);
- default:
- return (false);
- }
- }
-
- if (which_descriptor == MDSC_NOMSG_WOUNDS)
- {
- switch (which_class)
- {
- case MONS_RAKSHASA:
- case MONS_RAKSHASA_FAKE:
- case MONS_SKELETON_LARGE:
- case MONS_SKELETON_SMALL:
- case MONS_ZOMBIE_LARGE:
- case MONS_ZOMBIE_SMALL:
- case MONS_SIMULACRUM_SMALL:
- case MONS_SIMULACRUM_LARGE:
- return (true);
- default:
- return (false);
- }
- }
- return (false);
-} // end monster_descriptor()
-
-bool message_current_target(void)
-{
- if (you.prev_targ != MHITNOT && you.prev_targ != MHITYOU)
- {
- struct monsters *montarget = &menv[you.prev_targ];
-
- if (mons_near(montarget) && player_monster_visible( montarget ))
- {
- snprintf( info, INFO_SIZE,
- "You are currently targeting %s (use p/t to fire).",
- ptr_monam(montarget, DESC_NOCAP_THE) );
-
- mpr(info);
- return (true); // early return {dlb}
- }
-
- mpr("You have no current target.");
- }
-
- return (false);
-} // end message_current_target()
-
-// aaah, the simple joys of pointer arithmetic! {dlb}:
-unsigned int monster_index(const monsters *monster)
-{
- return (monster - menv.buffer());
-} // end monster_index()
-
-bool hurt_monster(struct monsters * victim, int damage_dealt)
-{
- bool just_a_scratch = true;
-
- if (damage_dealt > 0)
- {
- just_a_scratch = false;
- victim->hit_points -= damage_dealt;
- }
-
- return (!just_a_scratch);
-} // end hurt_monster()
-
-bool heal_monster(struct monsters * patient, int health_boost,
- bool permit_growth)
-{
- if (health_boost < 1)
- return (false);
- else if (!permit_growth && patient->hit_points == patient->max_hit_points)
- return (false);
- else
- {
- patient->hit_points += health_boost;
-
- if (patient->hit_points > patient->max_hit_points)
- {
- if (permit_growth)
- patient->max_hit_points++;
-
- patient->hit_points = patient->max_hit_points;
- }
- }
-
- return (true);
-} // end heal_monster()
-
-static int map_wand_to_mspell(int wand_type)
-{
- int mzap = 0;
-
- switch (wand_type)
- {
- case WAND_FLAME:
- mzap = MS_FLAME;
- break;
- case WAND_FROST:
- mzap = MS_FROST;
- break;
- case WAND_SLOWING:
- mzap = MS_SLOW;
- break;
- case WAND_HASTING:
- mzap = MS_HASTE;
- break;
- case WAND_MAGIC_DARTS:
- mzap = MS_MMISSILE;
- break;
- case WAND_HEALING:
- mzap = MS_HEAL;
- break;
- case WAND_PARALYSIS:
- mzap = MS_PARALYSIS;
- break;
- case WAND_FIRE:
- mzap = MS_FIRE_BOLT;
- break;
- case WAND_COLD:
- mzap = MS_COLD_BOLT;
- break;
- case WAND_CONFUSION:
- mzap = MS_CONFUSE;
- break;
- case WAND_INVISIBILITY:
- mzap = MS_INVIS;
- break;
- case WAND_TELEPORTATION:
- mzap = MS_TELEPORT_OTHER;
- break;
- case WAND_LIGHTNING:
- mzap = MS_LIGHTNING_BOLT;
- break;
- case WAND_DRAINING:
- mzap = MS_NEGATIVE_BOLT;
- break;
- default:
- mzap = 0;
- break;
- }
-
- return (mzap);
-}
diff --git a/stone_soup/crawl-ref/source/monstuff.h b/stone_soup/crawl-ref/source/monstuff.h
deleted file mode 100644
index 296ee6b14e..0000000000
--- a/stone_soup/crawl-ref/source/monstuff.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * File: monstuff.cc
- * Summary: Misc monster related functions.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef MONSTUFF_H
-#define MONSTUFF_H
-
-
-// useful macro
-#define SAME_ATTITUDE(x) (mons_friendly(x)?BEH_FRIENDLY:BEH_HOSTILE)
-
-// for definition of type monsters {dlb}
-#include "externs.h"
-// for definition of type monsters {dlb}
-
-void get_mimic_item( const struct monsters *mimic, item_def & item );
-int get_mimic_colour( struct monsters *mimic );
-
-// last updated: 08jun2000 {dlb}
-/* ***********************************************************************
- * called from: fight - item_use - items - spell
- * *********************************************************************** */
-void alert_nearby_monsters(void);
-
-
-// last updated: 08jun2000 {dlb}
-/* ***********************************************************************
- * called from: beam - effects - monstuff
- * *********************************************************************** */
-bool monster_polymorph(struct monsters *monster, int targetc, int power);
-
-// last updated: 08jun2000 {dlb}
-/* ***********************************************************************
- * called from: bang - beam - effects - fight - misc - monstuff - mstuff2 -
- * spells1 - spells2 - spells3 - spells4
- * *********************************************************************** */
-void monster_die(struct monsters *monster, char killer, int i);
-
-// last updated: 17dec2000 {gdl}
-/* ***********************************************************************
- * called from: monstuff - fight
- * *********************************************************************** */
-void monster_cleanup(struct monsters *monster);
-
-
-/* ***********************************************************************
- * called from: monstuff beam effects fight view
- * *********************************************************************** */
-void behaviour_event( struct monsters *mon, int event_type,
- int src = MHITNOT, int src_x = 0, int src_y = 0 );
-
-/* ***********************************************************************
- * called from: fight - it_use3 - spells
- * *********************************************************************** */
-bool curse_an_item(char which, char power);
-
-
-/* ***********************************************************************
- * called from: fight
- * *********************************************************************** */
-void monster_blink(struct monsters *monster);
-
-
-/* ***********************************************************************
- * called from: spells1 spells4 monstuff
- * defaults are set up for player blink; monster blink should call with
- * false, false
- * *********************************************************************** */
-bool random_near_space( int ox, int oy, int &tx, int &ty,
- bool allow_adjacent = false, bool restrict_LOS = true);
-
-
-/* ***********************************************************************
- * called from: beam - effects - fight - monstuff - mstuff2 - spells1 -
- * spells2 - spells4
- * *********************************************************************** */
-bool simple_monster_message(struct monsters *monster, const char *event,
- int channel = MSGCH_PLAIN, int param = 0);
-
-
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-bool swap_places(struct monsters *monster);
-
-
-/* ***********************************************************************
- * called from: bang - beam - direct - fight - spells1 - spells2 - spells3
- * *********************************************************************** */
-void print_wounds(struct monsters *monster);
-
-
-/* ***********************************************************************
- * called from: fight
- * *********************************************************************** */
-bool wounded_damaged(int wound_class);
-
-
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void handle_monsters(void);
-
-
-/* ***********************************************************************
- * called from: acr - bang - beam - direct - dungeon - fight - files -
- * monplace - mstuff2 - spells3 - view
- * *********************************************************************** */
-unsigned char monster_habitat(int which_class);
-
-
-/* ***********************************************************************
- * called from: misc
- * *********************************************************************** */
-bool monster_descriptor(int which_class, unsigned char which_descriptor);
-
-
-/* ***********************************************************************
- * called from: direct - item_use - spells1
- * *********************************************************************** */
-bool message_current_target(void);
-
-
-/* ***********************************************************************
- * called from: xxx
- * *********************************************************************** */
-unsigned int monster_index(const monsters *monster);
-
-
-// last updated 08jun2000 {dlb}
-/* ***********************************************************************
- * called from: bang - beam - effects - fight - monstuff - mstuff2 -
- * spells2 - spells3 - spells4
- * *********************************************************************** */
-bool hurt_monster(struct monsters *victim, int damage_dealt);
-
-
-/* ***********************************************************************
- * called from: beam - fight - files - monstuff - spells1
- * *********************************************************************** */
-bool heal_monster(struct monsters *patient, int health_boost, bool permit_growth);
-
-
-#endif
diff --git a/stone_soup/crawl-ref/source/mstuff2.cc b/stone_soup/crawl-ref/source/mstuff2.cc
deleted file mode 100644
index d4460a0697..0000000000
--- a/stone_soup/crawl-ref/source/mstuff2.cc
+++ /dev/null
@@ -1,1768 +0,0 @@
-/*
- * File: mstuff2.cc
- * Summary: Misc monster related functions.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <5> 31 July 2000 JDJ Fixed mon_throw to use lnchType.
- * <4> 29 July 2000 JDJ Tweaked mons_throw so it doesn't index past
- * the end of the array when monsters don't have
- * a weapon equipped.
- * <3> 25 July 2000 GDL Fixed Manticores
- * <2> 28 July 2000 GDL Revised monster throwing
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "mstuff2.h"
-
-#include <string>
-#include <string.h>
-#include <stdio.h>
-
-#include "externs.h"
-
-#include "beam.h"
-#include "debug.h"
-#include "effects.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "items.h"
-#include "misc.h"
-#include "monplace.h"
-#include "monstuff.h"
-#include "mon-util.h"
-#include "player.h"
-#include "spells2.h"
-#include "spells4.h"
-#include "spl-cast.h"
-#include "stuff.h"
-#include "view.h"
-#include "wpn-misc.h"
-
-static unsigned char monster_abjuration(int pow, bool test);
-
-// XXX: must fix species abils to not use duration 15
-// -- ummm ... who wrote this? {dlb}
-
-// NB: only works because grid location already verified
-// to be some sort of trap prior to function call: {dlb}
-void mons_trap(struct monsters *monster)
-{
- if (!is_trap_square(monster->x, monster->y))
- return;
-
- int temp_rand = 0; // probability determination {dlb}
-
- // single calculation permissible {dlb}
- bool monsterNearby = mons_near(monster);
-
- // new function call {dlb}
- int which_trap = trap_at_xy(monster->x, monster->y);
- if (which_trap == -1)
- return;
-
- bool trapKnown = (grd[monster->x][monster->y] != DNGN_UNDISCOVERED_TRAP);
- bool revealTrap = false; // more sophisticated trap uncovering {dlb}
- bool projectileFired = false; // <sigh> I had to do it, I swear {dlb}
- int damage_taken = -1; // must initialize at -1 for this f(x) {dlb}
-
- struct bolt beem;
-
-
- // flying monsters neatly avoid mechanical traps
- // and may actually exit this function early: {dlb}
- if (mons_flies(monster))
- {
- if (trap_category(env.trap[which_trap].type) == DNGN_TRAP_MECHANICAL)
- {
- if (trapKnown)
- simple_monster_message(monster, " flies safely over a trap.");
-
- return; // early return {dlb}
- }
- }
-
- //
- // Trap damage to monsters is not a function of level, beacuse they
- // are fairly stupid and tend to have fewer hp than players -- this
- // choice prevents traps from easily killing large monsters fairly
- // deep within the dungeon.
- //
- switch (env.trap[which_trap].type)
- {
- case TRAP_DART:
- projectileFired = true;
- strcpy(beem.beam_name, " dart");
- beem.damage = dice_def( 1, 4 );
- beem.colour = OBJ_MISSILES;
- beem.type = MI_DART;
- break;
- case TRAP_NEEDLE:
- projectileFired = true;
- strcpy(beem.beam_name, " needle");
- beem.damage = dice_def( 1, 0 );
- beem.colour = OBJ_MISSILES;
- beem.type = MI_NEEDLE;
- break;
- case TRAP_ARROW:
- projectileFired = true;
- strcpy(beem.beam_name, "n arrow");
- beem.damage = dice_def( 1, 7 );
- beem.colour = OBJ_MISSILES;
- beem.type = MI_ARROW;
- break;
- case TRAP_SPEAR:
- projectileFired = true;
- strcpy(beem.beam_name, " spear");
- beem.damage = dice_def( 1, 10 );
- beem.colour = OBJ_WEAPONS;
- beem.type = WPN_SPEAR;
- break;
- case TRAP_BOLT:
- projectileFired = true;
- strcpy(beem.beam_name, " bolt");
- beem.damage = dice_def( 1, 13 );
- beem.colour = OBJ_MISSILES;
- beem.type = MI_BOLT;
- break;
- case TRAP_AXE:
- projectileFired = true;
- strcpy(beem.beam_name, "n axe");
- beem.damage = dice_def( 1, 15 );
- beem.colour = OBJ_WEAPONS;
- beem.type = WPN_HAND_AXE;
- break;
- // teleport traps are *never* revealed through
- // the triggering action of a monster, as any
- // number of factors could have been in play: {dlb}
- case TRAP_TELEPORT:
- monster_teleport(monster, true);
- break;
- // amnesia traps do not affect monsters (yet) and
- // only monsters of normal+ IQ will direct a msg
- // to the player - also, *never* revealed: {dlb}
- case TRAP_AMNESIA:
- if (mons_intel(monster->type) > I_ANIMAL)
- simple_monster_message(monster,
- " seems momentarily disoriented.");
- break;
- // blade traps sometimes fail to trigger altogether,
- // resulting in an "early return" from this f(x) for
- // some - otherwise, blade *always* revealed: {dlb}
- case TRAP_BLADE:
- if (one_chance_in(5))
- {
- if (trapKnown)
- {
- simple_monster_message(monster,
- " fails to trigger a blade trap.");
- }
- return; // early return {dlb}
- }
- else if (random2(monster->evasion) > 8)
- {
- if (monsterNearby && !simple_monster_message(monster,
- " avoids a huge, swinging blade."))
- {
- mpr("A huge blade swings out!");
- }
-
- damage_taken = -1; // just to be certain {dlb}
- }
- else
- {
- if (monsterNearby)
- {
- strcpy(info, "A huge blade swings out");
-
- if (player_monster_visible( monster ))
- {
- strcat(info, " and slices into ");
- strcat(info, ptr_monam( monster, DESC_NOCAP_THE ));
- }
-
- strcat(info, "!");
- mpr(info);
- }
-
- damage_taken = 10 + random2avg(29, 2);
- damage_taken -= random2(1 + monster->armour_class);
-
- if (damage_taken < 0)
- damage_taken = 0;
- }
-
- revealTrap = true;
- break;
-
- // zot traps are out to get *the player*! Hostile monsters
- // benefit and friendly monsters suffer - such is life - on
- // rare occasion, the trap affects nearby players, triggering
- // an "early return" - zot traps are *never* revealed - instead,
- // enchantment messages serve as clues to the trap's presence: {dlb}
- case TRAP_ZOT:
- if (monsterNearby)
- {
- if (one_chance_in(5))
- {
- mpr("The power of Zot is invoked against you!");
- miscast_effect( SPTYP_RANDOM, 10 + random2(30),
- 75 + random2(100), 0, "the power of Zot" );
- return; // early return {dlb}
- }
- }
-
- // output triggering message to player, where appropriate: {dlb}
- if (!silenced(monster->x, monster->y)
- && !silenced(you.x_pos, you.y_pos))
- {
- if (monsterNearby)
- strcpy(info, "You hear a loud \"Zot\"!");
- else
- strcpy(info, "You hear a distant \"Zot\"!");
- mpr(info);
- }
-
- // determine trap effects upon monster, based upon
- // whether it is naughty or nice to the player: {dlb}
-
- // NB: beem[].colour values are mislabeled as colours (?) -
- // cf. mons_ench_f2() [which are also mislabeled] {dlb}
- temp_rand = random2(16);
-
- beem.thrower = KILL_MON; // probably unnecessary
- beem.aux_source = NULL;
-
- if (mons_friendly(monster))
- {
- beem.colour = ((temp_rand < 3) ? CYAN : //paralyze - 3 in 16
- (temp_rand < 7) ? RED // confuse - 4 in 16
- : BLACK); // slow - 9 in 16
- }
- else
- {
- beem.colour = ((temp_rand < 3) ? BLUE : //haste - 3 in 16 {dlb}
- (temp_rand < 7) ? MAGENTA //invis - 4 in 16 {dlb}
- : GREEN); // heal - 9 in 16 {dlb}
- }
-
- mons_ench_f2(monster, beem);
- damage_taken = 0; // just to be certain {dlb}
- break;
- }
-
-
- // go back and handle projectile traps: {dlb}
- bool apply_poison = false;
-
- if (projectileFired)
- {
- // projectile traps *always* revealed after "firing": {dlb}
- revealTrap = true;
-
- // determine whether projectile hits, calculate damage: {dlb}
- if (((20 + (you.your_level * 2)) * random2(200)) / 100
- >= monster->evasion)
- {
- damage_taken = roll_dice( beem.damage );
- damage_taken -= random2(1 + monster->armour_class);
-
- if (damage_taken < 0)
- damage_taken = 0;
-
- if (beem.colour == OBJ_MISSILES
- && beem.type == MI_NEEDLE
- && random2(100) < 50 - (3*monster->armour_class/2))
- {
- apply_poison = true;
- }
- }
- else
- {
- damage_taken = -1; // negative damage marks a miss
- }
-
- if (monsterNearby)
- {
- snprintf( info, INFO_SIZE, "A%s %s %s%s!",
- beem.beam_name,
- (damage_taken >= 0) ? "hits" : "misses",
- ptr_monam( monster, DESC_NOCAP_THE ),
- (damage_taken == 0) ? ", but does no damage" : "" );
-
- mpr(info);
- }
-
- if (apply_poison)
- poison_monster( monster, false );
-
- // generate "fallen" projectile, where appropriate: {dlb}
- if (random2(10) < 7)
- {
- beem.target_x = monster->x;
- beem.target_y = monster->y;
- itrap(beem, which_trap);
- }
- }
-
-
- // reveal undiscovered traps, where appropriate: {dlb}
- if (monsterNearby && !trapKnown && revealTrap)
- {
- grd[monster->x][monster->y] = trap_category(env.trap[which_trap].type);
- }
-
- // apply damage and handle death, where appropriate: {dlb}
- if (damage_taken > 0)
- {
- hurt_monster(monster, damage_taken);
-
- if (monster->hit_points < 1)
- {
- monster_die(monster, KILL_MISC, 0);
- monster->speed_increment = 1;
- }
- }
-
- return;
-} // end mons_trap()
-
-void mons_cast(struct monsters *monster, struct bolt &pbolt, int spell_cast)
-{
- // always do setup. It might be done already, but it doesn't
- // hurt to do it again (cheap).
- setup_mons_cast(monster, pbolt, spell_cast);
-
- // single calculation permissible {dlb}
- bool monsterNearby = mons_near(monster);
-
- int sumcount = 0;
- int sumcount2;
- int summonik = 0;
- int duration = 0;
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "Mon #%d casts %s (#%d)", monster_index(monster),
- mons_spell_name( spell_cast ), spell_cast );
-
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- if (spell_cast == MS_HELLFIRE_BURST || spell_cast == MS_BRAIN_FEED
- || spell_cast == MS_SMITE || spell_cast == MS_MUTATION)
- { // etc.
- if (monster->foe == MHITYOU || monster->foe == MHITNOT)
- {
- if (monsterNearby)
- direct_effect( pbolt );
- return;
- }
-
- mons_direct_effect( pbolt, monster_index(monster) );
- return;
- }
-
- switch (spell_cast)
- {
- case MS_VAMPIRE_SUMMON:
- sumcount2 = 3 + random2(3) + monster->hit_dice / 5;
-
- for (sumcount = 0; sumcount < sumcount2; sumcount++)
- {
- int mons = MONS_GIANT_BAT;
-
- if (!one_chance_in(3))
- {
- switch (random2(4))
- {
- case 0:
- mons = MONS_ORANGE_RAT;
- break;
-
- case 1:
- mons = MONS_GREEN_RAT;
- break;
-
- case 2:
- mons = MONS_GREY_RAT;
- break;
-
- case 3:
- default:
- mons = MONS_RAT;
- break;
- }
- }
-
- create_monster( mons, ENCH_ABJ_V, SAME_ATTITUDE(monster),
- monster->x, monster->y, monster->foe, 250 );
- }
- return;
-
- case MS_LEVEL_SUMMON: // summon anything appropriate for level
- if (!mons_friendly(monster) && monsterNearby
- && monster_abjuration(1, true) > 0 && coinflip())
- {
- monster_abjuration( monster->hit_dice * 10, false );
- return;
- }
-
- sumcount2 = 1 + random2(4) + random2( monster->hit_dice / 7 + 1 );
-
- for (sumcount = 0; sumcount < sumcount2; sumcount++)
- {
- create_monster( RANDOM_MONSTER, ENCH_ABJ_V, SAME_ATTITUDE(monster),
- monster->x, monster->y, monster->foe, 250 );
- }
- return;
-
- case MS_FAKE_RAKSHASA_SUMMON:
- sumcount2 = (coinflip() ? 2 : 3);
-
- for (sumcount = 0; sumcount < sumcount2; sumcount++)
- {
- create_monster( MONS_RAKSHASA_FAKE, ENCH_ABJ_III,
- SAME_ATTITUDE(monster), monster->x, monster->y,
- monster->foe, 250 );
- }
- return;
-
- case MS_SUMMON_DEMON: // class 2-4 demons
- if (!mons_friendly(monster) && monsterNearby
- && monster_abjuration(1, true) > 0 && coinflip())
- {
- monster_abjuration(monster->hit_dice * 10, false);
- return;
- }
-
- sumcount2 = 1 + random2(2) + random2( monster->hit_dice / 10 + 1 );
-
- duration = ENCH_ABJ_II + monster->hit_dice / 10;
- if (duration > ENCH_ABJ_VI)
- duration = ENCH_ABJ_VI;
-
- for (sumcount = 0; sumcount < sumcount2; sumcount++)
- {
- create_monster( summon_any_demon(DEMON_COMMON), duration,
- SAME_ATTITUDE(monster), monster->x, monster->y,
- monster->foe, 250 );
- }
- return;
-
- case MS_ANIMATE_DEAD:
- // see special handling in monstuff::handle_spell {dlb}
- animate_dead( 5 + random2(5), SAME_ATTITUDE(monster), monster->foe, 1 );
- return;
-
- case MS_SUMMON_DEMON_LESSER: // class 5 demons
- sumcount2 = 1 + random2(3) + random2( monster->hit_dice / 5 + 1 );
-
- duration = ENCH_ABJ_II + monster->hit_dice / 5;
- if (duration > ENCH_ABJ_VI)
- duration = ENCH_ABJ_VI;
-
- for (sumcount = 0; sumcount < sumcount2; sumcount++)
- {
- create_monster( summon_any_demon(DEMON_LESSER), duration,
- SAME_ATTITUDE(monster), monster->x, monster->y,
- monster->foe, 250 );
- }
- return;
-
- case MS_SUMMON_UFETUBUS:
- sumcount2 = 2 + random2(2) + random2( monster->hit_dice / 5 + 1 );
-
- duration = ENCH_ABJ_II + monster->hit_dice / 5;
- if (duration > ENCH_ABJ_VI)
- duration = ENCH_ABJ_VI;
-
- for (sumcount = 0; sumcount < sumcount2; sumcount++)
- {
- create_monster( MONS_UFETUBUS, duration, SAME_ATTITUDE(monster),
- monster->x, monster->y, monster->foe, 250 );
- }
- return;
-
- case MS_SUMMON_BEAST: // Geryon
- create_monster( MONS_BEAST, ENCH_ABJ_IV, SAME_ATTITUDE(monster),
- monster->x, monster->y, monster->foe, 250 );
- return;
-
- case MS_SUMMON_UNDEAD: // summon undead around player
- if (!mons_friendly(monster) && monsterNearby
- && monster_abjuration(1, true) > 0 && coinflip())
- {
- monster_abjuration( monster->hit_dice * 10, false );
- return;
- }
-
- sumcount2 = 2 + random2(2) + random2( monster->hit_dice / 4 + 1 );
-
- duration = ENCH_ABJ_II + monster->hit_dice / 5;
- if (duration > ENCH_ABJ_VI)
- duration = ENCH_ABJ_VI;
-
- for (sumcount = 0; sumcount < sumcount2; sumcount++)
- {
- do
- {
- summonik = random2(241); // hmmmm ... {dlb}
- }
- while (mons_class_holiness(summonik) != MH_UNDEAD);
-
- create_monster(summonik, duration, SAME_ATTITUDE(monster),
- you.x_pos, you.y_pos, monster->foe, 250);
- }
- return;
-
- case MS_TORMENT:
- if (!monsterNearby || mons_friendly(monster))
- return;
-
- simple_monster_message(monster, " calls on the powers of Hell!");
-
- torment(monster->x, monster->y);
- return;
-
- case MS_SUMMON_DEMON_GREATER:
- if (!mons_friendly(monster) && !monsterNearby &&
- monster_abjuration(1, true) > 0 && coinflip())
- {
- monster_abjuration(monster->hit_dice * 10, false);
- return;
- }
-
- sumcount2 = 1 + random2( monster->hit_dice / 10 + 1 );
-
- duration = ENCH_ABJ_II + monster->hit_dice / 10;
- if (duration > ENCH_ABJ_VI)
- duration = ENCH_ABJ_VI;
-
- for (sumcount = 0; sumcount < sumcount2; sumcount++)
- {
- create_monster( summon_any_demon(DEMON_GREATER), duration,
- SAME_ATTITUDE(monster), monster->x, monster->y,
- monster->foe, 250 );
- }
- return;
-
- // Journey -- Added in Summon Lizards and Draconian
- case MS_SUMMON_LIZARDS:
- if (!mons_friendly( monster ) && !monsterNearby &&
- monster_abjuration( 1, true ) > 0 && coinflip())
- {
- monster_abjuration( monster->hit_dice * 10, false );
- return;
- }
-
- sumcount2 = 1 + random2(3) + random2( monster->hit_dice / 5 + 1 );
-
- duration = ENCH_ABJ_II + monster->hit_dice / 10;
- if (duration > ENCH_ABJ_VI)
- duration = ENCH_ABJ_VI;
-
- for (sumcount = 0; sumcount < sumcount2; sumcount++)
- {
- create_monster( rand_dragon( DRAGON_LIZARD ), duration,
- SAME_ATTITUDE(monster),
- monster->x, monster->y, monster->foe, 250 );
- }
- break;
-
- case MS_CANTRIP:
- // Monster spell of uselessness, just prints a message.
- // This spell exists so that some monsters with really strong
- // spells (ie orc priest) can be toned down a bit. -- bwr
- //
- // XXX: Needs expansion, and perhaps different priest/mage flavours.
- switch (random2(7))
- {
- case 0:
- simple_monster_message( monster, " glows brightly for a moment.",
- MSGCH_MONSTER_ENCHANT );
- break;
- case 1:
- mpr( "You feel troubled." );
- break;
- case 2:
- mpr( "You feel a wave of unholy energy pass over you." );
- break;
- case 3:
- simple_monster_message( monster, " looks stronger.",
- MSGCH_MONSTER_ENCHANT );
- break;
- case 4:
- simple_monster_message( monster, " becomes somewhat translucent.",
- MSGCH_MONSTER_ENCHANT );
- break;
- case 5:
- simple_monster_message( monster, "'s eyes start to glow.",
- MSGCH_MONSTER_ENCHANT );
- break;
- case 6:
- default:
- if (one_chance_in(20))
- mpr( "You resist (whatever that was supposed to do)." );
- else
- mpr( "You resist." );
- break;
- }
- return;
- }
-
- fire_beam( pbolt );
-} // end mons_cast()
-
-
-/*
- * setup bolt structure for monster spell casting.
- *
- */
-
-void setup_mons_cast(struct monsters *monster, struct bolt &pbolt, int spell_cast)
-{
- // always set these -- used by things other than fire_beam()
- pbolt.ench_power = 12 * monster->hit_dice;
-
- if (spell_cast == MS_TELEPORT)
- pbolt.ench_power = 2000;
- else if (spell_cast == MS_PAIN) // this is cast by low HD monsters
- pbolt.ench_power *= 2;
-
- pbolt.beam_source = monster_index(monster);
-
- // set bolt type
- if (spell_cast == MS_HELLFIRE_BURST
- || spell_cast == MS_BRAIN_FEED
- || spell_cast == MS_SMITE || spell_cast == MS_MUTATION)
- { // etc.
- switch (spell_cast)
- {
- case MS_HELLFIRE_BURST:
- pbolt.type = DMNBM_HELLFIRE;
- break;
- case MS_BRAIN_FEED:
- pbolt.type = DMNBM_BRAIN_FEED;
- break;
- case MS_SMITE:
- pbolt.type = DMNBM_SMITING;
- break;
- case MS_MUTATION:
- pbolt.type = DMNBM_MUTATION;
- break;
- }
- return;
- }
-
- // the below are no-ops since they don't involve direct_effect,
- // fire_tracer, or beam.
- switch (spell_cast)
- {
- case MS_VAMPIRE_SUMMON:
- case MS_LEVEL_SUMMON: // summon anything appropriate for level
- case MS_FAKE_RAKSHASA_SUMMON:
- case MS_SUMMON_DEMON:
- case MS_ANIMATE_DEAD:
- case MS_SUMMON_DEMON_LESSER:
- case MS_SUMMON_UFETUBUS:
- case MS_SUMMON_BEAST: // Geryon
- case MS_SUMMON_UNDEAD: // summon undead around player
- case MS_SUMMON_LIZARDS:
- case MS_TORMENT:
- case MS_SUMMON_DEMON_GREATER:
- case MS_CANTRIP:
- return;
- default:
- break;
- }
-
- // Need to correct this for power of spellcaster
- int power = 12 * monster->hit_dice;
-
- struct bolt theBeam = mons_spells(spell_cast, power);
-
- pbolt.colour = theBeam.colour;
- pbolt.range = theBeam.range;
- pbolt.rangeMax = theBeam.rangeMax;
- pbolt.hit = theBeam.hit;
- pbolt.damage = theBeam.damage;
- pbolt.ench_power = theBeam.ench_power;
- pbolt.type = theBeam.type;
- pbolt.flavour = theBeam.flavour;
- pbolt.thrower = theBeam.thrower;
- pbolt.aux_source = NULL;
- strcpy( pbolt.beam_name, theBeam.beam_name );
- pbolt.is_beam = theBeam.is_beam;
- pbolt.source_x = monster->x;
- pbolt.source_y = monster->y;
- pbolt.is_tracer = false;
-
- if (pbolt.beam_name[0] && pbolt.beam_name[0] != '0')
- pbolt.aux_source = pbolt.beam_name;
- else
- pbolt.aux_source = NULL;
-
- if (spell_cast == MS_HASTE
- || spell_cast == MS_INVIS
- || spell_cast == MS_HEAL || spell_cast == MS_TELEPORT)
- {
- pbolt.target_x = monster->x;
- pbolt.target_y = monster->y;
- }
-} // end setup_mons_cast()
-
-
-void monster_teleport(struct monsters *monster, bool instan)
-{
- if (!instan)
- {
- if (mons_del_ench(monster, ENCH_TP_I, ENCH_TP_IV))
- {
- simple_monster_message(monster, " seems more stable.");
- }
- else
- mons_add_ench(monster, (coinflip() ? ENCH_TP_III : ENCH_TP_IV ));
-
- return;
- }
-
- simple_monster_message(monster, " disappears!");
-
- // pick the monster up
- mgrd[monster->x][monster->y] = NON_MONSTER;
-
- char ogrid = monster_habitat(monster->type);
-
- int newx, newy;
- while(true)
- {
- newx = 10 + random2(GXM - 20);
- newy = 10 + random2(GYM - 20);
-
- // don't land on top of another monster
- if (mgrd[newx][newy] != NON_MONSTER)
- continue;
-
- // monsters going to the same habitat
- if (ogrid == grd[newx][newy])
- break;
-
- // DEEP_WATER monsters can be teleported to SHALLOW_WATER
- if (ogrid == DNGN_DEEP_WATER && grd[newx][newy] == DNGN_SHALLOW_WATER)
- break;
- }
-
- monster->x = newx;
- monster->y = newy;
-
- mgrd[monster->x][monster->y] = monster_index(monster);
-
- /* Mimics change form/colour when t'ported */
- if (mons_is_mimic( monster->type ))
- {
- monster->type = MONS_GOLD_MIMIC + random2(5);
- monster->number = get_mimic_colour( monster );
- }
-} // end monster_teleport()
-
-void setup_dragon(struct monsters *monster, struct bolt &pbolt)
-{
- const int type = (mons_genus( monster->type ) == MONS_DRACONIAN)
- ? draco_subspecies( monster ) : monster->type;
- int scaling = 100;
-
- strcpy(pbolt.beam_name, ptr_monam( monster, DESC_PLAIN ));
-
- switch (type)
- {
- case MONS_FIREDRAKE:
- case MONS_HELL_HOUND:
- case MONS_DRAGON:
- case MONS_LINDWURM:
- case MONS_XTAHUA:
- strcat(pbolt.beam_name, "'s blast of flame");
- pbolt.flavour = BEAM_FIRE;
- pbolt.colour = RED;
- pbolt.aux_source = "blast of fiery breath";
- break;
-
- case MONS_ICE_DRAGON:
- strcat(pbolt.beam_name, "'s blast of cold");
- pbolt.flavour = BEAM_COLD;
- pbolt.colour = WHITE;
- pbolt.aux_source = "blast of icy breath";
- break;
-
- case MONS_RED_DRACONIAN:
- snprintf( pbolt.beam_name, ITEMNAME_SIZE, "%s's searing breath",
- ptr_monam( monster, DESC_PLAIN ) );
-#ifdef DEBUG_DIAGNOSTICS
- mprf( MSGCH_DIAGNOSTICS, "bolt name: '%s'", pbolt.beam_name );
-#endif
- pbolt.flavour = BEAM_FIRE;
- pbolt.colour = RED;
- pbolt.aux_source = "blast of searing breath";
- scaling = 65;
- break;
-
- case MONS_WHITE_DRACONIAN:
- snprintf( pbolt.beam_name, ITEMNAME_SIZE, "%s's chilling breath",
- ptr_monam( monster, DESC_PLAIN ) );
-#ifdef DEBUG_DIAGNOSTICS
- mprf( MSGCH_DIAGNOSTICS, "bolt name: '%s'", pbolt.beam_name );
-#endif
- pbolt.flavour = BEAM_COLD;
- pbolt.colour = WHITE;
- pbolt.aux_source = "blast of chilling breath";
- scaling = 65;
- break;
-
- default:
- DEBUGSTR("Bad monster class in setup_dragon()");
- break;
- }
-
- pbolt.range = 4;
- pbolt.rangeMax = 13;
- pbolt.damage = dice_def( 3, (monster->hit_dice * 2) );
- pbolt.damage.size = scaling * pbolt.damage.size / 100;
- pbolt.type = SYM_ZAP;
- pbolt.hit = 30;
- pbolt.beam_source = monster_index(monster);
- pbolt.thrower = KILL_MON;
- pbolt.is_beam = true;
-} // end setup_dragon();
-
-void setup_generic_throw(struct monsters *monster, struct bolt &pbolt)
-{
- pbolt.range = 9;
- pbolt.rangeMax = 9;
- pbolt.beam_source = monster_index(monster);
-
- pbolt.type = SYM_MISSILE;
- pbolt.flavour = BEAM_MISSILE;
- pbolt.thrower = KILL_MON_MISSILE;
- pbolt.aux_source = NULL;
- pbolt.is_beam = false;
-}
-
-// decide if something is launched or thrown
-// pass -1 for launcher class & 0 for type if no weapon is weilded
-
-void throw_type( int lnchClass, int lnchType, int wepClass, int wepType,
- bool &launched, bool &thrown )
-{
- if (wepClass == OBJ_MISSILES
- && lnchClass == OBJ_WEAPONS
- && launches_things(lnchType) && wepType == launched_by(lnchType))
- {
- launched = true;
- }
-
- if (wepClass == OBJ_WEAPONS)
- {
- if (wepType == WPN_DAGGER || wepType == WPN_HAND_AXE || wepType == WPN_SPEAR)
- {
- thrown = true;
- }
- }
-
- if (wepClass == OBJ_MISSILES)
- {
- if (wepType == MI_DART || wepType == MI_STONE || wepType == MI_LARGE_ROCK)
- {
- thrown = true;
- }
- }
-
- // launched overrides thrown
- if (launched == true)
- thrown = false;
-}
-
-bool mons_throw(struct monsters *monster, struct bolt &pbolt, int hand_used)
-{
- // this was assumed during cleanup down below:
- ASSERT( hand_used == monster->inv[MSLOT_MISSILE] );
-
- // XXX: ugly hack, but avoids adding dynamic allocation to this code
- static char throw_buff[ ITEMNAME_SIZE ];
-
- int baseHit = 0, baseDam = 0; // from thrown or ammo
- int ammoHitBonus = 0, ammoDamBonus = 0; // from thrown or ammo
- int lnchHitBonus = 0, lnchDamBonus = 0; // special add from launcher
- int exHitBonus = 0, exDamBonus = 0; // 'extra' bonus from skill/dex/str
-
- int hitMult = 0;
- int damMult = 0;
-
- bool launched = false; // item is launched
- bool thrown = false; // item is sensible thrown item
-
- // some initial convenience & initializations
- int wepClass = mitm[hand_used].base_type;
- int wepType = mitm[hand_used].sub_type;
-
- int weapon = monster->inv[MSLOT_WEAPON];
-
- int lnchClass = (weapon != NON_ITEM) ? mitm[weapon].base_type : -1;
- int lnchType = (weapon != NON_ITEM) ? mitm[weapon].sub_type : 0;
-
- item_def item = mitm[hand_used]; // copy changed for venom launchers
- item.quantity = 1;
-
- pbolt.range = 9;
- pbolt.beam_source = monster_index(monster);
-
- pbolt.type = SYM_MISSILE;
- pbolt.colour = item.colour;
- pbolt.flavour = BEAM_MISSILE;
- pbolt.thrower = KILL_MON_MISSILE;
- pbolt.aux_source = NULL;
-
- // figure out if we're thrown or launched
- throw_type( lnchClass, lnchType, wepClass, wepType, launched, thrown );
-
- // extract launcher bonuses due to magic
- if (launched)
- {
- lnchHitBonus = mitm[ weapon ].plus;
- lnchDamBonus = mitm[ weapon ].plus2;
- }
-
- // extract weapon/ammo bonuses due to magic
- ammoHitBonus = item.plus;
- ammoDamBonus = item.plus2;
-
- if (thrown)
- {
- // Darts are easy.
- if (wepClass == OBJ_MISSILES && wepType == MI_DART)
- {
- baseHit = 5;
- hitMult = 40;
- damMult = 25;
- }
- else
- {
- baseHit = 0;
- hitMult = 30;
- damMult = 25;
- }
-
- baseDam = property( item, PWPN_DAMAGE );
-
- if (wepClass == OBJ_MISSILES) // throw missile
- // ammo damage needs adjusting here - OBJ_MISSILES
- // don't get separate tohit/damage bonuses!
- ammoDamBonus = ammoHitBonus;
-
- // give monster "skill" bonuses based on HD
- exHitBonus = (hitMult * monster->hit_dice) / 10 + 1;
- exDamBonus = (damMult * monster->hit_dice) / 10 + 1;
- }
-
- if (launched)
- {
- switch (lnchType)
- {
- case WPN_BLOWGUN:
- baseHit = 2;
- hitMult = 60;
- damMult = 0;
- lnchDamBonus = 0;
- break;
- case WPN_BOW:
- case WPN_LONGBOW:
- baseHit = 0;
- hitMult = 60;
- damMult = 35;
- // monsters get half the launcher damage bonus,
- // which is about as fair as I can figure it.
- lnchDamBonus = (lnchDamBonus + 1) / 2;
- break;
- case WPN_CROSSBOW:
- baseHit = 4;
- hitMult = 70;
- damMult = 30;
- break;
- case WPN_HAND_CROSSBOW:
- baseHit = 2;
- hitMult = 50;
- damMult = 20;
- break;
- case WPN_SLING:
- baseHit = 1;
- hitMult = 40;
- damMult = 20;
- // monsters get half the launcher damage bonus,
- // which is about as fair as I can figure it.
- lnchDamBonus /= 2;
- break;
- }
-
- baseDam = property( item, PWPN_DAMAGE );
-
- // missiles don't have pluses2; use hit bonus
- ammoDamBonus = ammoHitBonus;
-
- exHitBonus = (hitMult * monster->hit_dice) / 10 + 1;
- exDamBonus = (damMult * monster->hit_dice) / 10 + 1;
-
- // elven bow w/ elven arrow, also orcish
- if (get_equip_race( mitm[monster->inv[MSLOT_WEAPON]] )
- == get_equip_race( mitm[monster->inv[MSLOT_MISSILE]] ))
- {
- baseHit++;
- baseDam++;
-
- if (get_equip_race(mitm[monster->inv[MSLOT_WEAPON]]) == ISFLAG_ELVEN)
- pbolt.hit++;
- }
-
- // monsters no longer gain unfair advantages with weapons of fire/ice
- // and incorrect ammo. They now have same restriction as players.
-
- const int bow_brand = get_weapon_brand(mitm[monster->inv[MSLOT_WEAPON]]);
-
- const int ammo_brand = get_ammo_brand( item );
-
- bool poison = (ammo_brand == SPMSL_POISONED
- || ammo_brand == SPMSL_POISONED_II);
-
- // POISON brand launchers poison ammo
- if (bow_brand == SPWPN_VENOM && ammo_brand == SPMSL_NORMAL)
- set_item_ego_type( item, OBJ_MISSILES, SPMSL_POISONED );
-
-
- // WEAPON or AMMO of FIRE
- if ((bow_brand == SPWPN_FLAME || ammo_brand == SPMSL_FLAME)
- && bow_brand != SPWPN_FROST && ammo_brand != SPMSL_ICE)
- {
- baseHit += 2;
- exDamBonus += 6;
- pbolt.flavour = BEAM_FIRE;
- strcpy(pbolt.beam_name, "bolt of ");
-
- if (poison)
- strcat(pbolt.beam_name, "poison ");
-
- strcat(pbolt.beam_name, "flame");
- pbolt.colour = RED;
- pbolt.type = SYM_ZAP;
- }
-
- // WEAPON or AMMO of FROST
- if ((bow_brand == SPWPN_FROST || ammo_brand == SPMSL_ICE)
- && bow_brand != SPWPN_FLAME && ammo_brand != SPMSL_FLAME)
- {
- baseHit += 2;
- exDamBonus += 6;
- pbolt.flavour = BEAM_COLD;
- strcpy(pbolt.beam_name, "bolt of ");
-
- if (poison)
- strcat(pbolt.beam_name, "poison ");
-
- strcat(pbolt.beam_name, "frost");
- pbolt.colour = WHITE;
- pbolt.type = SYM_ZAP;
- }
-
- // Note: we already have 10 energy taken off. -- bwr
- if (lnchType == WPN_CROSSBOW)
- monster->speed_increment += ((bow_brand == SPWPN_SPEED) ? 4 : -2);
- else if (bow_brand == SPWPN_SPEED)
- monster->speed_increment += 5;
- }
-
- // monster intelligence bonus
- if (mons_intel(monster->type) == I_HIGH)
- exHitBonus += 10;
-
- // now, if a monster is, for some reason, throwing something really
- // stupid, it will have baseHit of 0 and damage of 0. Ah well.
- strcpy(info, ptr_monam( monster, DESC_CAP_THE) );
-
- strcat(info, (launched) ? " shoots " : " throws ");
-
- if (strlen(pbolt.beam_name) > 0)
- {
- strcat(info, "a ");
- strcat(info, pbolt.beam_name);
- }
- else
- {
- // build shoot message
- char str_pass[ ITEMNAME_SIZE ];
- item_name( item, DESC_NOCAP_A, str_pass );
- strcat(info, str_pass);
-
- // build beam name
- item_name( item, DESC_PLAIN, str_pass );
- strcpy(pbolt.beam_name, str_pass);
- }
-
- strcat(info, ".");
- mpr(info);
-
-
- if (launched)
- {
- snprintf( throw_buff, sizeof(throw_buff), "Shot with a%s %s by %s",
- (is_vowel(pbolt.beam_name[0]) ? "n" : ""), pbolt.beam_name,
- ptr_monam( monster, DESC_NOCAP_A ) );
- }
- else
- {
- snprintf( throw_buff, sizeof(throw_buff), "Hit by a%s %s thrown by %s",
- (is_vowel(pbolt.beam_name[0]) ? "n" : ""), pbolt.beam_name,
- ptr_monam( monster, DESC_NOCAP_A ) );
- }
-
- pbolt.aux_source = throw_buff;
-
- // add everything up.
- pbolt.hit = baseHit + random2avg(exHitBonus, 2) + ammoHitBonus;
- pbolt.damage = dice_def( 1, baseDam + random2avg(exDamBonus, 2) + ammoDamBonus );
-
- if (launched)
- {
- pbolt.damage.size += lnchDamBonus;
- pbolt.hit += lnchHitBonus;
- }
- scale_dice(pbolt.damage);
-
- // decrease inventory
- fire_beam( pbolt, &item );
-
- if (dec_mitm_item_quantity( hand_used, 1 ))
- monster->inv[MSLOT_MISSILE] = NON_ITEM;
-
-
- return (true);
-} // end mons_throw()
-
-// should really do something about mons_hit, but can't be bothered
-void spore_goes_pop(struct monsters *monster)
-{
- struct bolt beam;
- int type = monster->type;
-
- if (monster == NULL)
- return;
-
- beam.is_tracer = false;
- beam.is_explosion = true;
- beam.beam_source = monster_index(monster);
- beam.type = SYM_BURST;
- beam.target_x = monster->x;
- beam.target_y = monster->y;
- beam.thrower = KILL_MON; // someone else's explosion
- beam.aux_source = NULL;
-
- if (type == MONS_GIANT_SPORE)
- {
- beam.flavour = BEAM_SPORE;
- strcpy(beam.beam_name, "explosion of spores");
- beam.colour = LIGHTGREY;
- beam.damage = dice_def( 3, 15 );
- beam.ex_size = 2;
- strcpy( info, "The giant spore explodes!" );
- }
- else
- {
- beam.flavour = BEAM_ELECTRICITY;
- strcpy(beam.beam_name, "blast of lightning");
- beam.colour = LIGHTCYAN;
- beam.damage = dice_def( 3, 20 );
- beam.ex_size = coinflip() ? 3 : 2;
- strcpy( info, "The ball lightning explodes!" );
- }
-
- if (mons_near(monster))
- {
- viewwindow(1, false);
- mpr( info );
- }
-
- explosion(beam);
-} // end spore_goes_pop()
-
-bolt mons_spells( int spell_cast, int power )
-{
- ASSERT(power > 0);
-
- bolt beam;
-
- strcpy(beam.beam_name, "****"); // initialize to some bogus values so we can catch problems
- beam.colour = 1000;
- beam.range = beam.rangeMax = 8;
- beam.hit = -1;
- beam.damage = dice_def( 1, 0 );
- beam.ench_power = -1;
- beam.type = -1;
- beam.flavour = -1;
- beam.thrower = -1;
- beam.is_beam = false;
- beam.is_explosion = false;
-
- switch (spell_cast)
- {
- case MS_MMISSILE:
- beam.colour = LIGHTMAGENTA; //inv_colour [throw_2];
- strcpy(beam.beam_name, "magic dart"); // inv_name [throw_2]);
- beam.range = 6;
- beam.rangeMax = 10;
- beam.damage = dice_def( 3, 4 + (power / 100) );
- beam.hit = 1500;
- beam.type = SYM_ZAP;
- beam.thrower = KILL_MON_MISSILE;
- beam.flavour = BEAM_MMISSILE;
- beam.is_beam = false;
- break;
-
- case MS_FLAME:
- beam.colour = RED;
- strcpy(beam.beam_name, "puff of flame");
- beam.range = 6;
- beam.rangeMax = 10;
-
- // should this be the same as magic missile?
- // No... magic missile is special in that it has a really
- // high to-hit value, so these should do more damage -- bwr
- beam.damage = dice_def( 3, 5 + (power / 40) );
-
- beam.hit = 60;
- beam.type = SYM_ZAP;
- beam.thrower = KILL_MON_MISSILE;
- beam.flavour = BEAM_FIRE;
- beam.is_beam = false;
- break;
-
- case MS_FROST:
- beam.colour = WHITE;
- strcpy(beam.beam_name, "puff of frost");
- beam.range = 6;
- beam.rangeMax = 10;
-
- // should this be the same as magic missile?
- // see MS_FLAME -- bwr
- beam.damage = dice_def( 3, 5 + (power / 40) );
-
- beam.hit = 60;
- beam.type = SYM_ZAP;
- beam.thrower = KILL_MON_MISSILE;
- beam.flavour = BEAM_COLD;
- beam.is_beam = false;
- break;
-
- case MS_PARALYSIS:
- strcpy(beam.beam_name, "0");
- beam.range = 5;
- beam.rangeMax = 9;
- beam.type = 0;
- beam.flavour = BEAM_PARALYSIS;
- beam.thrower = KILL_MON_MISSILE;
- beam.is_beam = true;
- break;
-
- case MS_SLOW:
- strcpy(beam.beam_name, "0");
- beam.range = 5;
- beam.rangeMax = 9;
- beam.type = 0;
- beam.flavour = BEAM_SLOW;
- beam.thrower = KILL_MON_MISSILE;
- beam.is_beam = true;
- break;
-
- case MS_HASTE: // (self)
- strcpy(beam.beam_name, "0");
- beam.range = 5;
- beam.rangeMax = 9;
- beam.type = 0;
- beam.flavour = BEAM_HASTE;
- beam.thrower = KILL_MON_MISSILE;
- beam.is_beam = true;
- break;
-
- case MS_CONFUSE:
- strcpy(beam.beam_name, "0");
- beam.range = 5;
- beam.rangeMax = 9;
- beam.type = 0;
- beam.flavour = BEAM_CONFUSION;
- beam.thrower = KILL_MON_MISSILE;
- beam.is_beam = true;
- break;
-
- case MS_VENOM_BOLT:
- strcpy(beam.beam_name, "bolt of poison");
- beam.range = 7;
- beam.rangeMax = 16;
- beam.damage = dice_def( 3, 6 + power / 13 );
- beam.colour = LIGHTGREEN;
- beam.type = SYM_ZAP;
- beam.thrower = KILL_MON;
- beam.flavour = BEAM_POISON;
- beam.hit = 7 + random2(power) / 80;
- beam.is_beam = true;
- break;
-
- case MS_POISON_ARROW:
- strcpy( beam.beam_name, "poison arrow" );
- beam.damage = dice_def( 4, 5 + power / 12 );
- beam.colour = LIGHTGREEN;
- beam.type = SYM_MISSILE;
- beam.thrower = KILL_MON;
- beam.flavour = BEAM_POISON_ARROW;
- beam.hit = 40 + power / 5;
- beam.range = beam.rangeMax = 8;
- break;
-
- case MS_FIRE_BOLT:
- strcpy(beam.beam_name, "bolt of fire");
- beam.range = 4;
- beam.rangeMax = 13;
- beam.damage = dice_def( 3, 8 + power / 11 );
- beam.colour = RED;
- beam.type = SYM_ZAP;
- beam.thrower = KILL_MON;
- beam.flavour = BEAM_FIRE;
- beam.hit = 8 + random2(power) / 80; // hit
- beam.is_beam = true;
- break;
-
- case MS_COLD_BOLT:
- strcpy(beam.beam_name, "bolt of cold");
- beam.range = 4;
- beam.rangeMax = 13;
- beam.damage = dice_def( 3, 8 + power / 11 );
- beam.colour = WHITE;
- beam.type = SYM_ZAP;
- beam.thrower = KILL_MON;
- beam.flavour = BEAM_COLD;
- beam.hit = 8 + random2(power) / 80; // hit
- beam.is_beam = true;
- break;
-
- case MS_LIGHTNING_BOLT:
- strcpy(beam.beam_name, "bolt of lightning");
- beam.range = 7;
- beam.rangeMax = 16;
- beam.damage = dice_def( 3, 10 + power / 9 );
- beam.colour = LIGHTCYAN;
- beam.type = SYM_ZAP;
- beam.thrower = KILL_MON;
- beam.flavour = BEAM_ELECTRICITY;
- beam.hit = 10 + random2(power) / 40;
- beam.is_beam = true;
- break;
-
- case MS_INVIS:
- strcpy(beam.beam_name, "0");
- beam.range = 5;
- beam.rangeMax = 9;
- beam.type = 0;
- beam.flavour = BEAM_INVISIBILITY;
- beam.thrower = KILL_MON;
- beam.is_beam = true;
- break;
-
- case MS_FIREBALL:
- beam.colour = RED;
- strcpy(beam.beam_name, "fireball");
- beam.range = 6;
- beam.rangeMax = 10;
- beam.damage = dice_def( 3, 7 + power / 10 );
- beam.hit = 40;
- beam.type = SYM_ZAP;
- beam.thrower = KILL_MON;
- beam.flavour = BEAM_FIRE; // why not BEAM_FIRE? {dlb}
- beam.is_beam = false;
- beam.is_explosion = true;
- break;
-
- case MS_HEAL:
- strcpy(beam.beam_name, "0");
- beam.range = 5;
- beam.rangeMax = 9;
- beam.type = 0;
- beam.flavour = BEAM_HEALING;
- beam.thrower = KILL_MON;
- beam.hit = 5 + (power / 5);
- beam.is_beam = true;
- break;
-
- case MS_TELEPORT:
- strcpy(beam.beam_name, "0");
- beam.range = 5;
- beam.rangeMax = 9;
- beam.type = 0;
- beam.flavour = BEAM_TELEPORT; // 6 is used by digging
- beam.thrower = KILL_MON;
- beam.is_beam = true;
- break;
-
- case MS_TELEPORT_OTHER:
- strcpy(beam.beam_name, "0");
- beam.range = 5;
- beam.rangeMax = 9;
- beam.type = 0;
- beam.flavour = BEAM_TELEPORT; // 6 is used by digging
- beam.thrower = KILL_MON;
- beam.is_beam = true;
- break;
-
- case MS_BLINK:
- beam.is_beam = false;
- break;
-
- case MS_CRYSTAL_SPEAR: // was splinters
- strcpy(beam.beam_name, "crystal spear");
- beam.range = 7;
- beam.rangeMax = 16;
- beam.damage = dice_def( 3, 12 + power / 10 );
- beam.colour = WHITE;
- beam.type = SYM_MISSILE;
- beam.thrower = KILL_MON;
- beam.flavour = BEAM_MMISSILE;
- beam.hit = 6; // + random2(power) / 10;
- beam.is_beam = false;
- break;
-
- case MS_DIG:
- strcpy(beam.beam_name, "0");
- beam.range = 3;
- beam.rangeMax = 7 + random2(power) / 10;
- beam.type = 0;
- beam.flavour = BEAM_DIGGING;
- beam.thrower = KILL_MON;
- beam.is_beam = true;
- break;
-
- case MS_NEGATIVE_BOLT: // negative energy
- strcpy(beam.beam_name, "bolt of negative energy");
- beam.range = 7;
- beam.rangeMax = 16;
- beam.damage = dice_def( 3, 6 + power / 13 );
- beam.colour = DARKGREY;
- beam.type = SYM_ZAP;
- beam.thrower = KILL_MON;
- beam.flavour = BEAM_NEG;
- beam.hit = 7 + random2(power) / 80;
- beam.is_beam = true;
- break;
-
- // 20, 21 are used
-
- case MS_ORB_ENERGY: // mystic blast
- beam.colour = LIGHTMAGENTA;
- strcpy(beam.beam_name, "orb of energy");
- beam.range = 6;
- beam.rangeMax = 10;
- beam.damage = dice_def( 3, 7 + (power / 14) );
- beam.hit = 10 + (power / 20);
- beam.type = SYM_ZAP;
- beam.thrower = KILL_MON_MISSILE;
- beam.flavour = BEAM_MMISSILE;
- beam.is_beam = false;
- break;
-
- // 23 is brain feed
-
- case MS_STEAM_BALL:
- beam.colour = LIGHTGREY;
- strcpy(beam.beam_name, "ball of steam");
- beam.range = 6;
- beam.rangeMax = 10;
- beam.damage = dice_def( 3, 6 );
- beam.hit = 11;
- beam.type = SYM_ZAP;
- beam.thrower = KILL_MON_MISSILE;
- beam.flavour = BEAM_FIRE; // fire - I think this is appropriate
- beam.is_beam = false;
- break;
-
- // 27 is summon devils
- // 28 is animate dead
-
- case MS_PAIN:
- strcpy(beam.beam_name, "0");
- beam.range = 7;
- beam.rangeMax = 14;
- beam.type = 0;
- beam.flavour = BEAM_PAIN; // pain
- beam.thrower = KILL_MON;
- // beam.damage = dice_def( 1, 50 );
- beam.damage = dice_def( 1, 7 + (power / 20) );
- beam.ench_power = 50;
- beam.is_beam = true;
- break;
-
- // 30 is smiting
-
- case MS_STICKY_FLAME:
- beam.colour = RED;
- strcpy(beam.beam_name, "sticky flame");
- beam.range = 6;
- beam.rangeMax = 10;
- beam.damage = dice_def( 3, 3 + power / 50 );
- beam.hit = 8 + power / 15;
- beam.type = SYM_ZAP;
- beam.thrower = KILL_MON_MISSILE;
- beam.flavour = BEAM_FIRE;
- beam.is_beam = false;
- break;
-
- case MS_POISON_BLAST: // demon
- strcpy(beam.beam_name, "blast of poison");
- beam.range = 7;
- beam.rangeMax = 16;
- beam.damage = dice_def( 3, 3 + power / 25 );
- beam.colour = LIGHTGREEN;
- beam.type = SYM_ZAP;
- beam.thrower = KILL_MON;
- beam.flavour = BEAM_POISON;
- beam.hit = 7 + random2(power) / 80;
- beam.is_beam = true;
- beam.is_big_cloud = true;
- break;
-
- case MS_PURPLE_BLAST: // purple bang thing
- beam.colour = LIGHTMAGENTA;
- strcpy(beam.beam_name, "orb of energy");
- beam.range = 6;
- beam.rangeMax = 10;
- beam.damage = dice_def( 3, 10 + power / 15 );
- beam.hit = 10 + power / 20;
- beam.type = SYM_ZAP;
- beam.thrower = KILL_MON_MISSILE;
- beam.flavour = BEAM_MMISSILE;
- beam.is_beam = false;
- beam.is_explosion = true;
- break;
-
- case MS_ENERGY_BOLT: // eye of devastation
- beam.colour = YELLOW;
- strcpy(beam.beam_name, "bolt of energy");
- beam.range = 9;
- beam.rangeMax = 23;
- beam.damage = dice_def( 3, 20 );
- beam.hit = 9;
- beam.type = SYM_ZAP;
- beam.thrower = KILL_MON_MISSILE;
- beam.flavour = BEAM_NUKE; // a magical missile which destroys walls
- beam.is_beam = true;
- break;
-
- case MS_STING: // sting
- beam.colour = GREEN;
- strcpy(beam.beam_name, "sting");
- beam.range = 8;
- beam.rangeMax = 12;
- beam.damage = dice_def( 1, 6 + power / 25 );
- beam.hit = 60;
- beam.type = SYM_ZAP;
- beam.thrower = KILL_MON_MISSILE;
- beam.flavour = BEAM_POISON;
- beam.is_beam = false;
- break;
-
- case MS_IRON_BOLT:
- beam.colour = LIGHTCYAN;
- strcpy(beam.beam_name, "iron bolt");
- beam.range = 4;
- beam.rangeMax = 8;
- beam.damage = dice_def( 3, 8 + (power / 9) );
- beam.hit = 6 + (power / 25);
- beam.type = SYM_MISSILE;
- beam.thrower = KILL_MON_MISSILE;
- beam.flavour = BEAM_MMISSILE; // similarly unresisted thing
- beam.is_beam = false;
- break;
-
- case MS_STONE_ARROW:
- beam.colour = LIGHTGREY;
- strcpy(beam.beam_name, "stone arrow");
- beam.range = 8;
- beam.rangeMax = 12;
- beam.damage = dice_def( 3, 5 + (power / 10) );
- beam.hit = 5 + power / 47;
- beam.type = SYM_MISSILE;
- beam.thrower = KILL_MON_MISSILE;
- beam.flavour = BEAM_MMISSILE; // similarly unresisted thing
- beam.is_beam = false;
- break;
-
- case MS_POISON_SPLASH:
- beam.colour = GREEN;
- strcpy(beam.beam_name, "splash of poison");
- beam.range = 5;
- beam.rangeMax = 10;
- beam.damage = dice_def( 1, 4 + power / 10 );
- beam.hit = 9;
- beam.type = SYM_ZAP;
- beam.thrower = KILL_MON_MISSILE;
- beam.flavour = BEAM_POISON;
- beam.is_beam = false;
- break;
-
- case MS_DISINTEGRATE:
- strcpy(beam.beam_name, "0");
- beam.range = 7;
- beam.rangeMax = 14;
- beam.type = 0;
- beam.flavour = BEAM_DISINTEGRATION;
- beam.thrower = KILL_MON;
- beam.ench_power = 50;
- // beam.hit = 30 + (power / 10);
- beam.damage = dice_def( 1, 30 + (power / 10) );
- beam.is_beam = true;
- break;
-
- case MS_MARSH_GAS: // swamp drake
- strcpy(beam.beam_name, "foul vapour");
- beam.range = 7;
- beam.rangeMax = 16;
- beam.damage = dice_def( 3, 2 + power / 25 );
- beam.colour = GREEN;
- beam.type = SYM_ZAP;
- beam.thrower = KILL_MON;
- beam.flavour = BEAM_POISON;
- beam.hit = 7 + random2(power) / 80;
- beam.is_beam = true;
- beam.is_big_cloud = true;
- break;
-
- case MS_MIASMA: // death drake
- strcpy( beam.beam_name, "foul vapour" );
- beam.damage = dice_def( 3, 5 + power / 24 );
- beam.colour = DARKGREY;
- beam.type = SYM_ZAP;
- beam.thrower = KILL_MON;
- beam.flavour = BEAM_MIASMA;
- beam.hit = 80 + power / 20;
- beam.is_beam = true;
- beam.is_big_cloud = true;
- beam.range = beam.rangeMax = 8;
- break;
-
- case MS_QUICKSILVER_BOLT: // Quicksilver dragon
- beam.colour = random_colour();
- strcpy(beam.beam_name, "bolt of energy");
- beam.range = 9;
- beam.rangeMax = 23;
- beam.damage = dice_def( 3, 25 );
- beam.hit = 9;
- beam.type = SYM_ZAP;
- beam.thrower = KILL_MON_MISSILE;
- beam.flavour = BEAM_MMISSILE;
- beam.is_beam = false;
- break;
-
- case MS_HELLFIRE: // fiend's hellfire
- strcpy(beam.beam_name, "hellfire");
- beam.colour = RED;
- beam.range = 4;
- beam.rangeMax = 13;
- beam.damage = dice_def( 3, 25 );
- beam.hit = 20;
- beam.type = SYM_ZAP;
- beam.thrower = KILL_MON;
- beam.flavour = BEAM_HELLFIRE;
- beam.is_beam = true;
- beam.is_explosion = true;
- break;
-
- case MS_METAL_SPLINTERS:
- strcpy(beam.beam_name, "spray of metal splinters");
- beam.range = 7;
- beam.rangeMax = 16;
- beam.damage = dice_def( 3, 20 + power / 20 );
- beam.colour = CYAN;
- beam.type = SYM_ZAP;
- beam.thrower = KILL_MON;
- beam.flavour = BEAM_FRAG;
- beam.hit = 15 + random2(power) / 50;
- beam.is_beam = true;
- break;
-
- case MS_BANISHMENT:
- strcpy(beam.beam_name, "0");
- beam.range = 5;
- beam.rangeMax = 9;
- beam.type = 0;
- beam.flavour = BEAM_BANISH;
- beam.thrower = KILL_MON_MISSILE;
- beam.is_beam = true;
- break;
-
- case MS_BLINK_OTHER:
- strcpy(beam.beam_name, "0");
- beam.type = 0;
- beam.flavour = BEAM_BLINK;
- beam.thrower = KILL_MON;
- beam.is_beam = true;
- beam.is_enchant = true;
- beam.range = 8;
- beam.rangeMax = 8;
- break;
-
- default:
- DEBUGSTR("Unknown spell");
- }
-
- return (beam);
-} // end mons_spells()
-
-static unsigned char monster_abjuration(int pow, bool test)
-{
-
- unsigned char result = 0;
- struct monsters *monster = 0; // NULL {dlb}
-
- if (!test)
- mpr("Send 'em back where they came from!");
-
- for (int ab = 0; ab < MAX_MONSTERS; ab++)
- {
- int abjLevel;
-
- monster = &menv[ab];
-
- if (monster->type == -1 || !mons_near(monster))
- continue;
-
- if (!mons_friendly(monster))
- continue;
-
- abjLevel = mons_has_ench(monster, ENCH_ABJ_I, ENCH_ABJ_VI);
- if (abjLevel == ENCH_NONE)
- continue;
-
- result++;
-
- if (test)
- continue;
-
- if (pow > 60)
- pow = 60;
-
- abjLevel -= 1 + (random2(pow) / 3);
-
- if (abjLevel < ENCH_ABJ_I)
- monster_die(monster, KILL_RESET, 0);
- else
- {
- simple_monster_message(monster, " shudders.");
- mons_del_ench(monster, ENCH_ABJ_I, ENCH_ABJ_VI);
- mons_add_ench(monster, abjLevel);
- }
- }
-
- return result;
-} // end monster_abjuration()
diff --git a/stone_soup/crawl-ref/source/mstuff2.h b/stone_soup/crawl-ref/source/mstuff2.h
deleted file mode 100644
index 8ac7be902c..0000000000
--- a/stone_soup/crawl-ref/source/mstuff2.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * File: mstuff2.h
- * Summary: Misc monster related functions.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> 4/24/99 JDJ mons_spells returns an
- * SBeam instead of using
- * func_pass.
- */
-
-
-#ifndef MSTUFF2_H
-#define MSTUFF2_H
-
-
-#include <string>
-#include "externs.h"
-
-
-/*
- beam_colour = _pass[0];
- beam_range = _pass[1];
- beam_damage = _pass[2];
- beam_hit = _pass[3];
- beam_type = _pass[4];
- beam_flavour = _pass[5];
- thing_thrown = _pass[6];
- */
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: monstuff - mstuff2
- * *********************************************************************** */
-bolt mons_spells(int spell_cast, int power);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: monstuff
- * *********************************************************************** */
-void setup_dragon(struct monsters *monster, struct bolt &pbolt);
-
-
-// last updated 13feb2001 {gdl}
-/* ***********************************************************************
- * called from: monstuff
- * *********************************************************************** */
-void mons_cast(struct monsters *monster, struct bolt &pbolt, int spell_cast);
-
-// last updated 7jan2001 {gdl}
-/* ***********************************************************************
- * called from: monstuff
- * *********************************************************************** */
-void setup_mons_cast(struct monsters *monster, struct bolt &pbolt, int spell_cast);
-
-// last updated 28july2000 (gdl)
-/* ***********************************************************************
- * called from: monstuff
- * *********************************************************************** */
-bool mons_throw(struct monsters *monster, struct bolt &pbolt, int hand_used);
-
-// last updated 07jan2001 (gdl)
-/* ***********************************************************************
- * called from: monstuff
- * *********************************************************************** */
-void setup_generic_throw(struct monsters *monster, struct bolt &pbolt);
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: monstuff
- * *********************************************************************** */
-void mons_trap(struct monsters *monster);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: beam - fight - files - monstuff - mstuff2 - spells4
- * *********************************************************************** */
-void monster_teleport(struct monsters *monster, bool instan);
-
-
-// last updated Dec17,2000 -- gdl
-/* ***********************************************************************
- * called from: monstuff
- * *********************************************************************** */
-void spore_goes_pop(struct monsters *monster);
-
-
-// last updated Jan14,2001 -- gdl
-/* ***********************************************************************
- * called from: monstuff
- * *********************************************************************** */
-void throw_type(int lnchClass, int lnchType, int wepClass, int wepType,
- bool &launched, bool &thrown);
-
-
-
-#endif
diff --git a/stone_soup/crawl-ref/source/mt19937ar.cc b/stone_soup/crawl-ref/source/mt19937ar.cc
deleted file mode 100644
index 2b5697aeb5..0000000000
--- a/stone_soup/crawl-ref/source/mt19937ar.cc
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- A C-program for MT19937, with initialization improved 2002/1/26.
- Coded by Takuji Nishimura and Makoto Matsumoto.
-
- Before using, initialize the state by using init_genrand(seed)
- or init_by_array(init_key, key_length).
-
- Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. The names of its contributors may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
- Any feedback is very welcome.
- http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
- email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
-*/
-
-#include <stdio.h>
-#include <string.h>
-#include <stack>
-
-/* Period parameters */
-#define N 624
-#define M 397
-#define MATRIX_A 0x9908b0dfUL /* constant vector a */
-#define UPPER_MASK 0x80000000UL /* most significant w-r bits */
-#define LOWER_MASK 0x7fffffffUL /* least significant r bits */
-
-static unsigned long mt[N]; /* the array for the state vector */
-static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */
-
-struct mtrng_state
-{
- int mti;
- unsigned long mt[N];
-};
-
-static std::stack<mtrng_state*> states;
-
-void push_mt_state()
-{
- // We're doing a new, delete and a lot of copying for saving/restoring
- // state. Slow.
- mtrng_state *mtst = new mtrng_state;
- if (!mtst)
- return ;
- mtst->mti = mti;
- memcpy(mtst->mt, mt, sizeof(mt));
- states.push(mtst);
-}
-
-void pop_mt_state()
-{
- if (states.empty())
- return;
- mtrng_state *mtst = states.top();
- states.pop();
-
- mti = mtst->mti;
- memcpy(mt, mtst->mt, sizeof(mt));
-
- delete mtst;
-}
-
-/* initializes mt[N] with a seed */
-void init_genrand(unsigned long s)
-{
- mt[0]= s & 0xffffffffUL;
- for (mti=1; mti<N; mti++) {
- mt[mti] =
- (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
- /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
- /* In the previous versions, MSBs of the seed affect */
- /* only MSBs of the array mt[]. */
- /* 2002/01/09 modified by Makoto Matsumoto */
- mt[mti] &= 0xffffffffUL;
- /* for >32 bit machines */
- }
-}
-
-#if 0
-/* initialize by an array with array-length */
-/* init_key is the array for initializing keys */
-/* key_length is its length */
-/* slight change for C++, 2004/2/26 */
-void init_by_array(unsigned long init_key[], int key_length)
-{
- int i, j, k;
- init_genrand(19650218UL);
- i=1; j=0;
- k = (N>key_length ? N : key_length);
- for (; k; k--) {
- mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL))
- + init_key[j] + j; /* non linear */
- mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
- i++; j++;
- if (i>=N) { mt[0] = mt[N-1]; i=1; }
- if (j>=key_length) j=0;
- }
- for (k=N-1; k; k--) {
- mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL))
- - i; /* non linear */
- mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
- i++;
- if (i>=N) { mt[0] = mt[N-1]; i=1; }
- }
-
- mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */
-}
-#endif
-
-/* generates a random number on [0,0xffffffff]-interval */
-unsigned long genrand_int32(void)
-{
- unsigned long y;
- static unsigned long mag01[2]={0x0UL, MATRIX_A};
- /* mag01[x] = x * MATRIX_A for x=0,1 */
-
- if (mti >= N) { /* generate N words at one time */
- int kk;
-
- if (mti == N+1) /* if init_genrand() has not been called, */
- init_genrand(5489UL); /* a default initial seed is used */
-
- for (kk=0;kk<N-M;kk++) {
- y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
- mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
- }
- for (;kk<N-1;kk++) {
- y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
- mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
- }
- y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
- mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
-
- mti = 0;
- }
-
- y = mt[mti++];
-
- /* Tempering */
- y ^= (y >> 11);
- y ^= (y << 7) & 0x9d2c5680UL;
- y ^= (y << 15) & 0xefc60000UL;
- y ^= (y >> 18);
-
- return y;
-}
-
-#if 0
-/* generates a random number on [0,0x7fffffff]-interval */
-long genrand_int31(void)
-{
- return (long)(genrand_int32()>>1);
-}
-
-/* generates a random number on [0,1]-real-interval */
-double genrand_real1(void)
-{
- return genrand_int32()*(1.0/4294967295.0);
- /* divided by 2^32-1 */
-}
-
-/* generates a random number on [0,1)-real-interval */
-double genrand_real2(void)
-{
- return genrand_int32()*(1.0/4294967296.0);
- /* divided by 2^32 */
-}
-
-/* generates a random number on (0,1)-real-interval */
-double genrand_real3(void)
-{
- return (((double)genrand_int32()) + 0.5)*(1.0/4294967296.0);
- /* divided by 2^32 */
-}
-
-/* generates a random number on [0,1) with 53-bit resolution*/
-double genrand_res53(void)
-{
- unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6;
- return(a*67108864.0+b)*(1.0/9007199254740992.0);
-}
-/* These real versions are due to Isaku Wada, 2002/01/09 added */
-
-int main(void)
-{
- int i;
- unsigned long init[4]={0x123, 0x234, 0x345, 0x456}, length=4;
- init_by_array(init, length);
- printf("1000 outputs of genrand_int32()\n");
- for (i=0; i<1000; i++) {
- printf("%10lu ", genrand_int32());
- if (i%5==4) printf("\n");
- }
- printf("\n1000 outputs of genrand_real2()\n");
- for (i=0; i<1000; i++) {
- printf("%10.8f ", genrand_real2());
- if (i%5==4) printf("\n");
- }
- return 0;
-}
-#endif
diff --git a/stone_soup/crawl-ref/source/mt19937ar.h b/stone_soup/crawl-ref/source/mt19937ar.h
deleted file mode 100644
index 3e8948ee6a..0000000000
--- a/stone_soup/crawl-ref/source/mt19937ar.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- A C-program for MT19937, with initialization improved 2002/1/26.
- Coded by Takuji Nishimura and Makoto Matsumoto.
-
- Before using, initialize the state by using init_genrand(seed)
- or init_by_array(init_key, key_length).
-
- Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. The names of its contributors may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
- Any feedback is very welcome.
- http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
- email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
-*/
-
-/* initializes mt[N] with a seed */
-void init_genrand( unsigned long s );
-
-/* generates a random number on [0,0xffffffff]-interval */
-unsigned long genrand_int32( void );
-
-void push_mt_state();
-
-void pop_mt_state();
diff --git a/stone_soup/crawl-ref/source/mutation.cc b/stone_soup/crawl-ref/source/mutation.cc
deleted file mode 100644
index 027a810432..0000000000
--- a/stone_soup/crawl-ref/source/mutation.cc
+++ /dev/null
@@ -1,2328 +0,0 @@
-/*
- * File: mutation.cc
- * Summary: Functions for handling player mutations.
- * Written by: Linley Henzell
- *
- * Modified for Crawl Reference by $Author$ on $Date$
- *
- * Change History (most recent first):
- *
- * <5> 7/29/00 JDJ Made give_cosmetic_mutation static
- * <4> 9/25/99 CDL linuxlib -> liblinux
- * <3> 9/21/99 LRH Added many new scales
- * <2> 5/20/99 BWR Fixed it so demonspwan should
- * always get a mutation, 3 level
- * perma_mutations now work.
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "mutation.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef DOS
-#include <conio.h>
-#endif
-
-#ifdef UNIX
-#include "libunix.h"
-#endif
-
-#include "externs.h"
-
-#include "defines.h"
-#include "effects.h"
-#include "macro.h"
-#include "ouch.h"
-#include "player.h"
-#include "skills2.h"
-#include "stuff.h"
-#include "transfor.h"
-#include "view.h"
-
-
-int how_mutated(void);
-char body_covered(void);
-bool perma_mutate(int which_mut, char how_much);
-
-const char *mutation_descrip[][3] = {
- {"You have tough skin (AC +1).", "You have very tough skin (AC +2).",
- "You have extremely tough skin (AC +3)."},
-
- {"Your muscles are strong (Str +", "", ""},
- {"Your mind is acute (Int +", "", ""},
- {"You are agile (Dex +", "", ""},
-
- {"You are partially covered in green scales (AC + 1).",
- "You are mostly covered in green scales (AC + 3).",
- "You are covered in green scales (AC + 5)."},
-
- {"You are partially covered in thick black scales (AC + 3, dex - 1).",
- "You are mostly covered in thick black scales (AC + 6, dex - 2).",
- "You are completely covered in thick black scales (AC + 9, dex - 3)."},
-
- {"You are partially covered in supple grey scales (AC + 1).",
- "You are mostly covered in supple grey scales (AC + 2).",
- "You are completely covered in supple grey scales (AC + 3)."},
-
- {"You are protected by plates of bone (AC + 2, dex - 1).",
- "You are protected by plates of bone (AC + 3, dex - 2).",
- "You are protected by plates of bone (AC + 4, dex - 3)."},
-
- {"You are surrounded by a mild repulsion field (ev + 1).",
- "You are surrounded by a moderate repulsion field (ev + 3).",
- "You are surrounded by a strong repulsion field (ev + 5; repel missiles)."},
- {"Your system is immune to poisons.", "Your system is immune to poisons.",
- "Your system is immune to poisons."},
-// 10
-
- {"Your digestive system is specialised to digest meat.",
- "Your digestive system is specialised to digest meat.",
- "You are primarily a carnivore."},
-
- {"You digest meat inefficiently.", "You digest meat inefficiently.",
- "You are primarily a herbivore."},
-
- {"Your flesh is heat resistant.", "Your flesh is very heat resistant.",
- "Your flesh is almost immune to the effects of heat."},
-
- {"Your flesh is cold resistant.", "Your flesh is very cold resistant.",
- "Your flesh is almost immune to the effects of cold."},
-
- {"You are immune to electric shocks.", "You are immune to electric shocks.",
- "You are immune to electric shocks."},
-
- {"Your natural rate of healing is unusually fast.",
- "You heal very quickly.",
- "You regenerate."},
-
- {"You have a fast metabolism.", "You have a very fast metabolism.",
- "Your metabolism is lightning-fast."},
-
- {"You have a slow metabolism.", "You have a slow metabolism.",
- "You need consume almost no food."},
-
- {"You are weak (Str -", "", ""},
- {"You are dopey (Int -", "", ""},
-// 20
- {"You are clumsy (Dex -", "", ""},
-
- {"You can control translocations.", "You can control translocations.",
- "You can control translocations."},
-
- {"Space occasionally distorts in your vicinity.",
- "Space sometimes distorts in your vicinity.",
- "Space frequently distorts in your vicinity."},
-
- {"You are resistant to magic.", "You are highly resistant to magic.",
- "You are extremely resistant to the effects of magic."},
-
- {"You cover the ground quickly.", "You cover the ground very quickly.",
- "You cover the ground extremely quickly."},
-
- {"You have supernaturally acute eyesight.",
- "You have supernaturally acute eyesight.",
- "You have supernaturally acute eyesight."},
-
- {"Armour fits poorly on your deformed body.",
- "Armour fits poorly on your badly deformed body.",
- "Armour fits poorly on your hideously deformed body."},
-
- {"You can teleport at will.", "You are good at teleporting at will.",
- "You can teleport instantly at will."},
-
- {"You can spit poison.", "You can spit poison.", "You can spit poison."},
-
- {"You can sense your immediate surroundings.",
- "You can sense your surroundings.",
- "You can sense a large area of your surroundings."},
-
-// 30
-
- {"You can breathe flames.", "You can breathe fire.",
- "You can breathe blasts of fire."},
-
- {"You can translocate small distances instantaneously.",
- "You can translocate small distances instantaneously.",
- "You can translocate small distances instantaneously."},
-
- {"You have a pair of small horns on your head.",
- "You have a pair of horns on your head.",
- "You have a pair of large horns on your head."},
-
- {"Your muscles are strong (Str +1), but stiff (Dex -1).",
- "Your muscles are very strong (Str +2), but stiff (Dex -2).",
- "Your muscles are extremely strong (Str +3), but stiff (Dex -3)."},
-
- {"Your muscles are flexible (Dex +1), but weak (Str -1).",
- "Your muscles are very flexible (Dex +2), but weak (Str -2).",
- "Your muscles are extremely flexible (Dex +3), but weak (Str -3)."},
-
- {"You occasionally forget where you are.",
- "You sometimes forget where you are.",
- "You frequently forget where you are."},
-
- {"You possess an exceptional clarity of mind.",
- "You possess an unnatural clarity of mind.",
- "You possess a supernatural clarity of mind."},
-
- {"You tend to lose your temper in combat.",
- "You often lose your temper in combat.",
- "You have an uncontrollable temper."},
-
- {"Your body is slowly deteriorating.", "Your body is deteriorating.",
- "Your body is rapidly deteriorating."},
-
- {"Your vision is a little blurry.", "Your vision is quite blurry.",
- "Your vision is extremely blurry."},
-// 40
-
- {"You are somewhat resistant to further mutation.",
- "You are somewhat resistant to both further mutation and mutation removal.",
- "Your current mutations are irrevocably fixed, and you can mutate no more."},
-
- {"You are frail (-10 percent hp).", "You are very frail (-20 percent hp).",
- "You are extremely frail (-30 percent hp)."},
-
- {"You are robust (+10 percent hp).",
- "You are very robust (+20 percent hp).",
- "You are extremely robust (+30 percent hp)."},
-
- {"You are immune to unholy pain and torment.", "", ""},
-
- {"You resist negative energy.",
- "You are quite resistant to negative energy.",
- "You are immune to negative energy."},
-
- /* Use player_has_spell() to avoid duplication */
- {"You can summon minor demons to your aid.", "", ""},
- {"You can summon demons to your aid.", "", ""},
- {"You can hurl blasts of hellfire.", "", ""},
- {"You can call on the torments of Hell.", "", ""},
- {"You can raise the dead to walk for you.", "", ""},
-// 50
- {"You can control demons.", "", ""},
- {"You can travel to (but not from) Pandemonium at will.", "", ""},
- {"You can draw strength from death and destruction.", "", ""},
-
- /* Not worshippers of Vehumet */
- {"You can channel magical energy from Hell.", "", ""},
-
- {"You can drain life in unarmed combat.", "", ""},
-
- /* Not conjurers/worshippers of Makhleb */
- {"You can throw forth the flames of Gehenna.", "", ""},
-
- {"You can throw forth the frost of Cocytus.", "", ""},
-
- {"You can invoke the powers of Tartarus to smite your living foes.", "", ""},
- {"You have sharp fingernails.", "Your fingernails are very sharp.",
- "You have claws for hands."},
-
- {"You have hooves in place of feet.", "", ""},
- // 60 - leave some space for more demonic powers...
- {"You can exhale a cloud of poison.", "", ""},
-
- {"Your tail ends in a poisonous barb.",
- "Your tail ends in a sharp poisonous barb.",
- "Your tail ends in a wicked poisonous barb."}, //jmf: nagas & dracos
-
- {"Your wings are large and strong.", "", ""}, //jmf: dracos only
-
- //jmf: these next two are for evil gods to mark their followers; good gods
- // will never accept a 'marked' worhsipper
-
- {"There is a blue sigil on each of your hands.",
- "There are several blue sigils on your hands and arms.",
- "Your hands, arms and shoulders are covered in intricate, arcane blue writing."},
-
- {"There is a green sigil on your chest.",
- "There are several green sigils on your chest and abdomen.",
- "Your chest, abdomen and neck are covered in intricate, arcane green writing."},
-
- {"", "", ""},
- {"", "", ""},
- {"", "", ""},
- {"", "", ""},
- {"", "", ""},
- // 70
-
- {"You are partially covered in red scales (AC + 1).",
- "You are mostly covered in red scales (AC + 2).",
- "You are covered in red scales (AC + 4)."},
-
- {"You are partially covered in smooth nacreous scales (AC + 1).",
- "You are mostly covered in smooth nacreous scales (AC + 3).",
- "You are completely covered in smooth nacreous scales (AC + 5)."},
-
- {"You are partially covered in ridged grey scales (AC + 2, dex - 1).",
- "You are mostly covered in ridged grey scales (AC + 4, dex - 1).",
- "You are completely covered in ridged grey scales (AC + 6, dex - 2)."},
-
- {"You are partially covered in metallic scales (AC + 3, dex - 2).",
- "You are mostly covered in metallic scales (AC + 7, dex - 3).",
- "You are completely covered in metallic scales (AC + 10, dex - 4)."},
-
- {"You are partially covered in black scales (AC + 1).",
- "You are mostly covered in black scales (AC + 3).",
- "You are completely covered in black scales (AC + 5)."},
-
- {"You are partially covered in white scales (AC + 1).",
- "You are mostly covered in white scales (AC + 3).",
- "You are completely covered in white scales (AC + 5)."},
-
- {"You are partially covered in yellow scales (AC + 2).",
- "You are mostly covered in yellow scales (AC + 4, dex - 1).",
- "You are completely covered in yellow scales (AC + 6, dex - 2)."},
-
- {"You are partially covered in brown scales (AC + 2).",
- "You are mostly covered in brown scales (AC + 4).",
- "You are completely covered in brown scales (AC + 5)."},
-
- {"You are partially covered in blue scales (AC + 1).",
- "You are mostly covered in blue scales (AC + 2).",
- "You are completely covered in blue scales (AC + 3)."},
-
- {"You are partially covered in purple scales (AC + 2).",
- "You are mostly covered in purple scales (AC + 4).",
- "You are completely covered in purple scales (AC + 6)."},
-
-// 80
-
- {"You are partially covered in speckled scales (AC + 1).",
- "You are mostly covered in speckled scales (AC + 2).",
- "You are covered in speckled scales (AC + 3)."},
-
- {"You are partially covered in orange scales (AC + 1).",
- "You are mostly covered in orange scales (AC + 3).",
- "You are completely covered in orange scales (AC + 4)."},
-
- {"You are partially covered in indigo scales (AC + 2).",
- "You are mostly covered in indigo scales (AC + 3).",
- "You are completely covered in indigo scales (AC + 5)."},
-
- {"You are partially covered in knobbly red scales (AC + 2).",
- "You are mostly covered in knobbly red scales (AC + 5, dex - 1).",
- "You are completely covered in knobbly red scales (AC + 7, dex - 2)."},
-
- {"You are partially covered in iridescent scales (AC + 1).",
- "You are mostly covered in iridescent scales (AC + 2).",
- "You are completely covered in iridescent scales (AC + 3)."},
-
- {"You are partially covered in patterned scales (AC + 1).",
- "You are mostly covered in patterned scales (AC + 2).",
- "You are completely covered in patterned scales (AC + 3)."},
-};
-
-/*
- If giving a mutation which must succeed (eg demonspawn), must add exception
- to the "resist mutation" mutation thing.
- */
-
-const char *gain_mutation[][3] = {
- {"Your skin toughens.", "Your skin toughens.", "Your skin toughens."},
-
- {"", "", ""}, // replaced with player::modify_stat() handling {dlb}
- {"", "", ""}, // replaced with player::modify_stat() handling {dlb}
- {"", "", ""}, // replaced with player::modify_stat() handling {dlb}
-
- {"Green scales grow over part of your body.",
- "Green scales spread over more of your body.",
- "Green scales cover you completely."},
-
- {"Thick black scales grow over part of your body.",
- "Thick black scales spread over more of your body.",
- "Thick black scales cover you completely."},
-
- {"Supple grey scales grow over part of your body.",
- "Supple grey scales spread over more of your body.",
- "Supple grey scales cover you completely."},
-
- {"You grow protective plates of bone.",
- "You grow more protective plates of bone.",
- "You grow more protective plates of bone."},
-
- {"You begin to radiate repulsive energy.",
- "Your repulsive radiation grows stronger.",
- "Your repulsive radiation grows stronger."},
-
- {"You feel healthy.", "You feel healthy.", "You feel healthy."},
-// 10
- {"You hunger for flesh.", "You hunger for flesh.", "You hunger for flesh."},
-
- {"You hunger for vegetation.", "You hunger for vegetation.",
- "You hunger for vegetation."},
-
- {"You feel a sudden chill.", "You feel a sudden chill.",
- "You feel a sudden chill."},
-
- {"You feel hot for a moment.", "You feel hot for a moment.",
- "You feel hot for a moment."},
-
- {"You feel insulated.", "You feel insulated.", "You feel insulated."},
-
- {"You begin to heal more quickly.",
- "You begin to heal more quickly.",
- "You begin to regenerate."},
-
- {"You feel a little hungry.", "You feel a little hungry.",
- "You feel a little hungry."},
-
- {"Your metabolism slows.", "Your metabolism slows.",
- "Your metabolism slows."},
-
- {"You feel weaker.", "You feel weaker.", "You feel weaker."},
-
- {"You feel less intelligent.", "You feel less intelligent",
- "You feel less intelligent"},
-// 20
- {"You feel clumsy.", "You feel clumsy.",
- "You feel clumsy."},
-
- {"You feel controlled.", "You feel controlled.",
- "You feel controlled."},
-
- {"You feel weirdly uncertain.",
- "You feel even more weirdly uncertain.",
- "You feel even more weirdly uncertain."},
-
- {"You feel resistant to magic.",
- "You feel more resistant to magic.",
- "You feel almost impervious to the effects of magic."},
-
- {"You feel quick.", "You feel quick.", "You feel quick."},
-
- {"Your vision sharpens.", "Your vision sharpens.", "Your vision sharpens."},
-
- {"Your body twists and deforms.", "Your body twists and deforms.",
- "Your body twists and deforms."},
-
- {"You feel jumpy.", "You feel more jumpy.", "You feel even more jumpy."},
-
- {"There is a nasty taste in your mouth for a moment.",
- "There is a nasty taste in your mouth for a moment.",
- "There is a nasty taste in your mouth for a moment."},
-
- {"You feel aware of your surroundings.",
- "You feel more aware of your surroundings.",
- "You feel even more aware of your surroundings."},
-// 30
-
- {"Your throat feels hot.", "Your throat feels hot.",
- "Your throat feels hot."},
-
- {"You feel a little jumpy.", "You feel more jumpy.",
- "You feel even more jumpy."},
-
- {"A pair of horns grows on your head!",
- "The horns on your head grow some more.",
- "The horns on your head grow some more."},
-
- {"Your muscles feel sore.", "Your muscles feel sore.",
- "Your muscles feel sore."},
-
- {"Your muscles feel loose.", "Your muscles feel loose.",
- "Your muscles feel loose."},
-
- {"You feel a little disoriented.", "You feel a little disoriented.",
- "Where the Hells are you?"},
-
- {"Your thoughts seem clearer.", "Your thoughts seem clearer.",
- "Your thoughts seem clearer."},
-
- {"You feel a little pissed off.", "You feel angry.",
- "You feel extremely angry at everything!"},
-
- {"You feel yourself wasting away.", "You feel yourself wasting away.",
- "You feel your body start to fall apart."},
-
- {"Your vision blurs.", "Your vision blurs.", "Your vision blurs."},
-// 40
-
- {"You feel genetically stable.", "You feel genetically stable.",
- "You feel genetically immutable."},
-
- {"You feel frail.", "You feel frail.", "You feel frail."},
- {"You feel robust.", "You feel robust.", "You feel robust."},
- {"You feel a strange anaesthesia.", "", ""},
- {"You feel negative.", "You feel negative.", "You feel negative."},
- {"A thousand chattering voices call out to you.", "", ""},
- {"Help is not far away!", "", ""},
- {"You smell fire and brimstone.", "", ""},
- {"You feel a terrifying power at your call.", "", ""},
- {"You feel an affinity for the dead.", "", ""},
-// 50
- {"You feel an affinity for all demonkind.", "", ""},
- {"You feel something pulling you to a strange and terrible place.", "", ""},
- {"You feel hungry for death.", "", ""},
- {"You feel a flux of magical energy.", "", ""},
- {"Your skin tingles in a strangely unpleasant way.", "", ""},
- {"You smell the fires of Gehenna.", "", ""},
- {"You feel the icy cold of Cocytus chill your soul.", "", ""},
- {"A shadow passes over the world around you.", "", ""},
-
- {"Your fingernails lengthen.", "Your fingernails sharpen.",
- "Your hands twist into claws."},
-
- {"Your feet shrivel into cloven hooves.", "", ""},
- // 60
-
- {"You taste something nasty.", "You taste something very nasty.",
- "You taste something extremely nasty."},
-
- {"A poisonous barb forms on the end of your tail.",
- "The barb on your tail looks sharper.",
- "The barb on your tail looks very sharp."},
-
- {"Your wings grow larger and stronger.", "", ""},
-
- {"Your hands itch.", "Your hands and forearms itch.",
- "Your arms, hands and shoulders itch."},
-
- {"Your chest itches.", "Your chest and abdomen itch.",
- "Your chest, abdomen and neck itch."},
-
- {"", "", ""},
- {"", "", ""},
- {"", "", ""},
- {"", "", ""},
- {"", "", ""},
- // 70
-
- {"Red scales grow over part of your body.",
- "Red scales spread over more of your body.",
- "Red scales cover you completely."},
- {"Smooth nacreous scales grow over part of your body.",
- "Smooth nacreous scales spread over more of your body.",
- "Smooth nacreous scales cover you completely."},
- {"Ridged grey scales grow over part of your body.",
- "Ridged grey scales spread over more of your body.",
- "Ridged grey scales cover you completely."},
- {"Metallic scales grow over part of your body.",
- "Metallic scales spread over more of your body.",
- "Metallic scales cover you completely."},
- {"Black scales grow over part of your body.",
- "Black scales spread over more of your body.",
- "Black scales cover you completely."},
- {"White scales grow over part of your body.",
- "White scales spread over more of your body.",
- "White scales cover you completely."},
- {"Yellow scales grow over part of your body.",
- "Yellow scales spread over more of your body.",
- "Yellow scales cover you completely."},
- {"Brown scales grow over part of your body.",
- "Brown scales spread over more of your body.",
- "Brown scales cover you completely."},
- {"Blue scales grow over part of your body.",
- "Blue scales spread over more of your body.",
- "Blue scales cover you completely."},
- {"Purple scales grow over part of your body.",
- "Purple scales spread over more of your body.",
- "Purple scales cover you completely."},
- // 80
-
- {"Speckled scales grow over part of your body.",
- "Speckled scales spread over more of your body.",
- "Speckled scales cover you completely."},
- {"Orange scales grow over part of your body.",
- "Orange scales spread over more of your body.",
- "Orange scales cover you completely."},
- {"Indigo scales grow over part of your body.",
- "Indigo scales spread over more of your body.",
- "Indigo scales cover you completely."},
- {"Knobbly red scales grow over part of your body.",
- "Knobbly red scales spread over more of your body.",
- "Knobbly red scales cover you completely."},
- {"Iridescent scales grow over part of your body.",
- "Iridescent scales spread over more of your body.",
- "Iridescent scales cover you completely."},
- {"Patterned scales grow over part of your body.",
- "Patterned scales spread over more of your body.",
- "Patterned scales cover you completely."},
-};
-
-const char *lose_mutation[][3] = {
-
- {"Your skin feels delicate.", "Your skin feels delicate.",
- "Your skin feels delicate."},
-
- {"You feel weaker.", "You feel weaker.", "You feel weaker."},
-
- {"You feel less intelligent.", "You feel less intelligent",
- "You feel less intelligent"},
-
- {"You feel clumsy.", "You feel clumsy.", "You feel clumsy."},
-
- {"Your green scales disappear.",
- "Your green scales recede somewhat.",
- "Your green scales recede somewhat."},
-
- {"Your black scales disappear.", "Your black scales recede somewhat.",
- "Your black scales recede somewhat."},
-
- {"Your grey scales disappear.", "Your grey scales recede somewhat.",
- "Your grey scales recede somewhat."},
-
- {"Your bony plates shrink away.", "Your bony plates shrink.",
- "Your bony plates shrink."},
-
- {"You feel attractive.", "You feel attractive.", "You feel attractive."},
-
- {"You feel a little less healthy.", "You feel a little less healthy.",
- "You feel a little less healthy."},
-
- {"You feel able to eat a more balanced diet.",
- "You feel able to eat a more balanced diet.",
- "You feel able to eat a more balanced diet."},
-
- {"You feel able to eat a more balanced diet.",
- "You feel able to eat a more balanced diet.",
- "You feel able to eat a more balanced diet."},
-
- {"You feel hot for a moment.", "You feel hot for a moment.",
- "You feel hot for a moment."},
-
- {"You feel a sudden chill.", "You feel a sudden chill.",
- "You feel a sudden chill."},
-
- {"You feel conductive.", "You feel conductive.", "You feel conductive."},
-
- {"Your rate of healing slows.", "Your rate of healing slows.",
- "Your rate of healing slows."},
-
- {"Your metabolism slows.", "Your metabolism slows.",
- "Your metabolism slows."},
-
- {"You feel a little hungry.", "You feel a little hungry.",
- "You feel a little hungry."},
-
- {"", "", ""}, // replaced with player::modify_stat() handling {dlb}
- {"", "", ""}, // replaced with player::modify_stat() handling {dlb}
-// 20
- {"", "", ""}, // replaced with player::modify_stat() handling {dlb}
-
- {"You feel random.", "You feel uncontrolled.", "You feel uncontrolled."},
- {"You feel stable.", "You feel stable.", "You feel stable."},
-
- {"You feel less resistant to magic.", "You feel less resistant to magic.",
- "You feel vulnerable to magic again."},
-
- {"You feel sluggish.", "You feel sluggish.", "You feel sluggish."},
-
- {"Your vision seems duller.", "Your vision seems duller.",
- "Your vision seems duller."},
-
- {"Your body's shape seems more normal.",
- "Your body's shape seems slightly more normal.",
- "Your body's shape seems slightly more normal."},
-
- {"You feel static.", "You feel less jumpy.", "You feel less jumpy."},
-
- {"You feel an ache in your throat.",
- "You feel an ache in your throat.", "You feel an ache in your throat."},
-
- {"You feel slightly disorientated.", "You feel slightly disorientated.",
- "You feel slightly disorientated."},
-// 30
-
- {"A chill runs up and down your throat.",
- "A chill runs up and down your throat.",
- "A chill runs up and down your throat."},
-
- {"You feel a little less jumpy.", "You feel less jumpy.",
- "You feel less jumpy."},
-
- {"The horns on your head shrink away.",
- "The horns on your head shrink a bit.",
- "The horns on your head shrink a bit."},
-
- {"Your muscles feel loose.", "Your muscles feel loose.",
- "Your muscles feel loose."},
-
- {"Your muscles feel sore.", "Your muscles feel sore.",
- "Your muscles feel sore."},
-
- {"You feel less disoriented.", "You feel less disoriented.",
- "You feel less disoriented."},
-
- {"Your thinking seems confused.", "Your thinking seems confused.",
- "Your thinking seems confused."},
-
- {"You feel a little more calm.", "You feel a little less angry.",
- "You feel a little less angry."},
-
- {"You feel healthier.", "You feel a little healthier.",
- "You feel a little healthier."},
-
- {"Your vision sharpens.", "Your vision sharpens a little.",
- "Your vision sharpens a little."},
-// 40
-
- {"You feel genetically unstable.", "You feel genetically unstable.",
- "You feel genetically unstable."},
-
- {"You feel robust.", "You feel robust.", "You feel robust."},
- {"You feel frail.", "You feel frail.", "You feel frail."},
-
-/* Some demonic powers (which can't be lost) start here... */
- {"", "", ""},
- {"", "", ""},
- {"", "", ""},
- {"", "", ""},
- {"", "", ""},
- {"", "", ""},
- {"", "", ""},
-// 50
- {"", "", ""},
- {"", "", ""},
- {"", "", ""},
- {"", "", ""},
- {"", "", ""},
- {"", "", ""},
- {"", "", ""},
- {"", "", ""},
-
- {"Your fingernails shrink to normal size.",
- "Your fingernails look duller.", "Your hands feel fleshier."},
-
- {"Your hooves expand and flesh out into feet!", "", ""},
- // 60
- {"", "", ""},
- {"", "", ""},
- {"", "", ""},
- {"", "", ""},
- {"", "", ""},
- {"", "", ""},
- {"", "", ""},
- {"", "", ""},
- {"", "", ""},
- {"", "", ""},
-// 70
-
- {"Your red scales disappear.", "Your red scales recede somewhat.",
- "Your red scales recede somewhat."},
-
- {"Your smooth nacreous scales disappear.",
- "Your smooth nacreous scales recede somewhat.",
- "Your smooth nacreous scales recede somewhat."},
-
- {"Your ridged grey scales disappear.",
- "Your ridged grey scales recede somewhat.",
- "Your ridged grey scales recede somewhat."},
-
- {"Your metallic scales disappear.",
- "Your metallic scales recede somewhat.",
- "Your metallic scales recede somewhat."},
-
- {"Your black scales disappear.", "Your black scales recede somewhat.",
- "Your black scales recede somewhat."},
-
- {"Your white scales disappear.", "Your white scales recede somewhat.",
- "Your white scales recede somewhat."},
-
- {"Your yellow scales disappear.", "Your yellow scales recede somewhat.",
- "Your yellow scales recede somewhat."},
-
- {"Your brown scales disappear.", "Your brown scales recede somewhat.",
- "Your brown scales recede somewhat."},
-
- {"Your blue scales disappear.", "Your blue scales recede somewhat.",
- "Your blue scales recede somewhat."},
-
- {"Your purple scales disappear.", "Your purple scales recede somewhat.",
- "Your purple scales recede somewhat."},
-// 80
-
- {"Your speckled scales disappear.",
- "Your speckled scales recede somewhat.",
- "Your speckled scales recede somewhat."},
-
- {"Your orange scales disappear.", "Your orange scales recede somewhat.",
- "Your orange scales recede somewhat."},
-
- {"Your indigo scales disappear.", "Your indigo scales recede somewhat.",
- "Your indigo scales recede somewhat."},
-
- {"Your knobbly red scales disappear.",
- "Your knobbly red scales recede somewhat.",
- "Your knobbly red scales recede somewhat."},
-
- {"Your iridescent scales disappear.",
- "Your iridescent scales recede somewhat.",
- "Your iridescent scales recede somewhat."},
-
- {"Your patterned scales disappear.",
- "Your patterned scales recede somewhat.",
- "Your patterned scales recede somewhat."},
-};
-
-/*
- Chance out of 10 that mutation will be given/removed randomly. 0 means never.
- */
-const char mutation_rarity[] = {
- 10, // tough skin
- 8, // str
- 8, // int
- 8, // dex
- 2, // gr scales
- 1, // bl scales
- 2, // grey scales
- 1, // bone
- 1, // repuls field
- 4, // res poison
-// 10
- 5, // carn
- 5, // herb
- 4, // res fire
- 4, // res cold
- 2, // res elec
- 3, // regen
- 10, // fast meta
- 7, // slow meta
- 10, // abil loss
- 10, // ""
-// 20
- 10, // ""
- 2, // tele control
- 3, // teleport
- 5, // res magic
- 1, // run
- 2, // see invis
- 8, // deformation
- 2, // teleport at will
- 8, // spit poison
- 3, // sense surr
-// 30
- 4, // breathe fire
- 3, // blink
- 7, // horns
- 10, // strong/stiff muscles
- 10, // weak/loose muscles
- 6, // forgetfulness
- 6, // clarity (as the amulet)
- 7, // berserk/temper
- 10, // deterioration
- 10, // blurred vision
-// 40
- 4, // resist mutation
- 10, // frail
- 5, // robust
-/* Some demonic powers start here: */
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
-// 50
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 2, //jmf: claws
- 1, //jmf: hooves
-// 60
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
-// 70
- 2, // red scales
- 1, // nac scales
- 2, // r-grey scales
- 1, // metal scales
- 2, // black scales
- 2, // wh scales
- 2, // yel scales
- 2, // brown scales
- 2, // blue scales
- 2, // purple scales
-// 80
- 2, // speckled scales
- 2, // orange scales
- 2, // indigo scales
- 1, // kn red scales
- 1, // irid scales
- 1, // pattern scales
- 0, //
- 0, //
- 0, //
- 0 //
-};
-
-void display_mutations(void)
-{
- int i;
- int j = 0;
- const char *mut_title = "Innate abilities, Weirdness & Mutations";
- const int num_lines = get_number_of_lines();
-
-#ifdef DOS_TERM
- char buffer[4800];
-
- window(1, 1, 80, 25);
- gettext(1, 1, 80, 25, buffer);
-#endif
-
- clrscr();
- textcolor(WHITE);
-
- // center title
- i = 40 - strlen(mut_title) / 2;
- if (i<1) i=1;
- gotoxy(i, 1);
- cprintf(mut_title);
- gotoxy(1,3);
- textcolor(LIGHTBLUE); //textcolor for inborn abilities and weirdness
-
- switch (you.species) //mv: following code shows innate abilities - if any
- {
- case SP_MERFOLK:
- cprintf("You revert to your normal form in water." EOL);
- j++;
- break;
-
- case SP_NAGA:
- // breathe poison replaces spit poison:
- if (!you.mutation[MUT_BREATHE_POISON])
- cprintf("You can spit poison." EOL);
- else
- cprintf("You can exhale a cloud of poison." EOL);
-
- cprintf("Your system is immune to poisons." EOL);
- cprintf("You can see invisible." EOL);
- j += 3;
- break;
-
- case SP_GNOME:
- cprintf("You can sense your surroundings." EOL);
- j++;
- break;
-
- case SP_TROLL:
- cprintf("Your body regenerates quickly." EOL);
- j++;
- break;
-
- case SP_GHOUL:
- cprintf("Your body is rotting away." EOL);
- cprintf("You are carnivorous." EOL);
- j += 2;
- break;
-
- case SP_KOBOLD:
- cprintf("You are carnivorous." EOL);
- j++;
- break;
-
- case SP_GREY_ELF:
- if (you.experience_level > 4)
- {
- cprintf("You are very charming." EOL);
- j++;
- }
- break;
-
- case SP_KENKU:
- if (you.experience_level > 4)
- {
- cprintf("You can fly");
- cprintf((you.experience_level > 14) ? " continuously." EOL : "."
- EOL);
- j++;
- }
- break;
-
- case SP_MUMMY:
- cprintf("You are");
- cprintf((you.experience_level > 25) ? " very strongly" :
- ((you.experience_level > 12) ? " strongly" : ""));
- cprintf(" in touch with the powers of death." EOL);
- j++;
-
- if (you.experience_level >= 12)
- {
- cprintf("You can restore your body by infusing magical energy." EOL);
- j++;
- }
- break;
-
- case SP_GREEN_DRACONIAN:
- if (you.experience_level > 6)
- {
- cprintf("You are resistant to poison." EOL);
- cprintf("You can breathe poison." EOL);
- j += 2;
- }
- break;
-
- case SP_RED_DRACONIAN:
- if (you.experience_level > 6)
- {
- cprintf("You can breathe fire." EOL);
- j++;
- }
- if (you.experience_level > 17)
- {
- cprintf("You are resistant to fire." EOL);
- j++;
- }
- break;
-
- case SP_WHITE_DRACONIAN:
- if (you.experience_level > 6)
- {
- cprintf("You can breathe frost." EOL);
- j++;
- }
- if (you.experience_level > 17)
- {
- cprintf("You are resistant to cold." EOL);
- j++;
- }
- break;
-
- case SP_BLACK_DRACONIAN:
- if (you.experience_level > 6)
- {
- cprintf("You can breathe lightning." EOL);
- j++;
- }
- if (you.experience_level > 17)
- {
- cprintf("You are resistant to lightning." EOL);
- j++;
- }
- break;
-
- case SP_GOLDEN_DRACONIAN:
- if (you.experience_level > 6)
- {
- cprintf("You can spit acid." EOL);
- j++;
- }
- break;
-
- case SP_PURPLE_DRACONIAN:
- if (you.experience_level > 6)
- {
- cprintf("You can breathe power." EOL);
- j++;
- }
- break;
-
- case SP_MOTTLED_DRACONIAN:
- if (you.experience_level > 6)
- {
- cprintf("You can breathe sticky flames." EOL);
- j++;
- }
- break;
-
- case SP_PALE_DRACONIAN:
- if (you.experience_level > 6)
- {
- cprintf("You can breathe steam." EOL);
- j++;
- }
- break;
- } //end switch - innate abilities
-
- textcolor(LIGHTGREY);
-
- for (i = 0; i < 100; i++)
- {
- if (you.mutation[i] != 0)
- {
- // this is already handled above:
- if (you.species == SP_NAGA && i == MUT_BREATHE_POISON)
- continue;
-
- j++;
- textcolor(LIGHTGREY);
-
- if (j > num_lines - 4)
- {
- gotoxy( 1, num_lines - 1 );
- cprintf("-more-");
-
- if (getch() == 0)
- getch();
-
- clrscr();
-
- // center title
- int x = 40 - strlen(mut_title) / 2;
- if (x < 1)
- x = 1;
-
- gotoxy(x, 1);
- textcolor(WHITE);
- cprintf(mut_title);
- textcolor(LIGHTGREY);
- gotoxy(1,3);
- j = 1;
- }
-
- /* mutation is actually a demonic power */
- if (you.demon_pow[i] != 0)
- textcolor(RED);
-
- /* same as above, but power is enhanced by mutation */
- if (you.demon_pow[i] != 0 && you.demon_pow[i] < you.mutation[i])
- textcolor(LIGHTRED);
-
- cprintf( mutation_name( i ) );
- cprintf(EOL);
- }
- }
-
- if (j == 0)
- cprintf( "You are not a mutant." EOL );
-
- if (getch() == 0)
- getch();
-#ifdef DOS_TERM
- puttext(1, 1, 80, 25, buffer);
-#endif
-
- //cprintf("xxxxxxxxxxxxx");
- //last_requested = 0;
-
- return;
-} // end display_mutations()
-
-bool mutate(int which_mutation, bool failMsg)
-{
- int mutat = which_mutation;
- bool force_mutation = false; // is mutation forced?
- int i;
-
- if (which_mutation >= 1000) // must give mutation without failure
- {
- force_mutation = true;
- mutat -= 1000;
- which_mutation -= 1000;
- }
-
- // Undead bodies don't mutate, they fall apart. -- bwr
- if (you.is_undead)
- {
- if (force_mutation
- || (wearing_amulet(AMU_RESIST_MUTATION) && coinflip()))
- {
- mpr( "Your body decomposes!" );
-
- if (coinflip())
- lose_stat( STAT_RANDOM, 1 );
- else
- {
- ouch( 3, 0, KILLED_BY_ROTTING );
- rot_hp( roll_dice( 1, 3 ) );
- }
-
- return (true);
- }
-
- if (failMsg)
- mpr("You feel odd for a moment.");
-
- return (false);
- }
-
- if (wearing_amulet(AMU_RESIST_MUTATION)
- && !force_mutation && !one_chance_in(10))
- {
- if (failMsg)
- mpr("You feel odd for a moment.");
-
- return (false);
- }
-
- if (you.mutation[MUT_MUTATION_RESISTANCE]
- && !force_mutation
- && (you.mutation[MUT_MUTATION_RESISTANCE] == 3 || !one_chance_in(3)))
- {
- if (failMsg)
- mpr("You feel odd for a moment.");
-
- return (false);
- }
-
- if (which_mutation == 100 && random2(15) < how_mutated())
- {
- if (!force_mutation && !one_chance_in(3))
- return (false);
- else
- return (delete_mutation(100));
- }
-
- if (which_mutation == 100)
- {
- do
- {
- mutat = random2(NUM_MUTATIONS);
-
- if (one_chance_in(1000))
- return false;
- }
- while ((you.mutation[mutat] >= 3
- && (mutat != MUT_STRONG && mutat != MUT_CLEVER
- && mutat != MUT_AGILE) && (mutat != MUT_WEAK
- && mutat != MUT_DOPEY
- && mutat != MUT_CLUMSY))
- || you.mutation[mutat] > 13
- || random2(10) >= mutation_rarity[mutat] + you.demon_pow[mutat]);
- }
-
- if (you.mutation[mutat] >= 3
- && (mutat != MUT_STRONG && mutat != MUT_CLEVER && mutat != MUT_AGILE)
- && (mutat != MUT_WEAK && mutat != MUT_DOPEY && mutat != MUT_CLUMSY))
- {
- return false;
- }
-
- if (you.mutation[mutat] > 13 && !force_mutation)
- return false;
-
- // These can be forced by demonspawn
- if ((mutat == MUT_TOUGH_SKIN
- || (mutat >= MUT_GREEN_SCALES && mutat <= MUT_BONEY_PLATES)
- || (mutat >= MUT_RED_SCALES && mutat <= MUT_PATTERNED_SCALES))
- && body_covered() >= 3 && !force_mutation)
- {
- return false;
- }
-
- if (mutat == MUT_HORNS && you.species == SP_MINOTAUR)
- return false;
-
- // nagas have see invis and res poison and can spit poison
- if (you.species == SP_NAGA)
- {
- if (mutat == MUT_ACUTE_VISION || mutat == MUT_POISON_RESISTANCE)
- return false;
-
- // gdl: spit poison 'upgrades' to breathe poison. Why not..
- if (mutat == MUT_SPIT_POISON)
- {
- if (coinflip())
- return false;
- {
- mutat = MUT_BREATHE_POISON;
-
- // breathe poison replaces spit poison (so it takes the slot)
- for (i = 0; i < 52; i++)
- {
- if (you.ability_letter_table[i] == ABIL_SPIT_POISON)
- you.ability_letter_table[i] = ABIL_BREATHE_POISON;
- }
- }
- }
- }
-
- // gnomes can already sense surroundings
- if (you.species == SP_GNOME && mutat == MUT_MAPPING)
- return false;
-
- // spriggans already run at max speed (centaurs can get a bit faster)
- if (you.species == SP_SPRIGGAN && mutat == MUT_FAST)
- return false;
-
- // this might have issues if we allowed it -- bwr
- if (you.species == SP_KOBOLD
- && (mutat == MUT_CARNIVOROUS || mutat == MUT_HERBIVOROUS))
- {
- return (false);
- }
-
- // This one can be forced by demonspawn
- if (mutat == MUT_REGENERATION
- && you.mutation[MUT_SLOW_METABOLISM] > 0 && !force_mutation)
- {
- return false; /* if you have a slow metabolism, no regen */
- }
-
- if (mutat == MUT_SLOW_METABOLISM && you.mutation[MUT_REGENERATION] > 0)
- return false; /* if you have a slow metabolism, no regen */
-
- // This one can be forced by demonspawn
- if (mutat == MUT_ACUTE_VISION
- && you.mutation[MUT_BLURRY_VISION] > 0 && !force_mutation)
- {
- return false;
- }
-
- if (mutat == MUT_BLURRY_VISION && you.mutation[MUT_ACUTE_VISION] > 0)
- return false; /* blurred vision/see invis */
-
- //jmf: added some checks for new mutations
- if (mutat == MUT_STINGER
- && !(you.species == SP_NAGA || player_genus(GENPC_DRACONIAN)))
- {
- return false;
- }
-
- // putting boots on after they are forced off. -- bwr
- if (mutat == MUT_HOOVES
- && (you.species == SP_NAGA || you.species == SP_CENTAUR
- || you.species == SP_KENKU || player_genus(GENPC_DRACONIAN)))
- {
- return false;
- }
-
- if (mutat == MUT_BIG_WINGS && !player_genus(GENPC_DRACONIAN))
- return false;
-
- //jmf: added some checks for new mutations
- mpr("You mutate.", MSGCH_MUTATION);
-
- // find where these things are actually changed
- // -- do not globally force redraw {dlb}
- you.redraw_hit_points = 1;
- you.redraw_magic_points = 1;
- you.redraw_armour_class = 1;
- you.redraw_evasion = 1;
- you.redraw_experience = 1;
- you.redraw_gold = 1;
- //you.redraw_hunger = 1;
-
- switch (mutat)
- {
- case MUT_STRONG:
- if (you.mutation[MUT_WEAK] > 0)
- {
- delete_mutation(MUT_WEAK);
- return true;
- }
- // replaces earlier, redundant code - 12mar2000 {dlb}
- modify_stat(STAT_STRENGTH, 1, false);
- break;
-
- case MUT_CLEVER:
- if (you.mutation[MUT_DOPEY] > 0)
- {
- delete_mutation(MUT_DOPEY);
- return true;
- }
- // replaces earlier, redundant code - 12mar2000 {dlb}
- modify_stat(STAT_INTELLIGENCE, 1, false);
- break;
-
- case MUT_AGILE:
- if (you.mutation[MUT_CLUMSY] > 0)
- {
- delete_mutation(MUT_CLUMSY);
- return true;
- }
- // replaces earlier, redundant code - 12mar2000 {dlb}
- modify_stat(STAT_DEXTERITY, 1, false);
- break;
-
- case MUT_WEAK:
- if (you.mutation[MUT_STRONG] > 0)
- {
- delete_mutation(MUT_STRONG);
- return true;
- }
- modify_stat(STAT_STRENGTH, -1, true);
- mpr(gain_mutation[mutat][0], MSGCH_MUTATION);
- break;
-
- case MUT_DOPEY:
- if (you.mutation[MUT_CLEVER] > 0)
- {
- delete_mutation(MUT_CLEVER);
- return true;
- }
- modify_stat(STAT_INTELLIGENCE, -1, true);
- mpr(gain_mutation[mutat][0], MSGCH_MUTATION);
- break;
-
- case MUT_CLUMSY:
- if (you.mutation[MUT_AGILE] > 0)
- {
- delete_mutation(MUT_AGILE);
- return true;
- }
- modify_stat(STAT_DEXTERITY, -1, true);
- mpr(gain_mutation[mutat][0], MSGCH_MUTATION);
- break;
-
- case MUT_REGENERATION:
- if (you.mutation[MUT_SLOW_METABOLISM] > 0)
- {
- // Should only get here from demonspawn, where our innate
- // ability will clear away the counter-mutation.
- while (delete_mutation(MUT_SLOW_METABOLISM))
- ;
- }
- mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION);
- break;
-
- case MUT_ACUTE_VISION:
- if (you.mutation[MUT_BLURRY_VISION] > 0)
- {
- // Should only get here from demonspawn, where our inate
- // ability will clear away the counter-mutation.
- while (delete_mutation(MUT_BLURRY_VISION))
- ;
- }
- mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION);
- break;
-
- case MUT_CARNIVOROUS:
- if (you.mutation[MUT_HERBIVOROUS] > 0)
- {
- delete_mutation(MUT_HERBIVOROUS);
- return true;
- }
- mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION);
- break;
-
- case MUT_HERBIVOROUS:
- if (you.mutation[MUT_CARNIVOROUS] > 0)
- {
- delete_mutation(MUT_CARNIVOROUS);
- return true;
- }
- mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION);
- break;
-
- case MUT_SHOCK_RESISTANCE:
- mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION);
- break;
-
- case MUT_FAST_METABOLISM:
- if (you.mutation[MUT_SLOW_METABOLISM] > 0)
- {
- delete_mutation(MUT_SLOW_METABOLISM);
- return true;
- }
- mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION);
- break;
-
- case MUT_SLOW_METABOLISM:
- if (you.mutation[MUT_FAST_METABOLISM] > 0)
- {
- delete_mutation(MUT_FAST_METABOLISM);
- return true;
- }
- //if (you.mutation[mutat] == 0 || you.mutation[mutat] == 2)
- mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION);
- break;
-
- case MUT_TELEPORT_CONTROL:
- you.attribute[ATTR_CONTROL_TELEPORT]++;
- mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION);
- break;
-
-
- case MUT_HOOVES: //jmf: like horns
- mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION);
- if (you.equip[EQ_BOOTS] != -1)
- {
- FixedVector < char, 8 > removed;
-
- for (i = EQ_WEAPON; i < EQ_RIGHT_RING; i++)
- {
- removed[i] = 0;
- }
-
- removed[EQ_BOOTS] = 1;
- remove_equipment(removed);
- }
- break;
-
- case MUT_CLAWS:
- mpr( gain_mutation[ mutat ][ you.mutation[mutat] ], MSGCH_MUTATION );
-
- // gloves aren't prevented until level three
- if (you.mutation[ mutat ] >= 3 && you.equip[ EQ_GLOVES ] != -1)
- {
- FixedVector < char, 8 > removed;
-
- for (i = EQ_WEAPON; i < EQ_RIGHT_RING; i++)
- {
- removed[i] = 0;
- }
-
- removed[ EQ_GLOVES ] = 1;
- remove_equipment( removed );
- }
- break;
-
- case MUT_HORNS: // horns force your helmet off
- {
- mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION);
-
- if (you.equip[EQ_HELMET] != -1
- && you.inv[you.equip[EQ_HELMET]].plus2 > 1)
- {
- break; // horns don't push caps/wizard hats off
- }
-
- FixedVector < char, 8 > removed;
-
- for (i = EQ_WEAPON; i < EQ_RIGHT_RING; i++)
- {
- removed[i] = 0;
- }
-
- removed[EQ_HELMET] = 1;
- remove_equipment(removed);
- }
- break;
-
- case MUT_STRONG_STIFF:
- if (you.mutation[MUT_FLEXIBLE_WEAK] > 0)
- {
- delete_mutation(MUT_FLEXIBLE_WEAK);
- return true;
- }
- modify_stat(STAT_STRENGTH, 1, true);
- modify_stat(STAT_DEXTERITY, -1, true);
- mpr(gain_mutation[mutat][0], MSGCH_MUTATION);
- break;
-
- case MUT_FLEXIBLE_WEAK:
- if (you.mutation[MUT_STRONG_STIFF] > 0)
- {
- delete_mutation(MUT_STRONG_STIFF);
- return true;
- }
- modify_stat(STAT_STRENGTH, -1, true);
- modify_stat(STAT_DEXTERITY, 1, true);
- mpr(gain_mutation[mutat][0], MSGCH_MUTATION);
- break;
-
- case MUT_FRAIL:
- if (you.mutation[MUT_ROBUST] > 0)
- {
- delete_mutation(MUT_ROBUST);
- return true;
- }
- mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION);
- you.mutation[mutat]++;
- calc_hp();
- return true;
-
- case MUT_ROBUST:
- if (you.mutation[MUT_FRAIL] > 0)
- {
- delete_mutation(MUT_FRAIL);
- return true;
- }
- mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION);
- you.mutation[mutat]++;
- calc_hp();
- return true;
-
- case MUT_BLACK_SCALES:
- case MUT_BONEY_PLATES:
- modify_stat(STAT_DEXTERITY, -1, true);
- // deliberate fall-through
- default:
- mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION);
- break;
-
- case MUT_GREY2_SCALES:
- if (you.mutation[mutat] != 1)
- modify_stat(STAT_DEXTERITY, -1, true);
-
- mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION);
- break;
-
- case MUT_METALLIC_SCALES:
- if (you.mutation[mutat] == 0)
- modify_stat(STAT_DEXTERITY, -2, true);
- else
- modify_stat(STAT_DEXTERITY, -1, true);
-
- mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION);
- break;
-
- case MUT_RED2_SCALES:
- case MUT_YELLOW_SCALES:
- if (you.mutation[mutat] != 0)
- modify_stat(STAT_DEXTERITY, -1, true);
-
- mpr(gain_mutation[mutat][you.mutation[mutat]], MSGCH_MUTATION);
- break;
- }
-
- you.mutation[mutat]++;
-
- /* remember, some mutations don't get this far (eg frail) */
- return true;
-} // end mutation()
-
-int how_mutated(void)
-{
- int j = 0;
-
- for (int i = 0; i < 100; i++)
- {
- if (you.mutation[i] && you.demon_pow[i] < you.mutation[i])
- {
- // these allow for 14 levels:
- if (i == MUT_STRONG || i == MUT_CLEVER || i == MUT_AGILE
- || i == MUT_WEAK || i == MUT_DOPEY || i == MUT_CLUMSY)
- {
- j += (you.mutation[i] / 5 + 1);
- }
- else
- {
- j += you.mutation[i];
- }
- }
- }
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "levels: %d", j );
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- return (j);
-} // end how_mutated()
-
-bool delete_mutation(int which_mutation)
-{
- int mutat = which_mutation;
- int i;
-
- if (you.mutation[MUT_MUTATION_RESISTANCE] > 1
- && (you.mutation[MUT_MUTATION_RESISTANCE] == 3 || coinflip()))
- {
- mpr("You feel rather odd for a moment.");
- return false;
- }
-
- if (which_mutation == 100)
- {
- do
- {
- mutat = random2(NUM_MUTATIONS);
- if (one_chance_in(1000))
- return false;
- }
- while ((you.mutation[mutat] == 0
- && (mutat != MUT_STRONG && mutat != MUT_CLEVER && mutat != MUT_AGILE)
- && (mutat != MUT_WEAK && mutat != MUT_DOPEY && mutat != MUT_CLUMSY))
- || random2(10) >= mutation_rarity[mutat]
- || you.demon_pow[mutat] >= you.mutation[mutat]);
- }
-
- if (you.mutation[mutat] == 0)
- return false;
-
- if (you.demon_pow[mutat] >= you.mutation[mutat])
- return false;
-
- mpr("You mutate.", MSGCH_MUTATION);
-
- switch (mutat)
- {
- case MUT_STRONG:
- modify_stat(STAT_STRENGTH, -1, true);
- mpr(lose_mutation[mutat][0], MSGCH_MUTATION);
- break;
-
- case MUT_CLEVER:
- modify_stat(STAT_INTELLIGENCE, -1, true);
- mpr(lose_mutation[mutat][0], MSGCH_MUTATION);
- break;
-
- case MUT_AGILE:
- modify_stat(STAT_DEXTERITY, -1, true);
- mpr(lose_mutation[mutat][0], MSGCH_MUTATION);
- break;
-
- case MUT_WEAK:
- modify_stat(STAT_STRENGTH, 1, false);
- break;
-
- case MUT_DOPEY:
- modify_stat(STAT_INTELLIGENCE, 1, false);
- break;
-
- case MUT_CLUMSY:
- // replaces earlier, redundant code - 12mar2000 {dlb}
- modify_stat(STAT_DEXTERITY, 1, false);
- break;
-
- case MUT_SHOCK_RESISTANCE:
- mpr(lose_mutation[mutat][you.mutation[mutat] - 1], MSGCH_MUTATION);
- break;
-
- case MUT_FAST_METABOLISM:
- mpr(lose_mutation[mutat][you.mutation[mutat] - 1], MSGCH_MUTATION);
- break;
-
- case MUT_SLOW_METABOLISM:
- mpr(lose_mutation[mutat][you.mutation[mutat] - 1], MSGCH_MUTATION);
- break;
-
- case MUT_TELEPORT_CONTROL:
- you.attribute[ATTR_CONTROL_TELEPORT]--;
- mpr(lose_mutation[mutat][you.mutation[mutat] - 1], MSGCH_MUTATION);
- break;
-
- case MUT_STRONG_STIFF:
- modify_stat(STAT_STRENGTH, -1, true);
- modify_stat(STAT_DEXTERITY, 1, true);
- mpr(lose_mutation[mutat][0], MSGCH_MUTATION);
- break;
-
- case MUT_FLEXIBLE_WEAK:
- modify_stat(STAT_STRENGTH, 1, true);
- modify_stat(STAT_DEXTERITY, -1, true);
- mpr(lose_mutation[mutat][0], MSGCH_MUTATION);
- break;
-
- case MUT_FRAIL:
- mpr(lose_mutation[mutat][0], MSGCH_MUTATION);
- if (you.mutation[mutat] > 0)
- you.mutation[mutat]--;
- calc_hp();
- return true;
-
- case MUT_ROBUST:
- mpr(lose_mutation[mutat][0], MSGCH_MUTATION);
- if (you.mutation[mutat] > 0)
- you.mutation[mutat]--;
- calc_hp();
- return true;
-
- case MUT_BLACK_SCALES:
- case MUT_BONEY_PLATES:
- modify_stat(STAT_DEXTERITY, 1, true);
-
- default:
- mpr(lose_mutation[mutat][you.mutation[mutat] - 1], MSGCH_MUTATION);
- break;
-
- case MUT_GREY2_SCALES:
- if (you.mutation[mutat] != 2)
- modify_stat(STAT_DEXTERITY, 1, true);
- mpr(lose_mutation[mutat][you.mutation[mutat] - 1], MSGCH_MUTATION);
- break;
-
- case MUT_METALLIC_SCALES:
- if (you.mutation[mutat] == 1)
- modify_stat(STAT_DEXTERITY, 2, true);
- else
- modify_stat(STAT_DEXTERITY, 1, true);
-
- mpr(lose_mutation[mutat][you.mutation[mutat] - 1], MSGCH_MUTATION);
- break;
-
- case MUT_RED2_SCALES:
- case MUT_YELLOW_SCALES:
- if (you.mutation[mutat] != 1)
- modify_stat(STAT_DEXTERITY, 1, true);
-
- mpr(lose_mutation[mutat][you.mutation[mutat] - 1], MSGCH_MUTATION);
- break;
-
- case MUT_BREATHE_POISON:
- // can't be removed yet, but still covered:
- if (you.species == SP_NAGA)
- {
- // natural ability to spit poison retakes the slot
- for (i = 0; i < 52; i++)
- {
- if (you.ability_letter_table[i] == ABIL_BREATHE_POISON)
- you.ability_letter_table[i] = ABIL_SPIT_POISON;
- }
- }
- break;
- }
-
- // find where these things are actually altered
- /// -- do not globally force redraw {dlb}
- you.redraw_hit_points = 1;
- you.redraw_magic_points = 1;
- you.redraw_armour_class = 1;
- you.redraw_evasion = 1;
- you.redraw_experience = 1;
- you.redraw_gold = 1;
- //you.redraw_hunger = 1;
-
- if (you.mutation[mutat] > 0)
- you.mutation[mutat]--;
-
- return true;
-} // end delete_mutation()
-
-char body_covered(void)
-{
- /* checks how much of your body is covered by scales etc */
- char covered = 0;
-
- if (you.species == SP_NAGA)
- covered++;
-
- if (player_genus(GENPC_DRACONIAN))
- return 3;
-
- covered += you.mutation[MUT_TOUGH_SKIN];
- covered += you.mutation[MUT_GREEN_SCALES];
- covered += you.mutation[MUT_BLACK_SCALES];
- covered += you.mutation[MUT_GREY_SCALES];
- covered += you.mutation[MUT_BONEY_PLATES];
- covered += you.mutation[MUT_RED_SCALES];
- covered += you.mutation[MUT_NACREOUS_SCALES];
- covered += you.mutation[MUT_GREY2_SCALES];
- covered += you.mutation[MUT_METALLIC_SCALES];
- covered += you.mutation[MUT_BLACK2_SCALES];
- covered += you.mutation[MUT_WHITE_SCALES];
- covered += you.mutation[MUT_YELLOW_SCALES];
- covered += you.mutation[MUT_BROWN_SCALES];
- covered += you.mutation[MUT_BLUE_SCALES];
- covered += you.mutation[MUT_PURPLE_SCALES];
- covered += you.mutation[MUT_SPECKLED_SCALES];
- covered += you.mutation[MUT_ORANGE_SCALES];
- covered += you.mutation[MUT_INDIGO_SCALES];
- covered += you.mutation[MUT_RED2_SCALES];
- covered += you.mutation[MUT_IRIDESCENT_SCALES];
- covered += you.mutation[MUT_PATTERNED_SCALES];
-
- return covered;
-}
-
-const char *mutation_name(int which_mutat, int level )
-{
- static char mut_string[INFO_SIZE];
-
- // level == -1 means default action of current level
- if (level == -1)
- level = you.mutation[ which_mutat ];
-
- if (which_mutat == MUT_STRONG || which_mutat == MUT_CLEVER
- || which_mutat == MUT_AGILE || which_mutat == MUT_WEAK
- || which_mutat == MUT_DOPEY || which_mutat == MUT_CLUMSY)
- {
- snprintf( mut_string, sizeof( mut_string ), "%s%d).",
- mutation_descrip[ which_mutat ][0], level );
-
- return (mut_string);
- }
-
- // Some mutations only have one "level", and it's better
- // to show the first level description than a blank description.
- if (mutation_descrip[ which_mutat ][ level - 1 ][0] == '\0')
- return (mutation_descrip[ which_mutat ][ 0 ]);
- else
- return (mutation_descrip[ which_mutat ][ level - 1 ]);
-} // end mutation_name()
-
-/* Use an attribute counter for how many demonic mutations a dspawn has */
-void demonspawn(void)
-{
- int whichm = -1;
- char howm = 1;
- int counter = 0;
-
- const int scale_levels = body_covered();
-
- you.attribute[ATTR_NUM_DEMONIC_POWERS]++;
-
- mpr("Your demonic ancestry asserts itself...", MSGCH_INTRINSIC_GAIN);
-
- // Merged the demonspawn lists into a single loop. Now a high level
- // character can potentially get mutations from the low level list if
- // its having trouble with the high level list.
- do
- {
- if (you.experience_level >= 10)
- {
- if (you.skills[SK_CONJURATIONS] < 5)
- { // good conjurers don't get bolt of draining
- whichm = MUT_SMITE;
- howm = 1;
- }
-
- if (you.skills[SK_CONJURATIONS] < 10 && one_chance_in(4))
- { // good conjurers don't get hellfire
- whichm = MUT_HURL_HELLFIRE;
- howm = 1;
- }
-
- if (you.skills[SK_SUMMONINGS] < 5 && one_chance_in(3))
- { // good summoners don't get summon demon
- whichm = MUT_SUMMON_DEMONS;
- howm = 1;
- }
-
- if (one_chance_in(8))
- {
- whichm = MUT_MAGIC_RESISTANCE;
- howm = (coinflip() ? 2 : 3);
- }
-
- if (one_chance_in(12))
- {
- whichm = MUT_FAST;
- howm = 1;
- }
-
- if (one_chance_in(7))
- {
- whichm = MUT_TELEPORT_AT_WILL;
- howm = 2;
- }
-
- if (one_chance_in(10))
- {
- whichm = MUT_REGENERATION;
- howm = (coinflip() ? 2 : 3);
- }
-
- if (one_chance_in(12))
- {
- whichm = MUT_SHOCK_RESISTANCE;
- howm = 1;
- }
-
- if (!you.mutation[MUT_CALL_TORMENT] && one_chance_in(15))
- {
- whichm = MUT_TORMENT_RESISTANCE;
- howm = 1;
- }
-
- if (one_chance_in(12))
- {
- whichm = MUT_NEGATIVE_ENERGY_RESISTANCE;
- howm = 1 + random2(3);
- }
-
- if (!you.mutation[MUT_TORMENT_RESISTANCE] && one_chance_in(20))
- {
- whichm = MUT_CALL_TORMENT;
- howm = 1;
- }
-
- if (you.skills[SK_SUMMONINGS] < 5 && you.skills[SK_NECROMANCY] < 5
- && one_chance_in(12))
- {
- whichm = MUT_CONTROL_DEMONS;
- howm = 1;
- }
-
- if (you.skills[SK_TRANSLOCATIONS] < 5 && one_chance_in(15))
- {
- whichm = MUT_PANDEMONIUM;
- howm = 1;
- }
-
- if (you.religion != GOD_VEHUMET && one_chance_in(11))
- {
- whichm = MUT_DEATH_STRENGTH;
- howm = 1;
- }
-
- if (you.religion != GOD_VEHUMET && one_chance_in(11))
- {
- whichm = MUT_CHANNEL_HELL;
- howm = 1;
- }
-
- if (you.skills[SK_SUMMONINGS] < 3 && you.skills[SK_NECROMANCY] < 3
- && one_chance_in(10))
- {
- whichm = MUT_RAISE_DEAD;
- howm = 1;
- }
-
- if (you.skills[SK_UNARMED_COMBAT] > 5 && one_chance_in(14))
- {
- whichm = MUT_DRAIN_LIFE;
- howm = 1;
- }
- }
-
- // check here so we can see if we need to extent our options:
- if (whichm != -1 && you.mutation[whichm] != 0)
- whichm = -1;
-
- if (you.experience_level < 10 || (counter > 0 && whichm == -1))
- {
- if ((!you.mutation[MUT_THROW_FROST] // only one of these
- && !you.mutation[MUT_THROW_FLAMES]
- && !you.mutation[MUT_BREATHE_FLAMES])
- && (!you.skills[SK_CONJURATIONS] // conjurers seldomly
- || one_chance_in(5))
- && (!you.skills[SK_ICE_MAGIC] // already ice & fire?
- || !you.skills[SK_FIRE_MAGIC]))
- {
- // try to give the flavour the character doesn't have:
- if (!you.skills[SK_FIRE_MAGIC])
- whichm = MUT_THROW_FLAMES;
- else if (!you.skills[SK_ICE_MAGIC])
- whichm = MUT_THROW_FROST;
- else
- whichm = (coinflip() ? MUT_THROW_FLAMES : MUT_THROW_FROST);
-
- howm = 1;
- }
-
- if (!you.skills[SK_SUMMONINGS] && one_chance_in(3))
- { /* summoners don't get summon imp */
- whichm = (you.experience_level < 10) ? MUT_SUMMON_MINOR_DEMONS
- : MUT_SUMMON_DEMONS;
- howm = 1;
- }
-
- if (one_chance_in(4))
- {
- whichm = MUT_POISON_RESISTANCE;
- howm = 1;
- }
-
- if (one_chance_in(4))
- {
- whichm = MUT_COLD_RESISTANCE;
- howm = 1;
- }
-
- if (one_chance_in(4))
- {
- whichm = MUT_HEAT_RESISTANCE;
- howm = 1;
- }
-
- if (one_chance_in(5))
- {
- whichm = MUT_ACUTE_VISION;
- howm = 1;
- }
-
- if (!you.skills[SK_POISON_MAGIC] && one_chance_in(7))
- {
- whichm = MUT_SPIT_POISON;
- howm = (you.experience_level < 10) ? 1 : 3;
- }
-
- if (one_chance_in(10))
- {
- whichm = MUT_MAPPING;
- howm = 3;
- }
-
- if (one_chance_in(12))
- {
- whichm = MUT_TELEPORT_CONTROL;
- howm = 1;
- }
-
- if (!you.mutation[MUT_THROW_FROST] // not with these
- && !you.mutation[MUT_THROW_FLAMES]
- && !you.mutation[MUT_BREATHE_FLAMES]
- && !you.skills[SK_FIRE_MAGIC] // or with fire already
- && one_chance_in(5))
- {
- whichm = MUT_BREATHE_FLAMES;
- howm = 2;
- }
-
- if (!you.skills[SK_TRANSLOCATIONS] && one_chance_in(12))
- {
- whichm = (you.experience_level < 10) ? MUT_BLINK
- : MUT_TELEPORT_AT_WILL;
- howm = 2;
- }
-
- if (scale_levels < 3 && one_chance_in( 1 + scale_levels * 5 ))
- {
- const int bonus = (you.experience_level < 10) ? 0 : 1;
- int levels = 0;
-
- if (one_chance_in(10))
- {
- whichm = MUT_TOUGH_SKIN;
- levels = (coinflip() ? 2 : 3);
- }
-
- if (one_chance_in(24))
- {
- whichm = MUT_GREEN_SCALES;
- levels = (coinflip() ? 2 : 3);
- }
-
- if (one_chance_in(24))
- {
- whichm = MUT_BLACK_SCALES;
- levels = (coinflip() ? 2 : 3);
- }
-
- if (one_chance_in(24))
- {
- whichm = MUT_GREY_SCALES;
- levels = (coinflip() ? 2 : 3);
- }
-
- if (one_chance_in(12))
- {
- whichm = MUT_RED_SCALES + random2(16);
-
- switch (whichm)
- {
- case MUT_RED_SCALES:
- case MUT_NACREOUS_SCALES:
- case MUT_BLACK2_SCALES:
- case MUT_WHITE_SCALES:
- case MUT_BLUE_SCALES:
- case MUT_SPECKLED_SCALES:
- case MUT_ORANGE_SCALES:
- case MUT_IRIDESCENT_SCALES:
- case MUT_PATTERNED_SCALES:
- levels = (coinflip() ? 2 : 3);
- break;
-
- default:
- levels = (coinflip() ? 1 : 2);
- break;
- }
- }
-
- if (one_chance_in(30))
- {
- whichm = MUT_BONEY_PLATES;
- levels = (coinflip() ? 1 : 2);
- }
-
- if (levels)
- howm = MINIMUM( 3 - scale_levels, levels + bonus );
- }
-
- if (one_chance_in(25))
- {
- whichm = MUT_REPULSION_FIELD;
- howm = (coinflip() ? 2 : 3);
- }
-
- if (one_chance_in( (you.experience_level < 10) ? 5 : 20 ))
- {
- whichm = MUT_HORNS;
- howm = (coinflip() ? 1 : 2);
-
- if (you.experience_level > 4 || one_chance_in(5))
- howm++;
- }
- }
-
- if (whichm != -1 && you.mutation[whichm] != 0)
- whichm = -1;
-
- counter++;
- }
- while (whichm == -1 && counter < 5000);
-
- if (whichm == -1 || !perma_mutate( whichm, howm ))
- {
- /* unlikely but remotely possible */
- /* I know this is a cop-out */
- modify_stat(STAT_STRENGTH, 1, true);
- modify_stat(STAT_INTELLIGENCE, 1, true);
- modify_stat(STAT_DEXTERITY, 1, true);
- mpr("You feel much better now.", MSGCH_INTRINSIC_GAIN);
- }
-} // end demonspawn()
-
-bool perma_mutate(int which_mut, char how_much)
-{
- char levels = 0;
-
- if (mutate(which_mut + 1000))
- levels++;
-
- if (how_much >= 2 && mutate(which_mut + 1000))
- levels++;
-
- if (how_much >= 3 && mutate(which_mut + 1000))
- levels++;
-
- you.demon_pow[which_mut] = levels;
-
- return (levels > 0);
-} // end perma_mutate()
-
-bool give_good_mutation(bool failMsg)
-{
- int temp_rand = 0; // probability determination {dlb}
- int which_good_one = 0;
-
- temp_rand = random2(25);
-
- which_good_one = ((temp_rand >= 24) ? MUT_TOUGH_SKIN :
- (temp_rand == 23) ? MUT_STRONG :
- (temp_rand == 22) ? MUT_CLEVER :
- (temp_rand == 21) ? MUT_AGILE :
- (temp_rand == 20) ? MUT_HEAT_RESISTANCE :
- (temp_rand == 19) ? MUT_COLD_RESISTANCE :
- (temp_rand == 18) ? MUT_SHOCK_RESISTANCE :
- (temp_rand == 17) ? MUT_REGENERATION :
- (temp_rand == 16) ? MUT_TELEPORT_CONTROL :
- (temp_rand == 15) ? MUT_MAGIC_RESISTANCE :
- (temp_rand == 14) ? MUT_FAST :
- (temp_rand == 13) ? MUT_ACUTE_VISION :
- (temp_rand == 12) ? MUT_GREEN_SCALES :
- (temp_rand == 11) ? MUT_BLACK_SCALES :
- (temp_rand == 10) ? MUT_GREY_SCALES :
- (temp_rand == 9) ? MUT_BONEY_PLATES :
- (temp_rand == 8) ? MUT_REPULSION_FIELD :
- (temp_rand == 7) ? MUT_POISON_RESISTANCE :
- (temp_rand == 6) ? MUT_TELEPORT_AT_WILL :
- (temp_rand == 5) ? MUT_SPIT_POISON :
- (temp_rand == 4) ? MUT_MAPPING :
- (temp_rand == 3) ? MUT_BREATHE_FLAMES :
- (temp_rand == 2) ? MUT_BLINK :
- (temp_rand == 1) ? MUT_CLARITY
- : MUT_ROBUST);
-
- return (mutate(which_good_one, failMsg));
-} // end give_good_mutation()
-
-bool give_bad_mutation(bool forceMutation, bool failMsg)
-{
- int temp_rand = 0; // probability determination {dlb}
- int which_bad_one = 0;
-
- temp_rand = random2(12);
-
- which_bad_one = ((temp_rand >= 11) ? MUT_CARNIVOROUS :
- (temp_rand == 10) ? MUT_HERBIVOROUS :
- (temp_rand == 9) ? MUT_FAST_METABOLISM :
- (temp_rand == 8) ? MUT_WEAK :
- (temp_rand == 7) ? MUT_DOPEY :
- (temp_rand == 6) ? MUT_CLUMSY :
- (temp_rand == 5) ? MUT_TELEPORT :
- (temp_rand == 4) ? MUT_DEFORMED :
- (temp_rand == 3) ? MUT_LOST :
- (temp_rand == 2) ? MUT_DETERIORATION :
- (temp_rand == 1) ? MUT_BLURRY_VISION
- : MUT_FRAIL);
-
- if (forceMutation)
- which_bad_one += 1000;
-
- return (mutate(which_bad_one), failMsg);
-} // end give_bad_mutation()
-
-//jmf: might be useful somewhere (eg Xom or transmigration effect)
-bool give_cosmetic_mutation()
-{
- int mutation = -1;
- int how_much = 0;
- int counter = 0;
-
- do
- {
- mutation = MUT_DEFORMED;
- how_much = 1 + random2(3);
-
- if (one_chance_in(6))
- {
- mutation = MUT_ROBUST;
- how_much = 1 + random2(3);
- }
-
- if (one_chance_in(6))
- {
- mutation = MUT_FRAIL;
- how_much = 1 + random2(3);
- }
-
- if (one_chance_in(5))
- {
- mutation = MUT_TOUGH_SKIN;
- how_much = 1 + random2(3);
- }
-
- if (one_chance_in(4))
- {
- mutation = MUT_CLAWS;
- how_much = 1 + random2(3);
- }
-
- if (you.species != SP_CENTAUR && you.species != SP_NAGA
- && you.species != SP_KENKU && !player_genus(GENPC_DRACONIAN)
- && one_chance_in(5))
- {
- mutation = MUT_HOOVES;
- how_much = 1;
- }
-
- if (player_genus(GENPC_DRACONIAN) && one_chance_in(5))
- {
- mutation = MUT_BIG_WINGS;
- how_much = 1;
- }
-
- if (one_chance_in(5))
- {
- mutation = MUT_CARNIVOROUS;
- how_much = 1 + random2(3);
- }
-
- if (one_chance_in(6))
- {
- mutation = MUT_HORNS;
- how_much = 1 + random2(3);
- }
-
- if ((you.species == SP_NAGA || player_genus(GENPC_DRACONIAN))
- && one_chance_in(4))
- {
- mutation = MUT_STINGER;
- how_much = 1 + random2(3);
- }
-
- if (you.species == SP_NAGA && one_chance_in(6))
- {
- mutation = MUT_BREATHE_POISON;
- how_much = 1;
- }
-
- if (!(you.species == SP_NAGA || player_genus(GENPC_DRACONIAN))
- && one_chance_in(7))
- {
- mutation = MUT_SPIT_POISON;
- how_much = 1;
- }
-
- if (!(you.species == SP_NAGA || player_genus(GENPC_DRACONIAN))
- && one_chance_in(8))
- {
- mutation = MUT_BREATHE_FLAMES;
- how_much = 1 + random2(3);
- }
-
- if (you.mutation[mutation] > 0)
- how_much -= you.mutation[mutation];
-
- if (how_much < 0)
- how_much = 0;
- }
- while (how_much == 0 && counter++ < 5000);
-
- if (how_much != 0)
- return mutate(mutation);
- else
- return false;
-} // end give_cosmetic_mutation()
diff --git a/stone_soup/crawl-ref/source/mutation.h b/stone_soup/crawl-ref/source/mutation.h
deleted file mode 100644
index 76d821f2c4..0000000000
--- a/stone_soup/crawl-ref/source/mutation.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * File: mutation.cc
- * Summary: Functions for handling player mutations.
- * Written by: Linley Henzell
- *
- * Modified for Crawl Reference by $Author$ on $Date$
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef MUTATION_H
-#define MUTATION_H
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - decks - effects - fight - food - it_use2 - items -
- * mutation - religion - spell - spells
- * *********************************************************************** */
-bool mutate(int which_mutation, bool failMsg = true);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void display_mutations(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: decks - it_use2 - mutation - spells
- * *********************************************************************** */
-bool delete_mutation(int which_mutation);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: chardump
- * *********************************************************************** */
-// default of level == -1, means to use the player's current level
-const char *mutation_name( int which_mutat, int level = -1 );
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: religion
- * *********************************************************************** */
-bool give_good_mutation( bool failMsg = true );
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: items - religion
- * *********************************************************************** */
-bool give_cosmetic_mutation( void );
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: items - spells
- * *********************************************************************** */
-bool give_bad_mutation( bool forceMutation = false, bool failMsg = true );
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: player
- * *********************************************************************** */
-void demonspawn(void);
-
-
-#endif
diff --git a/stone_soup/crawl-ref/source/newgame.cc b/stone_soup/crawl-ref/source/newgame.cc
deleted file mode 100644
index 3a4a4e7a3d..0000000000
--- a/stone_soup/crawl-ref/source/newgame.cc
+++ /dev/null
@@ -1,4849 +0,0 @@
-/*
- * File: newgame.cc
- * Summary: Functions used when starting a new game.
- * Written by: Linley Henzell
- *
- * Modified for Crawl Reference by $Author$ on $Date$
- *
- * Change History (most recent first):
- *
- * <16> 19-Jun-2000 GDL changed handle to FILE *
- * <15> 06-Mar-2000 bwr changes to berserer, paladin, enchanter
- * <14> 10-Jan-2000 DLB class_allowed() lists excluded
- * species for all but hunters
- * some clean-up of init_player()
- * <13> 1/10/2000 BCR Made ogre berserkers get club
- * skill, Trolls get unarmed skill
- * Halflings can be assasins and
- * warpers
- * <12> 12/4/99 jmf Gave Paladins more armour skill + a
- * long sword (to compensate for
- * their inability to use poison).
- * Allowed Spriggan Stalkers (since
- * that's basically just a venom mage
- * + assassin, both of which are now
- * legal).
- * <11> 11/22/99 LRH Er, re-un-capitalised class
- * names (makes them distinguish-
- * able in score list)
- * <10> 10/31/99 CDL Allow Spriggan Assassins
- * Remove some old comments
- * <9> 10/12/99 BCR Made sure all the classes are
- * capitalized correctly.
- * <8> 9/09/99 BWR Changed character selection
- * screens look (added sub-species
- * menus from Dustin Ragan)
- * <7> 7/13/99 BWR Changed assassins to use
- * hand crossbows, changed
- * rangers into hunters.
- * <6> 6/22/99 BWR Added new rangers/slingers
- * <5> 6/17/99 BCR Removed some Linux/Mac filename
- * weirdness
- * <4> 6/13/99 BWR SysEnv support
- * <3> 6/11/99 DML Removed tmpfile purging.
- * <2> 5/20/99 BWR CRAWL_NAME, new berserk, upped
- * troll food consumption, added
- * demonspawn transmuters.
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "newgame.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <time.h>
-
-#ifdef DOS
-#include <conio.h>
-#endif
-
-#ifdef UNIX
-#include <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
-#endif
-
-#ifdef USE_EMX
-#include <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
-#endif
-
-#ifdef OS9
-#include <stat.h>
-#else
-#include <sys/stat.h>
-#endif
-
-#include "externs.h"
-
-#include "abl-show.h"
-#include "dungeon.h"
-#include "files.h"
-#include "fight.h"
-#include "initfile.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "items.h"
-#include "macro.h"
-#include "player.h"
-#include "randart.h"
-#include "skills.h"
-#include "skills2.h"
-#include "spl-util.h"
-#include "stuff.h"
-#include "version.h"
-#include "wpn-misc.h"
-
-
-#define MIN_START_STAT 1
-
-bool class_allowed(unsigned char speci, int char_class);
-bool verifyPlayerName(void);
-void choose_weapon(void);
-void enterPlayerName(bool blankOK);
-void give_basic_knowledge(int which_job);
-void give_basic_spells(int which_job);
-void give_last_paycheck(int which_job);
-void init_player(void);
-void jobs_stat_init(int which_job);
-void openingScreen(void);
-void species_stat_init(unsigned char which_species);
-
-#if 0
-// currently unused -- bwr
-static void give_random_wand( int slot );
-static void give_random_scroll( int slot );
-#endif
-
-static void give_random_potion( int slot );
-static void give_random_secondary_armour( int slot );
-static bool give_wanderer_weapon( int slot, int wpn_skill );
-static void create_wanderer(void);
-static void give_items_skills(void);
-static bool choose_race(void);
-static bool choose_class(void);
-static char letter_to_species(int keyn);
-static char letter_to_class(int keyn);
-
-////////////////////////////////////////////////////////////////////////
-// Remember player's startup options
-//
-
-static char ng_race, ng_cls;
-static bool ng_random;
-static int ng_ck, ng_dk, ng_pr;
-static int ng_weapon;
-
-static void reset_newgame_options(void)
-{
- ng_race = ng_cls = 0;
- ng_random = false;
- ng_ck = GOD_NO_GOD;
- ng_dk = DK_NO_SELECTION;
- ng_pr = GOD_NO_GOD;
- ng_weapon = WPN_UNKNOWN;
-}
-
-static void save_newgame_options(void)
-{
- // Note that we store race and class directly here, whereas up until
- // now we've been storing the hotkey.
- Options.prev_race = ng_race;
- Options.prev_cls = ng_cls;
- Options.prev_randpick = ng_random;
- Options.prev_ck = ng_ck;
- Options.prev_dk = ng_dk;
- Options.prev_pr = ng_pr;
- Options.prev_weapon = ng_weapon;
-
- write_newgame_options_file();
-}
-
-static void set_startup_options(void)
-{
- Options.race = Options.prev_race;
- Options.cls = Options.prev_cls;
- Options.weapon = Options.prev_weapon;
- Options.death_knight = Options.prev_dk;
- Options.chaos_knight = Options.prev_ck;
- Options.priest = Options.prev_pr;
-}
-
-static bool prev_startup_options_set(void)
-{
- // Are these two enough? They should be, in theory, since we'll
- // remember the player's weapon and god choices.
- return Options.prev_race && Options.prev_cls;
-}
-
-static std::string get_opt_race_name(char race)
-{
- int prace = letter_to_species(race);
- return prace? species_name(prace, 1) : "Random";
-}
-
-static std::string get_opt_class_name(char oclass)
-{
- int pcls = letter_to_class(oclass);
- return pcls != JOB_UNKNOWN? get_class_name(pcls) : "Random";
-}
-
-static std::string prev_startup_description(void)
-{
- if (Options.prev_race == '?' && Options.prev_cls == '?')
- Options.prev_randpick = true;
-
- if (Options.prev_randpick)
- return "Random character";
-
- if (Options.prev_cls == '?')
- return "Random " + get_opt_race_name(Options.prev_race);
- return get_opt_race_name(Options.prev_race) + " " +
- get_opt_class_name(Options.prev_cls);
-}
-
-int give_first_conjuration_book()
-{
- // Assume the fire/earth book, as conjurations is strong with fire -- bwr
- int book = BOOK_CONJURATIONS_I;
-
- // Conjuration books are largely Fire or Ice, so we'll use
- // that as the primary condition, and air/earth to break ties. -- bwr
- if (you.skills[SK_ICE_MAGIC] > you.skills[SK_FIRE_MAGIC]
- || (you.skills[SK_FIRE_MAGIC] == you.skills[SK_ICE_MAGIC]
- && you.skills[SK_AIR_MAGIC] > you.skills[SK_EARTH_MAGIC]))
- {
- book = BOOK_CONJURATIONS_II;
- }
- else if (you.skills[SK_FIRE_MAGIC] == 0 && you.skills[SK_EARTH_MAGIC] == 0)
- {
- // If we're here its because we were going to default to the
- // fire/earth book... but we don't have those skills. So we
- // choose randomly based on the species weighting, again
- // ignoring air/earth which are secondary in these books. -- bwr
- if (random2( species_skills( SK_ICE_MAGIC, you.species ) )
- < random2( species_skills( SK_FIRE_MAGIC, you.species ) ))
- {
- book = BOOK_CONJURATIONS_II;
- }
- }
-
- return (book);
-}
-
-static void pick_random_species_and_class( void )
-{
- //
- // We pick both species and class at the same time to give each
- // valid possibility a fair chance. For proof that this will
- // work correctly see the proof in religion.cc:handle_god_time().
- //
- int job_count = 0;
-
- int species = -1;
- int job = -1;
-
- // for each valid (species, class) choose one randomly
- for (int sp = SP_HUMAN; sp < NUM_SPECIES; sp++)
- {
- // we only want draconians counted once in this loop...
- // we'll add the variety lower down -- bwr
- if (sp >= SP_WHITE_DRACONIAN && sp <= SP_BASE_DRACONIAN)
- continue;
-
- for (int cl = JOB_FIGHTER; cl < NUM_JOBS; cl++)
- {
- if (class_allowed(sp, cl))
- {
- job_count++;
- if (one_chance_in( job_count ))
- {
- species = sp;
- job = cl;
- }
- }
- }
- }
-
- // at least one job must exist in the game else we're in big trouble
- ASSERT( species != -1 && job != -1 );
-
- // return draconian variety here
- if (species == SP_RED_DRACONIAN)
- you.species = SP_RED_DRACONIAN + random2(9);
- else
- you.species = species;
-
- you.char_class = job;
-}
-
-static bool check_saved_game(void)
-{
- FILE *handle;
- char char_fil[kFileNameSize];
-
-#ifdef LOAD_UNPACKAGE_CMD
- // Create the file name base
- char name_buff[kFileNameLen];
-
- snprintf( name_buff, sizeof(name_buff),
- SAVE_DIR_PATH "%s%d", you.your_name, (int) getuid() );
-
- char zip_buff[kFileNameLen];
-
- strcpy(zip_buff, name_buff);
- strcat(zip_buff, PACKAGE_SUFFIX);
-
- // Create save dir name
- strcpy(char_fil, name_buff);
- strcat(char_fil, ".sav");
-
- handle = fopen(zip_buff, "rb+");
- if (handle != NULL)
- {
- cprintf(EOL "Loading game..." EOL);
-
- // Create command
- char cmd_buff[1024];
-
- snprintf( cmd_buff, sizeof(cmd_buff), LOAD_UNPACKAGE_CMD, name_buff );
-
- if (system( cmd_buff ) != 0)
- {
- cprintf( EOL "Warning: Zip command (LOAD_UNPACKAGE_CMD) returned non-zero value!" EOL );
- }
-
- fclose(handle);
-
- // Remove save game package
- unlink(zip_buff);
- }
- else
- {
-#ifdef DO_ANTICHEAT_CHECKS
- // Simple security patch -- must have zip file otherwise invalidate
- // the character. Right now this just renames the .sav file to
- // .bak, allowing anyone with the appropriate permissions to
- // fix a character in the case of a bug. This could be changed
- // to unlinking the file(s) which would remove the character.
- strcat(name_buff, ".bak");
- rename(char_fil, name_buff);
-#endif
- }
-
-#else
- strcpy(char_fil, "");
- strncat(char_fil, you.your_name, kFileNameLen);
- strcat(char_fil, ".sav");
-#endif
-
- handle = fopen(char_fil, "rb+");
-
- if (handle != NULL)
- {
- fclose(handle);
- return true;
- }
- return false;
-}
-
-bool new_game(void)
-{
- int i, j; // loop variables {dlb}
-
- //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();
-
- you.exp_available = 25; // now why is this all the way up here? {dlb}
-
- textcolor(LIGHTGREY);
-
- // 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';
- }
-
- openingScreen();
- enterPlayerName(true);
-
- if (you.your_name[0] != '\0')
- {
- if (check_saved_game())
- {
- textcolor( BROWN );
- cprintf( EOL "Welcome back, " );
- textcolor( YELLOW );
- cprintf( you.your_name );
- cprintf( "!" );
- textcolor( LIGHTGREY );
-
- save_player_name();
- return (false);
- }
- }
-
- reset_newgame_options();
- if (Options.random_pick)
- {
- pick_random_species_and_class();
- ng_random = true;
- }
- else
- {
- while (choose_race() && !choose_class());
- }
-
- strcpy( you.class_name, get_class_name( you.char_class ) );
-
- // new: pick name _after_ race and class choices
- if (you.your_name[0] == '\0')
- {
- 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 );
-
- cprintf( info );
-
- enterPlayerName(false);
-
- 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(you.your_name);
- cprintf("!");
- textcolor( LIGHTGREY );
-
- return (false);
- }
- }
- }
-
-
-// ************ round-out character statistics and such ************
-
- species_stat_init( you.species ); // must be down here {dlb}
-
- you.is_undead = ((you.species == SP_MUMMY) ? US_UNDEAD :
- (you.species == SP_GHOUL) ? US_HUNGRY_DEAD : US_ALIVE);
-
- // 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;
-
- jobs_stat_init( you.char_class );
- give_last_paycheck( you.char_class );
-
- // 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;
-
- // first spend points to get us to the minimum allowed value -- bwr
- if (you.strength < MIN_START_STAT)
- {
- points_left -= (MIN_START_STAT - you.strength);
- you.strength = MIN_START_STAT;
- }
-
- if (you.intel < MIN_START_STAT)
- {
- points_left -= (MIN_START_STAT - you.intel);
- you.intel = MIN_START_STAT;
- }
-
- if (you.dex < MIN_START_STAT)
- {
- points_left -= (MIN_START_STAT - you.dex);
- you.dex = MIN_START_STAT;
- }
-
- // now randomly assign the remaining points --bwr
- while (points_left > 0)
- {
- switch (random2( NUM_STATS ))
- {
- case STAT_STRENGTH:
- if (you.strength > 17 && coinflip())
- continue;
-
- you.strength++;
- break;
-
- case STAT_DEXTERITY:
- if (you.dex > 17 && coinflip())
- continue;
-
- you.dex++;
- break;
-
- case STAT_INTELLIGENCE:
- if (you.intel > 17 && coinflip())
- continue;
-
- you.intel++;
- break;
- }
-
- points_left--;
- }
-
- // this function depends on stats being finalized
- give_items_skills();
-
- // then: adjust hp_max by species {dlb}
- if (player_genus(GENPC_DRACONIAN) || player_genus(GENPC_DWARVEN))
- inc_max_hp(1);
- else
- {
- switch (you.species)
- {
- case SP_CENTAUR:
- case SP_OGRE:
- case SP_TROLL:
- inc_max_hp(3);
- break;
-
- case SP_GHOUL:
- case SP_MINOTAUR:
- case SP_NAGA:
- case SP_OGRE_MAGE:
- case SP_DEMIGOD:
- inc_max_hp(2);
- break;
-
- case SP_HILL_ORC:
- case SP_MUMMY:
- case SP_MERFOLK:
- inc_max_hp(1);
- break;
-
- case SP_ELF:
- case SP_GREY_ELF:
- case SP_HIGH_ELF:
- dec_max_hp(1);
- break;
-
- case SP_DEEP_ELF:
- case SP_GNOME:
- case SP_HALFLING:
- case SP_KENKU:
- case SP_KOBOLD:
- case SP_SPRIGGAN:
- dec_max_hp(2);
- break;
-
- default:
- break;
- }
- }
-
- // then: adjust max_magic_points by species {dlb}
- switch (you.species)
- {
- case SP_SPRIGGAN:
- case SP_DEMIGOD:
- case SP_GREY_ELF:
- case SP_DEEP_ELF:
- inc_max_mp(1);
- break;
-
- 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;
-
- if (!you.is_undead)
- {
- for (i = 0; i < ENDOFPACK; i++)
- {
- if (!you.inv[i].quantity)
- {
- you.inv[i].quantity = 1;
- you.inv[i].base_type = OBJ_FOOD;
- you.inv[i].sub_type = FOOD_BREAD_RATION;
-
- 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;
- }
-
- you.inv[i].colour = BROWN;
- break;
- }
- }
- }
-
- for (i = 0; i < ENDOFPACK; i++)
- {
- if (you.inv[i].quantity)
- {
- 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 );
- if (you.inv[i].colour == LIGHTCYAN)
- you.inv[i].colour = CYAN;
- break;
-
- case SP_HILL_ORC:
- set_equip_race( you.inv[i], ISFLAG_ORCISH );
- break;
- }
- }
- }
- }
-
- // must remember to check for already existing colours/combinations
- for (i = 0; i < 4; i++)
- {
- for (j = 0; j < 50; j++)
- {
- you.item_description[i][j] = 255;
- }
- }
-
- you.item_description[IDESC_POTIONS][POT_PORRIDGE] = 153; // "gluggy white"
- you.item_description[IDESC_POTIONS][POT_WATER] = 0; // "clear"
-
- int passout;
-
- for (i = 0; i < 4; i++)
- {
- for (j = 0; j < 50; j++)
- {
- if (you.item_description[i][j] != 255)
- continue;
-
- do
- {
- passout = 1;
-
- switch (i)
- {
- case IDESC_WANDS: // wands
- you.item_description[i][j] = random2( 16 * 12 );
- if (coinflip())
- you.item_description[i][j] %= 12;
- break;
-
- case IDESC_POTIONS: // potions
- you.item_description[i][j] = random2( 15 * 14 );
- if (coinflip())
- you.item_description[i][j] %= 14;
- break;
-
- case IDESC_SCROLLS: // scrolls
- you.item_description[i][j] = random2(151);
- you.item_description[IDESC_SCROLLS_II][j] = random2(151);
- break;
-
- case IDESC_RINGS: // rings
- you.item_description[i][j] = random2( 13 * 13 );
- if (coinflip())
- you.item_description[i][j] %= 13;
- break;
- }
-
- // 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;
- }
- }
- }
- 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 );
-
- you.skill_points[i] = points + 1;
-
- 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;
-
- // ...and find out what level that earns this character.
- const int sp_diff = species_skills( i, you.species );
- you.skills[i] = 0;
-
- 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;
- }
- }
-
- calc_total_skill_points();
-
- for (i = 0; i < ENDOFPACK; i++)
- {
- if (you.inv[i].base_type != OBJ_WEAPONS)
- {
- set_ident_type( you.inv[i].base_type,
- you.inv[i].sub_type, ID_KNOWN_TYPE );
- }
-
- if (you.inv[i].base_type == OBJ_POTIONS
- || you.inv[i].base_type == OBJ_WANDS
- || you.inv[i].base_type == OBJ_JEWELLERY)
- {
- item_colour( you.inv[i] ); // set correct special and colour
- }
-
- if (is_valid_item(you.inv[i]))
- {
- you.inv[i].slot = index_to_letter(you.inv[i].link);
- }
- }
- // Brand items as original equipment.
- origin_set_inventory(origin_set_startequip);
-
- // we calculate hp and mp here; all relevant factors should be
- // finalized by now (GDL)
- calc_hp();
- calc_mp();
-
- // make sure the starting player is fully charged up
- set_hp( you.hp_max, false );
- set_mp( you.max_magic_points, false );
-
- give_basic_spells(you.char_class);
- 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 < MAX_BRANCHES; dng++)
- {
- tmp_file_pairs[lvl][dng] = false;
- }
- }
-
- // places staircases to the branch levels:
- for (i = 0; i < 30; i++)
- {
- you.branch_stairs[i] = 100;
- }
-
- you.branch_stairs[STAIRS_ECUMENICAL_TEMPLE] = 3 + random2(4); // avg: 4.5
-
- you.branch_stairs[STAIRS_ORCISH_MINES] = 5 + random2(6); // avg: 7.5
-
- you.branch_stairs[STAIRS_ELVEN_HALLS] =
- you.branch_stairs[STAIRS_ORCISH_MINES] + (coinflip() ? 4 : 3); // 11.0
-
- you.branch_stairs[STAIRS_LAIR] = 7 + random2(6); // avg: 9.5
-
- you.branch_stairs[STAIRS_HIVE] = 10 + random2(6); // avg: 12.5
-
- you.branch_stairs[STAIRS_SLIME_PITS] =
- you.branch_stairs[STAIRS_LAIR] + 3 + random2(4); // avg: 14.0
-
- you.branch_stairs[STAIRS_SWAMP] =
- you.branch_stairs[STAIRS_LAIR] + 2 + random2(6); // avg: 14.0
-
- you.branch_stairs[STAIRS_SNAKE_PIT] =
- you.branch_stairs[STAIRS_LAIR] + (coinflip() ? 7 : 6); // avg: 16.0
-
- you.branch_stairs[STAIRS_VAULTS] = 13 + random2(6); // avg: 15.5
-
- you.branch_stairs[STAIRS_CRYPT] =
- you.branch_stairs[STAIRS_VAULTS] + 2 + random2(3); // avg: 18.5
-
- you.branch_stairs[STAIRS_HALL_OF_BLADES] =
- you.branch_stairs[STAIRS_VAULTS] + 4; // avg: 19.5
-
- you.branch_stairs[STAIRS_TOMB] =
- you.branch_stairs[STAIRS_CRYPT] + ((coinflip()) ? 3 : 2); // avg: 20.0
-
- you.branch_stairs[STAIRS_HALL_OF_ZOT] = 26; // always 26
-
- save_newgame_options();
- return (true);
-} // end of new_game()
-
-static bool species_is_undead( unsigned char speci )
-{
- return (speci == SP_MUMMY || speci == SP_GHOUL);
-}
-
-bool class_allowed( unsigned char speci, int char_class )
-{
- switch (char_class)
- {
- case JOB_FIGHTER:
- switch (speci)
- {
- case SP_OGRE_MAGE:
- case SP_SPRIGGAN:
- return false;
- }
- return true;
-
- case JOB_WIZARD:
- if (species_is_undead( speci ))
- return false;
-
- switch (speci)
- {
- case SP_GNOME:
- case SP_HALFLING:
- case SP_HILL_DWARF:
- case SP_HILL_ORC:
- case SP_KENKU:
- case SP_KOBOLD:
- case SP_MINOTAUR:
- case SP_OGRE:
- case SP_SPRIGGAN:
- case SP_TROLL:
- return false;
- }
- return true;
-
- case JOB_PRIEST:
- if (player_genus(GENPC_DRACONIAN, speci))
- return false;
- if (species_is_undead( speci ))
- return false;
-
- switch (speci)
- {
- case SP_CENTAUR:
- case SP_DEMIGOD:
- case SP_DEMONSPAWN:
- case SP_GNOME:
- case SP_HALFLING:
- case SP_KENKU:
- case SP_KOBOLD:
- case SP_MINOTAUR:
- case SP_NAGA:
- case SP_OGRE:
- case SP_OGRE_MAGE:
- case SP_SPRIGGAN:
- case SP_TROLL:
- return false;
- }
- return true;
-
- case JOB_THIEF:
- if (species_is_undead( speci ))
- return false;
-
- switch (speci)
- {
- case SP_CENTAUR:
- case SP_KENKU:
- case SP_MINOTAUR:
- case SP_OGRE:
- case SP_OGRE_MAGE:
- case SP_SPRIGGAN:
- case SP_TROLL:
- return false;
- }
- return true;
-
- case JOB_GLADIATOR:
- if (player_genus(GENPC_ELVEN, speci))
- return false;
- if (species_is_undead( speci ))
- return false;
-
- switch (speci)
- {
- case SP_GNOME:
- case SP_HALFLING:
- case SP_KOBOLD:
- case SP_NAGA:
- case SP_OGRE:
- case SP_OGRE_MAGE:
- case SP_SPRIGGAN:
- case SP_TROLL:
- return false;
- }
- return true;
-
- case JOB_NECROMANCER:
- if (player_genus(GENPC_DWARVEN, speci))
- return false;
- if (player_genus(GENPC_DRACONIAN, speci))
- return false;
-
- switch (speci)
- {
- case SP_CENTAUR:
- case SP_ELF:
- case SP_GHOUL:
- case SP_GNOME:
- case SP_GREY_ELF:
- case SP_HALFLING:
- case SP_HIGH_ELF:
- case SP_MINOTAUR:
- case SP_OGRE:
- case SP_SPRIGGAN:
- case SP_TROLL:
- case SP_MERFOLK:
- return false;
- }
- return true;
-
- case JOB_PALADIN:
- switch (speci)
- {
- case SP_HUMAN:
- case SP_MOUNTAIN_DWARF:
- case SP_HIGH_ELF:
- return true;
- }
- return false;
-
- case JOB_ASSASSIN:
- if (player_genus(GENPC_DWARVEN, speci))
- return false;
- if (player_genus(GENPC_DRACONIAN, speci))
- return false;
-
- switch (speci)
- {
- case SP_CENTAUR:
- case SP_GHOUL:
- case SP_GNOME:
- case SP_MINOTAUR:
- case SP_OGRE:
- case SP_OGRE_MAGE:
- case SP_TROLL:
- return false;
- }
- return true;
-
- case JOB_BERSERKER:
- if (player_genus(GENPC_ELVEN, speci))
- return false;
- if (player_genus(GENPC_DRACONIAN, speci))
- return false;
- if (species_is_undead( speci ))
- return false;
-
- switch (speci)
- {
- case SP_DEMIGOD:
- case SP_GNOME:
- case SP_HALFLING:
- case SP_KENKU:
- case SP_KOBOLD:
- case SP_MOUNTAIN_DWARF:
- case SP_NAGA:
- case SP_OGRE_MAGE:
- case SP_SPRIGGAN:
- case SP_MERFOLK:
- return false;
- }
- return true;
-
- case JOB_HUNTER:
- if (player_genus(GENPC_DRACONIAN, speci)) // use bows
- return true;
- if (player_genus(GENPC_DWARVEN, speci)) // use xbows
- return true;
-
- switch (speci)
- {
- // bows --
- case SP_CENTAUR:
- case SP_DEMIGOD:
- case SP_DEMONSPAWN:
- case SP_ELF:
- case SP_GREY_ELF:
- case SP_HIGH_ELF:
- case SP_HUMAN:
- case SP_KENKU:
- case SP_MINOTAUR:
- case SP_NAGA:
- case SP_SLUDGE_ELF:
- // xbows --
- case SP_HILL_ORC:
- // slings --
- case SP_GNOME:
- case SP_HALFLING:
- // spear
- case SP_MERFOLK:
- return true;
- }
- return false;
-
- case JOB_CONJURER:
- if (species_is_undead( speci ))
- return false;
-
- switch (speci)
- {
- case SP_CENTAUR:
- case SP_GNOME:
- case SP_HALFLING:
- case SP_KOBOLD:
- case SP_MINOTAUR:
- case SP_OGRE:
- case SP_SPRIGGAN:
- case SP_TROLL:
- case SP_MERFOLK:
- case SP_SLUDGE_ELF:
- return false;
- }
- return true;
-
- case JOB_ENCHANTER:
- if (player_genus(GENPC_DRACONIAN, speci))
- return false;
- if (species_is_undead( speci ))
- return false;
-
- switch (speci)
- {
- case SP_GNOME:
- case SP_HILL_ORC:
- case SP_KENKU:
- case SP_KOBOLD:
- case SP_MINOTAUR:
- case SP_OGRE:
- case SP_TROLL:
- case SP_SLUDGE_ELF:
- return false;
- }
- return true;
-
- case JOB_FIRE_ELEMENTALIST:
- if (player_genus(GENPC_DRACONIAN, speci))
- return false;
- if (species_is_undead( speci ))
- return false;
-
- switch (speci)
- {
- case SP_GNOME:
- case SP_GREY_ELF:
- case SP_HALFLING:
- case SP_KOBOLD:
- case SP_MINOTAUR:
- case SP_NAGA:
- case SP_OGRE:
- case SP_SPRIGGAN:
- case SP_TROLL:
- case SP_MERFOLK:
- return false;
- }
- return true;
-
- case JOB_ICE_ELEMENTALIST:
- if (player_genus(GENPC_DWARVEN, speci))
- return false;
- if (player_genus(GENPC_DRACONIAN, speci))
- return false;
- if (species_is_undead( speci ))
- return false;
-
- switch (speci)
- {
- case SP_GNOME:
- case SP_GREY_ELF:
- case SP_HALFLING:
- case SP_HILL_ORC:
- case SP_KENKU:
- case SP_KOBOLD:
- case SP_MINOTAUR:
- case SP_NAGA:
- case SP_OGRE:
- case SP_SPRIGGAN:
- case SP_TROLL:
- return false;
- }
- return true;
-
- case JOB_SUMMONER:
- if (player_genus(GENPC_DWARVEN, speci))
- return false;
- if (species_is_undead( speci ))
- return false;
-
- switch (speci)
- {
- case SP_CENTAUR:
- case SP_GNOME:
- case SP_HALFLING:
- case SP_MINOTAUR:
- case SP_OGRE:
- case SP_SPRIGGAN:
- case SP_TROLL:
- return false;
- }
- return true;
-
- case JOB_AIR_ELEMENTALIST:
- if (player_genus(GENPC_DWARVEN, speci))
- return false;
- if (player_genus(GENPC_DRACONIAN, speci))
- return false;
- if (species_is_undead( speci ))
- return false;
-
- switch (speci)
- {
- case SP_GNOME:
- case SP_HALFLING:
- case SP_HILL_ORC:
- case SP_KOBOLD:
- case SP_MINOTAUR:
- case SP_NAGA:
- case SP_OGRE:
- case SP_SPRIGGAN:
- case SP_TROLL:
- case SP_MERFOLK:
- return false;
- }
- return true;
-
- case JOB_EARTH_ELEMENTALIST:
- if (player_genus(GENPC_DRACONIAN, speci))
- return false;
- if (species_is_undead( speci ))
- return false;
-
- switch (speci)
- {
- case SP_ELF:
- case SP_GREY_ELF:
- case SP_HALFLING:
- case SP_HIGH_ELF:
- case SP_KENKU:
- case SP_KOBOLD:
- case SP_MINOTAUR:
- case SP_NAGA:
- case SP_OGRE:
- case SP_SPRIGGAN:
- case SP_TROLL:
- case SP_MERFOLK:
- return false;
- }
- return true;
-
- case JOB_CRUSADER:
- if (player_genus(GENPC_DWARVEN, speci))
- return false;
- if (species_is_undead( speci ))
- return false;
- if (player_genus(GENPC_DRACONIAN, speci))
- return false;
-
- switch (speci)
- {
- case SP_GNOME:
- //case SP_HALFLING: //jmf: they're such good enchanters...
- case SP_KENKU:
- case SP_KOBOLD:
- case SP_MINOTAUR:
- case SP_NAGA:
- case SP_OGRE:
- case SP_SPRIGGAN:
- case SP_TROLL:
- case SP_MERFOLK:
- case SP_SLUDGE_ELF:
- return false;
- }
- return true;
-
- case JOB_DEATH_KNIGHT:
- if (player_genus(GENPC_DWARVEN, speci))
- return false;
-
- switch (speci)
- {
- case SP_ELF:
- case SP_GHOUL:
- case SP_GNOME:
- case SP_GREY_ELF:
- case SP_HALFLING:
- case SP_HIGH_ELF:
- // case SP_KOBOLD:
- case SP_MINOTAUR:
- case SP_OGRE:
- case SP_OGRE_MAGE:
- case SP_SPRIGGAN:
- case SP_TROLL:
- case SP_MERFOLK:
- return false;
- }
- return true;
-
- case JOB_VENOM_MAGE:
- if (player_genus(GENPC_DWARVEN, speci))
- return false;
- if (species_is_undead( speci ))
- return false;
-
- switch (speci)
- {
- case SP_CENTAUR:
- case SP_ELF:
- case SP_GNOME:
- case SP_GREY_ELF:
- case SP_HALFLING:
- case SP_HIGH_ELF:
- case SP_MINOTAUR:
- case SP_OGRE:
- case SP_TROLL:
- return false;
- }
- return true;
-
- case JOB_CHAOS_KNIGHT:
- if (player_genus(GENPC_DWARVEN, speci))
- return false;
- if (species_is_undead( speci ))
- return false;
-
- switch (speci)
- {
- case SP_DEMIGOD:
- case SP_GNOME:
- case SP_GREY_ELF:
- case SP_HALFLING:
- case SP_KENKU:
- case SP_OGRE:
- case SP_OGRE_MAGE:
- case SP_SPRIGGAN:
- case SP_TROLL:
- case SP_MERFOLK:
- return false;
- }
- return true;
-
- case JOB_TRANSMUTER:
- if (species_is_undead( speci ))
- return false;
-
- switch (speci)
- {
- case SP_HALFLING:
- case SP_HILL_DWARF:
- case SP_HILL_ORC:
- case SP_KENKU:
- case SP_MINOTAUR:
- case SP_OGRE:
- case SP_TROLL:
- return false;
- }
- return true;
-
- case JOB_HEALER:
- if (player_genus(GENPC_DRACONIAN, speci))
- return false;
- if (species_is_undead( speci ))
- return false;
-
- switch (speci)
- {
- case SP_DEMIGOD:
- case SP_DEMONSPAWN:
- case SP_GNOME:
- case SP_HALFLING:
- case SP_KENKU:
- case SP_KOBOLD:
- case SP_MINOTAUR:
- case SP_NAGA:
- case SP_OGRE:
- case SP_OGRE_MAGE:
- case SP_SPRIGGAN:
- case SP_TROLL:
- return false;
- }
- return true;
-
- case JOB_REAVER:
- if (species_is_undead( speci ))
- return false;
-
- switch (speci)
- {
- case SP_GNOME:
- case SP_GREY_ELF:
- case SP_HALFLING:
- case SP_HILL_DWARF:
- case SP_MINOTAUR:
- case SP_MOUNTAIN_DWARF:
- case SP_OGRE:
- case SP_OGRE_MAGE:
- case SP_SPRIGGAN:
- case SP_TROLL:
- case SP_MERFOLK:
- case SP_SLUDGE_ELF:
- return false;
- }
- return true;
-
- case JOB_STALKER:
- if (player_genus(GENPC_DWARVEN, speci))
- return false;
- if (player_genus(GENPC_DRACONIAN, speci))
- return false;
- if (species_is_undead( speci ))
- return false;
-
- switch (speci)
- {
- case SP_CENTAUR:
- case SP_GNOME:
- case SP_HALFLING:
- case SP_MINOTAUR:
- case SP_OGRE:
- case SP_OGRE_MAGE:
- case SP_TROLL:
- return false;
- }
- return true;
-
- case JOB_MONK:
- if (species_is_undead( speci ))
- return false;
-
- switch (speci)
- {
- case SP_CENTAUR:
- case SP_GNOME:
- case SP_HILL_DWARF:
- case SP_KOBOLD:
- case SP_NAGA:
- case SP_OGRE:
- case SP_OGRE_MAGE:
- case SP_SPRIGGAN:
- case SP_TROLL:
- return false;
- }
- return true;
-
- case JOB_WARPER:
- if (player_genus(GENPC_DWARVEN, speci))
- return false;
- if (player_genus(GENPC_DRACONIAN, speci))
- return false;
- if (species_is_undead( speci ))
- return false;
-
- switch (speci)
- {
- case SP_CENTAUR:
- case SP_GNOME:
- case SP_HILL_ORC:
- case SP_HALFLING:
- case SP_KENKU:
- case SP_MINOTAUR:
- case SP_OGRE:
- case SP_TROLL:
- case SP_MERFOLK:
- return false;
- }
- return true;
-
- case JOB_WANDERER:
- switch (speci)
- {
- case SP_HUMAN:
- case SP_DEMIGOD:
- case SP_DEMONSPAWN:
- case SP_GHOUL:
- return true;
- }
- return false;
-
- case JOB_QUITTER: // shouldn't happen since 'x' is handled specially
- default:
- return false;
- }
-} // end class_allowed()
-
-static char startwep[5] = { WPN_SHORT_SWORD, WPN_MACE,
- WPN_HAND_AXE, WPN_SPEAR, WPN_TRIDENT };
-
-void choose_weapon( void )
-{
- char wepName[ ITEMNAME_SIZE ];
- unsigned char keyin = 0;
- int num_choices = 4;
- int temp_rand; // probability determination {dlb}
-
- if (you.char_class == JOB_CHAOS_KNIGHT)
- {
- temp_rand = random2(4);
-
- you.inv[0].sub_type = ((temp_rand == 0) ? WPN_SHORT_SWORD :
- (temp_rand == 1) ? WPN_MACE :
- (temp_rand == 2) ? WPN_HAND_AXE : WPN_SPEAR);
- return;
- }
-
- if (you.char_class == JOB_GLADIATOR || you.species == SP_MERFOLK)
- num_choices = 5;
-
- if (Options.weapon != WPN_UNKNOWN && Options.weapon != WPN_RANDOM
- && (Options.weapon != WPN_TRIDENT || num_choices == 5))
- {
- you.inv[0].sub_type = Options.weapon;
- ng_weapon = Options.weapon;
- return;
- }
-
- if (!Options.random_pick && Options.weapon != WPN_RANDOM)
- {
- clrscr();
-
- textcolor( CYAN );
- cprintf(EOL " You have a choice of weapons:" EOL);
- textcolor( LIGHTGREY );
-
- bool prevmatch = false;
- for(int i=0; i<num_choices; i++)
- {
- int x = effective_stat_bonus(startwep[i]);
- standard_name_weap(startwep[i], wepName);
-
- snprintf( info, INFO_SIZE, "%c - %s%s" EOL, 'a' + i, wepName,
- (x <= -4) ? " (not ideal)" : "" );
-
- cprintf(info);
-
- if (Options.prev_weapon == startwep[i])
- prevmatch = true;
- }
- if (!prevmatch && Options.prev_weapon != WPN_RANDOM)
- Options.prev_weapon = WPN_UNKNOWN;
-
- textcolor(BROWN);
- cprintf(EOL "? - Random" );
- if (Options.prev_weapon != WPN_UNKNOWN)
- {
- char weapbuf[ITEMNAME_SIZE];
- if (Options.prev_weapon != WPN_RANDOM)
- standard_name_weap(Options.prev_weapon, weapbuf);
- cprintf("; Enter - %s",
- Options.prev_weapon == WPN_RANDOM? "Random" :
- weapbuf);
- }
- cprintf(EOL);
-
- do
- {
- textcolor( CYAN );
- cprintf(EOL "Which weapon? ");
- textcolor( LIGHTGREY );
-
- keyin = get_ch();
- }
- while (keyin != '?' &&
- ((keyin != '\r' && keyin != '\n')
- || Options.prev_weapon == WPN_UNKNOWN) &&
- (keyin < 'a' || keyin > ('a' + num_choices)));
-
- if (keyin == '\r' || keyin == '\n')
- {
- if (Options.prev_weapon == WPN_RANDOM)
- keyin = '?';
- else
- {
- for (int i = 0; i < num_choices; ++i)
- if (startwep[i] == Options.prev_weapon)
- keyin = 'a' + i;
- }
- }
-
- if (keyin != '?' && effective_stat_bonus(startwep[keyin-'a']) > -4)
- cprintf(EOL "A fine choice. " EOL);
- }
-
- if (Options.random_pick || Options.weapon == WPN_RANDOM || keyin == '?')
- {
- Options.weapon = WPN_RANDOM;
- // try to choose a decent weapon
- for(int times=0; times<50; times++)
- {
- keyin = random2(num_choices);
- int x = effective_stat_bonus(startwep[keyin]);
- if (x > -2)
- break;
- }
- keyin += 'a';
- }
-
- you.inv[0].sub_type = startwep[keyin-'a'];
- ng_weapon = (Options.random_pick ||
- Options.weapon == WPN_RANDOM ||
- keyin == '?')
- ? WPN_RANDOM : you.inv[0].sub_type;
-}
-
-void init_player(void)
-{
- unsigned char i = 0; // loop variable
-
- you.birth_time = time( NULL );
- you.real_time = 0;
- you.num_turns = 0;
-
-#ifdef WIZARD
- you.wizard = (Options.wiz_mode == WIZ_YES) ? true : false;
-#else
- you.wizard = false;
-#endif
-
- you.activity = ACT_NONE;
- you.berserk_penalty = 0;
- you.berserker = 0;
- you.conf = 0;
- you.confusing_touch = 0;
- you.deaths_door = 0;
- you.disease = 0;
- you.elapsed_time = 0;
- you.exhausted = 0;
- you.haste = 0;
- you.invis = 0;
- you.levitation = 0;
- you.might = 0;
- you.paralysis = 0;
- you.poison = 0;
- you.rotting = 0;
- you.fire_shield = 0;
- you.slow = 0;
- you.special_wield = SPWLD_NONE;
- you.sure_blade = 0;
- you.synch_time = 0;
-
- you.base_hp = 5000;
- you.base_hp2 = 5000;
- you.base_magic_points = 5000;
- you.base_magic_points2 = 5000;
-
- you.magic_points_regeneration = 0;
- you.strength = 0;
- you.max_strength = 0;
- you.intel = 0;
- you.max_intel = 0;
- you.dex = 0;
- you.max_dex = 0;
- you.experience = 0;
- you.experience_level = 1;
- you.max_level = 1;
- you.char_class = JOB_UNKNOWN;
-
- you.hunger = 6000;
- you.hunger_state = HS_SATIATED;
-
- you.gold = 0;
- // you.speed = 10; // 0.75; // unused
-
- you.burden = 0;
- you.burden_state = BS_UNENCUMBERED;
-
- you.spell_no = 0;
-
- you.your_level = 0;
- you.level_type = LEVEL_DUNGEON;
- you.where_are_you = BRANCH_MAIN_DUNGEON;
- you.char_direction = DIR_DESCENDING;
-
- you.prev_targ = MHITNOT;
- you.pet_target = MHITNOT;
-
- you.x_pos = 0;
- you.y_pos = 0;
-
- you.running = 0;
- you.run_x = 0;
- you.run_y = 0;
- you.travel_x = 0;
- you.travel_y = 0;
-
- for (i = 0; i < 3; i++)
- {
- you.run_check[i].grid = 0;
- you.run_check[i].dx = 0;
- you.run_check[i].dy = 0;
- }
-
- you.religion = GOD_NO_GOD;
- you.piety = 0;
-
- you.gift_timeout = 0;
-
- for (i = 0; i < MAX_NUM_GODS; i++)
- {
- you.penance[i] = 0;
- you.worshipped[i] = 0;
- you.num_gifts[i] = 0;
- }
-
- ghost.name[0] = '\0';
-
- for (i = 0; i < NUM_GHOST_VALUES; i++)
- ghost.values[i] = 0;
-
- for (i = EQ_WEAPON; i < NUM_EQUIP; i++)
- you.equip[i] = -1;
-
- for (i = 0; i < 25; i++)
- you.spells[i] = SPELL_NO_SPELL;
-
- for (i = 0; i < 52; i++)
- {
- you.spell_letter_table[i] = -1;
- you.ability_letter_table[i] = ABIL_NON_ABILITY;
- }
-
- for (i = 0; i < 100; i++)
- you.mutation[i] = 0;
-
- for (i = 0; i < 100; i++)
- you.demon_pow[i] = 0;
-
- for (i = 0; i < 50; i++)
- you.had_book[i] = 0;
-
- for (i = 0; i < 50; i++)
- you.unique_items[i] = UNIQ_NOT_EXISTS;
-
- for (i = 0; i < NO_UNRANDARTS; i++)
- set_unrandart_exist(i, 0);
-
- for (i = 0; i < 50; i++)
- {
- you.skills[i] = 0;
- you.skill_points[i] = 0;
- you.skill_order[i] = MAX_SKILL_ORDER;
- you.practise_skill[i] = 1;
- }
-
- you.skill_cost_level = 1;
- you.total_skill_points = 0;
-
- for (i = 0; i < 30; i++)
- you.attribute[i] = 0;
-
- for (i = 0; i < ENDOFPACK; i++)
- {
- you.inv[i].quantity = 0;
- you.inv[i].base_type = OBJ_WEAPONS;
- you.inv[i].sub_type = WPN_CLUB;
- you.inv[i].plus = 0;
- you.inv[i].plus2 = 0;
- you.inv[i].special = 0;
- you.inv[i].colour = 0;
- set_ident_flags( you.inv[i], ISFLAG_IDENT_MASK );
-
- you.inv[i].x = -1;
- you.inv[i].y = -1;
- you.inv[i].link = i;
- }
-
- for (i = 0; i < NUM_DURATIONS; i++)
- you.duration[i] = 0;
-}
-
-void give_last_paycheck(int which_job)
-{
- switch (which_job)
- {
- case JOB_HEALER:
- case JOB_THIEF:
- you.gold = roll_dice( 2, 100 );
- break;
-
- case JOB_WANDERER:
- case JOB_WARPER:
- case JOB_ASSASSIN:
- you.gold = roll_dice( 2, 50 );
- break;
-
- default:
- you.gold = roll_dice( 2, 20 );
- break;
-
- case JOB_PALADIN:
- case JOB_MONK:
- you.gold = 0;
- break;
- }
-}
-
-// requires stuff::modify_all_stats() and works because
-// stats zeroed out by newgame::init_player()... recall
-// that demonspawn & demingods get more later on {dlb}
-void species_stat_init(unsigned char which_species)
-{
- int sb = 0; // strength base
- int ib = 0; // intelligence base
- int db = 0; // dexterity base
-
- // Note: The stats in in this list aren't intended to sum the same
- // for all races. The fact that Mummies and Ghouls are really low
- // is considered acceptable (Mummies don't have to eat, and Ghouls
- // are supposted to be a really hard race). Also note that Demigods
- // and Demonspawn get seven more random points added later. -- bwr
- switch (which_species)
- {
- default: sb = 6; ib = 6; db = 6; break; // 18
- case SP_HUMAN: sb = 6; ib = 6; db = 6; break; // 18
- case SP_DEMIGOD: sb = 7; ib = 7; db = 7; break; // 21+7
- case SP_DEMONSPAWN: sb = 4; ib = 4; db = 4; break; // 12+7
-
- case SP_ELF: sb = 5; ib = 8; db = 8; break; // 21
- case SP_HIGH_ELF: sb = 5; ib = 9; db = 8; break; // 22
- case SP_GREY_ELF: sb = 4; ib = 9; db = 8; break; // 21
- case SP_DEEP_ELF: sb = 3; ib = 10; db = 8; break; // 21
- case SP_SLUDGE_ELF: sb = 6; ib = 7; db = 7; break; // 20
-
- case SP_HILL_DWARF: sb = 10; ib = 3; db = 4; break; // 17
- case SP_MOUNTAIN_DWARF: sb = 9; ib = 4; db = 5; break; // 18
-
- case SP_TROLL: sb = 13; ib = 2; db = 3; break; // 18
- case SP_OGRE: sb = 12; ib = 3; db = 3; break; // 18
- case SP_OGRE_MAGE: sb = 9; ib = 7; db = 3; break; // 19
-
- case SP_MINOTAUR: sb = 10; ib = 3; db = 3; break; // 16
- case SP_HILL_ORC: sb = 9; ib = 3; db = 4; break; // 16
- case SP_CENTAUR: sb = 8; ib = 5; db = 2; break; // 15
- case SP_NAGA: sb = 8; ib = 6; db = 4; break; // 18
-
- case SP_GNOME: sb = 6; ib = 6; db = 7; break; // 19
- case SP_MERFOLK: sb = 6; ib = 5; db = 7; break; // 18
- case SP_KENKU: sb = 6; ib = 6; db = 7; break; // 19
-
- case SP_KOBOLD: sb = 5; ib = 4; db = 8; break; // 17
- case SP_HALFLING: sb = 3; ib = 6; db = 9; break; // 18
- case SP_SPRIGGAN: sb = 2; ib = 7; db = 9; break; // 18
-
- case SP_MUMMY: sb = 7; ib = 3; db = 3; break; // 13
- case SP_GHOUL: sb = 9; ib = 1; db = 2; break; // 13
-
- case SP_RED_DRACONIAN:
- case SP_WHITE_DRACONIAN:
- case SP_GREEN_DRACONIAN:
- case SP_GOLDEN_DRACONIAN:
- case SP_GREY_DRACONIAN:
- case SP_BLACK_DRACONIAN:
- case SP_PURPLE_DRACONIAN:
- case SP_MOTTLED_DRACONIAN:
- case SP_PALE_DRACONIAN:
- case SP_UNK0_DRACONIAN:
- case SP_UNK1_DRACONIAN:
- case SP_BASE_DRACONIAN: sb = 9; ib = 6; db = 2; break; // 17
- }
-
- modify_all_stats( sb, ib, db );
-}
-
-void jobs_stat_init(int which_job)
-{
- int s = 0; // strength mod
- int i = 0; // intelligence mod
- int d = 0; // dexterity mod
- int hp = 0; // HP base
- int mp = 0; // MP base
-
- // Note: Wanderers are correct, they're a challenging class. -- bwr
- switch (which_job)
- {
- case JOB_FIGHTER: s = 7; i = 0; d = 3; hp = 15; mp = 0; break;
- case JOB_BERSERKER: s = 7; i = -1; d = 4; hp = 15; mp = 0; break;
- case JOB_GLADIATOR: s = 6; i = 0; d = 4; hp = 14; mp = 0; break;
- case JOB_PALADIN: s = 6; i = 2; d = 2; hp = 14; mp = 0; break;
-
- case JOB_CRUSADER: s = 4; i = 3; d = 3; hp = 13; mp = 1; break;
- case JOB_DEATH_KNIGHT: s = 4; i = 3; d = 3; hp = 13; mp = 1; break;
- case JOB_CHAOS_KNIGHT: s = 4; i = 3; d = 3; hp = 13; mp = 1; break;
-
- case JOB_REAVER: s = 4; i = 4; d = 2; hp = 13; mp = 1; break;
- case JOB_HEALER: s = 4; i = 4; d = 2; hp = 13; mp = 1; break;
- case JOB_PRIEST: s = 4; i = 4; d = 2; hp = 12; mp = 1; break;
-
- case JOB_ASSASSIN: s = 2; i = 2; d = 6; hp = 12; mp = 0; break;
- case JOB_THIEF: s = 3; i = 2; d = 5; hp = 13; mp = 0; break;
- case JOB_STALKER: s = 2; i = 3; d = 5; hp = 12; mp = 1; break;
-
- case JOB_HUNTER: s = 3; i = 3; d = 4; hp = 13; mp = 0; break;
- case JOB_WARPER: s = 3; i = 4; d = 3; hp = 12; mp = 1; break;
-
- case JOB_MONK: s = 2; i = 2; d = 6; hp = 13; mp = 0; break;
- case JOB_TRANSMUTER: s = 2; i = 4; d = 4; hp = 12; mp = 1; break;
-
- case JOB_WIZARD: s = -1; i = 8; d = 3; hp = 8; mp = 5; break;
- case JOB_CONJURER: s = 0; i = 6; d = 4; hp = 10; mp = 3; break;
- case JOB_ENCHANTER: s = 0; i = 6; d = 4; hp = 10; mp = 3; break;
- case JOB_FIRE_ELEMENTALIST: s = 0; i = 6; d = 4; hp = 10; mp = 3; break;
- case JOB_ICE_ELEMENTALIST: s = 0; i = 6; d = 4; hp = 10; mp = 3; break;
- case JOB_AIR_ELEMENTALIST: s = 0; i = 6; d = 4; hp = 10; mp = 3; break;
- case JOB_EARTH_ELEMENTALIST:s = 0; i = 6; d = 4; hp = 10; mp = 3; break;
- case JOB_SUMMONER: s = 0; i = 6; d = 4; hp = 10; mp = 3; break;
- case JOB_VENOM_MAGE: s = 0; i = 6; d = 4; hp = 10; mp = 3; break;
- case JOB_NECROMANCER: s = 0; i = 6; d = 4; hp = 10; mp = 3; break;
-
- case JOB_WANDERER: s = 2; i = 2; d = 2; hp = 11; mp = 1; break;
- default: s = 0; i = 0; d = 0; hp = 10; mp = 0; break;
- }
-
- modify_all_stats( s, i, d );
-
- set_hp( hp, true );
- set_mp( mp, true );
-}
-
-void give_basic_knowledge(int which_job)
-{
- switch (which_job)
- {
- case JOB_PRIEST:
- case JOB_PALADIN:
- set_ident_type( OBJ_POTIONS, POT_HEALING, ID_KNOWN_TYPE );
- break;
-
- case JOB_HEALER:
- set_ident_type( OBJ_POTIONS, POT_HEALING, ID_KNOWN_TYPE );
- set_ident_type( OBJ_POTIONS, POT_HEAL_WOUNDS, ID_KNOWN_TYPE );
- break;
-
- case JOB_ASSASSIN:
- case JOB_STALKER:
- case JOB_VENOM_MAGE:
- set_ident_type( OBJ_POTIONS, POT_POISON, ID_KNOWN_TYPE );
- break;
-
- case JOB_WARPER:
- set_ident_type( OBJ_SCROLLS, SCR_BLINKING, ID_KNOWN_TYPE );
- break;
-
- case JOB_TRANSMUTER:
- set_ident_type( OBJ_POTIONS, POT_WATER, ID_KNOWN_TYPE );
- set_ident_type( OBJ_POTIONS, POT_CONFUSION, ID_KNOWN_TYPE );
- set_ident_type( OBJ_POTIONS, POT_POISON, ID_KNOWN_TYPE );
- break;
-
- default:
- break;
- }
-
- return;
-} // end give_basic_knowledge()
-
-void give_basic_spells(int which_job)
-{
- // wanderers may or may not already have a spell -- bwr
- if (which_job == JOB_WANDERER)
- return;
-
- unsigned char which_spell = SPELL_NO_SPELL;
-
- switch (which_job)
- {
- case JOB_CONJURER:
- case JOB_REAVER:
- case JOB_WIZARD:
- which_spell = SPELL_MAGIC_DART;
- break;
- case JOB_STALKER:
- case JOB_VENOM_MAGE:
- which_spell = SPELL_STING;
- break;
- case JOB_SUMMONER:
- which_spell = SPELL_SUMMON_SMALL_MAMMAL;
- break;
- case JOB_ICE_ELEMENTALIST:
- which_spell = SPELL_FREEZE;
- break;
- case JOB_NECROMANCER:
- which_spell = SPELL_PAIN;
- break;
- case JOB_ENCHANTER:
- which_spell = SPELL_BACKLIGHT;
- break;
- case JOB_FIRE_ELEMENTALIST:
- which_spell = SPELL_FLAME_TONGUE;
- break;
- case JOB_AIR_ELEMENTALIST:
- which_spell = SPELL_SHOCK;
- break;
- case JOB_EARTH_ELEMENTALIST:
- which_spell = SPELL_SANDBLAST;
- break;
- case JOB_DEATH_KNIGHT:
- if (you.species == SP_DEMIGOD || you.religion != GOD_YREDELEMNUL)
- which_spell = SPELL_PAIN;
- break;
-
- default:
- break;
- }
-
- if (which_spell != SPELL_NO_SPELL)
- add_spell_to_memory( which_spell );
-
- return;
-} // end give_basic_spells()
-
-
-/* ************************************************************************
-
-// MAKE INTO FUNCTION!!! {dlb}
-// randomly boost stats a number of times based on species {dlb}
- unsigned char points_left = ( you.species == SP_DEMIGOD || you.species == SP_DEMONSPAWN ) ? 15 : 8;
-
- do
- {
- switch ( random2(NUM_STATS) )
- {
- case STAT_STRENGTH:
- if ( you.strength > 17 && coinflip() )
- continue;
- you.strength++;
- break;
- case STAT_DEXTERITY:
- if ( you.dex > 17 && coinflip() )
- continue;
- you.dex++;
- break;
- case STAT_INTELLIGENCE:
- if ( you.intel > 17 && coinflip() )
- continue;
- you.intel++;
- break;
- }
- points_left--;
- }
- while (points_left > 0);
-
-************************************************************************ */
-
-
-// eventually, this should be something more grand {dlb}
-void openingScreen(void)
-{
-/* **********************************************
-// this does not work just yet ... {dlb}:
- cprintf(EOL "Hello, ");
-
- if ( you.your_name[0] != '\0' )
- {
- cprintf(you.your_name); // better be less than 31 characters :P {dlb}
- // of course, invalid names will appear {dlb}
- cprintf(", ");
- }
-********************************************** */
-
- textcolor( YELLOW );
- cprintf("Hello, welcome to Dungeon Crawl Stone Soup " VERSION "!");
- textcolor( BROWN );
- cprintf(EOL "(c) Copyright 1997-2002 Linley Henzell");
- cprintf(EOL "Please consult crawl.txt for instructions and legal details."
- EOL);
- textcolor( LIGHTGREY );
-
- return;
-} // end openingScreen()
-
-
-void enterPlayerName(bool blankOK)
-{
- // temporary 'til copyover to you.your_name {dlb}
- // made this rediculously long so that the game doesn't
- // crash if a really really long name is entered (argh). {gdl}
- char name_entered[200];
-
- // anything to avoid goto statements {dlb}
- bool acceptable_name = false;
- bool first_time = true;
-
- // first time -- names set through init.txt/environment assumed ok {dlb}
- if (you.your_name[0] != '\0')
- acceptable_name = true;
-
- do
- {
- // prompt for a new name if current one unsatisfactory {dlb}:
- if (!acceptable_name)
- {
- textcolor( CYAN );
- if (blankOK && first_time)
- {
- if (Options.prev_name.length() && Options.remember_name)
- cprintf(EOL "Press <Enter> for \"%s\"." EOL,
- Options.prev_name.c_str());
- else
- cprintf(EOL
- "Press <Enter> to answer this after race and "
- "class are chosen." EOL);
- }
-
- first_time = false;
-
- cprintf(EOL "What is your name today? ");
- textcolor( LIGHTGREY );
- get_input_line( name_entered, sizeof( name_entered ) );
-
- strncpy( you.your_name, name_entered, kNameLen );
- you.your_name[ kNameLen - 1 ] = '\0';
- }
-
- if (!*you.your_name && blankOK && Options.prev_name.length() &&
- Options.remember_name)
- {
- strncpy(you.your_name, Options.prev_name.c_str(), kNameLen);
- you.your_name[kNameLen - 1] = 0;
- }
-
- // '.', '?' and '*' are blanked.
- if (!you.your_name[1] && (*you.your_name == '.' ||
- *you.your_name == '*' ||
- *you.your_name == '?'))
- {
- *you.your_name = 0;
- }
-
- // verification begins here {dlb}:
- if (you.your_name[0] == '\0')
- {
- if (blankOK)
- return;
-
- cprintf(EOL "That's a silly name!" EOL);
- acceptable_name = false;
- }
-
- // if SAVE_DIR_PATH is defined, userid will be tacked onto the end
- // of each character's files, making bones a valid player name.
-#ifndef SAVE_DIR_PATH
- // this would cause big probs with ghosts
- // what would? {dlb}
- // ... having the name "bones" of course! The problem comes from
- // the fact that bones files would have the exact same filename
- // as level files for a character named "bones". -- bwr
- else if (stricmp(you.your_name, "bones") == 0)
- {
- cprintf(EOL "That's a silly name!" EOL);
- acceptable_name = false;
- }
-#endif
- else
- acceptable_name = verifyPlayerName();
-
- }
- while (!acceptable_name);
-} // end enterPlayerName()
-
-bool verifyPlayerName(void)
-{
-#if defined(DOS) || defined(WIN32CONSOLE)
- static int william_tanksley_asked_for_this = 2;
-
- // quick check for CON -- blows up real good under DOS/Windows
- if (stricmp(you.your_name, "con") == 0)
- {
- cprintf(EOL "Sorry, that name gives your OS a headache." EOL);
- return (false);
- }
-
- // quick check for LPTx -- thank you, Mr. Tanksley! ;-)
- if (strnicmp(you.your_name, "LPT", 3) == 0)
- {
- switch (william_tanksley_asked_for_this)
- {
- case 2:
- cprintf(EOL "Hello, William! How is work on Omega going?" EOL);
- break;
- case 1:
- cprintf(EOL "Look, it's just not a legal name." EOL);
- break;
- case 0:
- strcpy(you.your_name, "William");
- return (true);
- } // end switch
-
- william_tanksley_asked_for_this --;
- return (false);
- }
-#endif
-
- const size_t len = strlen( you.your_name );
- for (unsigned int i = 0; i < len; i++)
- {
-#if MAC
- // the only bad character on Macs is the path seperator
- if (you.your_name[i] == ':')
- {
- cprintf(EOL "No colons, please." EOL);
- return (false);
- }
-#else
- // Note that this includes systems which may be using the
- // packaging system. The packaging system is very simple
- // and doesn't take the time to escape every characters that
- // might be a problem for some random shell or OS... so we
- // play it very conservative here. -- bwr
- if (!isalnum( you.your_name[i] ) && you.your_name[i] != '_')
- {
- cprintf( EOL "Alpha-numerics and underscores only, please." EOL );
- return (false);
- }
-#endif
- }
-
-#ifdef SAVE_DIR_PATH
- // Until we have a better way to handle the fact that this could lead
- // to some confusion with where the name ends and the uid begins. -- bwr
- if (isdigit( you.your_name[ len - 1 ] ))
- {
- cprintf( EOL "Sorry, your name cannot end with a digit." EOL );
- return (false);
- }
-#endif
-
- return (true);
-} // end verifyPlayerName()
-
-#if 0
-// currently unused
-static void give_random_scroll( int slot )
-{
- you.inv[ slot ].quantity = 1;
- you.inv[ slot ].base_type = OBJ_SCROLLS;
- you.inv[ slot ].plus = 0;
- you.inv[ slot ].special = 0;
- you.inv[ slot ].colour = WHITE;
-
- switch (random2(8))
- {
- case 0:
- you.inv[ slot ].sub_type = SCR_DETECT_CURSE;
- break;
-
- case 1:
- you.inv[ slot ].sub_type = SCR_IDENTIFY;
- break;
-
- case 2:
- case 3:
- you.inv[ slot ].sub_type = SCR_BLINKING;
- break;
-
- case 4:
- you.inv[ slot ].sub_type = SCR_FEAR;
- break;
-
- case 5:
- you.inv[ slot ].sub_type = SCR_SUMMONING;
- break;
-
- case 6:
- case 7:
- default:
- you.inv[ slot ].sub_type = SCR_TELEPORTATION;
- break;
- }
-}
-#endif
-
-static void give_random_potion( int slot )
-{
- you.inv[ slot ].quantity = 1;
- you.inv[ slot ].base_type = OBJ_POTIONS;
- you.inv[ slot ].plus = 0;
- you.inv[ slot ].plus2 = 0;
-
- switch (random2(8))
- {
- case 0:
- case 1:
- case 2:
- you.inv[ slot ].sub_type = POT_HEALING;
- break;
- case 3:
- case 4:
- you.inv[ slot ].sub_type = POT_HEAL_WOUNDS;
- break;
- case 5:
- you.inv[ slot ].sub_type = POT_SPEED;
- break;
- case 6:
- you.inv[ slot ].sub_type = POT_MIGHT;
- break;
- case 7:
- you.inv[ slot ].sub_type = POT_BERSERK_RAGE;
- break;
- }
-}
-
-#if 0
-// currently unused
-static void give_random_wand( int slot )
-{
- you.inv[ slot ].quantity = 1;
- you.inv[ slot ].base_type = OBJ_WANDS;
- you.inv[ slot ].special = 0;
- you.inv[ slot ].plus2 = 0;
- you.inv[ slot ].colour = random_colour();
-
- switch (random2(4))
- {
- case 0:
- you.inv[ slot ].sub_type = WAND_SLOWING;
- you.inv[ slot ].plus = 7 + random2(5);
- break;
- case 1:
- you.inv[ slot ].sub_type = WAND_PARALYSIS;
- you.inv[ slot ].plus = 5 + random2(4);
- break;
- case 2:
- you.inv[ slot ].sub_type = coinflip() ? WAND_FROST : WAND_FLAME;
- you.inv[ slot ].plus = 6 + random2(4);
- break;
- case 3:
- you.inv[ slot ].sub_type = WAND_TELEPORTATION;
- you.inv[ slot ].plus = 3 + random2(4);
- break;
- }
-}
-#endif
-
-static void give_random_secondary_armour( int slot )
-{
- you.inv[ slot ].quantity = 1;
- you.inv[ slot ].base_type = OBJ_ARMOUR;
- you.inv[ slot ].special = 0;
- you.inv[ slot ].plus = 0;
- you.inv[ slot ].plus2 = 0;
- you.inv[ slot ].colour = BROWN;
-
- switch (random2(4))
- {
- case 0:
- you.inv[ slot ].sub_type = ARM_CLOAK;
- you.equip[EQ_CLOAK] = slot;
- break;
- case 1:
- you.inv[ slot ].sub_type = ARM_BOOTS;
- you.equip[EQ_BOOTS] = slot;
- break;
- case 2:
- you.inv[ slot ].sub_type = ARM_GLOVES;
- you.equip[EQ_GLOVES] = slot;
- break;
- case 3:
- you.inv[ slot ].sub_type = ARM_HELMET;
- you.equip[EQ_HELMET] = slot;
- break;
- }
-}
-
-// Returns true if a "good" weapon is given
-static bool give_wanderer_weapon( int slot, int wpn_skill )
-{
- bool ret = false;
-
- // Slot's always zero, but we pass it anyways.
-
- // We'll also re-fill the template, all this for later possible
- // safe reuse of code in the future.
- you.inv[ slot ].quantity = 1;
- you.inv[ slot ].base_type = OBJ_WEAPONS;
- you.inv[ slot ].colour = LIGHTCYAN;
- you.inv[ slot ].plus = 0;
- you.inv[ slot ].plus2 = 0;
- you.inv[ slot ].special = 0;
-
- // Now fill in the type according to the random wpn_skill
- switch (wpn_skill)
- {
- case SK_MACES_FLAILS:
- you.inv[ slot ].sub_type = WPN_CLUB;
- you.inv[ slot ].colour = BROWN;
- break;
-
- case SK_POLEARMS:
- you.inv[ slot ].sub_type = WPN_SPEAR;
- break;
-
- case SK_SHORT_BLADES:
- you.inv[ slot ].sub_type = WPN_DAGGER;
- break;
-
- case SK_AXES:
- you.inv[ slot ].sub_type = WPN_HAND_AXE;
- ret = true;
- break;
-
- case SK_STAVES:
- you.inv[ slot ].sub_type = WPN_QUARTERSTAFF;
- you.inv[ slot ].colour = BROWN;
- ret = true;
- break;
-
- case SK_LONG_SWORDS:
- default:
- // all long swords are too good for a starting character...
- // especially this class where we have to be careful about
- // giving away anything good at all.
- // We default here if the character only has fighting skill -- bwr
- you.inv[ slot ].sub_type = WPN_SHORT_SWORD;
- ret = true;
- break;
- }
-
- return (ret);
-}
-
-//
-// The idea behind wanderers is a class that has various different
-// random skills that's a challenge to play... not a class that can
-// be continually rerolled to gain the ideal character. To maintain
-// this, we have to try and make sure that they typically get worse
-// equipment than any other class... this for certain means no
-// spellbooks ever, and the bows and xbows down below might be too
-// much... so pretty much things should be removed rather than
-// added here. -- bwr
-//
-static void create_wanderer( void )
-{
- const int util_skills[] =
- { SK_DARTS, SK_RANGED_COMBAT, SK_ARMOUR, SK_DODGING, SK_STEALTH,
- SK_STABBING, SK_SHIELDS, SK_TRAPS_DOORS, SK_UNARMED_COMBAT,
- SK_INVOCATIONS, SK_EVOCATIONS };
- const int num_util_skills = sizeof(util_skills) / sizeof(int);
-
- // Long swords is missing to increae it's rarity because we
- // can't give out a long sword to a starting character (they're
- // all too good)... Staves is also removed because it's not
- // one of the fighter options.-- bwr
- const int fight_util_skills[] =
- { SK_FIGHTING, SK_SHORT_BLADES, SK_AXES,
- SK_MACES_FLAILS, SK_POLEARMS,
- SK_DARTS, SK_RANGED_COMBAT, SK_ARMOUR, SK_DODGING, SK_STEALTH,
- SK_STABBING, SK_SHIELDS, SK_TRAPS_DOORS, SK_UNARMED_COMBAT,
- SK_INVOCATIONS, SK_EVOCATIONS };
- const int num_fight_util_skills = sizeof(fight_util_skills) / sizeof(int);
-
- const int not_rare_skills[] =
- { SK_SLINGS, SK_BOWS, SK_CROSSBOWS,
- SK_SPELLCASTING, SK_CONJURATIONS, SK_ENCHANTMENTS,
- SK_FIRE_MAGIC, SK_ICE_MAGIC, SK_AIR_MAGIC, SK_EARTH_MAGIC,
- SK_FIGHTING, SK_SHORT_BLADES, SK_LONG_SWORDS, SK_AXES,
- SK_MACES_FLAILS, SK_POLEARMS, SK_STAVES,
- SK_DARTS, SK_RANGED_COMBAT, SK_ARMOUR, SK_DODGING, SK_STEALTH,
- SK_STABBING, SK_SHIELDS, SK_TRAPS_DOORS, SK_UNARMED_COMBAT,
- SK_INVOCATIONS, SK_EVOCATIONS };
- const int num_not_rare_skills = sizeof(not_rare_skills) / sizeof(int);
-
- const int all_skills[] =
- { SK_SUMMONINGS, SK_NECROMANCY, SK_TRANSLOCATIONS, SK_TRANSMIGRATION,
- SK_DIVINATIONS, SK_POISON_MAGIC,
- SK_SLINGS, SK_BOWS, SK_CROSSBOWS,
- SK_SPELLCASTING, SK_CONJURATIONS, SK_ENCHANTMENTS,
- SK_FIRE_MAGIC, SK_ICE_MAGIC, SK_AIR_MAGIC, SK_EARTH_MAGIC,
- SK_FIGHTING, SK_SHORT_BLADES, SK_LONG_SWORDS, SK_AXES,
- SK_MACES_FLAILS, SK_POLEARMS, SK_STAVES,
- SK_DARTS, SK_RANGED_COMBAT, SK_ARMOUR, SK_DODGING, SK_STEALTH,
- SK_STABBING, SK_SHIELDS, SK_TRAPS_DOORS, SK_UNARMED_COMBAT,
- SK_INVOCATIONS, SK_EVOCATIONS };
- const int num_all_skills = sizeof(all_skills) / sizeof(int);
-
- int skill;
-
- for (int i = 0; i < 2; i++)
- {
- do
- {
- skill = random2( num_util_skills );
- }
- while (you.skills[ util_skills[ skill ]] >= 2);
-
- you.skills[ util_skills[ skill ]] += 1;
- }
-
- for (int i = 0; i < 3; i++)
- {
- do
- {
- skill = random2( num_fight_util_skills );
- }
- while (you.skills[ fight_util_skills[ skill ]] >= 2);
-
- you.skills[ fight_util_skills[ skill ]] += 1;
- }
-
- // Spell skills are possible past this point, but we won't
- // allow two levels of any of them -- bwr
- for (int i = 0; i < 3; i++)
- {
- do
- {
- skill = random2( num_not_rare_skills );
- }
- while (you.skills[ not_rare_skills[ skill ]] >= 2
- || (not_rare_skills[ skill ] >= SK_SPELLCASTING
- && you.skills[ not_rare_skills[ skill ]]));
-
- you.skills[ not_rare_skills[ skill ]] += 1;
- }
-
- for (int i = 0; i < 2; i++)
- {
- do
- {
- skill = random2( num_all_skills );
- }
- while (you.skills[all_skills[ skill ]] >= 2
- || (all_skills[ skill ] >= SK_SPELLCASTING
- && you.skills[ all_skills[ skill ]]));
-
- you.skills[ all_skills[ skill ]] += 1;
- }
-
- // Demigods can't use invocations so we'll swap it for something else
- if (you.species == SP_DEMIGOD && you.skills[ SK_INVOCATIONS ])
- {
- you.skills[ SK_INVOCATIONS ] = 0;
-
- do
- {
- skill = random2( num_all_skills );
- }
- while (skill == SK_INVOCATIONS && you.skills[all_skills[ skill ]]);
-
- you.skills[ skill ] = 1;
- }
-
- int wpn_skill = SK_FIGHTING; // prefered weapon type
- int wpn_skill_size = 0; // level of skill in prefered weapon type
- int num_wpn_skills = 0; // used to choose prefered weapon
- int total_wpn_skills = 0; // used to choose template
-
- // This algorithm is the same as the one used to pick a random
- // angry god for retribution, except that whenever a higher skill
- // is found than the current one, we automatically take it and
- // only consider skills at that level or higher from that point on,
- // This should give a random wpn skill from the set of skills with
- // the highest value. -- bwr
- for (int i = SK_SHORT_BLADES; i <= SK_STAVES; i++)
- {
- if (you.skills[i] > 0)
- {
- total_wpn_skills++;
-
- if (you.skills[i] > wpn_skill_size)
- {
- // switch to looking in the new set of better skills
- num_wpn_skills = 1; // reset to one, because it's a new set
- wpn_skill = i;
- wpn_skill_size = you.skills[i];
- }
- else if (you.skills[i] == wpn_skill_size)
- {
- // still looking at the old level
- num_wpn_skills++;
- if (one_chance_in( num_wpn_skills ))
- {
- wpn_skill = i;
- wpn_skill_size = you.skills[i];
- }
- }
- }
- }
-
- // Let's try to make an appropriate weapon
- // Start with a template for a weapon
- you.inv[0].quantity = 1;
- you.inv[0].base_type = OBJ_WEAPONS;
- you.inv[0].sub_type = WPN_KNIFE;
- you.inv[0].colour = LIGHTCYAN;
- you.inv[0].plus = 0;
- you.inv[0].plus2 = 0;
- you.inv[0].special = 0;
-
- // And a default armour template for a robe (leaving slot 1 open for
- // a secondary weapon).
- you.inv[2].quantity = 1;
- you.inv[2].base_type = OBJ_ARMOUR;
- you.inv[2].sub_type = ARM_ROBE;
- you.inv[2].colour = BROWN;
- you.inv[2].plus = 0;
- you.inv[2].special = 0;
-
- // Wanderers have at least seen one type of potion, and if they
- // don't get anything else good, they'll get to keep this one...
- // Note: even if this is taken away, the knowledge of the potion
- // type is still given to the character.
- give_random_potion(3);
-
- if (you.skills[SK_FIGHTING] || total_wpn_skills >= 3)
- {
- // Fighter style wanderer
- if (you.skills[SK_ARMOUR])
- {
- you.inv[2].sub_type = ARM_RING_MAIL;
- you.inv[2].colour = LIGHTCYAN;
-
- you.inv[3].quantity = 0; // remove potion
- }
- else if (you.skills[SK_SHIELDS] && wpn_skill != SK_STAVES)
- {
- you.inv[4].quantity = 1;
- you.inv[4].base_type = OBJ_ARMOUR;
- you.inv[4].sub_type = ARM_BUCKLER;
- you.inv[4].plus = 0;
- you.inv[4].special = 0;
- you.inv[4].colour = LIGHTCYAN;
- you.equip[EQ_SHIELD] = 4;
-
- you.inv[3].quantity = 0; // remove potion
- }
- else
- {
- give_random_secondary_armour(5);
- }
-
- // remove potion if good weapon is given:
- if (give_wanderer_weapon( 0, wpn_skill ))
- you.inv[3].quantity = 0;
- }
-#ifdef USE_SPELLCASTER_AND_RANGER_WANDERER_TEMPLATES
- else if (you.skills[ SK_SPELLCASTING ])
- {
- // Spellcaster style wanderer
-
- // Could only have learned spells in common schools...
- const int school_list[5] =
- { SK_CONJURATIONS,
- SK_ENCHANTMENTS, SK_ENCHANTMENTS,
- SK_TRANSLOCATIONS, SK_NECROMANCY };
-
- //jmf: Two of those spells are gone due to their munchkinicity.
- // crush() and arc() are like having good melee capability.
- // Therefore giving them to "harder" class makes less-than-
- // zero sense, and they're now gone.
- const int spell_list[5] =
- { SPELL_MAGIC_DART,
- SPELL_CONFUSING_TOUCH, SPELL_BACKLIGHT,
- SPELL_APPORTATION, SPELL_ANIMATE_SKELETON };
-
- // Choose one of the schools we have at random.
- int school = SK_SPELLCASTING;
- int num_schools = 0;
- for (int i = 0; i < 5; i++)
- {
- if (you.skills[ school_list[ i ]])
- {
- num_schools++;
- if (one_chance_in( num_schools ))
- school = i;
- }
- }
-
- // Magic dart is quite a good spell, so if the player only has
- // spellcasting and conjurations, we sometimes hold off... and
- // treat them like an unskilled spellcaster.
- if (school == SK_SPELLCASTING
- || (num_schools == 1 && school == SK_CONJURATIONS && coinflip()))
- {
- // Not much melee potential and no common spell school,
- // we'll give the player a dagger.
- you.inv[0].sub_type = WPN_DAGGER;
-
- // ... and a random scroll
- give_random_scroll(4);
-
- // ... and knowledge of another
- give_random_scroll(5);
- you.inv[5].quantity = 0;
-
- // ... and a wand.
- give_random_wand(6);
- }
- else
- {
- // Give them an appropriate spell
- add_spell_to_memory( spell_list[ school ] );
- }
- }
- else if (you.skills[ SK_RANGED_COMBAT ] && one_chance_in(3)) // these are rare
- {
- // Ranger style wanderer
- // Rare since starting with a throwing weapon is very good
-
- // Create a default launcher template, but the
- // quantity may be reset to 0 if we don't want one -- bwr
- // thorwing weapons are lowered to -1 to make them
- // not as good as the one's hunters get, ammo is
- // also much smaller -- bwr
- you.inv[1].quantity = 1;
- you.inv[1].base_type = OBJ_WEAPONS;
- you.inv[1].sub_type = WPN_BOW;
- you.inv[1].plus = -1;
- you.inv[1].plus2 = -1;
- you.inv[1].special = 0;
- you.inv[1].colour = BROWN;
-
- // Create default ammo template (darts) (armour is slot 2)
- you.inv[4].base_type = OBJ_MISSILES;
- you.inv[4].sub_type = MI_DART;
- you.inv[4].quantity = 10 + roll_dice( 2, 6 );
- you.inv[4].plus = 0;
- you.inv[4].plus2 = 0;
- you.inv[4].special = 0;
- you.inv[4].colour = LIGHTCYAN;
-
- if (you.skills[ SK_SLINGS ])
- {
- // slingers get some extra ammo
- you.inv[4].quantity += random2avg(20,5);
- you.inv[4].sub_type = MI_STONE;
- you.inv[4].colour = BROWN;
- you.inv[1].sub_type = WPN_SLING;
- you.inv[1].plus = 0; // slings aren't so good
- you.inv[1].plus2 = 0; // so we'll make them +0
-
- you.inv[3].quantity = 0; // remove potion
- you.inv[3].base_type = 0; // forget potion
- you.inv[3].sub_type = 0;
- }
- else if (you.skills[ SK_BOWS ])
- {
- you.inv[4].sub_type = MI_ARROW;
- you.inv[4].colour = BROWN;
- you.inv[1].sub_type = WPN_BOW;
-
- you.inv[3].quantity = 0; // remove potion
- you.inv[3].base_type = 0; // forget potion
- you.inv[3].sub_type = 0;
- }
- else if (you.skills[ SK_CROSSBOWS ])
- {
- // Hand crossbows want the darts.
- you.inv[1].sub_type = WPN_HAND_CROSSBOW;
-
- you.inv[3].quantity = 0; // remove potion
- you.inv[3].base_type = 0; // forget potion
- you.inv[3].sub_type = 0;
- }
- else
- {
- // little extra poisoned darts for throwers
- you.inv[4].quantity += random2avg(10,5);
- set_item_ego_type( you.inv[4], OBJ_MISSILES, SPMSL_POISONED );
-
- you.inv[0].sub_type = WPN_DAGGER; // up knife to dagger
- you.inv[1].quantity = 0; // remove bow
- }
- }
-#endif
- else
- {
- // Generic wanderer
- give_wanderer_weapon( 0, wpn_skill );
- give_random_secondary_armour(5);
- }
-
- you.equip[EQ_WEAPON] = 0;
- you.equip[EQ_BODY_ARMOUR] = 2;
-}
-
-static char letter_to_class(int keyn)
-{
- if (keyn == 'a')
- return JOB_FIGHTER;
- else if (keyn == 'b')
- return JOB_WIZARD;
- else if (keyn == 'c')
- return JOB_PRIEST;
- else if (keyn == 'd')
- return JOB_THIEF;
- else if (keyn == 'e')
- return JOB_GLADIATOR;
- else if (keyn == 'f')
- return JOB_NECROMANCER;
- else if (keyn == 'g')
- return JOB_PALADIN;
- else if (keyn == 'h')
- return JOB_ASSASSIN;
- else if (keyn == 'i')
- return JOB_BERSERKER;
- else if (keyn == 'j')
- return JOB_HUNTER;
- else if (keyn == 'k')
- return JOB_CONJURER;
- else if (keyn == 'l')
- return JOB_ENCHANTER;
- else if (keyn == 'm')
- return JOB_FIRE_ELEMENTALIST;
- else if (keyn == 'n')
- return JOB_ICE_ELEMENTALIST;
- else if (keyn == 'o')
- return JOB_SUMMONER;
- else if (keyn == 'p')
- return JOB_AIR_ELEMENTALIST;
- else if (keyn == 'q')
- return JOB_EARTH_ELEMENTALIST;
- else if (keyn == 'r')
- return JOB_CRUSADER;
- else if (keyn == 's')
- return JOB_DEATH_KNIGHT;
- else if (keyn == 't')
- return JOB_VENOM_MAGE;
- else if (keyn == 'u')
- return JOB_CHAOS_KNIGHT;
- else if (keyn == 'v')
- return JOB_TRANSMUTER;
- else if (keyn == 'w')
- return JOB_HEALER;
- else if (keyn == 'y')
- return JOB_REAVER;
- else if (keyn == 'z')
- return JOB_STALKER;
- else if (keyn == 'A')
- return JOB_MONK;
- else if (keyn == 'B')
- return JOB_WARPER;
- else if (keyn == 'C')
- return JOB_WANDERER;
- return JOB_UNKNOWN;
-}
-
-static char letter_to_species(int keyn)
-{
- switch (keyn)
- {
- case 'a':
- return SP_HUMAN;
- case 'b':
- return SP_ELF;
- case 'c':
- return SP_HIGH_ELF;
- case 'd':
- return SP_GREY_ELF;
- case 'e':
- return SP_DEEP_ELF;
- case 'f':
- return SP_SLUDGE_ELF;
- case 'g':
- return SP_HILL_DWARF;
- case 'h':
- return SP_MOUNTAIN_DWARF;
- case 'i':
- return SP_HALFLING;
- case 'j':
- return SP_HILL_ORC;
- case 'k':
- return SP_KOBOLD;
- case 'l':
- return SP_MUMMY;
- case 'm':
- return SP_NAGA;
- case 'n':
- return SP_GNOME;
- case 'o':
- return SP_OGRE;
- case 'p':
- return SP_TROLL;
- case 'q':
- return SP_OGRE_MAGE;
- case 'r': // draconian
- return SP_RED_DRACONIAN + random2(9); // random drac
- case 's':
- return SP_CENTAUR;
- case 't':
- return SP_DEMIGOD;
- case 'u':
- return SP_SPRIGGAN;
- case 'v':
- return SP_MINOTAUR;
- case 'w':
- return SP_DEMONSPAWN;
- case 'x':
- return SP_GHOUL;
- case 'y':
- return SP_KENKU;
- case 'z':
- return SP_MERFOLK;
- default:
- return 0;
- }
-}
-
-static char species_to_letter(int spec)
-{
- if (spec > SP_RED_DRACONIAN && spec <= SP_BASE_DRACONIAN)
- spec = SP_RED_DRACONIAN;
- else if (spec > SP_BASE_DRACONIAN)
- spec -= SP_BASE_DRACONIAN - SP_RED_DRACONIAN;
- return 'a' + spec - 1;
-}
-
-// choose_race returns true if the player should also pick a class.
-// This is done because of the '*' option which will pick a random
-// character, obviating the necessity of choosing a class.
-
-bool choose_race()
-{
- char keyn;
-
- bool printed = false;
-
- if (Options.cls)
- {
- you.char_class = letter_to_class(Options.cls);
- ng_cls = Options.cls;
- }
-
- if (Options.race != 0)
- printed = true;
-
-spec_query:
- bool prevraceok = Options.prev_race == '?';
- if (!printed)
- {
- clrscr();
-
- if (you.char_class != JOB_UNKNOWN)
- {
- textcolor( BROWN );
- bool shortgreet = false;
- if (strlen(you.your_name) || you.char_class != JOB_UNKNOWN)
- cprintf("Welcome, ");
- else
- {
- cprintf("Welcome.");
- shortgreet = true;
- }
-
- textcolor( YELLOW );
- if (strlen(you.your_name) > 0)
- {
- cprintf(you.your_name);
- if (you.char_class != JOB_UNKNOWN)
- cprintf(" the ");
- }
- if (you.char_class != JOB_UNKNOWN)
- cprintf(get_class_name(you.char_class));
-
- if (!shortgreet)
- cprintf(".");
- }
- else
- {
- textcolor( WHITE );
- cprintf("You must be new here!");
- }
- cprintf(EOL EOL);
- textcolor( CYAN );
- cprintf("You can be:");
- cprintf(EOL EOL);
-
- textcolor( LIGHTGREY );
-
- int linec = 0;
- char linebuf[200];
- *linebuf = 0;
- for (int i = SP_HUMAN; i < NUM_SPECIES; ++i)
- {
- if (i > SP_RED_DRACONIAN && i <= SP_BASE_DRACONIAN)
- continue;
-
- if (you.char_class != JOB_UNKNOWN &&
- !class_allowed(i, you.char_class))
- continue;
-
- char buf[100];
- char sletter = species_to_letter(i);
- snprintf(buf, sizeof buf, "%c - %-26s",
- sletter,
- species_name(i, 1));
- if (sletter == Options.prev_race)
- prevraceok = true;
- strncat(linebuf, buf, sizeof linebuf);
- if (++linec >= 2)
- {
- cprintf("%s" EOL, linebuf);
- *linebuf = 0;
- linec = 0;
- }
- }
-
- if (linec)
- cprintf("%s" EOL, linebuf);
-
- textcolor( BROWN );
-
- if (you.char_class == JOB_UNKNOWN)
- cprintf(EOL "SPACE - Choose class first; "
- "? - Random Species; * - Random Character; X - Quit"
- EOL);
- else
- cprintf(EOL "? - Random; Bksp - Back to class selection; X - Quit"
- EOL);
-
- if (Options.prev_race)
- {
- if (prevraceok)
- cprintf("Enter - %s", get_opt_race_name(Options.prev_race).c_str());
- if (prev_startup_options_set())
- cprintf("%sTAB - %s",
- prevraceok? "; " : "",
- prev_startup_description().c_str());
- cprintf(EOL);
- }
-
- textcolor( CYAN );
- cprintf(EOL "Which one? ");
- textcolor( LIGHTGREY );
-
- printed = true;
- }
-
- if (Options.race != 0)
- {
- keyn = Options.race;
- }
- else
- {
- keyn = c_getch();
- }
-
- if ((keyn == '\r' || keyn == '\n') && Options.prev_race && prevraceok)
- keyn = Options.prev_race;
-
- if (keyn == '\t' && prev_startup_options_set())
- {
- if (Options.prev_randpick ||
- (Options.prev_race == '?' && Options.prev_cls == '?'))
- {
- Options.random_pick = true;
- ng_random = true;
- pick_random_species_and_class();
- return false;
- }
- set_startup_options();
- you.species = 0;
- you.char_class = JOB_UNKNOWN;
- return true;
- }
-
- if (keyn == CK_BKSP || keyn == ' ')
- {
- you.species = 0;
- Options.race = 0;
- return true;
- }
-
- bool randrace = (keyn == '?');
- if (keyn == '?')
- {
- do
- keyn = 'a' + random2(26);
- while (you.char_class != JOB_UNKNOWN &&
- !class_allowed(letter_to_species(keyn), you.char_class));
- }
- else if (keyn == '*')
- {
- pick_random_species_and_class();
- Options.random_pick = true; // used to give random weapon/god as well
- ng_random = true;
- return false;
- }
-
- if (!(you.species = letter_to_species(keyn)))
- {
- switch (keyn)
- {
- case 'X':
- cprintf(EOL "Goodbye!");
- end(0);
- break;
- default:
- if (Options.race != 0)
- {
- Options.race = 0;
- printed = false;
- }
- goto spec_query;
- }
- }
- if (you.species && you.char_class != JOB_UNKNOWN
- && !class_allowed(you.species, you.char_class))
- goto spec_query;
-
- // set to 0 in case we come back from choose_class()
- Options.race = 0;
- ng_race = randrace? '?' : keyn;
-
- return true;
-}
-
-// returns true if a class was chosen, false if we should go back to
-// race selection.
-
-bool choose_class(void)
-{
- char keyn;
- int i,j;
-
- bool printed = false;
- if (Options.cls != 0)
- printed = true;
-
- if (you.species && you.char_class != JOB_UNKNOWN)
- return true;
-
- ng_cls = 0;
-
-job_query:
- bool prevclassok = Options.prev_cls == '?';
- if (!printed)
- {
- clrscr();
-
- if (you.species)
- {
- textcolor( BROWN );
- bool shortgreet = false;
- if (strlen(you.your_name) || you.species)
- cprintf("Welcome, ");
- else
- {
- cprintf("Welcome.");
- shortgreet = true;
- }
-
- textcolor( YELLOW );
- if (strlen(you.your_name) > 0)
- {
- cprintf(you.your_name);
- if (you.species)
- cprintf(" the ");
- }
- if (you.species)
- cprintf(species_name(you.species,you.experience_level));
-
- if (!shortgreet)
- cprintf(".");
- }
- else
- {
- textcolor( WHITE );
- cprintf("You must be new here!");
- }
-
- cprintf(EOL EOL);
- textcolor( CYAN );
- cprintf("You can be:");
- cprintf(EOL EOL);
-
- textcolor( LIGHTGREY );
-
- j = 0; // used within for loop to determine newline {dlb}
-
- for (i = 0; i < NUM_JOBS; i++)
- {
- if (you.species? !class_allowed(you.species, i) : i == JOB_QUITTER)
- continue;
-
- char letter = index_to_letter(i);
-
- if (letter == Options.prev_cls)
- prevclassok = true;
-
- putch( letter );
- cprintf( " - " );
- cprintf( get_class_name(i) );
-
- if (j % 2)
- cprintf(EOL);
- else
- gotoxy(31, wherey());
-
- j++;
- }
-
- if (j % 2)
- cprintf(EOL);
-
- textcolor( BROWN );
- if (!you.species)
- cprintf(EOL "SPACE - Choose species first; "
- "? - Random Class; * - Random Character; X - Quit"
- EOL);
- else
- cprintf(EOL "? - Random; Bksp - Back to species selection; X - Quit"
- EOL);
-
- if (Options.prev_cls)
- {
- if (prevclassok)
- cprintf("Enter - %s", get_opt_class_name(Options.prev_cls).c_str());
- if (prev_startup_options_set())
- cprintf("%sTAB - %s",
- prevclassok? "; " : "",
- prev_startup_description().c_str());
- cprintf(EOL);
- }
-
- textcolor( CYAN );
- cprintf(EOL "Which one? ");
- textcolor( LIGHTGREY );
-
- printed = true;
- }
-
- if (Options.cls != 0)
- {
- keyn = Options.cls;
- }
- else
- {
- keyn = c_getch();
- }
-
- if ((keyn == '\r' || keyn == '\n') && Options.prev_cls && prevclassok)
- keyn = Options.prev_cls;
-
- if (keyn == '\t' && prev_startup_options_set())
- {
- if (Options.prev_randpick ||
- (Options.prev_race == '?' && Options.prev_cls == '?'))
- {
- Options.random_pick = true;
- ng_random = true;
- pick_random_species_and_class();
- return true;
- }
- set_startup_options();
-
- // Toss out old species selection, if any.
- you.species = 0;
- you.char_class = JOB_UNKNOWN;
-
- return false;
- }
-
- if ((you.char_class = letter_to_class(keyn)) == JOB_UNKNOWN)
- {
- if (keyn == '?')
- {
- // pick a job at random... see god retribution for proof this
- // is uniform. -- bwr
- int job_count = 0;
- int job = -1;
-
- for (i = 0; i < NUM_JOBS; i++)
- {
- if (!you.species || class_allowed(you.species, i))
- {
- job_count++;
- if (one_chance_in( job_count ))
- job = i;
- }
- }
-
- ASSERT( job != -1 ); // at least one class should have been allowed
- you.char_class = job;
-
- ng_cls = '?';
- }
- else if (keyn == '*')
- {
- pick_random_species_and_class();
- // used to give random weapon/god as well
- Options.random_pick = true;
- ng_random = true;
- return true;
- }
- else if ((keyn == ' ' && !you.species) ||
- keyn == 'x' || keyn == ESCAPE || keyn == CK_BKSP)
- {
- you.char_class = JOB_UNKNOWN;
- return false;
- }
- else if (keyn == 'X')
- {
- cprintf(EOL "Goodbye!");
- end(0);
- }
- else
- {
- if (Options.cls != 0)
- {
- Options.cls = 0;
- printed = false;
- }
- goto job_query;
- }
- }
-
- if (you.species && !class_allowed(you.species, you.char_class))
- {
- if (Options.cls != 0)
- {
- Options.cls = 0;
- printed = false;
- }
- goto job_query;
- }
-
- if (ng_cls != '?')
- ng_cls = keyn;
-
- return you.char_class != JOB_UNKNOWN && you.species;
-}
-
-
-void give_items_skills()
-{
- char keyn;
- int weap_skill = 0;
- int to_hit_bonus; // used for assigning primary weapons {dlb}
- int choice; // used for third-screen choices
- int tmp;
-
- switch (you.char_class)
- {
- case JOB_FIGHTER:
- you.inv[0].quantity = 1;
- you.inv[0].base_type = OBJ_WEAPONS;
- you.inv[0].sub_type = WPN_SHORT_SWORD;
- you.inv[0].plus = 0;
- you.inv[0].plus2 = 0;
- you.inv[0].special = 0;
- you.inv[0].colour = LIGHTCYAN;
-
- if (you.species == SP_OGRE || you.species == SP_TROLL
- || player_genus(GENPC_DRACONIAN))
- {
- you.inv[1].quantity = 1;
- you.inv[1].base_type = OBJ_ARMOUR;
- you.inv[1].sub_type = ARM_ANIMAL_SKIN;
- you.inv[1].plus = 0;
- you.inv[1].special = 0;
- you.inv[1].colour = BROWN;
-
- if (you.species == SP_OGRE)
- {
- you.inv[0].quantity = 1;
- you.inv[0].base_type = OBJ_WEAPONS;
- you.inv[0].sub_type = WPN_CLUB;
- you.inv[0].plus = 0;
- you.inv[0].special = 0;
- you.inv[0].colour = BROWN;
-
- }
- else if (you.species == SP_TROLL)
- {
- you.inv[0].quantity = 0;
- you.inv[0].base_type = OBJ_WEAPONS;
- you.inv[0].sub_type = WPN_CLUB;
- you.inv[0].plus = 0;
- you.inv[0].special = 0;
- you.inv[0].colour = BROWN;
-
- }
- else if (player_genus(GENPC_DRACONIAN))
- {
- you.inv[2].quantity = 1;
- you.inv[2].base_type = OBJ_ARMOUR;
- you.inv[2].sub_type = ARM_SHIELD;
- you.inv[2].plus = 0;
- you.inv[2].special = 0;
- you.inv[2].colour = LIGHTCYAN;
- }
- }
- else if (you.species == SP_GHOUL || you.species == SP_MUMMY)
- {
- you.inv[1].quantity = 1;
- you.inv[1].base_type = OBJ_ARMOUR;
- you.inv[1].sub_type = ARM_ROBE;
- you.inv[1].plus = 0;
- you.inv[1].special = 0;
- you.inv[1].colour = WHITE; // grave shroud
-
- if (you.species == SP_MUMMY)
- {
- you.inv[2].quantity = 1;
- you.inv[2].base_type = OBJ_ARMOUR;
- you.inv[2].sub_type = ARM_SHIELD;
- you.inv[2].plus = 0;
- you.inv[2].special = 0;
- you.inv[2].colour = LIGHTCYAN;
- }
- }
- else if (you.species == SP_KOBOLD)
- {
- you.inv[1].quantity = 1;
- you.inv[1].base_type = OBJ_ARMOUR;
- you.inv[1].sub_type = ARM_LEATHER_ARMOUR;
- you.inv[1].plus = 0;
- you.inv[1].special = 0;
- you.inv[1].colour = BROWN;
-
- you.inv[2].base_type = OBJ_MISSILES;
- you.inv[2].sub_type = MI_DART;
- you.inv[2].quantity = 10 + roll_dice( 2, 10 );
- you.inv[2].plus = 0;
- you.inv[2].special = 0;
- you.inv[2].colour = LIGHTCYAN;
-
- }
- else
- {
- you.inv[1].quantity = 1;
- you.inv[1].base_type = OBJ_ARMOUR;
- you.inv[1].sub_type = ARM_SCALE_MAIL;
- you.inv[1].plus = 0;
- you.inv[1].special = 0;
- you.inv[1].colour = LIGHTCYAN;
-
- you.inv[2].quantity = 1;
- you.inv[2].base_type = OBJ_ARMOUR;
- you.inv[2].sub_type = ARM_SHIELD;
- you.inv[2].plus = 0;
- you.inv[2].special = 0;
- you.inv[2].colour = LIGHTCYAN;
-
- choose_weapon();
- }
-
- if (you.species != SP_TROLL)
- you.equip[EQ_WEAPON] = 0;
-
- you.equip[EQ_BODY_ARMOUR] = 1;
-
- if (you.species != SP_KOBOLD && you.species != SP_OGRE
- && you.species != SP_TROLL && you.species != SP_GHOUL)
- {
- you.equip[EQ_SHIELD] = 2;
- }
-
- you.skills[SK_FIGHTING] = 3;
-
- weap_skill = 2;
-
- if (you.species == SP_KOBOLD)
- {
- you.skills[SK_RANGED_COMBAT] = 1;
- you.skills[SK_DARTS] = 1;
- you.skills[SK_DODGING] = 1;
- you.skills[SK_STEALTH] = 1;
- you.skills[SK_STABBING] = 1;
- you.skills[SK_DODGING + random2(3)] += 1;
- }
- else if (you.species == SP_OGRE || you.species == SP_TROLL)
- {
- if (you.species == SP_TROLL) //jmf: these guys get no weapon!
- you.skills[SK_UNARMED_COMBAT] += 3;
- else
- you.skills[SK_FIGHTING] += 2;
-
- // BWR sez Ogres & Trolls should probably start w/ Dodge 2 -- GDL
- you.skills[SK_DODGING] = 3;
- }
- else
- {
- // Players get dodging or armour skill depending on their
- // starting armour now (note: the armour has to be quiped
- // for this function to work)
-
- you.skills[(player_light_armour()? SK_DODGING : SK_ARMOUR)] = 2;
-
- you.skills[SK_SHIELDS] = 2;
- you.skills[SK_RANGED_COMBAT] = 2;
- you.skills[(coinflip() ? SK_STABBING : SK_SHIELDS)]++;
- }
- break;
-
- case JOB_WIZARD:
- you.inv[0].quantity = 1;
- you.inv[0].base_type = OBJ_WEAPONS;
-
- if (you.species == SP_OGRE_MAGE)
- {
- you.inv[0].sub_type = WPN_QUARTERSTAFF;
- you.inv[0].colour = BROWN;
- }
- else if (player_genus(GENPC_DWARVEN))
- {
- you.inv[0].sub_type = WPN_HAMMER;
- you.inv[0].colour = CYAN;
- }
- else
- {
- you.inv[0].sub_type = WPN_DAGGER;
- you.inv[0].colour = LIGHTCYAN;
- }
-
- you.inv[0].plus = 0;
- you.inv[0].plus2 = 0;
- you.inv[0].special = 0;
-
- you.inv[1].quantity = 1;
- you.inv[1].base_type = OBJ_ARMOUR;
- you.inv[1].sub_type = ARM_ROBE;
- you.inv[1].plus = 0;
-
- switch (random2(7))
- {
- case 0:
- case 1:
- default:
- set_equip_desc( you.inv[1], ISFLAG_EMBROIDERED_SHINY );
- break;
- case 2:
- case 3:
- set_equip_desc( you.inv[1], ISFLAG_GLOWING );
- break;
- case 4:
- case 5:
- set_equip_desc( you.inv[1], ISFLAG_RUNED );
- break;
- case 6:
- set_equip_race( you.inv[1], ISFLAG_ELVEN );
- break;
- }
-
-
- you.inv[1].colour = random_colour();
- you.equip[EQ_WEAPON] = 0;
- you.equip[EQ_BODY_ARMOUR] = 1;
-
- // extra items being tested:
- you.inv[2].base_type = OBJ_BOOKS;
- you.inv[2].sub_type = BOOK_MINOR_MAGIC_I + random2(3);
- you.inv[2].quantity = 1;
- you.inv[2].plus = 0; // = 127
- you.inv[2].special = 1;
- you.inv[2].colour = CYAN;
-
- you.skills[SK_DODGING] = 1;
- you.skills[SK_STEALTH] = 1;
- you.skills[(coinflip() ? SK_DODGING : SK_STEALTH)]++;
- you.skills[SK_SPELLCASTING] = 2;
- you.skills[SK_CONJURATIONS] = 1;
- you.skills[SK_ENCHANTMENTS] = 1;
- you.skills[SK_SPELLCASTING + random2(3)]++;
- you.skills[SK_SUMMONINGS + random2(5)]++;
-
- if (player_genus(GENPC_DWARVEN))
- you.skills[SK_MACES_FLAILS] = 1;
- else
- you.skills[SK_SHORT_BLADES] = 1;
-
- you.skills[SK_STAVES] = 1;
- break;
-
- case JOB_PRIEST:
- you.piety = 45;
-
- you.inv[0].quantity = 1;
- you.inv[0].base_type = OBJ_WEAPONS;
- you.inv[0].sub_type = WPN_MACE; //jmf: moved from "case 'b'" below
- you.inv[0].plus = 0;
- you.inv[0].plus2 = 0;
- you.inv[0].special = 0;
- you.inv[0].colour = LIGHTCYAN;
-
- you.inv[1].quantity = 1;
- you.inv[1].base_type = OBJ_ARMOUR;
- you.inv[1].sub_type = ARM_ROBE;
- you.inv[1].plus = 0;
- you.inv[1].special = 0;
- you.inv[1].colour = WHITE;
-
- you.inv[2].base_type = OBJ_POTIONS;
- you.inv[2].sub_type = POT_HEALING;
- you.inv[2].quantity = 2;
- you.inv[2].plus = 0;
-
- you.equip[EQ_WEAPON] = 0;
-
- you.equip[EQ_BODY_ARMOUR] = 1;
-
- you.skills[SK_FIGHTING] = 2;
- you.skills[SK_DODGING] = 1;
- you.skills[SK_SHIELDS] = 1;
- you.skills[SK_MACES_FLAILS] = 2;
- you.skills[SK_STAVES] = 1;
-
- you.skills[SK_INVOCATIONS] = 4;
-
- if (Options.priest != GOD_NO_GOD && Options.priest != GOD_RANDOM)
- ng_pr = you.religion = Options.priest;
- else if (Options.random_pick || Options.priest == GOD_RANDOM)
- {
- you.religion = coinflip() ? GOD_YREDELEMNUL : GOD_ZIN;
- ng_pr = GOD_RANDOM;
- }
- else
- {
- clrscr();
-
- textcolor( CYAN );
- cprintf(EOL " Which god do you wish to serve?" EOL);
-
- textcolor( LIGHTGREY );
- cprintf("a - Zin (for traditional priests)" EOL);
- cprintf("b - Yredelemnul (for priests of death)" EOL);
-
- if (Options.prev_pr != GOD_NO_GOD)
- {
- textcolor(BROWN);
- cprintf(EOL "Enter - %s" EOL,
- Options.prev_pr == GOD_ZIN? "Zin" :
- Options.prev_pr == GOD_YREDELEMNUL? "Yredelemnul" :
- "Random");
- }
-
- getkey:
- keyn = get_ch();
-
- if ((keyn == '\r' || keyn == '\n')
- && Options.prev_pr != GOD_NO_GOD)
- {
- keyn = Options.prev_pr == GOD_ZIN? 'a' :
- Options.prev_pr == GOD_YREDELEMNUL? 'b' :
- '?';
-
- }
-
- switch (keyn)
- {
- case '?':
- you.religion = coinflip()? GOD_ZIN : GOD_YREDELEMNUL;
- break;
- case 'a':
- you.religion = GOD_ZIN;
- break;
- case 'b':
- you.religion = GOD_YREDELEMNUL;
- break;
- default:
- goto getkey;
- }
-
- ng_pr = keyn == '?'? GOD_RANDOM : you.religion;
- }
- break;
-
- case JOB_THIEF:
- you.inv[0].quantity = 1;
- you.inv[0].base_type = OBJ_WEAPONS;
- you.inv[0].sub_type = WPN_SHORT_SWORD;
-
- you.inv[0].plus = 0;
- you.inv[0].plus2 = 0;
- you.inv[0].special = 0;
- you.inv[0].colour = LIGHTCYAN;
-
- you.inv[1].quantity = 1;
- you.inv[1].base_type = OBJ_WEAPONS;
- you.inv[1].sub_type = WPN_DAGGER;
-
- you.inv[1].plus = 0;
- you.inv[1].plus2 = 0;
- you.inv[1].special = 0;
- you.inv[1].colour = LIGHTCYAN;
-
- you.inv[2].quantity = 1;
- you.inv[2].base_type = OBJ_ARMOUR;
- you.inv[2].sub_type = ARM_ROBE;
- you.inv[2].plus = 0;
- you.inv[2].special = 0;
- you.inv[2].colour = BROWN;
-
- you.inv[3].quantity = 1;
- you.inv[3].base_type = OBJ_ARMOUR;
- you.inv[3].sub_type = ARM_CLOAK;
- you.inv[3].plus = 0;
- you.inv[3].special = 0;
- you.inv[3].colour = DARKGREY;
-
- you.inv[4].base_type = OBJ_MISSILES;
- you.inv[4].sub_type = MI_DART;
- you.inv[4].quantity = 10 + roll_dice( 2, 10 );
- you.inv[4].plus = 0;
- you.inv[4].special = 0;
- you.inv[4].colour = LIGHTCYAN;
-
- you.equip[EQ_WEAPON] = 0;
- you.equip[EQ_BODY_ARMOUR] = 2;
- you.equip[EQ_CLOAK] = 3;
-
- you.skills[SK_FIGHTING] = 1;
- you.skills[SK_SHORT_BLADES] = 2;
- you.skills[SK_DODGING] = 2;
- you.skills[SK_STEALTH] = 2;
- you.skills[SK_STABBING] = 1;
- you.skills[SK_DODGING + random2(3)]++;
- you.skills[SK_RANGED_COMBAT] = 1;
- you.skills[SK_DARTS] = 1;
- you.skills[SK_TRAPS_DOORS] = 2;
- break;
-
- case JOB_GLADIATOR:
- you.inv[0].quantity = 1;
- you.inv[0].base_type = OBJ_WEAPONS;
- you.inv[0].sub_type = WPN_SHORT_SWORD;
- choose_weapon();
-
- you.inv[0].plus = 0;
- you.inv[0].plus2 = 0;
- you.inv[0].special = 0;
- you.inv[0].colour = LIGHTCYAN;
-
- if (player_genus(GENPC_DRACONIAN))
- {
- you.inv[1].quantity = 1;
- you.inv[1].base_type = OBJ_ARMOUR;
- you.inv[1].sub_type = ARM_ANIMAL_SKIN;
- you.inv[1].plus = 0;
- you.inv[1].special = 0;
- you.inv[1].colour = BROWN;
-
- you.inv[2].quantity = 1;
- you.inv[2].base_type = OBJ_ARMOUR;
- you.inv[2].sub_type = ARM_SHIELD;
- you.inv[2].plus = 0;
- you.inv[2].special = 0;
- you.inv[2].colour = LIGHTCYAN;
- }
- else
- {
- you.inv[1].quantity = 1;
- you.inv[1].base_type = OBJ_ARMOUR;
- you.inv[1].sub_type = ARM_RING_MAIL;
- you.inv[1].plus = 0;
- you.inv[1].special = 0;
- you.inv[1].colour = LIGHTCYAN;
-
- you.inv[2].quantity = 1;
- you.inv[2].base_type = OBJ_ARMOUR;
- you.inv[2].sub_type = ARM_BUCKLER;
- you.inv[2].plus = 0;
- you.inv[2].special = 0;
- you.inv[2].colour = LIGHTCYAN;
- }
-
- you.equip[EQ_WEAPON] = 0;
- you.equip[EQ_BODY_ARMOUR] = 1;
- you.equip[EQ_SHIELD] = 2;
-
- you.skills[SK_FIGHTING] = 3;
- weap_skill = 3;
-
- if (player_genus(GENPC_DRACONIAN))
- you.skills[SK_DODGING] = 2;
- else
- you.skills[SK_ARMOUR] = 2;
-
- you.skills[SK_SHIELDS] = 1;
- you.skills[SK_UNARMED_COMBAT] = 2;
- break;
-
-
- case JOB_NECROMANCER:
- you.inv[0].quantity = 1;
- you.inv[0].base_type = OBJ_WEAPONS;
- you.inv[0].sub_type = WPN_DAGGER;
- you.inv[0].plus = 0;
- you.inv[0].plus2 = 0;
- you.inv[0].special = 0;
- you.inv[0].colour = LIGHTCYAN;
- you.inv[1].quantity = 1;
- you.inv[1].base_type = OBJ_ARMOUR;
- you.inv[1].sub_type = ARM_ROBE;
- you.inv[1].plus = 0;
- you.inv[1].special = 0;
- you.inv[1].colour = DARKGREY;
- you.equip[EQ_WEAPON] = 0;
- you.equip[EQ_BODY_ARMOUR] = 1;
-
- you.inv[2].base_type = OBJ_BOOKS;
- you.inv[2].sub_type = BOOK_NECROMANCY;
- you.inv[2].quantity = 1;
- you.inv[2].plus = 0; // = 127
- you.inv[2].special = 0; // = 1;
- you.inv[2].colour = DARKGREY;
-
- you.skills[SK_DODGING] = 1;
- you.skills[SK_STEALTH] = 1;
- you.skills[(coinflip()? SK_DODGING : SK_STEALTH)]++;
- you.skills[SK_SPELLCASTING] = 1;
- you.skills[SK_NECROMANCY] = 4;
- you.skills[SK_SHORT_BLADES] = 1;
- you.skills[SK_STAVES] = 1;
- break;
-
- case JOB_PALADIN:
- you.religion = GOD_SHINING_ONE;
- you.piety = 28;
-
- you.inv[0].quantity = 1;
- you.inv[0].base_type = OBJ_WEAPONS;
- you.inv[0].sub_type = WPN_FALCHION;
- you.inv[0].plus = 0;
- you.inv[0].plus2 = 0;
- you.inv[0].special = 0;
- you.inv[0].colour = LIGHTCYAN;
-
- you.inv[1].quantity = 1;
- you.inv[1].base_type = OBJ_ARMOUR;
- you.inv[1].sub_type = ARM_ROBE;
- you.inv[1].plus = 0;
- you.inv[1].special = 0;
- you.inv[1].colour = WHITE;
-
- you.inv[2].quantity = 1;
- you.inv[2].base_type = OBJ_ARMOUR;
- you.inv[2].sub_type = ARM_SHIELD;
- you.inv[2].plus = 0;
- you.inv[2].special = 0;
- you.inv[2].colour = LIGHTCYAN;
-
- you.equip[EQ_WEAPON] = 0;
- you.equip[EQ_BODY_ARMOUR] = 1;
- you.equip[EQ_SHIELD] = 2;
-
- you.inv[3].base_type = OBJ_POTIONS;
- you.inv[3].sub_type = POT_HEALING;
- you.inv[3].quantity = 1;
- you.inv[3].plus = 0;
-
- you.skills[SK_FIGHTING] = 2;
- you.skills[SK_ARMOUR] = 1;
- you.skills[SK_DODGING] = 1;
- you.skills[(coinflip()? SK_ARMOUR : SK_DODGING)]++;
- you.skills[SK_SHIELDS] = 2;
- you.skills[SK_LONG_SWORDS] = 3;
- you.skills[SK_INVOCATIONS] = 2;
- break;
-
- case JOB_ASSASSIN:
- you.inv[0].quantity = 1;
- you.inv[0].base_type = OBJ_WEAPONS;
- you.inv[0].sub_type = WPN_DAGGER;
- to_hit_bonus = random2(3);
- you.inv[0].plus = 1 + to_hit_bonus;
- you.inv[0].plus2 = 1 + (2 - to_hit_bonus);
- you.inv[0].special = 0;
- you.inv[0].colour = LIGHTCYAN;
-
- you.inv[1].quantity = 1;
- you.inv[1].base_type = OBJ_WEAPONS;
- you.inv[1].sub_type = WPN_BLOWGUN;
- you.inv[1].plus = 0;
- you.inv[1].plus2 = 0;
- you.inv[1].special = 0;
- you.inv[1].colour = LIGHTGREY;
-
- you.inv[2].quantity = 1;
- you.inv[2].base_type = OBJ_ARMOUR;
- you.inv[2].sub_type = ARM_ROBE;
- you.inv[2].plus = 0;
- you.inv[2].special = 0;
- you.inv[2].colour = DARKGREY;
-
- you.inv[3].quantity = 1;
- you.inv[3].base_type = OBJ_ARMOUR;
- you.inv[3].sub_type = ARM_CLOAK;
- you.inv[3].plus = 0;
- you.inv[3].special = 0;
- you.inv[3].colour = DARKGREY;
-
- you.inv[4].base_type = OBJ_MISSILES;
- you.inv[4].sub_type = MI_NEEDLE;
- you.inv[4].quantity = 10 + roll_dice( 2, 10 );
- you.inv[4].plus = 0;
- you.inv[4].colour = WHITE;
- set_item_ego_type( you.inv[4], OBJ_MISSILES, SPMSL_POISONED );
-
- // deep elves get hand crossbows, everyone else gets blowguns
- // (deep elves tend to suck at melee and need something that
- // can do ranged damage)
- if (you.species == SP_DEEP_ELF)
- {
- you.inv[1].sub_type = WPN_HAND_CROSSBOW;
- you.inv[1].colour = BROWN;
-
- you.inv[4].sub_type = MI_DART;
- you.inv[4].colour = LIGHTCYAN;
- }
-
-
- you.equip[EQ_WEAPON] = 0;
- you.equip[EQ_BODY_ARMOUR] = 2;
- you.equip[EQ_CLOAK] = 3;
-
- you.skills[SK_FIGHTING] = 2;
- you.skills[SK_SHORT_BLADES] = 2;
- you.skills[SK_DODGING] = 1;
- you.skills[SK_STEALTH] = 3;
- you.skills[SK_STABBING] = 2;
- you.skills[SK_RANGED_COMBAT] = 1;
- you.skills[SK_DARTS] = 1;
- if (you.species == SP_DEEP_ELF)
- you.skills[SK_CROSSBOWS] = 1;
- else
- you.skills[SK_RANGED_COMBAT] += 1;
-
- break;
-
- case JOB_BERSERKER:
- you.religion = GOD_TROG;
- you.piety = 35;
-
- // WEAPONS
- if (you.species == SP_OGRE)
- {
- you.inv[0].quantity = 1;
- you.inv[0].base_type = OBJ_WEAPONS;
- you.inv[0].sub_type = WPN_CLUB;
- you.inv[0].plus = 0;
- you.inv[0].plus2 = 0;
- you.inv[0].special = 0;
- you.inv[0].colour = BROWN;
- you.equip[EQ_WEAPON] = 0;
- }
- else if (you.species == SP_TROLL)
- {
- you.equip[EQ_WEAPON] = -1;
- }
- else
- {
- you.inv[0].quantity = 1;
- you.inv[0].base_type = OBJ_WEAPONS;
- you.inv[0].sub_type = WPN_HAND_AXE;
- you.inv[0].plus = 0;
- you.inv[0].plus2 = 0;
- you.inv[0].special = 0;
- you.inv[0].colour = LIGHTCYAN;
- you.equip[EQ_WEAPON] = 0;
-
- for (unsigned char i = 1; i <= 3; i++)
- {
- you.inv[i].quantity = 1;
- you.inv[i].base_type = OBJ_WEAPONS;
- you.inv[i].sub_type = WPN_SPEAR;
- you.inv[i].plus = 0;
- you.inv[i].plus2 = 0;
- you.inv[i].special = 0;
- you.inv[i].colour = LIGHTCYAN;
- }
- }
-
- // ARMOUR
-
- if (you.species == SP_OGRE || you.species == SP_TROLL
- || player_genus(GENPC_DRACONIAN))
- {
- you.inv[1].quantity = 1;
- you.inv[1].base_type = OBJ_ARMOUR;
- you.inv[1].sub_type = ARM_ANIMAL_SKIN;
- you.inv[1].plus = 0;
- you.inv[1].special = 0;
- you.inv[1].colour = BROWN;
- you.equip[EQ_BODY_ARMOUR] = 1;
- }
- else
- {
- you.inv[4].quantity = 1;
- you.inv[4].base_type = OBJ_ARMOUR;
- you.inv[4].sub_type = ARM_LEATHER_ARMOUR;
- you.inv[4].plus = 0;
- you.inv[4].special = 0;
- you.inv[4].colour = BROWN;
- you.equip[EQ_BODY_ARMOUR] = 4;
- }
-
- // SKILLS
- you.skills[SK_FIGHTING] = 2;
-
- if (you.species == SP_TROLL)
- {
- // no wep - give them unarmed.
- you.skills[SK_FIGHTING] += 3;
- you.skills[SK_DODGING] = 2;
- you.skills[SK_UNARMED_COMBAT] = 2;
- }
- else if (you.species == SP_OGRE)
- {
- you.skills[SK_FIGHTING] += 3;
- you.skills[SK_AXES] = 1;
- you.skills[SK_MACES_FLAILS] = 3;
- }
- else
- {
- you.skills[SK_AXES] = 3;
- you.skills[SK_POLEARMS] = 1;
- you.skills[SK_ARMOUR] = 2;
- you.skills[SK_DODGING] = 2;
- you.skills[SK_RANGED_COMBAT] = 2;
- }
- break;
-
- case JOB_HUNTER:
- you.inv[0].quantity = 1;
- you.inv[0].base_type = OBJ_WEAPONS;
- you.inv[0].sub_type = WPN_DAGGER;
- you.inv[0].plus = 0;
- you.inv[0].plus2 = 0;
- you.inv[0].special = 0;
- you.inv[0].colour = LIGHTCYAN;
-
- you.inv[4].quantity = 1;
- you.inv[4].base_type = OBJ_ARMOUR;
- you.inv[4].sub_type = ARM_LEATHER_ARMOUR;
- you.inv[4].plus = 0;
- you.inv[4].special = 0;
- you.inv[4].colour = BROWN;
-
- if (you.species != SP_MERFOLK)
- {
- you.inv[2].quantity = 15 + random2avg(21, 5);
- you.inv[2].base_type = OBJ_MISSILES;
- you.inv[2].sub_type = MI_ARROW;
- you.inv[2].plus = 0;
- you.inv[2].plus2 = 0;
- you.inv[2].special = 0;
- you.inv[2].colour = BROWN;
-
- you.inv[1].quantity = 1;
- you.inv[1].base_type = OBJ_WEAPONS;
- you.inv[1].sub_type = WPN_BOW;
- you.inv[1].plus = 0;
- you.inv[1].plus2 = 0;
- you.inv[1].special = 0;
- you.inv[1].colour = BROWN;
- }
- else
- {
- // Merfolk are spear hunters -- clobber bow, give three spears
- for (unsigned char i = 1; i <= 3; i++)
- {
- you.inv[i].quantity = 1;
- you.inv[i].base_type = OBJ_WEAPONS;
- you.inv[i].sub_type = WPN_SPEAR;
- you.inv[i].plus = 0;
- you.inv[i].plus2 = 0;
- you.inv[i].special = 0;
- you.inv[i].colour = LIGHTCYAN;
- }
- }
-
- if (player_genus(GENPC_DRACONIAN))
- {
- you.inv[4].sub_type = ARM_ROBE;
- you.inv[4].colour = GREEN;
- }
-
- you.equip[EQ_WEAPON] = 0;
- you.equip[EQ_BODY_ARMOUR] = 4;
-
- you.skills[SK_FIGHTING] = 2;
- you.skills[SK_RANGED_COMBAT] = 3;
-
- // Removing spellcasting -- bwr
- // you.skills[SK_SPELLCASTING] = 1;
-
- switch (you.species)
- {
- case SP_HALFLING:
- case SP_GNOME:
- you.inv[2].quantity += random2avg(15, 2);
- you.inv[2].sub_type = MI_STONE;
- you.inv[2].colour = BROWN;
- you.inv[1].sub_type = WPN_SLING;
-
- you.skills[SK_DODGING] = 2;
- you.skills[SK_STEALTH] = 2;
- you.skills[SK_SLINGS] = 2;
- break;
-
- case SP_HILL_DWARF:
- case SP_MOUNTAIN_DWARF:
- case SP_HILL_ORC:
- you.inv[2].sub_type = MI_BOLT;
- you.inv[2].colour = LIGHTCYAN;
- you.inv[1].sub_type = WPN_CROSSBOW;
-
- if (you.species == SP_HILL_ORC)
- {
- you.inv[0].sub_type = WPN_SHORT_SWORD;
- you.skills[SK_SHORT_BLADES] = 1;
- }
- else
- {
- you.inv[0].sub_type = WPN_HAND_AXE;
- you.skills[SK_AXES] = 1;
- }
-
- you.skills[SK_DODGING] = 1;
- you.skills[SK_SHIELDS] = 1;
- you.skills[SK_CROSSBOWS] = 2;
- break;
-
- case SP_MERFOLK:
- you.inv[0].sub_type = WPN_TRIDENT;
-
- you.skills[SK_POLEARMS] = 2;
- you.skills[SK_DODGING] = 2;
- you.skills[SK_RANGED_COMBAT] += 1;
- break;
-
- default:
- you.skills[SK_DODGING] = 1;
- you.skills[SK_STEALTH] = 1;
- you.skills[(coinflip() ? SK_STABBING : SK_SHIELDS)]++;
- you.skills[SK_BOWS] = 2;
- break;
- }
- break;
-
- case JOB_CONJURER:
- case JOB_ENCHANTER:
- case JOB_SUMMONER:
- case JOB_FIRE_ELEMENTALIST:
- case JOB_ICE_ELEMENTALIST:
- case JOB_AIR_ELEMENTALIST:
- case JOB_EARTH_ELEMENTALIST:
- case JOB_VENOM_MAGE:
- you.inv[0].quantity = 1;
- you.inv[0].base_type = OBJ_WEAPONS;
- you.inv[0].sub_type = WPN_DAGGER;
- you.inv[0].colour = LIGHTCYAN;
- you.inv[0].plus = 0;
- you.inv[0].plus2 = 0;
- you.inv[0].special = 0;
-
- you.inv[1].quantity = 1;
- you.inv[1].base_type = OBJ_ARMOUR;
- you.inv[1].sub_type = ARM_ROBE;
- you.inv[1].plus = 0;
-
- if (you.char_class == JOB_ENCHANTER)
- {
- you.inv[0].plus = 1;
- you.inv[0].plus2 = 1;
- you.inv[1].plus = 1;
- }
-
- you.inv[1].special = 0;
-
- you.equip[EQ_WEAPON] = 0;
- you.equip[EQ_BODY_ARMOUR] = 1;
- you.inv[2].base_type = OBJ_BOOKS;
- you.inv[2].sub_type = give_first_conjuration_book();
- you.inv[2].plus = 0;
-
- switch (you.char_class)
- {
- case JOB_SUMMONER:
- you.inv[2].sub_type = BOOK_CALLINGS;
-
- you.skills[SK_SUMMONINGS] = 4;
-
- // gets some darts - this class is difficult to start off with
- you.inv[3].base_type = OBJ_MISSILES;
- you.inv[3].sub_type = MI_DART;
- you.inv[3].quantity = 8 + roll_dice( 2, 8 );
- you.inv[3].plus = 0;
- you.inv[3].special = 0;
- you.inv[3].colour = LIGHTCYAN;
- break;
-
- case JOB_CONJURER:
- you.skills[SK_CONJURATIONS] = 4;
- break;
-
- case JOB_ENCHANTER:
- you.inv[2].sub_type = BOOK_CHARMS;
-
- you.skills[SK_ENCHANTMENTS] = 4;
-
- // gets some darts - this class is difficult to start off with
- you.inv[3].base_type = OBJ_MISSILES;
- you.inv[3].sub_type = MI_DART;
- you.inv[3].quantity = 8 + roll_dice( 2, 8 );
- you.inv[3].plus = 1;
- you.inv[3].special = 0;
- you.inv[3].colour = LIGHTCYAN;
-
- if (you.species == SP_SPRIGGAN)
- {
- you.inv[0].base_type = OBJ_STAVES;
- you.inv[0].sub_type = STAFF_STRIKING;
- you.inv[0].colour = BROWN;
- }
- break;
-
- case JOB_FIRE_ELEMENTALIST:
- you.inv[2].sub_type = BOOK_FLAMES;
-
- you.skills[SK_CONJURATIONS] = 1;
- you.skills[SK_FIRE_MAGIC] = 3;
- //you.skills [SK_ENCHANTMENTS] = 1;
- break;
-
- case JOB_ICE_ELEMENTALIST:
- you.inv[2].sub_type = BOOK_FROST;
-
- you.skills[SK_CONJURATIONS] = 1;
- you.skills[SK_ICE_MAGIC] = 3;
- //you.skills [SK_ENCHANTMENTS] = 1;
- break;
-
- case JOB_AIR_ELEMENTALIST:
- you.inv[2].sub_type = BOOK_AIR;
-
- you.skills[SK_CONJURATIONS] = 1;
- you.skills[SK_AIR_MAGIC] = 3;
- //you.skills [SK_ENCHANTMENTS] = 1;
- break;
-
- case JOB_EARTH_ELEMENTALIST:
- you.inv[2].sub_type = BOOK_GEOMANCY;
-
- you.inv[3].quantity = random2avg(12, 2) + 6;
- you.inv[3].base_type = OBJ_MISSILES;
- you.inv[3].sub_type = MI_STONE;
- you.inv[3].plus = 0;
- you.inv[3].plus2 = 0;
- you.inv[3].special = 0;
- you.inv[3].colour = BROWN;
-
- if (you.species == SP_GNOME)
- {
- you.inv[1].quantity = 1;
- you.inv[1].base_type = OBJ_WEAPONS;
- you.inv[1].sub_type = WPN_SLING;
- you.inv[1].plus = 0;
- you.inv[1].plus2 = 0;
- you.inv[1].special = 0;
- you.inv[1].colour = BROWN;
-
- you.inv[4].quantity = 1;
- you.inv[4].base_type = OBJ_ARMOUR;
- you.inv[4].sub_type = ARM_ROBE;
- you.inv[4].plus = 0;
- you.inv[4].plus2 = 0;
- you.inv[4].special = 0;
- you.inv[4].colour = BROWN;
- you.equip[EQ_BODY_ARMOUR] = 4;
-
- }
- you.skills[SK_TRANSMIGRATION] = 1;
- you.skills[SK_EARTH_MAGIC] = 3;
- break;
-
- case JOB_VENOM_MAGE:
- you.inv[2].sub_type = BOOK_YOUNG_POISONERS;
- you.skills[SK_POISON_MAGIC] = 4;
- break;
- }
-
- if (you.species == SP_OGRE_MAGE)
- {
- you.inv[0].sub_type = WPN_QUARTERSTAFF;
- you.inv[0].colour = BROWN;
- }
- else if (player_genus(GENPC_DWARVEN))
- {
- you.inv[0].sub_type = WPN_HAMMER;
- you.inv[0].colour = CYAN;
- }
-
- you.inv[2].quantity = 1;
- you.inv[2].special = 0;
-
- switch (you.char_class)
- {
- case JOB_FIRE_ELEMENTALIST: tmp = RED; break;
- case JOB_ICE_ELEMENTALIST: tmp = LIGHTCYAN; break;
- case JOB_AIR_ELEMENTALIST: tmp = LIGHTBLUE; break;
- case JOB_EARTH_ELEMENTALIST: tmp = BROWN; break;
- case JOB_VENOM_MAGE: tmp = GREEN; break;
- default: tmp = random_colour(); break;
- }
-
- you.inv[1].colour = tmp; // robe
- you.inv[2].colour = tmp; // book
-
- you.skills[SK_SPELLCASTING] = 1;
-
- // These summoner races start with polearms and should they
- // get their hands on a polearm of reaching they should have
- // lots of fun... -- bwr
- if (you.char_class == JOB_SUMMONER
- && (you.species == SP_MERFOLK || you.species == SP_HILL_ORC ||
- you.species == SP_KENKU || you.species == SP_MINOTAUR))
- {
- if (you.species == SP_MERFOLK)
- you.inv[0].sub_type = WPN_TRIDENT;
- else
- you.inv[0].sub_type = WPN_SPEAR;
-
- you.skills[SK_POLEARMS] = 1;
- }
- else if (player_genus(GENPC_DWARVEN))
- {
- you.skills[SK_MACES_FLAILS] = 1;
- }
- else if (you.char_class == JOB_ENCHANTER && you.species == SP_SPRIGGAN)
- {
- you.skills[SK_EVOCATIONS] = 1;
- }
- else
- {
- you.skills[SK_SHORT_BLADES] = 1;
- }
-
- if (you.species == SP_GNOME)
- you.skills[SK_SLINGS]++;
- else
- you.skills[SK_STAVES]++;
-
- you.skills[SK_DODGING] = 1;
- you.skills[SK_STEALTH] = 1;
-
- if (you.species == SP_GNOME && you.char_class == JOB_EARTH_ELEMENTALIST)
- you.skills[SK_RANGED_COMBAT]++;
- else
- you.skills[ coinflip() ? SK_DODGING : SK_STEALTH ]++;
- break;
-
- case JOB_TRANSMUTER:
- // some sticks for sticks to snakes:
- you.inv[1].quantity = 6 + roll_dice( 3, 4 );
- you.inv[1].base_type = OBJ_MISSILES;
- you.inv[1].sub_type = MI_ARROW;
- you.inv[1].plus = 0;
- you.inv[1].plus2 = 0;
- you.inv[1].special = 0;
- you.inv[1].colour = BROWN;
-
- you.inv[2].base_type = OBJ_ARMOUR;
- you.inv[2].sub_type = ARM_ROBE;
- you.inv[2].plus = 0;
- you.inv[2].special = 0;
- you.inv[2].quantity = 1;
- you.inv[2].colour = BROWN;
-
- you.inv[3].base_type = OBJ_BOOKS;
- you.inv[3].sub_type = BOOK_CHANGES;
- you.inv[3].quantity = 1;
- you.inv[3].plus = 0;
- you.inv[3].special = 0;
- you.inv[3].colour = random_colour();
-
- // A little bit of starting ammo for evaporate... don't need too
- // much now that the character can make their own. -- bwr
- //
- // some ammo for evaporate:
- you.inv[4].base_type = OBJ_POTIONS;
- you.inv[4].sub_type = POT_CONFUSION;
- you.inv[4].quantity = 2;
- you.inv[4].plus = 0;
-
- // some more ammo for evaporate:
- you.inv[5].base_type = OBJ_POTIONS;
- you.inv[5].sub_type = POT_POISON;
- you.inv[5].quantity = 1;
- you.inv[5].plus = 0;
-
- you.equip[EQ_WEAPON] = -1;
- you.equip[EQ_BODY_ARMOUR] = 2;
-
- you.skills[SK_FIGHTING] = 1;
- you.skills[SK_UNARMED_COMBAT] = 3;
- you.skills[SK_RANGED_COMBAT] = 2;
- you.skills[SK_DODGING] = 2;
- you.skills[SK_SPELLCASTING] = 2;
- you.skills[SK_TRANSMIGRATION] = 2;
-
- if (you.species == SP_SPRIGGAN)
- {
- you.inv[0].base_type = OBJ_STAVES;
- you.inv[0].sub_type = STAFF_STRIKING;
- you.inv[0].quantity = 1;
- you.inv[0].plus = 0;
- you.inv[0].plus2 = 0;
- you.inv[0].special = 0;
- you.inv[0].colour = BROWN;
-
- you.skills[SK_EVOCATIONS] = 2;
- you.skills[SK_FIGHTING] = 0;
-
- you.equip[EQ_WEAPON] = 0;
- }
- break;
-
- case JOB_WARPER:
- you.inv[0].quantity = 1;
- you.inv[0].plus = 0;
- you.inv[0].plus2 = 0;
- you.inv[0].special = 0;
- you.inv[0].colour = LIGHTCYAN;
-
- if (you.species == SP_SPRIGGAN)
- {
- you.inv[0].base_type = OBJ_STAVES;
- you.inv[0].sub_type = STAFF_STRIKING;
- you.inv[0].colour = BROWN;
-
- you.skills[SK_EVOCATIONS] = 3;
- }
- else
- {
- you.inv[0].base_type = OBJ_WEAPONS;
- you.inv[0].sub_type = WPN_SHORT_SWORD;
-
- if (you.species == SP_OGRE_MAGE)
- {
- you.inv[0].sub_type = WPN_QUARTERSTAFF;
- you.inv[0].colour = BROWN;
- }
-
- weap_skill = 2;
- you.skills[SK_FIGHTING] = 1;
- }
-
- you.inv[1].base_type = OBJ_ARMOUR;
- you.inv[1].sub_type = ARM_LEATHER_ARMOUR;
- you.inv[1].quantity = 1;
- you.inv[1].plus = 0;
- you.inv[1].special = 0;
- you.inv[1].colour = BROWN;
-
- if (you.species == SP_SPRIGGAN || you.species == SP_OGRE_MAGE)
- you.inv[1].sub_type = ARM_ROBE;
-
- you.inv[2].base_type = OBJ_BOOKS;
- you.inv[2].sub_type = BOOK_SPATIAL_TRANSLOCATIONS;
- you.inv[2].quantity = 1;
- you.inv[2].plus = 0;
- you.inv[2].special = 0;
- you.inv[2].colour = random_colour();
-
- // one free escape:
- you.inv[3].base_type = OBJ_SCROLLS;
- you.inv[3].sub_type = SCR_BLINKING;
- you.inv[3].quantity = 1;
- you.inv[3].plus = 0;
- you.inv[3].special = 0;
- you.inv[3].colour = WHITE;
-
- you.inv[4].base_type = OBJ_MISSILES;
- you.inv[4].sub_type = MI_DART;
- you.inv[4].quantity = 10 + roll_dice( 2, 10 );
- you.inv[4].plus = 0;
- you.inv[4].special = 0;
- you.inv[4].colour = LIGHTCYAN;
-
- you.equip[EQ_WEAPON] = 0;
- you.equip[EQ_BODY_ARMOUR] = 1;
-
- you.skills[SK_RANGED_COMBAT] = 1;
- you.skills[SK_DARTS] = 2;
- you.skills[SK_DODGING] = 2;
- you.skills[SK_STEALTH] = 1;
- you.skills[SK_SPELLCASTING] = 2;
- you.skills[SK_TRANSLOCATIONS] = 2;
- break;
-
- case JOB_CRUSADER:
- you.inv[0].quantity = 1;
- you.inv[0].base_type = OBJ_WEAPONS;
- you.inv[0].sub_type = WPN_SHORT_SWORD;
-
- //if (you.species == SP_OGRE_MAGE) you.inv_sub_type [0] = WPN_GLAIVE;
-
- you.inv[0].plus = 0;
- you.inv[0].plus2 = 0;
- you.inv[0].special = 0;
- you.inv[0].colour = LIGHTCYAN;
- choose_weapon();
- weap_skill = 2;
- you.inv[1].quantity = 1;
- you.inv[1].base_type = OBJ_ARMOUR;
- you.inv[1].sub_type = ARM_ROBE;
- you.inv[1].plus = 0;
- you.inv[1].special = 0;
- you.inv[1].colour = random_colour();
-
- you.inv[2].base_type = OBJ_BOOKS;
- you.inv[2].sub_type = BOOK_WAR_CHANTS;
- you.inv[2].quantity = 1;
- you.inv[2].plus = 0;
- you.inv[2].special = 0;
- you.inv[2].colour = random_colour();
-
- you.equip[EQ_WEAPON] = 0;
- you.equip[EQ_BODY_ARMOUR] = 1;
-
- you.skills[SK_FIGHTING] = 3;
- you.skills[SK_ARMOUR] = 1;
- you.skills[SK_DODGING] = 1;
- you.skills[SK_STEALTH] = 1;
- you.skills[SK_SPELLCASTING] = 2;
- you.skills[SK_ENCHANTMENTS] = 2;
- break;
-
-
- case JOB_DEATH_KNIGHT:
- you.inv[0].quantity = 1;
- you.inv[0].base_type = OBJ_WEAPONS;
- you.inv[0].sub_type = WPN_SHORT_SWORD;
- you.inv[0].plus = 0;
- you.inv[0].plus2 = 0;
- you.inv[0].special = 0;
- you.inv[0].colour = LIGHTCYAN;
- choose_weapon();
- weap_skill = 2;
-
- you.inv[1].quantity = 1;
- you.inv[1].base_type = OBJ_ARMOUR;
- you.inv[1].sub_type = ARM_ROBE;
- you.inv[1].plus = 0;
- you.inv[1].special = 0;
- you.inv[1].colour = DARKGREY;
-
- you.inv[2].base_type = OBJ_BOOKS;
- you.inv[2].sub_type = BOOK_NECROMANCY;
- you.inv[2].quantity = 1;
- you.inv[2].plus = 0;
- you.inv[2].special = 0;
- you.inv[2].colour = DARKGREY;
-
- you.equip[EQ_WEAPON] = 0;
- you.equip[EQ_BODY_ARMOUR] = 1;
-
- choice = DK_NO_SELECTION;
-
- // order is important here -- bwr
- if (you.species == SP_DEMIGOD)
- choice = DK_NECROMANCY;
- else if (Options.death_knight != DK_NO_SELECTION
- && Options.death_knight != DK_RANDOM)
- {
- ng_dk = choice = Options.death_knight;
- }
- else if (Options.random_pick || Options.death_knight == DK_RANDOM)
- {
- choice = (coinflip() ? DK_NECROMANCY : DK_YREDELEMNUL);
- ng_dk = DK_RANDOM;
- }
- else
- {
- clrscr();
-
- textcolor( CYAN );
- cprintf(EOL " From where do you draw your power?" EOL);
-
- textcolor( LIGHTGREY );
- cprintf("a - Necromantic magic" EOL);
- cprintf("b - the god Yredelemnul" EOL);
-
- if (Options.prev_dk != DK_NO_SELECTION)
- {
- textcolor(BROWN);
- cprintf(EOL "Enter - %s" EOL,
- Options.prev_dk == DK_NECROMANCY? "Necromancy" :
- Options.prev_dk == DK_YREDELEMNUL? "Yredelemnul" :
- "Random");
- }
-
- getkey1:
- keyn = get_ch();
-
- if ((keyn == '\r' || keyn == '\n')
- && Options.prev_dk != DK_NO_SELECTION)
- {
- keyn = Options.prev_dk == DK_NECROMANCY? 'a' :
- Options.prev_dk == DK_YREDELEMNUL? 'b' :
- '?';
- }
-
- switch (keyn)
- {
- case '?':
- choice = coinflip()? DK_NECROMANCY : DK_YREDELEMNUL;
- break;
- case 'a':
- cprintf(EOL "Very well.");
- choice = DK_NECROMANCY;
- break;
- case 'b':
- choice = DK_YREDELEMNUL;
- break;
- default:
- goto getkey1;
- }
-
- ng_dk = keyn == '?'? DK_RANDOM : choice;
- }
-
- switch (choice)
- {
- default: // this shouldn't happen anyways -- bwr
- case DK_NECROMANCY:
- you.skills[SK_SPELLCASTING] = 1;
- you.skills[SK_NECROMANCY] = 2;
- break;
- case DK_YREDELEMNUL:
- you.religion = GOD_YREDELEMNUL;
- you.piety = 28;
- you.inv[0].plus = 1;
- you.inv[0].plus2 = 1;
- you.inv[2].quantity = 0;
- you.skills[SK_INVOCATIONS] = 3;
- break;
- }
-
- you.skills[SK_FIGHTING] = 2;
- you.skills[SK_ARMOUR] = 1;
- you.skills[SK_DODGING] = 1;
- you.skills[SK_STEALTH] = 1;
- //you.skills [SK_SHORT_BLADES] = 2;
- you.skills[SK_STABBING] = 1;
- break;
-
- case JOB_CHAOS_KNIGHT:
- you.piety = 25; // irrelevant for Xom, of course
- you.inv[0].quantity = 1;
- you.inv[0].base_type = OBJ_WEAPONS;
- you.inv[0].sub_type = WPN_SHORT_SWORD;
- you.inv[0].plus = random2(3);
- you.inv[0].plus2 = random2(3);
- you.inv[0].special = 0;
-
- if (one_chance_in(5))
- set_equip_desc( you.inv[0], ISFLAG_RUNED );
-
- if (one_chance_in(5))
- set_equip_desc( you.inv[0], ISFLAG_GLOWING );
-
- you.inv[0].colour = LIGHTCYAN;
- choose_weapon();
- weap_skill = 2;
- you.inv[1].quantity = 1;
- you.inv[1].base_type = OBJ_ARMOUR;
- you.inv[1].sub_type = ARM_ROBE;
- you.inv[1].plus = random2(3);
- you.inv[1].special = 0;
- you.inv[1].colour = random_colour();
-
- you.equip[EQ_WEAPON] = 0;
- you.equip[EQ_BODY_ARMOUR] = 1;
-
- you.skills[SK_FIGHTING] = 3;
- you.skills[SK_ARMOUR] = 1;
- you.skills[SK_DODGING] = 1;
- you.skills[(coinflip()? SK_ARMOUR : SK_DODGING)]++;
- you.skills[SK_STABBING] = 1;
-
- if (Options.chaos_knight != GOD_NO_GOD
- && Options.chaos_knight != GOD_RANDOM)
- {
- ng_ck = you.religion = Options.chaos_knight;
- }
- else if (Options.random_pick || Options.chaos_knight == GOD_RANDOM)
- {
- you.religion = coinflip() ? GOD_XOM : GOD_MAKHLEB;
- ng_ck = GOD_RANDOM;
- }
- else
- {
- clrscr();
-
- textcolor( CYAN );
- cprintf(EOL " Which god of chaos do you wish to serve?" EOL);
-
- textcolor( LIGHTGREY );
- cprintf("a - Xom of Chaos" EOL);
- cprintf("b - Makhleb the Destroyer" EOL);
-
- if (Options.prev_ck != GOD_NO_GOD)
- {
- textcolor(BROWN);
- cprintf(EOL "Enter - %s" EOL,
- Options.prev_ck == GOD_XOM? "Xom" :
- Options.prev_ck == GOD_MAKHLEB? "Makhleb" :
- "Random");
- textcolor(LIGHTGREY);
- }
-
- getkey2:
-
- keyn = get_ch();
-
- if ((keyn == '\r' || keyn == '\n')
- && Options.prev_ck != GOD_NO_GOD)
- {
- keyn = Options.prev_ck == GOD_XOM? 'a' :
- Options.prev_ck == GOD_MAKHLEB? 'b' :
- '?';
- }
-
- switch (keyn)
- {
- case '?':
- you.religion = coinflip()? GOD_XOM : GOD_MAKHLEB;
- break;
- case 'a':
- you.religion = GOD_XOM;
- break;
- case 'b':
- you.religion = GOD_MAKHLEB;
- break;
- default:
- goto getkey2;
- }
-
- ng_ck = keyn == '?'? GOD_RANDOM : you.religion;
- }
-
- if (you.religion == GOD_XOM)
- you.skills[SK_FIGHTING]++;
- else // you.religion == GOD_MAKHLEB
- you.skills[SK_INVOCATIONS] = 2;
-
- break;
-
- case JOB_HEALER:
- you.religion = GOD_ELYVILON;
- you.piety = 45;
-
- you.inv[0].quantity = 1;
- you.inv[0].base_type = OBJ_WEAPONS;
- you.inv[0].sub_type = WPN_QUARTERSTAFF;
- you.inv[0].colour = BROWN;
- you.inv[0].plus = 0;
- you.inv[0].plus2 = 0;
- you.inv[0].special = 0;
-
- // Robe
- you.inv[1].quantity = 1;
- you.inv[1].base_type = OBJ_ARMOUR;
- you.inv[1].sub_type = ARM_ROBE;
- you.inv[1].plus = 0;
- you.inv[1].special = 0;
- you.inv[1].colour = WHITE;
-
- you.inv[2].base_type = OBJ_POTIONS;
- you.inv[2].sub_type = POT_HEALING;
- you.inv[2].quantity = 1;
- you.inv[2].plus = 0;
-
- you.inv[3].base_type = OBJ_POTIONS;
- you.inv[3].sub_type = POT_HEAL_WOUNDS;
- you.inv[3].quantity = 1;
- you.inv[3].plus = 0;
-
- you.equip[EQ_WEAPON] = 0;
- you.equip[EQ_BODY_ARMOUR] = 1;
-
- you.skills[SK_FIGHTING] = 2;
- you.skills[SK_DODGING] = 1;
- you.skills[SK_SHIELDS] = 1;
- you.skills[SK_RANGED_COMBAT] = 2;
- you.skills[SK_STAVES] = 3;
- you.skills[SK_INVOCATIONS] = 2;
- break;
-
- case JOB_REAVER:
- you.inv[0].quantity = 1;
- you.inv[0].base_type = OBJ_WEAPONS;
- you.inv[0].sub_type = WPN_SHORT_SWORD;
- you.inv[0].plus = 0;
- you.inv[0].plus2 = 0;
- you.inv[0].special = 0;
- you.inv[0].colour = LIGHTCYAN;
- choose_weapon();
- weap_skill = 3;
-
- you.inv[1].quantity = 1;
- you.inv[1].base_type = OBJ_ARMOUR;
- you.inv[1].sub_type = ARM_ROBE;
- you.inv[1].plus = 0;
- you.inv[1].special = 0;
- you.inv[1].colour = RED;
-
- you.inv[2].base_type = OBJ_BOOKS;
- you.inv[2].sub_type = give_first_conjuration_book();
- you.inv[2].quantity = 1;
- you.inv[2].plus = 0; // = 127
- you.inv[2].special = 0;
- you.inv[2].colour = RED;
-
- you.equip[EQ_WEAPON] = 0;
- you.equip[EQ_BODY_ARMOUR] = 1;
-
- you.skills[SK_FIGHTING] = 2;
- you.skills[SK_ARMOUR] = 1;
- you.skills[SK_DODGING] = 1;
-
- you.skills[SK_SPELLCASTING] = 1;
- you.skills[SK_CONJURATIONS] = 2;
- break;
-
- case JOB_STALKER:
- you.inv[0].quantity = 1;
- you.inv[0].base_type = OBJ_WEAPONS;
- you.inv[0].sub_type = WPN_DAGGER;
- to_hit_bonus = random2(3);
- you.inv[0].plus = 1 + to_hit_bonus;
- you.inv[0].plus2 = 1 + (2 - to_hit_bonus);
- you.inv[0].special = 0;
- you.inv[0].colour = LIGHTCYAN;
-
- you.inv[1].quantity = 1;
- you.inv[1].base_type = OBJ_ARMOUR;
- you.inv[1].sub_type = ARM_ROBE;
- you.inv[1].plus = 0;
- you.inv[1].special = 0;
- you.inv[1].colour = GREEN;
-
- you.inv[2].quantity = 1;
- you.inv[2].base_type = OBJ_ARMOUR;
- you.inv[2].sub_type = ARM_CLOAK;
- you.inv[2].plus = 0;
- you.inv[2].special = 0;
- you.inv[2].colour = DARKGREY;
-
- you.inv[3].base_type = OBJ_BOOKS;
- //you.inv[3].sub_type = BOOK_YOUNG_POISONERS;
- you.inv[3].sub_type = BOOK_STALKING; //jmf: new book!
- you.inv[3].quantity = 1;
- you.inv[3].plus = 0;
- you.inv[3].special = 0;
- you.inv[3].colour = GREEN;
-
- you.equip[EQ_WEAPON] = 0;
- you.equip[EQ_BODY_ARMOUR] = 1;
- you.equip[EQ_CLOAK] = 2;
-
- you.skills[SK_FIGHTING] = 1;
- you.skills[SK_SHORT_BLADES] = 1;
- you.skills[SK_POISON_MAGIC] = 1;
- you.skills[SK_DODGING] = 1;
- you.skills[SK_STEALTH] = 2;
- you.skills[SK_STABBING] = 2;
- you.skills[SK_DODGING + random2(3)]++;
- //you.skills[SK_RANGED_COMBAT] = 1; //jmf: removed these, added magic below
- //you.skills[SK_DARTS] = 1;
- you.skills[SK_SPELLCASTING] = 1;
- you.skills[SK_ENCHANTMENTS] = 1;
- break;
-
- case JOB_MONK:
- you.inv[0].base_type = OBJ_ARMOUR;
- you.inv[0].sub_type = ARM_ROBE;
- you.inv[0].plus = 0;
- you.inv[0].special = 0;
- you.inv[0].quantity = 1;
- you.inv[0].colour = BROWN;
-
- you.equip[EQ_WEAPON] = -1;
- you.equip[EQ_BODY_ARMOUR] = 0;
-
- you.skills[SK_FIGHTING] = 3;
- you.skills[SK_UNARMED_COMBAT] = 4;
- you.skills[SK_DODGING] = 3;
- you.skills[SK_STEALTH] = 2;
- break;
-
- case JOB_WANDERER:
- create_wanderer();
- break;
- }
-
- if (weap_skill)
- you.skills[weapon_skill(OBJ_WEAPONS, you.inv[0].sub_type)] = weap_skill;
-
- init_skill_order();
-
- if (you.religion != GOD_NO_GOD)
- {
- you.worshipped[you.religion] = 1;
- set_god_ability_slots();
- }
-}
diff --git a/stone_soup/crawl-ref/source/newgame.h b/stone_soup/crawl-ref/source/newgame.h
deleted file mode 100644
index 6b71e483ba..0000000000
--- a/stone_soup/crawl-ref/source/newgame.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * File: newgame.cc
- * Summary: Functions used when starting a new game.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef NEWGAME_H
-#define NEWGAME_H
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-bool new_game();
-
-int give_first_conjuration_book();
-
-#endif
diff --git a/stone_soup/crawl-ref/source/ouch.cc b/stone_soup/crawl-ref/source/ouch.cc
deleted file mode 100644
index 5fa0ff13bd..0000000000
--- a/stone_soup/crawl-ref/source/ouch.cc
+++ /dev/null
@@ -1,1046 +0,0 @@
-/*
- * File: ouch.cc
- * Summary: Functions used when Bad Things happen to the player.
- * Written by: Linley Henzell
- *
- * Modified for Crawl Reference by $Author$ on $Date$
- *
- * Change History (most recent first):
- *
- * <8> 7/30/00 JDJ Fixed end_game so that it works with filenames longer than 6 characters.
- * <7> 19 June 2000 GDL Changed handle to FILE *
- * <6> 11/23/99 LRH Fixed file purging for DOS?
- * <5> 9/29/99 BCR Fixed highscore so that it
- * doesn't take so long. Also
- * added some whitespace to the scores.
- * Fixed problem with uniques and 'a'.
- * <4> 6/13/99 BWR applied a mix of DML and my tmp
- * file purging improvements.
- * <3> 5/26/99 JDJ highscore() will print more scores on
- * larger windows.
- * <2> 5/21/99 BWR Added SCORE_FILE_ENTRIES, so
- * that more top scores can be
- * saved.
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-
-#include <string.h>
-#include <string>
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <time.h>
-
-#ifdef DOS
-#include <conio.h>
-#include <file.h>
-#endif
-
-#ifdef UNIX
-#include <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
-#endif
-
-#ifdef USE_EMX
-#include <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
-#endif
-
-#ifdef OS9
-#include <stat.h>
-#else
-#include <sys/stat.h>
-#endif
-
-#include "ouch.h"
-
-#ifdef __MINGW32__
-#include <io.h>
-#endif
-
-#include "externs.h"
-
-#include "chardump.h"
-#include "delay.h"
-#include "files.h"
-#include "hiscores.h"
-#include "invent.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "items.h"
-#include "macro.h"
-#include "mon-util.h"
-#include "player.h"
-#include "randart.h"
-#include "religion.h"
-#include "shopping.h"
-#include "skills2.h"
-#include "spells4.h"
-#include "stuff.h"
-#include "view.h"
-
-
-void end_game( struct scorefile_entry &se );
-void item_corrode( char itco );
-
-
-/* NOTE: DOES NOT check for hellfire!!! */
-int check_your_resists(int hurted, int flavour)
-{
- int resist;
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "checking resistance: flavour=%d", flavour );
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- if (flavour == BEAM_FIRE || flavour == BEAM_LAVA
- || flavour == BEAM_HELLFIRE || flavour == BEAM_FRAG)
- {
- if (you.duration[DUR_CONDENSATION_SHIELD] > 0)
- {
- mpr( "Your icy shield dissipates!", MSGCH_DURATION );
- you.duration[DUR_CONDENSATION_SHIELD] = 0;
- you.redraw_armour_class = 1;
- }
- }
-
- switch (flavour)
- {
- case BEAM_FIRE:
- resist = player_res_fire();
- if (resist > 0)
- {
- canned_msg(MSG_YOU_RESIST);
- hurted /= (1 + (resist * resist));
- }
- else if (resist < 0)
- {
- mpr("It burns terribly!");
- hurted *= 15;
- hurted /= 10;
- }
- break;
-
- case BEAM_COLD:
- resist = player_res_cold();
- if (resist > 0)
- {
- canned_msg(MSG_YOU_RESIST);
- hurted /= (1 + (resist * resist));
- }
- else if (resist < 0)
- {
- mpr("You feel a terrible chill!");
- hurted *= 15;
- hurted /= 10;
- }
- break;
-
- case BEAM_ELECTRICITY:
- resist = player_res_electricity();
- if (resist >= 3)
- {
- canned_msg(MSG_YOU_RESIST);
- hurted = 0;
- }
- else if (resist > 0)
- {
- canned_msg(MSG_YOU_RESIST);
- hurted /= 3;
- }
- break;
-
-
- case BEAM_POISON:
- resist = player_res_poison();
-
- if (!resist)
- poison_player( coinflip() ? 2 : 1 );
- else
- {
- canned_msg(MSG_YOU_RESIST);
- hurted /= 3;
- }
- break;
-
- case BEAM_POISON_ARROW:
- // [dshaligram] NOT importing uber-poison arrow from 4.1. Giving no
- // bonus to poison resistant players seems strange and unnecessarily
- // arbitrary.
- resist = player_res_poison();
-
- if (!resist)
- poison_player( 6 + random2(3), true );
- else
- {
- mpr("You partially resist.");
- hurted /= 2;
-
- if (!you.is_undead)
- poison_player( 2 + random2(3), true );
- }
- break;
-
- case BEAM_NEG:
- resist = player_prot_life();
-
- if (resist > 0)
- {
- hurted -= (resist * hurted) / 3;
- }
-
- drain_exp();
- break;
-
- case BEAM_ICE:
- resist = player_res_cold();
-
- if (resist > 0)
- {
- mpr("You partially resist.");
- hurted /= 2;
- }
- else if (resist < 0)
- {
- mpr("You feel a painful chill!");
- hurted *= 13;
- hurted /= 10;
- }
- break;
-
- case BEAM_LAVA:
- resist = player_res_fire();
-
- if (resist > 1)
- {
- mpr("You partially resist.");
- hurted /= (1 + resist);
- }
- else if (resist < 0)
- {
- mpr("It burns terribly!");
- hurted *= 15;
- hurted /= 10;
- }
- break;
-
- case BEAM_ACID:
- if (player_res_acid())
- {
- canned_msg( MSG_YOU_RESIST );
- hurted /= 3;
- }
- break;
-
- case BEAM_MIASMA:
- if (player_prot_life() > random2(3))
- {
- canned_msg( MSG_YOU_RESIST );
- hurted = 0;
- }
- break;
-
- case BEAM_HOLY:
- if (!you.is_undead && you.species != SP_DEMONSPAWN)
- {
- canned_msg( MSG_YOU_RESIST );
- hurted = 0;
- }
- break;
- } /* end switch */
-
- return (hurted);
-} // end check_your_resists()
-
-void splash_with_acid( char acid_strength )
-{
- /* affects equip only?
- assume that a message has already been sent, also that damage has
- already been done
- */
- char splc = 0;
- int dam = 0;
-
- const bool wearing_cloak = (you.equip[EQ_CLOAK] == -1);
-
- for (splc = EQ_CLOAK; splc <= EQ_BODY_ARMOUR; splc++)
- {
- if (you.equip[splc] == -1)
- {
- if (!wearing_cloak || coinflip())
- dam += roll_dice( 1, acid_strength );
-
- continue;
- }
-
- if (random2(20) <= acid_strength)
- item_corrode( you.equip[splc] );
- }
-
- if (dam)
- {
- mpr( "The acid burns!" );
- ouch( dam, 0, KILLED_BY_ACID );
- }
-} // end splash_with_acid()
-
-void weapon_acid( char acid_strength )
-{
- char hand_thing = you.equip[EQ_WEAPON];
-
- if (hand_thing == -1)
- hand_thing = you.equip[EQ_GLOVES];
-
- if (hand_thing == -1)
- {
- snprintf( info, INFO_SIZE, "Your %s burn!", your_hand(true) );
- mpr( info );
-
- ouch( roll_dice( 1, acid_strength ), 0, KILLED_BY_ACID );
- }
- else if (random2(20) <= acid_strength)
- {
- item_corrode( hand_thing );
- }
-} // end weapon_acid()
-
-void item_corrode( char itco )
-{
- int chance_corr = 0; // no idea what its full range is {dlb}
- bool it_resists = false; // code simplifier {dlb}
- bool suppress_msg = false; // code simplifier {dlb}
- int how_rusty = ((you.inv[itco].base_type == OBJ_WEAPONS)
- ? you.inv[itco].plus2 : you.inv[itco].plus);
-
- // early return for "oRC and cloak/preservation {dlb}:
- if (wearing_amulet(AMU_RESIST_CORROSION) && !one_chance_in(10))
- {
-#if DEBUG_DIAGNOSTICS
- mpr( "Amulet protects.", MSGCH_DIAGNOSTICS );
-#endif
- return;
- }
-
- // early return for items already pretty d*** rusty {dlb}:
- if (how_rusty < -5)
- return;
-
- // determine possibility of resistance by object type {dlb}:
- switch (you.inv[itco].base_type)
- {
- case OBJ_ARMOUR:
- if (is_random_artefact( you.inv[itco] ))
- {
- it_resists = true;
- suppress_msg = true;
- }
- else if ((you.inv[itco].sub_type == ARM_CRYSTAL_PLATE_MAIL
- || get_equip_race(you.inv[itco]) == ISFLAG_DWARVEN)
- && !one_chance_in(5))
- {
- it_resists = true;
- suppress_msg = false;
- }
- break;
-
- case OBJ_WEAPONS:
- if (is_fixed_artefact(you.inv[itco])
- || is_random_artefact(you.inv[itco]))
- {
- it_resists = true;
- suppress_msg = true;
- }
- else if (get_equip_race(you.inv[itco]) == ISFLAG_DWARVEN
- && !one_chance_in(5))
- {
- it_resists = true;
- suppress_msg = false;
- }
- break;
-
- case OBJ_MISSILES:
- if (get_equip_race(you.inv[itco]) == ISFLAG_DWARVEN
- && !one_chance_in(5))
- {
- it_resists = true;
- suppress_msg = false;
- }
- break;
- }
-
- // determine chance of corrosion {dlb}:
- if (!it_resists)
- {
- chance_corr = abs( how_rusty );
-
- // ---------------------------- but it needs to stay this way
- // (as it *was* this way)
-
- // the embedded equation may look funny, but it actually works well
- // to generate a pretty probability ramp {6%, 18%, 34%, 58%, 98%}
- // for values [0,4] which closely matches the original, ugly switch
- // {dlb}
- if (chance_corr >= 0 && chance_corr <= 4)
- {
- it_resists = (random2(100) <
- 2 + (2 << (1 + chance_corr)) + (chance_corr * 8));
- }
- else
- it_resists = true; // no idea how often this occurs {dlb}
-
- // if the checks get this far, you should hear about it {dlb}
- suppress_msg = false;
- }
-
- // handle message output and item damage {dlb}:
- if (!suppress_msg)
- {
- char str_pass[ ITEMNAME_SIZE ];
- in_name(itco, DESC_CAP_YOUR, str_pass);
- strcpy(info, str_pass);
- strcat(info, (it_resists) ? " resists." : " is eaten away!");
- mpr(info);
- }
-
- if (!it_resists)
- {
- how_rusty--;
-
- if (you.inv[itco].base_type == OBJ_WEAPONS)
- you.inv[itco].plus2 = how_rusty;
- else
- you.inv[itco].plus = how_rusty;
-
- you.redraw_armour_class = 1; // for armour, rings, etc. {dlb}
-
- if (you.equip[EQ_WEAPON] == itco)
- you.wield_change = true;
- }
-
- return;
-} // end item_corrode()
-
-void scrolls_burn(char burn_strength, char target_class)
-{
-
- unsigned char burnc;
- unsigned char burn2;
- unsigned char burn_no = 0;
-
- if (wearing_amulet(AMU_CONSERVATION) && !one_chance_in(10))
- {
-#if DEBUG_DIAGNOSTICS
- mpr( "Amulet conserves.", MSGCH_DIAGNOSTICS );
-#endif
- return;
- }
-
- for (burnc = 0; burnc < ENDOFPACK; burnc++)
- {
- if (!you.inv[burnc].quantity)
- continue;
- if (you.inv[burnc].base_type != target_class)
- continue;
-
- for (burn2 = 0; burn2 < you.inv[burnc].quantity; burn2++)
- {
- if (random2(70) < burn_strength)
- {
- burn_no++;
-
- if (burnc == you.equip[EQ_WEAPON])
- you.wield_change = true;
-
- if (dec_inv_item_quantity( burnc, 1 ))
- break;
- }
- }
- }
-
- if (burn_no == 1)
- {
- if (target_class == OBJ_SCROLLS)
- mpr("A scroll you are carrying catches fire!");
- else if (target_class == OBJ_POTIONS)
- mpr("A potion you are carrying freezes and shatters!");
- else if (target_class == OBJ_FOOD)
- mpr("Some of your food is covered with spores!");
- }
- else if (burn_no > 1)
- {
- if (target_class == OBJ_SCROLLS)
- mpr("Some of the scrolls you are carrying catch fire!");
- else if (target_class == OBJ_POTIONS)
- mpr("Some of the potions you are carrying freeze and shatter!");
- else if (target_class == OBJ_FOOD)
- mpr("Some of your food is covered with spores!");
- }
- /* burn_no could be 0 */
-}
-
- // end scrolls_burn()
-void lose_level(void)
-{
- // because you.experience is unsigned long, if it's going to be -ve
- // must die straightaway.
- if (you.experience_level == 1)
- ouch( -9999, 0, KILLED_BY_DRAINING );
-
- you.experience = exp_needed( you.experience_level + 1 ) - 1;
- you.experience_level--;
-
- snprintf( info, INFO_SIZE, "You are now a level %d %s!",
- you.experience_level, you.class_name );
- mpr( info, MSGCH_WARN );
-
- // Constant value to avoid grape jelly trick... see level_change() for
- // where these HPs and MPs are given back. -- bwr
- ouch( 4, 0, KILLED_BY_DRAINING );
- dec_max_hp(4);
-
- dec_mp(1);
- dec_max_mp(1);
-
- calc_hp();
- calc_mp();
-
- you.redraw_experience = 1;
-} // end lose_level()
-
-void drain_exp(void)
-{
- int protection = player_prot_life();
-
- if (you.duration[DUR_PRAYER]
- && (you.religion == GOD_ZIN || you.religion == GOD_SHINING_ONE)
- && random2(150) < you.piety)
- {
- simple_god_message(" protects your life force!");
- return;
- }
-
- if (protection >= 3 || you.is_undead)
- {
- mpr("You fully resist.");
- return;
- }
-
- if (you.experience == 0)
- ouch(-9999, 0, KILLED_BY_DRAINING);
-
- if (you.experience_level == 1)
- {
- you.experience = 0;
- return;
- }
-
- unsigned long total_exp = exp_needed( you.experience_level + 2 )
- - exp_needed( you.experience_level + 1 );
- unsigned long exp_drained = total_exp * (10 + random2(11));
-
- exp_drained /= 100;
-
- if (protection > 0)
- {
- mpr("You partially resist.");
- exp_drained -= (protection * exp_drained) / 3;
- }
-
- if (exp_drained > 0)
- {
- mpr("You feel drained.");
- you.experience -= exp_drained;
- you.exp_available -= exp_drained;
-
- if (you.exp_available < 0)
- you.exp_available = 0;
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "You lose %ld experience points.",
- exp_drained );
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- you.redraw_experience = 1;
-
- if (you.experience < exp_needed(you.experience_level + 1))
- lose_level();
- }
-} // end drain_exp()
-
-// death_source should be set to zero for non-monsters {dlb}
-void ouch( int dam, int death_source, char death_type, const char *aux )
-{
- int d = 0;
- int e = 0;
-
- ait_hp_loss hpl(dam, death_type);
- interrupt_activity( AI_HP_LOSS, &hpl );
-
- if (you.deaths_door && death_type != KILLED_BY_LAVA
- && death_type != KILLED_BY_WATER)
- {
- return;
- }
-
- // assumed bug for high damage amounts
- if (dam > 300)
- {
- snprintf( info, INFO_SIZE,
- "Potential bug: Unexpectedly high damage = %d", dam );
- mpr( info, MSGCH_DANGER );
- return;
- }
-
- if (you_are_delayed())
- {
- stop_delay();
- }
-
- if (dam > -9000) // that is, a "death" caused by hp loss {dlb}
- {
- switch (you.religion)
- {
- case GOD_XOM:
- if (random2(you.hp_max) > you.hp && dam > random2(you.hp)
- && one_chance_in(5))
- {
- simple_god_message( " protects you from harm!" );
- return;
- }
- break;
-
- case GOD_ZIN:
- case GOD_SHINING_ONE:
- case GOD_ELYVILON:
- case GOD_OKAWARU:
- case GOD_YREDELEMNUL:
- if (dam >= you.hp && you.duration[DUR_PRAYER]
- && random2(you.piety) >= 30)
- {
- simple_god_message( " protects you from harm!" );
- return;
- }
- break;
- }
-
- // Damage applied here:
- dec_hp( dam, true );
-
- // Even if we have low HP messages off, we'll still give a
- // big hit warning (in this case, a hit for half our HPs) -- bwr
- if (dam > 0 && you.hp_max <= dam * 2)
- mpr( "Ouch! That really hurt!", MSGCH_DANGER );
-
- if (you.hp > 0 && Options.hp_warning
- && you.hp <= (you.hp_max * Options.hp_warning) / 100)
- {
- mpr( "* * * LOW HITPOINT WARNING * * *", MSGCH_DANGER );
- }
-
- if (you.hp > 0)
- return;
- }
-
-#ifdef WIZARD
- if (death_type != KILLED_BY_QUITTING
- && death_type != KILLED_BY_WINNING
- && death_type != KILLED_BY_LEAVING)
- {
- if (you.wizard)
- {
-#ifdef USE_OPTIONAL_WIZARD_DEATH
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "Damage: %d; Hit points: %d", dam, you.hp );
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif // DEBUG_DIAGNOSTICS
-
- if (!yesno("Die?", false, 'n'))
- {
- set_hp(you.hp_max, false);
- return;
- }
-#else // !def USE_OPTIONAL_WIZARD_DEATH
- mpr("Since you're a debugger, I'll let you live.");
- mpr("Be more careful next time, okay?");
-
- set_hp(you.hp_max, false);
- return;
-#endif // USE_OPTIONAL_WIZARD_DEATH
- }
- }
-#endif // WIZARD
-
- //okay, so you're dead:
-
- // do points first.
- long points = you.gold;
- points += (you.experience * 7) / 10;
-
- //if (death_type == KILLED_BY_WINNING) points += points / 2;
- //if (death_type == KILLED_BY_LEAVING) points += points / 10;
- // these now handled by giving player the value of their inventory
- char temp_id[4][50];
-
- for (d = 0; d < 4; d++)
- {
- for (e = 0; e < 50; e++)
- temp_id[d][e] = 1;
- }
-
- // CONSTRUCT SCOREFILE ENTRY
- struct scorefile_entry se;
-
- // Score file entry version:
- //
- // 4.0 - original versioned entry
- // 4.1 - added real_time and num_turn fields
- // 4.2 - stats and god info
-
- se.version = 4;
- se.release = 2;
-
- strncpy( se.name, you.your_name, kNameLen );
- se.name[ kNameLen - 1 ] = '\0';
-#ifdef MULTIUSER
- se.uid = (int) getuid();
-#else
- se.uid = 0;
-#endif
-
- FixedVector< int, NUM_RUNE_TYPES > rune_array;
-
- se.num_runes = 0;
- se.num_diff_runes = 0;
-
- for (int i = 0; i < NUM_RUNE_TYPES; i++)
- rune_array[i] = 0;
-
- // Calculate value of pack and runes when character leaves dungeon
- if (death_type == KILLED_BY_LEAVING || death_type == KILLED_BY_WINNING)
- {
- for (d = 0; d < ENDOFPACK; d++)
- {
- if (is_valid_item( you.inv[d] ))
- {
- points += item_value( you.inv[d], temp_id, true );
-
- if (you.inv[d].base_type == OBJ_MISCELLANY
- && you.inv[d].sub_type == MISC_RUNE_OF_ZOT)
- {
- if (rune_array[ you.inv[d].plus ] == 0)
- se.num_diff_runes++;
-
- se.num_runes += you.inv[d].quantity;
- rune_array[ you.inv[d].plus ] += you.inv[d].quantity;
- }
- }
- }
-
- // Bonus for exploring different areas, not for collecting a
- // huge stack of demonic runes in Pandemonium (gold value
- // is enough for those). -- bwr
- if (se.num_diff_runes >= 3)
- points += ((se.num_diff_runes + 2) * (se.num_diff_runes + 2) * 1000);
- }
-
- // Players will have a hard time getting 1/10 of this (see XP cap):
- if (points > 99999999)
- points = 99999999;
-
- se.points = points;
- se.race = you.species;
- se.cls = you.char_class;
-
- // strcpy(se.race_class_name, "");
- se.race_class_name[0] = '\0';
-
- se.lvl = you.experience_level;
- se.best_skill = best_skill( SK_FIGHTING, NUM_SKILLS - 1, 99 );
- se.best_skill_lvl = you.skills[ se.best_skill ];
- se.death_type = death_type;
-
- // for death by monster
-
- // Set the default aux data value...
- // If aux is passed in (ie for a trap), we'll default to that.
- if (aux == NULL)
- se.auxkilldata[0] = '\0';
- else
- {
- strncpy( se.auxkilldata, aux, ITEMNAME_SIZE );
- se.auxkilldata[ ITEMNAME_SIZE - 1 ] = '\0';
- }
-
- if ((death_type == KILLED_BY_MONSTER || death_type == KILLED_BY_BEAM)
- && death_source >= 0 && death_source < MAX_MONSTERS)
- {
- struct monsters *monster = &menv[death_source];
-
- if (monster->type > 0 || monster->type <= NUM_MONSTERS)
- {
- se.death_source = monster->type;
- se.mon_num = monster->number;
-
- // Previously the weapon was only used for dancing weapons,
- // but now we pass it in as a string through the scorefile
- // entry to be appended in hiscores_format_single in long or
- // medium scorefile formats.
- // It still isn't used in monam for anything but flying weapons
- // though
- if (death_type == KILLED_BY_MONSTER
- && monster->inv[MSLOT_WEAPON] != NON_ITEM)
- {
-#if HISCORE_WEAPON_DETAIL
- set_ident_flags( mitm[monster->inv[MSLOT_WEAPON]],
- ISFLAG_IDENT_MASK );
-#else
- // changing this to ignore the pluses to keep it short
- unset_ident_flags( mitm[monster->inv[MSLOT_WEAPON]],
- ISFLAG_IDENT_MASK );
-
- set_ident_flags( mitm[monster->inv[MSLOT_WEAPON]],
- ISFLAG_KNOW_TYPE );
-
- // clear "runed" description text to make shorter yet
- set_equip_desc( mitm[monster->inv[MSLOT_WEAPON]], 0 );
-#endif
-
- // Setting this is redundant for dancing weapons, however
- // we do care about the above indentification. -- bwr
- if (monster->type != MONS_DANCING_WEAPON)
- {
- it_name( monster->inv[MSLOT_WEAPON], DESC_NOCAP_A, info );
- strncpy( se.auxkilldata, info, ITEMNAME_SIZE );
- se.auxkilldata[ ITEMNAME_SIZE - 1 ] = '\0';
- }
- }
-
- strcpy( info,
- monam( monster->number, monster->type, true, DESC_NOCAP_A,
- monster->inv[MSLOT_WEAPON] ) );
-
- strncpy( se.death_source_name, info, 40 );
- se.death_source_name[39] = '\0';
- }
- }
- else
- {
- se.death_source = death_source;
- se.mon_num = 0;
- se.death_source_name[0] = '\0';
- }
-
- se.damage = dam;
- se.final_hp = you.hp;
- se.final_max_hp = you.hp_max;
- se.final_max_max_hp = you.hp_max + player_rotted();
- se.str = you.strength;
- se.intel = you.intel;
- se.dex = you.dex;
-
- se.god = you.religion;
- if (you.religion != GOD_NO_GOD)
- {
- se.piety = you.piety;
- se.penance = you.penance[you.religion];
- }
-
- // main dungeon: level is simply level
- se.dlvl = you.your_level + 1;
- switch (you.where_are_you)
- {
- case BRANCH_ORCISH_MINES:
- case BRANCH_HIVE:
- case BRANCH_LAIR:
- case BRANCH_SLIME_PITS:
- case BRANCH_VAULTS:
- case BRANCH_CRYPT:
- case BRANCH_HALL_OF_BLADES:
- case BRANCH_HALL_OF_ZOT:
- case BRANCH_ECUMENICAL_TEMPLE:
- case BRANCH_SNAKE_PIT:
- case BRANCH_ELVEN_HALLS:
- case BRANCH_TOMB:
- case BRANCH_SWAMP:
- se.dlvl = you.your_level - you.branch_stairs[you.where_are_you - 10];
- break;
-
- case BRANCH_DIS:
- case BRANCH_GEHENNA:
- case BRANCH_VESTIBULE_OF_HELL:
- case BRANCH_COCYTUS:
- case BRANCH_TARTARUS:
- case BRANCH_INFERNO:
- case BRANCH_THE_PIT:
- se.dlvl = you.your_level - 26;
- break;
- }
-
- se.branch = you.where_are_you; // no adjustments necessary.
- se.level_type = you.level_type; // pandemonium, labyrinth, dungeon..
-
- se.birth_time = you.birth_time; // start time of game
- se.death_time = time( NULL ); // end time of game
-
- if (you.real_time != -1)
- se.real_time = you.real_time + (se.death_time - you.start_time);
- else
- se.real_time = -1;
-
- se.num_turns = you.num_turns;
-
-#ifdef WIZARD
- se.wiz_mode = (you.wizard ? 1 : 0);
-#else
- se.wiz_mode = 0;
-#endif
-
-#ifdef SCORE_WIZARD_CHARACTERS
- // add this highscore to the score file.
- hiscores_new_entry(se);
-#else
-
- // only add non-wizards to the score file.
- // never generate bones files of wizard characters -- bwr
- if (!you.wizard)
- {
- hiscores_new_entry(se);
-
- if (death_type != KILLED_BY_LEAVING && death_type != KILLED_BY_WINNING)
- save_ghost();
- }
-
-#endif
-
- end_game(se);
-}
-
-void end_game( struct scorefile_entry &se )
-{
- int i;
- char del_file[300]; // massive overkill!
- bool dead = true;
-
- if (se.death_type == KILLED_BY_LEAVING ||
- se.death_type == KILLED_BY_WINNING)
- {
- dead = false;
- }
-
- // clean all levels that we think we have ever visited
- for (int level = 0; level < MAX_LEVELS; level++)
- {
- for (int dungeon = 0; dungeon < MAX_BRANCHES; dungeon++)
- {
- if (tmp_file_pairs[level][dungeon])
- {
- make_filename( info, you.your_name, level, dungeon,
- false, false );
- unlink(info);
- }
- }
- }
-
- // temp level, if any
- make_filename( info, you.your_name, 0, 0, true, false );
- unlink(info);
-
- // create base file name
-#ifdef SAVE_DIR_PATH
- snprintf( info, INFO_SIZE, SAVE_DIR_PATH "%s%d", you.your_name, (int) getuid());
-#else
- strncpy(info, you.your_name, kFileNameLen);
- info[kFileNameLen] = '\0';
-#endif
-
- // this is to catch the game package if it still exists.
-#ifdef PACKAGE_SUFFIX
- strcpy(del_file, info);
- strcat(del_file, "." PACKAGE_SUFFIX);
- unlink(del_file);
-#endif
-
- // last, but not least, delete player .sav file
- strcpy(del_file, info);
-
- std::string basefile = del_file;
-
- strcat(del_file, ".sav");
- unlink(del_file);
-
- // Delete record of stashes, kills, travel cache and lua save.
- unlink( (basefile + ".st").c_str() );
- unlink( (basefile + ".kil").c_str() );
- unlink( (basefile + ".tc").c_str() );
-#ifdef CLUA_BINDINGS
- unlink( (basefile + ".lua").c_str() );
-#endif
-
- // death message
- if (dead)
- {
- mpr("You die..."); // insert player name here? {dlb}
- viewwindow(1, false); // don't do this for leaving/winning characters
- }
- more();
-
- for (i = 0; i < ENDOFPACK; i++)
- set_ident_flags( you.inv[i], ISFLAG_IDENT_MASK );
-
- for (i = 0; i < ENDOFPACK; i++)
- {
- if (you.inv[i].base_type != 0)
- {
- set_ident_type( you.inv[i].base_type,
- you.inv[i].sub_type, ID_KNOWN_TYPE );
- }
- }
-
- invent( -1, dead );
- clrscr();
-
- if (!dump_char( "morgue.txt", !dead ))
- mpr("Char dump unsuccessful! Sorry about that.");
-#if DEBUG_DIAGNOSTICS
- //jmf: switched logic and moved "success" message to debug-only
- else
- mpr("Char dump successful! (morgue.txt).");
-#endif // DEBUG
-
- more();
-
- clrscr();
-#ifdef DOS_TERM
- window(1, 1, 80, 25);
-#endif
-
- clrscr();
- cprintf( "Goodbye, " );
- cprintf( you.your_name );
- cprintf( "." );
- cprintf( EOL EOL " " ); // Space padding where # would go in list format
-
- char scorebuff[ HIGHSCORE_SIZE ];
-
- const int lines = hiscores_format_single_long( scorebuff, se, true );
-
- // truncate
- scorebuff[ HIGHSCORE_SIZE - 1 ] = '\0';
- cprintf( scorebuff );
-
- cprintf( EOL "Best Crawlers -" EOL );
-
- // "- 5" gives us an extra line in case the description wraps on a line.
- hiscores_print_list( get_number_of_lines() - lines - 5 );
-
- // just to pause, actual value returned does not matter {dlb}
- get_ch();
- end(0);
-}
diff --git a/stone_soup/crawl-ref/source/ouch.h b/stone_soup/crawl-ref/source/ouch.h
deleted file mode 100644
index 23894dade5..0000000000
--- a/stone_soup/crawl-ref/source/ouch.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * File: ouch.cc
- * Summary: Functions used when Bad Things happen to the player.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <2> 9/29/99 BCR Added the DEATH_NAME_LENGTH define
- * It determines how many characters of
- * a long player name are printed in
- * the score list.
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef OUCH_H
-#define OUCH_H
-
-
-#define DEATH_NAME_LENGTH 10
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: bang - beam - effects - spells
- * *********************************************************************** */
-int check_your_resists(int hurted, int flavour);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: fight
- * *********************************************************************** */
-void splash_with_acid(char acid_strength);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: fight
- * *********************************************************************** */
-void weapon_acid(char acid_strength);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - bang - beam - effects - fight - misc - spells -
- * spells2
- * *********************************************************************** */
-void scrolls_burn(char burn_strength, char target_class);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - bang - beam - command - effects - fight - misc -
- * ouch - output - religion - spells - spells2 - spells4
- * *********************************************************************** */
-void ouch(int dam, int death_source, char death_type, const char *aux = NULL);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: decks - ouch
- * *********************************************************************** */
-void lose_level(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: decks - fight - item_use - ouch - religion - spells
- * *********************************************************************** */
-void drain_exp(void);
-
-
-#endif
diff --git a/stone_soup/crawl-ref/source/output.cc b/stone_soup/crawl-ref/source/output.cc
deleted file mode 100644
index 415e970fc0..0000000000
--- a/stone_soup/crawl-ref/source/output.cc
+++ /dev/null
@@ -1,818 +0,0 @@
-/*
- * File: output.cc
- * Summary: Functions used to print player related info.
- * Written by: Linley Henzell
- *
- * Modified for Crawl Reference by $Author$ on $Date$
- *
- * Change History (most recent first):
- *
- * <2> 5/20/99 BWR Efficiency changes for curses.
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "output.h"
-
-#include <stdlib.h>
-
-#ifdef DOS
-#include <conio.h>
-#endif
-
-#include "externs.h"
-
-#include "fight.h"
-#include "itemname.h"
-#include "menu.h"
-#include "ouch.h"
-#include "player.h"
-#include "religion.h"
-#include "skills2.h"
-#include "stuff.h"
-
-static int bad_ench_colour( int lvl, int orange, int red )
-{
- if (lvl > red)
- return (RED);
- else if (lvl > orange)
- return (LIGHTRED);
-
- return (YELLOW);
-}
-
-static void dur_colour( int colour, bool running_out )
-{
- if (running_out)
- textcolor( colour );
- else
- {
- switch (colour)
- {
- case GREEN: textcolor( LIGHTGREEN ); break;
- case BLUE: textcolor( LIGHTBLUE ); break;
- case MAGENTA: textcolor( LIGHTMAGENTA ); break;
- case LIGHTGREY: textcolor( WHITE ); break;
- }
- }
-}
-
-void print_stats(void)
-{
- textcolor(LIGHTGREY);
-
- if (you.redraw_hit_points)
- {
- const int max_max_hp = you.hp_max + player_rotted();
- const int hp_warn = MAXIMUM( 25, Options.hp_warning );
- const int hp_attent = MAXIMUM( 10, Options.hp_attention );
-
- gotoxy(44, 3);
-
- if (you.hp <= (you.hp_max * hp_warn) / 100)
- textcolor(RED);
- else if (you.hp <= (you.hp_max * hp_attent) / 100)
- textcolor(YELLOW);
-
- cprintf( "%d", you.hp );
-
- textcolor(LIGHTGREY);
- cprintf( "/%d", you.hp_max );
-
- if (max_max_hp != you.hp_max)
- cprintf( " (%d)", max_max_hp );
-
-#ifdef UNIX
- clear_to_end_of_line();
-#else
- cprintf(" ");
-#endif
-
- you.redraw_hit_points = 0;
- }
-
- if (you.redraw_magic_points)
- {
- gotoxy(47, 4);
-
- cprintf( "%d/%d", you.magic_points, you.max_magic_points );
-
-#ifdef UNIX
- clear_to_end_of_line();
-#else
- cprintf(" ");
-#endif
-
- you.redraw_magic_points = 0;
- }
-
- if (you.redraw_strength)
- {
- if (you.strength < 0)
- you.strength = 0;
- else if (you.strength > 72)
- you.strength = 72;
-
- if (you.max_strength > 72)
- you.max_strength = 72;
-
- gotoxy(45, 7);
-
- if (you.might)
- textcolor(LIGHTBLUE); // no end of effect warning
- else if (you.strength < you.max_strength)
- textcolor(YELLOW);
-
- cprintf( "%d", you.strength );
- textcolor(LIGHTGREY);
-
- if (you.strength != you.max_strength)
- cprintf( " (%d)", you.max_strength );
- else
- cprintf( " " );
-
- you.redraw_strength = 0;
-
- if (you.strength < 1)
- ouch(-9999, 0, KILLED_BY_WEAKNESS);
-
- burden_change();
- }
-
- if (you.redraw_intelligence)
- {
- if (you.intel < 0)
- you.intel = 0;
- else if (you.intel > 72)
- you.intel = 72;
-
- if (you.max_intel > 72)
- you.max_intel = 72;
-
- gotoxy(45, 8);
-
- if (you.intel < you.max_intel)
- textcolor(YELLOW);
-
- cprintf( "%d", you.intel );
- textcolor(LIGHTGREY);
-
- if (you.intel != you.max_intel)
- cprintf( " (%d)", you.max_intel );
- else
- cprintf( " " );
-
- you.redraw_intelligence = 0;
-
- if (you.intel < 1)
- ouch(-9999, 0, KILLED_BY_STUPIDITY);
- }
-
- if (you.redraw_dexterity)
- {
- if (you.dex < 0)
- you.dex = 0;
- else if (you.dex > 72)
- you.dex = 72;
-
- if (you.max_dex > 72)
- you.max_dex = 72;
-
- gotoxy(45, 9);
-
- if (you.dex < you.max_dex)
- textcolor(YELLOW);
-
- cprintf( "%d", you.dex );
- textcolor(LIGHTGREY);
-
- if (you.dex != you.max_dex)
- cprintf( " (%d)", you.max_dex );
- else
- cprintf( " " );
-
- you.redraw_dexterity = 0;
-
- if (you.dex < 1)
- ouch(-9999, 0, KILLED_BY_CLUMSINESS);
- }
-
- if (you.redraw_armour_class)
- {
- gotoxy(44, 5);
-
- if (you.duration[DUR_STONEMAIL])
- dur_colour( BLUE, (you.duration[DUR_STONEMAIL] <= 6) );
- else if (you.duration[DUR_ICY_ARMOUR] || you.duration[DUR_STONESKIN])
- textcolor( LIGHTBLUE ); // no end of effect warning
-
- cprintf( "%d ", player_AC() );
- textcolor( LIGHTGREY );
-
- gotoxy(50, 5);
-
- if (you.duration[DUR_CONDENSATION_SHIELD]) //jmf: added 24mar2000
- textcolor( LIGHTBLUE ); // no end of effect warning
-
- cprintf( "(%d) ", player_shield_class() );
- textcolor( LIGHTGREY );
-
- you.redraw_armour_class = 0;
- }
-
- if (you.redraw_evasion)
- {
- gotoxy(44, 6);
-
- if (you.duration[DUR_FORESCRY])
- textcolor(LIGHTBLUE); // no end of effect warning
-
- cprintf( "%d ", player_evasion() );
- textcolor(LIGHTGREY);
-
- you.redraw_evasion = 0;
- }
-
- if (you.redraw_gold)
- {
- gotoxy(46, 10);
- cprintf( "%d ", you.gold );
- you.redraw_gold = 0;
- }
-
- if (you.redraw_experience)
- {
- gotoxy(52, 11);
-
-#if DEBUG_DIAGNOSTICS
- cprintf( "%d/%d (%d/%d)",
- you.experience_level, you.experience,
- you.skill_cost_level, you.exp_available );
-#else
- cprintf( "%d/%d (%d)",
- you.experience_level, you.experience, you.exp_available );
-#endif
-
-#ifdef UNIX
- clear_to_end_of_line();
-#else
- cprintf(" ");
-#endif
- you.redraw_experience = 0;
- }
-
- if (you.wield_change)
- {
- gotoxy(40, 13);
-#ifdef UNIX
- clear_to_end_of_line();
-#else
- cprintf(" ");
-#endif
-
- if (you.equip[EQ_WEAPON] != -1)
- {
- gotoxy(40, 13);
- textcolor(you.inv[you.equip[EQ_WEAPON]].colour);
-
- char str_pass[ ITEMNAME_SIZE ];
- in_name( you.equip[EQ_WEAPON], DESC_INVENTORY, str_pass, false );
- int prefcol = menu_colour(str_pass);
- if (prefcol != -1)
- textcolor(prefcol);
-
- in_name( you.equip[EQ_WEAPON], DESC_INVENTORY, str_pass,
- Options.terse_hand );
- str_pass[39] = '\0';
-
- cprintf(str_pass);
- textcolor(LIGHTGREY);
- }
- else
- {
- gotoxy(40, 13);
-
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_BLADE_HANDS)
- {
- textcolor(RED);
- cprintf("Blade Hands");
- textcolor(LIGHTGREY);
- }
- else
- {
- textcolor(LIGHTGREY);
- cprintf("Nothing wielded");
- }
- }
- you.wield_change = false;
- }
-
- // The colour scheme for these flags is currently:
- //
- // - yellow, "orange", red for bad conditions
- // - light grey, white for god based conditions
- // - green, light green for good conditions
- // - blue, light blue for good enchantments
- // - magenta, light magenta for "better" enchantments (deflect, fly)
-
- if (you.redraw_status_flags & REDRAW_LINE_1_MASK)
- {
- gotoxy(40, 14);
-
-#ifdef UNIX
- clear_to_end_of_line();
-#else
- cprintf( " " );
- gotoxy(40, 14);
-#endif
-
- switch (you.burden_state)
- {
- case BS_OVERLOADED:
- textcolor( RED );
- cprintf( "Overloaded " );
- break;
-
- case BS_ENCUMBERED:
- textcolor( LIGHTRED );
- cprintf( "Encumbered " );
- break;
-
- case BS_UNENCUMBERED:
- break;
- }
-
- switch (you.hunger_state)
- {
- case HS_ENGORGED:
- textcolor( LIGHTGREEN );
- cprintf( "Engorged" );
- break;
-
- case HS_FULL:
- textcolor( GREEN );
- cprintf( "Full" );
- break;
-
- case HS_SATIATED:
- break;
-
- case HS_HUNGRY:
- textcolor( YELLOW );
- cprintf( "Hungry" );
- break;
-
- case HS_STARVING:
- textcolor( RED );
- cprintf( "Starving" );
- break;
- }
-
- textcolor( LIGHTGREY );
-
-#if DEBUG_DIAGNOSTICS
- // debug mode hunger-o-meter
- cprintf( " (%d:%d) ", you.hunger - you.old_hunger, you.hunger );
-#endif
- }
-
- if (you.redraw_status_flags & REDRAW_LINE_2_MASK)
- {
- gotoxy(40, 15);
-
-#ifdef UNIX
- clear_to_end_of_line();
-#else
- cprintf( " " );
- gotoxy(40, 15);
-#endif
-
- // Max length of this line = 8 * 5 - 1 = 39
-
- if (you.duration[DUR_PRAYER])
- {
- textcolor( WHITE ); // no end of effect warning
- cprintf( "Pray " );
- }
-
- if (you.duration[DUR_REPEL_UNDEAD])
- {
- dur_colour( LIGHTGREY, (you.duration[DUR_REPEL_UNDEAD] <= 4) );
- cprintf( "Holy " );
- }
-
- if (you.duration[DUR_DEFLECT_MISSILES])
- {
-
- dur_colour( MAGENTA, (you.duration[DUR_DEFLECT_MISSILES] <= 6) );
- cprintf( "DMsl " );
- }
- else if (you.duration[DUR_REPEL_MISSILES])
- {
- dur_colour( BLUE, (you.duration[DUR_REPEL_MISSILES] <= 6) );
- cprintf( "RMsl " );
- }
-
- if (you.duration[DUR_REGENERATION])
- {
- dur_colour( BLUE, (you.duration[DUR_REGENERATION] <= 6) );
- cprintf( "Regen " );
- }
-
- if (you.duration[DUR_INSULATION])
- {
- dur_colour( BLUE, (you.duration[DUR_INSULATION] <= 6) );
- cprintf( "Ins " );
- }
-
- if (player_is_levitating())
- {
- bool perm = (you.species == SP_KENKU && you.experience_level >= 15)
- || (player_equip_ego_type( EQ_BOOTS, SPARM_LEVITATION ))
- || (you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON);
-
- if (wearing_amulet( AMU_CONTROLLED_FLIGHT ))
- {
- dur_colour( MAGENTA, (you.levitation <= 10 && !perm) );
- cprintf( "Fly " );
- }
- else
- {
- dur_colour( BLUE, (you.levitation <= 10 && !perm) );
- cprintf( "Lev " );
- }
- }
-
- if (you.invis)
- {
- dur_colour( BLUE, (you.invis <= 6) );
- cprintf( "Invis " );
- }
-
- // Perhaps this should be reversed to show when it can be used?
- // In that case, it should be probably be GREEN, and we'd have
- // to check to see if the player does have a breath weapon. -- bwr
- if (you.duration[DUR_BREATH_WEAPON])
- {
- textcolor( YELLOW ); // no warning
- cprintf( "BWpn" );
- }
-
- textcolor( LIGHTGREY );
- }
-
- if (you.redraw_status_flags & REDRAW_LINE_3_MASK)
- {
- gotoxy(40, 16);
-
-#ifdef UNIX
- clear_to_end_of_line();
-#else
- cprintf( " " );
- gotoxy(40, 16);
-#endif
- // Max length of this line = 7 * 5 + 3 - 1 = 37
-
- // Note the usage of bad_ench_colour() correspond to levels that
- // can be found in player.cc, ie those that the player can tell by
- // using the '@' command. Things like confusion and sticky flame
- // hide their amounts and are thus always the same colour (so
- // we're not really exposing any new information). --bwr
- if (you.conf)
- {
- textcolor( RED ); // no different levels
- cprintf( "Conf " );
- }
-
- if (you.duration[DUR_LIQUID_FLAMES])
- {
- textcolor( RED ); // no different levels
- cprintf( "Fire " );
- }
-
- if (you.poison)
- {
- // We skip marking "quite" poisoned and instead mark the
- // levels where the rules for dealing poison damage change
- // significantly. See acr.cc for that code. -- bwr
- textcolor( bad_ench_colour( you.poison, 5, 10 ) );
- cprintf( "Pois " );
- }
-
- if (you.disease)
- {
- textcolor( bad_ench_colour( you.disease, 40, 120 ) );
- cprintf( "Sick " );
- }
-
- if (you.rotting)
- {
- textcolor( bad_ench_colour( you.rotting, 4, 8 ) );
- cprintf( "Rot " );
- }
-
- if (you.magic_contamination > 5)
- {
- textcolor( bad_ench_colour( you.magic_contamination, 15, 25 ) );
- cprintf( "Glow " );
- }
-
- if (you.duration[DUR_SWIFTNESS])
- {
- dur_colour( BLUE, (you.duration[DUR_SWIFTNESS] <= 6) );
- cprintf( "Swift " );
- }
-
- if (you.slow && !you.haste)
- {
- textcolor( RED ); // no end of effect warning
- cprintf( "Slow" );
- }
- else if (you.haste && !you.slow)
- {
- dur_colour( BLUE, (you.haste <= 6) );
- cprintf( "Fast" );
- }
-
- textcolor( LIGHTGREY );
- }
-
- you.redraw_status_flags = 0;
-
-#if DEBUG_DIAGNOSTICS
- // debug mode GPS
- gotoxy(40, 17);
- cprintf( "Position (%2d,%2d)", you.x_pos, you.y_pos );
-#endif
-
-#ifdef UNIX
- // get curses to redraw screen
- update_screen();
-#endif
-} // end print_stats()
-
-unsigned char* itosym1(int stat)
-{
- return (unsigned char*)( (stat >= 1) ? "+ " : ". " );
-}
-
-unsigned char* itosym3(int stat)
-{
- return (unsigned char*)( (stat >= 3) ? "+ + +" :
- (stat == 2) ? "+ + ." :
- (stat == 1) ? "+ . ." :
- (stat == 0) ? ". . ." :
- "x . .");
-}
-
-static const char *s_equip_slot_names[] =
-{
- "Weapon",
- "Cloak",
- "Helmet",
- "Gloves",
- "Boots",
- "Shield",
- "Armour",
- "Left Ring",
- "Right Ring",
- "Amulet",
-};
-
-const char *equip_slot_to_name(int equip)
-{
- if (equip == EQ_RINGS)
- return "Ring";
- if (equip < 0 || equip >= NUM_EQUIP)
- return "";
- return s_equip_slot_names[equip];
-}
-
-int equip_name_to_slot(const char *s)
-{
- for (int i = 0; i < NUM_EQUIP; ++i)
- {
- if (!stricmp(s_equip_slot_names[i], s))
- return i;
- }
- return -1;
-}
-
-void get_full_detail(char* buffer, bool calc_unid)
-{
-#define FIR_AD buffer,44
-#define CUR_AD &buffer[++lines*45],44
-#define BUF_SIZE 25*3*45
- int lines = 0;
-
- memset(buffer, 0, BUF_SIZE);
-
- snprintf(CUR_AD, "%s the %s", you.your_name, player_title());
- lines++;
- snprintf(CUR_AD, "Race : %s", species_name(you.species,you.experience_level) );
- snprintf(CUR_AD, "Class : %s", you.class_name);
- snprintf(CUR_AD, "Worship : %s",
- you.religion == GOD_NO_GOD? "" : god_name(you.religion) );
- snprintf(CUR_AD, "Level : %7d", you.experience_level);
- snprintf(CUR_AD, "Exp : %7lu", you.experience);
-
- if (you.experience_level < 27)
- {
- int xp_needed = (exp_needed(you.experience_level+2) - you.experience) + 1;
- snprintf(CUR_AD, "Next Level : %7lu", exp_needed(you.experience_level + 2) + 1);
- snprintf(CUR_AD, "Exp Needed : %7d", xp_needed);
- }
- else
- {
- snprintf(CUR_AD, " ");
- snprintf(CUR_AD, " ");
- }
-
- snprintf(CUR_AD, "Spls.Left : %7d", player_spell_levels() );
- snprintf(CUR_AD, "Gold : %7d", you.gold );
-
- lines++;
-
- if (!player_rotted())
- {
- if (you.hp < you.hp_max)
- snprintf(CUR_AD, "HP : %3d/%d", you.hp, you.hp_max);
- else
- snprintf(CUR_AD, "HP : %3d", you.hp);
- }
- else
- {
- snprintf(CUR_AD, "HP : %3d/%d (%d)",
- you.hp, you.hp_max, you.hp_max + player_rotted() );
- }
-
- if (you.magic_points < you.max_magic_points)
- snprintf(CUR_AD, "MP : %3d/%d",
- you.magic_points, you.max_magic_points);
- else
- snprintf(CUR_AD, "MP : %3d", you.magic_points);
-
- if (you.strength == you.max_strength)
- snprintf(CUR_AD, "Str : %3d", you.strength);
- else
- snprintf(CUR_AD, "Str : %3d (%d)",
- you.strength, you.max_strength);
-
- if (you.intel == you.max_intel)
- snprintf(CUR_AD, "Int : %3d", you.intel);
- else
- snprintf(CUR_AD, "Int : %3d (%d)", you.intel, you.max_intel);
-
- if (you.dex == you.max_dex)
- snprintf(CUR_AD, "Dex : %3d", you.dex);
- else
- snprintf(CUR_AD, "Dex : %3d (%d)", you.dex, you.max_dex);
-
- snprintf(CUR_AD, "AC : %3d", player_AC() );
- snprintf(CUR_AD, "Evasion : %3d", player_evasion() );
- snprintf(CUR_AD, "Shield : %3d", player_shield_class() );
- lines++;
-
- if (you.real_time != -1)
- {
- const time_t curr = you.real_time + (time(NULL) - you.start_time);
- char buff[200];
- make_time_string( curr, buff, sizeof(buff), true );
-
- snprintf(CUR_AD, "Play time : %10s", buff);
- snprintf(CUR_AD, "Turns : %10ld", you.num_turns );
- }
-
- lines = 27;
-
- snprintf(CUR_AD, "Res.Fire : %s",
- itosym3( player_res_fire(calc_unid) ) );
- snprintf(CUR_AD, "Res.Cold : %s",
- itosym3( player_res_cold(calc_unid) ) );
- snprintf(CUR_AD, "Life Prot.: %s",
- itosym3( player_prot_life(calc_unid) ) );
- snprintf(CUR_AD, "Res.Poison: %s",
- itosym1( player_res_poison(calc_unid) ) );
- snprintf(CUR_AD, "Res.Elec. : %s",
- itosym1( player_res_electricity(calc_unid) ) );
- lines++;
-
- snprintf(CUR_AD, "Sust.Abil.: %s",
- itosym1( player_sust_abil(calc_unid) ) );
- snprintf(CUR_AD, "Res.Mut. : %s",
- itosym1( wearing_amulet( AMU_RESIST_MUTATION, calc_unid) ) );
- snprintf(CUR_AD, "Res.Slow : %s",
- itosym1( wearing_amulet( AMU_RESIST_SLOW, calc_unid) ) );
- snprintf(CUR_AD, "Clarity : %s",
- itosym1( wearing_amulet( AMU_CLARITY, calc_unid) ) );
- lines++;
- lines++;
-
- {
- char str_pass[ITEMNAME_SIZE];
- const int e_order[] =
- {
- EQ_WEAPON, EQ_BODY_ARMOUR, EQ_SHIELD, EQ_HELMET, EQ_CLOAK,
- EQ_GLOVES, EQ_BOOTS, EQ_AMULET, EQ_RIGHT_RING, EQ_LEFT_RING
- };
-
- for(int i = 0; i < NUM_EQUIP; i++)
- {
- int eqslot = e_order[i];
- const char *slot = equip_slot_to_name( eqslot );
- if (eqslot == EQ_LEFT_RING || eqslot == EQ_RIGHT_RING)
- slot = "Ring";
- else if (eqslot == EQ_BOOTS
- && (you.species == SP_CENTAUR
- || you.species == SP_NAGA))
- slot = "Barding";
-
- if ( you.equip[ e_order[i] ] != -1)
- {
- in_name( you.equip[ e_order[i] ], DESC_PLAIN,
- str_pass, Options.terse_hand );
- snprintf(CUR_AD, "%-7s: %s", slot, str_pass);
- }
- else
- {
- if (e_order[i] == EQ_WEAPON)
- {
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_BLADE_HANDS)
- snprintf(CUR_AD, "%-7s: Blade Hands", slot);
- else if (you.skills[SK_UNARMED_COMBAT])
- snprintf(CUR_AD, "%-7s: Unarmed", slot);
- else
- snprintf(CUR_AD, "%-7s:", slot);
- }
- else
- {
- snprintf(CUR_AD, "%-7s:", slot);
- }
- }
- }
- }
-
- lines = 52;
- snprintf(CUR_AD, "See Invis. : %s",
- itosym1( player_see_invis(calc_unid) ) );
- snprintf(CUR_AD, "Warding : %s",
- itosym1( wearing_amulet(AMU_WARDING, calc_unid)
- || (you.religion == GOD_VEHUMET &&
- you.duration[DUR_PRAYER] &&
- !player_under_penance() &&
- you.piety >= 75) ) );
- snprintf(CUR_AD, "Conserve : %s",
- itosym1( wearing_amulet( AMU_CONSERVATION, calc_unid) ) );
- snprintf(CUR_AD, "Res.Corr. : %s",
- itosym1( wearing_amulet( AMU_RESIST_CORROSION, calc_unid) ) );
-
- if ( !wearing_amulet( AMU_THE_GOURMAND, calc_unid) )
- {
- switch (you.species)
- {
- case SP_GHOUL:
- snprintf(CUR_AD, "Saprovore : %s", itosym3(3) );
- break;
-
- case SP_KOBOLD:
- case SP_TROLL:
- snprintf(CUR_AD, "Saprovore : %s", itosym3(2) );
- break;
-
- case SP_HILL_ORC:
- case SP_OGRE:
- snprintf(CUR_AD, "Saprovore : %s", itosym3(1) );
- break;
-#ifdef V_FIX
- case SP_OGRE_MAGE:
- snprintf(CUR_AD, "Voracious : %s", itosym1(1) );
- break;
-#endif
- default:
- snprintf(CUR_AD, "Gourmand : %s", itosym1(0) );
- break;
- }
- }
- else
- {
- snprintf(CUR_AD, "Gourmand : %s",
- itosym1( wearing_amulet( AMU_THE_GOURMAND, calc_unid) ) );
- }
-
- lines++;
-
- if ( scan_randarts(RAP_PREVENT_TELEPORTATION, calc_unid) )
- snprintf(CUR_AD, "Prev.Telep.: %s",
- itosym1( scan_randarts(RAP_PREVENT_TELEPORTATION, calc_unid) ) );
- else
- snprintf(CUR_AD, "Rnd.Telep. : %s",
- itosym1( player_teleport(calc_unid) ) );
- snprintf(CUR_AD, "Ctrl.Telep.: %s",
- itosym1( you.attribute[ATTR_CONTROL_TELEPORT] ) );
- snprintf(CUR_AD, "Levitation : %s", itosym1( player_is_levitating() ) );
- snprintf(CUR_AD, "Ctrl.Flight: %s",
- itosym1( wearing_amulet(AMU_CONTROLLED_FLIGHT, calc_unid) ) );
- lines++;
-
- return;
-}
diff --git a/stone_soup/crawl-ref/source/output.h b/stone_soup/crawl-ref/source/output.h
deleted file mode 100644
index 1fa77fd34b..0000000000
--- a/stone_soup/crawl-ref/source/output.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * File: output.cc
- * Summary: Functions used to print player related info.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef OUTPUT_H
-#define OUTPUT_H
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - player - stuff
- * *********************************************************************** */
-void print_stats(void);
-
-/* ***********************************************************************
- * called from: chardump
- * *********************************************************************** */
-void get_full_detail(char* buffer, bool calc_unid);
-
-const char *equip_slot_to_name(int equip);
-
-int equip_name_to_slot(const char *s);
-
-const char *equip_slot_to_name(int equip);
-
-#endif
diff --git a/stone_soup/crawl-ref/source/overmap.cc b/stone_soup/crawl-ref/source/overmap.cc
deleted file mode 100644
index e271a25fdf..0000000000
--- a/stone_soup/crawl-ref/source/overmap.cc
+++ /dev/null
@@ -1,539 +0,0 @@
-/*
- * File: overmap.cc
- * Idea: allow player to make notes about levels. I don't know how
- * to do this (I expect it will require some kind of dynamic
- * memory management thing). - LH
- * Summary: Records location of stairs etc
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <3> 30/7/00 MV Made Over-map full-screen
- * <2> 8/10/99 BCR Changed Linley's macros
- * to an enum in overmap.h
- * <1> 29/8/99 LRH Created
- */
-
-#include "AppHdr.h"
-#include "overmap.h"
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "externs.h"
-
-// for #definitions of MAX_BRANCHES & MAX_LEVELS
-#include "files.h"
-// for #definitions of MAX_BRANCHES & MAX_LEVELS
-#include "religion.h"
-#include "stuff.h"
-#include "view.h"
-
-enum
-{
- NO_FEATURE = 0x00,
- FEATURE_SHOP = 0x01,
- FEATURE_LABYRINTH = 0x02,
- FEATURE_HELL = 0x04,
- FEATURE_ABYSS = 0x08,
- FEATURE_PANDEMONIUM = 0x10
-};
-
-// These variables need to become part of the player struct
-// and need to be stored in the .sav file:
-
-// 0 == no altars;
-// 100 == more than one altar; or
-// # == which god for remaining numbers.
-
-FixedArray<unsigned char, MAX_LEVELS, MAX_BRANCHES> altars_present;
-FixedVector<char, MAX_BRANCHES> stair_level;
-FixedArray<unsigned char, MAX_LEVELS, MAX_BRANCHES> feature;
-
-int map_lines = 0; //mv: number of lines already printed on "over-map" screen
-
-//mv: prints one line in specified colour
-// void print_one_map_line( const char *line, int colour );
-// void print_branch_entrance_line( const char *area );
-
-void print_one_simple_line( const char *line, int colour );
-void print_one_highlighted_line( const char *pre, const char *text,
- const char *post, int colour );
-
-static void print_level_name( int branch, int depth,
- bool &printed_branch, bool &printed_level );
-
-void init_overmap( void )
-{
- for (int i = 0; i < MAX_LEVELS; i++)
- {
- for (int j = 0; j < MAX_BRANCHES; j++)
- {
- altars_present[i][j] = 0;
- feature[i][j] = 0;
- }
- }
-
- for (int i = 0; i < MAX_BRANCHES; i++)
- stair_level[i] = -1;
-} // end init_overmap()
-
-void display_overmap( void )
-{
-#ifdef DOS_TERM
- char buffer[4800];
-
- window(1, 1, 80, 25);
- gettext(1, 1, 80, 25, buffer);
-#endif
-
- //mv: must be set to 0 so "More..." message appears really at the
- // bottom of the screen
- //Don't forget it could be changed since the last call of display_overmap
- map_lines = 0;
-
- clrscr();
- bool pr_lev = false;
- bool output = false;
-
- print_one_simple_line(" Overview of the Dungeon", WHITE);
-
- // This is a more sensible order than the order of the enums -- bwr
- const int list_order[] =
- {
- BRANCH_MAIN_DUNGEON,
- BRANCH_ECUMENICAL_TEMPLE,
- BRANCH_ORCISH_MINES, BRANCH_ELVEN_HALLS,
- BRANCH_LAIR, BRANCH_SWAMP, BRANCH_SLIME_PITS, BRANCH_SNAKE_PIT,
- BRANCH_HIVE,
- BRANCH_VAULTS, BRANCH_HALL_OF_BLADES, BRANCH_CRYPT, BRANCH_TOMB,
- BRANCH_VESTIBULE_OF_HELL,
- BRANCH_DIS, BRANCH_GEHENNA, BRANCH_COCYTUS, BRANCH_TARTARUS,
- BRANCH_HALL_OF_ZOT
- };
-
- for (unsigned int index = 0; index < sizeof(list_order) / sizeof(int); index++)
- {
- const int i = list_order[index];
- bool printed_branch = false;
-
- for (int j = 0; j < MAX_LEVELS; j++)
- {
- bool printed_level = false;
-
- if (altars_present[j][i] != 0)
- {
- print_level_name( i, j, printed_branch, printed_level );
- output = true;
-
- if (altars_present[j][i] == 100)
- {
- print_one_highlighted_line( " - some ",
- "altars to the gods", ".",
- WHITE );
- }
- else
- {
- snprintf( info, INFO_SIZE, "altar to %s",
- god_name( altars_present[j][i] ) );
-
- print_one_highlighted_line( " - an ", info, ".", WHITE );
- }
- }
-
- if ( (feature[j][i] & FEATURE_SHOP) )
- {
- print_level_name( i, j, printed_branch, printed_level );
-
- // print_one_simple_line(" - facilities for the purchase of goods.",LIGHTGREY);
-
- print_one_highlighted_line( " - facilities for the ",
- "purchase of goods", ".", LIGHTGREEN );
- output = true;
- }
-
- if ( (feature[j][i] & FEATURE_ABYSS) )
- {
- print_level_name( i, j, printed_branch, printed_level );
- // print_one_simple_line(" - a gateway into the Abyss.", LIGHTRED);
- print_one_highlighted_line( " - a gateway into ",
- "the Abyss", ".", MAGENTA );
- output = true;
- }
-
- if ( (feature[j][i] & FEATURE_PANDEMONIUM) )
- {
- print_level_name( i, j, printed_branch, printed_level );
- // print_one_simple_line(" - a link to Pandemonium.", LIGHTRED);
-
- print_one_highlighted_line( " - a link to ", "Pandemonium",
- ".", LIGHTBLUE );
- output = true;
- }
-
- if ( (feature[j][i] & FEATURE_HELL) )
- {
- print_level_name( i, j, printed_branch, printed_level );
- // print_one_simple_line(" - a mouth of Hell.", LIGHTRED);
- print_one_highlighted_line( " - a mouth of ", "Hell", ".", RED );
- output = true;
- }
-
- if ( (feature[j][i] & FEATURE_LABYRINTH) )
- {
- print_level_name( i, j, printed_branch, printed_level );
- // print_one_simple_line(" - the entrance of a Labyrinth.", LIGHTRED);
- print_one_highlighted_line( " - an entrance to ",
- "a Labyrinth", ".", CYAN );
- output = true;
- }
-
-
- // NB: k starts at 1 because there aren't any staircases
- // to the main dungeon
- for (int k = 1; k < MAX_BRANCHES; k++)
- {
- pr_lev = false;
- // strcpy(info, " - a staircase leading to ");
- info[0] = '\0';
-
- if (stair_level[k] == j)
- {
- switch (i)
- {
- case BRANCH_LAIR:
- switch (k)
- {
- case BRANCH_SLIME_PITS:
- strcat(info, "the Slime Pits");
- pr_lev = true;
- break;
- case BRANCH_SNAKE_PIT:
- strcat(info, "the Snake Pit");
- pr_lev = true;
- break;
- case BRANCH_SWAMP:
- strcat(info, "the Swamp");
- pr_lev = true;
- break;
- }
- break;
-
- case BRANCH_VAULTS:
- switch (k)
- {
- case BRANCH_HALL_OF_BLADES:
- strcat(info, "the Hall of Blades");
- pr_lev = true;
- break;
- case BRANCH_CRYPT:
- strcat(info, "the Crypt");
- pr_lev = true;
- break;
- }
- break;
-
- case BRANCH_CRYPT:
- switch (k)
- {
- case BRANCH_TOMB:
- strcat(info, "the Tomb");
- pr_lev = true;
- break;
- }
- break;
-
- case BRANCH_ORCISH_MINES:
- switch (k)
- {
- case BRANCH_ELVEN_HALLS:
- strcat(info, "the Elven Halls");
- pr_lev = true;
- break;
- }
- break;
-
- case BRANCH_MAIN_DUNGEON:
- switch (k)
- {
- case BRANCH_ORCISH_MINES:
- strcat(info, "the Orcish Mines");
- pr_lev = true;
- break;
- case BRANCH_HIVE:
- strcat(info, "the Hive");
- pr_lev = true;
- break;
- case BRANCH_LAIR:
- strcat(info, "the Lair");
- pr_lev = true;
- break;
- case BRANCH_VAULTS:
- strcat(info, "the Vaults");
- pr_lev = true;
- break;
- case BRANCH_HALL_OF_ZOT:
- strcat(info, "the Hall of Zot");
- pr_lev = true;
- break;
- case BRANCH_ECUMENICAL_TEMPLE:
- strcat(info, "the Ecumenical Temple");
- pr_lev = true;
- break;
- }
- break;
- }
- }
-
- if (pr_lev)
- {
- print_level_name( i, j, printed_branch, printed_level );
- print_one_highlighted_line( " - the entrance to ", info,
- ".", YELLOW );
- output = true;
- }
- }
- }
- }
-
- textcolor( LIGHTGREY );
-
- if (!output)
- cprintf( EOL "You have yet to discover anything worth noting." EOL );
-
- getch();
-
- redraw_screen();
-
-#ifdef DOS_TERM
- puttext(1, 1, 80, 25, buffer);
-#endif
-} // end display_overmap()
-
-
-static void print_level_name( int branch, int depth,
- bool &printed_branch, bool &printed_level )
-{
- if (!printed_branch)
- {
- printed_branch = true;
-
- print_one_simple_line( "", YELLOW );
- print_one_simple_line(
- (branch == BRANCH_MAIN_DUNGEON) ? "Main Dungeon" :
- (branch == BRANCH_ORCISH_MINES) ? "The Orcish Mines" :
- (branch == BRANCH_HIVE) ? "The Hive" :
- (branch == BRANCH_LAIR) ? "The Lair" :
- (branch == BRANCH_SLIME_PITS) ? "The Slime Pits" :
- (branch == BRANCH_VAULTS) ? "The Vaults" :
- (branch == BRANCH_CRYPT) ? "The Crypt" :
- (branch == BRANCH_HALL_OF_BLADES) ? "The Hall of Blades" :
- (branch == BRANCH_HALL_OF_ZOT) ? "The Hall of Zot" :
- (branch == BRANCH_ECUMENICAL_TEMPLE) ? "The Ecumenical Temple" :
- (branch == BRANCH_SNAKE_PIT) ? "The Snake Pit" :
- (branch == BRANCH_ELVEN_HALLS) ? "The Elven Halls" :
- (branch == BRANCH_TOMB) ? "The Tomb" :
- (branch == BRANCH_SWAMP) ? "The Swamp" :
-
- (branch == BRANCH_DIS) ? "The Iron City of Dis" :
- (branch == BRANCH_GEHENNA) ? "Gehenna" :
- (branch == BRANCH_VESTIBULE_OF_HELL) ? "The Vestibule of Hell" :
- (branch == BRANCH_COCYTUS) ? "Cocytus" :
- (branch == BRANCH_TARTARUS) ? "Tartarus"
- : "Unknown Area",
-
- YELLOW );
- }
-
- if (!printed_level)
- {
- printed_level = true;
-
- if (branch == BRANCH_ECUMENICAL_TEMPLE
- || branch == BRANCH_HALL_OF_BLADES
- || branch == BRANCH_VESTIBULE_OF_HELL)
- {
- // these areas only have one level... let's save the space
- return;
- }
-
- // we need our own buffer in here (info is used):
- char buff[ INFO_SIZE ] = "\0";;
-
- if (branch == BRANCH_MAIN_DUNGEON)
- depth += 1;
- else if (branch >= BRANCH_ORCISH_MINES && branch <= BRANCH_SWAMP)
- depth -= you.branch_stairs[ branch - BRANCH_ORCISH_MINES ];
- else // branch is in hell (all of which start at depth 28)
- depth -= 26;
-
- snprintf( buff, INFO_SIZE, " Level %d:", depth );
- print_one_simple_line( buff, LIGHTRED );
- }
-}
-
-void seen_staircase( unsigned char which_staircase )
-{
- // which_staircase holds the grid value of the stair, must be converted
- // Only handles stairs, not gates or arches
- // Don't worry about:
- // - stairs returning to dungeon - predictable
- // - entrances to the hells - always in vestibule
-
- unsigned char which_branch = BRANCH_MAIN_DUNGEON;
-
- switch ( which_staircase )
- {
- case DNGN_ENTER_ORCISH_MINES:
- which_branch = BRANCH_ORCISH_MINES;
- break;
- case DNGN_ENTER_HIVE:
- which_branch = BRANCH_HIVE;
- break;
- case DNGN_ENTER_LAIR:
- which_branch = BRANCH_LAIR;
- break;
- case DNGN_ENTER_SLIME_PITS:
- which_branch = BRANCH_SLIME_PITS;
- break;
- case DNGN_ENTER_VAULTS:
- which_branch = BRANCH_VAULTS;
- break;
- case DNGN_ENTER_CRYPT:
- which_branch = BRANCH_CRYPT;
- break;
- case DNGN_ENTER_HALL_OF_BLADES:
- which_branch = BRANCH_HALL_OF_BLADES;
- break;
- case DNGN_ENTER_ZOT:
- which_branch = BRANCH_HALL_OF_ZOT;
- break;
- case DNGN_ENTER_TEMPLE:
- which_branch = BRANCH_ECUMENICAL_TEMPLE;
- break;
- case DNGN_ENTER_SNAKE_PIT:
- which_branch = BRANCH_SNAKE_PIT;
- break;
- case DNGN_ENTER_ELVEN_HALLS:
- which_branch = BRANCH_ELVEN_HALLS;
- break;
- case DNGN_ENTER_TOMB:
- which_branch = BRANCH_TOMB;
- break;
- case DNGN_ENTER_SWAMP:
- which_branch = BRANCH_SWAMP;
- break;
- default:
- exit(-1); // shouldn't happen
- }
-
- stair_level[which_branch] = you.your_level;
-} // end seen_staircase()
-
-
-// if player has seen an altar; record it
-void seen_altar( unsigned char which_altar )
-{
- // can't record in abyss or pan.
- if ( you.level_type != LEVEL_DUNGEON )
- return;
-
- // portable; no point in recording
- if ( which_altar == GOD_NEMELEX_XOBEH )
- return;
-
- // already seen
- if ( altars_present[you.your_level][you.where_are_you] == which_altar )
- return;
-
- if ( altars_present[you.your_level][you.where_are_you] == 0 )
- altars_present[you.your_level][you.where_are_you] = which_altar;
- else
- altars_present[you.your_level][you.where_are_you] = 100;
-} // end seen_altar()
-
-
-// if player has seen any other thing; record it
-void seen_other_thing( unsigned char which_thing )
-{
- if ( you.level_type != LEVEL_DUNGEON ) // can't record in abyss or pan.
- return;
-
- switch ( which_thing )
- {
- case DNGN_ENTER_SHOP:
- feature[you.your_level][you.where_are_you] |= FEATURE_SHOP;
- break;
- case DNGN_ENTER_LABYRINTH:
- feature[you.your_level][you.where_are_you] |= FEATURE_LABYRINTH;
- break;
- case DNGN_ENTER_HELL:
- feature[you.your_level][you.where_are_you] |= FEATURE_HELL;
- break;
- case DNGN_ENTER_ABYSS:
- feature[you.your_level][you.where_are_you] |= FEATURE_ABYSS;
- break;
- case DNGN_ENTER_PANDEMONIUM:
- feature[you.your_level][you.where_are_you] |= FEATURE_PANDEMONIUM;
- break;
- }
-} // end seen_other_thing()
-
-
-/* mv: this function prints one line at "Over-map screen" in specified colour.
- * If map_lines = maximum number of lines (it means the screen is full) it
- * prints "More..." message, read key, clear screen and after that prints new
- * line
- */
-void print_one_simple_line( const char *line , int colour)
-{
- if (map_lines == (get_number_of_lines() - 2))
- {
- textcolor( LIGHTGREY );
- cprintf(EOL);
- cprintf("More...");
- getch();
- clrscr();
- map_lines = 0;
- }
-
- textcolor( colour );
- cprintf( line );
- cprintf( EOL );
-
- map_lines++;
-}
-
-void print_one_highlighted_line( const char *pre, const char *text,
- const char *post, int colour )
-{
- if (map_lines == (get_number_of_lines() - 2))
- {
- textcolor( LIGHTGREY );
- cprintf(EOL);
- cprintf("More...");
- getch();
- clrscr();
- map_lines = 0;
- }
-
- if (pre[0] != '\0')
- {
- textcolor( LIGHTGREY );
- cprintf( pre );
- }
-
- textcolor( colour );
- cprintf( text );
-
- if (post[0] != '\0')
- {
- textcolor( LIGHTGREY );
- cprintf( post );
- }
-
- cprintf( EOL );
-
- map_lines++;
-}
diff --git a/stone_soup/crawl-ref/source/overmap.h b/stone_soup/crawl-ref/source/overmap.h
deleted file mode 100644
index 9d02b320e6..0000000000
--- a/stone_soup/crawl-ref/source/overmap.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * File: overmap.cc
- * Summary: "Overmap" functionality
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> --/--/-- LRH Created
- */
-
-
-#ifndef OVERMAP_H
-#define OVERMAP_H
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: view
- * *********************************************************************** */
-void seen_altar(unsigned char which_altar);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void init_overmap(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void display_overmap(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: view
- * *********************************************************************** */
-void seen_staircase(unsigned char which_staircase);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: view
- * *********************************************************************** */
-void seen_other_thing(unsigned char which_thing);
-
-
-#endif
diff --git a/stone_soup/crawl-ref/source/player.cc b/stone_soup/crawl-ref/source/player.cc
deleted file mode 100644
index 91ee0dea54..0000000000
--- a/stone_soup/crawl-ref/source/player.cc
+++ /dev/null
@@ -1,4127 +0,0 @@
-/*
- * File: player.cc
- * Summary: Player related functions.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <6> 7/30/99 BWR Added player_spell_levels()
- * <5> 7/13/99 BWR Added player_res_electricity()
- * and player_hunger_rate()
- * <4> 6/22/99 BWR Racial adjustments to stealth and Armour.
- * <3> 5/20/99 BWR Fixed problems with random stat increases, added kobold
- * stat increase. increased EV recovery for Armour.
- * <2> 5/08/99 LRH display_char_status correctly handles magic_contamination.
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "player.h"
-
-#ifdef DOS
-#include <conio.h>
-#endif
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <math.h>
-#include <ctype.h>
-
-#include "externs.h"
-
-#include "clua.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "items.h"
-#include "macro.h"
-#include "misc.h"
-#include "mon-util.h"
-#include "mutation.h"
-#include "output.h"
-#include "randart.h"
-#include "religion.h"
-#include "skills2.h"
-#include "spl-util.h"
-#include "spells4.h"
-#include "stuff.h"
-#include "transfor.h"
-#include "travel.h"
-#include "view.h"
-#include "wpn-misc.h"
-
-
-/*
- you.duration []: //jmf: obsolete, see enum.h instead
- 0 - liquid flames
- 1 - icy armour
- 2 - repel missiles
- 3 - prayer
- 4 - regeneration
- 5 - vorpal blade
- 6 - fire brand
- 7 - ice brand
- 8 - lethal infusion
- 9 - swiftness
- 10 - insulation
- 11 - stonemail
- 12 - controlled flight
- 13 - teleport
- 14 - control teleport
- 15 - poison weapon
- 16 - resist poison
- 17 - breathe something
- 18 - transformation (duration)
- 19 - death channel
- 20 - deflect missiles
- */
-
-/* attributes
- 0 - resist lightning
- 1 - spec_air
- 2 - spec_earth
- 3 - control teleport
- 4 - walk slowly (eg naga)
- 5 - transformation (form)
- 6 - Nemelex card gift countdown
- 7 - Nemelex has given you a card table
- 8 - How many demonic powers a dspawn has
- */
-
-/* armour list
- 0 - wielded
- 1 - cloak
- 2 - helmet
- 3 - gloves
- 4 - boots
- 5 - shield
- 6 - body armour
- 7 - ring 0
- 8 - ring 1
- 9 - amulet
- */
-
-/* Contains functions which return various player state vars,
- and other stuff related to the player. */
-
-int species_exp_mod(char species);
-void ability_increase(void);
-
-//void priest_spells(int priest_pass[10], char religious); // see actual function for reasoning here {dlb}
-bool player_in_branch( int branch )
-{
- return (you.level_type == LEVEL_DUNGEON && you.where_are_you == branch);
-}
-
-bool player_in_hell( void )
-{
- return (you.level_type == LEVEL_DUNGEON
- && (you.where_are_you >= BRANCH_DIS
- && you.where_are_you <= BRANCH_THE_PIT)
- && you.where_are_you != BRANCH_VESTIBULE_OF_HELL);
-}
-
-bool player_in_water(void)
-{
- return (!player_is_levitating()
- && (grd[you.x_pos][you.y_pos] == DNGN_DEEP_WATER
- || grd[you.x_pos][you.y_pos] == DNGN_SHALLOW_WATER));
-}
-
-bool player_is_swimming(void)
-{
- return (player_in_water() && you.species == SP_MERFOLK);
-}
-
-bool player_under_penance(void)
-{
- if (you.religion != GOD_NO_GOD)
- return (you.penance[you.religion]);
- else
- return (false);
-}
-
-bool player_genus(unsigned char which_genus, unsigned char species)
-{
- if (species == SP_UNKNOWN)
- species = you.species;
-
- switch (species)
- {
- case SP_RED_DRACONIAN:
- case SP_WHITE_DRACONIAN:
- case SP_GREEN_DRACONIAN:
- case SP_GOLDEN_DRACONIAN:
- case SP_GREY_DRACONIAN:
- case SP_BLACK_DRACONIAN:
- case SP_PURPLE_DRACONIAN:
- case SP_MOTTLED_DRACONIAN:
- case SP_PALE_DRACONIAN:
- case SP_UNK0_DRACONIAN:
- case SP_UNK1_DRACONIAN:
- case SP_BASE_DRACONIAN:
- return (which_genus == GENPC_DRACONIAN);
-
- case SP_ELF:
- case SP_HIGH_ELF:
- case SP_GREY_ELF:
- case SP_DEEP_ELF:
- case SP_SLUDGE_ELF:
- return (which_genus == GENPC_ELVEN);
-
- case SP_HILL_DWARF:
- case SP_MOUNTAIN_DWARF:
- return (which_genus == GENPC_DWARVEN);
-
- default:
- break;
- }
-
- return (false);
-} // end player_genus()
-
-bool player_weapon_wielded()
-{
- const int wpn = you.equip[EQ_WEAPON];
-
- if (wpn == -1)
- return (false);
-
- if (you.inv[wpn].base_type != OBJ_WEAPONS
- && you.inv[wpn].base_type != OBJ_STAVES)
- {
- return (false);
- }
-
- // FIXME: This needs to go in eventually.
- /*
- // should never have a bad "shape" weapon in hand
- ASSERT( check_weapon_shape( you.inv[wpn], false ) );
-
- if (!check_weapon_wieldable_size( you.inv[wpn], player_size() ))
- return (false);
- */
-
- return (true);
-}
-
-// Returns the you.inv[] index of our wielded weapon or -1 (no item, not wield)
-int get_player_wielded_item()
-{
- return (you.equip[EQ_WEAPON]);
-}
-
-int get_player_wielded_weapon()
-{
- return (player_weapon_wielded()? get_player_wielded_item() : -1);
-}
-
-// Looks in equipment "slot" to see if there is an equiped "sub_type".
-// Returns number of matches (in the case of rings, both are checked)
-int player_equip( int slot, int sub_type, bool calc_unid )
-{
- int ret = 0;
-
- switch (slot)
- {
- case EQ_WEAPON:
- // Hands can have more than just weapons.
- if (you.equip[EQ_WEAPON] != -1
- && you.inv[you.equip[EQ_WEAPON]].base_type == OBJ_WEAPONS
- && you.inv[you.equip[EQ_WEAPON]].sub_type == sub_type)
- {
- ret++;
- }
- break;
-
- case EQ_STAFF:
- // Like above, but must be magical stave.
- if (you.equip[EQ_WEAPON] != -1
- && you.inv[you.equip[EQ_WEAPON]].base_type == OBJ_STAVES
- && you.inv[you.equip[EQ_WEAPON]].sub_type == sub_type
- && (calc_unid ||
- item_ident(you.inv[you.equip[EQ_WEAPON]], ISFLAG_KNOW_TYPE)))
- {
- ret++;
- }
- break;
-
- case EQ_RINGS:
- if (you.equip[EQ_LEFT_RING] != -1
- && you.inv[you.equip[EQ_LEFT_RING]].sub_type == sub_type
- && (calc_unid ||
- item_type_known(you.inv[you.equip[EQ_LEFT_RING]])))
- {
- ret++;
- }
-
- if (you.equip[EQ_RIGHT_RING] != -1
- && you.inv[you.equip[EQ_RIGHT_RING]].sub_type == sub_type
- && (calc_unid ||
- item_type_known(you.inv[you.equip[EQ_RIGHT_RING]])))
- {
- ret++;
- }
- break;
-
- case EQ_RINGS_PLUS:
- if (you.equip[EQ_LEFT_RING] != -1
- && you.inv[you.equip[EQ_LEFT_RING]].sub_type == sub_type)
- {
- ret += you.inv[you.equip[EQ_LEFT_RING]].plus;
- }
-
- if (you.equip[EQ_RIGHT_RING] != -1
- && you.inv[you.equip[EQ_RIGHT_RING]].sub_type == sub_type)
- {
- ret += you.inv[you.equip[EQ_RIGHT_RING]].plus;
- }
- break;
-
- case EQ_RINGS_PLUS2:
- if (you.equip[EQ_LEFT_RING] != -1
- && you.inv[you.equip[EQ_LEFT_RING]].sub_type == sub_type)
- {
- ret += you.inv[you.equip[EQ_LEFT_RING]].plus2;
- }
-
- if (you.equip[EQ_RIGHT_RING] != -1
- && you.inv[you.equip[EQ_RIGHT_RING]].sub_type == sub_type)
- {
- ret += you.inv[you.equip[EQ_RIGHT_RING]].plus2;
- }
- break;
-
- case EQ_ALL_ARMOUR:
- // doesn't make much sense here... be specific. -- bwr
- break;
-
- default:
- if (you.equip[slot] != -1
- && you.inv[you.equip[slot]].sub_type == sub_type
- && (calc_unid ||
- item_ident(you.inv[you.equip[slot]], ISFLAG_KNOW_TYPE)))
- {
- ret++;
- }
- break;
- }
-
- return (ret);
-}
-
-
-// Looks in equipment "slot" to see if equiped item has "special" ego-type
-// Returns number of matches (jewellery returns zero -- no ego type).
-int player_equip_ego_type( int slot, int special )
-{
- int ret = 0;
- int wpn;
-
- switch (slot)
- {
- case EQ_WEAPON:
- // This actually checks against the "branding", so it will catch
- // randart brands, but not fixed artefacts. -- bwr
-
- // Hands can have more than just weapons.
- wpn = you.equip[EQ_WEAPON];
- if (wpn != -1
- && you.inv[wpn].base_type == OBJ_WEAPONS
- && get_weapon_brand( you.inv[wpn] ) == special)
- {
- ret++;
- }
- break;
-
- case EQ_LEFT_RING:
- case EQ_RIGHT_RING:
- case EQ_AMULET:
- case EQ_STAFF:
- case EQ_RINGS:
- case EQ_RINGS_PLUS:
- case EQ_RINGS_PLUS2:
- // no ego types for these slots
- break;
-
- case EQ_ALL_ARMOUR:
- // Check all armour slots:
- for (int i = EQ_CLOAK; i <= EQ_BODY_ARMOUR; i++)
- {
- if (you.equip[i] != -1
- && get_armour_ego_type( you.inv[you.equip[i]] ) == special)
- {
- ret++;
- }
- }
- break;
-
- default:
- // Check a specific armour slot for an ego type:
- if (you.equip[slot] != -1
- && get_armour_ego_type( you.inv[you.equip[slot]] ) == special)
- {
- ret++;
- }
- break;
- }
-
- return (ret);
-}
-
-int player_damage_type( void )
-{
- const int wpn = you.equip[ EQ_WEAPON ];
-
- if (wpn != -1)
- {
- return (damage_type(you.inv[wpn]));
- }
- else if (you.equip[EQ_GLOVES] == -1 &&
- (you.attribute[ATTR_TRANSFORMATION] == TRAN_BLADE_HANDS
- || you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON
- || you.mutation[MUT_CLAWS]
- || you.species == SP_TROLL
- || you.species == SP_GHOUL))
- {
- return (DVORP_SLICING);
- }
-
- return (DVORP_CRUSHING);
-}
-
-// returns band of player's melee damage
-int player_damage_brand( void )
-{
- int ret = SPWPN_NORMAL;
- const int wpn = you.equip[ EQ_WEAPON ];
-
- if (wpn != -1)
- ret = get_weapon_brand( you.inv[wpn] );
- else if (you.confusing_touch)
- ret = SPWPN_CONFUSE;
- else if (you.mutation[MUT_DRAIN_LIFE])
- ret = SPWPN_DRAINING;
- else
- {
- switch (you.attribute[ATTR_TRANSFORMATION])
- {
- case TRAN_SPIDER:
- ret = SPWPN_VENOM;
- break;
-
- case TRAN_ICE_BEAST:
- ret = SPWPN_FREEZING;
- break;
-
- case TRAN_LICH:
- ret = SPWPN_DRAINING;
- break;
-
- default:
- break;
- }
- }
-
- return (ret);
-}
-
-int player_teleport(bool calc_unid)
-{
- int tp = 0;
-
- /* rings */
- tp += 8 * player_equip( EQ_RINGS, RING_TELEPORTATION, calc_unid );
-
- /* mutations */
- tp += you.mutation[MUT_TELEPORT] * 3;
-
- /* randart weapons only */
- if (you.equip[EQ_WEAPON] != -1
- && you.inv[you.equip[EQ_WEAPON]].base_type == OBJ_WEAPONS
- && is_random_artefact( you.inv[you.equip[EQ_WEAPON]] ))
- {
- tp += scan_randarts(RAP_CAUSE_TELEPORTATION, calc_unid);
- }
-
- return tp;
-} // end player_teleport()
-
-int player_regen(void)
-{
- int rr = you.hp_max / 3;
-
- if (rr > 20)
- rr = 20 + ((rr - 20) / 2);
-
- /* rings */
- rr += 40 * player_equip( EQ_RINGS, RING_REGENERATION );
-
- /* spell */
- if (you.duration[DUR_REGENERATION])
- rr += 100;
-
- /* troll or troll leather -- trolls can't get both */
- if (you.species == SP_TROLL)
- rr += 40;
- else if (player_equip( EQ_BODY_ARMOUR, ARM_TROLL_LEATHER_ARMOUR ))
- rr += 30;
-
- /* fast heal mutation */
- rr += you.mutation[MUT_REGENERATION] * 20;
-
- /* ghouls heal slowly */
- // dematerialized people heal slowly
- // dematerialized ghouls shouldn't heal any more slowly -- bwr
- if ((you.species == SP_GHOUL
- && (you.attribute[ATTR_TRANSFORMATION] == TRAN_NONE
- || you.attribute[ATTR_TRANSFORMATION] == TRAN_BLADE_HANDS))
- || you.attribute[ATTR_TRANSFORMATION] == TRAN_AIR)
- {
- rr /= 2;
- }
-
- if (rr < 1)
- rr = 1;
-
- return (rr);
-}
-
-int player_hunger_rate(void)
-{
- int hunger = 3;
-
- // jmf: hunger isn't fair while you can't eat
- // Actually, it is since you can detransform any time you like -- bwr
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_AIR)
- return 0;
-
- switch (you.species)
- {
- case SP_HALFLING:
- case SP_SPRIGGAN:
- hunger--;
- break;
-
- case SP_OGRE:
- case SP_OGRE_MAGE:
- case SP_DEMIGOD:
- hunger++;
- break;
-
- case SP_CENTAUR:
- hunger += 2;
- break;
-
- case SP_TROLL:
- hunger += 6;
- break;
- }
-
- if (you.duration[DUR_REGENERATION] > 0)
- hunger += 4;
-
- // moved here from acr.cc... maintaining the >= 40 behaviour
- if (you.hunger >= 40)
- {
- if (you.invis > 0)
- hunger += 5;
-
- // berserk has its own food penalty -- excluding berserk haste
- if (you.haste > 0 && !you.berserker)
- hunger += 5;
- }
-
- hunger += you.mutation[MUT_FAST_METABOLISM];
-
- if (you.mutation[MUT_SLOW_METABOLISM] > 2)
- hunger -= 2;
- else if (you.mutation[MUT_SLOW_METABOLISM] > 0)
- hunger--;
-
- // rings
- hunger += 2 * player_equip( EQ_RINGS, RING_REGENERATION );
- hunger += 4 * player_equip( EQ_RINGS, RING_HUNGER );
- hunger -= 2 * player_equip( EQ_RINGS, RING_SUSTENANCE );
-
- // weapon ego types
- hunger += 6 * player_equip_ego_type( EQ_WEAPON, SPWPN_VAMPIRICISM );
- hunger += 9 * player_equip_ego_type( EQ_WEAPON, SPWPN_VAMPIRES_TOOTH );
-
- // troll leather armour
- hunger += player_equip( EQ_BODY_ARMOUR, ARM_TROLL_LEATHER_ARMOUR );
-
- // randarts
- hunger += scan_randarts(RAP_METABOLISM);
-
- // burden
- hunger += you.burden_state;
-
- if (hunger < 1)
- hunger = 1;
-
- return (hunger);
-}
-
-int player_spell_levels(void)
-{
- int sl = (you.experience_level - 1) + (you.skills[SK_SPELLCASTING] * 2);
-
- bool fireball = false;
- bool delayed_fireball = false;
-
- if (sl > 99)
- sl = 99;
-
- for (int i = 0; i < 25; i++)
- {
- if (you.spells[i] == SPELL_FIREBALL)
- fireball = true;
- else if (you.spells[i] == SPELL_DELAYED_FIREBALL)
- delayed_fireball = true;
-
- if (you.spells[i] != SPELL_NO_SPELL)
- sl -= spell_difficulty(you.spells[i]);
- }
-
- // Fireball is free for characters with delayed fireball
- if (fireball && delayed_fireball)
- sl += spell_difficulty( SPELL_FIREBALL );
-
- // Note: This can happen because of level drain. Maybe we should
- // force random spells out when that happens. -- bwr
- if (sl < 0)
- sl = 0;
-
- return (sl);
-}
-
-int player_res_magic(void)
-{
- int rm = 0;
-
- switch (you.species)
- {
- default:
- rm = you.experience_level * 3;
- break;
- case SP_HIGH_ELF:
- case SP_GREY_ELF:
- case SP_ELF:
- case SP_SLUDGE_ELF:
- case SP_HILL_DWARF:
- case SP_MOUNTAIN_DWARF:
- rm = you.experience_level * 4;
- break;
- case SP_NAGA:
- rm = you.experience_level * 5;
- break;
- case SP_PURPLE_DRACONIAN:
- case SP_GNOME:
- case SP_DEEP_ELF:
- rm = you.experience_level * 6;
- break;
- case SP_SPRIGGAN:
- rm = you.experience_level * 7;
- break;
- }
-
- /* armour */
- rm += 30 * player_equip_ego_type( EQ_ALL_ARMOUR, SPARM_MAGIC_RESISTANCE );
-
- /* rings of magic resistance */
- rm += 40 * player_equip( EQ_RINGS, RING_PROTECTION_FROM_MAGIC );
-
- /* randarts */
- rm += scan_randarts(RAP_MAGIC);
-
- /* Enchantment skill */
- rm += 2 * you.skills[SK_ENCHANTMENTS];
-
- /* Mutations */
- rm += 30 * you.mutation[MUT_MAGIC_RESISTANCE];
-
- /* transformations */
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_LICH)
- rm += 50;
-
- return rm;
-}
-
-int player_res_fire(bool calc_unid)
-{
- int rf = 0;
-
- /* rings of fire resistance/fire */
- rf += player_equip( EQ_RINGS, RING_PROTECTION_FROM_FIRE, calc_unid );
- rf += player_equip( EQ_RINGS, RING_FIRE, calc_unid );
-
- /* rings of ice */
- rf -= player_equip( EQ_RINGS, RING_ICE, calc_unid );
-
- /* Staves */
- rf += player_equip( EQ_STAFF, STAFF_FIRE, calc_unid );
-
- // body armour:
- rf += 2 * player_equip( EQ_BODY_ARMOUR, ARM_DRAGON_ARMOUR );
- rf += player_equip( EQ_BODY_ARMOUR, ARM_GOLD_DRAGON_ARMOUR );
- rf -= player_equip( EQ_BODY_ARMOUR, ARM_ICE_DRAGON_ARMOUR );
-
- // ego armours
- rf += player_equip_ego_type( EQ_ALL_ARMOUR, SPARM_FIRE_RESISTANCE );
- rf += player_equip_ego_type( EQ_ALL_ARMOUR, SPARM_RESISTANCE );
-
- // randart weapons:
- rf += scan_randarts(RAP_FIRE, calc_unid);
-
- // species:
- if (you.species == SP_MUMMY)
- rf--;
- else if (you.species == SP_RED_DRACONIAN && you.experience_level > 17)
- rf++;
-
- // mutations:
- rf += you.mutation[MUT_HEAT_RESISTANCE];
-
- if (you.fire_shield)
- rf += 2;
-
- // transformations:
- switch (you.attribute[ATTR_TRANSFORMATION])
- {
- case TRAN_ICE_BEAST:
- rf--;
- break;
- case TRAN_DRAGON:
- rf += 2;
- break;
- case TRAN_SERPENT_OF_HELL:
- rf += 2;
- break;
- case TRAN_AIR:
- rf -= 2;
- break;
- }
-
- if (rf < -3)
- rf = -3;
- else if (rf > 3)
- rf = 3;
-
- return (rf);
-}
-
-int player_res_cold(bool calc_unid)
-{
- int rc = 0;
-
- /* rings of fire resistance/fire */
- rc += player_equip( EQ_RINGS, RING_PROTECTION_FROM_COLD, calc_unid );
- rc += player_equip( EQ_RINGS, RING_ICE, calc_unid );
-
- /* rings of ice */
- rc -= player_equip( EQ_RINGS, RING_FIRE, calc_unid );
-
- /* Staves */
- rc += player_equip( EQ_STAFF, STAFF_COLD, calc_unid );
-
- // body armour:
- rc += 2 * player_equip( EQ_BODY_ARMOUR, ARM_ICE_DRAGON_ARMOUR );
- rc += player_equip( EQ_BODY_ARMOUR, ARM_GOLD_DRAGON_ARMOUR );
- rc -= player_equip( EQ_BODY_ARMOUR, ARM_DRAGON_ARMOUR );
-
- // ego armours
- rc += player_equip_ego_type( EQ_ALL_ARMOUR, SPARM_COLD_RESISTANCE );
- rc += player_equip_ego_type( EQ_ALL_ARMOUR, SPARM_RESISTANCE );
-
- // randart weapons:
- rc += scan_randarts(RAP_COLD, calc_unid);
-
- // species:
- if (you.species == SP_MUMMY || you.species == SP_GHOUL)
- rc++;
- else if (you.species == SP_WHITE_DRACONIAN && you.experience_level > 17)
- rc++;
-
- // mutations:
- rc += you.mutation[MUT_COLD_RESISTANCE];
-
- if (you.fire_shield)
- rc -= 2;
-
- // transformations:
- switch (you.attribute[ATTR_TRANSFORMATION])
- {
- case TRAN_ICE_BEAST:
- rc += 3;
- break;
- case TRAN_DRAGON:
- rc--;
- break;
- case TRAN_LICH:
- rc++;
- break;
- case TRAN_AIR:
- rc -= 2;
- break;
- }
-
- if (rc < -3)
- rc = -3;
- else if (rc > 3)
- rc = 3;
-
- return (rc);
-}
-
-int player_res_acid( void )
-{
- return (!transform_changed_physiology()
- && ((you.species == SP_GOLDEN_DRACONIAN
- && you.experience_level >= 7)
- || you.mutation[MUT_YELLOW_SCALES] == 3));
-}
-
-int player_res_electricity(bool calc_unid)
-{
- int re = 0;
-
- if (you.duration[DUR_INSULATION])
- re++;
-
- // staff
- re += player_equip( EQ_STAFF, STAFF_AIR, calc_unid );
-
- // body armour:
- re += player_equip( EQ_BODY_ARMOUR, ARM_STORM_DRAGON_ARMOUR );
-
- // randart weapons:
- re += scan_randarts(RAP_ELECTRICITY, calc_unid);
-
- // species:
- if (you.species == SP_BLACK_DRACONIAN && you.experience_level > 17)
- re++;
-
- // mutations:
- if (you.mutation[MUT_SHOCK_RESISTANCE])
- re++;
-
- // transformations:
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_STATUE)
- re += 1;
-
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_AIR)
- re += 2; // mutliple levels currently meaningless
-
- if (you.attribute[ATTR_DIVINE_LIGHTNING_PROTECTION] > 0)
- re = 3;
- else if (re > 1)
- re = 1;
-
- return (re);
-} // end player_res_electricity()
-
-// Does the player resist asphyxiation?
-bool player_res_asphyx()
-{
- // The undead are immune to asphyxiation, or so we'll assume.
- if (you.is_undead)
- return (true);
-
- switch (you.attribute[ATTR_TRANSFORMATION])
- {
- case TRAN_LICH:
- case TRAN_STATUE:
- case TRAN_SERPENT_OF_HELL:
- case TRAN_AIR:
- return (true);
- }
- return (false);
-}
-
-// funny that no races are susceptible to poisons {dlb}
-int player_res_poison(bool calc_unid)
-{
- int rp = 0;
-
- /* rings of poison resistance */
- rp += player_equip( EQ_RINGS, RING_POISON_RESISTANCE, calc_unid );
-
- /* Staves */
- rp += player_equip( EQ_STAFF, STAFF_POISON, calc_unid );
-
- /* the staff of Olgreb: */
- if (you.equip[EQ_WEAPON] != -1
- && you.inv[you.equip[EQ_WEAPON]].base_type == OBJ_WEAPONS
- && you.inv[you.equip[EQ_WEAPON]].special == SPWPN_STAFF_OF_OLGREB)
- {
- rp++;
- }
-
- // ego armour:
- rp += player_equip_ego_type( EQ_ALL_ARMOUR, SPARM_POISON_RESISTANCE );
-
- // body armour:
- rp += player_equip( EQ_BODY_ARMOUR, ARM_GOLD_DRAGON_ARMOUR );
- rp += player_equip( EQ_BODY_ARMOUR, ARM_SWAMP_DRAGON_ARMOUR );
-
- // spells:
- if (you.duration[DUR_RESIST_POISON] > 0)
- rp++;
-
- // randart weapons:
- rp += scan_randarts(RAP_POISON, calc_unid);
-
- // species:
- if (you.species == SP_MUMMY || you.species == SP_NAGA
- || you.species == SP_GHOUL
- || (you.species == SP_GREEN_DRACONIAN && you.experience_level > 6))
- {
- rp++;
- }
-
- // mutations:
- rp += you.mutation[MUT_POISON_RESISTANCE];
-
- // transformations:
- switch (you.attribute[ATTR_TRANSFORMATION])
- {
- case TRAN_LICH:
- case TRAN_ICE_BEAST:
- case TRAN_STATUE:
- case TRAN_DRAGON:
- case TRAN_SERPENT_OF_HELL:
- case TRAN_AIR:
- rp++;
- break;
- }
-
- if (rp > 3)
- rp = 3;
-
- return (rp);
-} // end player_res_poison()
-
-unsigned char player_spec_death(void)
-{
- int sd = 0;
-
- /* Staves */
- sd += player_equip( EQ_STAFF, STAFF_DEATH );
-
- // body armour:
- if (player_equip_ego_type( EQ_BODY_ARMOUR, SPARM_ARCHMAGI ))
- sd++;
-
- // species:
- if (you.species == SP_MUMMY)
- {
- if (you.experience_level >= 13)
- sd++;
- if (you.experience_level >= 26)
- sd++;
- }
-
- // transformations:
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_LICH)
- sd++;
-
- return sd;
-}
-
-unsigned char player_spec_holy(void)
-{
- //if ( you.char_class == JOB_PRIEST || you.char_class == JOB_PALADIN )
- // return 1;
- return 0;
-}
-
-unsigned char player_spec_fire(void)
-{
- int sf = 0;
-
- // staves:
- sf += player_equip( EQ_STAFF, STAFF_FIRE );
-
- // rings of fire:
- sf += player_equip( EQ_RINGS, RING_FIRE );
-
- if (you.fire_shield)
- sf++;
-
- return sf;
-}
-
-unsigned char player_spec_cold(void)
-{
- int sc = 0;
-
- // staves:
- sc += player_equip( EQ_STAFF, STAFF_COLD );
-
- // rings of ice:
- sc += player_equip( EQ_RINGS, RING_ICE );
-
- return sc;
-}
-
-unsigned char player_spec_earth(void)
-{
- int se = 0;
-
- /* Staves */
- se += player_equip( EQ_STAFF, STAFF_EARTH );
-
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_AIR)
- se--;
-
- return se;
-}
-
-unsigned char player_spec_air(void)
-{
- int sa = 0;
-
- /* Staves */
- sa += player_equip( EQ_STAFF, STAFF_AIR );
-
- //jmf: this was too good
- //if (you.attribute[ATTR_TRANSFORMATION] == TRAN_AIR)
- // sa++;
- return sa;
-}
-
-unsigned char player_spec_conj(void)
-{
- int sc = 0;
-
- /* Staves */
- sc += player_equip( EQ_STAFF, STAFF_CONJURATION );
-
- // armour of the Archmagi
- if (player_equip_ego_type( EQ_BODY_ARMOUR, SPARM_ARCHMAGI ))
- sc++;
-
- return sc;
-}
-
-unsigned char player_spec_ench(void)
-{
- int se = 0;
-
- /* Staves */
- se += player_equip( EQ_STAFF, STAFF_ENCHANTMENT );
-
- // armour of the Archmagi
- if (player_equip_ego_type( EQ_BODY_ARMOUR, SPARM_ARCHMAGI ))
- se++;
-
- return se;
-}
-
-unsigned char player_spec_summ(void)
-{
- int ss = 0;
-
- /* Staves */
- ss += player_equip( EQ_STAFF, STAFF_SUMMONING );
-
- // armour of the Archmagi
- if (player_equip_ego_type( EQ_BODY_ARMOUR, SPARM_ARCHMAGI ))
- ss++;
-
- return ss;
-}
-
-unsigned char player_spec_poison(void)
-{
- int sp = 0;
-
- /* Staves */
- sp += player_equip( EQ_STAFF, STAFF_POISON );
-
- if (you.equip[EQ_WEAPON] != -1
- && you.inv[you.equip[EQ_WEAPON]].base_type == OBJ_WEAPONS
- && you.inv[you.equip[EQ_WEAPON]].special == SPWPN_STAFF_OF_OLGREB)
- {
- sp++;
- }
-
- return sp;
-}
-
-unsigned char player_energy(void)
-{
- unsigned char pe = 0;
-
- // Staves
- pe += player_equip( EQ_STAFF, STAFF_ENERGY );
-
- return pe;
-}
-
-int player_prot_life(bool calc_unid)
-{
- int pl = 0;
-
- // rings
- pl += player_equip( EQ_RINGS, RING_LIFE_PROTECTION, calc_unid );
-
- // armour: (checks body armour only)
- pl += player_equip_ego_type( EQ_ALL_ARMOUR, SPARM_POSITIVE_ENERGY );
-
- if (you.is_undead)
- pl += 3;
-
- switch (you.attribute[ATTR_TRANSFORMATION])
- {
- case TRAN_STATUE:
- pl += 1;
- break;
-
- case TRAN_SERPENT_OF_HELL:
- pl += 2;
- break;
-
- case TRAN_LICH:
- pl += 3;
- break;
-
- default:
- break;
- }
-
- // randart wpns
- pl += scan_randarts(RAP_NEGATIVE_ENERGY, calc_unid);
-
- // demonic power
- pl += you.mutation[MUT_NEGATIVE_ENERGY_RESISTANCE];
-
- if (pl > 3)
- pl = 3;
-
- return (pl);
-}
-
-// New player movement speed system... allows for a bit more that
-// "player runs fast" and "player walks slow" in that the speed is
-// actually calculated (allowing for centaurs to get a bonus from
-// swiftness and other such things). Levels of the mutation now
-// also have meaning (before they all just meant fast). Most of
-// this isn't as fast as it used to be (6 for having anything), but
-// even a slight speed advantage is very good... and we certainly don't
-// want to go past 6 (see below). -- bwr
-int player_movement_speed(void)
-{
- int mv = 10;
-
- if (you.species == SP_MERFOLK && player_is_swimming())
- {
- // This is swimming... so it doesn't make sense to really
- // apply the other things (the mutation is "cover ground",
- // swiftness is an air spell, can't wear boots, can't be
- // transformed).
- mv = 6;
- }
- else
- {
- /* transformations */
- if (!player_is_shapechanged())
- {
- // Centaurs and spriggans are only fast in their regular
- // shape (ie untransformed, blade hands, lich form)
- if (you.species == SP_CENTAUR)
- mv = 8;
- else if (you.species == SP_SPRIGGAN)
- mv = 6;
- }
- else if (you.attribute[ATTR_TRANSFORMATION] == TRAN_SPIDER)
- mv = 8;
-
- /* armour */
- if (player_equip_ego_type( EQ_BOOTS, SPARM_RUNNING ))
- mv -= 2;
-
- if (player_equip_ego_type( EQ_BODY_ARMOUR, SPARM_PONDEROUSNESS ))
- mv += 2;
-
- // Swiftness is an Air spell, it doesn't work in water...
- // but levitating players will move faster. -- bwr
- if (you.duration[DUR_SWIFTNESS] > 0 && !player_in_water())
- mv -= (player_is_levitating() ? 4 : 2);
-
- /* Mutations: -2, -3, -4 */
- if (you.mutation[MUT_FAST] > 0)
- mv -= (you.mutation[MUT_FAST] + 1);
-
- // Burden
- if (you.burden_state == BS_ENCUMBERED)
- mv += 1;
- else if (you.burden_state == BS_OVERLOADED)
- mv += 3;
- }
-
- // We'll use the old value of six as a minimum, with haste this could
- // end up as a speed of three, which is about as fast as we want
- // the player to be able to go (since 3 is 3.33x as fast and 2 is 5x,
- // which is a bit of a jump, and a bit too fast) -- bwr
- if (mv < 6)
- mv = 6;
-
- // Nagas move slowly:
- if (you.species == SP_NAGA && !player_is_shapechanged())
- {
- mv *= 14;
- mv /= 10;
- }
-
- return (mv);
-}
-
-// This function differs from the above in that it's used to set the
-// initial time_taken value for the turn. Everything else (movement,
-// spellcasting, combat) applies a ratio to this value.
-int player_speed(void)
-{
- int ps = 10;
-
- if (you.haste)
- ps /= 2;
-
- switch (you.attribute[ATTR_TRANSFORMATION])
- {
- case TRAN_STATUE:
- ps *= 15;
- ps /= 10;
- break;
-
- case TRAN_SERPENT_OF_HELL:
- ps *= 12;
- ps /= 10;
- break;
-
- default:
- break;
- }
-
- return ps;
-}
-
-int player_AC(void)
-{
- int AC = 0;
- int i; // loop variable
-
- // get the armour race value that corresponds to the character's race:
- const unsigned long racial_type
- = ((player_genus(GENPC_DWARVEN)) ? ISFLAG_DWARVEN :
- (player_genus(GENPC_ELVEN)) ? ISFLAG_ELVEN :
- (you.species == SP_HILL_ORC) ? ISFLAG_ORCISH
- : 0);
-
- for (i = EQ_CLOAK; i <= EQ_BODY_ARMOUR; i++)
- {
- const int item = you.equip[i];
-
- if (item == -1 || i == EQ_SHIELD)
- continue;
-
- AC += you.inv[ item ].plus;
-
- // Note that helms and boots have a sub-sub classing system
- // which uses "plus2"... since not all members have the same
- // AC value, we use special cases. -- bwr
- if (i == EQ_HELMET
- && (get_helmet_type(you.inv[ item ]) == THELM_CAP
- || get_helmet_type(you.inv[ item ]) == THELM_WIZARD_HAT
- || get_helmet_type(you.inv[ item ]) == THELM_SPECIAL))
- {
- continue;
- }
-
- int racial_bonus = 0; // additional levels of armour skill
- const unsigned long armour_race = get_equip_race( you.inv[ item ] );
- const int ac_value = property( you.inv[ item ], PARM_AC );
-
- // Dwarven armour is universally good -- bwr
- if (armour_race == ISFLAG_DWARVEN)
- racial_bonus += 2;
-
- if (racial_type && armour_race == racial_type)
- {
- // Elven armour is light, but still gives one level
- // to elves. Orcish and Dwarven armour are worth +2
- // to the correct species, plus the plus that anyone
- // gets with dwarven armour. -- bwr
-
- if (racial_type == ISFLAG_ELVEN)
- racial_bonus++;
- else
- racial_bonus += 2;
- }
-
- AC += ac_value * (15 + you.skills[SK_ARMOUR] + racial_bonus) / 15;
-
- /* Nagas/Centaurs/the deformed don't fit into body armour very well */
- if ((you.species == SP_NAGA || you.species == SP_CENTAUR
- || you.mutation[MUT_DEFORMED] > 0) && i == EQ_BODY_ARMOUR)
- {
- AC -= ac_value / 2;
- }
- }
-
- AC += player_equip( EQ_RINGS_PLUS, RING_PROTECTION );
-
- if (player_equip_ego_type( EQ_WEAPON, SPWPN_PROTECTION ))
- AC += 5;
-
- if (player_equip_ego_type( EQ_SHIELD, SPARM_PROTECTION ))
- AC += 3;
-
- AC += scan_randarts(RAP_AC);
-
- if (you.duration[DUR_ICY_ARMOUR])
- AC += 4 + you.skills[SK_ICE_MAGIC] / 3; // max 13
-
- if (you.duration[DUR_STONEMAIL])
- AC += 5 + you.skills[SK_EARTH_MAGIC] / 2; // max 18
-
- if (you.duration[DUR_STONESKIN])
- AC += 2 + you.skills[SK_EARTH_MAGIC] / 5; // max 7
-
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_NONE
- || you.attribute[ATTR_TRANSFORMATION] == TRAN_LICH
- || you.attribute[ATTR_TRANSFORMATION] == TRAN_BLADE_HANDS)
- {
- // Being a lich doesn't preclude the benefits of hide/scales -- bwr
- //
- // Note: Even though necromutation is a high level spell, it does
- // allow the character full armour (so the bonus is low). -- bwr
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_LICH)
- AC += (3 + you.skills[SK_NECROMANCY] / 6); // max 7
-
- //jmf: only give:
- if (player_genus(GENPC_DRACONIAN))
- {
- if (you.experience_level < 8)
- AC += 2;
- else if (you.species == SP_GREY_DRACONIAN)
- AC += 1 + (you.experience_level - 4) / 2; // max 12
- else
- AC += 1 + (you.experience_level / 4); // max 7
- }
- else
- {
- switch (you.species)
- {
- case SP_NAGA:
- AC += you.experience_level / 3; // max 9
- break;
-
- case SP_OGRE:
- AC++;
- break;
-
- case SP_TROLL:
- case SP_CENTAUR:
- AC += 3;
- break;
-
- default:
- break;
- }
- }
-
- // Scales -- some evil uses of the fact that boolean "true" == 1...
- // I'll spell things out with some comments -- bwr
-
- // mutations:
- // these give: +1, +2, +3
- AC += you.mutation[MUT_TOUGH_SKIN];
- AC += you.mutation[MUT_GREY_SCALES];
- AC += you.mutation[MUT_SPECKLED_SCALES];
- AC += you.mutation[MUT_IRIDESCENT_SCALES];
- AC += you.mutation[MUT_PATTERNED_SCALES];
- AC += you.mutation[MUT_BLUE_SCALES];
-
- // these gives: +1, +3, +5
- if (you.mutation[MUT_GREEN_SCALES] > 0)
- AC += (you.mutation[MUT_GREEN_SCALES] * 2) - 1;
- if (you.mutation[MUT_NACREOUS_SCALES] > 0)
- AC += (you.mutation[MUT_NACREOUS_SCALES] * 2) - 1;
- if (you.mutation[MUT_BLACK2_SCALES] > 0)
- AC += (you.mutation[MUT_BLACK2_SCALES] * 2) - 1;
- if (you.mutation[MUT_WHITE_SCALES] > 0)
- AC += (you.mutation[MUT_WHITE_SCALES] * 2) - 1;
-
- // these give: +2, +4, +6
- AC += you.mutation[MUT_GREY2_SCALES] * 2;
- AC += you.mutation[MUT_YELLOW_SCALES] * 2;
- AC += you.mutation[MUT_PURPLE_SCALES] * 2;
-
- // black gives: +3, +6, +9
- AC += you.mutation[MUT_BLACK_SCALES] * 3;
-
- // boney plates give: +2, +3, +4
- if (you.mutation[MUT_BONEY_PLATES] > 0)
- AC += you.mutation[MUT_BONEY_PLATES] + 1;
-
- // red gives +1, +2, +4
- AC += you.mutation[MUT_RED_SCALES]
- + (you.mutation[MUT_RED_SCALES] == 3);
-
- // indigo gives: +2, +3, +5
- if (you.mutation[MUT_INDIGO_SCALES] > 0)
- {
- AC += 1 + you.mutation[MUT_INDIGO_SCALES]
- + (you.mutation[MUT_INDIGO_SCALES] == 3);
- }
-
- // brown gives: +2, +4, +5
- AC += (you.mutation[MUT_BROWN_SCALES] * 2)
- - (you.mutation[MUT_METALLIC_SCALES] == 3);
-
- // orange gives: +1, +3, +4
- AC += you.mutation[MUT_ORANGE_SCALES]
- + (you.mutation[MUT_ORANGE_SCALES] > 1);
-
- // knobbly red gives: +2, +5, +7
- AC += (you.mutation[MUT_RED2_SCALES] * 2)
- + (you.mutation[MUT_RED2_SCALES] > 1);
-
- // metallic gives +3, +7, +10
- AC += you.mutation[MUT_METALLIC_SCALES] * 3
- + (you.mutation[MUT_METALLIC_SCALES] > 1);
- }
- else
- {
- // transformations:
- switch (you.attribute[ATTR_TRANSFORMATION])
- {
- case TRAN_NONE:
- case TRAN_BLADE_HANDS:
- case TRAN_LICH: // can wear normal body armour (small bonus)
- break;
-
-
- case TRAN_SPIDER: // low level (small bonus), also gets EV
- AC += (2 + you.skills[SK_POISON_MAGIC] / 6); // max 6
- break;
-
- case TRAN_ICE_BEAST:
- AC += (5 + (you.skills[SK_ICE_MAGIC] + 1) / 4); // max 12
-
- if (you.duration[DUR_ICY_ARMOUR])
- AC += (1 + you.skills[SK_ICE_MAGIC] / 4); // max +7
- break;
-
- case TRAN_DRAGON:
- AC += (7 + you.skills[SK_FIRE_MAGIC] / 3); // max 16
- break;
-
- case TRAN_STATUE: // main ability is armour (high bonus)
- AC += (17 + you.skills[SK_EARTH_MAGIC] / 2); // max 30
-
- if (you.duration[DUR_STONESKIN] || you.duration[DUR_STONEMAIL])
- AC += (1 + you.skills[SK_EARTH_MAGIC] / 4); // max +7
- break;
-
- case TRAN_SERPENT_OF_HELL:
- AC += (10 + you.skills[SK_FIRE_MAGIC] / 3); // max 19
- break;
-
- case TRAN_AIR: // air - scales & species ought to be irrelevent
- AC = (you.skills[SK_AIR_MAGIC] * 3) / 2; // max 40
- break;
-
- default:
- break;
- }
- }
-
- return AC;
-}
-
-bool is_light_armour( const item_def &item )
-{
- if (get_equip_race(item) == ISFLAG_ELVEN)
- return (true);
-
- switch (item.sub_type)
- {
- case ARM_ROBE:
- case ARM_ANIMAL_SKIN:
- case ARM_LEATHER_ARMOUR:
- case ARM_STEAM_DRAGON_HIDE:
- case ARM_STEAM_DRAGON_ARMOUR:
- case ARM_MOTTLED_DRAGON_HIDE:
- case ARM_MOTTLED_DRAGON_ARMOUR:
- //case ARM_TROLL_HIDE: //jmf: these are knobbly and stiff
- //case ARM_TROLL_LEATHER_ARMOUR:
- return (true);
-
- default:
- return (false);
- }
-}
-
-bool player_light_armour(void)
-{
- if (you.equip[EQ_BODY_ARMOUR] == -1)
- return true;
-
- return (is_light_armour( you.inv[you.equip[EQ_BODY_ARMOUR]] ));
-} // end player_light_armour()
-
-//
-// This function returns true if the player has a radically different
-// shape... minor changes like blade hands don't count, also note
-// that lich transformation doesn't change the character's shape
-// (so we end up with Naga-lichs, Spiggan-lichs, Minotaur-lichs)
-// it just makes the character undead (with the benefits that implies). --bwr
-//
-bool player_is_shapechanged(void)
-{
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_NONE
- || you.attribute[ATTR_TRANSFORMATION] == TRAN_BLADE_HANDS
- || you.attribute[ATTR_TRANSFORMATION] == TRAN_LICH)
- {
- return (false);
- }
-
- return (true);
-}
-
-int player_evasion(void)
-{
- int ev = 10;
-
- int armour_ev_penalty;
-
- if (you.equip[EQ_BODY_ARMOUR] == -1)
- armour_ev_penalty = 0;
- else
- {
- armour_ev_penalty = property( you.inv[you.equip[EQ_BODY_ARMOUR]],
- PARM_EVASION );
- }
-
- // We return 2 here to give the player some chance of not being hit,
- // repulsion fields still work while paralysed
- if (you.paralysis)
- return (2 + you.mutation[MUT_REPULSION_FIELD] * 2);
-
- if (you.species == SP_CENTAUR)
- ev -= 3;
-
- if (you.equip[EQ_BODY_ARMOUR] != -1)
- {
- int ev_change = 0;
-
- ev_change = armour_ev_penalty;
- ev_change += you.skills[SK_ARMOUR] / 3;
-
- if (ev_change > armour_ev_penalty / 3)
- ev_change = armour_ev_penalty / 3;
-
- ev += ev_change; /* remember that it's negative */
- }
-
- ev += player_equip( EQ_RINGS_PLUS, RING_EVASION );
-
- if (player_equip_ego_type( EQ_BODY_ARMOUR, SPARM_PONDEROUSNESS ))
- ev -= 2;
-
- if (you.duration[DUR_STONEMAIL])
- ev -= 2;
-
- if (you.duration[DUR_FORESCRY])
- ev += 8; //jmf: is this a reasonable value?
-
- int emod = 0;
-
- if (!player_light_armour())
- {
- // meaning that the armour evasion modifier is often effectively
- // applied twice, but not if you're wearing elven armour
- emod += (armour_ev_penalty * 14) / 10;
- }
-
- emod += you.skills[SK_DODGING] / 2;
-
- if (emod > 0)
- ev += emod;
-
- if (you.mutation[MUT_REPULSION_FIELD] > 0)
- ev += (you.mutation[MUT_REPULSION_FIELD] * 2) - 1;
-
- switch (you.attribute[ATTR_TRANSFORMATION])
- {
- case TRAN_DRAGON:
- ev -= 3;
- break;
-
- case TRAN_STATUE:
- case TRAN_SERPENT_OF_HELL:
- ev -= 5;
- break;
-
- case TRAN_SPIDER:
- ev += 3;
- break;
-
- case TRAN_AIR:
- ev += 20;
- break;
-
- default:
- break;
- }
-
- ev += scan_randarts(RAP_EVASION);
-
- return ev;
-} // end player_evasion()
-
-int player_magical_power( void )
-{
- int ret = 0;
-
- ret += 13 * player_equip( EQ_STAFF, STAFF_POWER );
- ret += 9 * player_equip( EQ_RINGS, RING_MAGICAL_POWER );
-
- return (ret);
-}
-
-int player_mag_abil(bool is_weighted)
-{
- int ma = 0;
-
- ma += 3 * player_equip( EQ_RINGS, RING_WIZARDRY );
-
- /* Staves */
- ma += 4 * player_equip( EQ_STAFF, STAFF_WIZARDRY );
-
- /* armour of the Archmagi (checks body armour only) */
- ma += 2 * player_equip_ego_type( EQ_BODY_ARMOUR, SPARM_ARCHMAGI );
-
- return ((is_weighted) ? ((ma * you.intel) / 10) : ma);
-} // end player_mag_abil()
-
-int player_shield_class(void) //jmf: changes for new spell
-{
- int base_shield = 0;
- const int shield = you.equip[EQ_SHIELD];
-
- if (shield == -1)
- {
- if (!you.fire_shield && you.duration[DUR_CONDENSATION_SHIELD])
- base_shield = 2 + (you.skills[SK_ICE_MAGIC] / 6); // max 6
- else
- return (0);
- }
- else
- {
- switch (you.inv[ shield ].sub_type)
- {
- case ARM_BUCKLER:
- base_shield = 3; // +3/20 per skill level max 7
- break;
- case ARM_SHIELD:
- base_shield = 5; // +5/20 per skill level max 11
- break;
- case ARM_LARGE_SHIELD:
- base_shield = 7; // +7/20 per skill level max 16
- break;
- }
-
- // bonus applied only to base, see above for effect:
- base_shield *= (20 + you.skills[SK_SHIELDS]);
- base_shield /= 20;
-
- base_shield += you.inv[ shield ].plus;
- }
-
- return (base_shield);
-} // end player_shield_class()
-
-unsigned char player_see_invis(bool calc_unid)
-{
- unsigned char si = 0;
-
- si += player_equip( EQ_RINGS, RING_SEE_INVISIBLE, calc_unid );
-
- /* armour: (checks head armour only) */
- si += player_equip_ego_type( EQ_HELMET, SPARM_SEE_INVISIBLE );
-
- /* Nagas & Spriggans have good eyesight */
- if (you.species == SP_NAGA || you.species == SP_SPRIGGAN)
- si++;
-
- if (you.mutation[MUT_ACUTE_VISION] > 0)
- si += you.mutation[MUT_ACUTE_VISION];
-
- //jmf: added see_invisible spell
- if (you.duration[DUR_SEE_INVISIBLE] > 0)
- si++;
-
- /* randart wpns */
- int artefacts = scan_randarts(RAP_EYESIGHT, calc_unid);
-
- if (artefacts > 0)
- si += artefacts;
-
- return si;
-}
-
-// This does NOT do line of sight! It checks the monster's visibility
-// with repect to the players perception, but doesn't do walls or range...
-// to find if the square the monster is in is visible see mons_near().
-bool player_monster_visible( const monsters *mon )
-{
- if (mons_has_ench( mon, ENCH_SUBMERGED )
- || (mons_has_ench( mon, ENCH_INVIS ) && !player_see_invis()))
- {
- return (false);
- }
-
- return (true);
-}
-
-unsigned char player_sust_abil(bool calc_unid)
-{
- unsigned char sa = 0;
-
- sa += player_equip( EQ_RINGS, RING_SUSTAIN_ABILITIES, calc_unid );
-
- return sa;
-} // end player_sust_abil()
-
-int carrying_capacity(void)
-{
- // Originally: 1000 + you.strength * 200 + ( you.levitation ? 1000 : 0 )
- return (3500 + (you.strength * 100) + (player_is_levitating() ? 1000 : 0));
-}
-
-int burden_change(void)
-{
- char old_burdenstate = you.burden_state;
-
- you.burden = 0;
-
- int max_carried = carrying_capacity();
-
- if (you.duration[DUR_STONEMAIL])
- you.burden += 800;
-
- for (unsigned char bu = 0; bu < ENDOFPACK; bu++)
- {
- if (you.inv[bu].quantity < 1)
- continue;
-
- if (you.inv[bu].base_type == OBJ_CORPSES)
- {
- if (you.inv[bu].sub_type == CORPSE_BODY)
- you.burden += mons_weight(you.inv[bu].plus);
- else if (you.inv[bu].sub_type == CORPSE_SKELETON)
- you.burden += mons_weight(you.inv[bu].plus) / 2;
- }
- else
- {
- you.burden += item_mass( you.inv[bu] ) * you.inv[bu].quantity;
- }
- }
-
- you.burden_state = BS_UNENCUMBERED;
- set_redraw_status( REDRAW_BURDEN );
-
- // changed the burdened levels to match the change to max_carried
- if (you.burden < (max_carried * 5) / 6)
- // (you.burden < max_carried - 1000)
- {
- you.burden_state = BS_UNENCUMBERED;
-
- // this message may have to change, just testing {dlb}
- if (old_burdenstate != you.burden_state)
- mpr("Your possessions no longer seem quite so burdensome.");
- }
- else if (you.burden < (max_carried * 11) / 12)
- // (you.burden < max_carried - 500)
- {
- you.burden_state = BS_ENCUMBERED;
-
- if (old_burdenstate != you.burden_state)
- mpr("You are being weighed down by all of your possessions.");
- }
- else
- {
- you.burden_state = BS_OVERLOADED;
-
- if (old_burdenstate != you.burden_state)
- mpr("You are being crushed by all of your possessions.");
- }
-
- // Stop travel if we get burdened (as from potions of might/levitation
- // wearing off).
- if (you.burden_state > old_burdenstate)
- interrupt_activity( AI_BURDEN_CHANGE );
-
- return you.burden;
-} // end burden_change()
-
-bool you_resist_magic(int power)
-{
- int ench_power = stepdown_value( power, 30, 40, 100, 120 );
-
- int mrchance = 100 + player_res_magic();
-
- mrchance -= ench_power;
-
- int mrch2 = random2(100) + random2(101);
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "Power: %d, player's MR: %d, target: %d, roll: %d",
- ench_power, player_res_magic(), mrchance, mrch2 );
-
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- if (mrch2 < mrchance)
- return true; // ie saved successfully
-
- return false;
-/* if (random2(power) / 3 + random2(power) / 3 + random2(power) / 3 >= player_res_magic()) return 0;
- return 1; */
-}
-
-void forget_map(unsigned char chance_forgotten)
-{
- unsigned char xcount, ycount = 0;
-
- for (xcount = 0; xcount < GXM; xcount++)
- {
- for (ycount = 0; ycount < GYM; ycount++)
- {
- if (random2(100) < chance_forgotten)
- {
- env.map[xcount][ycount] = 0;
- }
- }
- }
-} // end forget_map()
-
-void gain_exp( unsigned int exp_gained )
-{
-
- if (player_equip_ego_type( EQ_BODY_ARMOUR, SPARM_ARCHMAGI )
- && !one_chance_in(20))
- {
- return;
- }
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "gain_exp: %d", exp_gained );
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- if (you.experience + exp_gained > 8999999)
- you.experience = 8999999;
- else
- you.experience += exp_gained;
-
- if (you.exp_available + exp_gained > 20000)
- you.exp_available = 20000;
- else
- you.exp_available += exp_gained;
-
- level_change();
-} // end gain_exp()
-
-void level_change(void)
-{
- int hp_adjust = 0;
- int mp_adjust = 0;
-
- // necessary for the time being, as level_change() is called
- // directly sometimes {dlb}
- you.redraw_experience = 1;
-
- while (you.experience_level < 27
- && you.experience > exp_needed(you.experience_level + 2))
- {
- you.experience_level++;
-
- if (you.experience_level <= you.max_level)
- {
- snprintf( info, INFO_SIZE, "Welcome back to level %d!",
- you.experience_level );
-
- mpr(info, MSGCH_INTRINSIC_GAIN);
- more();
-
- // Gain back the hp and mp we lose in lose_level(). -- bwr
- inc_hp( 4, true );
- inc_mp( 1, true );
- }
- else // character has gained a new level
- {
- snprintf( info, INFO_SIZE, "You are now a level %d %s!",
- you.experience_level, you.class_name );
-
- mpr(info, MSGCH_INTRINSIC_GAIN);
- more();
-
- int brek = 0;
-
- if (you.experience_level > 21)
- brek = (coinflip() ? 3 : 2);
- else if (you.experience_level > 12)
- brek = 3 + random2(3); // up from 2 + rand(3) -- bwr
- else
- brek = 4 + random2(4); // up from 3 + rand(4) -- bwr
-
- inc_hp( brek, true );
- inc_mp( 1, true );
-
- if (!(you.experience_level % 3))
- ability_increase();
-
- switch (you.species)
- {
- case SP_HUMAN:
- if (!(you.experience_level % 5))
- modify_stat(STAT_RANDOM, 1, false);
- break;
-
- case SP_ELF:
- if (you.experience_level % 3)
- hp_adjust--;
- else
- mp_adjust++;
-
- if (!(you.experience_level % 4))
- {
- modify_stat( (coinflip() ? STAT_INTELLIGENCE
- : STAT_DEXTERITY), 1, false );
- }
- break;
-
- case SP_HIGH_ELF:
- if (you.experience_level == 15)
- {
- //jmf: got Glamour ability
- mpr("You feel charming!", MSGCH_INTRINSIC_GAIN);
- }
-
- if (you.experience_level % 3)
- hp_adjust--;
-
- if (!(you.experience_level % 2))
- mp_adjust++;
-
- if (!(you.experience_level % 3))
- {
- modify_stat( (coinflip() ? STAT_INTELLIGENCE
- : STAT_DEXTERITY), 1, false );
- }
- break;
-
- case SP_GREY_ELF:
- if (you.experience_level == 5)
- {
- //jmf: got Glamour ability
- mpr("You feel charming!", MSGCH_INTRINSIC_GAIN);
- mp_adjust++;
- }
-
- if (you.experience_level < 14)
- hp_adjust--;
-
- if (you.experience_level % 3)
- mp_adjust++;
-
- if (!(you.experience_level % 4))
- {
- modify_stat( (coinflip() ? STAT_INTELLIGENCE
- : STAT_DEXTERITY), 1, false );
- }
-
- break;
-
- case SP_DEEP_ELF:
- if (you.experience_level < 17)
- hp_adjust--;
- if (!(you.experience_level % 3))
- hp_adjust--;
-
- mp_adjust++;
-
- if (!(you.experience_level % 4))
- modify_stat(STAT_INTELLIGENCE, 1, false);
- break;
-
- case SP_SLUDGE_ELF:
- if (you.experience_level % 3)
- hp_adjust--;
- else
- mp_adjust++;
-
- if (!(you.experience_level % 4))
- {
- modify_stat( (coinflip() ? STAT_INTELLIGENCE
- : STAT_DEXTERITY), 1, false );
- }
- break;
-
- case SP_HILL_DWARF:
- // lowered because of HD raise -- bwr
- // if (you.experience_level < 14)
- // hp_adjust++;
-
- if (you.experience_level % 3)
- hp_adjust++;
-
- if (!(you.experience_level % 2))
- mp_adjust--;
-
- if (!(you.experience_level % 4))
- modify_stat(STAT_STRENGTH, 1, false);
- break;
-
- case SP_MOUNTAIN_DWARF:
- // lowered because of HD raise -- bwr
- // if (you.experience_level < 14)
- // hp_adjust++;
-
- if (!(you.experience_level % 2))
- hp_adjust++;
-
- if (!(you.experience_level % 3))
- mp_adjust--;
-
- if (!(you.experience_level % 4))
- modify_stat(STAT_STRENGTH, 1, false);
- break;
-
- case SP_HALFLING:
- if (!(you.experience_level % 5))
- modify_stat(STAT_DEXTERITY, 1, false);
-
- if (you.experience_level < 17)
- hp_adjust--;
-
- if (!(you.experience_level % 2))
- hp_adjust--;
- break;
-
- case SP_KOBOLD:
- if (!(you.experience_level % 5))
- {
- modify_stat( (coinflip() ? STAT_STRENGTH
- : STAT_DEXTERITY), 1, false );
- }
-
- if (you.experience_level < 17)
- hp_adjust--;
-
- if (!(you.experience_level % 2))
- hp_adjust--;
- break;
-
- case SP_HILL_ORC:
- // lower because of HD raise -- bwr
- // if (you.experience_level < 17)
- // hp_adjust++;
-
- if (!(you.experience_level % 2))
- hp_adjust++;
-
- if (!(you.experience_level % 3))
- mp_adjust--;
-
- if (!(you.experience_level % 5))
- modify_stat(STAT_STRENGTH, 1, false);
- break;
-
- case SP_MUMMY:
- if (you.experience_level == 13 || you.experience_level == 26)
- {
- mpr( "You feel more in touch with the powers of death.",
- MSGCH_INTRINSIC_GAIN );
- }
-
- if (you.experience_level == 13) // level 13 for now -- bwr
- {
- mpr( "You can now infuse your body with magic to restore decomposition.", MSGCH_INTRINSIC_GAIN );
- }
- break;
-
- case SP_NAGA:
- // lower because of HD raise -- bwr
- // if (you.experience_level < 14)
- // hp_adjust++;
-
- hp_adjust++;
-
- if (!(you.experience_level % 4))
- modify_stat(STAT_RANDOM, 1, false);
-
- if (!(you.experience_level % 3))
- {
- mpr("Your skin feels tougher.", MSGCH_INTRINSIC_GAIN);
- you.redraw_armour_class = 1;
- }
- break;
-
- case SP_GNOME:
- if (you.experience_level < 13)
- hp_adjust--;
-
- if (!(you.experience_level % 3))
- hp_adjust--;
-
- if (!(you.experience_level % 4))
- {
- modify_stat( (coinflip() ? STAT_INTELLIGENCE
- : STAT_DEXTERITY), 1, false );
- }
- break;
-
- case SP_OGRE:
- case SP_TROLL:
- hp_adjust++;
-
- // lowered because of HD raise -- bwr
- // if (you.experience_level < 14)
- // hp_adjust++;
-
- if (!(you.experience_level % 2))
- hp_adjust++;
-
- if (you.experience_level % 3)
- mp_adjust--;
-
- if (!(you.experience_level % 3))
- modify_stat(STAT_STRENGTH, 1, false);
- break;
-
- case SP_OGRE_MAGE:
- hp_adjust++;
-
- // lowered because of HD raise -- bwr
- // if (you.experience_level < 14)
- // hp_adjust++;
-
- if (!(you.experience_level % 5))
- {
- modify_stat( (coinflip() ? STAT_INTELLIGENCE
- : STAT_STRENGTH), 1, false );
- }
- break;
-
- case SP_RED_DRACONIAN:
- case SP_WHITE_DRACONIAN:
- case SP_GREEN_DRACONIAN:
- case SP_GOLDEN_DRACONIAN:
-/* Grey is later */
- case SP_BLACK_DRACONIAN:
- case SP_PURPLE_DRACONIAN:
- case SP_MOTTLED_DRACONIAN:
- case SP_PALE_DRACONIAN:
- case SP_UNK0_DRACONIAN:
- case SP_UNK1_DRACONIAN:
- case SP_BASE_DRACONIAN:
- if (you.experience_level == 7)
- {
- switch (you.species)
- {
- case SP_RED_DRACONIAN:
- mpr("Your scales start taking on a fiery red colour.",
- MSGCH_INTRINSIC_GAIN);
- break;
- case SP_WHITE_DRACONIAN:
- mpr("Your scales start taking on an icy white colour.",
- MSGCH_INTRINSIC_GAIN);
- break;
- case SP_GREEN_DRACONIAN:
- mpr("Your scales start taking on a green colour.",
- MSGCH_INTRINSIC_GAIN);
- mpr("You feel resistant to poison.", MSGCH_INTRINSIC_GAIN);
- break;
-
- case SP_GOLDEN_DRACONIAN:
- mpr("Your scales start taking on a golden yellow colour.", MSGCH_INTRINSIC_GAIN);
- break;
- case SP_BLACK_DRACONIAN:
- mpr("Your scales start turning black.", MSGCH_INTRINSIC_GAIN);
- break;
- case SP_PURPLE_DRACONIAN:
- mpr("Your scales start taking on a rich purple colour.", MSGCH_INTRINSIC_GAIN);
- break;
- case SP_MOTTLED_DRACONIAN:
- mpr("Your scales start taking on a weird mottled pattern.", MSGCH_INTRINSIC_GAIN);
- break;
- case SP_PALE_DRACONIAN:
- mpr("Your scales start fading to a pale grey colour.", MSGCH_INTRINSIC_GAIN);
- break;
- case SP_UNK0_DRACONIAN:
- case SP_UNK1_DRACONIAN:
- case SP_BASE_DRACONIAN:
- mpr("");
- break;
- }
- more();
- redraw_screen();
- }
-
- if (you.experience_level == 18)
- {
- switch (you.species)
- {
- case SP_RED_DRACONIAN:
- mpr("You feel resistant to fire.", MSGCH_INTRINSIC_GAIN);
- break;
- case SP_WHITE_DRACONIAN:
- mpr("You feel resistant to cold.", MSGCH_INTRINSIC_GAIN);
- break;
- case SP_BLACK_DRACONIAN:
- mpr("You feel resistant to electrical energy.",
- MSGCH_INTRINSIC_GAIN);
- break;
- }
- }
-
- if (!(you.experience_level % 3))
- hp_adjust++;
-
- if (you.experience_level > 7 && !(you.experience_level % 4))
- {
- mpr("Your scales feel tougher.", MSGCH_INTRINSIC_GAIN);
- you.redraw_armour_class = 1;
- modify_stat(STAT_RANDOM, 1, false);
- }
- break;
-
- case SP_GREY_DRACONIAN:
- if (you.experience_level == 7)
- {
- mpr("Your scales start turning grey.", MSGCH_INTRINSIC_GAIN);
- more();
- redraw_screen();
- }
-
- if (!(you.experience_level % 3))
- {
- hp_adjust++;
- if (you.experience_level > 7)
- hp_adjust++;
- }
-
- if (you.experience_level > 7 && !(you.experience_level % 2))
- {
- mpr("Your scales feel tougher.", MSGCH_INTRINSIC_GAIN);
- you.redraw_armour_class = 1;
- }
-
- if ((you.experience_level > 7 && !(you.experience_level % 3))
- || you.experience_level == 4 || you.experience_level == 7)
- {
- modify_stat(STAT_RANDOM, 1, false);
- }
- break;
-
- case SP_CENTAUR:
- if (!(you.experience_level % 4))
- {
- modify_stat( (coinflip() ? STAT_DEXTERITY
- : STAT_STRENGTH), 1, false );
- }
-
- // lowered because of HD raise -- bwr
- // if (you.experience_level < 17)
- // hp_adjust++;
-
- if (!(you.experience_level % 2))
- hp_adjust++;
-
- if (!(you.experience_level % 3))
- mp_adjust--;
- break;
-
- case SP_DEMIGOD:
- if (!(you.experience_level % 3))
- modify_stat(STAT_RANDOM, 1, false);
-
- // lowered because of HD raise -- bwr
- // if (you.experience_level < 17)
- // hp_adjust++;
-
- if (!(you.experience_level % 2))
- hp_adjust++;
-
- if (you.experience_level % 3)
- mp_adjust++;
- break;
-
- case SP_SPRIGGAN:
- if (you.experience_level < 17)
- hp_adjust--;
-
- if (you.experience_level % 3)
- hp_adjust--;
-
- mp_adjust++;
-
- if (!(you.experience_level % 5))
- {
- modify_stat( (coinflip() ? STAT_INTELLIGENCE
- : STAT_DEXTERITY), 1, false );
- }
- break;
-
- case SP_MINOTAUR:
- // lowered because of HD raise -- bwr
- // if (you.experience_level < 17)
- // hp_adjust++;
-
- if (!(you.experience_level % 2))
- hp_adjust++;
-
- if (!(you.experience_level % 2))
- mp_adjust--;
-
- if (!(you.experience_level % 4))
- {
- modify_stat( (coinflip() ? STAT_DEXTERITY
- : STAT_STRENGTH), 1, false );
- }
- break;
-
- case SP_DEMONSPAWN:
- if (you.attribute[ATTR_NUM_DEMONIC_POWERS] == 0
- && (you.experience_level == 4
- || (you.experience_level < 4 && one_chance_in(3))))
- {
- demonspawn();
- }
-
- if (you.attribute[ATTR_NUM_DEMONIC_POWERS] == 1
- && you.experience_level > 4
- && (you.experience_level == 9
- || (you.experience_level < 9 && one_chance_in(3))))
- {
- demonspawn();
- }
-
- if (you.attribute[ATTR_NUM_DEMONIC_POWERS] == 2
- && you.experience_level > 9
- && (you.experience_level == 14
- || (you.experience_level < 14 && one_chance_in(3))))
- {
- demonspawn();
- }
-
- if (you.attribute[ATTR_NUM_DEMONIC_POWERS] == 3
- && you.experience_level > 14
- && (you.experience_level == 19
- || (you.experience_level < 19 && one_chance_in(3))))
- {
- demonspawn();
- }
-
- if (you.attribute[ATTR_NUM_DEMONIC_POWERS] == 4
- && you.experience_level > 19
- && (you.experience_level == 24
- || (you.experience_level < 24 && one_chance_in(3))))
- {
- demonspawn();
- }
-
- if (you.attribute[ATTR_NUM_DEMONIC_POWERS] == 5
- && you.experience_level == 27)
- {
- demonspawn();
- }
-
-/*if (you.attribute [ATTR_NUM_DEMONIC_POWERS] == 6 && (you.experience_level == 8 || (you.experience_level < 8 && one_chance_in(3) ) )
- demonspawn(); */
- if (!(you.experience_level % 4))
- modify_stat(STAT_RANDOM, 1, false);
- break;
-
- case SP_GHOUL:
- // lowered because of HD raise -- bwr
- // if (you.experience_level < 17)
- // hp_adjust++;
-
- if (!(you.experience_level % 2))
- hp_adjust++;
-
- if (!(you.experience_level % 3))
- mp_adjust--;
-
- if (!(you.experience_level % 5))
- modify_stat(STAT_STRENGTH, 1, false);
- break;
-
- case SP_KENKU:
- if (you.experience_level < 17)
- hp_adjust--;
-
- if (!(you.experience_level % 3))
- hp_adjust--;
-
- if (!(you.experience_level % 4))
- modify_stat(STAT_RANDOM, 1, false);
-
- if (you.experience_level == 5)
- mpr("You have gained the ability to fly.", MSGCH_INTRINSIC_GAIN);
- else if (you.experience_level == 15)
- mpr("You can now fly continuously.", MSGCH_INTRINSIC_GAIN);
- break;
-
- case SP_MERFOLK:
- if (you.experience_level % 3)
- hp_adjust++;
-
- if (!(you.experience_level % 5))
- modify_stat(STAT_RANDOM, 1, false);
- break;
- }
- }
-
- // add hp and mp adjustments - GDL
- inc_max_hp( hp_adjust );
- inc_max_mp( mp_adjust );
-
- deflate_hp( you.hp_max, false );
-
- if (you.magic_points < 0)
- you.magic_points = 0;
-
- calc_hp();
- calc_mp();
-
- if (you.experience_level > you.max_level)
- you.max_level = you.experience_level;
-
- if (you.religion == GOD_XOM)
- Xom_acts(true, you.experience_level, true);
- }
-
- redraw_skill( you.your_name, player_title() );
-} // end level_change()
-
-// here's a question for you: does the ordering of mods make a difference?
-// (yes) -- are these things in the right order of application to stealth?
-// - 12mar2000 {dlb}
-int check_stealth(void)
-{
- if (you.special_wield == SPWLD_SHADOW)
- return (0);
-
- int stealth = you.dex * 3;
-
- if (you.skills[SK_STEALTH])
- {
- if (player_genus(GENPC_DRACONIAN))
- stealth += (you.skills[SK_STEALTH] * 12);
- else
- {
- switch (you.species)
- {
- case SP_TROLL:
- case SP_OGRE:
- case SP_OGRE_MAGE:
- case SP_CENTAUR:
- stealth += (you.skills[SK_STEALTH] * 9);
- break;
- case SP_MINOTAUR:
- stealth += (you.skills[SK_STEALTH] * 12);
- break;
- case SP_GNOME:
- case SP_HALFLING:
- case SP_KOBOLD:
- case SP_SPRIGGAN:
- case SP_NAGA: // not small but very good at stealth
- stealth += (you.skills[SK_STEALTH] * 18);
- break;
- default:
- stealth += (you.skills[SK_STEALTH] * 15);
- break;
- }
- }
- }
-
- if (you.burden_state == BS_ENCUMBERED)
- stealth /= 2;
- else if (you.burden_state == BS_OVERLOADED)
- stealth /= 5;
-
- if (you.conf)
- stealth /= 3;
-
- const int arm = you.equip[EQ_BODY_ARMOUR];
- const int cloak = you.equip[EQ_CLOAK];
- const int boots = you.equip[EQ_BOOTS];
-
- if (arm != -1 && !player_light_armour())
- stealth -= (item_mass( you.inv[arm] ) / 10);
-
- if (cloak != -1 && get_equip_race(you.inv[cloak]) == ISFLAG_ELVEN)
- stealth += 20;
-
- if (boots != -1)
- {
- if (get_armour_ego_type( you.inv[boots] ) == SPARM_STEALTH)
- stealth += 50;
-
- if (get_equip_race(you.inv[boots]) == ISFLAG_ELVEN)
- stealth += 20;
- }
-
- stealth += scan_randarts( RAP_STEALTH );
-
- if (player_is_levitating())
- stealth += 10;
- else if (player_in_water())
- {
- // Merfolk can sneak up on monsters underwater -- bwr
- if (you.species == SP_MERFOLK)
- stealth += 50;
- else
- stealth /= 2; // splashy-splashy
- }
-
- // Radiating silence is the negative compliment of shouting all the
- // time... a sudden change from background noise to no noise is going
- // to clue anything in to the fact that something is very wrong...
- // a personal silence spell would naturally be different, but this
- // silence radiates for a distance and prevents monster spellcasting,
- // which pretty much gives away the stealth game.
- if (you.duration[DUR_SILENCE])
- stealth -= 50;
-
- if (stealth < 0)
- stealth = 0;
-
- return (stealth);
-} // end check_stealth()
-
-void ability_increase(void)
-{
- unsigned char keyin;
-
- mpr("Your experience leads to an increase in your attributes!",
- MSGCH_INTRINSIC_GAIN);
-
- more();
- mesclr();
-
- mpr("Increase (S)trength, (I)ntelligence, or (D)exterity? ", MSGCH_PROMPT);
-
- get_key:
- keyin = getch();
- if (keyin == 0)
- {
- getch();
- goto get_key;
- }
-
- switch (keyin)
- {
- case 's':
- case 'S':
- modify_stat(STAT_STRENGTH, 1, false);
- return;
-
- case 'i':
- case 'I':
- modify_stat(STAT_INTELLIGENCE, 1, false);
- return;
-
- case 'd':
- case 'D':
- modify_stat(STAT_DEXTERITY, 1, false);
- return;
- }
-
- goto get_key;
-/* this is an infinite loop because it is reasonable to assume that you're not going to want to leave it prematurely. */
-} // end ability_increase()
-
-void display_char_status(void)
-{
- if (you.is_undead)
- mpr( "You are undead." );
- else if (you.deaths_door)
- mpr( "You are standing in death's doorway." );
- else
- mpr( "You are alive." );
-
- switch (you.attribute[ATTR_TRANSFORMATION])
- {
- case TRAN_SPIDER:
- mpr( "You are in spider-form." );
- break;
- case TRAN_BLADE_HANDS:
- mpr( "You have blades for hands." );
- break;
- case TRAN_STATUE:
- mpr( "You are a statue." );
- break;
- case TRAN_ICE_BEAST:
- mpr( "You are an ice creature." );
- break;
- case TRAN_DRAGON:
- mpr( "You are in dragon-form." );
- break;
- case TRAN_LICH:
- mpr( "You are in lich-form." );
- break;
- case TRAN_SERPENT_OF_HELL:
- mpr( "You are a huge demonic serpent." );
- break;
- case TRAN_AIR:
- mpr( "You are a cloud of diffuse gas." );
- break;
- }
-
- if (you.duration[DUR_BREATH_WEAPON])
- mpr( "You are short of breath." );
-
- if (you.duration[DUR_REPEL_UNDEAD])
- mpr( "You have a holy aura protecting you from undead." );
-
- if (you.duration[DUR_LIQUID_FLAMES])
- mpr( "You are covered in liquid flames." );
-
- if (you.duration[DUR_ICY_ARMOUR])
- mpr( "You are protected by an icy shield." );
-
- if (you.duration[DUR_REPEL_MISSILES])
- mpr( "You are protected from missiles." );
-
- if (you.duration[DUR_DEFLECT_MISSILES])
- mpr( "You deflect missiles." );
-
- if (you.duration[DUR_PRAYER])
- mpr( "You are praying." );
-
- if (you.duration[DUR_REGENERATION])
- mpr( "You are regenerating." );
-
- if (you.duration[DUR_SWIFTNESS])
- mpr( "You can move swiftly." );
-
- if (you.duration[DUR_INSULATION])
- mpr( "You are insulated." );
-
- if (you.duration[DUR_STONEMAIL])
- mpr( "You are covered in scales of stone." );
-
- if (you.duration[DUR_CONTROLLED_FLIGHT])
- mpr( "You can control your flight." );
-
- if (you.duration[DUR_TELEPORT])
- mpr( "You are about to teleport." );
-
- if (you.duration[DUR_CONTROL_TELEPORT])
- mpr( "You can control teleportation." );
-
- if (you.duration[DUR_DEATH_CHANNEL])
- mpr( "You are channeling the dead." );
-
- if (you.duration[DUR_FORESCRY]) //jmf: added 19mar2000
- mpr( "You are forewarned." );
-
- if (you.duration[DUR_SILENCE]) //jmf: added 27mar2000
- mpr( "You radiate silence." );
-
- if (you.duration[DUR_STONESKIN])
- mpr( "Your skin is tough as stone." );
-
- if (you.duration[DUR_SEE_INVISIBLE])
- mpr( "You can see invisible." );
-
- if (you.invis)
- mpr( "You are invisible." );
-
- if (you.conf)
- mpr( "You are confused." );
-
- if (you.paralysis)
- mpr( "You are paralysed." );
-
- if (you.exhausted)
- mpr( "You are exhausted." );
-
- if (you.slow && you.haste)
- mpr( "You are under both slowing and hasting effects." );
- else if (you.slow)
- mpr( "You are moving very slowly." );
- else if (you.haste)
- mpr( "You are moving very quickly." );
-
- if (you.might)
- mpr( "You are mighty." );
-
- if (you.berserker)
- mpr( "You are possessed by a berserker rage." );
-
- if (player_is_levitating())
- mpr( "You are hovering above the floor." );
-
- if (you.poison)
- {
- snprintf( info, INFO_SIZE, "You are %s poisoned.",
- (you.poison > 10) ? "extremely" :
- (you.poison > 5) ? "very" :
- (you.poison > 3) ? "quite"
- : "mildly" );
- mpr(info);
- }
-
- if (you.disease)
- {
- snprintf( info, INFO_SIZE, "You are %sdiseased.",
- (you.disease > 120) ? "badly " :
- (you.disease > 40) ? ""
- : "mildly " );
- mpr(info);
- }
-
- if (you.rotting || you.species == SP_GHOUL)
- {
- // I apologize in advance for the horrendous ugliness about to
- // transpire. Avert your eyes!
- snprintf( info, INFO_SIZE, "Your flesh is rotting%s",
- (you.rotting > 15) ? " before your eyes!":
- (you.rotting > 8) ? " away quickly.":
- (you.rotting > 4) ? " badly."
- : ((you.species == SP_GHOUL && you.rotting > 0)
- ? " faster than usual." : ".") );
- mpr(info);
- }
-
- contaminate_player( 0, true );
-
- if (you.confusing_touch)
- {
- snprintf( info, INFO_SIZE, "Your hands are glowing %s red.",
- (you.confusing_touch > 40) ? "an extremely bright" :
- (you.confusing_touch > 20) ? "bright"
- : "a soft" );
- mpr(info);
- }
-
- if (you.sure_blade)
- {
- snprintf( info, INFO_SIZE, "You have a %sbond with your blade.",
- (you.sure_blade > 15) ? "strong " :
- (you.sure_blade > 5) ? ""
- : "weak " );
- mpr(info);
- }
-} // end display_char_status()
-
-void redraw_skill(const char your_name[kNameLen], const char class_name[80])
-{
- char print_it[80];
-
- memset( print_it, ' ', sizeof(print_it) );
- snprintf( print_it, sizeof(print_it), "%s the %s", your_name, class_name );
-
- int in_len = strlen( print_it );
- if (in_len > 40)
- {
- in_len -= 3; // what we're getting back from removing "the"
-
- const int name_len = strlen(your_name);
- char name_buff[kNameLen];
- strncpy( name_buff, your_name, kNameLen );
-
- // squeeze name if required, the "- 8" is too not squueze too much
- if (in_len > 40 && (name_len - 8) > (in_len - 40))
- name_buff[ name_len - (in_len - 40) - 1 ] = '\0';
- else
- name_buff[ kNameLen - 1 ] = '\0';
-
- snprintf( print_it, sizeof(print_it), "%s, %s", name_buff, class_name );
- }
-
- for (int i = strlen(print_it); i < 41; i++)
- print_it[i] = ' ';
-
- print_it[40] = '\0';
-
-#ifdef DOS_TERM
- window(1, 1, 80, 25);
-#endif
- gotoxy(40, 1);
-
- textcolor( LIGHTGREY );
- cprintf( print_it );
-} // end redraw_skill()
-
-// Note that this function only has the one static buffer, so if you
-// want to use the results, you'll want to make a copy.
-char *species_name( int speci, int level, bool genus, bool adj, bool cap )
-// defaults: false false true
-{
- static char species_buff[80];
-
- if (player_genus( GENPC_DRACONIAN, speci ))
- {
- if (adj || genus) // adj doesn't care about exact species
- strcpy( species_buff, "Draconian" );
- else
- {
- // No longer have problems with ghosts here -- Sharp Aug2002
- if (level < 7)
- strcpy( species_buff, "Draconian" );
- else
- {
- switch (speci)
- {
- case SP_RED_DRACONIAN:
- strcpy( species_buff, "Red Draconian" );
- break;
- case SP_WHITE_DRACONIAN:
- strcpy( species_buff, "White Draconian" );
- break;
- case SP_GREEN_DRACONIAN:
- strcpy( species_buff, "Green Draconian" );
- break;
- case SP_GOLDEN_DRACONIAN:
- strcpy( species_buff, "Yellow Draconian" );
- break;
- case SP_GREY_DRACONIAN:
- strcpy( species_buff, "Grey Draconian" );
- break;
- case SP_BLACK_DRACONIAN:
- strcpy( species_buff, "Black Draconian" );
- break;
- case SP_PURPLE_DRACONIAN:
- strcpy( species_buff, "Purple Draconian" );
- break;
- case SP_MOTTLED_DRACONIAN:
- strcpy( species_buff, "Mottled Draconian" );
- break;
- case SP_PALE_DRACONIAN:
- strcpy( species_buff, "Pale Draconian" );
- break;
- case SP_UNK0_DRACONIAN:
- case SP_UNK1_DRACONIAN:
- case SP_BASE_DRACONIAN:
- default:
- strcpy( species_buff, "Draconian" );
- break;
- }
- }
- }
- }
- else if (player_genus( GENPC_ELVEN, speci ))
- {
- if (adj) // doesn't care about species/genus
- strcpy( species_buff, "Elven" );
- else if (genus)
- strcpy( species_buff, "Elf" );
- else
- {
- switch (speci)
- {
- case SP_ELF:
- default:
- strcpy( species_buff, "Elf" );
- break;
- case SP_HIGH_ELF:
- strcpy( species_buff, "High Elf" );
- break;
- case SP_GREY_ELF:
- strcpy( species_buff, "Grey Elf" );
- break;
- case SP_DEEP_ELF:
- strcpy( species_buff, "Deep Elf" );
- break;
- case SP_SLUDGE_ELF:
- strcpy( species_buff, "Sludge Elf" );
- break;
- }
- }
- }
- else if (player_genus( GENPC_DWARVEN, speci ))
- {
- if (adj) // doesn't care about species/genus
- strcpy( species_buff, "Dwarven" );
- else if (genus)
- strcpy( species_buff, "Dwarf" );
- else
- {
- switch (speci)
- {
- case SP_HILL_DWARF:
- strcpy( species_buff, "Hill Dwarf" );
- break;
- case SP_MOUNTAIN_DWARF:
- strcpy( species_buff, "Mountain Dwarf" );
- break;
- default:
- strcpy( species_buff, "Dwarf" );
- break;
- }
- }
- }
- else
- {
- switch (speci)
- {
- case SP_HUMAN:
- strcpy( species_buff, "Human" );
- break;
- case SP_HALFLING:
- strcpy( species_buff, "Halfling" );
- break;
- case SP_HILL_ORC:
- strcpy( species_buff, (adj) ? "Orcish" : (genus) ? "Orc"
- : "Hill Orc" );
- break;
- case SP_KOBOLD:
- strcpy( species_buff, "Kobold" );
- break;
- case SP_MUMMY:
- strcpy( species_buff, "Mummy" );
- break;
- case SP_NAGA:
- strcpy( species_buff, "Naga" );
- break;
- case SP_GNOME:
- strcpy( species_buff, (adj) ? "Gnomish" : "Gnome" );
- break;
- case SP_OGRE:
- strcpy( species_buff, (adj) ? "Ogreish" : "Ogre" );
- break;
- case SP_TROLL:
- strcpy( species_buff, (adj) ? "Trollish" : "Troll" );
- break;
- case SP_OGRE_MAGE:
- // We've previously declared that these are radically
- // different from Ogres... so we're not going to
- // refer to them as Ogres. -- bwr
- strcpy( species_buff, "Ogre-Mage" );
- break;
- case SP_CENTAUR:
- strcpy( species_buff, "Centaur" );
- break;
- case SP_DEMIGOD:
- strcpy( species_buff, (adj) ? "Divine" : "Demigod" );
- break;
- case SP_SPRIGGAN:
- strcpy( species_buff, "Spriggan" );
- break;
- case SP_MINOTAUR:
- strcpy( species_buff, "Minotaur" );
- break;
- case SP_DEMONSPAWN:
- strcpy( species_buff, (adj) ? "Demonic" : "Demonspawn" );
- break;
- case SP_GHOUL:
- strcpy( species_buff, (adj) ? "Ghoulish" : "Ghoul" );
- break;
- case SP_KENKU:
- strcpy( species_buff, "Kenku" );
- break;
- case SP_MERFOLK:
- strcpy( species_buff, (adj) ? "Merfolkian" : "Merfolk" );
- break;
- default:
- strcpy( species_buff, (adj) ? "Yakish" : "Yak" );
- break;
- }
- }
-
- if (!cap)
- strlwr( species_buff );
-
- return (species_buff);
-} // end species_name()
-
-bool wearing_amulet(char amulet, bool calc_unid)
-{
- if (amulet == AMU_CONTROLLED_FLIGHT
- && (you.duration[DUR_CONTROLLED_FLIGHT]
- || player_genus(GENPC_DRACONIAN)
- || you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON))
- {
- return true;
- }
-
- if (amulet == AMU_CLARITY && you.mutation[MUT_CLARITY])
- return true;
-
- if (amulet == AMU_RESIST_CORROSION || amulet == AMU_CONSERVATION)
- {
- // this is hackish {dlb}
- if (player_equip_ego_type( EQ_CLOAK, SPARM_PRESERVATION ))
- return true;
- }
-
- if (you.equip[EQ_AMULET] == -1)
- return false;
-
- if (you.inv[you.equip[EQ_AMULET]].sub_type == amulet
- && (calc_unid ||
- item_type_known(you.inv[you.equip[EQ_AMULET]])))
- return true;
-
- return false;
-} // end wearing_amulet()
-
-bool player_is_levitating(void)
-{
- return (you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON || you.levitation);
-}
-
-bool player_has_spell( int spell )
-{
- for (int i = 0; i < 25; i++)
- {
- if (you.spells[i] == spell)
- return (true);
- }
-
- return (false);
-}
-
-int species_exp_mod(char species)
-{
-
- if (player_genus(GENPC_DRACONIAN))
- return 14;
- else if (player_genus(GENPC_DWARVEN))
- return 13;
- {
- switch (species)
- {
- case SP_HUMAN:
- case SP_HALFLING:
- case SP_HILL_ORC:
- case SP_KOBOLD:
- return 10;
- case SP_GNOME:
- return 11;
- case SP_ELF:
- case SP_SLUDGE_ELF:
- case SP_NAGA:
- case SP_GHOUL:
- case SP_MERFOLK:
- return 12;
- case SP_SPRIGGAN:
- case SP_KENKU:
- return 13;
- case SP_GREY_ELF:
- case SP_DEEP_ELF:
- case SP_OGRE:
- case SP_CENTAUR:
- case SP_MINOTAUR:
- case SP_DEMONSPAWN:
- return 14;
- case SP_HIGH_ELF:
- case SP_MUMMY:
- case SP_TROLL:
- case SP_OGRE_MAGE:
- return 15;
- case SP_DEMIGOD:
- return 16;
- default:
- return 0;
- }
- }
-} // end species_exp_mod()
-
-unsigned long exp_needed(int lev)
-{
- lev--;
-
- unsigned long level = 0;
-
-#if 0
- case 1: level = 1;
- case 2: level = 10;
- case 3: level = 35;
- case 4: level = 70;
- case 5: level = 120;
- case 6: level = 250;
- case 7: level = 510;
- case 8: level = 900;
- case 9: level = 1700;
- case 10: level = 3500;
- case 11: level = 8000;
- case 12: level = 20000;
-
- default: //return 14000 * (lev - 11);
- level = 20000 * (lev - 11) + ((lev - 11) * (lev - 11) * (lev - 11)) * 130;
- break;
-#endif
-
- // This is a better behaved function than the above. The above looks
- // really ugly when you consider the second derivative, its not smooth
- // and has a horrible bump at level 12 followed by comparitively easy
- // teen levels. This tries to sort out those issues.
- //
- // Basic plan:
- // Section 1: levels 1- 5, second derivative goes 10-10-20-30.
- // Section 2: levels 6-13, second derivative is exponential/doubling.
- // Section 3: levels 14-27, second derivative is constant at 6000.
- //
- // Section three is constant so we end up with high levels at about
- // their old values (level 27 at 850k), without delta2 ever decreasing.
- // The values that are considerably different (ie level 13 is now 29000,
- // down from 41040 are because the second derivative goes from 9040 to
- // 1430 at that point in the original, and then slowly builds back
- // up again). This function smoothes out the old level 10-15 area
- // considerably.
-
- // Here's a table:
- //
- // level xp delta delta2
- // ===== ======= ===== ======
- // 1 0 0 0
- // 2 10 10 10
- // 3 30 20 10
- // 4 70 40 20
- // 5 140 70 30
- // 6 270 130 60
- // 7 520 250 120
- // 8 1010 490 240
- // 9 1980 970 480
- // 10 3910 1930 960
- // 11 7760 3850 1920
- // 12 15450 7690 3840
- // 13 29000 13550 5860
- // 14 48500 19500 5950
- // 15 74000 25500 6000
- // 16 105500 31500 6000
- // 17 143000 37500 6000
- // 18 186500 43500 6000
- // 19 236000 49500 6000
- // 20 291500 55500 6000
- // 21 353000 61500 6000
- // 22 420500 67500 6000
- // 23 494000 73500 6000
- // 24 573500 79500 6000
- // 25 659000 85500 6000
- // 26 750500 91500 6000
- // 27 848000 97500 6000
-
-
- switch (lev)
- {
- case 1:
- level = 1;
- break;
- case 2:
- level = 10;
- break;
- case 3:
- level = 30;
- break;
- case 4:
- level = 70;
- break;
-
- default:
- if (lev < 13)
- {
- lev -= 4;
- level = 10 + 10 * lev
- + 30 * (static_cast<int>(pow( 2.0, lev + 1 )));
- }
- else
- {
- lev -= 12;
- level = 15500 + 10500 * lev + 3000 * lev * lev;
- }
- break;
- }
-
- return ((level - 1) * species_exp_mod(you.species) / 10);
-} // end exp_needed()
-
-// returns bonuses from rings of slaying, etc.
-int slaying_bonus(char which_affected)
-{
- int ret = 0;
-
- if (which_affected == PWPN_HIT)
- {
- ret += player_equip( EQ_RINGS_PLUS, RING_SLAYING );
- ret += scan_randarts(RAP_ACCURACY);
- }
- else if (which_affected == PWPN_DAMAGE)
- {
- ret += player_equip( EQ_RINGS_PLUS2, RING_SLAYING );
- ret += scan_randarts(RAP_DAMAGE);
- }
-
- return (ret);
-} // end slaying_bonus()
-
-/* Checks each equip slot for a randart, and adds up all of those with
- a given property. Slow if any randarts are worn, so avoid where possible. */
-int scan_randarts(char which_property, bool calc_unid)
-{
- int i = 0;
- int retval = 0;
-
- for (i = EQ_WEAPON; i < NUM_EQUIP; i++)
- {
- const int eq = you.equip[i];
-
- if (eq == -1)
- continue;
-
- // only weapons give their effects when in our hands
- if (i == EQ_WEAPON && you.inv[ eq ].base_type != OBJ_WEAPONS)
- continue;
-
- if (!is_random_artefact( you.inv[ eq ] ))
- continue;
-
- // Ignore unidentified items [TileCrawl dump enhancements].
- if (!item_ident(you.inv[ eq ], ISFLAG_KNOW_PROPERTIES) &&
- !calc_unid)
- continue;
-
- retval += randart_wpn_property( you.inv[ eq ], which_property );
- }
-
- return (retval);
-} // end scan_randarts()
-
-void modify_stat(unsigned char which_stat, char amount, bool suppress_msg)
-{
- char *ptr_stat = NULL;
- char *ptr_stat_max = NULL;
- char *ptr_redraw = NULL;
-
- // sanity - is non-zero amount?
- if (amount == 0)
- return;
-
- // Stop running/travel if a stat drops.
- if (amount < 0)
- interrupt_activity( AI_STAT_CHANGE );
-
- if (!suppress_msg)
- strcpy(info, "You feel ");
-
- if (which_stat == STAT_RANDOM)
- which_stat = random2(NUM_STATS);
-
- switch (which_stat)
- {
- case STAT_STRENGTH:
- ptr_stat = &you.strength;
- ptr_stat_max = &you.max_strength;
- ptr_redraw = &you.redraw_strength;
- if (!suppress_msg)
- strcat(info, (amount > 0) ? "stronger." : "weaker.");
- break;
-
- case STAT_DEXTERITY:
- ptr_stat = &you.dex;
- ptr_stat_max = &you.max_dex;
- ptr_redraw = &you.redraw_dexterity;
- if (!suppress_msg)
- strcat(info, (amount > 0) ? "agile." : "clumsy.");
- break;
-
- case STAT_INTELLIGENCE:
- ptr_stat = &you.intel;
- ptr_stat_max = &you.max_intel;
- ptr_redraw = &you.redraw_intelligence;
- if (!suppress_msg)
- strcat(info, (amount > 0) ? "clever." : "stupid.");
- break;
- }
-
- if (!suppress_msg)
- mpr( info, (amount > 0) ? MSGCH_INTRINSIC_GAIN : MSGCH_WARN );
-
- *ptr_stat += amount;
- *ptr_stat_max += amount;
- *ptr_redraw = 1;
-
- if (ptr_stat == &you.strength)
- burden_change();
-
- return;
-} // end modify_stat()
-
-void dec_hp(int hp_loss, bool fatal)
-{
- if (hp_loss < 1)
- return;
-
- you.hp -= hp_loss;
-
- if (!fatal && you.hp < 1)
- you.hp = 1;
-
- you.redraw_hit_points = 1;
-
- return;
-} // end dec_hp()
-
-void dec_mp(int mp_loss)
-{
- if (mp_loss < 1)
- return;
-
- you.magic_points -= mp_loss;
-
- if (you.magic_points < 0)
- you.magic_points = 0;
-
- you.redraw_magic_points = 1;
-
- return;
-} // end dec_mp()
-
-bool enough_hp(int minimum, bool suppress_msg)
-{
- // We want to at least keep 1 HP -- bwr
- if (you.hp < minimum + 1)
- {
- if (!suppress_msg)
- mpr("You haven't enough vitality at the moment.");
-
- return false;
- }
-
- return true;
-} // end enough_hp()
-
-bool enough_mp(int minimum, bool suppress_msg)
-{
- if (you.magic_points < minimum)
- {
- if (!suppress_msg)
- mpr("You haven't enough magic at the moment.");
-
- return false;
- }
-
- return true;
-} // end enough_mp()
-
-// Note that "max_too" refers to the base potential, the actual
-// resulting max value is subject to penalties, bonuses, and scalings.
-void inc_mp(int mp_gain, bool max_too)
-{
- if (mp_gain < 1)
- return;
-
- you.magic_points += mp_gain;
-
- if (max_too)
- inc_max_mp( mp_gain );
-
- if (you.magic_points > you.max_magic_points)
- you.magic_points = you.max_magic_points;
-
- you.redraw_magic_points = 1;
-
- return;
-} // end inc_mp()
-
-// Note that "max_too" refers to the base potential, the actual
-// resulting max value is subject to penalties, bonuses, and scalings.
-void inc_hp(int hp_gain, bool max_too)
-{
- if (hp_gain < 1)
- return;
-
- you.hp += hp_gain;
-
- if (max_too)
- inc_max_hp( hp_gain );
-
- if (you.hp > you.hp_max)
- you.hp = you.hp_max;
-
- you.redraw_hit_points = 1;
-} // end inc_hp()
-
-void rot_hp( int hp_loss )
-{
- you.base_hp -= hp_loss;
- calc_hp();
-
- you.redraw_hit_points = 1;
-}
-
-void unrot_hp( int hp_recovered )
-{
- if (hp_recovered >= 5000 - you.base_hp)
- you.base_hp = 5000;
- else
- you.base_hp += hp_recovered;
-
- calc_hp();
-
- you.redraw_hit_points = 1;
-}
-
-int player_rotted( void )
-{
- return (5000 - you.base_hp);
-}
-
-void rot_mp( int mp_loss )
-{
- you.base_magic_points -= mp_loss;
- calc_mp();
-
- you.redraw_magic_points = 1;
-}
-
-void inc_max_hp( int hp_gain )
-{
- you.base_hp2 += hp_gain;
- calc_hp();
-
- you.redraw_hit_points = 1;
-}
-
-void dec_max_hp( int hp_loss )
-{
- you.base_hp2 -= hp_loss;
- calc_hp();
-
- you.redraw_hit_points = 1;
-}
-
-void inc_max_mp( int mp_gain )
-{
- you.base_magic_points2 += mp_gain;
- calc_mp();
-
- you.redraw_magic_points = 1;
-}
-
-void dec_max_mp( int mp_loss )
-{
- you.base_magic_points2 -= mp_loss;
- calc_mp();
-
- you.redraw_magic_points = 1;
-}
-
-// use of floor: false = hp max, true = hp min {dlb}
-void deflate_hp(int new_level, bool floor)
-{
- if (floor && you.hp < new_level)
- you.hp = new_level;
- else if (!floor && you.hp > new_level)
- you.hp = new_level;
-
- // must remain outside conditional, given code usage {dlb}
- you.redraw_hit_points = 1;
-
- return;
-} // end deflate_hp()
-
-// Note that "max_too" refers to the base potential, the actual
-// resulting max value is subject to penalties, bonuses, and scalings.
-void set_hp(int new_amount, bool max_too)
-{
- if (you.hp != new_amount)
- you.hp = new_amount;
-
- if (max_too && you.hp_max != new_amount)
- {
- you.base_hp2 = 5000 + new_amount;
- calc_hp();
- }
-
- if (you.hp > you.hp_max)
- you.hp = you.hp_max;
-
- // must remain outside conditional, given code usage {dlb}
- you.redraw_hit_points = 1;
-
- return;
-} // end set_hp()
-
-// Note that "max_too" refers to the base potential, the actual
-// resulting max value is subject to penalties, bonuses, and scalings.
-void set_mp(int new_amount, bool max_too)
-{
- if (you.magic_points != new_amount)
- you.magic_points = new_amount;
-
- if (max_too && you.max_magic_points != new_amount)
- {
- // note that this gets scaled down for values > 18
- you.base_magic_points2 = 5000 + new_amount;
- calc_mp();
- }
-
- if (you.magic_points > you.max_magic_points)
- you.magic_points = you.max_magic_points;
-
- // must remain outside conditional, given code usage {dlb}
- you.redraw_magic_points = 1;
-
- return;
-} // end set_mp()
-
-
-static const char * Species_Abbrev_List[ NUM_SPECIES ] =
- { "XX", "Hu", "El", "HE", "GE", "DE", "SE", "HD", "MD", "Ha",
- "HO", "Ko", "Mu", "Na", "Gn", "Og", "Tr", "OM", "Dr", "Dr",
- "Dr", "Dr", "Dr", "Dr", "Dr", "Dr", "Dr", "Dr", "Dr", "Dr",
- "Ce", "DG", "Sp", "Mi", "DS", "Gh", "Ke", "Mf" };
-
-int get_species_index_by_abbrev( const char *abbrev )
-{
- int i;
- 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 get_species_index_by_name( const char *name )
-{
- int i;
- int sp = -1;
-
- char *ptr;
- char lowered_buff[80];
-
- strncpy( lowered_buff, name, sizeof( lowered_buff ) );
- strlwr( lowered_buff );
-
- for (i = SP_HUMAN; i < NUM_SPECIES; i++)
- {
- char *lowered_species = species_name( i, 0, false, false, false );
- ptr = strstr( lowered_species, lowered_buff );
- if (ptr != NULL)
- {
- sp = i;
- if (ptr == lowered_species) // 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 ]);
-}
-
-
-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", "XX", "Re", "St", "Mo", "Wr", "Wn" };
-
-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", "Quitter", "Reaver", "Stalker",
- "Monk", "Warper", "Wanderer" };
-
-int get_class_index_by_abbrev( const char *abbrev )
-{
- int i;
-
- for (i = 0; i < NUM_JOBS; i++)
- {
- if (i == JOB_QUITTER)
- continue;
-
- 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);
-}
-
-const char *get_class_abbrev( int which_job )
-{
- ASSERT( which_job < NUM_JOBS && which_job != JOB_QUITTER );
-
- return (Class_Abbrev_List[ which_job ]);
-}
-
-int get_class_index_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++)
- {
- if (i == JOB_QUITTER)
- continue;
-
- 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);
-}
-
-const char *get_class_name( int which_job )
-{
- ASSERT( which_job < NUM_JOBS && which_job != JOB_QUITTER );
-
- return (Class_Name_List[ which_job ]);
-}
-
-/* ******************************************************************
-
-// this function is solely called by a commented out portion of
-// player::level_change() and is a bit outta whack with the
-// current codebase - probably should be struck as well 19may2000 {dlb}
-
-void priest_spells( int priest_pass[10], char religious )
-{
-
- switch ( religious )
- {
- case GOD_ZIN:
- priest_pass[1] = SPELL_LESSER_HEALING;
- priest_pass[2] = SPELL_REPEL_UNDEAD;
- priest_pass[3] = SPELL_HEAL_OTHER;
- priest_pass[4] = SPELL_PURIFICATION;
- priest_pass[5] = SPELL_GREATER_HEALING;
- priest_pass[6] = SPELL_SMITING;
- priest_pass[7] = SPELL_HOLY_WORD;
- priest_pass[8] = SPELL_REMOVE_CURSE;
- priest_pass[9] = SPELL_GUARDIAN;
- break;
-
- case GOD_SHINING_ONE:
- priest_pass[1] = SPELL_REPEL_UNDEAD;
- priest_pass[2] = SPELL_LESSER_HEALING;
- priest_pass[3] = SPELL_HEAL_OTHER;
- priest_pass[4] = SPELL_PURIFICATION;
- priest_pass[5] = SPELL_ABJURATION_II;
- priest_pass[6] = SPELL_THUNDERBOLT;
- priest_pass[7] = SPELL_SHINING_LIGHT;
- priest_pass[8] = SPELL_SUMMON_DAEVA;
- priest_pass[9] = SPELL_FLAME_OF_CLEANSING;
- break;
-
- case GOD_ELYVILON:
- priest_pass[1] = SPELL_LESSER_HEALING;
- priest_pass[2] = SPELL_HEAL_OTHER;
- priest_pass[3] = SPELL_PURIFICATION;
- priest_pass[4] = 93; // restore abilities
- priest_pass[5] = SPELL_GREATER_HEALING;
- priest_pass[6] = 94; // another healing spell
- priest_pass[7] = 95; // something else
- priest_pass[8] = -1; //
- priest_pass[9] = -1; //
- break;
- }
-
-}
-
-// Spells to be added: (+ renamed!)
-// holy berserker
-// 87 Pestilence
-// 93 Restore Abilities
-// 94 something else healing
-// 95 something else
-
-****************************************************************** */
-
-void contaminate_player(int change, bool statusOnly)
-{
- // get current contamination level
- int old_level;
- int new_level;
-
-
-#if DEBUG_DIAGNOSTICS
- if (change > 0 || (change < 0 && you.magic_contamination))
- {
- snprintf( info, INFO_SIZE, "change: %d radiation: %d",
- change, change + you.magic_contamination );
-
- mpr( info, MSGCH_DIAGNOSTICS );
- }
-#endif
-
- old_level = (you.magic_contamination > 60)?(you.magic_contamination / 20 + 2) :
- (you.magic_contamination > 40)?4 :
- (you.magic_contamination > 25)?3 :
- (you.magic_contamination > 15)?2 :
- (you.magic_contamination > 5)?1 : 0;
-
- // make the change
- if (change + you.magic_contamination < 0)
- you.magic_contamination = 0;
- else
- {
- if (change + you.magic_contamination > 250)
- you.magic_contamination = 250;
- else
- you.magic_contamination += change;
- }
-
- // figure out new level
- new_level = (you.magic_contamination > 60)?(you.magic_contamination / 20 + 2) :
- (you.magic_contamination > 40)?4 :
- (you.magic_contamination > 25)?3 :
- (you.magic_contamination > 15)?2 :
- (you.magic_contamination > 5)?1 : 0;
-
- if (statusOnly)
- {
- if (new_level > 0)
- {
- if (new_level > 3)
- {
- strcpy(info, (new_level == 4) ?
- "Your entire body has taken on an eerie glow!" :
- "You are engulfed in a nimbus of crackling magics!");
- }
- else
- {
- snprintf( info, INFO_SIZE, "You are %s with residual magics%c",
- (new_level == 3) ? "practically glowing" :
- (new_level == 2) ? "heavily infused"
- : "contaminated",
- (new_level == 3) ? '!' : '.');
- }
-
- mpr(info);
- }
- return;
- }
-
- if (new_level == old_level)
- return;
-
- snprintf( info, INFO_SIZE, "You feel %s contaminated with magical energies.",
- (change < 0) ? "less" : "more" );
-
- mpr( info, (change > 0) ? MSGCH_WARN : MSGCH_RECOVERY );
-}
-
-void poison_player( int amount, bool force )
-{
- if ((!force && player_res_poison()) || amount <= 0)
- return;
-
- const int old_value = you.poison;
- you.poison += amount;
-
- if (you.poison > 40)
- you.poison = 40;
-
- if (you.poison > old_value)
- {
- snprintf( info, INFO_SIZE, "You are %spoisoned.",
- (old_value > 0) ? "more " : "" );
-
- // XXX: which message channel for this message?
- mpr( info );
- }
-}
-
-void reduce_poison_player( int amount )
-{
- if (you.poison == 0 || amount <= 0)
- return;
-
- you.poison -= amount;
-
- if (you.poison <= 0)
- {
- you.poison = 0;
- mpr( "You feel better.", MSGCH_RECOVERY );
- }
- else
- {
- mpr( "You feel a little better.", MSGCH_RECOVERY );
- }
-}
-
-void confuse_player( int amount, bool resistable )
-{
- if (amount <= 0)
- return;
-
- if (resistable && wearing_amulet(AMU_CLARITY))
- {
- mpr( "You feel momentarily confused." );
- return;
- }
-
- const int old_value = you.conf;
- you.conf += amount;
-
- if (you.conf > 40)
- you.conf = 40;
-
- if (you.conf > old_value)
- {
- snprintf( info, INFO_SIZE, "You are %sconfused.",
- (old_value > 0) ? "more " : "" );
-
- // XXX: which message channel for this message?
- mpr( info );
- }
-}
-
-void reduce_confuse_player( int amount )
-{
- if (you.conf == 0 || amount <= 0)
- return;
-
- you.conf -= amount;
-
- if (you.conf <= 0)
- {
- you.conf = 0;
- mpr( "You feel less confused." );
- }
-}
-
-void slow_player( int amount )
-{
- if (amount <= 0)
- return;
-
- if (wearing_amulet( AMU_RESIST_SLOW ))
- mpr("You feel momentarily lethargic.");
- else if (you.slow >= 100)
- mpr( "You already are as slow as you could be." );
- else
- {
- if (you.slow == 0)
- mpr( "You feel yourself slow down." );
- else
- mpr( "You feel as though you will be slow longer." );
-
- you.slow += amount;
-
- if (you.slow > 100)
- you.slow = 100;
- }
-}
-
-void dec_slow_player( void )
-{
- if (you.slow > 1)
- {
- // BCR - Amulet of resist slow affects slow counter
- if (wearing_amulet(AMU_RESIST_SLOW))
- {
- you.slow -= 5;
- if (you.slow < 1)
- you.slow = 1;
- }
- else
- you.slow--;
- }
- else if (you.slow == 1)
- {
- mpr("You feel yourself speed up.", MSGCH_DURATION);
- you.slow = 0;
- }
-}
-
-void haste_player( int amount )
-{
- bool amu_eff = wearing_amulet( AMU_RESIST_SLOW );
-
- if (amount <= 0)
- return;
-
- if (amu_eff)
- mpr( "Your amulet glows brightly." );
-
- if (you.haste == 0)
- mpr( "You feel yourself speed up." );
- else if (you.haste > 80 + 20 * amu_eff)
- mpr( "You already have as much speed as you can handle." );
- else
- {
- mpr( "You feel as though your hastened speed will last longer." );
- contaminate_player(1);
- }
-
- you.haste += amount;
-
- if (you.haste > 80 + 20 * amu_eff)
- you.haste = 80 + 20 * amu_eff;
-
- did_god_conduct( DID_STIMULANTS, 4 + random2(4) );
-}
-
-void dec_haste_player( void )
-{
- if (you.haste > 1)
- {
- // BCR - Amulet of resist slow affects haste counter
- if (!wearing_amulet(AMU_RESIST_SLOW) || coinflip())
- you.haste--;
-
- if (you.haste == 6)
- {
- mpr( "Your extra speed is starting to run out.", MSGCH_DURATION );
- if (coinflip())
- you.haste--;
- }
- }
- else if (you.haste == 1)
- {
- mpr( "You feel yourself slow down.", MSGCH_DURATION );
- you.haste = 0;
- }
-}
-
-void disease_player( int amount )
-{
- if (you.is_undead || amount <= 0)
- return;
-
- mpr( "You feel ill." );
-
- const int tmp = you.disease + amount;
- you.disease = (tmp > 210) ? 210 : tmp;
-}
-
-void dec_disease_player( void )
-{
- if (you.disease > 0)
- {
- you.disease--;
-
- if (you.disease > 5
- && (you.species == SP_KOBOLD
- || you.duration[ DUR_REGENERATION ]
- || you.mutation[ MUT_REGENERATION ] == 3))
- {
- you.disease -= 2;
- }
-
- if (!you.disease)
- mpr("You feel your health improve.", MSGCH_RECOVERY);
- }
-}
-
-void rot_player( int amount )
-{
- if (amount <= 0)
- return;
-
- if (you.rotting < 40)
- {
- // Either this, or the actual rotting message should probably
- // be changed so that they're easier to tell apart. -- bwr
- snprintf( info, INFO_SIZE, "You feel your flesh %s away!",
- (you.rotting) ? "rotting" : "start to rot" );
- mpr( info, MSGCH_WARN );
-
- you.rotting += amount;
- }
-}
-
-void run_macro(const char *macroname)
-{
- if (you.activity != ACT_NONE && you.activity != ACT_MACRO)
- return;
-
-#ifdef CLUA_BINDINGS
- if (!clua)
- {
- mpr("Lua not initialized", MSGCH_DIAGNOSTICS);
- you.activity = ACT_NONE;
- return;
- }
-
- if (!clua.callbooleanfn(false, "c_macro", "s", macroname))
- {
- if (clua.error.length())
- mpr(clua.error.c_str());
- you.activity = ACT_NONE;
- }
- else
- {
- you.activity = ACT_MACRO;
- }
-#else
- you.activity = ACT_NONE;
-#endif
-}
-
-void perform_activity()
-{
- switch (you.activity)
- {
- case ACT_MULTIDROP:
- drop();
- break;
- case ACT_MACRO:
- run_macro();
- break;
- default:
- break;
- }
-}
-
-#ifdef CLUA_BINDINGS
-static const char *activity_interrupt_name(activity_interrupt_type ai)
-{
- switch (ai)
- {
- case AI_FORCE_INTERRUPT: return "force";
- case AI_KEYPRESS: return "keypress";
- case AI_FULL_HP: return "full_hp";
- case AI_FULL_MP: return "full_mp";
- case AI_STATUE: return "statue";
- case AI_HUNGRY: return "hungry";
- case AI_MESSAGE: return "message";
- case AI_HP_LOSS: return "hp_loss";
- case AI_BURDEN_CHANGE: return "burden";
- case AI_STAT_CHANGE: return "stat";
- case AI_SEE_MONSTER: return "monster";
- case AI_TELEPORT: return "teleport";
- default: return "unknown";
- }
-}
-
-static const char *activity_names[] = {
- "",
- "multidrop",
- "run",
- "travel",
- "macro"
-};
-
-static const char *activity_name(int act)
-{
- if (act < ACT_NONE || act >= ACT_ACTIVITY_COUNT)
- return NULL;
- return activity_names[act];
-}
-#endif
-
-static void kill_activity()
-{
- if (you.running)
- stop_running();
- you.activity = ACT_NONE;
-}
-
-static bool userdef_interrupt_activity( activity_interrupt_type ai,
- const activity_interrupt_data &at )
-{
-#ifdef CLUA_BINDINGS
- lua_State *ls = clua.state();
- if (!ls || ai == AI_FORCE_INTERRUPT)
- {
- if (ai == AI_FORCE_INTERRUPT || you.activity == ACT_MACRO)
- kill_activity();
- return true;
- }
-
- const char *interrupt_name = activity_interrupt_name(ai);
- const char *act_name = activity_name(you.activity);
-
- bool ran = clua.callfn("c_interrupt_activity", "1:ssA",
- act_name, interrupt_name, &at);
- if (ran)
- {
- // If the function returned nil, we want to cease processing.
- if (lua_isnil(ls, -1))
- {
- lua_pop(ls, 1);
- return false;
- }
-
- bool stopact = lua_toboolean(ls, -1);
- lua_pop(ls, 1);
- if (stopact)
- {
- kill_activity();
- return true;
- }
- }
-
- if (you.activity == ACT_MACRO &&
- clua.callbooleanfn(true, "c_interrupt_macro",
- "sA", interrupt_name, &at))
- {
- kill_activity();
- }
-
-#else
- if (you.activity == ACT_MACRO)
- kill_activity();
-#endif
- return true;
-}
-
-void interrupt_activity( activity_interrupt_type ai,
- const activity_interrupt_data &at )
-{
- if (you.running && !you.activity)
- you.activity = you.running > 0? ACT_RUNNING : ACT_TRAVELING;
-
- if (!you.activity)
- return;
-
- if (!userdef_interrupt_activity(ai, at) || !you.activity)
- {
- if (you.activity == ACT_RUNNING || you.activity == ACT_TRAVELING)
- you.activity = ACT_NONE;
- return;
- }
-
- if (!ai || (Options.activity_interrupts[ you.activity ] & ai)) {
- kill_activity();
- }
-
- if (you.activity == ACT_RUNNING || you.activity == ACT_TRAVELING)
- you.activity = ACT_NONE;
-}
diff --git a/stone_soup/crawl-ref/source/player.h b/stone_soup/crawl-ref/source/player.h
deleted file mode 100644
index 70db5bea41..0000000000
--- a/stone_soup/crawl-ref/source/player.h
+++ /dev/null
@@ -1,459 +0,0 @@
-/*
- * File: player.cc
- * Summary: Player related functions.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef PLAYER_H
-#define PLAYER_H
-
-#include "externs.h"
-
-bool player_in_branch( int branch );
-bool player_in_hell( void );
-
-int get_player_wielded_weapon();
-int player_equip( int slot, int sub_type, bool calc_unid = true );
-int player_equip_ego_type( int slot, int sub_type );
-int player_damage_type( void );
-int player_damage_brand( void );
-
-bool player_is_shapechanged(void);
-
-/* ***********************************************************************
- * called from: player - item_use
- * *********************************************************************** */
-bool is_light_armour( const item_def &item );
-
-/* ***********************************************************************
- * called from: beam - fight - misc - newgame
- * *********************************************************************** */
-bool player_light_armour(void);
-
-
-/* ***********************************************************************
- * called from: acr.cc - fight.cc - misc.cc - player.cc
- * *********************************************************************** */
-bool player_in_water(void);
-bool player_is_swimming(void);
-bool player_is_levitating(void);
-
-/* ***********************************************************************
- * called from: ability - chardump - fight - religion - spell - spells -
- * spells0 - spells2
- * *********************************************************************** */
-bool player_under_penance(void);
-
-int player_wielded_item();
-
-/* ***********************************************************************
- * called from: ability - acr - fight - food - it_use2 - item_use - items -
- * misc - mutation - ouch
- * *********************************************************************** */
-bool wearing_amulet(char which_am, bool calc_unid = true);
-
-
-/* ***********************************************************************
- * called from: acr - chardump - describe - newgame - view
- * *********************************************************************** */
-char *species_name( int speci, int level, bool genus = false, bool adj = false, bool cap = true );
-
-
-/* ***********************************************************************
- * called from: beam
- * *********************************************************************** */
-bool you_resist_magic(int power);
-
-
-/* ***********************************************************************
- * called from: acr - decks - effects - it_use2 - it_use3 - item_use -
- * items - output - shopping - spells1 - spells3
- * *********************************************************************** */
-int burden_change(void);
-
-
-/* ***********************************************************************
- * called from: items - misc
- * *********************************************************************** */
-int carrying_capacity(void);
-
-
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-int check_stealth(void);
-
-
-/* ***********************************************************************
- * called from: bang - beam - chardump - fight - files - it_use2 -
- * item_use - misc - output - spells - spells1
- * *********************************************************************** */
-int player_AC(void);
-
-
-/* ***********************************************************************
- * called from: spell
- * *********************************************************************** */
-unsigned char player_energy(void);
-
-
-/* ***********************************************************************
- * called from: beam - chardump - fight - files - misc - output
- * *********************************************************************** */
-int player_evasion(void);
-
-
-#if 0
-/* ***********************************************************************
- * called from: acr - spells1
- * *********************************************************************** */
-unsigned char player_fast_run(void);
-#endif
-
-/* ***********************************************************************
- * called from: acr - spells1
- * *********************************************************************** */
-int player_movement_speed(void);
-
-
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-int player_hunger_rate(void);
-
-
-/* ***********************************************************************
- * called from: debug - it_use3 - spells0
- * *********************************************************************** */
-int player_mag_abil(bool is_weighted);
-int player_magical_power( void );
-
-/* ***********************************************************************
- * called from: fight - misc - ouch - spells
- * *********************************************************************** */
-int player_prot_life(bool calc_unid = true);
-
-
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-int player_regen(void);
-
-
-/* ***********************************************************************
- * called from: fight - files - it_use2 - misc - ouch - spells - spells2
- * *********************************************************************** */
-int player_res_cold(bool calc_unid = true);
-int player_res_acid(void);
-
-/* ***********************************************************************
- * called from: fight - files - ouch
- * *********************************************************************** */
-int player_res_electricity(bool calc_unid = true);
-
-
-/* ***********************************************************************
- * called from: acr - fight - misc - ouch - spells
- * *********************************************************************** */
-int player_res_fire(bool calc_unid = true);
-
-
-/* ***********************************************************************
- * called from: beam - decks - fight - fod - it_use2 - misc - ouch -
- * spells - spells2
- * *********************************************************************** */
-int player_res_poison(bool calc_unid = true);
-
-int player_res_magic(void);
-
-bool player_res_asphyx();
-
-/* ***********************************************************************
- * called from: beam - chardump - fight - misc - output
- * *********************************************************************** */
-int player_shield_class(void);
-
-
-/* ***********************************************************************
- * called from: spell - spells0
- * *********************************************************************** */
-unsigned char player_spec_air(void);
-
-
-/* ***********************************************************************
- * called from: spell - spells0
- * *********************************************************************** */
-unsigned char player_spec_cold(void);
-
-
-/* ***********************************************************************
- * called from: spell - spells0
- * *********************************************************************** */
-unsigned char player_spec_conj(void);
-
-
-/* ***********************************************************************
- * called from: it_use3 - spell - spells0
- * *********************************************************************** */
-unsigned char player_spec_death(void);
-
-
-/* ***********************************************************************
- * called from: spell - spells0
- * *********************************************************************** */
-unsigned char player_spec_earth(void);
-
-
-/* ***********************************************************************
- * called from: spell - spells0
- * *********************************************************************** */
-unsigned char player_spec_ench(void);
-
-
-/* ***********************************************************************
- * called from: spell - spells0
- * *********************************************************************** */
-unsigned char player_spec_fire(void);
-
-
-/* ***********************************************************************
- * called from: spell - spells0
- * *********************************************************************** */
-unsigned char player_spec_holy(void);
-
-
-/* ***********************************************************************
- * called from: spell - spells0
- * *********************************************************************** */
-unsigned char player_spec_poison(void);
-
-
-/* ***********************************************************************
- * called from: spell - spells0
- * *********************************************************************** */
-unsigned char player_spec_summ(void);
-
-
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-int player_speed(void);
-
-
-/* ***********************************************************************
- * called from: chardump - spells
- * *********************************************************************** */
-int player_spell_levels(void);
-
-
-// last updated 18may2000 {dlb}
-/* ***********************************************************************
- * called from: effects
- * *********************************************************************** */
-unsigned char player_sust_abil(bool calc_unid = true);
-
-
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-int player_teleport(bool calc_unid = true);
-
-
-/* ***********************************************************************
- * called from: ability - acr - items - misc - spells1 - spells3
- * *********************************************************************** */
-int scan_randarts(char which_property, bool calc_unid = true);
-
-
-/* ***********************************************************************
- * called from: fight - item_use
- * *********************************************************************** */
-int slaying_bonus(char which_affected);
-
-
-/* ***********************************************************************
- * called from: beam - decks - direct - effects - fight - files - it_use2 -
- * items - monstuff - mon-util - mstuff2 - spells1 - spells2 -
- * spells3
- * *********************************************************************** */
-unsigned char player_see_invis(bool calc_unid = true);
-bool player_monster_visible( const monsters *mon );
-
-
-/* ***********************************************************************
- * called from: acr - decks - it_use2 - ouch
- * *********************************************************************** */
-unsigned long exp_needed(int lev);
-
-
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void display_char_status(void);
-
-
-/* ***********************************************************************
- * called from: item_use - items - misc - spells - spells3
- * *********************************************************************** */
-void forget_map(unsigned char chance_forgotten);
-
-
-// last updated 19may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - fight
- * *********************************************************************** */
-void gain_exp(unsigned int exp_gained);
-
-
-// last updated 17dec2000 {gdl}
-/* ***********************************************************************
- * called from: acr - it_use2 - item_use - mutation - transfor - player -
- * misc - stuff
- * *********************************************************************** */
-void modify_stat(unsigned char which_stat, char amount, bool suppress_msg);
-
-
-// last updated 19may2000 {dlb}
-/* ***********************************************************************
- * called from: decks - it_use2 - player
- * *********************************************************************** */
-void level_change(void);
-
-
-/* ***********************************************************************
- * called from: skills
- * *********************************************************************** */
-void redraw_skill(const char your_name[kNameLen], const char class_name[80]);
-
-
-/* ***********************************************************************
- * called from: ability - fight - item_use - mutation - newgame - spells0 -
- * transfor
- * *********************************************************************** */
-bool player_genus( unsigned char which_genus,
- unsigned char species = SP_UNKNOWN );
-
-
-/* ***********************************************************************
- * called from: ability - effects - fight - it_use3 - ouch - spell -
- * spells - spells2 - spells3 - spells4
- * *********************************************************************** */
-void dec_hp(int hp_loss, bool fatal);
-
-
-/* ***********************************************************************
- * called from: ability - it_use3 - spell - spells3
- * *********************************************************************** */
-bool enough_hp (int minimum, bool suppress_msg);
-
-
-/* ***********************************************************************
- * called from: ability - it_use3
- * *********************************************************************** */
-bool enough_mp (int minimum, bool suppress_msg);
-
-
-/* ***********************************************************************
- * called from: ability - fight - it_use3 - monstuff - ouch - spell
- * *********************************************************************** */
-void dec_mp(int mp_loss);
-
-
-/* ***********************************************************************
- * called from: ability - acr - fight - it_use2 - it_use3 - spells3
- * *********************************************************************** */
-void inc_mp(int mp_gain, bool max_too);
-
-
-/* ***********************************************************************
- * called from: acr - fight - food - spells1 - spells2
- * *********************************************************************** */
-void inc_hp(int hp_gain, bool max_too);
-
-void rot_hp( int hp_loss );
-void unrot_hp( int hp_recovered );
-int player_rotted( void );
-void rot_mp( int mp_loss );
-
-void inc_max_hp( int hp_gain );
-void dec_max_hp( int hp_loss );
-
-void inc_max_mp( int mp_gain );
-void dec_max_mp( int mp_loss );
-
-/* ***********************************************************************
- * called from: acr - misc - religion - skills2 - spells1 - transfor
- * *********************************************************************** */
-void deflate_hp(int new_level, bool floor);
-
-
-/* ***********************************************************************
- * called from: acr - it_use2 - newgame - ouch - religion - spell - spells1
- * *********************************************************************** */
-void set_hp(int new_amount, bool max_too);
-
-
-/* ***********************************************************************
- * called from: it_use3 - newgame
- * *********************************************************************** */
-void set_mp(int new_amount, bool max_too);
-
-
-/* ***********************************************************************
- * called from: newgame
- * *********************************************************************** */
-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 );
-
-
-// last updated 19apr2001 {gdl}
-/* ***********************************************************************
- * called from:
- * *********************************************************************** */
-void contaminate_player(int change, bool statusOnly = false);
-
-void poison_player( int amount, bool force = false );
-void reduce_poison_player( int amount );
-
-void confuse_player( int amount, bool resistable = true );
-void reduce_confuse_player( int amount );
-
-void slow_player( int amount );
-void dec_slow_player();
-
-void haste_player( int amount );
-void dec_haste_player();
-
-void disease_player( int amount );
-void dec_disease_player();
-
-void rot_player( int amount );
-
-void perform_activity();
-
-void interrupt_activity( activity_interrupt_type ai,
- const activity_interrupt_data &a
- = activity_interrupt_data() );
-
-// last updated 15sep2001 {bwr}
-/* ***********************************************************************
- * called from:
- * *********************************************************************** */
-bool player_has_spell( int spell );
-
-bool player_weapon_wielded();
-
-void run_macro(const char *macroname = NULL);
-
-#endif
diff --git a/stone_soup/crawl-ref/source/randart.cc b/stone_soup/crawl-ref/source/randart.cc
deleted file mode 100644
index 5d2ef93188..0000000000
--- a/stone_soup/crawl-ref/source/randart.cc
+++ /dev/null
@@ -1,1995 +0,0 @@
-/*
- * File: randart.cc
- * Summary: Random and unrandom artifact functions.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <8> 19 Jun 99 GDL added IBMCPP support
- * <7> 14/12/99 LRH random2 -> random5
- * <6> 11/06/99 cdl random4 -> random2
- *
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "randart.h"
-
-#include <string.h>
-#include <stdio.h>
-
-#include "externs.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "stuff.h"
-#include "wpn-misc.h"
-
-/*
- The initial generation of a randart is very simple - it occurs
- in dungeon.cc and consists of giving it a few random things - plus & plus2
- mainly.
-*/
-const char *rand_wpn_names[] = {
- " of Blood",
- " of Death",
- " of Bloody Death",
- " of Pain",
- " of Painful Death",
- " of Pain & Death",
- " of Infinite Pain",
- " of Eternal Torment",
- " of Power",
- " of Wrath",
-/* 10: */
- " of Doom",
- " of Tender Mercy",
- " of the Apocalypse",
- " of the Jester",
- " of the Ring",
- " of the Fool",
- " of the Gods",
- " of the Imperium",
- " of Destruction",
- " of Armageddon",
-/* 20: */
- " of Cruel Justice",
- " of Righteous Anger",
- " of Might",
- " of the Orb",
- " of Makhleb",
- " of Trog",
- " of Xom",
- " of the Ancients",
- " of Mana",
- " of Nemelex Xobeh",
-/* 30: */
- " of the Magi",
- " of the Archmagi",
- " of the King",
- " of the Queen",
- " of the Spheres",
- " of Circularity",
- " of Linearity",
- " of Conflict",
- " of Battle",
- " of Honour",
-/* 40: */
- " of the Butterfly",
- " of the Wasp",
- " of the Frog",
- " of the Weasel",
- " of the Troglodytes",
- " of the Pill-Bug",
- " of Sin",
- " of Vengeance",
- " of Execution",
- " of Arbitration",
-/* 50: */
- " of the Seeker",
- " of Truth",
- " of Lies",
- " of the Eggplant",
- " of the Turnip",
- " of Chance",
- " of Curses",
- " of Hell's Wrath",
- " of the Undead",
- " of Chaos",
-/* 60: */
- " of Law",
- " of Life",
- " of the Old World",
- " of the New World",
- " of the Middle World",
- " of Crawl",
- " of Unpleasantness",
- " of Discomfort",
- " of Brutal Revenge",
- " of Triumph",
-/* 70: */
- " of Evisceration",
- " of Dismemberment",
- " of Terror",
- " of Fear",
- " of Pride",
- " of the Volcano",
- " of Blood-Lust",
- " of Division",
- " of Eternal Harmony",
- " of Peace",
-/* 80: */
- " of Quick Death",
- " of Instant Death",
- " of Misery",
- " of the Whale",
- " of the Lobster",
- " of the Whelk",
- " of the Penguin",
- " of the Puffin",
- " of the Mushroom",
- " of the Toadstool",
-/* 90: */
- " of the Little People",
- " of the Puffball",
- " of Spores",
- " of Optimality",
- " of Pareto-Optimality",
- " of Greatest Utility",
- " of Anarcho-Capitalism",
- " of Ancient Evil",
- " of the Revolution",
- " of the People",
-/* 100: */
- " of the Elves",
- " of the Dwarves",
- " of the Orcs",
- " of the Humans",
- " of Sludge",
- " of the Naga",
- " of the Trolls",
- " of the Ogres",
- " of Equitable Redistribution",
- " of Wealth",
-/* 110: */
- " of Poverty",
- " of Reapportionment",
- " of Fragile Peace",
- " of Reinforcement",
- " of Beauty",
- " of the Slug",
- " of the Snail",
- " of the Gastropod",
- " of Corporal Punishment",
- " of Capital Punishment",
-/* 120: */
- " of the Beast",
- " of Light",
- " of Darkness",
- " of Day",
- " of the Day",
- " of Night",
- " of the Night",
- " of Twilight",
- " of the Twilight",
- " of Dawn",
-/* 130: */
- " of the Dawn",
- " of the Sun",
- " of the Moon",
- " of Distant Worlds",
- " of the Unseen Realm",
- " of Pandemonium",
- " of the Abyss",
- " of the Nexus",
- " of the Gulag",
- " of the Crusades",
-/* 140: */
- " of Proximity",
- " of Wounding",
- " of Peril",
- " of the Eternal Warrior",
- " of the Eternal War",
- " of Evil",
- " of Pounding",
- " of Oozing Pus",
- " of Pestilence",
- " of Plague",
-/* 150: */
- " of Negation",
- " of the Saviour",
- " of Infection",
- " of Defence",
- " of Protection",
- " of Defence by Offence",
- " of Expedience",
- " of Reason",
- " of Unreason",
- " of the Heart",
-/* 160: */
- " of Offence",
- " of the Leaf",
- " of Leaves",
- " of Winter",
- " of Summer",
- " of Autumn",
- " of Spring",
- " of Midsummer",
- " of Midwinter",
- " of Eternal Night",
-/* 170: */
- " of Shrieking Terror",
- " of the Lurker",
- " of the Crawling Thing",
- " of the Thing",
- "\"Thing\"",
- " of the Sea",
- " of the Forest",
- " of the Trees",
- " of Earth",
- " of the World",
-/* 180: */
- " of Bread",
- " of Yeast",
- " of the Amoeba",
- " of Deformation",
- " of Guilt",
- " of Innocence",
- " of Ascent",
- " of Descent",
- " of Music",
- " of Brilliance",
-/* 190: */
- " of Disgust",
- " of Feasting",
- " of Sunlight",
- " of Starshine",
- " of the Stars",
- " of Dust",
- " of the Clouds",
- " of the Sky",
- " of Ash",
- " of Slime",
-/* 200: */
- " of Clarity",
- " of Eternal Vigilance",
- " of Purpose",
- " of the Moth",
- " of the Goat",
- " of Fortitude",
- " of Equivalence",
- " of Balance",
- " of Unbalance",
- " of Harmony",
-/* 210: */
- " of Disharmony",
- " of the Inferno",
- " of the Omega Point",
- " of Inflation",
- " of Deflation",
- " of Supply",
- " of Demand",
- " of Gross Domestic Product",
- " of Unjust Enrichment",
- " of Detinue",
-/* 220: */
- " of Conversion",
- " of Anton Piller",
- " of Mandamus",
- " of Frustration",
- " of Breach",
- " of Fundamental Breach",
- " of Termination",
- " of Extermination",
- " of Satisfaction",
- " of Res Nullius",
-/* 230: */
- " of Fee Simple",
- " of Terra Nullius",
- " of Context",
- " of Prescription",
- " of Freehold",
- " of Tortfeasance",
- " of Omission",
- " of Negligence",
- " of Pains",
- " of Attainder",
-/* 240: */
- " of Action",
- " of Inaction",
- " of Truncation",
- " of Defenestration",
- " of Desertification",
- " of the Wilderness",
- " of Psychosis",
- " of Neurosis",
- " of Fixation",
- " of the Open Hand",
-/* 250: */
- " of the Tooth",
- " of Honesty",
- " of Dishonesty",
- " of Divine Compulsion",
- " of the Invisible Hand",
- " of Freedom",
- " of Liberty",
- " of Servitude",
- " of Domination",
- " of Tension",
-/* 260: */
- " of Monotheism",
- " of Atheism",
- " of Agnosticism",
- " of Existentialism",
- " of the Good",
- " of Relativism",
- " of Absolutism",
- " of Absolution",
- " of Abstinence",
- " of Abomination",
-/* 270: */
- " of Mutilation",
- " of Stasis",
- " of Wonder",
- " of Dullness",
- " of Dim Light",
- " of the Shining Light",
- " of Immorality",
- " of Amorality",
- " of Precise Incision",
- " of Orthodoxy",
-/* 280: */
- " of Faith",
- " of Untruth",
- " of the Augurer",
- " of the Water Diviner",
- " of the Soothsayer",
- " of Punishment",
- " of Amelioration",
- " of Sulphur",
- " of the Egg",
- " of the Globe",
-/* 290: */
- " of the Candle",
- " of the Candelabrum",
- " of the Vampires",
- " of the Orcs",
- " of the Halflings",
- " of World's End",
- " of Blue Skies",
- " of Red Skies",
- " of Orange Skies",
- " of Purple Skies",
-/* 300: */
- " of Articulation",
- " of the Mind",
- " of the Spider",
- " of the Lamprey",
- " of the Beginning",
- " of the End",
- " of Severance",
- " of Sequestration",
- " of Mourning",
- " of Death's Door",
-/* 310: */
- " of the Key",
- " of Earthquakes",
- " of Failure",
- " of Success",
- " of Intimidation",
- " of the Mosquito",
- " of the Gnat",
- " of the Blowfly",
- " of the Turtle",
- " of the Tortoise",
-/* 320: */
- " of the Pit",
- " of the Grave",
- " of Submission",
- " of Dominance",
- " of the Messenger",
- " of Crystal",
- " of Gravity",
- " of Levity",
- " of the Slorg",
- " of Surprise",
-/* 330: */
- " of the Maze",
- " of the Labyrinth",
- " of Divine Intervention",
- " of Rotation",
- " of the Spinneret",
- " of the Scorpion",
- " of Demonkind",
- " of the Genius",
- " of Bloodstone",
- " of Grontol",
-/* 340: */
- " \"Grim Tooth\"",
- " \"Widowmaker\"",
- " \"Widowermaker\"",
- " \"Lifebane\"",
- " \"Conservator\"",
- " \"Banisher\"",
- " \"Tormentor\"",
- " \"Secret Weapon\"",
- " \"String\"",
- " \"Stringbean\"",
-/* 350: */
- " \"Blob\"",
- " \"Globulus\"",
- " \"Hulk\"",
- " \"Raisin\"",
- " \"Starlight\"",
- " \"Giant's Toothpick\"",
- " \"Pendulum\"",
- " \"Backscratcher\"",
- " \"Brush\"",
- " \"Murmur\"",
-/* 360: */
- " \"Sarcophage\"",
- " \"Concordance\"",
- " \"Dragon's Tongue\"",
- " \"Arbiter\"",
- " \"Gram\"",
- " \"Grom\"",
- " \"Grim\"",
- " \"Grum\"",
- " \"Rummage\"",
- " \"Omelette\"",
-/* 370: */
- " \"Egg\"",
- " \"Aubergine\"",
- " \"Z\"",
- " \"X\"",
- " \"Q\"",
- " \"Ox\"",
- " \"Death Rattle\"",
- " \"Tattletale\"",
- " \"Fish\"",
- " \"Bung\"",
-/* 380: */
- " \"Arcanum\"",
- " \"Mud Pie of Death\"",
- " \"Transmigrator\"",
- " \"Ultimatum\"",
- " \"Earthworm\"",
- " \"Worm\"",
- " \"Worm's Wrath\"",
- " \"Xom's Favour\"",
- " \"Bingo\"",
- " \"Leviticus\"",
-// Not yet possible...
-/* 390: */
- " of Joyful Slaughter",
- " of ",
- " of ",
- " of ",
- " of ",
- " of ",
- " of ",
- " of ",
- " of ",
- " of ",
-
-/* 390: */
- "\"\"",
- "\"\"",
- "\"\"",
- "\"\"",
- "\"\"",
- "\"\"",
- "\"\"",
- "\"\"",
- "\"\"",
- "\"\"",
-
-/* 340: */
- " of ",
- " of ",
- " of ",
- " of ",
- " of ",
- " of ",
- " of ",
- " of ",
- " of ",
- " of ",
-
-/* 200: */
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
-};
-
-const char *rand_armour_names[] = {
-/* 0: */
- " of Shielding",
- " of Grace",
- " of Impermeability",
- " of the Onion",
- " of Life",
- " of Defence",
- " of Nonsense",
- " of Eternal Vigilance",
- " of Fun",
- " of Joy",
-/* 10: */
- " of Death's Door",
- " of the Gate",
- " of Watchfulness",
- " of Integrity",
- " of Bodily Harmony",
- " of Harmony",
- " of the Untouchables",
- " of Grot",
- " of Grottiness",
- " of Filth",
-/* 20: */
- " of Wonder",
- " of Wondrous Power",
- " of Power",
- " of Vlad",
- " of the Eternal Fruit",
- " of Invincibility",
- " of Hide-and-Seek",
- " of the Mouse",
- " of the Saviour",
- " of Plasticity",
-/* 30: */
- " of Baldness",
- " of Terror",
- " of the Arcane",
- " of Resist Death",
- " of Anaesthesia",
- " of the Guardian",
- " of Inviolability",
- " of the Tortoise",
- " of the Turtle",
- " of the Armadillo",
-/* 40: */
- " of the Echidna",
- " of the Armoured One",
- " of Weirdness",
- " of Pathos",
- " of Serendipity",
- " of Loss",
- " of Hedging",
- " of Indemnity",
- " of Limitation",
- " of Exclusion",
-/* 50: */
- " of Repulsion",
- " of Untold Secrets",
- " of the Earth",
- " of the Turtledove",
- " of Limited Liability",
- " of Responsibility",
- " of Hadjma",
- " of Glory",
- " of Preservation",
- " of Conservation",
-/* 60: */
- " of Protective Custody",
- " of the Clam",
- " of the Barnacle",
- " of the Lobster",
- " of Hairiness",
- " of Supple Strength",
- " of Space",
- " of the Vacuum",
- " of Compression",
- " of Decompression",
-
-/* 70: */
- " of the Loofah",
- " of ",
- " of ",
- " of ",
- " of ",
- " of ",
- " of ",
- " of ",
- " of ",
- " of ",
-// Sarcophagus
-};
-
-// Remember: disallow unrandart creation in abyss/pan
-
-/*
- The following unrandart bits were taken from $pellbinder's mon-util code
- (see mon-util.h & mon-util.cc) and modified (LRH). They're in randart.cc and
- not randart.h because they're only used in this code module.
-*/
-
-#if defined(MAC) || defined(__IBMCPP__) || defined(__BCPLUSPLUS__)
-#define PACKED
-#else
-#ifndef PACKED
-#define PACKED __attribute__ ((packed))
-#endif
-#endif
-
-//int unranddatasize;
-
-#ifdef __IBMCPP__
-#pragma pack(push)
-#pragma pack(1)
-#endif
-
-struct unrandart_entry
-{
- const char *name; // true name of unrandart (max 31 chars)
- const char *unid_name; // un-id'd name of unrandart (max 31 chars)
-
- int ura_cl; // class of ura
- int ura_ty; // type of ura
- int ura_pl; // plus of ura
- int ura_pl2; // plus2 of ura
- int ura_col; // colour of ura
- short prpty[RA_PROPERTIES];
-
- // special description added to 'v' command output (max 31 chars)
- const char *spec_descrip1;
- // special description added to 'v' command output (max 31 chars)
- const char *spec_descrip2;
- // special description added to 'v' command output (max 31 chars)
- const char *spec_descrip3;
-};
-
-#ifdef __IBMCPP__
-#pragma pack(pop)
-#endif
-
-static struct unrandart_entry unranddata[] = {
-#include "unrand.h"
-};
-
-char *art_n;
-static FixedVector < char, NO_UNRANDARTS > unrandart_exist;
-
-// static int random5( int randmax );
-static struct unrandart_entry *seekunrandart( const item_def &item );
-
-static inline int random5( int randmax )
-{
- return random2(randmax);
-}
-
-void set_unrandart_exist(int whun, char is_exist)
-{
- unrandart_exist[whun] = is_exist;
-}
-
-char does_unrandart_exist(int whun)
-{
- return (unrandart_exist[whun]);
-}
-
-// returns true is item is a pure randart or an unrandart
-bool is_random_artefact( const item_def &item )
-{
- return (item.flags & ISFLAG_ARTEFACT_MASK);
-}
-
-// returns true if item in an unrandart
-bool is_unrandom_artefact( const item_def &item )
-{
- return (item.flags & ISFLAG_UNRANDART);
-}
-
-// returns true if item is one of the origional fixed artefacts
-bool is_fixed_artefact( const item_def &item )
-{
- if (!is_random_artefact( item )
- && item.base_type == OBJ_WEAPONS
- && item.special >= SPWPN_SINGING_SWORD)
- {
- return (true);
- }
-
- return (false);
-}
-
-int get_unique_item_status( int base_type, int art )
-{
- // Note: for weapons "art" is in item.special,
- // for orbs it's the sub_type.
- if (base_type == OBJ_WEAPONS)
- {
- if (art >= SPWPN_SINGING_SWORD && art <= SPWPN_SWORD_OF_ZONGULDROK)
- return (you.unique_items[ art - SPWPN_SINGING_SWORD ]);
- else if (art >= SPWPN_SWORD_OF_POWER && art <= SPWPN_STAFF_OF_WUCAD_MU)
- return (you.unique_items[ art - SPWPN_SWORD_OF_POWER + 24 ]);
- }
- else if (base_type == OBJ_ORBS)
- {
- if (art >= 4 && art <= 19)
- return (you.unique_items[ art + 3 ]);
-
- }
-
- return (UNIQ_NOT_EXISTS);
-}
-
-void set_unique_item_status( int base_type, int art, int status )
-{
- // Note: for weapons "art" is in item.special,
- // for orbs it's the sub_type.
- if (base_type == OBJ_WEAPONS)
- {
- if (art >= SPWPN_SINGING_SWORD && art <= SPWPN_SWORD_OF_ZONGULDROK)
- you.unique_items[ art - SPWPN_SINGING_SWORD ] = status;
- else if (art >= SPWPN_SWORD_OF_POWER && art <= SPWPN_STAFF_OF_WUCAD_MU)
- you.unique_items[ art - SPWPN_SWORD_OF_POWER + 24 ] = status;
- }
- else if (base_type == OBJ_ORBS)
- {
- if (art >= 4 && art <= 19)
- you.unique_items[ art + 3 ] = status;
-
- }
-}
-
-static long calc_seed( const item_def &item )
-{
- return (item.special & RANDART_SEED_MASK);
-}
-
-void randart_wpn_properties( const item_def &item,
- FixedVector< char, RA_PROPERTIES > &proprt )
-{
- ASSERT( is_random_artefact( item ) );
-
- const int aclass = item.base_type;
- const int atype = item.sub_type;
-
- int i = 0;
- int power_level = 0;
-
- if (is_unrandom_artefact( item ))
- {
- struct unrandart_entry *unrand = seekunrandart( item );
-
- for (i = 0; i < RA_PROPERTIES; i++)
- proprt[i] = unrand->prpty[i];
-
- return;
- }
-
- // long seed = aclass * adam + atype * (aplus % 100) + aplus2 * 100;
- long seed = calc_seed( item );
- push_rng_state();
- seed_rng( seed );
-
- if (aclass == OBJ_ARMOUR)
- power_level = item.plus / 2 + 2;
- else if (aclass == OBJ_JEWELLERY)
- power_level = 1 + random5(3) + random5(2);
- else // OBJ_WEAPON
- power_level = item.plus / 3 + item.plus2 / 3;
-
- if (power_level < 0)
- power_level = 0;
-
- for (i = 0; i < RA_PROPERTIES; i++)
- proprt[i] = 0;
-
- if (aclass == OBJ_WEAPONS) /* Only weapons get brands, of course */
- {
- proprt[RAP_BRAND] = SPWPN_FLAMING + random5(15); /* brand */
-
- if (random5(6) == 0)
- proprt[RAP_BRAND] = SPWPN_FLAMING + random5(2);
-
- if (random5(6) == 0)
- proprt[RAP_BRAND] = SPWPN_ORC_SLAYING + random5(4);
-
- if (random5(6) == 0)
- proprt[RAP_BRAND] = SPWPN_VORPAL;
-
- if (proprt[RAP_BRAND] == SPWPN_FLAME
- || proprt[RAP_BRAND] == SPWPN_FROST)
- {
- proprt[RAP_BRAND] = 0; /* missile wpns */
- }
-
- if (proprt[RAP_BRAND] == SPWPN_PROTECTION)
- proprt[RAP_BRAND] = 0; /* no protection */
-
- if (proprt[RAP_BRAND] == SPWPN_DISRUPTION
- && !(atype == WPN_MACE || atype == WPN_GREAT_MACE
- || atype == WPN_HAMMER))
- {
- proprt[RAP_BRAND] = SPWPN_NORMAL;
- }
-
- // is this happens, things might get broken -- bwr
- if (proprt[RAP_BRAND] == SPWPN_SPEED && atype == WPN_QUICK_BLADE)
- proprt[RAP_BRAND] = SPWPN_NORMAL;
-
- if (launches_things(atype))
- {
- proprt[RAP_BRAND] = SPWPN_NORMAL;
-
- if (random5(3) == 0)
- {
- int tmp = random5(20);
-
- proprt[RAP_BRAND] = (tmp >= 18) ? SPWPN_SPEED :
- (tmp >= 14) ? SPWPN_PROTECTION :
- (tmp >= 10) ? SPWPN_VENOM
- : SPWPN_VORPAL + random2(3);
- if (proprt[RAP_BRAND] == SPWPN_VORPAL && atype == WPN_BLOWGUN)
- proprt[RAP_BRAND] = SPWPN_VENOM;
- }
- }
-
-
- if (is_demonic(atype))
- {
- switch (random5(9))
- {
- case 0:
- proprt[RAP_BRAND] = SPWPN_DRAINING;
- break;
- case 1:
- proprt[RAP_BRAND] = SPWPN_FLAMING;
- break;
- case 2:
- proprt[RAP_BRAND] = SPWPN_FREEZING;
- break;
- case 3:
- proprt[RAP_BRAND] = SPWPN_ELECTROCUTION;
- break;
- case 4:
- proprt[RAP_BRAND] = SPWPN_VAMPIRICISM;
- break;
- case 5:
- proprt[RAP_BRAND] = SPWPN_PAIN;
- break;
- case 6:
- proprt[RAP_BRAND] = SPWPN_VENOM;
- break;
- default:
- power_level -= 2;
- }
- power_level += 2;
- }
- else if (random5(3) == 0)
- proprt[RAP_BRAND] = SPWPN_NORMAL;
- else
- power_level++;
- }
-
- if (random5(5) == 0)
- goto skip_mods;
-
- /* AC mod - not for armours or rings of protection */
- if (random5(4 + power_level) == 0
- && aclass != OBJ_ARMOUR
- && (aclass != OBJ_JEWELLERY || atype != RING_PROTECTION))
- {
- proprt[RAP_AC] = 1 + random5(3) + random5(3) + random5(3);
- power_level++;
- if (random5(4) == 0)
- {
- proprt[RAP_AC] -= 1 + random5(3) + random5(3) + random5(3);
- power_level--;
- }
- }
-
- /* ev mod - not for rings of evasion */
- if (random5(4 + power_level) == 0
- && (aclass != OBJ_JEWELLERY || atype != RING_EVASION))
- {
- proprt[RAP_EVASION] = 1 + random5(3) + random5(3) + random5(3);
- power_level++;
- if (random5(4) == 0)
- {
- proprt[RAP_EVASION] -= 1 + random5(3) + random5(3) + random5(3);
- power_level--;
- }
- }
-
- /* str mod - not for rings of strength */
- if (random5(4 + power_level) == 0
- && (aclass != OBJ_JEWELLERY || atype != RING_STRENGTH))
- {
- proprt[RAP_STRENGTH] = 1 + random5(3) + random5(2);
- power_level++;
- if (random5(4) == 0)
- {
- proprt[RAP_STRENGTH] -= 1 + random5(3) + random5(3) + random5(3);
- power_level--;
- }
- }
-
- /* int mod - not for rings of intelligence */
- if (random5(4 + power_level) == 0
- && (aclass != OBJ_JEWELLERY || atype != RING_INTELLIGENCE))
- {
- proprt[RAP_INTELLIGENCE] = 1 + random5(3) + random5(2);
- power_level++;
- if (random5(4) == 0)
- {
- proprt[RAP_INTELLIGENCE] -= 1 + random5(3) + random5(3) + random5(3);
- power_level--;
- }
- }
-
- /* dex mod - not for rings of dexterity */
- if (random5(4 + power_level) == 0
- && (aclass != OBJ_JEWELLERY || atype != RING_DEXTERITY))
- {
- proprt[RAP_DEXTERITY] = 1 + random5(3) + random5(2);
- power_level++;
- if (random5(4) == 0)
- {
- proprt[RAP_DEXTERITY] -= 1 + random5(3) + random5(3) + random5(3);
- power_level--;
- }
- }
-
- skip_mods:
- if (random5(15) < power_level
- || aclass == OBJ_WEAPONS
- || (aclass == OBJ_JEWELLERY && atype == RING_SLAYING))
- {
- goto skip_combat;
- }
-
- /* Weapons and rings of slaying can't get these */
- if (random5(4 + power_level) == 0) /* to-hit */
- {
- proprt[RAP_ACCURACY] = 1 + random5(3) + random5(2);
- power_level++;
- if (random5(4) == 0)
- {
- proprt[RAP_ACCURACY] -= 1 + random5(3) + random5(3) + random5(3);
- power_level--;
- }
- }
-
- if (random5(4 + power_level) == 0) /* to-dam */
- {
- proprt[RAP_DAMAGE] = 1 + random5(3) + random5(2);
- power_level++;
- if (random5(4) == 0)
- {
- proprt[RAP_DAMAGE] -= 1 + random5(3) + random5(3) + random5(3);
- power_level--;
- }
- }
-
- skip_combat:
- if (random5(12) < power_level)
- goto finished_powers;
-
-/* res_fire */
- if (random5(4 + power_level) == 0
- && (aclass != OBJ_JEWELLERY
- || (atype != RING_PROTECTION_FROM_FIRE
- && atype != RING_FIRE
- && atype != RING_ICE))
- && (aclass != OBJ_ARMOUR
- || (atype != ARM_DRAGON_ARMOUR
- && atype != ARM_ICE_DRAGON_ARMOUR
- && atype != ARM_GOLD_DRAGON_ARMOUR)))
- {
- proprt[RAP_FIRE] = 1;
- if (random5(5) == 0)
- proprt[RAP_FIRE]++;
- power_level++;
- }
-
- /* res_cold */
- if (random5(4 + power_level) == 0
- && (aclass != OBJ_JEWELLERY
- || (atype != RING_PROTECTION_FROM_COLD
- && atype != RING_FIRE
- && atype != RING_ICE))
- && (aclass != OBJ_ARMOUR
- || (atype != ARM_DRAGON_ARMOUR
- && atype != ARM_ICE_DRAGON_ARMOUR
- && atype != ARM_GOLD_DRAGON_ARMOUR)))
- {
- proprt[RAP_COLD] = 1;
- if (random5(5) == 0)
- proprt[RAP_COLD]++;
- power_level++;
- }
-
- if (random5(12) < power_level || power_level > 7)
- goto finished_powers;
-
- /* res_elec */
- if (random5(4 + power_level) == 0
- && (aclass != OBJ_ARMOUR || atype != ARM_STORM_DRAGON_ARMOUR))
- {
- proprt[RAP_ELECTRICITY] = 1;
- power_level++;
- }
-
-/* res_poison */
- if (random5(5 + power_level) == 0
- && (aclass != OBJ_JEWELLERY || atype != RING_POISON_RESISTANCE)
- && (aclass != OBJ_ARMOUR
- || atype != ARM_GOLD_DRAGON_ARMOUR
- || atype != ARM_SWAMP_DRAGON_ARMOUR))
- {
- proprt[RAP_POISON] = 1;
- power_level++;
- }
-
- /* prot_life - no necromantic brands on weapons allowed */
- if (random5(4 + power_level) == 0
- && (aclass != OBJ_JEWELLERY || atype != RING_TELEPORTATION)
- && proprt[RAP_BRAND] != SPWPN_DRAINING
- && proprt[RAP_BRAND] != SPWPN_VAMPIRICISM
- && proprt[RAP_BRAND] != SPWPN_PAIN)
- {
- proprt[RAP_NEGATIVE_ENERGY] = 1;
- power_level++;
- }
-
- /* res magic */
- if (random5(4 + power_level) == 0
- && (aclass != OBJ_JEWELLERY || atype != RING_PROTECTION_FROM_MAGIC))
- {
- proprt[RAP_MAGIC] = 20 + random5(40);
- power_level++;
- }
-
- /* see_invis */
- if (random5(4 + power_level) == 0
- && (aclass != OBJ_JEWELLERY || atype != RING_INVISIBILITY))
- {
- proprt[RAP_EYESIGHT] = 1;
- power_level++;
- }
-
- if (random5(12) < power_level || power_level > 10)
- goto finished_powers;
-
- /* turn invis */
- if (random5(10) == 0
- && (aclass != OBJ_JEWELLERY || atype != RING_INVISIBILITY))
- {
- proprt[RAP_INVISIBLE] = 1;
- power_level++;
- }
-
- /* levitate */
- if (random5(10) == 0
- && (aclass != OBJ_JEWELLERY || atype != RING_LEVITATION))
- {
- proprt[RAP_LEVITATE] = 1;
- power_level++;
- }
-
- if (random5(10) == 0) /* blink */
- {
- proprt[RAP_BLINK] = 1;
- power_level++;
- }
-
- /* teleport */
- if (random5(10) == 0
- && (aclass != OBJ_JEWELLERY || atype != RING_TELEPORTATION))
- {
- proprt[RAP_CAN_TELEPORT] = 1;
- power_level++;
- }
-
- /* go berserk */
- if (random5(10) == 0 && (aclass != OBJ_JEWELLERY || atype != AMU_RAGE))
- {
- proprt[RAP_BERSERK] = 1;
- power_level++;
- }
-
- if (random5(10) == 0) /* sense surr */
- {
- proprt[RAP_MAPPING] = 1;
- power_level++;
- }
-
-
- finished_powers:
- /* Armours get less powers, and are also less likely to be
- cursed that wpns */
- if (aclass == OBJ_ARMOUR)
- power_level -= 4;
-
- if (random5(17) >= power_level || power_level < 2)
- goto finished_curses;
-
- switch (random5(9))
- {
- case 0: /* makes noise */
- if (aclass != OBJ_WEAPONS)
- break;
- proprt[RAP_NOISES] = 1 + random5(4);
- break;
- case 1: /* no magic */
- proprt[RAP_PREVENT_SPELLCASTING] = 1;
- break;
- case 2: /* random teleport */
- if (aclass != OBJ_WEAPONS)
- break;
- proprt[RAP_CAUSE_TELEPORTATION] = 5 + random5(15);
- break;
- case 3: /* no teleport - doesn't affect some instantaneous teleports */
- if (aclass == OBJ_JEWELLERY && atype == RING_TELEPORTATION)
- break; /* already is a ring of tport */
- if (aclass == OBJ_JEWELLERY && atype == RING_TELEPORT_CONTROL)
- break; /* already is a ring of tport ctrl */
- proprt[RAP_BLINK] = 0;
- proprt[RAP_CAN_TELEPORT] = 0;
- proprt[RAP_PREVENT_TELEPORTATION] = 1;
- break;
- case 4: /* berserk on attack */
- if (aclass != OBJ_WEAPONS)
- break;
- proprt[RAP_ANGRY] = 1 + random5(8);
- break;
- case 5: /* susceptible to fire */
- if (aclass == OBJ_JEWELLERY
- && (atype == RING_PROTECTION_FROM_FIRE || atype == RING_FIRE
- || atype == RING_ICE))
- break; /* already does this or something */
- if (aclass == OBJ_ARMOUR
- && (atype == ARM_DRAGON_ARMOUR || atype == ARM_ICE_DRAGON_ARMOUR
- || atype == ARM_GOLD_DRAGON_ARMOUR))
- break;
- proprt[RAP_FIRE] = -1;
- break;
- case 6: /* susceptible to cold */
- if (aclass == OBJ_JEWELLERY
- && (atype == RING_PROTECTION_FROM_COLD || atype == RING_FIRE
- || atype == RING_ICE))
- break; /* already does this or something */
- if (aclass == OBJ_ARMOUR
- && (atype == ARM_DRAGON_ARMOUR || atype == ARM_ICE_DRAGON_ARMOUR
- || atype == ARM_GOLD_DRAGON_ARMOUR))
- break;
- proprt[RAP_COLD] = -1;
- break;
- case 7: /* speed metabolism */
- if (aclass == OBJ_JEWELLERY && atype == RING_HUNGER)
- break; /* already is a ring of hunger */
- if (aclass == OBJ_JEWELLERY && atype == RING_SUSTENANCE)
- break; /* already is a ring of sustenance */
- proprt[RAP_METABOLISM] = 1 + random5(3);
- break;
- case 8: /* emits mutagenic radiation - increases magic_contamination */
- /* property is chance (1 in ...) of increasing magic_contamination */
- proprt[RAP_MUTAGENIC] = 2 + random5(4);
- break;
- }
-
-/*
- 26 - +to-hit (no wpns)
- 27 - +to-dam (no wpns)
- */
-
-finished_curses:
- if (random5(10) == 0
- && (aclass != OBJ_ARMOUR
- || atype != ARM_CLOAK
- || get_equip_race(item) != ISFLAG_ELVEN)
- && (aclass != OBJ_ARMOUR
- || atype != ARM_BOOTS
- || get_equip_race(item) != ISFLAG_ELVEN)
- && get_armour_ego_type( item ) != SPARM_STEALTH)
- {
- power_level++;
- proprt[RAP_STEALTH] = 10 + random5(70);
-
- if (random5(4) == 0)
- {
- proprt[RAP_STEALTH] = -proprt[RAP_STEALTH] - random5(20);
- power_level--;
- }
- }
-
- if ((power_level < 2 && random5(5) == 0) || random5(30) == 0)
- proprt[RAP_CURSED] = 1;
-
- pop_rng_state();
-
-}
-
-int randart_wpn_property( const item_def &item, char prop )
-{
- FixedVector< char, RA_PROPERTIES > proprt;
-
- randart_wpn_properties( item, proprt );
-
- return (proprt[prop]);
-}
-
-const char *randart_name( const item_def &item )
-{
- ASSERT( item.base_type == OBJ_WEAPONS );
-
- if (is_unrandom_artefact( item ))
- {
- struct unrandart_entry *unrand = seekunrandart( item );
-
- return (item_ident(item, ISFLAG_KNOW_TYPE) ? unrand->name
- : unrand->unid_name);
- }
-
- free(art_n);
- art_n = (char *) malloc(sizeof(char) * 80);
-
- if (art_n == NULL)
- return ("Malloc Failed Error");
-
- strcpy(art_n, "");
-
- // long seed = aclass + adam * (aplus % 100) + atype * aplus2;
- long seed = calc_seed( item );
- push_rng_state();
- seed_rng( seed );
-
- if (!item_ident( item, ISFLAG_KNOW_TYPE ))
- {
- switch (random5(21))
- {
- case 0: strcat(art_n, "brightly glowing "); break;
- case 1: strcat(art_n, "runed "); break;
- case 2: strcat(art_n, "smoking "); break;
- case 3: strcat(art_n, "bloodstained "); break;
- case 4: strcat(art_n, "twisted "); break;
- case 5: strcat(art_n, "shimmering "); break;
- case 6: strcat(art_n, "warped "); break;
- case 7: strcat(art_n, "crystal "); break;
- case 8: strcat(art_n, "jewelled "); break;
- case 9: strcat(art_n, "transparent "); break;
- case 10: strcat(art_n, "encrusted "); break;
- case 11: strcat(art_n, "pitted "); break;
- case 12: strcat(art_n, "slimy "); break;
- case 13: strcat(art_n, "polished "); break;
- case 14: strcat(art_n, "fine "); break;
- case 15: strcat(art_n, "crude "); break;
- case 16: strcat(art_n, "ancient "); break;
- case 17: strcat(art_n, "ichor-stained "); break;
- case 18: strcat(art_n, "faintly glowing "); break;
- case 19: strcat(art_n, "steaming "); break;
- case 20: strcat(art_n, "shiny "); break;
- }
-
- char st_p3[ITEMNAME_SIZE];
-
- standard_name_weap( item.sub_type, st_p3 );
- strcat(art_n, st_p3);
- pop_rng_state();
- return (art_n);
- }
-
- char st_p[ITEMNAME_SIZE];
-
- if (random5(2) == 0)
- {
- standard_name_weap( item.sub_type, st_p );
- strcat(art_n, st_p);
- strcat(art_n, rand_wpn_names[random5(390)]);
- }
- else
- {
- char st_p2[ITEMNAME_SIZE];
-
- make_name(random_int(), false, st_p);
- standard_name_weap( item.sub_type, st_p2 );
- strcat(art_n, st_p2);
-
- if (random5(3) == 0)
- {
- strcat(art_n, " of ");
- strcat(art_n, st_p);
- }
- else
- {
- strcat(art_n, " \"");
- strcat(art_n, st_p);
- strcat(art_n, "\"");
- }
- }
-
- pop_rng_state();
-
- return (art_n);
-}
-
-const char *randart_armour_name( const item_def &item )
-{
- ASSERT( item.base_type == OBJ_ARMOUR );
-
- if (is_unrandom_artefact( item ))
- {
- struct unrandart_entry *unrand = seekunrandart( item );
-
- return (item_ident(item, ISFLAG_KNOW_TYPE) ? unrand->name
- : unrand->unid_name);
- }
-
- free(art_n);
- art_n = (char *) malloc(sizeof(char) * 80);
-
- if (art_n == NULL)
- {
- return ("Malloc Failed Error");
- }
-
- strcpy(art_n, "");
-
- // long seed = aclass + adam * (aplus % 100) + atype * aplus2;
- long seed = calc_seed( item );
-
- push_rng_state();
- seed_rng( seed );
-
- if (!item_ident( item, ISFLAG_KNOW_TYPE ))
- {
- switch (random5(21))
- {
- case 0: strcat(art_n, "brightly glowing "); break;
- case 1: strcat(art_n, "runed "); break;
- case 2: strcat(art_n, "smoking "); break;
- case 3: strcat(art_n, "bloodstained "); break;
- case 4: strcat(art_n, "twisted "); break;
- case 5: strcat(art_n, "shimmering "); break;
- case 6: strcat(art_n, "warped "); break;
- case 7: strcat(art_n, "heavily runed "); break;
- case 8: strcat(art_n, "jeweled "); break;
- case 9: strcat(art_n, "transparent "); break;
- case 10: strcat(art_n, "encrusted "); break;
- case 11: strcat(art_n, "pitted "); break;
- case 12: strcat(art_n, "slimy "); break;
- case 13: strcat(art_n, "polished "); break;
- case 14: strcat(art_n, "fine "); break;
- case 15: strcat(art_n, "crude "); break;
- case 16: strcat(art_n, "ancient "); break;
- case 17: strcat(art_n, "ichor-stained "); break;
- case 18: strcat(art_n, "faintly glowing "); break;
- case 19: strcat(art_n, "steaming "); break;
- case 20: strcat(art_n, "shiny "); break;
- }
- char st_p3[ITEMNAME_SIZE];
-
- standard_name_armour(item, st_p3);
- strcat(art_n, st_p3);
- pop_rng_state();
- return (art_n);
- }
-
- char st_p[ITEMNAME_SIZE];
-
- if (random5(2) == 0)
- {
- standard_name_armour(item, st_p);
- strcat(art_n, st_p);
- strcat(art_n, rand_armour_names[random5(71)]);
- }
- else
- {
- char st_p2[ITEMNAME_SIZE];
-
- make_name(random_int(), false, st_p);
- standard_name_armour(item, st_p2);
- strcat(art_n, st_p2);
- if (random5(3) == 0)
- {
- strcat(art_n, " of ");
- strcat(art_n, st_p);
- }
- else
- {
- strcat(art_n, " \"");
- strcat(art_n, st_p);
- strcat(art_n, "\"");
- }
- }
-
- pop_rng_state();
-
- return (art_n);
-}
-
-const char *randart_ring_name( const item_def &item )
-{
- ASSERT( item.base_type == OBJ_JEWELLERY );
-
- int temp_rand = 0; // probability determination {dlb}
-
- if (is_unrandom_artefact( item ))
- {
- struct unrandart_entry *unrand = seekunrandart( item );
-
- return (item_ident(item, ISFLAG_KNOW_TYPE) ? unrand->name
- : unrand->unid_name);
- }
-
- char st_p[ITEMNAME_SIZE];
-
- free(art_n);
- art_n = (char *) malloc(sizeof(char) * 80);
-
- if (art_n == NULL)
- return ("Malloc Failed Error");
-
- strcpy(art_n, "");
-
- // long seed = aclass + adam * (aplus % 100) + atype * aplus2;
- long seed = calc_seed( item );
- push_rng_state();
- seed_rng( seed );
-
- if (!item_ident( item, ISFLAG_KNOW_TYPE ))
- {
- temp_rand = random5(21);
-
- strcat(art_n, (temp_rand == 0) ? "brightly glowing" :
- (temp_rand == 1) ? "runed" :
- (temp_rand == 2) ? "smoking" :
- (temp_rand == 3) ? "ruby" :
- (temp_rand == 4) ? "twisted" :
- (temp_rand == 5) ? "shimmering" :
- (temp_rand == 6) ? "warped" :
- (temp_rand == 7) ? "crystal" :
- (temp_rand == 8) ? "diamond" :
- (temp_rand == 9) ? "transparent" :
- (temp_rand == 10) ? "encrusted" :
- (temp_rand == 11) ? "pitted" :
- (temp_rand == 12) ? "slimy" :
- (temp_rand == 13) ? "polished" :
- (temp_rand == 14) ? "fine" :
- (temp_rand == 15) ? "crude" :
- (temp_rand == 16) ? "ancient" :
- (temp_rand == 17) ? "emerald" :
- (temp_rand == 18) ? "faintly glowing" :
- (temp_rand == 19) ? "steaming"
- : "shiny");
-
- strcat(art_n, " ");
- strcat(art_n, (item.sub_type < AMU_RAGE) ? "ring" : "amulet");
-
- pop_rng_state();
-
- return (art_n);
- }
-
- if (random5(5) == 0)
- {
- strcat(art_n, (item.sub_type < AMU_RAGE) ? "ring" : "amulet");
- strcat(art_n, rand_armour_names[random5(71)]);
- }
- else
- {
- make_name(random_int(), false, st_p);
-
- strcat(art_n, (item.sub_type < AMU_RAGE) ? "ring" : "amulet");
-
- if (random5(3) == 0)
- {
- strcat(art_n, " of ");
- strcat(art_n, st_p);
- }
- else
- {
- strcat(art_n, " \"");
- strcat(art_n, st_p);
- strcat(art_n, "\"");
- }
- }
-
- pop_rng_state();
-
- return (art_n);
-} // end randart_ring_name()
-
-static struct unrandart_entry *seekunrandart( const item_def &item )
-{
- int x = 0;
-
- while (x < NO_UNRANDARTS)
- {
- if (unranddata[x].ura_cl == item.base_type
- && unranddata[x].ura_ty == item.sub_type
- && unranddata[x].ura_pl == item.plus
- && unranddata[x].ura_pl2 == item.plus2)
- {
- return (&unranddata[x]);
- }
-
- x++;
- }
-
- return (&unranddata[0]); // Dummy object
-} // end seekunrandart()
-
-int find_unrandart_index(int item_number)
-{
- int x;
-
- for(x=0; x < NO_UNRANDARTS; x++)
- {
- if (unranddata[x].ura_cl == mitm[item_number].base_type
- && unranddata[x].ura_ty == mitm[item_number].sub_type
- && unranddata[x].ura_pl == mitm[item_number].plus
- && unranddata[x].ura_pl2 == mitm[item_number].plus2)
- {
- return (x);
- }
- }
-
- return (-1);
-}
-
-int find_okay_unrandart(unsigned char aclass, unsigned char atype)
-{
- int x, count;
- int ret = -1;
-
- for (x = 0, count = 0; x < NO_UNRANDARTS; x++)
- {
- if (unranddata[x].ura_cl == aclass
- && does_unrandart_exist(x) == 0
- && (atype == OBJ_RANDOM || unranddata[x].ura_ty == atype))
- {
- count++;
-
- if (random5(count) == 0)
- ret = x;
- }
- }
-
- return (ret);
-} // end find_okay_unrandart()
-
-// which == 0 (default) gives random fixed artefact.
-// Returns true if successful.
-bool make_item_fixed_artefact( item_def &item, bool in_abyss, int which )
-{
- bool force = true; // we force any one asked for specifically
-
- if (!which)
- {
- // using old behaviour... try only once. -- bwr
- force = false;
-
- which = SPWPN_SINGING_SWORD + random2(12);
- if (which >= SPWPN_SWORD_OF_CEREBOV)
- which += 3; // skip over Cerebov's, Dispater's, and Asmodeus' weapons
- }
-
- int status = get_unique_item_status( OBJ_WEAPONS, which );
-
- if ((status == UNIQ_EXISTS
- || (in_abyss && status == UNIQ_NOT_EXISTS)
- || (!in_abyss && status == UNIQ_LOST_IN_ABYSS))
- && !force)
- {
- return (false);
- }
-
- switch (which)
- {
- case SPWPN_SINGING_SWORD:
- item.base_type = OBJ_WEAPONS;
- item.sub_type = WPN_LONG_SWORD;
- item.plus = 7;
- item.plus2 = 6;
- break;
-
- case SPWPN_WRATH_OF_TROG:
- item.base_type = OBJ_WEAPONS;
- item.sub_type = WPN_BATTLEAXE;
- item.plus = 3;
- item.plus2 = 11;
- break;
-
- case SPWPN_SCYTHE_OF_CURSES:
- item.base_type = OBJ_WEAPONS;
- item.sub_type = WPN_SCYTHE;
- item.plus = 13;
- item.plus2 = 13;
- break;
-
- case SPWPN_MACE_OF_VARIABILITY:
- item.base_type = OBJ_WEAPONS;
- item.sub_type = WPN_MACE;
- item.plus = random2(16) - 4;
- item.plus2 = random2(16) - 4;
- break;
-
- case SPWPN_GLAIVE_OF_PRUNE:
- item.base_type = OBJ_WEAPONS;
- item.sub_type = WPN_GLAIVE;
- item.plus = 0;
- item.plus2 = 12;
- break;
-
- case SPWPN_SCEPTRE_OF_TORMENT:
- item.base_type = OBJ_WEAPONS;
- item.sub_type = WPN_MACE;
- item.plus = 7;
- item.plus2 = 6;
- break;
-
- case SPWPN_SWORD_OF_ZONGULDROK:
- item.base_type = OBJ_WEAPONS;
- item.sub_type = WPN_LONG_SWORD;
- item.plus = 9;
- item.plus2 = 9;
- break;
-
- case SPWPN_SWORD_OF_POWER:
- item.base_type = OBJ_WEAPONS;
- item.sub_type = WPN_GREAT_SWORD;
- item.plus = 0; // set on wield
- item.plus2 = 0; // set on wield
- break;
-
- case SPWPN_KNIFE_OF_ACCURACY:
- item.base_type = OBJ_WEAPONS;
- item.sub_type = WPN_DAGGER;
- item.plus = 27;
- item.plus2 = -1;
- break;
-
- case SPWPN_STAFF_OF_OLGREB:
- item.base_type = OBJ_WEAPONS;
- item.sub_type = WPN_QUARTERSTAFF;
- item.plus = 0; // set on wield
- item.plus2 = 0; // set on wield
- break;
-
- case SPWPN_VAMPIRES_TOOTH:
- item.base_type = OBJ_WEAPONS;
- item.sub_type = WPN_DAGGER;
- item.plus = 3;
- item.plus2 = 4;
- break;
-
- case SPWPN_STAFF_OF_WUCAD_MU:
- item.base_type = OBJ_WEAPONS;
- item.sub_type = WPN_QUARTERSTAFF;
- item.plus = 0; // set on wield
- item.plus2 = 0; // set on wield
- break;
-
- case SPWPN_SWORD_OF_CEREBOV:
- item.base_type = OBJ_WEAPONS;
- item.sub_type = WPN_GREAT_SWORD;
- item.plus = 6;
- item.plus2 = 6;
- item.colour = YELLOW;
- do_curse_item( item );
- break;
-
- case SPWPN_STAFF_OF_DISPATER:
- item.base_type = OBJ_WEAPONS;
- item.sub_type = WPN_QUARTERSTAFF;
- item.plus = 4;
- item.plus2 = 4;
- item.colour = YELLOW;
- break;
-
- case SPWPN_SCEPTRE_OF_ASMODEUS:
- item.base_type = OBJ_WEAPONS;
- item.sub_type = WPN_QUARTERSTAFF;
- item.plus = 7;
- item.plus2 = 7;
- item.colour = RED;
- break;
-
- default:
- DEBUGSTR( "Trying to create illegal fixed artefact!" );
- return (false);
- }
-
- // If we get here, we've made the artefact
- item.special = which;
- item.quantity = 1;
-
- // Items originally generated in the abyss and not found will be
- // shifted to "lost in abyss", and will only be found there. -- bwr
- set_unique_item_status( OBJ_WEAPONS, which, UNIQ_EXISTS );
-
- return (true);
-}
-
-bool make_item_randart( item_def &item )
-{
- if (item.base_type != OBJ_WEAPONS
- && item.base_type != OBJ_ARMOUR
- && item.base_type != OBJ_JEWELLERY)
- {
- return (false);
- }
-
- item.flags |= ISFLAG_RANDART;
- item.special = (random_int() & RANDART_SEED_MASK);
-
- return (true);
-}
-
-// void make_item_unrandart( int x, int ura_item )
-bool make_item_unrandart( item_def &item, int unrand_index )
-{
- item.base_type = unranddata[unrand_index].ura_cl;
- item.sub_type = unranddata[unrand_index].ura_ty;
- item.plus = unranddata[unrand_index].ura_pl;
- item.plus2 = unranddata[unrand_index].ura_pl2;
- item.colour = unranddata[unrand_index].ura_col;
-
- item.flags |= ISFLAG_UNRANDART;
- item.special = unranddata[ unrand_index ].prpty[ RAP_BRAND ];
-
- if (unranddata[ unrand_index ].prpty[ RAP_CURSED ])
- do_curse_item( item );
-
- set_unrandart_exist( unrand_index, 1 );
-
- return (true);
-} // end make_item_unrandart()
-
-const char *unrandart_descrip( char which_descrip, const item_def &item )
-{
-/* Eventually it would be great to have randomly generated descriptions for
- randarts. */
- struct unrandart_entry *unrand = seekunrandart( item );
-
- return ((which_descrip == 0) ? unrand->spec_descrip1 :
- (which_descrip == 1) ? unrand->spec_descrip2 :
- (which_descrip == 2) ? unrand->spec_descrip3 : "Unknown.");
-
-} // end unrandart_descrip()
-
-void standard_name_weap(unsigned char item_typ, char glorg[ITEMNAME_SIZE])
-{
- strcpy(glorg, (item_typ == WPN_CLUB) ? "club" :
- (item_typ == WPN_MACE) ? "mace" :
- (item_typ == WPN_FLAIL) ? "flail" :
- (item_typ == WPN_KNIFE) ? "knife" :
- (item_typ == WPN_DAGGER) ? "dagger" :
- (item_typ == WPN_MORNINGSTAR) ? "morningstar" :
- (item_typ == WPN_SHORT_SWORD) ? "short sword" :
- (item_typ == WPN_LONG_SWORD) ? "long sword" :
- (item_typ == WPN_GREAT_SWORD) ? "great sword" :
- (item_typ == WPN_SCIMITAR) ? "scimitar" :
- (item_typ == WPN_HAND_AXE) ? "hand axe" :
- (item_typ == WPN_BATTLEAXE) ? "battleaxe" :
- (item_typ == WPN_SPEAR) ? "spear" :
- (item_typ == WPN_TRIDENT) ? "trident" :
- (item_typ == WPN_HALBERD) ? "halberd" :
- (item_typ == WPN_SLING) ? "sling" :
- (item_typ == WPN_BOW) ? "bow" :
- (item_typ == WPN_LONGBOW) ? "longbow" :
- (item_typ == WPN_BLOWGUN) ? "blowgun" :
- (item_typ == WPN_CROSSBOW) ? "crossbow" :
- (item_typ == WPN_HAND_CROSSBOW) ? "hand crossbow" :
- (item_typ == WPN_GLAIVE) ? "glaive" :
- (item_typ == WPN_QUARTERSTAFF) ? "quarterstaff" :
- (item_typ == WPN_SCYTHE) ? "scythe" :
- (item_typ == WPN_EVENINGSTAR) ? "eveningstar" :
- (item_typ == WPN_QUICK_BLADE) ? "quick blade" :
- (item_typ == WPN_KATANA) ? "katana" :
- (item_typ == WPN_LAJATANG) ? "lajatang" :
- (item_typ == WPN_EXECUTIONERS_AXE) ? "executioner's axe" :
- (item_typ == WPN_DOUBLE_SWORD) ? "double sword" :
- (item_typ == WPN_TRIPLE_SWORD) ? "triple sword" :
- (item_typ == WPN_HAMMER) ? "hammer" :
- (item_typ == WPN_ANCUS) ? "ancus" :
- (item_typ == WPN_WHIP) ? "whip" :
- (item_typ == WPN_SABRE) ? "sabre" :
- (item_typ == WPN_DEMON_BLADE) ? "demon blade" :
- (item_typ == WPN_BLESSED_BLADE)? "blessed blade" :
- (item_typ == WPN_LOCHABER_AXE) ? "lochaber axe" :
- (item_typ == WPN_DEMON_WHIP) ? "demon whip" :
- (item_typ == WPN_DEMON_TRIDENT) ? "demon trident" :
- (item_typ == WPN_BROAD_AXE) ? "broad axe" :
- (item_typ == WPN_WAR_AXE) ? "war axe" :
- (item_typ == WPN_SPIKED_FLAIL) ? "spiked flail" :
- (item_typ == WPN_GREAT_MACE) ? "great mace" :
- (item_typ == WPN_DIRE_FLAIL) ? "dire flail" :
- (item_typ == WPN_FALCHION) ? "falchion" :
-
- (item_typ == WPN_GIANT_CLUB)
- ? (SysEnv.board_with_nail ? "two-by-four"
- : "giant club") :
-
- (item_typ == WPN_GIANT_SPIKED_CLUB)
- ? (SysEnv.board_with_nail ? "board with nail"
- : "giant spiked club")
-
- : "unknown weapon");
-} // end standard_name_weap()
-
-void standard_name_armour( const item_def &item, char glorg[ITEMNAME_SIZE] )
-{
- short helm_type;
-
- glorg[0] = '\0';
-
- switch (item.sub_type)
- {
- case ARM_ROBE:
- strcat(glorg, "robe");
- break;
-
- case ARM_LEATHER_ARMOUR:
- strcat(glorg, "leather armour");
- break;
-
- case ARM_RING_MAIL:
- strcat(glorg, "ring mail");
- break;
-
- case ARM_SCALE_MAIL:
- strcat(glorg, "scale mail");
- break;
-
- case ARM_CHAIN_MAIL:
- strcat(glorg, "chain mail");
- break;
-
- case ARM_SPLINT_MAIL:
- strcat(glorg, "splint mail");
- break;
-
- case ARM_BANDED_MAIL:
- strcat(glorg, "banded mail");
- break;
-
- case ARM_PLATE_MAIL:
- strcat(glorg, "plate mail");
- break;
-
- case ARM_SHIELD:
- strcat(glorg, "shield");
- break;
-
- case ARM_CLOAK:
- strcat(glorg, "cloak");
- break;
-
- case ARM_HELMET:
- if (get_helmet_type(item) == THELM_HELM
- || get_helmet_type(item) == THELM_HELMET)
- {
- short dhelm = get_helmet_desc( item );
-
- if (dhelm != THELM_DESC_PLAIN)
- {
- strcat( glorg,
- (dhelm == THELM_DESC_WINGED) ? "winged " :
- (dhelm == THELM_DESC_HORNED) ? "horned " :
- (dhelm == THELM_DESC_CRESTED) ? "crested " :
- (dhelm == THELM_DESC_PLUMED) ? "plumed " :
- (dhelm == THELM_DESC_SPIKED) ? "spiked " :
- (dhelm == THELM_DESC_VISORED) ? "visored " :
- (dhelm == THELM_DESC_JEWELLED) ? "jeweled "
- : "buggy " );
- }
- }
-
- helm_type = get_helmet_type( item );
- if (helm_type == THELM_HELM)
- strcat(glorg, "helm");
- else if (helm_type == THELM_CAP)
- strcat(glorg, "cap");
- else if (helm_type == THELM_WIZARD_HAT)
- strcat(glorg, "wizard's hat");
- else
- strcat(glorg, "helmet");
- break;
-
- case ARM_GLOVES:
- strcat(glorg, "gloves");
- break;
-
- case ARM_NAGA_BARDING:
- strcat(glorg, "naga barding");
- break;
-
- case ARM_CENTAUR_BARDING:
- strcat(glorg, "centaur barding");
- break;
-
- case ARM_BOOTS:
- strcat(glorg, "boots");
- break;
-
- case ARM_BUCKLER:
- strcat(glorg, "buckler");
- break;
-
- case ARM_LARGE_SHIELD:
- strcat(glorg, "large shield");
- break;
-
- case ARM_DRAGON_HIDE:
- strcat(glorg, "dragon hide");
- break;
-
- case ARM_TROLL_HIDE:
- strcat(glorg, "troll hide");
- break;
-
- case ARM_CRYSTAL_PLATE_MAIL:
- strcat(glorg, "crystal plate mail");
- break;
-
- case ARM_DRAGON_ARMOUR:
- strcat(glorg, "dragon armour");
- break;
-
- case ARM_TROLL_LEATHER_ARMOUR:
- strcat(glorg, "troll leather armour");
- break;
-
- case ARM_ICE_DRAGON_HIDE:
- strcat(glorg, "ice dragon hide");
- break;
-
- case ARM_ICE_DRAGON_ARMOUR:
- strcat(glorg, "ice dragon armour");
- break;
-
- case ARM_STEAM_DRAGON_HIDE:
- strcat(glorg, "steam dragon hide");
- break;
-
- case ARM_STEAM_DRAGON_ARMOUR:
- strcat(glorg, "steam dragon armour");
- break;
-
- case ARM_MOTTLED_DRAGON_HIDE:
- strcat(glorg, "mottled dragon hide");
- break;
-
- case ARM_MOTTLED_DRAGON_ARMOUR:
- strcat(glorg, "mottled dragon armour");
- break;
-
- case ARM_STORM_DRAGON_HIDE:
- strcat(glorg, "storm dragon hide");
- break;
-
- case ARM_STORM_DRAGON_ARMOUR:
- strcat(glorg, "storm dragon armour");
- break;
-
- case ARM_GOLD_DRAGON_HIDE:
- strcat(glorg, "gold dragon hide");
- break;
-
- case ARM_GOLD_DRAGON_ARMOUR:
- strcat(glorg, "gold dragon armour");
- break;
-
- case ARM_ANIMAL_SKIN:
- strcat(glorg, "animal skin");
- break;
-
- case ARM_SWAMP_DRAGON_HIDE:
- strcat(glorg, "swamp dragon hide");
- break;
-
- case ARM_SWAMP_DRAGON_ARMOUR:
- strcat(glorg, "swamp dragon armour");
- break;
- }
-} // end standard_name_armour()
diff --git a/stone_soup/crawl-ref/source/randart.h b/stone_soup/crawl-ref/source/randart.h
deleted file mode 100644
index df175e0a62..0000000000
--- a/stone_soup/crawl-ref/source/randart.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * File: randart.cc
- * Summary: Random and unrandom artifact functions.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef RANDART_H
-#define RANDART_H
-
-#include "enum.h"
-#include "externs.h"
-
-// used in files.cc, newgame.cc, randart.cc {dlb}
-#ifdef USE_NEW_UNRANDS
-#define NO_UNRANDARTS 52
-#else // USE_NEW_UNRANDS
-#define NO_UNRANDARTS 14
-#endif // USE_NEW_UNRANDS
-
-#define RA_PROPERTIES 30
-
-// Reserving the upper bits for later expansion/versioning.
-#define RANDART_SEED_MASK 0x00ffffff
-
-
-bool is_random_artefact( const item_def &item );
-bool is_unrandom_artefact( const item_def &item );
-bool is_fixed_artefact( const item_def &item );
-
-int get_unique_item_status( int base_type, int type );
-void set_unique_item_status( int base_type, int type, int status );
-
-/* ***********************************************************************
- * called from: itemname
- * *********************************************************************** */
-const char *randart_armour_name( const item_def &item );
-
-/* ***********************************************************************
- * called from: itemname
- * *********************************************************************** */
-const char *randart_name( const item_def &item );
-
-/* ***********************************************************************
- * called from: itemname
- * *********************************************************************** */
-const char *randart_ring_name( const item_def &item );
-
-/* ***********************************************************************
- * called from: describe
- * *********************************************************************** */
-const char *unrandart_descrip( char which_descrip, const item_def &item );
-
-/* ***********************************************************************
- * called from: files
- * *********************************************************************** */
-char does_unrandart_exist(int whun);
-
-
-/* ***********************************************************************
- * called from: dungeon
- * *********************************************************************** */
-int find_okay_unrandart(unsigned char aclass, unsigned char atype = OBJ_RANDOM);
-
-
-/* ***********************************************************************
- * called from: describe - fight - it_use2 - item_use - player
- * *********************************************************************** */
-void randart_wpn_properties( const item_def &item,
- FixedVector< char, RA_PROPERTIES > &proprt );
-
-int randart_wpn_property( const item_def &item, char prop );
-
-
-/* ***********************************************************************
- * called from: dungeon
- * *********************************************************************** */
-bool make_item_fixed_artefact( item_def &item, bool in_abyss, int which = 0 );
-
-bool make_item_randart( item_def &item );
-bool make_item_unrandart( item_def &item, int unrand_index );
-
-
-/* ***********************************************************************
- * called from: files - newgame
- * *********************************************************************** */
-void set_unrandart_exist(int whun, char is_exist);
-
-
-/* ***********************************************************************
- * called from: itemname
- * *********************************************************************** */
-void standard_name_armour( const item_def &item, char glorg[ITEMNAME_SIZE] );
-
-
-/* ***********************************************************************
- * called from: itemname
- * *********************************************************************** */
-void standard_name_weap(unsigned char item_typ, char glog[ITEMNAME_SIZE]);
-
-
-/* ***********************************************************************
- * called from: items
- * *********************************************************************** */
-int find_unrandart_index(int item_index);
-
-#endif
diff --git a/stone_soup/crawl-ref/source/religion.cc b/stone_soup/crawl-ref/source/religion.cc
deleted file mode 100644
index 964840f972..0000000000
--- a/stone_soup/crawl-ref/source/religion.cc
+++ /dev/null
@@ -1,2762 +0,0 @@
-/*
- * File: religion.cc
- * Summary: Misc religion related functions.
- * Written by: Linley Henzell
- *
- * Modified for Crawl Reference by $Author$ on $Date$
- *
- * Change History (most recent first):
- *
- *
- * <7> 11jan2001 gdl added M. Valvoda's changes to
- * god_colour() and god_name()
- * <6> 06-Mar-2000 bwr added penance, gift_timeout,
- * divine_retribution(), god_speaks()
- * <5> 11/15/99 cdl Fixed Daniel's yellow Xom patch :)
- * Xom will sometimes answer prayers
- * <4> 10/11/99 BCR Added Daniel's yellow Xom patch
- * <3> 6/13/99 BWR Vehumet book giving code.
- * <2> 5/20/99 BWR Added screen redraws
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "religion.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "externs.h"
-
-#include "abl-show.h"
-#include "beam.h"
-#include "debug.h"
-#include "decks.h"
-#include "describe.h"
-#include "dungeon.h"
-#include "effects.h"
-#include "food.h"
-#include "it_use2.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "item_use.h"
-#include "items.h"
-#include "misc.h"
-#include "monplace.h"
-#include "mutation.h"
-#include "newgame.h"
-#include "ouch.h"
-#include "player.h"
-#include "randart.h"
-#include "shopping.h"
-#include "skills2.h"
-#include "spells1.h"
-#include "spells2.h"
-#include "spells3.h"
-#include "spl-cast.h"
-#include "stuff.h"
-#include "wpn-misc.h"
-
-const char *sacrifice[] = {
- " glows silver and disappears.",
- " glows a brilliant golden colour and disappears.",
- " rots away in an instant.",
- " crumbles to dust.",
- " is eaten by a bug.", /* Xom - no sacrifices */
- " explodes into nothingness.",
- " is consumed in a burst of flame.",
- " is consumed in a roaring column of flame.",
- " glows faintly for a moment, then is gone.",
- " is consumed in a roaring column of flame.",
- " glows with a rainbow of weird colours and disappears.",
- " evaporates."
-};
-
-void altar_prayer(void);
-void dec_penance(int god, int val);
-void divine_retribution(int god);
-void inc_penance(int god, int val);
-void inc_penance(int val);
-
-void dec_penance(int god, int val)
-{
- if (you.penance[god] > 0)
- {
- if (you.penance[god] <= val)
- {
- simple_god_message(" seems mollified.", god);
- you.penance[god] = 0;
- }
- else
- you.penance[god] -= val;
- }
-} // end dec_penance()
-
-void dec_penance(int val)
-{
- dec_penance(you.religion, val);
-} // end dec_penance()
-
-void inc_penance(int god, int val)
-{
- if ((int) you.penance[god] + val > 200)
- you.penance[god] = 200;
- else
- you.penance[god] += val;
-} // end inc_penance()
-
-void inc_penance(int val)
-{
- inc_penance(you.religion, val);
-} // end inc_penance()
-
-static void inc_gift_timeout(int val)
-{
- if ((int) you.gift_timeout + val > 200)
- you.gift_timeout = 200;
- else
- you.gift_timeout += val;
-} // end inc_gift_timeout()
-
-static int random_undead_servant(int religion)
-{
- // error trapping {dlb}
- int thing_called = MONS_PROGRAM_BUG;
- int temp_rand = random2(100);
- thing_called = ((temp_rand > 66) ? MONS_WRAITH : // 33%
- (temp_rand > 52) ? MONS_WIGHT : // 12%
- (temp_rand > 40) ? MONS_SPECTRAL_WARRIOR : // 16%
- (temp_rand > 31) ? MONS_ROTTING_HULK : // 9%
- (temp_rand > 23) ? MONS_SKELETAL_WARRIOR : // 8%
- (temp_rand > 16) ? MONS_VAMPIRE : // 7%
- (temp_rand > 10) ? MONS_GHOUL : // 6%
- (temp_rand > 4) ? MONS_MUMMY // 6%
- : MONS_FLAYED_GHOST); // 5%
- return (thing_called);
-}
-
-void pray(void)
-{
- unsigned char was_praying = you.duration[DUR_PRAYER];
- bool success = false;
-
- if (silenced(you.x_pos, you.y_pos))
- {
- mpr("You are unable to make a sound!");
- return;
- }
-
- // all prayers take time
- you.turn_is_over = 1;
-
- if (you.religion != GOD_NO_GOD
- && grd[you.x_pos][you.y_pos] == 179 + you.religion)
- {
- altar_prayer();
- }
- else if (grd[you.x_pos][you.y_pos] >= 180
- && grd[you.x_pos][you.y_pos] <= 199)
- {
- if (you.species == SP_DEMIGOD)
- {
- mpr("Sorry, a being of your status cannot worship here.");
- return;
- }
- god_pitch(grd[you.x_pos][you.y_pos] - 179);
- return;
- }
-
- if (you.religion == GOD_NO_GOD)
- {
- strcpy(info, "You spend a moment contemplating the meaning of ");
-
- if (you.is_undead)
- strcat(info, "un");
-
- strcat(info, "life.");
- mpr(info);
- return;
- }
- else if (you.religion == GOD_XOM)
- {
- if (one_chance_in(100))
- {
- // Every now and then, Xom listens
- // This is for flavour, not effect, so praying should not be
- // encouraged.
-
- // Xom is nicer to experienced players
- bool nice = (27 <= random2( 27 + you.experience_level ));
-
- // and he's not very nice even then
- int sever = (nice) ? random2( random2( you.experience_level ) )
- : you.experience_level;
-
- // bad results are enforced, good are not
- bool force = !nice;
-
- Xom_acts( nice, 1 + sever, force );
- }
- else
- mpr("Xom ignores you.");
-
- return;
- }
-
- strcpy( info, "You offer a prayer to " );
- strcat( info, god_name( you.religion ) );
- strcat( info, "." );
- mpr(info);
-
- you.duration[DUR_PRAYER] = 9 + (random2(you.piety) / 20)
- + (random2(you.piety) / 20);
-
- if (player_under_penance())
- simple_god_message(" demands penance!");
- else
- {
- strcpy(info, god_name(you.religion));
- strcat(info, " is ");
-
- strcat(info, (you.piety > 130) ? "exalted by your worship" :
- (you.piety > 100) ? "extremely pleased with you" :
- (you.piety > 70) ? "greatly pleased with you" :
- (you.piety > 40) ? "most pleased with you" :
- (you.piety > 20) ? "pleased with you" :
- (you.piety > 5) ? "noncommittal"
- : "displeased");
-
- strcat(info, ".");
- god_speaks(you.religion, info);
-
- if (you.piety > 130)
- you.duration[DUR_PRAYER] *= 3;
- else if (you.piety > 70)
- you.duration[DUR_PRAYER] *= 2;
- }
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "piety: %d", you.piety );
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- // Consider a gift if we don't have a timeout and weren't
- // already praying when we prayed.
- if (!you.penance[you.religion] && !you.gift_timeout && !was_praying)
- {
- // Remember to check for water/lava
- switch (you.religion)
- {
- default:
- break;
-
- case GOD_ZIN:
- //jmf: "good" god will sometimes feed you (a la Nethack)
- if (you.hunger_state == HS_STARVING
- && random2(250) <= you.piety)
- {
- god_speaks(you.religion, "Your stomach feels content.");
- set_hunger(6000, true);
- lose_piety(5 + random2avg(10, 2));
- inc_gift_timeout(30 + random2avg(10, 2));
- }
- break;
-
- case GOD_NEMELEX_XOBEH:
- if (random2(200) <= you.piety
- && (!you.attribute[ATTR_CARD_TABLE] || one_chance_in(3))
- && !you.attribute[ATTR_CARD_COUNTDOWN]
- && !grid_destroys_items(grd[you.x_pos][you.y_pos]))
- {
- int thing_created = NON_ITEM;
- unsigned char gift_type = MISC_DECK_OF_TRICKS;
-
- if (!you.attribute[ATTR_CARD_TABLE])
- {
- thing_created = items( 1, OBJ_MISCELLANY,
- MISC_PORTABLE_ALTAR_OF_NEMELEX,
- true, 1, 250 );
-
- if (thing_created != NON_ITEM)
- you.attribute[ATTR_CARD_TABLE] = 1;
- }
- else
- {
- if (random2(200) <= you.piety && one_chance_in(4))
- gift_type = MISC_DECK_OF_SUMMONINGS;
- if (random2(200) <= you.piety && coinflip())
- gift_type = MISC_DECK_OF_WONDERS;
- if (random2(200) <= you.piety && one_chance_in(4))
- gift_type = MISC_DECK_OF_POWER;
-
- thing_created = items( 1, OBJ_MISCELLANY, gift_type,
- true, 1, 250 );
- }
-
- if (thing_created != NON_ITEM)
- {
- move_item_to_grid( &thing_created, you.x_pos, you.y_pos );
- origin_acquired(mitm[thing_created], you.religion);
-
- simple_god_message(" grants you a gift!");
- more();
- canned_msg(MSG_SOMETHING_APPEARS);
-
- you.attribute[ATTR_CARD_COUNTDOWN] = 10;
- inc_gift_timeout(5 + random2avg(9, 2));
- you.num_gifts[you.religion]++;
- }
- }
- break;
-
- case GOD_OKAWARU:
- if (you.piety > 80
- && random2( you.piety ) > 70
- && !grid_destroys_items( grd[you.x_pos][you.y_pos] )
- && one_chance_in(4)
- && you.skills[ best_skill(SK_SLINGS, SK_RANGED_COMBAT) ] >= 3)
- {
- success = acquirement( OBJ_MISSILES, you.religion );
- if (success)
- {
- simple_god_message( " has granted you a gift!" );
- more();
-
- inc_gift_timeout( 4 + roll_dice(2,4) );
- you.num_gifts[ you.religion ]++;
- }
- break;
- }
- // intentional fall through
-
- case GOD_TROG:
- if (you.piety > 130
- && random2(you.piety) > 120
- && !grid_destroys_items(grd[you.x_pos][you.y_pos])
- && one_chance_in(4))
- {
- if (you.religion == GOD_TROG
- || (you.religion == GOD_OKAWARU && coinflip()))
- {
- success = acquirement(OBJ_WEAPONS, you.religion);
- }
- else
- {
- success = acquirement(OBJ_ARMOUR, you.religion);
- }
-
- if (success)
- {
- simple_god_message(" has granted you a gift!");
- more();
-
- inc_gift_timeout(30 + random2avg(19, 2));
- you.num_gifts[ you.religion ]++;
- }
- }
- break;
-
- case GOD_YREDELEMNUL:
- if (random2(you.piety) > 80 && one_chance_in(5))
- {
- int thing_called = random_undead_servant(GOD_YREDELEMNUL);
- if (create_monster( thing_called, 0, BEH_FRIENDLY,
- you.x_pos, you.y_pos,
- you.pet_target, 250 ) != -1)
- {
- simple_god_message(" grants you an undead servant!");
- more();
- inc_gift_timeout(4 + random2avg(7, 2));
- you.num_gifts[you.religion]++;
- }
- }
- break;
-
- case GOD_KIKUBAAQUDGHA:
- case GOD_SIF_MUNA:
- case GOD_VEHUMET:
- if (you.piety > 160 && random2(you.piety) > 100)
- {
- unsigned int gift = NUM_BOOKS;
-
- switch (you.religion)
- {
- case GOD_KIKUBAAQUDGHA: // gives death books
- if (!you.had_book[BOOK_NECROMANCY])
- gift = BOOK_NECROMANCY;
- else if (!you.had_book[BOOK_DEATH])
- gift = BOOK_DEATH;
- else if (!you.had_book[BOOK_UNLIFE])
- gift = BOOK_UNLIFE;
- else if (!you.had_book[BOOK_NECRONOMICON])
- gift = BOOK_NECRONOMICON;
- break;
-
- case GOD_SIF_MUNA:
- gift = OBJ_RANDOM; // Sif Muna - gives any
- break;
-
- // Vehumet - gives conj/summ. books (higher skill first)
- case GOD_VEHUMET:
- if (!you.had_book[BOOK_CONJURATIONS_I])
- gift = give_first_conjuration_book();
- else if (!you.had_book[BOOK_POWER])
- gift = BOOK_POWER;
- else if (!you.had_book[BOOK_ANNIHILATIONS])
- gift = BOOK_ANNIHILATIONS; // conj books
-
- if (you.skills[SK_CONJURATIONS] <
- you.skills[SK_SUMMONINGS]
- || gift == NUM_BOOKS)
- {
- if (!you.had_book[BOOK_CALLINGS])
- gift = BOOK_CALLINGS;
- else if (!you.had_book[BOOK_SUMMONINGS])
- gift = BOOK_SUMMONINGS;
- else if (!you.had_book[BOOK_DEMONOLOGY])
- gift = BOOK_DEMONOLOGY; // summoning bks
- }
- break;
- }
-
- if (gift != NUM_BOOKS
- && (grd[you.x_pos][you.y_pos] != DNGN_LAVA
- && grd[you.x_pos][you.y_pos] != DNGN_DEEP_WATER))
- {
- if (gift == OBJ_RANDOM)
- success = acquirement(OBJ_BOOKS, you.religion);
- else
- {
- int thing_created = items(1, OBJ_BOOKS, gift, true, 1, 250);
- if (thing_created == NON_ITEM)
- return;
-
- move_item_to_grid( &thing_created, you.x_pos, you.y_pos );
-
- if (thing_created != NON_ITEM)
- {
- success = true;
- origin_acquired(mitm[thing_created], you.religion);
- }
- }
-
- if (success)
- {
- simple_god_message(" has granted you a gift!");
- more();
-
- inc_gift_timeout(40 + random2avg(19, 2));
- you.num_gifts[ you.religion ]++;
- }
-
- // Vehumet gives books less readily
- if (you.religion == GOD_VEHUMET && success)
- inc_gift_timeout(10 + random2(10));
- } // end of giving book
- } // end of book gods
- break;
- }
- } // end of gift giving
-} // end pray()
-
-char *god_name( int which_god, bool long_name ) // mv - rewritten
-{
- static char godname_buff[80];
-
- switch (which_god)
- {
- case GOD_NO_GOD:
- sprintf(godname_buff, "No God");
- break;
- case GOD_ZIN:
- sprintf(godname_buff, "Zin%s", long_name ? " the Law-Giver" : "");
- break;
- case GOD_SHINING_ONE:
- sprintf(godname_buff, "The Shining One");
- break;
- case GOD_KIKUBAAQUDGHA:
- strcpy(godname_buff, "Kikubaaqudgha");
- break;
- case GOD_YREDELEMNUL:
- sprintf(godname_buff, "Yredelemnul%s", long_name ? " the Dark" : "");
- break;
- case GOD_XOM:
- strcpy(godname_buff, "Xom");
- if (long_name)
- {
- strcat(godname_buff, " ");
- switch(random2(1000))
- {
- default:
- strcat(godname_buff, "of Chaos");
- break;
- case 1:
- strcat(godname_buff, "the Random");
- if (coinflip())
- strcat(godname_buff, coinflip()?"master":" Number God");
- break;
- case 2:
- strcat(godname_buff, "the Tricky");
- break;
- case 3:
- sprintf( godname_buff, "Xom the %sredictible", coinflip() ? "Less-P"
- : "Unp" );
- break;
- case 4:
- strcat(godname_buff, "of Many Doors");
- break;
- case 5:
- strcat(godname_buff, "the Capricious");
- break;
- case 6:
- strcat(godname_buff, "of ");
- strcat(godname_buff, coinflip() ? "Bloodstained" : "Enforced");
- strcat(godname_buff, " Whimsey");
- break;
- case 7:
- strcat(godname_buff, "\"What was your username?\" *clickity-click*");
- break;
- case 8:
- strcat(godname_buff, "of Bone-Dry Humour");
- break;
- case 9:
- strcat(godname_buff, "of ");
- strcat(godname_buff, coinflip() ? "Malevolent" : "Malicious");
- strcat(godname_buff, " Giggling");
- break;
- case 10:
- strcat(godname_buff, "the Psycho");
- strcat(godname_buff, coinflip() ? "tic" : "path");
- break;
- case 11:
- strcat(godname_buff, "of ");
- switch(random2(5))
- {
- case 0: strcat(godname_buff, "Gnomic"); break;
- case 1: strcat(godname_buff, "Ineffable"); break;
- case 2: strcat(godname_buff, "Fickle"); break;
- case 3: strcat(godname_buff, "Swiftly Tilting"); break;
- case 4: strcat(godname_buff, "Unknown"); break;
- }
- strcat(godname_buff, " Intent");
- if (coinflip())
- strcat(godname_buff, "ion");
- break;
- case 12:
- sprintf(godname_buff, "The Xom-Meister");
- if (coinflip())
- strcat(godname_buff, ", Xom-a-lom-a-ding-dong");
- else if (coinflip())
- strcat(godname_buff, ", Xom-o-Rama");
- else if (coinflip())
- strcat(godname_buff, ", Xom-Xom-bo-Bom, Banana-Fana-fo-Fom");
- break;
- case 13:
- strcat(godname_buff, "the Begetter of ");
- strcat(godname_buff, coinflip() ? "Turbulence" : "Discontinuities");
- break;
- }
- }
- break;
- case GOD_VEHUMET:
- strcpy(godname_buff, "Vehumet");
- break;
- case GOD_OKAWARU:
- sprintf(godname_buff, "%sOkawaru", long_name ? "Warmaster " : "");
- break;
- case GOD_MAKHLEB:
- sprintf(godname_buff, "Makhleb%s", long_name ? " the Destroyer" : "");
- break;
- case GOD_SIF_MUNA:
- sprintf(godname_buff, "Sif Muna%s", long_name ? " the Loreminder" : "");
- break;
- case GOD_TROG:
- sprintf(godname_buff, "Trog%s", long_name ? " the Wrathful" : "");
- break;
- case GOD_NEMELEX_XOBEH:
- strcpy(godname_buff, "Nemelex Xobeh");
- break;
- case GOD_ELYVILON:
- sprintf(godname_buff, "Elyvilon%s", long_name ? " the Healer" : "");
- break;
- default:
- sprintf(godname_buff, "The Buggy One (%d)", which_god);
- }
-
- return (godname_buff);
-} // end god_name()
-
-void god_speaks( int god, const char *mesg )
-{
- mpr( mesg, MSGCH_GOD, god );
-} // end god_speaks()
-
-void Xom_acts(bool niceness, int sever, bool force_sever)
-{
- // niceness = false - bad, true - nice
- int temp_rand; // probability determination {dlb}
- bool done_bad = false; // flag to clarify logic {dlb}
- bool done_good = false; // flag to clarify logic {dlb}
-
- struct bolt beam;
-
- if (sever < 1)
- sever = 1;
-
- if (!force_sever)
- sever = random2(sever);
-
- if (sever == 0)
- return;
-
- okay_try_again:
-
- if (!niceness || one_chance_in(3))
- {
- // begin "Bad Things"
- done_bad = false;
-
- // this should always be first - it will often be called
- // deliberately, with a low sever value
- if (random2(sever) <= 2)
- {
- temp_rand = random2(4);
-
- god_speaks(GOD_XOM,
- (temp_rand == 0) ? "Xom notices you." :
- (temp_rand == 1) ? "Xom's attention turns to you for a moment.":
- (temp_rand == 2) ? "Xom's power touches on you for a moment."
- : "You hear Xom's maniacal laughter.");
-
- miscast_effect( SPTYP_RANDOM, 5 + random2(10), random2(100), 0,
- "the capriciousness of Xom" );
-
- done_bad = true;
- }
- else if (random2(sever) <= 2)
- {
- temp_rand = random2(4);
-
- god_speaks(GOD_XOM,
- (temp_rand == 0) ? "\"Suffer!\"" :
- (temp_rand == 1) ? "Xom's malign attention turns to you for a moment." :
- (temp_rand == 2) ? "Xom's power touches on you for a moment."
- : "You hear Xom's maniacal laughter.");
-
- lose_stat(STAT_RANDOM, 1 + random2(3), true);
-
- done_bad = true;
- }
- else if (random2(sever) <= 2)
- {
- temp_rand = random2(4);
-
- god_speaks(GOD_XOM,
- (temp_rand == 0) ? "Xom notices you." :
- (temp_rand == 1) ? "Xom's attention turns to you for a moment.":
- (temp_rand == 2) ? "Xom's power touches on you for a moment."
- : "You hear Xom's maniacal laughter.");
-
- miscast_effect( SPTYP_RANDOM, 5 + random2(15), random2(250), 0,
- "the capriciousness of Xom" );
-
- done_bad = true;
- }
- else if (!you.is_undead && random2(sever) <= 3)
- {
- temp_rand = random2(4);
-
- god_speaks(GOD_XOM,
- (temp_rand == 0) ? "\"You need some minor adjustments, mortal!\"" :
- (temp_rand == 1) ? "\"Let me alter your pitiful body.\"" :
- (temp_rand == 2) ? "Xom's power touches on you for a moment."
- : "You hear Xom's maniacal laughter.");
-
- mpr("Your body is suffused with distortional energy.");
-
- set_hp(1 + random2(you.hp), false);
- deflate_hp(you.hp_max / 2, true);
-
- bool failMsg = true;
- for (int i = 0; i < 4; i++)
- {
- if (!mutate(100, failMsg))
- failMsg = false;
- }
-
- done_bad = true;
- }
- else if (!you.is_undead && random2(sever) <= 3)
- {
- temp_rand = random2(4);
-
- god_speaks(GOD_XOM,
- (temp_rand == 0) ? "\"You have displeased me, mortal.\"" :
- (temp_rand == 1) ? "\"You have grown too confident for your meagre worth.\"" :
- (temp_rand == 2) ? "Xom's power touches on you for a moment."
- : "You hear Xom's maniacal laughter.");
-
- if (one_chance_in(4))
- {
- drain_exp();
- if (random2(sever) > 3)
- drain_exp();
- if (random2(sever) > 3)
- drain_exp();
- }
- else
- {
- mpr("A wave of agony tears through your body!");
- set_hp(1 + (you.hp / 2), false);
- }
-
- done_bad = true;
- }
- else if (random2(sever) <= 3)
- {
- temp_rand = random2(4);
-
- god_speaks(GOD_XOM,
- (temp_rand == 0) ? "\"Time to have some fun!\"" :
- (temp_rand == 1) ? "\"Fight to survive, mortal.\"" :
- (temp_rand == 2) ? "\"Let's see if it's strong enough to survive yet.\""
- : "You hear Xom's maniacal laughter.");
-
- if (one_chance_in(4))
- dancing_weapon(100, true); // nasty, but fun
- else
- {
- create_monster(MONS_NEQOXEC + random2(5), ENCH_ABJ_III,
- BEH_HOSTILE, you.x_pos, you.y_pos, MHITNOT, 250);
-
- if (one_chance_in(3))
- create_monster(MONS_NEQOXEC + random2(5), ENCH_ABJ_III,
- BEH_HOSTILE, you.x_pos, you.y_pos, MHITNOT, 250);
-
- if (one_chance_in(4))
- create_monster(MONS_NEQOXEC + random2(5), ENCH_ABJ_III,
- BEH_HOSTILE, you.x_pos, you.y_pos, MHITNOT, 250);
-
- if (one_chance_in(3))
- create_monster(MONS_HELLION + random2(10), ENCH_ABJ_III,
- BEH_HOSTILE, you.x_pos, you.y_pos, MHITNOT, 250);
-
- if (one_chance_in(4))
- create_monster(MONS_HELLION + random2(10), ENCH_ABJ_III,
- BEH_HOSTILE, you.x_pos, you.y_pos, MHITNOT, 250);
- }
-
- done_bad = true;
- }
- else if (you.your_level == 0)
- {
- // this should remain the last possible outcome {dlb}
- temp_rand = random2(3);
-
- god_speaks(GOD_XOM,
- (temp_rand == 0) ? "\"You have grown too comfortable in your little world, mortal!\"" :
- (temp_rand == 1) ? "Xom casts you into the Abyss!"
- : "The world seems to spin as Xom's maniacal laughter rings in your ears.");
-
- banished(DNGN_ENTER_ABYSS);
-
- done_bad = true;
- }
- } // end "Bad Things"
- else
- {
- // begin "Good Things"
- done_good = false;
-
-// Okay, now for the nicer stuff (note: these things are not necessarily nice):
- if (random2(sever) <= 2)
- {
- temp_rand = random2(4);
-
- god_speaks(GOD_XOM,
- (temp_rand == 0) ? "\"Go forth and destroy!\"" :
- (temp_rand == 1) ? "\"Go forth and destroy, mortal!\"" :
- (temp_rand == 2) ? "Xom grants you a minor favour."
- : "Xom smiles on you.");
-
- switch (random2(7))
- {
- case 0:
- potion_effect(POT_HEALING, 150);
- break;
- case 1:
- potion_effect(POT_HEAL_WOUNDS, 150);
- break;
- case 2:
- potion_effect(POT_SPEED, 150);
- break;
- case 3:
- potion_effect(POT_MIGHT, 150);
- break;
- case 4:
- potion_effect(POT_INVISIBILITY, 150);
- break;
- case 5:
- if (one_chance_in(6))
- potion_effect(POT_EXPERIENCE, 150);
- else
- {
- you.berserk_penalty = NO_BERSERK_PENALTY;
- potion_effect(POT_BERSERK_RAGE, 150);
- }
- break;
- case 6:
- you.berserk_penalty = NO_BERSERK_PENALTY;
- potion_effect(POT_BERSERK_RAGE, 150);
- break;
- }
-
- done_good = true;
- }
- else if (random2(sever) <= 4)
- {
- temp_rand = random2(3);
-
- god_speaks(GOD_XOM,
- (temp_rand == 0) ? "\"Serve the mortal, my children!\"" :
- (temp_rand == 1) ? "Xom grants you some temporary aid."
- : "Xom opens a gate.");
-
- create_monster( MONS_NEQOXEC + random2(5), ENCH_ABJ_III,
- BEH_FRIENDLY, you.x_pos, you.y_pos,
- you.pet_target, 250 );
-
- create_monster( MONS_NEQOXEC + random2(5), ENCH_ABJ_III,
- BEH_FRIENDLY, you.x_pos, you.y_pos,
- you.pet_target, 250 );
-
- if (random2( you.experience_level ) >= 8)
- {
- create_monster( MONS_NEQOXEC + random2(5), ENCH_ABJ_III,
- BEH_FRIENDLY, you.x_pos, you.y_pos,
- you.pet_target, 250 );
- }
-
- if (random2( you.experience_level ) >= 8)
- {
- create_monster( MONS_HELLION + random2(10), ENCH_ABJ_III,
- BEH_FRIENDLY, you.x_pos, you.y_pos,
- you.pet_target, 250 );
- }
-
- if (random2( you.experience_level ) >= 8)
- {
- create_monster( MONS_HELLION + random2(10), ENCH_ABJ_III,
- BEH_FRIENDLY, you.x_pos, you.y_pos,
- you.pet_target, 250 );
- }
-
- done_good = true;
- }
- else if (random2(sever) <= 3)
- {
- temp_rand = random2(3);
-
- god_speaks(GOD_XOM,
- (temp_rand == 0) ? "\"Take this token of my esteem.\"" :
- (temp_rand == 1) ? "Xom grants you a gift!"
- : "Xom's generous nature manifests itself.");
-
- if (grd[you.x_pos][you.y_pos] == DNGN_LAVA
- || grd[you.x_pos][you.y_pos] == DNGN_DEEP_WATER)
- {
- // How unfortunate. I'll bet Xom feels sorry for you.
- mpr("You hear a splash.");
- }
- else
- {
- int thing_created = items(1, OBJ_RANDOM, OBJ_RANDOM, true,
- you.experience_level * 3, 250);
-
- move_item_to_grid( &thing_created, you.x_pos, you.y_pos );
-
- if (thing_created != NON_ITEM)
- {
- origin_acquired(mitm[thing_created], GOD_XOM);
- canned_msg(MSG_SOMETHING_APPEARS);
- more();
- }
- }
-
- done_good = true;
- }
- else if (random2(sever) <= 4)
- {
- const int demon = (random2(you.experience_level) < 6)
- ? MONS_WHITE_IMP + random2(5)
- : MONS_NEQOXEC + random2(5);
-
- if (create_monster( demon, 0, BEH_FRIENDLY, you.x_pos, you.y_pos,
- you.pet_target, 250 ) != -1)
- {
- temp_rand = random2(3);
-
- god_speaks(GOD_XOM,
- (temp_rand == 0) ? "\"Serve the mortal, my child!\"" :
- (temp_rand == 1) ? "Xom grants you a demonic servitor."
- : "Xom opens a gate.");
- }
-
- done_good = true; // well, for Xom, trying == doing {dlb}
- }
- else if (random2(sever) <= 4)
- {
- temp_rand = random2(4);
-
- god_speaks(GOD_XOM,
- (temp_rand == 0) ? "\"Take this instrument of destruction!\"" :
- (temp_rand == 1) ? "\"You have earned yourself a gift.\"" :
- (temp_rand == 2) ? "Xom grants you an implement of death."
- : "Xom smiles on you.");
-
- if (acquirement(OBJ_WEAPONS, GOD_XOM))
- more();
-
- done_good = true;
- }
- else if (!you.is_undead && random2(sever) <= 5)
- {
- temp_rand = random2(4);
-
- god_speaks(GOD_XOM,
- (temp_rand == 0) ? "\"You need some minor adjustments, mortal!\"" :
- (temp_rand == 1) ? "\"Let me alter your pitiful body.\"" :
- (temp_rand == 2) ? "Xom's power touches on you for a moment."
- : "You hear Xom's maniacal chuckling.");
-
- mpr("Your body is suffused with distortional energy.");
-
- set_hp(1 + random2(you.hp), false);
- deflate_hp(you.hp_max / 2, true);
-
- if (coinflip() || !give_cosmetic_mutation())
- give_good_mutation();
-
- done_good = true;
- }
- else if (random2(sever) <= 2)
- {
- // this should remain the last possible outcome {dlb}
- if (!one_chance_in(8))
- you.attribute[ATTR_DIVINE_LIGHTNING_PROTECTION] = 1;
-
- god_speaks(GOD_XOM, "The area is suffused with divine lightning!");
-
- beam.beam_source = NON_MONSTER;
- beam.type = SYM_BURST;
- beam.damage = dice_def( 3, 30 );
- beam.flavour = BEAM_ELECTRICITY;
- beam.target_x = you.x_pos;
- beam.target_y = you.y_pos;
- strcpy(beam.beam_name, "blast of lightning");
- beam.colour = LIGHTCYAN;
- beam.thrower = KILL_MISC;
- beam.aux_source = "Xom's lightning strike";
- beam.ex_size = 2;
- beam.is_tracer = false;
- beam.is_explosion = true;
-
- explosion(beam);
-
- if (you.attribute[ATTR_DIVINE_LIGHTNING_PROTECTION] == 1)
- {
- mpr("Your divine protection wanes.");
- you.attribute[ATTR_DIVINE_LIGHTNING_PROTECTION] = 0;
- }
-
- done_good = true;
- }
- } // end "Good Things"
-
- if (done_bad || done_good || one_chance_in(4))
- return;
- else
- goto okay_try_again;
-} // end Xom_acts()
-
-// This function is the merger of done_good() and naughty().
-// Returns true if god was interested (good or bad) in conduct.
-bool did_god_conduct( int thing_done, int level )
-{
- bool ret = false;
- int piety_change = 0;
- int penance = 0;
-
- if (you.religion == GOD_NO_GOD || you.religion == GOD_XOM)
- return (false);
-
- switch (thing_done)
- {
- case DID_NECROMANCY:
- case DID_UNHOLY:
- case DID_ATTACK_HOLY:
- switch (you.religion)
- {
- case GOD_ZIN:
- case GOD_SHINING_ONE:
- case GOD_ELYVILON:
- piety_change = -level;
- penance = level * ((you.religion == GOD_ZIN) ? 2 : 1);
- ret = true;
- break;
- }
- break;
-
- case DID_STABBING:
- case DID_POISON:
- if (you.religion == GOD_SHINING_ONE)
- {
- ret = true;
- piety_change = -level;
- penance = level * 2;
- }
- break;
-
- case DID_ATTACK_FRIEND:
- switch (you.religion)
- {
- case GOD_ZIN:
- case GOD_SHINING_ONE:
- case GOD_ELYVILON:
- case GOD_OKAWARU:
- piety_change = -level;
- penance = level * 3;
- ret = true;
- break;
- }
- break;
-
- case DID_FRIEND_DIES:
- switch (you.religion)
- {
- case GOD_ELYVILON:
- penance = level; // healer god cares more about this
- // fall through
- case GOD_ZIN:
- case GOD_SHINING_ONE:
- case GOD_OKAWARU:
- piety_change = -level;
- ret = true;
- break;
- }
- break;
-
- case DID_DEDICATED_BUTCHERY: // aka field sacrifice
- switch (you.religion)
- {
- case GOD_ELYVILON:
- simple_god_message(" did not appreciate that!");
- ret = true;
- piety_change = -10;
- penance = 10;
- break;
-
- case GOD_OKAWARU:
- case GOD_MAKHLEB:
- case GOD_TROG:
- simple_god_message(" accepts your offering.");
- ret = true;
- if (random2(level + 10) > 5)
- piety_change = 1;
- break;
- }
- break;
-
- case DID_DEDICATED_KILL_LIVING:
- switch (you.religion)
- {
- case GOD_ELYVILON:
- simple_god_message(" did not appreciate that!");
- ret = true;
- piety_change = -level;
- penance = level * 2;
- break;
-
- case GOD_KIKUBAAQUDGHA:
- case GOD_YREDELEMNUL:
- case GOD_OKAWARU:
- case GOD_VEHUMET:
- case GOD_MAKHLEB:
- case GOD_TROG:
- simple_god_message(" accepts your kill.");
- ret = true;
- if (random2(level + 18) > 5)
- piety_change = 1;
- break;
- }
- break;
-
- case DID_DEDICATED_KILL_UNDEAD:
- switch (you.religion)
- {
- case GOD_ZIN:
- case GOD_SHINING_ONE:
- case GOD_OKAWARU:
- case GOD_VEHUMET:
- case GOD_MAKHLEB:
- simple_god_message(" accepts your kill.");
- ret = true;
- if (random2(level + 18) > 4)
- piety_change = 1;
- break;
- }
- break;
-
- case DID_DEDICATED_KILL_DEMON:
- switch (you.religion)
- {
- case GOD_ZIN:
- case GOD_SHINING_ONE:
- case GOD_OKAWARU:
- simple_god_message(" accepts your kill.");
- ret = true;
- if (random2(level + 18) > 3)
- piety_change = 1;
- break;
- }
- break;
-
- case DID_DEDICATED_KILL_WIZARD:
- if (you.religion == GOD_TROG)
- {
- // hooking this up, but is it too good?
- // enjoy it while you can -- bwr
- simple_god_message(" appreciates your killing of a magic user.");
- ret = true;
- if (random2(level + 10) > 5)
- piety_change = 1;
- }
- break;
-
- // Note that Angel deaths are special, they are always noticed...
- // if you or any friendly kills one you'll get the credit or the blame.
- case DID_ANGEL_KILLED_BY_SERVANT:
- case DID_KILL_ANGEL:
- switch (you.religion)
- {
- case GOD_ZIN:
- case GOD_SHINING_ONE:
- case GOD_ELYVILON:
- level *= 3;
- piety_change = -level;
- penance = level * ((you.religion == GOD_ZIN) ? 2 : 1);
- ret = true;
- break;
-
- case GOD_KIKUBAAQUDGHA:
- case GOD_YREDELEMNUL:
- case GOD_MAKHLEB:
- snprintf( info, INFO_SIZE, " accepts your %skill.",
- (thing_done == DID_KILL_ANGEL) ? "" : "collateral " );
-
- simple_god_message( info );
-
- ret = true;
- if (random2(level + 18) > 2)
- piety_change = 1;
- break;
- }
- break;
-
- // Undead slave is any friendly undead... Kiku and Yred pay attention
- // to the undead and both like the death of living things.
- case DID_LIVING_KILLED_BY_UNDEAD_SLAVE:
- switch (you.religion)
- {
- case GOD_KIKUBAAQUDGHA:
- case GOD_YREDELEMNUL:
- simple_god_message(" accepts your slave's kill.");
- ret = true;
- if (random2(level + 10) > 5)
- piety_change = 1;
- break;
- }
- break;
-
- // Servants are currently any friendly monster under Vehumet, or
- // any god given pet for everyone else (excluding undead which are
- // handled above).
- case DID_LIVING_KILLED_BY_SERVANT:
- switch (you.religion)
- {
- case GOD_KIKUBAAQUDGHA: // note: reapers aren't undead
- case GOD_VEHUMET:
- case GOD_MAKHLEB:
- simple_god_message(" accepts your collateral kill.");
- ret = true;
- if (random2(level + 10) > 5)
- piety_change = 1;
- break;
- }
- break;
-
- case DID_UNDEAD_KILLED_BY_SERVANT:
- switch (you.religion)
- {
- case GOD_ZIN:
- case GOD_SHINING_ONE:
- case GOD_VEHUMET:
- case GOD_MAKHLEB:
- simple_god_message(" accepts your collateral kill.");
- ret = true;
- if (random2(level + 10) > 5)
- piety_change = 1;
- break;
- }
- break;
-
- case DID_DEMON_KILLED_BY_SERVANT:
- switch (you.religion)
- {
- case GOD_ZIN:
- case GOD_SHINING_ONE:
- simple_god_message(" accepts your collateral kill.");
- ret = true;
- if (random2(level + 10) > 5)
- piety_change = 1;
- break;
- }
- break;
-
- case DID_SPELL_MEMORISE:
- if (you.religion == GOD_TROG)
- {
- penance = level * 10;
- piety_change = -penance;
- ret = true;
- }
- break;
-
- case DID_SPELL_CASTING:
- if (you.religion == GOD_TROG)
- {
- piety_change = -level;
- penance = level * 5;
- ret = true;
- }
- break;
-
- case DID_SPELL_PRACTISE:
- // Like CAST, but for skill advancement.
- // Level is number of skill points gained... typically 10 * exerise,
- // but may be more/less if the skill is at 0 (INT adjustment), or
- // if the PC's pool is low and makes change.
- if (you.religion == GOD_SIF_MUNA)
- {
- // Old curve: random2(12) <= spell-level, this is similar,
- // but faster at low levels (to help ease things for low level
- // Power averages about (level * 20 / 3) + 10 / 3 now. Also
- // note that spell skill practise comes just after XP gain, so
- // magical kills tend to do both at the same time (unlike melee).
- // This means high level spells probably work pretty much like
- // they used to (use spell, get piety).
- piety_change = div_rand_round( level + 10, 90 );
- ret = true;
- }
- break;
-
- case DID_CARDS:
- if (you.religion == GOD_NEMELEX_XOBEH)
- {
- piety_change = level;
- ret = true;
- }
- break;
-
- case DID_STIMULANTS: // unused
- case DID_EAT_MEAT: // unused
- case DID_CREATED_LIFE: // unused
- case DID_DEDICATED_KILL_NATURAL_EVIL: // unused
- case DID_NATURAL_EVIL_KILLED_BY_SERVANT: // unused
- case DID_SPELL_NONUTILITY: // unused
- default:
- break;
- }
-
- if (piety_change > 0)
- {
- // positive conduct only interesting out in the real world
- if (!player_in_branch( BRANCH_ECUMENICAL_TEMPLE ))
- gain_piety( piety_change );
- else if (one_chance_in(10))
- {
- simple_god_message( " says: \"Go forth into the world to show your devotion to me!\"" );
- }
- }
- else
- {
- const int piety_loss = -piety_change;
-
- if (piety_loss)
- {
- // output guilt message:
- mprf( "You feel%sguilty.",
- (piety_loss == 1) ? " a little " :
- (piety_loss < 5) ? " " :
- (piety_loss < 10) ? " very "
- : " extremely " );
-
- lose_piety( piety_loss );
- }
-
- if (you.piety < 1)
- excommunication();
- else if (penance) // only if still in religion
- {
- god_speaks( you.religion,
- "\"You will pay for your transgression, mortal!\"" );
-
- inc_penance( penance );
- }
- }
-
-#if DEBUG_DIAGNOSTICS
- if (ret)
- {
- static const char *conducts[] =
- {
- "",
- "Necromancy", "Unholy", "Attack Holy", "Attack Friend",
- "Friend Died", "Stab", "Poison", "Field Sacrifice",
- "Kill Living", "Kill Undead", "Kill Demon", "Kill Natural Evil",
- "Kill Wizard",
- "Kill Priest", "Kill Angel", "Undead Slave Kill Living",
- "Servant Kill Living", "Servant Kill Undead",
- "Servant Kill Demon", "Servant Kill Natural Evil",
- "Servant Kill Angel",
- "Spell Memorise", "Spell Cast", "Spell Practise", "Spell Nonutility",
- "Cards", "Stimulants", "Eat Meat", "Create Life"
- };
-
- mprf( MSGCH_DIAGNOSTICS,
- "conduct: %s; piety: %d (%+d); penance: %d (%+d)",
- conducts[thing_done],
- you.piety, piety_change, you.penance[you.religion], penance );
-
- }
-#endif
-
- return (ret);
-}
-
-void gain_piety(char pgn)
-{
- // check to see if we owe anything first
- if (you.penance[you.religion] > 0)
- {
- dec_penance(pgn);
- return;
- }
- else if (you.gift_timeout > 0)
- {
- if (you.gift_timeout > pgn)
- you.gift_timeout -= pgn;
- else
- you.gift_timeout = 0;
-
- // Slow down piety gain to account for the fact that gifts
- // no longer have a piety cost for getting them
- if (!one_chance_in(8))
- return;
- }
-
- // slow down gain at upper levels of piety
- if (you.piety > 199
- || (you.piety > 150 && one_chance_in(3))
- || (you.piety > 100 && one_chance_in(3)))
- return;
-
- int old_piety = you.piety;
-
- you.piety += pgn;
-
- if (you.piety >= 30 && old_piety < 30)
- {
- switch (you.religion)
- {
- case GOD_NO_GOD:
- case GOD_XOM:
- case GOD_NEMELEX_XOBEH:
- case GOD_SIF_MUNA:
- break;
- default:
- strcpy(info, "You can now ");
- strcat(info,
- (you.religion == GOD_ZIN || you.religion == GOD_SHINING_ONE)
- ? "repel the undead" :
-
- (you.religion == GOD_KIKUBAAQUDGHA)
- ? "recall your undead slaves" :
- (you.religion == GOD_YREDELEMNUL)
- ? "animate corpses" :
- (you.religion == GOD_VEHUMET)
- ? "gain power from killing in Vehumet's name" :
- (you.religion == GOD_MAKHLEB)
- ? "gain power from killing in Makhleb's name" :
- (you.religion == GOD_OKAWARU)
- ? "give your body great, but temporary strength" :
- (you.religion == GOD_TROG)
- ? "go berserk at will" :
- (you.religion == GOD_ELYVILON)
- ? "call upon Elyvilon for minor healing"
- // Unknown god
- : "endure this program bug @30");
-
- strcat(info, ".");
- god_speaks(you.religion, info);
- break;
- }
- }
-
- if (you.piety >= 50 && old_piety < 50)
- {
- switch (you.religion)
- {
- case GOD_NO_GOD:
- case GOD_XOM:
- case GOD_NEMELEX_XOBEH:
- break;
- case GOD_KIKUBAAQUDGHA:
- simple_god_message(" is protecting you from some side-effects of death magic.");
- break;
-
- case GOD_VEHUMET:
- god_speaks(you.religion, "You can call upon Vehumet to aid your destructive magics with prayer.");
- break;
-
- default:
- strcpy(info, "You can now ");
-
- strcat(info,
- (you.religion == GOD_ZIN)
- ? "call upon Zin for minor healing" :
- (you.religion == GOD_SHINING_ONE)
- ? "smite your foes" :
- (you.religion == GOD_YREDELEMNUL)
- ? "recall your undead slaves" :
- (you.religion == GOD_OKAWARU)
- ? "call upon Okawaru for minor healing" :
- (you.religion == GOD_MAKHLEB)
- ? "harness Makhleb's destructive might" :
- (you.religion == GOD_SIF_MUNA)
- ? "freely open your mind to new spells" :
- (you.religion == GOD_TROG)
- ? "give your body great, but temporary, strength" :
- (you.religion == GOD_ELYVILON)
- ? "call upon Elyvilon for purification"
- // Unknown god
- : "endure this program bug @50");
-
- strcat(info, ".");
- god_speaks(you.religion, info);
- break;
- }
- }
-
- if (you.piety >= 75 && old_piety < 75)
- {
- switch (you.religion)
- {
- case GOD_NO_GOD:
- case GOD_XOM:
- case GOD_OKAWARU:
- case GOD_NEMELEX_XOBEH:
- case GOD_SIF_MUNA:
- case GOD_TROG:
- break;
- case GOD_VEHUMET:
- god_speaks(you.religion,"During prayer you have some protection from summoned creatures.");
- break;
-
- default:
- strcpy(info, "You can now ");
- strcat(info,
- (you.religion == GOD_ZIN)
- ? "call down a plague" :
- (you.religion == GOD_SHINING_ONE)
- ? "dispel the undead" :
- (you.religion == GOD_KIKUBAAQUDGHA)
- ? "permanently enslave the undead" :
- (you.religion == GOD_YREDELEMNUL)
- ? "animate legions of the dead" :
- (you.religion == GOD_MAKHLEB)
- ? "summon a lesser servant of Makhleb" :
- (you.religion == GOD_ELYVILON)
- ? "call upon Elyvilon for moderate healing"
- // Unknown god
- : "endure this program bug @75");
- strcat(info, ".");
- god_speaks(you.religion, info);
- break;
- }
- }
-
- if (you.piety >= 100 && old_piety < 100)
- {
- switch (you.religion)
- {
- case GOD_NO_GOD:
- case GOD_XOM:
- case GOD_OKAWARU:
- case GOD_NEMELEX_XOBEH:
- case GOD_KIKUBAAQUDGHA:
- break;
- case GOD_SIF_MUNA:
- simple_god_message
- (" is protecting you from some side-effects of spellcasting.");
- break;
-
- default:
- strcpy(info, "You can now ");
-
- strcat(info,
- (you.religion == GOD_ZIN)
- ? "utter a Holy Word" :
- (you.religion == GOD_SHINING_ONE)
- ? "hurl bolts of divine anger" :
- (you.religion == GOD_YREDELEMNUL)
- ? "drain ambient lifeforce" :
- (you.religion == GOD_VEHUMET)
- ? "tap ambient magical fields" :
- (you.religion == GOD_MAKHLEB)
- ? "hurl Makhleb's greater destruction" :
- (you.religion == GOD_TROG)
- ? "haste yourself" :
- (you.religion == GOD_ELYVILON)
- ? "call upon Elyvilon to restore your abilities"
- // Unknown god
- : "endure this program bug @100");
-
- strcat(info, ".");
- god_speaks(you.religion, info);
- break;
- }
- }
-
- if (you.piety >= 120 && old_piety < 120)
- {
- switch (you.religion)
- {
- case GOD_NO_GOD:
- case GOD_XOM:
- case GOD_NEMELEX_XOBEH:
- case GOD_VEHUMET:
- case GOD_SIF_MUNA:
- case GOD_TROG:
- break;
- default:
- strcpy(info, "You can now ");
-
- strcat(info,
- (you.religion == GOD_ZIN)
- ? "summon a guardian angel" :
- (you.religion == GOD_SHINING_ONE)
- ? "summon a divine warrior" :
- (you.religion == GOD_KIKUBAAQUDGHA)
- ? "summon an emissary of Death" :
- (you.religion == GOD_YREDELEMNUL)
- ? "control the undead" :
- (you.religion == GOD_OKAWARU)
- ? "haste yourself" :
- (you.religion == GOD_MAKHLEB)
- ? "summon a greater servant of Makhleb" :
- (you.religion == GOD_ELYVILON)
- ? "call upon Elyvilon for incredible healing"
- // Unknown god
- : "endure this program bug @120");
-
- strcat(info, ".");
- god_speaks(you.religion, info);
- break;
- }
- }
-} // end gain_piety()
-
-void lose_piety(char pgn)
-{
- int old_piety = you.piety;
-
- if (you.piety - pgn < 0)
- you.piety = 0;
- else
- you.piety -= pgn;
-
- // Don't bother printing out these messages if you're under
- // penance, you wouldn't notice since all these abilities
- // are withheld.
- if (!player_under_penance() && you.piety != old_piety)
- {
- if (you.piety < 120 && old_piety >= 120)
- {
- switch (you.religion)
- {
- case GOD_NO_GOD:
- case GOD_XOM:
- case GOD_NEMELEX_XOBEH:
- case GOD_VEHUMET:
- case GOD_SIF_MUNA:
- case GOD_TROG:
- break;
- default:
- strcpy(info, "You can no longer ");
-
- strcat(info,
- (you.religion == GOD_ZIN)
- ? "summon guardian angels" :
- (you.religion == GOD_SHINING_ONE)
- ? "summon divine warriors" :
- (you.religion == GOD_KIKUBAAQUDGHA)
- ? "summon Death's emissaries" :
- (you.religion == GOD_YREDELEMNUL)
- ? "control undead beings" :
- (you.religion == GOD_OKAWARU)
- ? "haste yourself" :
- (you.religion == GOD_MAKHLEB)
- ? "summon a greater servant of Makhleb" :
- (you.religion == GOD_ELYVILON)
- ? "call upon Elyvilon for incredible healing"
- // Unknown god
- : "endure this program bug @120");
-
- strcat(info, ".");
- god_speaks(you.religion, info);
- break;
- }
- }
-
- if (you.piety < 100 && old_piety >= 100)
- {
- switch (you.religion)
- {
- case GOD_NO_GOD:
- case GOD_XOM:
- case GOD_OKAWARU:
- case GOD_NEMELEX_XOBEH:
- case GOD_KIKUBAAQUDGHA:
- break;
- case GOD_SIF_MUNA:
- god_speaks(you.religion,"Sif Muna is no longer protecting you from miscast magic.");
- break;
- default:
- strcpy(info, "You can no longer ");
- strcat(info,
- (you.religion == GOD_ZIN)
- ? "utter a Holy Word" :
- (you.religion == GOD_ELYVILON)
- ? "call upon Elyvilon to restore your abilities" :
- (you.religion == GOD_SHINING_ONE)
- ? "hurl bolts of divine anger" :
- (you.religion == GOD_YREDELEMNUL)
- ? "drain ambient life force" :
- (you.religion == GOD_VEHUMET)
- ? "tap ambient magical fields" :
- (you.religion == GOD_MAKHLEB)
- ? "direct Makhleb's greater destructive powers" :
- (you.religion == GOD_TROG)
- ? "haste yourself"
- // Unknown god
- : "endure this program bug @100");
-
- strcat(info, ".");
- god_speaks(you.religion, info);
- break;
- }
- }
-
- if (you.piety < 75 && old_piety >= 75)
- {
- switch (you.religion)
- {
- case GOD_NO_GOD:
- case GOD_XOM:
- case GOD_OKAWARU:
- case GOD_NEMELEX_XOBEH:
- case GOD_SIF_MUNA:
- case GOD_TROG:
- break;
- case GOD_VEHUMET:
- simple_god_message(" will no longer shield you from summoned creatures.");
- break;
- default:
- strcpy(info, "You can no longer ");
-
- strcat(info,
- (you.religion == GOD_ZIN)
- ? "call down a plague" :
- (you.religion == GOD_SHINING_ONE)
- ? "dispel undead" :
- (you.religion == GOD_KIKUBAAQUDGHA)
- ? "enslave undead" :
- (you.religion == GOD_YREDELEMNUL)
- ? "animate legions of the dead" :
- (you.religion == GOD_MAKHLEB)
- ? "summon a servant of Makhleb" :
- (you.religion == GOD_ELYVILON)
- ? "call upon Elyvilon for moderate healing"
- // Unknown god
- : "endure this program bug @75");
-
- strcat(info, ".");
- god_speaks(you.religion, info);
- break;
- }
- }
-
- if (you.piety < 50 && old_piety >= 50)
- {
- switch (you.religion)
- {
- case GOD_NO_GOD:
- case GOD_XOM:
- case GOD_NEMELEX_XOBEH:
- break;
- case GOD_KIKUBAAQUDGHA:
- simple_god_message(" is no longer shielding you from miscast death magic.");
- break;
- case GOD_VEHUMET:
- simple_god_message(" will no longer aid your destructive magics.");
- break;
-
- default:
- strcpy(info, "You can no longer ");
-
- strcat(info,
- (you.religion == GOD_ZIN)
- ? "call upon Zin for minor healing" :
- (you.religion == GOD_SHINING_ONE)
- ? "smite your foes" :
- (you.religion == GOD_YREDELEMNUL)
- ? "recall your undead slaves" :
- (you.religion == GOD_OKAWARU)
- ? "call upon Okawaru for minor healing" :
- (you.religion == GOD_MAKHLEB)
- ? "hurl Makhleb's destruction" :
- (you.religion == GOD_SIF_MUNA)
- ? "forget spells at will" :
- (you.religion == GOD_TROG)
- ? "give your body great, but temporary, strength" :
- (you.religion == GOD_ELYVILON)
- ? "call upon Elyvilon for Purification"
- // Unknown god
- : "endure this program bug @50");
-
- strcat(info, ".");
- god_speaks(you.religion, info);
- break;
- }
- }
-
- if (you.piety < 30 && old_piety >= 30)
- {
- switch (you.religion)
- {
- case GOD_NO_GOD:
- case GOD_XOM:
- case GOD_NEMELEX_XOBEH:
- case GOD_SIF_MUNA:
- break;
- default:
- strcpy(info, "You can no longer ");
-
- strcat(info,
- (you.religion == GOD_ZIN || you.religion == GOD_SHINING_ONE)
- ? "repel the undead" :
- (you.religion == GOD_KIKUBAAQUDGHA)
- ? "recall your undead slaves" :
- (you.religion == GOD_YREDELEMNUL)
- ? "animate corpses" :
- (you.religion == GOD_VEHUMET)
- ? "gain power from killing in Vehumet's name" :
- (you.religion == GOD_MAKHLEB)
- ? "gain power from killing in Makhleb's name" :
- (you.religion == GOD_OKAWARU)
- ? "give your body great, but temporary, strength" :
- (you.religion == GOD_TROG)
- ? "go berserk at will" :
- (you.religion == GOD_ELYVILON)
- ? "call upon Elyvilon for minor healing."
- // Unknown god
- : "endure this program bug @30");
-
- strcat(info, ".");
- god_speaks(you.religion, info);
- break;
- }
- }
- }
-} // end lose_piety()
-
-void divine_retribution( int god )
-{
- ASSERT(god != GOD_NO_GOD);
-
- int loopy = 0; // general purpose loop variable {dlb}
- int temp_rand = 0; // probability determination {dlb}
- int punisher = MONS_PROGRAM_BUG;
- bool success = false;
- int how_many = 0;
- int divine_hurt = 0;
-
- // Good gods don't use divine retribution on their followers, they
- // will consider it for those who have gone astray however.
- if (god == you.religion)
- {
- if (god == GOD_SHINING_ONE || god == GOD_ZIN || god == GOD_ELYVILON)
- return;
- }
-
- // Just the thought of retribution (getting this far) mollifies the
- // god by a point... the punishment might reduce penance further.
- dec_penance( god, 1 + random2(3) );
-
- switch (god)
- {
- case GOD_XOM:
- {
- // One in ten chance that Xom might do something good...
- // but that isn't forced, bad things are though
- bool nice = one_chance_in(10);
- bool force = !nice;
-
- Xom_acts(nice, you.experience_level, force);
- }
- break;
-
- case GOD_SHINING_ONE:
- // daeva/smiting theme
- // Doesn't care unless you've gone over to evil/destructive gods
- if (you.religion == GOD_KIKUBAAQUDGHA || you.religion == GOD_MAKHLEB
- || you.religion == GOD_YREDELEMNUL || you.religion == GOD_VEHUMET)
- {
- if (coinflip())
- {
- success = false;
- how_many = 1 + random2(you.experience_level / 5) + random2(3);
-
- for (loopy = 0; loopy < how_many; loopy++)
- {
- if (create_monster( MONS_DAEVA, 0, BEH_HOSTILE,
- you.x_pos, you.y_pos, MHITYOU, 250) != -1)
- {
- success = true;
- }
- }
-
- if (success)
- {
- simple_god_message( " sends the divine host to punish you for your evil ways!", god );
- }
- }
- else
- {
- divine_hurt = 10 + random2(10);
-
- for (loopy = 0; loopy < 5; loopy++)
- divine_hurt += random2( you.experience_level );
-
- if (!player_under_penance() && you.piety > random2(400))
- {
- strcpy(info, "Mortal, I have averted the wrath of "
- "the Shining One... this time.");
- god_speaks(you.religion, info);
- }
- else
- {
- simple_god_message( " smites you!", god );
- ouch( divine_hurt, 0, KILLED_BY_TSO_SMITING );
- dec_penance( GOD_SHINING_ONE, 1 );
- }
- }
- break;
- }
- return;
-
- case GOD_ZIN:
- // angels/creeping doom theme:
- // Doesn't care unless you've gone over to evil
- if (you.religion == GOD_KIKUBAAQUDGHA || you.religion == GOD_MAKHLEB
- || you.religion == GOD_YREDELEMNUL || you.religion == GOD_VEHUMET)
- {
- if (random2(you.experience_level) > 7 && !one_chance_in(5))
- {
- success = false;
- how_many = 1 + (you.experience_level / 10) + random2(3);
-
- for (loopy = 0; loopy < how_many; loopy++)
- {
- if (create_monster(MONS_ANGEL, 0, BEH_HOSTILE,
- you.x_pos, you.y_pos, MHITYOU, 250) != -1)
- {
- success = true;
- }
- }
-
- if (success)
- {
- simple_god_message(" sends the divine host to punish you for your evil ways!", god);
- }
- }
- else
- {
- // god_gift == false gives unfriendly
- summon_swarm( you.experience_level * 20, true, false );
- simple_god_message(" sends a plague down upon you!", god);
- }
- break;
- }
- return;
-
- case GOD_MAKHLEB:
- // demonic servant theme
- if (random2(you.experience_level) > 7 && !one_chance_in(5))
- {
- if (create_monster(MONS_EXECUTIONER + random2(5), 0,
- BEH_HOSTILE, you.x_pos, you.y_pos,
- MHITYOU, 250) != -1)
- {
- simple_god_message(" sends a greater servant after you!",
- god);
- }
- }
- else
- {
- success = false;
- how_many = 1 + (you.experience_level / 7);
-
- for (loopy = 0; loopy < how_many; loopy++)
- {
- if (create_monster(MONS_NEQOXEC + random2(5), 0, BEH_HOSTILE,
- you.x_pos, you.y_pos, MHITYOU, 250) != -1)
- {
- success = true;
- }
- }
-
- if (success)
- simple_god_message(" sends minions to punish you.", god);
- }
- break;
-
- case GOD_KIKUBAAQUDGHA:
- // death/necromancy theme
- if (random2(you.experience_level) > 7 && !one_chance_in(5))
- {
- success = false;
- how_many = 1 + (you.experience_level / 5) + random2(3);
-
- for (loopy = 0; loopy < how_many; loopy++)
- {
- if (create_monster(MONS_REAPER, 0, BEH_HOSTILE, you.x_pos,
- you.y_pos, MHITYOU, 250) != -1)
- {
- success = true;
- }
- }
-
- if (success)
- simple_god_message(" unleashes Death upon you!", god);
- }
- else
- {
- god_speaks(god, (coinflip()) ? "You hear Kikubaaqudgha cackling."
- : "Kikubaaqudgha's malice focuses upon you.");
-
- miscast_effect( SPTYP_NECROMANCY, 5 + you.experience_level,
- random2avg(88, 3), 100, "the malice of Kikubaaqudgha" );
- }
- break;
-
- case GOD_YREDELEMNUL:
- // undead theme
- if (random2(you.experience_level) > 4)
- {
- success = false;
- how_many = 1 + random2(1 + (you.experience_level / 5));
-
- for (loopy = 0; loopy < how_many; loopy++)
- {
- temp_rand = random2(100);
-
- punisher = ((temp_rand > 66) ? MONS_WRAITH : // 33%
- (temp_rand > 52) ? MONS_WIGHT : // 12%
- (temp_rand > 40) ? MONS_SPECTRAL_WARRIOR : // 16%
- (temp_rand > 31) ? MONS_ROTTING_HULK : // 9%
- (temp_rand > 23) ? MONS_SKELETAL_WARRIOR : // 8%
- (temp_rand > 16) ? MONS_VAMPIRE : // 7%
- (temp_rand > 10) ? MONS_GHOUL : // 6%
- (temp_rand > 4) ? MONS_MUMMY // 6%
- : MONS_FLAYED_GHOST); // 5%
-
- if (create_monster( punisher, 0, BEH_HOSTILE,
- you.x_pos, you.y_pos, MHITYOU, 250 ) != -1)
- {
- success = true;
- }
- }
-
- if (success)
- simple_god_message(" sends a servant to punish you.", god);
- }
- else
- {
- simple_god_message("'s anger turns toward you for a moment.",
- god);
-
- miscast_effect( SPTYP_NECROMANCY, 5 + you.experience_level,
- random2avg(88, 3), 100, "the anger of Yredelemnul" );
- }
- break;
-
- case GOD_TROG:
- // physical/berserk theme
- switch (random2(6))
- {
- case 0:
- case 1:
- case 2:
- {
- // Would be better if berserking monsters were available,
- // we just send some big bruisers for now.
- success = false;
-
- int points = 3 + you.experience_level * 3;
-
- while (points > 0)
- {
- if (points > 20 && coinflip())
- {
- // quick reduction for large values
- punisher = MONS_DEEP_TROLL;
- points -= 15;
- break;
- }
- else
- {
- switch (random2(10))
- {
- case 0:
- punisher = MONS_IRON_TROLL;
- points -= 10;
- break;
-
- case 1:
- punisher = MONS_ROCK_TROLL;
- points -= 10;
- break;
-
- case 2:
- punisher = MONS_TROLL;
- points -= 6;
- break;
-
- case 3:
- case 4:
- punisher = MONS_MINOTAUR;
- points -= 3;
- break;
-
- case 5:
- case 6:
- punisher = MONS_TWO_HEADED_OGRE;
- points -= 4;
- break;
-
- case 7:
- case 8:
- case 9:
- default:
- punisher = MONS_OGRE;
- points -= 3;
- }
- }
-
- if (create_monster(punisher, 0, BEH_HOSTILE, you.x_pos,
- you.y_pos, MHITYOU, 250) != -1)
- {
- success = true;
- }
- }
-
- if (success)
- simple_god_message(" sends monsters to punish you.", god);
- }
- break;
-
- case 3:
- case 4:
- simple_god_message("'s voice booms out, \"Feel my wrath!\"", god );
-
- // A collection of physical effects that might be better
- // suited to Trog than wild fire magic... messages could
- // be better here... something more along the lines of apathy
- // or loss of rage to go with the anti-berzerk effect-- bwr
- switch (random2(6))
- {
- case 0:
- potion_effect( POT_DECAY, 100 );
- break;
-
- case 1:
- case 2:
- lose_stat(STAT_STRENGTH, 1 + random2(you.strength / 5), true);
- break;
-
- case 3:
- if (!you.paralysis)
- {
- dec_penance(GOD_TROG, 3);
- mpr( "You suddenly pass out!", MSGCH_WARN );
- you.paralysis = 2 + random2(6);
- }
- break;
-
- case 4:
- case 5:
- if (you.slow < 90)
- {
- dec_penance( GOD_TROG, 1 );
- mpr( "You suddenly feel exhausted!", MSGCH_WARN );
- you.exhausted = 100;
- slow_player( 100 );
- }
- break;
- };
- break;
- //jmf: returned Trog's old Fire damage
- // -- actually, this function partially exists to remove that,
- // we'll leave this effect in, but we'll remove the wild
- // fire magic. -- bwr
- case 5:
- dec_penance(GOD_TROG, 2);
- mpr( "You feel Trog's fiery rage upon you!", MSGCH_WARN );
- miscast_effect( SPTYP_FIRE, 8 + you.experience_level,
- random2avg(98, 3), 100, "the fiery rage of Trog" );
- break;
- }
- break;
-
- case GOD_OKAWARU:
- {
- // warrior theme:
- success = false;
- how_many = 1 + (you.experience_level / 5);
-
- for (loopy = 0; loopy < how_many; loopy++)
- {
- temp_rand = random2(100);
-
- punisher = ((temp_rand > 84) ? MONS_ORC_WARRIOR :
- (temp_rand > 69) ? MONS_ORC_KNIGHT :
- (temp_rand > 59) ? MONS_NAGA_WARRIOR :
- (temp_rand > 49) ? MONS_CENTAUR_WARRIOR :
- (temp_rand > 39) ? MONS_STONE_GIANT :
- (temp_rand > 29) ? MONS_FIRE_GIANT :
- (temp_rand > 19) ? MONS_FROST_GIANT :
- (temp_rand > 9) ? MONS_CYCLOPS :
- (temp_rand > 4) ? MONS_HILL_GIANT
- : MONS_TITAN);
-
- if (create_monster(punisher, 0, BEH_HOSTILE,
- you.x_pos, you.y_pos, MHITYOU, 250) != -1)
- {
- success = true;
- }
- }
-
- if (success)
- simple_god_message(" sends forces against you!", god);
- }
- break;
-
- case GOD_VEHUMET:
- // conjuration and summoning theme
- simple_god_message("'s vengence finds you.", god);
- miscast_effect( coinflip() ? SPTYP_CONJURATION : SPTYP_SUMMONING,
- 8 + you.experience_level, random2avg(98, 3), 100,
- "the wrath of Vehumet" );
- break;
-
- case GOD_NEMELEX_XOBEH:
- // like Xom, this might actually help the player -- bwr`
- simple_god_message(" makes you to draw from the Deck of Punishment.",
- god);
- deck_of_cards(DECK_OF_PUNISHMENT);
- break;
-
- case GOD_SIF_MUNA:
- simple_god_message("'s wrath finds you.", god);
- dec_penance(GOD_SIF_MUNA, 1);
-
- // magic and intelligence theme:
- switch (random2(10))
- {
- case 0:
- case 1:
- lose_stat(STAT_INTELLIGENCE, 1 + random2( you.intel / 5 ), true);
- break;
-
- case 2:
- case 3:
- case 4:
- confuse_player( 3 + random2(10), false );
- break;
-
- case 5:
- case 6:
- miscast_effect(SK_DIVINATIONS, 9, 90, 100, "the will of Sif Muna");
- break;
-
- case 7:
- case 8:
- if (you.magic_points)
- {
- dec_mp( 100 ); // this should zero it.
- mpr( "You suddenly feel drained of magical energy!",
- MSGCH_WARN );
- }
- break;
-
- case 9:
- // This will set all the extendable duration spells to
- // a duration of one round, thus potentially exposing
- // the player to real danger.
- antimagic();
- mpr( "You sense a dampening of magic.", MSGCH_WARN );
- break;
- }
- break;
-
- case GOD_ELYVILON: // Elyvilon doesn't seek revenge
- default:
- return;
- }
-
- // Sometimes divine experiences are overwelming...
- if (one_chance_in(5) && you.experience_level < random2(37))
- {
- if (coinflip())
- confuse_player( 3 + random2(10) );
- else
- {
- if (you.slow < 90)
- {
- mpr( "The divine experience leaves you feeling exhausted!",
- MSGCH_WARN );
-
- slow_player( random2(20) );
- }
- }
- }
-
- return;
-} // end divine_retribution()
-
-void excommunication(void)
-{
- const int old_god = you.religion;
-
- you.duration[DUR_PRAYER] = 0;
- you.religion = GOD_NO_GOD;
- you.piety = 0;
- redraw_skill( you.your_name, player_title() );
-
- mpr("You have lost your religion!");
- more();
-
- switch (old_god)
- {
- case GOD_XOM:
- Xom_acts( false, (you.experience_level * 2), true );
- inc_penance( old_god, 50 );
- break;
-
- case GOD_KIKUBAAQUDGHA:
- simple_god_message( " does not appreciate desertion!", old_god );
- miscast_effect( SPTYP_NECROMANCY, 5 + you.experience_level,
- random2avg(88, 3), 100, "the malice of Kikubaaqudgha" );
- inc_penance( old_god, 30 );
- break;
-
- case GOD_YREDELEMNUL:
- simple_god_message( " does not appreciate desertion!", old_god );
- miscast_effect( SPTYP_NECROMANCY, 5 + you.experience_level,
- random2avg(88, 3), 100, "the anger of Yredelemnul" );
- inc_penance( old_god, 30 );
- break;
-
- case GOD_VEHUMET:
- simple_god_message( " does not appreciate desertion!", old_god );
- miscast_effect( (coinflip() ? SPTYP_CONJURATION : SPTYP_SUMMONING),
- 8 + you.experience_level, random2avg(98, 3), 100,
- "the wrath of Vehumet" );
- inc_penance( old_god, 25 );
- break;
-
- case GOD_MAKHLEB:
- simple_god_message( " does not appreciate desertion!", old_god );
- miscast_effect( (coinflip() ? SPTYP_CONJURATION : SPTYP_SUMMONING),
- 8 + you.experience_level, random2avg(98, 3), 100,
- "the fury of Makhleb" );
- inc_penance( old_god, 25 );
- break;
-
- case GOD_TROG:
- simple_god_message( " does not appreciate desertion!", old_god );
-
- // Penence has to come before retribution to prevent "mollify"
- inc_penance( old_god, 50 );
- divine_retribution( old_god );
- break;
-
- // these like to haunt players for a bit more than the standard
- case GOD_NEMELEX_XOBEH:
- case GOD_SIF_MUNA:
- inc_penance( old_god, 50 );
- break;
-
- default:
- inc_penance( old_god, 25 );
- break;
-
- case GOD_ELYVILON: // never seeks revenge
- break;
- }
-} // end excommunication()
-
-static bool bless_weapon( int god, int brand, int colour )
-{
- const int wpn = get_player_wielded_weapon();
-
- // Assuming the type of weapon is correct, we only need to check
- // to see if it's an artefact we can successfully clobber:
- if (!is_fixed_artefact( you.inv[wpn] )
- && !is_random_artefact( you.inv[wpn] ))
- {
- you.duration[DUR_WEAPON_BRAND] = 0; // just in case
-
- set_equip_desc( you.inv[wpn], ISFLAG_GLOWING );
- set_item_ego_type( you.inv[wpn], OBJ_WEAPONS, brand );
- you.inv[wpn].colour = colour;
-
- do_uncurse_item( you.inv[wpn] );
- enchant_weapon( ENCHANT_TO_HIT, true );
- enchant_weapon( ENCHANT_TO_DAM, true );
-
- you.wield_change = true;
- you.num_gifts[god]++;
-
- you.flash_colour = colour;
- viewwindow( true, false );
-
- mprf( MSGCH_GOD, "Your weapon shines brightly!" );
- simple_god_message( " booms: Use this gift wisely!" );
-
- // as currently only Zin and TSO do this is our permabrand effect:
- holy_word( 100, true );
- delay(500);
-
- return (true);
- }
-
- return (false);
-}
-
-void altar_prayer(void)
-{
- int i, j, next;
- char subst_id[4][50];
- char str_pass[ ITEMNAME_SIZE ];
-
- for (i = 0; i < 4; i++)
- {
- for (j = 0; j < 50; j++)
- {
- subst_id[i][j] = 1;
- }
- }
-
- mpr( "You kneel at the altar and pray." );
-
- if (you.religion == GOD_XOM)
- return;
-
- // TSO blesses long swords with holy wrath
- if (you.religion == GOD_SHINING_ONE
- && !you.num_gifts[GOD_SHINING_ONE]
- && !player_under_penance()
- && you.piety > 160)
- {
- const int wpn = get_player_wielded_weapon();
-
- if (wpn != -1
- && weapon_skill( you.inv[wpn] ) == SK_LONG_SWORDS
- && get_weapon_brand( you.inv[wpn] ) != SPWPN_HOLY_WRATH)
- {
- if (bless_weapon( GOD_SHINING_ONE, SPWPN_HOLY_WRATH, YELLOW ))
- {
- // convert those demon blades if blessed:
- if (you.inv[wpn].sub_type == WPN_DEMON_BLADE)
- you.inv[wpn].sub_type = WPN_BLESSED_BLADE;
- }
- }
- }
-
- // Zin blesses maces with disruption
- if (you.religion == GOD_ZIN
- && !you.num_gifts[GOD_ZIN]
- && !player_under_penance()
- && you.piety > 160)
- {
- const int wpn = get_player_wielded_weapon();
-
- if (wpn != -1
- && (you.inv[wpn].base_type == OBJ_WEAPONS
- && (you.inv[wpn].sub_type == WPN_MACE
- || you.inv[wpn].sub_type == WPN_GREAT_MACE))
- && get_weapon_brand( you.inv[wpn] ) != SPWPN_DISRUPTION)
- {
- bless_weapon( GOD_ZIN, SPWPN_DISRUPTION, WHITE );
- }
- }
-
- i = igrd[you.x_pos][you.y_pos];
- while (i != NON_ITEM)
- {
- if (one_chance_in(1000))
- break;
-
- next = mitm[i].link; // in case we can't get it later.
-
- const int value = item_value( mitm[i], subst_id, true );
-
- switch (you.religion)
- {
- case GOD_ZIN:
- case GOD_OKAWARU:
- case GOD_MAKHLEB:
- case GOD_NEMELEX_XOBEH:
- it_name(i, DESC_CAP_THE, str_pass);
- strcpy(info, str_pass);
- strcat(info, sacrifice[you.religion - 1]);
- mpr(info);
-
- if (mitm[i].base_type == OBJ_CORPSES
- || random2(value) >= 50
- || player_under_penance())
- {
- gain_piety(1);
- }
-
- destroy_item(i);
- break;
-
- case GOD_SIF_MUNA:
- it_name(i, DESC_CAP_THE, str_pass);
- strcpy(info, str_pass);
- strcat(info, sacrifice[you.religion - 1]);
- mpr(info);
-
- if (value >= 150)
- gain_piety(1 + random2(3));
-
- destroy_item(i);
- break;
-
- case GOD_KIKUBAAQUDGHA:
- case GOD_TROG:
- if (mitm[i].base_type != OBJ_CORPSES)
- break;
-
- it_name(i, DESC_CAP_THE, str_pass);
- strcpy(info, str_pass);
- strcat(info, sacrifice[you.religion - 1]);
- mpr(info);
-
- gain_piety(1);
- destroy_item(i);
- break;
-
- case GOD_ELYVILON:
- if (mitm[i].base_type != OBJ_WEAPONS
- && mitm[i].base_type != OBJ_MISSILES)
- {
- break;
- }
-
- it_name(i, DESC_CAP_THE, str_pass);
- strcpy(info, str_pass);
- strcat(info, sacrifice[you.religion - 1]);
- mpr(info);
-
- if (random2(value) >= random2(50)
- || (mitm[i].base_type == OBJ_WEAPONS
- && (you.piety < 30 || player_under_penance())))
- {
- gain_piety(1);
- }
-
- destroy_item(i);
- break;
-
- default:
- break;
- }
-
- i = next;
- }
-} // end altar_prayer()
-
-void god_pitch(unsigned char which_god)
-{
- strcpy(info, "You kneel at the altar of ");
- strcat(info, god_name(which_god));
- strcat(info, ".");
- mpr(info);
-
- more();
-
- // Note: using worship we could make some gods not allow followers to
- // return, or not allow worshippers from other religions. -- bwr
-
- if ((you.is_undead || you.species == SP_DEMONSPAWN)
- && (which_god == GOD_ZIN || which_god == GOD_SHINING_ONE
- || which_god == GOD_ELYVILON))
- {
- simple_god_message(" does not accept worship from those such as you!",
- which_god);
- return;
- }
-
- describe_god( which_god, false );
-
- snprintf( info, INFO_SIZE, "Do you wish to %sjoin this religion?",
- (you.worshipped[which_god]) ? "re" : "" );
-
- if (!yesno( info ))
- {
- redraw_screen();
- return;
- }
-
- if (!yesno("Are you sure?"))
- {
- redraw_screen();
- return;
- }
-
- redraw_screen();
- if (you.religion != GOD_NO_GOD)
- excommunication();
-
- you.religion = which_god; //jmf: moved up so god_speaks gives right colour
- you.piety = 15; // to prevent near instant excommunication
- you.gift_timeout = 0;
- set_god_ability_slots(); // remove old god's slots, reserve new god's
-
- snprintf( info, INFO_SIZE, " welcomes you%s!",
- (you.worshipped[which_god]) ? " back" : "" );
-
- simple_god_message( info );
- more();
-
- if (you.worshipped[you.religion] < 100)
- you.worshipped[you.religion]++;
-
- // Currently penance is just zeroed, this could be much more interesting.
- you.penance[you.religion] = 0;
-
- if (you.religion == GOD_KIKUBAAQUDGHA || you.religion == GOD_YREDELEMNUL
- || you.religion == GOD_VEHUMET || you.religion == GOD_MAKHLEB)
- {
- // Note: Using worshipped[] we could make this sort of grudge
- // permanent instead of based off of penance. -- bwr
- if (you.penance[GOD_SHINING_ONE] > 0)
- {
- inc_penance(GOD_SHINING_ONE, 30);
- god_speaks(GOD_SHINING_ONE, "\"You will pay for your evil ways, mortal!\"");
- }
- }
- redraw_skill( you.your_name, player_title() );
-} // end god_pitch()
-
-void offer_corpse(int corpse)
-{
- char str_pass[ ITEMNAME_SIZE ];
- it_name(corpse, DESC_CAP_THE, str_pass);
- strcpy(info, str_pass);
- strcat(info, sacrifice[you.religion - 1]);
- mpr(info);
-
- did_god_conduct(DID_DEDICATED_BUTCHERY, 10);
-} // end offer_corpse()
-
-//jmf: moved stuff from items::handle_time()
-void handle_god_time(void)
-{
- if (one_chance_in(100))
- {
- // Choose a god randomly from those to whom we owe penance.
- //
- // Proof: (By induction)
- //
- // 1) n = 1, probability of choosing god is one_chance_in(1)
- // 2) Asuume true for n = k (ie. prob = 1 / n for all n)
- // 3) For n = k + 1,
- //
- // P:new-found-god = 1 / n (see algorithm)
- // P:other-gods = (1 - P:new-found-god) * P:god-at-n=k
- // 1 1
- // = (1 - -------) * ---
- // k + 1 k
- //
- // k 1
- // = ----------- * ---
- // k + 1 k
- //
- // 1 1
- // = ----- = ---
- // k + 1 n
- //
- // Therefore, by induction the probability is uniform. As for
- // why we do it this way... it requires only one pass and doesn't
- // require an array.
-
- int which_god = GOD_NO_GOD;
- unsigned int count = 0;
-
- for (int i = GOD_NO_GOD; i < NUM_GODS; i++)
- {
- if (you.penance[i])
- {
- count++;
- if (one_chance_in(count))
- which_god = i;
- }
- }
-
- if (which_god != GOD_NO_GOD)
- divine_retribution(which_god);
- }
-
- // Update the god's opinion of the player
- if (you.religion != GOD_NO_GOD)
- {
- switch (you.religion)
- {
- case GOD_XOM:
- if (one_chance_in(75))
- Xom_acts(true, you.experience_level + random2(15), true);
- break;
-
- case GOD_ZIN: // These gods like long-standing worshippers
- case GOD_ELYVILON:
- if (you.piety < 150 && one_chance_in(20))
- gain_piety(1);
- break;
-
- case GOD_SHINING_ONE:
- if (you.piety < 150 && one_chance_in(15))
- gain_piety(1);
- break;
-
- case GOD_YREDELEMNUL:
- case GOD_KIKUBAAQUDGHA:
- case GOD_VEHUMET:
- if (one_chance_in(17))
- lose_piety(1);
- if (you.piety < 1)
- excommunication();
- break;
-
- case GOD_OKAWARU: // These gods accept corpses, so they time-out faster
- case GOD_TROG:
- if (one_chance_in(14))
- lose_piety(1);
- if (you.piety < 1)
- excommunication();
- break;
-
- case GOD_MAKHLEB:
- if (one_chance_in(16))
- lose_piety(1);
- if (you.piety < 1)
- excommunication();
- break;
-
- case GOD_SIF_MUNA:
- // [dshaligram] Sif Muna is now very patient - has to be
- // to make up for the new spell training requirements, else
- // it's practically impossible to get Master of Arcane status.
- if (one_chance_in(60))
- lose_piety(1);
- if (you.piety < 1)
- excommunication();
- break;
-
- case GOD_NEMELEX_XOBEH: // relatively patient
- if (one_chance_in(35))
- lose_piety(1);
- if (you.attribute[ATTR_CARD_COUNTDOWN] > 0 && coinflip())
- you.attribute[ATTR_CARD_COUNTDOWN]--;
- if (you.piety < 1)
- excommunication();
- break;
-
- default:
- DEBUGSTR("Bad god, no bishop!");
- }
- }
-} // end handle_god_time()
-
-// yet another wrapper for mpr() {dlb}:
-void simple_god_message(const char *event, int which_deity)
-{
- char buff[ INFO_SIZE ];
-
- if (which_deity == GOD_NO_GOD)
- which_deity = you.religion;
-
- snprintf( buff, sizeof(buff), "%s%s", god_name( which_deity ), event );
-
- god_speaks( which_deity, buff );
-}
-
-char god_colour( char god ) //mv - added
-{
- switch (god)
- {
- case GOD_SHINING_ONE:
- case GOD_ZIN:
- case GOD_ELYVILON:
- case GOD_OKAWARU:
- return(CYAN);
-
- case GOD_YREDELEMNUL:
- case GOD_KIKUBAAQUDGHA:
- case GOD_MAKHLEB:
- case GOD_VEHUMET:
- case GOD_TROG:
- return(LIGHTRED);
-
- case GOD_XOM:
- return(YELLOW);
-
- case GOD_NEMELEX_XOBEH:
- return(LIGHTMAGENTA);
-
- case GOD_SIF_MUNA:
- return(LIGHTBLUE);
-
- case GOD_NO_GOD:
- default:
- break;
- }
-
- return(YELLOW);
-}
diff --git a/stone_soup/crawl-ref/source/religion.h b/stone_soup/crawl-ref/source/religion.h
deleted file mode 100644
index 1ec71c827b..0000000000
--- a/stone_soup/crawl-ref/source/religion.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * File: religion.cc
- * Summary: Misc religion related functions.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef RELIGION_H
-#define RELIGION_H
-
-#include "enum.h"
-
-void simple_god_message( const char *event, int which_deity = GOD_NO_GOD );
-char *god_name(int which_god,bool long_name=false); //mv
-void dec_penance(int val);
-void dec_penance(int god, int val);
-void Xom_acts(bool niceness, int sever, bool force_sever);
-bool did_god_conduct(int thing_done, int pgain);
-void excommunication(void);
-void gain_piety(char pgn);
-void god_speaks( int god, const char *mesg );
-void lose_piety(char pgn);
-void offer_corpse(int corpse);
-void pray(void);
-void handle_god_time(void);
-char god_colour(char god);
-void god_pitch(unsigned char which_god);
-
-#endif
diff --git a/stone_soup/crawl-ref/source/shopping.cc b/stone_soup/crawl-ref/source/shopping.cc
deleted file mode 100644
index cff3ce8f51..0000000000
--- a/stone_soup/crawl-ref/source/shopping.cc
+++ /dev/null
@@ -1,1610 +0,0 @@
-/*
- * File: shopping.cc
- * Summary: Shop keeper functions.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <3> Jul 30 00 JDJ in_a_shop uses shoppy instead of i when calling shop_set_id.
- * <2> Oct 31 99 CDL right justify prices
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "chardump.h"
-#include "shopping.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef DOS
-#include <conio.h>
-#endif
-
-#include "externs.h"
-
-#include "describe.h"
-#include "invent.h"
-#include "items.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "macro.h"
-#include "player.h"
-#include "randart.h"
-#include "spl-book.h"
-#include "stash.h"
-#include "stuff.h"
-
-static char in_a_shop(char shoppy, id_arr id);
-static char more3(void);
-static void purchase( int shop, int item_got, int cost );
-static void shop_init_id(int i, id_fix_arr &shop_id);
-static void shop_print(const char *shoppy, char sh_line);
-static void shop_set_ident_type(int i, id_fix_arr &shop_id,
- unsigned char base_type, unsigned char sub_type);
-static void shop_uninit_id(int i, const id_fix_arr &shop_id);
-
-char in_a_shop( char shoppy, id_arr id )
-{
- // easier to work with {dlb}
- unsigned int greedy = env.shop[shoppy].greed;
-
- id_fix_arr shop_id;
- FixedVector < int, 20 > shop_items;
-
- char st_pass[ ITEMNAME_SIZE ] = "";
- unsigned int gp_value = 0;
- char i;
- unsigned char ft;
-
-#ifdef DOS_TERM
- char buffer[4800];
- gettext(1, 1, 80, 25, buffer);
-#endif
-
-#ifdef DOS_TERM
- window(1, 1, 80, 25);
-#endif
-
- clrscr();
- int itty = 0;
-
- snprintf( info, INFO_SIZE, "Welcome to %s!",
- shop_name(env.shop[shoppy].x, env.shop[shoppy].y) );
-
-#ifdef STASH_TRACKING
- ShopInfo &si = stashes.get_shop(env.shop[shoppy].x, env.shop[shoppy].y);
-#endif
-
- shop_print(info, 20);
-
- more3();
- shop_init_id(shoppy, shop_id);
-
- /* *************************************
- THINGS TO DO:
- Allow inventory
- Remove id change for antique shops
- selling?
- ************************************* */
-
- save_id(id);
-
- print_stock:
- clrscr();
- itty = igrd[0][5 + shoppy];
-
-#ifdef STASH_TRACKING
- si.reset();
-#endif
- if (itty == NON_ITEM)
- {
- shop_print("I'm sorry, my shop is empty now.", 20);
- more3();
- goto goodbye;
- }
-
- for (i = 1; i < 20; i++)
- {
- shop_items[i - 1] = itty;
-
- if (itty == NON_ITEM) //mitm.link [itty] == NON_ITEM)
- {
- shop_items[i - 1] = NON_ITEM;
- continue;
- }
-
- itty = mitm[itty].link;
- }
-
- itty = igrd[0][5 + shoppy];
-
- for (i = 1; i < 18; i++)
- {
- gotoxy(1, i);
-
- textcolor((i % 2) ? WHITE : LIGHTGREY);
-
- it_name(itty, DESC_NOCAP_A, st_pass);
- putch(i + 96);
- cprintf(" - ");
- cprintf(st_pass);
-
- gp_value = greedy * item_value( mitm[itty], id );
- gp_value /= 10;
- if (gp_value <= 1)
- gp_value = 1;
-
- std::string desc;
- if (is_dumpable_artifact(mitm[itty], Options.verbose_dump))
- desc = munge_description(get_item_description(mitm[itty],
- Options.verbose_dump,
- true ));
-# ifdef STASH_TRACKING
- si.add_item(mitm[itty], gp_value);
-# endif
-
- gotoxy(60, i);
- // cdl - itoa(gp_value, st_pass, 10);
- snprintf(st_pass, sizeof(st_pass), "%5d", gp_value);
- cprintf(st_pass);
- cprintf(" gold");
- if (mitm[itty].link == NON_ITEM)
- break;
-
- itty = mitm[itty].link;
- }
-
- textcolor(LIGHTGREY);
-
- shop_print("Type letter to buy item, x/Esc to leave, ?/* for inventory, v to examine.", 23);
-
- purchase:
- snprintf( info, INFO_SIZE, "You have %d gold piece%s.", you.gold,
- (you.gold == 1) ? "" : "s" );
-
- textcolor(YELLOW);
- shop_print(info, 19);
-
- textcolor(CYAN);
- shop_print("What would you like to purchase?", 20);
- textcolor(LIGHTGREY);
-
- ft = get_ch();
-
- if (ft == 'x' || ft == ESCAPE)
- goto goodbye;
-
- if (ft == 'v')
- {
- textcolor(CYAN);
- shop_print("Examine which item?", 20);
- textcolor(LIGHTGREY);
- ft = get_ch();
-
- // wonder whether this should be recoded to permit uppercase, too? {dlb}
- if (ft < 'a' || ft > 'z')
- goto huh;
-
- ft -= 'a'; // see above comment {dlb}
-
- if (ft > 18)
- goto huh;
-
- if (shop_items[ft] == NON_ITEM)
- {
- shop_print("I'm sorry, you seem to be confused.", 20);
- more3();
- goto purchase;
- }
-
- describe_item( mitm[shop_items[ft]] );
-
- goto print_stock;
- }
-
- if (ft == '?' || ft == '*')
- {
- shop_uninit_id(shoppy, shop_id);
- invent(-1, false);
- shop_init_id(shoppy, shop_id);
-#ifdef DOS_TERM
- window(1, 1, 80, 25);
-#endif
- goto print_stock;
- }
-
- if (ft < 'a' || ft > 'z') // see earlier comments re: uppercase {dlb}
- {
- huh:
- shop_print("Huh?", 20);
- more3();
- goto purchase;
- }
-
- ft -= 'a'; // see earlier comments re: uppercase {dlb}
-
- if (ft > 18)
- goto huh;
-
- if (shop_items[ft] == NON_ITEM)
- {
- shop_print("I'm sorry, you seem to be confused.", 20);
- more3();
- goto purchase;
- }
-
- gp_value = greedy * item_value( mitm[shop_items[ft]], id ) / 10;
-
- if (gp_value > you.gold)
- {
- shop_print("I'm sorry, you don't seem to have enough money.", 20);
- more3();
- goto purchase;
- }
-
- shop_set_ident_type( shoppy, shop_id, mitm[shop_items[ft]].base_type,
- mitm[shop_items[ft]].sub_type );
-
- purchase( shoppy, shop_items[ft], gp_value );
-
- goto print_stock;
-
- goodbye:
- //clear_line();
- shop_print("Goodbye!", 20);
- more3();
-
-#ifdef DOS_TERM
- puttext(1, 1, 80, 25, buffer);
- gotoxy(1, 1);
- cprintf(" ");
-#endif
-
- shop_uninit_id( shoppy, shop_id );
- return 0;
-}
-
-void shop_init_id_type(int shoptype, id_fix_arr &shop_id)
-{
- if (shoptype != SHOP_WEAPON_ANTIQUE
- && shoptype != SHOP_ARMOUR_ANTIQUE
- && shoptype != SHOP_GENERAL_ANTIQUE)
- {
- for (int j = 0; j < 50; j++)
- {
- shop_id[ IDTYPE_WANDS ][j] = get_ident_type(OBJ_WANDS, j);
- set_ident_type(OBJ_WANDS, j, ID_KNOWN_TYPE);
-
- shop_id[ IDTYPE_SCROLLS ][j] = get_ident_type(OBJ_SCROLLS, j);
- set_ident_type(OBJ_SCROLLS, j, ID_KNOWN_TYPE);
-
- shop_id[ IDTYPE_JEWELLERY ][j] = get_ident_type(OBJ_JEWELLERY, j);
- set_ident_type(OBJ_JEWELLERY, j, ID_KNOWN_TYPE);
-
- shop_id[ IDTYPE_POTIONS ][j] = get_ident_type(OBJ_POTIONS, j);
- set_ident_type(OBJ_POTIONS, j, ID_KNOWN_TYPE);
- }
- }
-}
-
-static void shop_init_id(int i, id_fix_arr &shop_id)
-{
- shop_init_id_type( env.shop[i].type, shop_id );
-}
-
-void shop_uninit_id_type(int shoptype, const id_fix_arr &shop_id)
-{
- if (shoptype != SHOP_WEAPON_ANTIQUE
- && shoptype != SHOP_ARMOUR_ANTIQUE
- && shoptype != SHOP_GENERAL_ANTIQUE)
- {
- for (int j = 0; j < 50; j++)
- {
- set_ident_type( OBJ_WANDS, j,
- shop_id[ IDTYPE_WANDS ][j], true );
- set_ident_type( OBJ_SCROLLS, j,
- shop_id[ IDTYPE_SCROLLS ][j], true );
- set_ident_type( OBJ_JEWELLERY, j,
- shop_id[ IDTYPE_JEWELLERY ][j], true );
- set_ident_type( OBJ_POTIONS, j,
- shop_id[ IDTYPE_POTIONS ][j], true );
- }
- }
-}
-
-static void shop_uninit_id(int i, const id_fix_arr &shop_id)
-{
- shop_uninit_id_type(env.shop[i].type, shop_id);
-}
-
-void shop_set_ident_type( int i, id_fix_arr &shop_id,
- unsigned char base_type, unsigned char sub_type )
-{
- if (env.shop[i].type != SHOP_WEAPON_ANTIQUE
- && env.shop[i].type != SHOP_ARMOUR_ANTIQUE
- && env.shop[i].type != SHOP_GENERAL_ANTIQUE)
- {
- switch (base_type)
- {
- case OBJ_WANDS:
- shop_id[ IDTYPE_WANDS ][sub_type] = ID_KNOWN_TYPE;
- break;
- case OBJ_SCROLLS:
- shop_id[ IDTYPE_SCROLLS ][sub_type] = ID_KNOWN_TYPE;
- break;
- case OBJ_JEWELLERY:
- shop_id[ IDTYPE_JEWELLERY ][sub_type] = ID_KNOWN_TYPE;
- break;
- case OBJ_POTIONS:
- shop_id[ IDTYPE_POTIONS ][sub_type] = ID_KNOWN_TYPE;
- break;
- }
- }
-}
-
-void shop_print( const char *shoppy, char sh_lines )
-{
- gotoxy(1, sh_lines);
-
- cprintf(shoppy);
-
- for (int i = strlen(shoppy); i < 80; i++)
- cprintf(" ");
-}
-
-char more3(void)
-{
- char keyin = 0;
-
- gotoxy(70, 20);
- cprintf("-more-");
- keyin = getch();
- if (keyin == 0)
- getch();
- //clear_line();
- return keyin;
-}
-
-static void purchase( int shop, int item_got, int cost )
-{
- you.gold -= cost;
-
- origin_purchased(mitm[item_got]);
- int num = move_item_to_player( item_got, mitm[item_got].quantity, true );
-
- // Shopkeepers will now place goods you can't carry outside the shop.
- if (num < mitm[item_got].quantity)
- {
- snprintf( info, INFO_SIZE, "I'll put %s outside for you.",
- (mitm[item_got].quantity == 1) ? "it" :
- (num > 0) ? "the rest"
- : "these" );
-
- shop_print( info, 20 );
- more3();
-
- move_item_to_grid( &item_got, env.shop[shop].x, env.shop[shop].y );
- }
-} // end purchase()
-
-// This probably still needs some work. Rings used to be the only
-// artefacts which had a change in price, and that value corresponds
-// to returning 50 from this function. Good artefacts will probably
-// be returning just over 30 right now. Note that this isn't used
-// as a multiple, its used in the old ring way: 7 * ret is added to
-// the price of the artefact. -- bwr
-int randart_value( const item_def &item )
-{
- ASSERT( is_random_artefact( item ) );
-
- int ret = 10;
- FixedVector< char, RA_PROPERTIES > prop;
-
- randart_wpn_properties( item, prop );
-
- // Brands are already accounted for via existing ego checks
-
- // This should probably be more complex... but this isn't so bad:
- ret += 3 * prop[ RAP_AC ] + 3 * prop[ RAP_EVASION ]
- + 3 * prop[ RAP_ACCURACY ] + 3 * prop[ RAP_DAMAGE ]
- + 6 * prop[ RAP_STRENGTH ] + 6 * prop[ RAP_INTELLIGENCE ]
- + 6 * prop[ RAP_DEXTERITY ];
-
- // These resistances have meaningful levels
- if (prop[ RAP_FIRE ] > 0)
- ret += 5 + 5 * (prop[ RAP_FIRE ] * prop[ RAP_FIRE ]);
- else if (prop[ RAP_FIRE ] < 0)
- ret -= 10;
-
- if (prop[ RAP_COLD ] > 0)
- ret += 5 + 5 * (prop[ RAP_COLD ] * prop[ RAP_COLD ]);
- else if (prop[ RAP_COLD ] < 0)
- ret -= 10;
-
- // These normally come alone or in resist/susceptible pairs...
- // we're making items a bit more expensive if they have both positive.
- if (prop[ RAP_FIRE ] > 0 && prop[ RAP_COLD ] > 0)
- ret += 20;
-
- if (prop[ RAP_NEGATIVE_ENERGY ] > 0)
- ret += 5 + 5 * (prop[RAP_NEGATIVE_ENERGY] * prop[RAP_NEGATIVE_ENERGY]);
-
- // only one meaningful level:
- if (prop[ RAP_POISON ])
- ret += 15;
-
- // only one meaningful level (hard to get):
- if (prop[ RAP_ELECTRICITY ])
- ret += 30;
-
- // magic resistance is from 20-120
- if (prop[ RAP_MAGIC ])
- ret += 5 + prop[ RAP_MAGIC ] / 10;
-
- if (prop[ RAP_EYESIGHT ])
- ret += 10;
-
- // abilities:
- if (prop[ RAP_LEVITATE ])
- ret += 3;
-
- if (prop[ RAP_BLINK ])
- ret += 3;
-
- if (prop[ RAP_CAN_TELEPORT ])
- ret += 5;
-
- if (prop[ RAP_BERSERK ])
- ret += 5;
-
- if (prop[ RAP_MAPPING ])
- ret += 15;
-
- if (prop[ RAP_INVISIBLE ])
- ret += 20;
-
- if (prop[ RAP_ANGRY ])
- ret -= 3;
-
- if (prop[ RAP_CAUSE_TELEPORTATION ])
- ret -= 3;
-
- if (prop[ RAP_NOISES ])
- ret -= 5;
-
- if (prop[ RAP_PREVENT_TELEPORTATION ])
- ret -= 8;
-
- if (prop[ RAP_PREVENT_SPELLCASTING ])
- ret -= 10;
-
- // ranges from 2-5
- if (prop[ RAP_MUTAGENIC ])
- ret -= (5 + 3 * prop[ RAP_MUTAGENIC ]);
-
- // ranges from 1-3
- if (prop[ RAP_METABOLISM ])
- ret -= (2 * prop[ RAP_METABOLISM ]);
-
- return ((ret > 0) ? ret : 0);
-}
-
-unsigned int item_value( item_def item, id_arr id, bool ident )
-{
- // Note that we pass item in by value, since we want a local
- // copy to mangle as neccessary... maybe that should be fixed,
- // but this function isn't called too often.
- item.flags = (ident) ? (item.flags | ISFLAG_IDENT_MASK) : (item.flags);
-
- int valued = 0;
-
- switch (item.base_type)
- {
- case OBJ_WEAPONS:
- if (is_fixed_artefact( item ))
- {
- if (item_ident( item, ISFLAG_KNOW_PROPERTIES ))
- {
- switch (item.special)
- {
- case SPWPN_SWORD_OF_CEREBOV:
- valued += 2000;
- break;
-
- case SPWPN_SCEPTRE_OF_ASMODEUS:
- valued += 1500;
- break;
-
- case SPWPN_SWORD_OF_ZONGULDROK:
- valued += 1250;
- break;
-
- case SPWPN_SCEPTRE_OF_TORMENT:
- case SPWPN_SINGING_SWORD:
- case SPWPN_STAFF_OF_DISPATER:
- valued += 1200;
- break;
-
- case SPWPN_GLAIVE_OF_PRUNE:
- case SPWPN_WRATH_OF_TROG:
- valued += 1000;
- break;
-
- case SPWPN_SCYTHE_OF_CURSES:
- valued += 800;
- break;
-
- case SPWPN_MACE_OF_VARIABILITY:
- valued += 700;
- break;
-
- default:
- valued += 1000;
- break;
- }
- break;
- }
-
- } // end uniques
-
- switch (item.sub_type)
- {
- case WPN_CLUB:
- case WPN_KNIFE:
- valued += 10;
- break;
-
- case WPN_SLING:
- valued += 15;
- break;
-
- case WPN_GIANT_CLUB:
- valued += 17;
- break;
-
- case WPN_GIANT_SPIKED_CLUB:
- valued += 19;
- break;
-
- case WPN_DAGGER:
- valued += 20;
- break;
-
- case WPN_WHIP:
- case WPN_BLOWGUN:
- valued += 25;
- break;
-
- case WPN_HAND_AXE:
- valued += 28;
- break;
-
- case WPN_HAMMER:
- case WPN_FALCHION:
- case WPN_MACE:
- case WPN_SCYTHE:
- valued += 30;
- break;
-
- case WPN_BOW:
- valued += 31;
- break;
-
- case WPN_QUARTERSTAFF:
- case WPN_SHORT_SWORD:
- case WPN_SPEAR:
- valued += 32;
- break;
-
- case WPN_FLAIL:
- valued += 35;
- break;
-
- case WPN_ANCUS:
- case WPN_WAR_AXE:
- case WPN_MORNINGSTAR:
- case WPN_SABRE:
- valued += 40;
- break;
-
- case WPN_CROSSBOW:
- valued += 41;
- break;
-
- case WPN_TRIDENT:
- valued += 42;
- break;
-
- case WPN_LONG_SWORD:
- case WPN_LONGBOW:
- case WPN_SCIMITAR:
- valued += 45;
- break;
-
- case WPN_SPIKED_FLAIL:
- valued += 50;
-
- case WPN_HAND_CROSSBOW:
- valued += 51;
- break;
-
- case WPN_HALBERD:
- valued += 52;
- break;
-
- case WPN_GLAIVE:
- valued += 55;
- break;
-
- case WPN_BROAD_AXE:
- case WPN_GREAT_SWORD:
- valued += 60;
- break;
-
- case WPN_BATTLEAXE:
- case WPN_GREAT_MACE:
- valued += 65;
- break;
-
- case WPN_DIRE_FLAIL:
- case WPN_LOCHABER_AXE:
- valued += 90;
- break;
-
- case WPN_EVENINGSTAR:
- valued += 65;
- break;
-
- case WPN_EXECUTIONERS_AXE:
- valued += 100;
- break;
-
- case WPN_DOUBLE_SWORD:
- valued += 100;
- break;
-
- case WPN_DEMON_WHIP:
- valued += 130;
- break;
-
- case WPN_QUICK_BLADE:
- case WPN_DEMON_TRIDENT:
- valued += 150;
- break;
-
- case WPN_KATANA:
- case WPN_TRIPLE_SWORD:
- case WPN_DEMON_BLADE:
- case WPN_BLESSED_BLADE:
- case WPN_LAJATANG:
- valued += 200;
- break;
- }
-
- if (item_ident( item, ISFLAG_KNOW_TYPE ))
- {
- switch (get_weapon_brand( item ))
- {
- case SPWPN_NORMAL:
- default: // randart
- valued *= 10;
- break;
-
- case SPWPN_DRAINING:
- valued *= 64;
- break;
-
- case SPWPN_VAMPIRICISM:
- valued *= 60;
- break;
-
- case SPWPN_DISRUPTION:
- case SPWPN_FLAME:
- case SPWPN_FROST:
- case SPWPN_HOLY_WRATH:
- case SPWPN_REACHING:
- valued *= 50;
- break;
-
- case SPWPN_SPEED:
- valued *= 40;
- break;
-
- case SPWPN_DISTORTION:
- case SPWPN_ELECTROCUTION:
- case SPWPN_PAIN:
- case SPWPN_VORPAL:
- valued *= 30;
- break;
-
- case SPWPN_FLAMING:
- case SPWPN_FREEZING:
- valued *= 25;
- break;
-
- case SPWPN_VENOM:
- valued *= 23;
- break;
-
- case SPWPN_ORC_SLAYING:
- valued *= 21;
- break;
-
- case SPWPN_PROTECTION:
- valued *= 20;
- break;
- }
-
- valued /= 10;
- }
-
- // elf/dwarf
- if (get_equip_race(item) == ISFLAG_ELVEN
- || get_equip_race(item) == ISFLAG_DWARVEN)
- {
- valued *= 12;
- valued /= 10;
- }
-
- // value was "6" but comment read "orc", so I went with comment {dlb}
- if (get_equip_race(item) == ISFLAG_ORCISH)
- {
- valued *= 8;
- valued /= 10;
- }
-
- if (item_ident( item, ISFLAG_KNOW_PLUSES ))
- {
- if (item.plus >= 0)
- {
- valued += item.plus * 2;
- valued *= 10 + 3 * item.plus;
- valued /= 10;
- }
-
- if (item.plus2 >= 0)
- {
- valued += item.plus2 * 2;
- valued *= 10 + 3 * item.plus2;
- valued /= 10;
- }
-
- if (item.plus < 0)
- {
- valued -= 5;
- valued += (item.plus * item.plus * item.plus);
-
- if (valued < 1)
- valued = 1;
- //break;
- }
-
- if (item.plus2 < 0)
- {
- valued -= 5;
- valued += (item.plus2 * item.plus2 * item.plus2);
-
- if (valued < 1)
- valued = 1;
- }
- }
-
- if (is_random_artefact( item ))
- {
- if (item_ident( item, ISFLAG_KNOW_TYPE ))
- valued += (7 * randart_value( item ));
- else
- valued += 50;
- }
- else if (item_ident( item, ISFLAG_KNOW_TYPE )
- && get_equip_desc(item) != 0)
- {
- valued += 20;
- }
-
- if (item_cursed( item ))
- {
- valued *= 6;
- valued /= 10;
- }
- break;
-
- case OBJ_MISSILES: // ammunition
- if (item_ident( item, ISFLAG_KNOW_PLUSES ))
- {
- // assume not cursed (can they be anyway?)
- if (item.plus < 0)
- valued -= 11150;
-
- if (item.plus >= 0)
- valued += (item.plus * 2);
- }
-
- switch (item.sub_type)
- {
- case MI_DART:
- case MI_LARGE_ROCK:
- case MI_STONE:
- case MI_NONE:
- valued++;
- break;
- case MI_ARROW:
- case MI_BOLT:
- case MI_NEEDLE:
- valued += 2;
- break;
- default:
- // was: cases 6 through 16 with empty strcat()'s 15jan2000 {dlb}
- valued += 5;
- break; //strcat(glog , ""); break;
- }
- break;
-
- case OBJ_ARMOUR:
- switch (item.sub_type)
- {
- case ARM_GOLD_DRAGON_ARMOUR:
- valued += 1600;
- break;
-
- case ARM_GOLD_DRAGON_HIDE:
- valued += 1400;
- break;
-
- case ARM_STORM_DRAGON_ARMOUR:
- valued += 1050;
- break;
-
- case ARM_STORM_DRAGON_HIDE:
- valued += 900;
- break;
-
- case ARM_DRAGON_ARMOUR:
- case ARM_ICE_DRAGON_ARMOUR:
- valued += 750;
- break;
-
- case ARM_SWAMP_DRAGON_ARMOUR:
- valued += 650;
- break;
-
- case ARM_DRAGON_HIDE:
- case ARM_CRYSTAL_PLATE_MAIL:
- case ARM_TROLL_LEATHER_ARMOUR:
- case ARM_ICE_DRAGON_HIDE:
- valued += 500;
- break;
-
- case ARM_MOTTLED_DRAGON_ARMOUR:
- case ARM_SWAMP_DRAGON_HIDE:
- valued += 400;
- break;
-
- case ARM_STEAM_DRAGON_ARMOUR:
- case ARM_MOTTLED_DRAGON_HIDE:
- valued += 300;
- break;
-
- case ARM_PLATE_MAIL:
- valued += 230;
- break;
-
- case ARM_STEAM_DRAGON_HIDE:
- valued += 200;
- break;
-
- case ARM_BANDED_MAIL:
- case ARM_CENTAUR_BARDING:
- case ARM_NAGA_BARDING:
- valued += 150;
- break;
-
- case ARM_SPLINT_MAIL:
- valued += 140;
- break;
-
- case ARM_TROLL_HIDE:
- valued += 130;
- break;
-
- case ARM_CHAIN_MAIL:
- valued += 110;
- break;
-
- case ARM_SCALE_MAIL:
- valued += 83;
- break;
-
- case ARM_LARGE_SHIELD:
- valued += 75;
- break;
-
- case ARM_SHIELD:
- valued += 45;
- break;
-
- case ARM_RING_MAIL:
- valued += 40;
- break;
-
- case ARM_HELMET:
- case ARM_BUCKLER:
- valued += 25;
- break;
-
- case ARM_LEATHER_ARMOUR:
- valued += 20;
- break;
-
- case ARM_BOOTS:
- valued += 15;
- break;
-
- case ARM_GLOVES:
- valued += 12;
- break;
-
- case ARM_CLOAK:
- valued += 10;
- break;
-
- case ARM_ROBE:
- valued += 7;
- break;
-
- case ARM_ANIMAL_SKIN:
- valued += 3;
- break;
- }
-
- if (item_ident( item, ISFLAG_KNOW_TYPE ))
- {
- const int sparm = get_armour_ego_type( item );
- switch (sparm)
- {
- case SPARM_NORMAL:
- default:
- valued *= 10;
- break;
-
- case SPARM_ARCHMAGI:
- valued *= 100;
- break;
-
- case SPARM_DARKNESS:
- case SPARM_RESISTANCE:
- valued *= 60;
- break;
-
- case SPARM_POSITIVE_ENERGY:
- valued *= 50;
- break;
-
- case SPARM_MAGIC_RESISTANCE:
- case SPARM_PROTECTION:
- case SPARM_RUNNING:
- valued *= 40;
- break;
-
- case SPARM_COLD_RESISTANCE:
- case SPARM_DEXTERITY:
- case SPARM_FIRE_RESISTANCE:
- case SPARM_SEE_INVISIBLE:
- case SPARM_INTELLIGENCE:
- case SPARM_LEVITATION:
- case SPARM_PRESERVATION:
- case SPARM_STEALTH:
- case SPARM_STRENGTH:
- valued *= 30;
- break;
-
- case SPARM_POISON_RESISTANCE:
- valued *= 20;
- break;
-
- case SPARM_PONDEROUSNESS:
- valued *= 5;
- break;
- }
-
- valued /= 10;
- }
-
- if (get_equip_race(item) == ISFLAG_ELVEN
- || get_equip_race(item) == ISFLAG_DWARVEN)
- {
- valued *= 12;
- valued /= 10;
- }
-
- if (get_equip_race(item) == ISFLAG_ORCISH)
- {
- valued *= 8;
- valued /= 10;
- }
-
- if (item_ident( item, ISFLAG_KNOW_PLUSES ))
- {
- valued += 5;
- if (item.plus >= 0)
- {
- valued += item.plus * 30;
- valued *= 10 + 4 * item.plus;
- valued /= 10;
- }
-
- if (item.plus < 0)
- {
- valued += item.plus * item.plus * item.plus;
-
- if (valued < 1)
- valued = 1;
- }
- }
-
- if (is_random_artefact( item ))
- {
- if (item_ident( item, ISFLAG_KNOW_TYPE ))
- valued += (7 * randart_value( item ));
- else
- valued += 50;
- }
- else if (item_ident( item, ISFLAG_KNOW_TYPE )
- && get_equip_desc(item) != 0)
- {
- valued += 20;
- }
-
- if (item_cursed( item ))
- {
- valued *= 6;
- valued /= 10;
- }
- break;
-
- case OBJ_WANDS:
- if (!id[ IDTYPE_WANDS ][item.sub_type])
- valued += 200;
- else
- {
- switch (item.sub_type)
- {
- case WAND_FIREBALL:
- case WAND_HASTING:
- valued += 600;
- break;
-
- case WAND_HEALING:
- case WAND_TELEPORTATION:
- valued += 500;
- break;
-
- case WAND_INVISIBILITY:
- case WAND_DISINTEGRATION:
- case WAND_LIGHTNING:
- valued += 400;
- break;
-
- case WAND_COLD:
- case WAND_FIRE:
- valued += 350;
- break;
-
- case WAND_DIGGING:
- valued += 200;
- break;
-
- case WAND_FLAME:
- case WAND_FROST:
- case WAND_DRAINING:
- case WAND_PARALYSIS:
- valued += 150;
- break;
-
- case WAND_ENSLAVEMENT:
- case WAND_POLYMORPH_OTHER:
- case WAND_SLOWING:
- valued += 100;
- break;
-
- case WAND_CONFUSION:
- case WAND_MAGIC_DARTS:
- case WAND_RANDOM_EFFECTS:
- default:
- valued += 75;
- break;
- }
-
- if (item_ident( item, ISFLAG_KNOW_PLUSES ))
- {
- if (item.plus == 0)
- valued -= 50;
- else
- valued = (valued * (item.plus + 45)) / 50;
- }
- }
- break;
-
- case OBJ_POTIONS:
- if (!id[3][item.sub_type])
- valued += 9;
- else
- {
- switch (item.sub_type)
- {
- case POT_EXPERIENCE:
- valued += 500;
- break;
- case POT_GAIN_DEXTERITY:
- case POT_GAIN_INTELLIGENCE:
- case POT_GAIN_STRENGTH:
- valued += 350;
- break;
- case POT_CURE_MUTATION:
- valued += 150;
- break;
- case POT_MAGIC:
- valued += 120;
- break;
- case POT_INVISIBILITY:
- valued += 55;
- break;
- case POT_MUTATION:
- case POT_RESTORE_ABILITIES:
- valued += 50;
- break;
- case POT_BERSERK_RAGE:
- case POT_HEAL_WOUNDS:
- valued += 30;
- break;
- case POT_MIGHT:
- case POT_SPEED:
- valued += 25;
- break;
- case POT_HEALING:
- case POT_LEVITATION:
- valued += 20;
- break;
- case POT_PORRIDGE:
- valued += 10;
- break;
- case POT_CONFUSION:
- case POT_DECAY:
- case POT_DEGENERATION:
- case POT_PARALYSIS:
- case POT_POISON:
- case POT_SLOWING:
- case POT_STRONG_POISON:
- case POT_WATER:
- valued++;
- break;
- }
- }
- break;
-
- case OBJ_FOOD:
- switch (item.sub_type)
- {
- case FOOD_ROYAL_JELLY:
- valued = 120;
- break;
-
- case FOOD_MEAT_RATION:
- case FOOD_BREAD_RATION:
- valued = 40;
- break;
-
- case FOOD_HONEYCOMB:
- valued = 25;
- break;
-
- case FOOD_BEEF_JERKY:
- case FOOD_PIZZA:
- valued = 18;
- break;
-
- case FOOD_CHEESE:
- case FOOD_SAUSAGE:
- valued = 15;
- break;
-
- case FOOD_LEMON:
- case FOOD_ORANGE:
- case FOOD_BANANA:
- valued = 12;
- break;
-
- case FOOD_APPLE:
- case FOOD_APRICOT:
- case FOOD_PEAR:
- valued = 8;
- break;
-
- case FOOD_CHOKO:
- case FOOD_LYCHEE:
- case FOOD_RAMBUTAN:
- case FOOD_SNOZZCUMBER:
- case FOOD_CHUNK:
- valued = 4;
- break;
-
- case FOOD_STRAWBERRY:
- case FOOD_GRAPE:
- case FOOD_SULTANA:
- valued = 1;
- break;
- }
- break;
-
- case OBJ_SCROLLS:
- if (!id[1][item.sub_type])
- valued += 10;
- else
- switch (item.sub_type)
- {
- case SCR_ACQUIREMENT:
- valued += 520;
- break;
- case SCR_ENCHANT_WEAPON_III:
- case SCR_VORPALISE_WEAPON:
- valued += 200;
- break;
- case SCR_SUMMONING:
- valued += 95;
- break;
- case SCR_TORMENT:
- valued += 75;
- break;
- case SCR_ENCHANT_WEAPON_II:
- valued += 55;
- break;
- case SCR_RECHARGING:
- valued += 50;
- break;
- case SCR_ENCHANT_ARMOUR:
- case SCR_ENCHANT_WEAPON_I:
- valued += 48;
- break;
- case SCR_FEAR:
- valued += 45;
- break;
- case SCR_MAGIC_MAPPING:
- valued += 35;
- break;
- case SCR_BLINKING:
- case SCR_REMOVE_CURSE:
- case SCR_TELEPORTATION:
- valued += 30;
- break;
- case SCR_DETECT_CURSE:
- case SCR_IDENTIFY:
- valued += 20;
- break;
- case SCR_NOISE:
- case SCR_RANDOM_USELESSNESS:
- valued += 2;
- break;
- case SCR_CURSE_ARMOUR:
- case SCR_CURSE_WEAPON:
- case SCR_FORGETFULNESS:
- case SCR_PAPER:
- case SCR_IMMOLATION:
- valued++;
- break;
- }
- break;
-
- case OBJ_JEWELLERY:
- if (!id[2][item.sub_type])
- valued += 50;
-
- if (item_cursed( item ))
- valued -= 10;
-
- if (id[2][item.sub_type] > 0)
- {
- if (item_ident( item, ISFLAG_KNOW_PLUSES )
- && (item.sub_type == RING_PROTECTION
- || item.sub_type == RING_STRENGTH
- || item.sub_type == RING_EVASION
- || item.sub_type == RING_DEXTERITY
- || item.sub_type == RING_INTELLIGENCE
- || item.sub_type == RING_SLAYING))
- {
- if (item.plus > 0)
- valued += 10 * item.plus;
-
- if (item.sub_type == RING_SLAYING && item.plus2 > 0)
- valued += 10 * item.plus;
- }
-
- switch (item.sub_type)
- {
- case RING_INVISIBILITY:
- valued += 100;
- break;
- case RING_REGENERATION:
- valued += 75;
- break;
- case RING_FIRE:
- case RING_ICE:
- valued += 62;
- break;
- case RING_LIFE_PROTECTION:
- valued += 60;
- break;
- case RING_TELEPORT_CONTROL:
- valued += 42;
- break;
- case RING_MAGICAL_POWER:
- case RING_PROTECTION_FROM_MAGIC:
- valued += 40;
- break;
- case RING_WIZARDRY:
- valued += 35;
- break;
- case RING_LEVITATION:
- case RING_POISON_RESISTANCE:
- case RING_PROTECTION_FROM_COLD:
- case RING_PROTECTION_FROM_FIRE:
- case RING_SLAYING:
- valued += 30;
- break;
- case RING_SUSTAIN_ABILITIES:
- case RING_SUSTENANCE:
- valued += 25;
- break;
- case RING_SEE_INVISIBLE:
- valued += 20;
- break;
- case RING_DEXTERITY:
- case RING_EVASION:
- case RING_INTELLIGENCE:
- case RING_PROTECTION:
- case RING_STRENGTH:
- valued += 10;
- break;
- case RING_TELEPORTATION:
- valued -= 10;
- break;
- case RING_HUNGER:
- valued -= 50;
- break;
- case AMU_THE_GOURMAND:
- valued += 35;
- break;
- case AMU_CLARITY:
- case AMU_RESIST_CORROSION:
- case AMU_RESIST_MUTATION:
- case AMU_RESIST_SLOW:
- case AMU_WARDING:
- valued += 30;
- break;
- case AMU_CONSERVATION:
- case AMU_CONTROLLED_FLIGHT:
- valued += 25;
- break;
- case AMU_RAGE:
- valued += 20;
- break;
- case AMU_INACCURACY:
- valued -= 50;
- break;
- // got to do delusion!
- }
-
- if (is_random_artefact(item))
- {
- if (item_ident(item, ISFLAG_KNOW_TYPE))
- {
- if (valued < 0)
- valued = randart_value( item ) - 5;
- else
- valued += randart_value( item );
- }
- else
- {
- valued += 50;
- }
- }
-
- valued *= 7;
- }
- break;
-
- case OBJ_MISCELLANY:
- if (item_ident( item, ISFLAG_KNOW_TYPE ))
- {
- switch (item.sub_type)
- {
- case MISC_RUNE_OF_ZOT: // upped from 1200 to encourage collecting
- valued += 10000;
- break;
- case MISC_HORN_OF_GERYON:
- valued += 5000;
- break;
- case MISC_DISC_OF_STORMS:
- valued += 2000;
- break;
- case MISC_CRYSTAL_BALL_OF_SEEING:
- valued += 500;
- break;
- case MISC_BOTTLED_EFREET:
- valued += 400;
- break;
- case MISC_CRYSTAL_BALL_OF_FIXATION:
- case MISC_EMPTY_EBONY_CASKET:
- valued += 20;
- break;
- default:
- valued += 500;
- }
- }
- else
- {
- switch (item.sub_type)
- {
- case MISC_RUNE_OF_ZOT:
- valued += 5000;
- break;
- case MISC_HORN_OF_GERYON:
- valued += 1000;
- break;
- case MISC_CRYSTAL_BALL_OF_SEEING:
- valued += 450;
- break;
- case MISC_BOTTLED_EFREET:
- valued += 350;
- break;
- case MISC_DECK_OF_TRICKS:
- valued += 100;
- break;
- default:
- valued += 400;
- }
- }
- break;
-
- //case 10: break;
-
- case OBJ_BOOKS:
- valued = 150 + (item_ident( item, ISFLAG_KNOW_TYPE )
- ? book_rarity(item.sub_type) * 50 : 0);
- break;
-
- case OBJ_STAVES:
- if (!item_ident( item, ISFLAG_KNOW_TYPE ))
- valued = 120;
- else if (item.sub_type == STAFF_SMITING
- || item.sub_type == STAFF_STRIKING
- || item.sub_type == STAFF_WARDING
- || item.sub_type == STAFF_DISCOVERY)
- {
- valued = 150;
- }
- else
- valued = 250;
-
- if (item_is_rod( item ) && item_ident( item, ISFLAG_KNOW_PLUSES ))
- valued += 50 * (item.plus2 / ROD_CHARGE_MULT);
-
- break;
-
- case OBJ_ORBS:
- valued = 250000;
- break;
- } // end switch
-
- if (valued < 1)
- valued = 1;
-
- valued *= item.quantity;
-
- return (valued);
-} // end item_value()
-
-void shop(void)
-{
- unsigned char i = 0;
-
- for (i = 0; i < MAX_SHOPS; i++)
- {
- if (env.shop[i].x == you.x_pos && env.shop[i].y == you.y_pos)
- break;
- }
-
- if (i == MAX_SHOPS)
- {
- mpr("Help! Non-existent shop.");
- return;
- }
-
- id_arr identy;
-
- save_id(identy);
-
- in_a_shop(i, identy);
- you.redraw_gold = 1;
- burden_change();
-
- redraw_screen();
-} // end shop()
-
-const shop_struct *get_shop(int sx, int sy)
-{
- if (grd[sx][sy] != DNGN_ENTER_SHOP)
- return (NULL);
-
- // find shop
- for (int shoppy = 0; shoppy < MAX_SHOPS; shoppy ++)
- {
- // find shop index plus a little bit of paranoia
- if (env.shop[shoppy].x == sx && env.shop[shoppy].y == sy &&
- env.shop[shoppy].type != SHOP_UNASSIGNED)
- {
- return (&env.shop[shoppy]);
- }
- }
- return (NULL);
-}
-
-const char *shop_name(int sx, int sy)
-{
- static char sh_name[80];
- const shop_struct *cshop = get_shop(sx, sy);
-
- // paranoia
- if (grd[sx][sy] != DNGN_ENTER_SHOP)
- return ("");
-
- if (!cshop)
- {
- mpr("Help! Non-existent shop.");
- return ("Buggy Shop");
- }
-
- int shop_type = cshop->type;
-
- char st_p[ITEMNAME_SIZE];
-
- unsigned long seed = static_cast<unsigned long>( cshop->keeper_name[0] )
- | (static_cast<unsigned long>( cshop->keeper_name[1] ) << 8)
- | (static_cast<unsigned long>( cshop->keeper_name[1] ) << 16);
- make_name( seed, false, st_p );
-
- strcpy(sh_name, st_p);
- strcat(sh_name, "'s ");
-
- if (shop_type == SHOP_WEAPON_ANTIQUE || shop_type == SHOP_ARMOUR_ANTIQUE)
- strcat( sh_name, "Antique " );
-
- strcat(sh_name, (shop_type == SHOP_WEAPON
- || shop_type == SHOP_WEAPON_ANTIQUE) ? "Weapon" :
- (shop_type == SHOP_ARMOUR
- || shop_type == SHOP_ARMOUR_ANTIQUE) ? "Armour" :
-
- (shop_type == SHOP_JEWELLERY) ? "Jewellery" :
- (shop_type == SHOP_WAND) ? "Magical Wand" :
- (shop_type == SHOP_BOOK) ? "Book" :
- (shop_type == SHOP_FOOD) ? "Food" :
- (shop_type == SHOP_SCROLL) ? "Magic Scroll" :
- (shop_type == SHOP_GENERAL_ANTIQUE) ? "Assorted Antiques" :
- (shop_type == SHOP_DISTILLERY) ? "Distillery" :
- (shop_type == SHOP_GENERAL) ? "General Store"
- : "Bug");
-
-
- if (shop_type != SHOP_GENERAL
- && shop_type != SHOP_GENERAL_ANTIQUE && shop_type != SHOP_DISTILLERY)
- {
- int temp = sx + sy % 4;
- strcat( sh_name, (temp == 0) ? " Shoppe" :
- (temp == 1) ? " Boutique" :
- (temp == 2) ? " Emporium"
- : " Shop" );
- }
-
- return (sh_name);
-}
diff --git a/stone_soup/crawl-ref/source/shopping.h b/stone_soup/crawl-ref/source/shopping.h
deleted file mode 100644
index 8891f16eb9..0000000000
--- a/stone_soup/crawl-ref/source/shopping.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * File: shopping.cc
- * Summary: Shop keeper functions.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef SHOPPING_H
-#define SHOPPING_H
-
-#include "externs.h"
-
-typedef FixedArray < int, 4, 50 > id_fix_arr;
-typedef char id_arr[4][50];
-
-void shop_init_id_type(int shoptype, id_fix_arr &shop_id);
-void shop_uninit_id_type(int shoptype, const id_fix_arr &shop_id);
-
-int randart_value( const item_def &item );
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: chardump - invent - ouch - religion - shopping
- * *********************************************************************** */
-
-// ident == true overrides the item ident level and gives the price
-// as if the item was fully id'd
-unsigned int item_value( item_def item, id_arr id, bool ident = false );
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: misc
- * *********************************************************************** */
-void shop(void);
-
-const shop_struct *get_shop(int sx, int sy);
-
-// last updated 06mar2001 {gdl}
-/* ***********************************************************************
- * called from: items direct
- * *********************************************************************** */
-const char *shop_name(int sx, int sy);
-
-#endif
diff --git a/stone_soup/crawl-ref/source/skills.cc b/stone_soup/crawl-ref/source/skills.cc
deleted file mode 100644
index db7fe62372..0000000000
--- a/stone_soup/crawl-ref/source/skills.cc
+++ /dev/null
@@ -1,454 +0,0 @@
-/*
- * File: skills.cc
- * Summary: Skill exercising functions.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <3> 8/08/99 BWR Increased skill cost in midgame
- *
- * <2> 7/31/99 BWR Inc skill_point granularity,
- * added MAX_SPENDING_LIMIT
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "skills.h"
-
-#include <string.h>
-#include <stdlib.h>
-
-#include "externs.h"
-
-#include "macro.h"
-#include "player.h"
-#include "skills2.h"
-#include "stuff.h"
-
-
-// MAX_COST_LIMIT is the maximum XP amount it will cost to raise a skill
-// by 10 skill points (ie one standard practice).
-//
-// MAX_SPENDING_LIMIT is the maximum XP amount we allow the player to
-// spend on a skill in a single raise.
-//
-// Note that they don't have to be equal, but it is important to make
-// sure that they're set so that the spending limit will always allow
-// for 1 skill point to be earned.
-#define MAX_COST_LIMIT 250
-#define MAX_SPENDING_LIMIT 250
-
-static int exercise2( int exsk );
-
-// These values were calculated by running a simulation of gaining skills.
-// The goal is to try and match the old cost system which used the player's
-// experience level (which has a number of problems) so things shouldn't
-// seem too different to the player... but we still try to err on the
-// high side for the lower levels. -- bwr
-int skill_cost_needed( int level )
-{
- // The average starting skill total is actually lower, but
- // some classes get about 2200, and they would probably be
- // start around skill cost level 3 if we used the average. -- bwr
- int ret = 2200;
-
- switch (level)
- {
- case 1: ret = 0; break;
-
- case 2: ret += 250; break; // 250 -- big because of initial 25 pool
- case 3: ret += 350; break; // 100
- case 4: ret += 550; break; // 200
- case 5: ret += 900; break; // 350
- case 6: ret += 1300; break; // 400
- case 7: ret += 1900; break; // 600
- case 8: ret += 2800; break; // 900
- case 9: ret += 4200; break; // 1400
- case 10: ret += 5900; break; // 1700
- case 11: ret += 9000; break; // 3100
-
- default:
- ret += 9000 + (4000 * (level - 11));
- break;
- }
-
- return (ret);
-}
-
-void calc_total_skill_points( void )
-{
- int i;
-
- you.total_skill_points = 0;
-
- for (i = 0; i < NUM_SKILLS; i++)
- {
- you.total_skill_points += you.skill_points[i];
- }
-
- for (i = 1; i <= 27; i++)
- {
- if (you.total_skill_points < skill_cost_needed(i))
- break;
- }
-
- you.skill_cost_level = i - 1;
-
-#if DEBUG_DIAGNOSTICS
- you.redraw_experience = 1;
-#endif
-}
-
-// skill_cost_level makes skills more expensive for more experienced characters
-// skill_level makes higher skills more expensive
-static int calc_skill_cost( int skill_cost_level, int skill_level )
-{
- int ret = 1 + skill_level;
-
- // does not yet allow for loss of skill levels.
- if (skill_level > 9)
- {
- ret *= (skill_level - 7);
- ret /= 3;
- }
-
- if (skill_cost_level > 4)
- ret += skill_cost_level - 4;
- if (skill_cost_level > 7)
- ret += skill_cost_level - 7;
- if (skill_cost_level > 10)
- ret += skill_cost_level - 10;
- if (skill_cost_level > 13)
- ret += skill_cost_level - 13;
- if (skill_cost_level > 16)
- ret += skill_cost_level - 16;
-
- if (skill_cost_level > 10)
- {
- ret *= (skill_cost_level - 5);
- ret /= 5;
- }
-
- if (skill_level > 7)
- ret += 1;
- if (skill_level > 9)
- ret += 2;
- if (skill_level > 11)
- ret += 3;
- if (skill_level > 13)
- ret += 4;
- if (skill_level > 15)
- ret += 5;
-
- if (ret > MAX_COST_LIMIT)
- ret = MAX_COST_LIMIT;
-
- return (ret);
-}
-
-// returns total number of skill points gained
-int exercise(int exsk, int deg)
-{
- int ret = 0;
-
- while (deg > 0)
- {
- if (you.exp_available <= 0 || you.skills[exsk] >= 27)
- break;
-
- if (you.practise_skill[exsk] || one_chance_in(4))
- ret += exercise2( exsk );
-
- deg--;
- }
-
-#ifdef DEBUG_DIAGNOSTICS
- if (ret)
- {
- mprf(MSGCH_DIAGNOSTICS,
- "Exercised %s (deg: %d) by %d",
- skill_name(exsk),
- deg,
- ret);
- }
-#endif
-
- return (ret);
-} // end exercise()
-
-static int exercise2( int exsk )
-{
- int deg = 1;
- int bonus = 0;
- char old_best_skill = best_skill(SK_FIGHTING, (NUM_SKILLS - 1), 99);
-
- int skill_change = calc_skill_cost(you.skill_cost_level, you.skills[exsk]);
- int i;
-
- // being good at some weapons makes others easier to learn:
- if (exsk < SK_SLINGS)
- {
- /* blades to blades */
- if ((exsk == SK_SHORT_BLADES || exsk == SK_LONG_SWORDS)
- && (you.skills[SK_SHORT_BLADES] > you.skills[exsk]
- || you.skills[SK_LONG_SWORDS] > you.skills[exsk]))
- {
- bonus += random2(3);
- }
-
- /* Axes and Polearms */
- if ((exsk == SK_AXES || exsk == SK_POLEARMS)
- && (you.skills[SK_AXES] > you.skills[exsk]
- || you.skills[SK_POLEARMS] > you.skills[exsk]))
- {
- bonus += random2(3);
- }
-
- /* Polearms and Staves */
- if ((exsk == SK_POLEARMS || exsk == SK_STAVES)
- && (you.skills[SK_POLEARMS] > you.skills[exsk]
- || you.skills[SK_STAVES] > you.skills[exsk]))
- {
- bonus += random2(3);
- }
-
- /* Axes and Maces */
- if ((exsk == SK_AXES || exsk == SK_MACES_FLAILS)
- && (you.skills[SK_AXES] > you.skills[exsk]
- || you.skills[SK_MACES_FLAILS] > you.skills[exsk]))
- {
- bonus += random2(3);
- }
- }
-
- // Quick fix for the fact that stealth can't be gained fast enough to
- // keep up with the monster levels, this should speed its advancement
- if (exsk == SK_STEALTH)
- bonus += random2(3);
-
- // spell casting is cheaper early on, and elementals hinder each other
- if (exsk >= SK_SPELLCASTING)
- {
- if (you.skill_cost_level < 5)
- {
- skill_change /= 2;
- }
- else if (you.skill_cost_level < 15)
- {
- skill_change *= (10 + (you.skill_cost_level - 5));
- skill_change /= 20;
- }
-
- // being good at elemental magic makes other elements harder to learn:
- if (exsk >= SK_FIRE_MAGIC && exsk <= SK_EARTH_MAGIC
- && (you.skills[SK_FIRE_MAGIC] > you.skills[exsk]
- || you.skills[SK_ICE_MAGIC] > you.skills[exsk]
- || you.skills[SK_AIR_MAGIC] > you.skills[exsk]
- || you.skills[SK_EARTH_MAGIC] > you.skills[exsk]))
- {
- if (one_chance_in(3))
- return (0);
- }
-
- // some are direct opposites
- if ((exsk == SK_FIRE_MAGIC || exsk == SK_ICE_MAGIC)
- && (you.skills[SK_FIRE_MAGIC] > you.skills[exsk]
- || you.skills[SK_ICE_MAGIC] > you.skills[exsk]))
- {
- // of course, this is cumulative with the one above.
- if (!one_chance_in(3))
- return (0);
- }
-
- if ((exsk == SK_AIR_MAGIC || exsk == SK_EARTH_MAGIC)
- && (you.skills[SK_AIR_MAGIC] > you.skills[exsk]
- || you.skills[SK_EARTH_MAGIC] > you.skills[exsk]))
- {
- if (!one_chance_in(3))
- return (0);
- }
-
- // experimental restriction (too many spell schools) -- bwr
- int skill_rank = 1;
-
- for (i = SK_CONJURATIONS; i <= SK_DIVINATIONS; i++)
- {
- if (you.skills[exsk] < you.skills[i])
- skill_rank++;
- }
-
- // Things get progressively harder, but not harder than
- // the Fire-Air or Ice-Earth level.
- if (skill_rank > 3 && one_chance_in(10 - skill_rank))
- return (0);
- }
-
- int fraction = 0;
- int spending_limit = (you.exp_available < MAX_SPENDING_LIMIT)
- ? you.exp_available : MAX_SPENDING_LIMIT;
-
- // handle fractional learning
- if (skill_change > spending_limit)
- {
- // This system is a bit hard on missile weapons in the late game
- // since they require expendable ammo in order to practise.
- // Increasing the "deg"ree of exercise would make missile
- // weapons too easy earlier on, so instead we're giving them
- // a special case here.
- if ((exsk != SK_DARTS && exsk != SK_BOWS && exsk != SK_CROSSBOWS)
- || skill_change > you.exp_available)
- {
- fraction = (spending_limit * 10) / skill_change;
- skill_change = (skill_change * fraction) / 10;
-
- deg = (deg * fraction) / 10;
-
- if (deg == 0)
- bonus = (bonus * fraction) / 10;
- }
- else
- {
- if ((skill_change / 2) > MAX_SPENDING_LIMIT)
- {
- deg = 0;
- fraction = 5;
- }
- else
- {
- deg = 1;
- }
-
- skill_change = spending_limit;
- }
- }
-
- skill_change -= random2(5);
-
- if (skill_change < 1)
- {
- // No free lunch, this is a problem now that we don't
- // have overspending.
- if (deg > 0 || fraction > 0 || bonus > 0)
- skill_change = 1;
- else
- skill_change = 0;
- }
-
- // Can safely return at any stage before this
- int skill_inc = (deg + bonus) * 10 + fraction;
-
- // Starting to learn skills is easier if the appropriate stat is high
- if (you.skills[exsk] == 0)
- {
- if ((exsk >= SK_FIGHTING && exsk <= SK_STAVES) || exsk == SK_ARMOUR)
- {
- // These skills are easier for the strong
- skill_inc *= ((you.strength < 5) ? 5 : you.strength);
- skill_inc /= 10;
- }
- else if (exsk >= SK_SLINGS && exsk <= SK_UNARMED_COMBAT)
- {
- // These skills are easier for the dexterous
- // Note: Armour is handled above.
- skill_inc *= ((you.dex < 5) ? 5 : you.dex);
- skill_inc /= 10;
- }
- else if (exsk >= SK_SPELLCASTING && exsk <= SK_POISON_MAGIC)
- {
- // These skills are easier for the smart
- skill_inc *= ((you.intel < 5) ? 5 : you.intel);
- skill_inc /= 10;
- }
- }
-
- if (skill_inc <= 0)
- return (0);
-
- you.skill_points[exsk] += skill_inc;
- you.exp_available -= skill_change;
-
- you.total_skill_points += skill_inc;
- if (you.skill_cost_level < 27
- && you.total_skill_points >= skill_cost_needed(you.skill_cost_level + 1))
- {
- you.skill_cost_level++;
- }
-
- if (you.exp_available < 0)
- you.exp_available = 0;
-
- you.redraw_experience = 1;
-
-/*
- New (LH): debugging bit: when you exercise a skill, displays the skill
- exercised and how much you spent on it. Too irritating to be a regular
- WIZARD feature.
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "Exercised %s * %d for %d xp.",
- skill_name(exsk), skill_inc, skill_change );
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-*/
-
- if (you.skill_points[exsk] >
- (skill_exp_needed(you.skills[exsk] + 2)
- * species_skills(exsk, you.species) / 100))
- {
- strcpy(info, "Your ");
- strcat(info, skill_name(exsk));
- strcat(info, " skill increases!");
- mpr(info, MSGCH_INTRINSIC_GAIN);
-
- you.skills[exsk]++;
-
- // Recalculate this skill's order for tie breaking skills
- // at its new level. See skills2.cc::init_skill_order()
- // for more details. -- bwr
- you.skill_order[exsk] = 0;
- for (i = SK_FIGHTING; i < NUM_SKILLS; i++)
- {
- if (i == exsk)
- continue;
-
- if (you.skills[i] >= you.skills[exsk])
- you.skill_order[exsk]++;
- }
-
- if (exsk == SK_FIGHTING)
- calc_hp();
-
- if (exsk == SK_INVOCATIONS || exsk == SK_SPELLCASTING)
- {
- calc_mp();
- }
-
- if (exsk == SK_DODGING || exsk == SK_ARMOUR)
- you.redraw_evasion = 1;
-
- if (exsk == SK_ARMOUR || exsk == SK_SHIELDS
- || exsk == SK_ICE_MAGIC || exsk == SK_EARTH_MAGIC
- || you.duration[ DUR_TRANSFORMATION ] > 0)
- {
- you.redraw_armour_class = 1;
- }
-
- const unsigned char best = best_skill( SK_FIGHTING,
- (NUM_SKILLS - 1), 99 );
-
- const unsigned char best_spell = best_skill( SK_SPELLCASTING,
- SK_POISON_MAGIC, 99 );
-
- if ((exsk == SK_SPELLCASTING)
- && (you.skills[exsk] == 1 && best_spell == SK_SPELLCASTING))
- {
- mpr("You're starting to get the hang of this magic thing.");
- }
-
- if (best != old_best_skill || old_best_skill == exsk)
- {
- redraw_skill( you.your_name, player_title() );
- }
- }
- return (skill_inc);
-} // end exercise2()
diff --git a/stone_soup/crawl-ref/source/skills.h b/stone_soup/crawl-ref/source/skills.h
deleted file mode 100644
index 35136ec427..0000000000
--- a/stone_soup/crawl-ref/source/skills.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * File: skills.cc
- * Summary: Skill exercising functions.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef SKILLS_H
-#define SKILLS_H
-
-int skill_cost_needed( int level );
-void calc_total_skill_points( void );
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: ability - bang - beam - debug - fight - it_use3 - item_use -
- * items - misc - spell
- * *********************************************************************** */
-int exercise(int exsk, int deg);
-
-
-#endif
diff --git a/stone_soup/crawl-ref/source/skills2.cc b/stone_soup/crawl-ref/source/skills2.cc
deleted file mode 100644
index b4a0cbca9f..0000000000
--- a/stone_soup/crawl-ref/source/skills2.cc
+++ /dev/null
@@ -1,2366 +0,0 @@
-/*
- * File: skills2.cc
- * Summary: More skill related functions.
- * Written by: Linley Henzell
- *
- * Modified for Crawl Reference by $Author$ on $Date$
- *
- * Change History (most recent first):
- *
- * 01aug2000 jmf RESTORED TITLES TO THEIR FORMER GLORY! MUA-HA!
- * <4> 22Jul2000 GDL added warning for low throwing skill
- * Changed a few titles.
- * <3> 5/20/99 BWR Changed Trapper titles, avoided
- * overflow on the weapon skill
- * column.
- * <2> -/--/-- WL Extensive mods from Wladimir van der Laan.
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "skills2.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-
-#ifdef DOS
-#include <conio.h>
-#endif
-
-#include "externs.h"
-#include "fight.h"
-#include "player.h"
-#include "randart.h"
-#include "religion.h"
-#include "stuff.h"
-#include "wpn-misc.h"
-#include "view.h"
-
-/* jmf: some references for words I used below:
- Peltast http://www.geocities.com/Athens/Aegean/9659/shields_main.htm
- Phalangite http://www.users.cts.com/funtv/j/jjartist/EpiroteScenario1.htm
- Yeoman: http://snt.student.utwente.nl/campus/sagi/artikel/longbow/longbow.html
-*/
-
-// Note: Even though %s could be used with most of these, remember that
-// the character's race will be listed on the next line. Its only really
-// intended for cases where things might be really awkward without it. -- bwr
-
-const char *skills[50][6] = {
- {"Fighting", "Skirmisher", "Grunt", "Veteran", "Warrior", "Slayer"}, // 0
- {"Short Blades", "Stabber", "Cutter", "Knifefighter", "Eviscerator", "Blademaster"},
- {"Long Blades", "Slasher", "Slicer", "Fencer", "Swordfighter", "Swordmaster"},
- {NULL}, // 3- was: great swords {dlb}
- {"Axes", "Chopper", "Cleaver", "Hacker", "Severer", "Axe Maniac"},
- {"Maces & Flails", "Basher", "Cudgeler", "Shatterer", "Bludgeoner", "Skullcrusher"}, // 5
- {"Polearms", "Spear-Bearer", "Pike-%s", "Phalangite", "Lancer", "Halberdier"},
- {"Staves", "Twirler", "Cruncher", "Smasher", "Stickfighter", "Skullbreaker"},
-
- {"Slings", "Vandal", "Slinger", "Whirler", "Crazy %s", "Very Crazy %s"},
- {"Bows", "Shooter", "Yeoman", "Archer", "Merry %s", "Merry %s"},
- {"Crossbows", "Shooter", "Sharpshooter", "Archer", "%s Ballista", "%s Ballista"}, // 10
- {"Darts", "Dart Thrower", "Hurler", "Hurler, First Class", "%s Darts Champion", "Universal Darts Champion"},
- {"Ranged Combat", "Chucker", "Thrower", "Deadly Accurate", "Hawkeye", "Sniper"},
-
- {"Armour", "Covered", "Protected", "Tortoise", "Impregnable", "Invulnerable"},
- {"Dodging", "Ducker", "Dodger", "Nimble", "Spry", "Acrobat"},
- {"Stealth", "Footpad", "Sneak", "Covert", "Unseen", "Imperceptible"},
- {"Stabbing", "Miscreant", "Blackguard", "Backstabber", "Cutthroat", "Politician"},
- {"Shields", "Shield-Bearer", "Blocker", "%s Barricade", "Peltast", "Hoplite"},
- {"Traps & Doors", "Disarmer", "Trapper", "Architect", "Engineer", "Dungeon Master"},
-
- // STR based fighters, for DEX/martial arts titles see below
- {"Unarmed Combat", "Ruffian", "Grappler", "Brawler", "Wrestler", "Boxer" },
-
- {NULL}, // 20- empty
- {NULL}, // 21- empty
- {NULL}, // 22- empty
- {NULL}, // 23- empty
- {NULL}, // 24- empty
-
- {"Spellcasting", "Magician", "Thaumaturge", "Eclecticist", "Sorcerer", "Archmage"}, // 25
- {"Conjurations", "Ruinous", "Conjurer", "Destroyer", "Devastator", "Annihilator"},
- {"Enchantments", "Charm-Maker", "Infuser", "Bewitcher", "Enchanter", "Spellbinder"},
- {"Summonings", "Caller", "Summoner", "Convoker", "Demonologist", "Hellbinder"},
- {"Necromancy", "Grave Robber", "Reanimator", "Necromancer", "Thanatomancer", "%s of Death"},
- {"Translocations", "Jumper", "Blinker", "Shifter", "Portalist", "Plane Walker"}, // 30
- {"Transmigration", "Changer", "Transmogrifier", "Transformer", "Alchemist", "Transmuter"},
- {"Divinations", "Seer", "Soothsayer", "Diviner", "Augur", "Oracle"},
-
- {"Fire Magic", "Firebug", "Arsonist", "Scorcher", "Pyromancer", "Infernalist"},
- {"Ice Magic", "Chiller", "Frost Mage", "Ice Mage", "Cryomancer", "Englaciator"},
- {"Air Magic", "Wind Mage", "Cloud Mage", "Air Mage", "Sky Mage", "Storm Mage"}, // 35
- {"Earth Magic", "Digger", "Geomancer", "Earth Mage", "Metallomancer", "Petrodigitator"},
- {"Poison Magic", "Stinger", "Tainter", "Polluter", "Poisoner", "Envenomancer"},
-
- {"Invocations", "Believer", "Servant", "Worldly Agent", "Theurge", "Avatar"}, // 38
- {"Evocations", "Charlatan", "Prestidigitator", "Fetichist", "Evocator", "Talismancer"}, // 39
-
-/*NOTE: If more skills are added, must change ranges in level_change() in player.cc */
-/*{"", "", "", "", ""}, */
-
- {NULL}, // 40- empty
- {NULL}, // 41- empty
- {NULL}, // 42- empty
- {NULL}, // 43- empty
- {NULL}, // 44- empty
- {NULL}, // 45- empty
- {NULL}, // 46- empty
- {NULL}, // 47- empty
- {NULL}, // 48- empty
- {NULL} // 49- empty {end of array}
-};
-
-const char *martial_arts_titles[6] =
- {"Unarmed Combat", "Martial Artist", "Black Belt", "Sensei", "Master", "Grand Master"};
-
-
-/* Note that this (humans have 100 for all skills) is assumed in the
- level_change function in player.cc, if CLASSES is def'd
-
- 3.10: but it never is, and CLASSES is probably broken now. Anyway,
- the Spellcasting skill (25) is actually about 130% of what is shown here.
- */
-const int spec_skills[ NUM_SPECIES ][40] = {
- { // SP_HUMAN (1)
- 100, // SK_FIGHTING
- 100, // SK_SHORT_BLADES
- 100, // SK_LONG_SWORDS
- 100, // SK_UNUSED_1
- 100, // SK_AXES
- 100, // SK_MACES_FLAILS
- 100, // SK_POLEARMS
- 100, // SK_STAVES
- 100, // SK_SLINGS
- 100, // SK_BOWS
- 100, // SK_CROSSBOWS
- 100, // SK_DARTS
- 100, // SK_RANGED_COMBAT
- 100, // SK_ARMOUR
- 100, // SK_DODGING
- 100, // SK_STEALTH
- 100, // SK_STABBING
- 100, // SK_SHIELDS
- 100, // SK_TRAPS_DOORS
- 100, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // SK_SPELLCASTING
- 100, // SK_CONJURATIONS
- 100, // SK_ENCHANTMENTS
- 100, // SK_SUMMONINGS
- 100, // SK_NECROMANCY
- 100, // SK_TRANSLOCATIONS
- 100, // SK_TRANSMIGRATION
- 100, // SK_DIVINATIONS
- 100, // SK_FIRE_MAGIC
- 100, // SK_ICE_MAGIC
- 100, // SK_AIR_MAGIC
- 100, // SK_EARTH_MAGIC
- 100, // SK_POISON_MAGIC
- 100, // SK_INVOCATIONS
- 100, // SK_EVOCATIONS
- },
-
- { // SP_ELF (2)
- 120, // SK_FIGHTING
- 80, // SK_SHORT_BLADES
- 80, // SK_LONG_SWORDS
- 110, // SK_UNUSED_1
- 120, // SK_AXES
- 130, // SK_MACES_FLAILS
- 130, // SK_POLEARMS
- 100, // SK_STAVES
- 120, // SK_SLINGS
- 60, // SK_BOWS
- 100, // SK_CROSSBOWS
- 90, // SK_DARTS
- 80, // SK_RANGED_COMBAT
- 120, // SK_ARMOUR
- 80, // SK_DODGING
- 80, // SK_STEALTH
- 100, // SK_STABBING
- 120, // SK_SHIELDS
- 100, // SK_TRAPS_DOORS
- 110, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 80, // SK_SPELLCASTING
- 105, // SK_CONJURATIONS
- 70, // SK_ENCHANTMENTS
- 100, // SK_SUMMONINGS
- 120, // SK_NECROMANCY
- 100, // SK_TRANSLOCATIONS
- 100, // SK_TRANSMIGRATION
- 100, // SK_DIVINATIONS
- 100, // SK_FIRE_MAGIC
- 100, // SK_ICE_MAGIC
- 70, // SK_AIR_MAGIC
- 130, // SK_EARTH_MAGIC
- 110, // SK_POISON_MAGIC
- 100, // SK_INVOCATIONS
- 80, // SK_EVOCATIONS
- },
-
- { // SP_HIGH_ELF (3)
- 100, // SK_FIGHTING
- 70, // SK_SHORT_BLADES
- 70, // SK_LONG_SWORDS
- 115, // SK_UNUSED_1
- 130, // SK_AXES
- 150, // SK_MACES_FLAILS
- 150, // SK_POLEARMS
- 100, // SK_STAVES
- 140, // SK_SLINGS
- 60, // SK_BOWS
- 100, // SK_CROSSBOWS
- 90, // SK_DARTS
- 80, // SK_RANGED_COMBAT
- 110, // SK_ARMOUR
- 90, // SK_DODGING
- 90, // SK_STEALTH
- 110, // SK_STABBING
- 110, // SK_SHIELDS
- 100, // SK_TRAPS_DOORS
- 130, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 70, // SK_SPELLCASTING
- 90, // SK_CONJURATIONS
- 70, // SK_ENCHANTMENTS
- 110, // SK_SUMMONINGS
- 130, // SK_NECROMANCY
- 90, // SK_TRANSLOCATIONS
- 90, // SK_TRANSMIGRATION
- 110, // SK_DIVINATIONS
- 100, // SK_FIRE_MAGIC
- 100, // SK_ICE_MAGIC
- 70, // SK_AIR_MAGIC
- 130, // SK_EARTH_MAGIC
- 130, // SK_POISON_MAGIC
- 100, // SK_INVOCATIONS
- 100, // SK_EVOCATIONS
- },
-
- { // SP_GREY_ELF (4)
- 140, // SK_FIGHTING
- 90, // SK_SHORT_BLADES
- 95, // SK_LONG_SWORDS
- 120, // SK_UNUSED_1
- 140, // SK_AXES
- 160, // SK_MACES_FLAILS
- 160, // SK_POLEARMS
- 100, // SK_STAVES
- 130, // SK_SLINGS
- 70, // SK_BOWS
- 100, // SK_CROSSBOWS
- 90, // SK_DARTS
- 80, // SK_RANGED_COMBAT
- 140, // SK_ARMOUR
- 75, // SK_DODGING
- 70, // SK_STEALTH
- 100, // SK_STABBING
- 140, // SK_SHIELDS
- 100, // SK_TRAPS_DOORS
- 130, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 60, // SK_SPELLCASTING
- 90, // SK_CONJURATIONS
- 50, // SK_ENCHANTMENTS
- 90, // SK_SUMMONINGS
- 130, // SK_NECROMANCY
- 80, // SK_TRANSLOCATIONS
- 80, // SK_TRANSMIGRATION
- 80, // SK_DIVINATIONS
- 90, // SK_FIRE_MAGIC
- 90, // SK_ICE_MAGIC
- 60, // SK_AIR_MAGIC
- 150, // SK_EARTH_MAGIC
- 110, // SK_POISON_MAGIC
- 100, // SK_INVOCATIONS
- 90, // SK_EVOCATIONS
- },
-
- { // SP_DEEP_ELF (5)
- 150, // SK_FIGHTING
- 100, // SK_SHORT_BLADES
- 105, // SK_LONG_SWORDS
- 120, // SK_UNUSED_1
- 150, // SK_AXES
- 165, // SK_MACES_FLAILS
- 165, // SK_POLEARMS
- 100, // SK_STAVES
- 135, // SK_SLINGS
- 74, // SK_BOWS
- 75, // SK_CROSSBOWS
- 75, // SK_DARTS
- 80, // SK_RANGED_COMBAT
- 140, // SK_ARMOUR
- 70, // SK_DODGING
- 65, // SK_STEALTH
- 80, // SK_STABBING
- 140, // SK_SHIELDS
- 100, // SK_TRAPS_DOORS
- 130, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 55, // SK_SPELLCASTING
- 80, // SK_CONJURATIONS
- 50, // SK_ENCHANTMENTS
- 80, // SK_SUMMONINGS
- 70, // SK_NECROMANCY
- 75, // SK_TRANSLOCATIONS
- 75, // SK_TRANSMIGRATION
- 75, // SK_DIVINATIONS
- 90, // SK_FIRE_MAGIC
- 90, // SK_ICE_MAGIC
- 80, // SK_AIR_MAGIC
- 100, // SK_EARTH_MAGIC
- 80, // SK_POISON_MAGIC
- 100, // SK_INVOCATIONS
- 90, // SK_EVOCATIONS
- },
-
- { // SP_SLUDGE_ELF (6)
- 80, // SK_FIGHTING
- 110, // SK_SHORT_BLADES
- 110, // SK_LONG_SWORDS
- 110, // SK_UNUSED_1
- 130, // SK_AXES
- 140, // SK_MACES_FLAILS
- 140, // SK_POLEARMS
- 100, // SK_STAVES
- 100, // SK_SLINGS
- 100, // SK_BOWS
- 100, // SK_CROSSBOWS
- 100, // SK_DARTS
- 70, // SK_RANGED_COMBAT
- 140, // SK_ARMOUR
- 70, // SK_DODGING
- 75, // SK_STEALTH
- 100, // SK_STABBING
- 130, // SK_SHIELDS
- 100, // SK_TRAPS_DOORS
- 80, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 70, // SK_SPELLCASTING
- 130, // SK_CONJURATIONS
- 130, // SK_ENCHANTMENTS
- 90, // SK_SUMMONINGS
- 90, // SK_NECROMANCY
- 100, // SK_TRANSLOCATIONS
- 60, // SK_TRANSMIGRATION
- 130, // SK_DIVINATIONS
- 80, // SK_FIRE_MAGIC
- 80, // SK_ICE_MAGIC
- 80, // SK_AIR_MAGIC
- 80, // SK_EARTH_MAGIC
- 80, // SK_POISON_MAGIC
- 100, // SK_INVOCATIONS
- 110, // SK_EVOCATIONS
- },
-
- { // SP_HILL_DWARF (7)
- 70, // SK_FIGHTING
- 80, // SK_SHORT_BLADES
- 80, // SK_LONG_SWORDS
- 90, // SK_UNUSED_1
- 60, // SK_AXES
- 70, // SK_MACES_FLAILS
- 110, // SK_POLEARMS
- 130, // SK_STAVES
- 130, // SK_SLINGS
- 150, // SK_BOWS
- 120, // SK_CROSSBOWS
- 120, // SK_DARTS
- 120, // SK_RANGED_COMBAT
- 70, // SK_ARMOUR
- 120, // SK_DODGING
- 150, // SK_STEALTH
- 140, // SK_STABBING
- 70, // SK_SHIELDS
- 100, // SK_TRAPS_DOORS
- 100, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 160, // SK_SPELLCASTING
- 120, // SK_CONJURATIONS
- 150, // SK_ENCHANTMENTS
- 150, // SK_SUMMONINGS
- 160, // SK_NECROMANCY
- 150, // SK_TRANSLOCATIONS
- 120, // SK_TRANSMIGRATION
- 130, // SK_DIVINATIONS
- 80, // SK_FIRE_MAGIC
- 120, // SK_ICE_MAGIC
- 150, // SK_AIR_MAGIC
- 70, // SK_EARTH_MAGIC
- 130, // SK_POISON_MAGIC
- 100, // SK_INVOCATIONS
- 60, // SK_EVOCATIONS
- },
-
- { // SP_MOUNTAIN_DWARF (8)
- 70, // SK_FIGHTING
- 90, // SK_SHORT_BLADES
- 90, // SK_LONG_SWORDS
- 100, // SK_UNUSED_1
- 70, // SK_AXES
- 70, // SK_MACES_FLAILS
- 110, // SK_POLEARMS
- 120, // SK_STAVES
- 125, // SK_SLINGS
- 140, // SK_BOWS
- 100, // SK_CROSSBOWS
- 120, // SK_DARTS
- 115, // SK_RANGED_COMBAT
- 60, // SK_ARMOUR
- 110, // SK_DODGING
- 140, // SK_STEALTH
- 130, // SK_STABBING
- 70, // SK_SHIELDS
- 100, // SK_TRAPS_DOORS
- 100, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 140, // SK_SPELLCASTING
- 115, // SK_CONJURATIONS
- 135, // SK_ENCHANTMENTS
- 150, // SK_SUMMONINGS
- 160, // SK_NECROMANCY
- 150, // SK_TRANSLOCATIONS
- 120, // SK_TRANSMIGRATION
- 130, // SK_DIVINATIONS
- 70, // SK_FIRE_MAGIC
- 130, // SK_ICE_MAGIC
- 150, // SK_AIR_MAGIC
- 70, // SK_EARTH_MAGIC
- 130, // SK_POISON_MAGIC
- 100, // SK_INVOCATIONS
- 70, // SK_EVOCATIONS
- },
-
- { // SP_HALFLING (9)
- 120, // SK_FIGHTING
- 60, // SK_SHORT_BLADES
- 100, // SK_LONG_SWORDS
- 130, // SK_UNUSED_1
- 120, // SK_AXES
- 150, // SK_MACES_FLAILS
- 160, // SK_POLEARMS
- 130, // SK_STAVES
- 50, // SK_SLINGS
- 70, // SK_BOWS
- 90, // SK_CROSSBOWS
- 50, // SK_DARTS
- 60, // SK_RANGED_COMBAT
- 150, // SK_ARMOUR
- 70, // SK_DODGING
- 60, // SK_STEALTH
- 70, // SK_STABBING
- 130, // SK_SHIELDS
- 100, // SK_TRAPS_DOORS
- 140, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 130, // SK_SPELLCASTING
- 130, // SK_CONJURATIONS
- 100, // SK_ENCHANTMENTS
- 120, // SK_SUMMONINGS
- 150, // SK_NECROMANCY
- 100, // SK_TRANSLOCATIONS
- 150, // SK_TRANSMIGRATION
- 140, // SK_DIVINATIONS
- 100, // SK_FIRE_MAGIC
- 100, // SK_ICE_MAGIC
- 90, // SK_AIR_MAGIC
- 100, // SK_EARTH_MAGIC
- 120, // SK_POISON_MAGIC
- 100, // SK_INVOCATIONS
- 90, // SK_EVOCATIONS
- },
-
- { // SP_HILL_ORC (10)
- 70, // SK_FIGHTING
- 100, // SK_SHORT_BLADES
- 80, // SK_LONG_SWORDS
- 70, // SK_UNUSED_1
- 70, // SK_AXES
- 80, // SK_MACES_FLAILS
- 80, // SK_POLEARMS
- 110, // SK_STAVES
- 130, // SK_SLINGS
- 120, // SK_BOWS
- 120, // SK_CROSSBOWS
- 130, // SK_DARTS
- 130, // SK_RANGED_COMBAT
- 90, // SK_ARMOUR
- 140, // SK_DODGING
- 150, // SK_STEALTH
- 100, // SK_STABBING
- 80, // SK_SHIELDS
- 100, // SK_TRAPS_DOORS
- 90, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 150, // SK_SPELLCASTING
- 100, // SK_CONJURATIONS
- 120, // SK_ENCHANTMENTS
- 120, // SK_SUMMONINGS
- 100, // SK_NECROMANCY
- 150, // SK_TRANSLOCATIONS
- 160, // SK_TRANSMIGRATION
- 160, // SK_DIVINATIONS
- 100, // SK_FIRE_MAGIC
- 100, // SK_ICE_MAGIC
- 150, // SK_AIR_MAGIC
- 100, // SK_EARTH_MAGIC
- 110, // SK_POISON_MAGIC
- 100, // SK_INVOCATIONS
- 100, // SK_EVOCATIONS
- },
-
- { // SP_KOBOLD (11)
- 80, // SK_FIGHTING
- 60, // SK_SHORT_BLADES
- 100, // SK_LONG_SWORDS
- 120, // SK_UNUSED_1
- 110, // SK_AXES
- 140, // SK_MACES_FLAILS
- 150, // SK_POLEARMS
- 110, // SK_STAVES
- 70, // SK_SLINGS
- 80, // SK_BOWS
- 90, // SK_CROSSBOWS
- 50, // SK_DARTS
- 60, // SK_RANGED_COMBAT
- 140, // SK_ARMOUR
- 70, // SK_DODGING
- 60, // SK_STEALTH
- 70, // SK_STABBING
- 130, // SK_SHIELDS
- 100, // SK_TRAPS_DOORS
- 100, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 110, // SK_SPELLCASTING
- 110, // SK_CONJURATIONS
- 110, // SK_ENCHANTMENTS
- 105, // SK_SUMMONINGS
- 105, // SK_NECROMANCY
- 100, // SK_TRANSLOCATIONS
- 110, // SK_TRANSMIGRATION
- 130, // SK_DIVINATIONS
- 100, // SK_FIRE_MAGIC
- 100, // SK_ICE_MAGIC
- 100, // SK_AIR_MAGIC
- 100, // SK_EARTH_MAGIC
- 100, // SK_POISON_MAGIC
- 100, // SK_INVOCATIONS
- 80, // SK_EVOCATIONS
- },
-
- { // SP_MUMMY (12)
- 100, // SK_FIGHTING
- 140, // SK_SHORT_BLADES
- 140, // SK_LONG_SWORDS
- 140, // SK_UNUSED_1
- 140, // SK_AXES
- 140, // SK_MACES_FLAILS
- 140, // SK_POLEARMS
- 140, // SK_STAVES
- 140, // SK_SLINGS
- 140, // SK_BOWS
- 140, // SK_CROSSBOWS
- 140, // SK_DARTS
- 140, // SK_RANGED_COMBAT
- 140, // SK_ARMOUR
- 140, // SK_DODGING
- 140, // SK_STEALTH
- 140, // SK_STABBING
- 140, // SK_SHIELDS
- 140, // SK_TRAPS_DOORS
- 140, // SK_UNARMED_COMBAT
- 140, // undefined
- 140, // undefined
- 140, // undefined
- 140, // undefined
- 140, // undefined
- 100, // SK_SPELLCASTING
- 140, // SK_CONJURATIONS
- 140, // SK_ENCHANTMENTS
- 140, // SK_SUMMONINGS
- 100, // SK_NECROMANCY
- 140, // SK_TRANSLOCATIONS
- 140, // SK_TRANSMIGRATION
- 140, // SK_DIVINATIONS
- 140, // SK_FIRE_MAGIC
- 140, // SK_ICE_MAGIC
- 140, // SK_AIR_MAGIC
- 140, // SK_EARTH_MAGIC
- 140, // SK_POISON_MAGIC
- 140, // SK_INVOCATIONS
- 140, // SK_EVOCATIONS
- },
-
- { // SP_NAGA (13)
- 100, // SK_FIGHTING
- 100, // SK_SHORT_BLADES
- 100, // SK_LONG_SWORDS
- 100, // SK_UNUSED_1
- 100, // SK_AXES
- 100, // SK_MACES_FLAILS
- 100, // SK_POLEARMS
- 120, // SK_STAVES
- 120, // SK_SLINGS
- 120, // SK_BOWS
- 120, // SK_CROSSBOWS
- 120, // SK_DARTS
- 120, // SK_RANGED_COMBAT
- 150, // SK_ARMOUR
- 150, // SK_DODGING
- 40, // SK_STEALTH
- 100, // SK_STABBING
- 140, // SK_SHIELDS
- 100, // SK_TRAPS_DOORS
- 100, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // SK_SPELLCASTING
- 100, // SK_CONJURATIONS
- 100, // SK_ENCHANTMENTS
- 100, // SK_SUMMONINGS
- 100, // SK_NECROMANCY
- 100, // SK_TRANSLOCATIONS
- 100, // SK_TRANSMIGRATION
- 100, // SK_DIVINATIONS
- 100, // SK_FIRE_MAGIC
- 100, // SK_ICE_MAGIC
- 100, // SK_AIR_MAGIC
- 100, // SK_EARTH_MAGIC
- 60, // SK_POISON_MAGIC
- 100, // SK_INVOCATIONS
- 100, // SK_EVOCATIONS
- },
-
- { // SP_GNOME (14)
- 100, // SK_FIGHTING
- 75, // SK_SHORT_BLADES
- 100, // SK_LONG_SWORDS
- 130, // SK_UNUSED_1
- 100, // SK_AXES
- 130, // SK_MACES_FLAILS
- 140, // SK_POLEARMS
- 130, // SK_STAVES
- 80, // SK_SLINGS
- 100, // SK_BOWS
- 90, // SK_CROSSBOWS
- 60, // SK_DARTS
- 100, // SK_RANGED_COMBAT
- 150, // SK_ARMOUR
- 70, // SK_DODGING
- 70, // SK_STEALTH
- 80, // SK_STABBING
- 120, // SK_SHIELDS
- 100, // SK_TRAPS_DOORS
- 110, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 120, // SK_SPELLCASTING
- 100, // SK_CONJURATIONS
- 100, // SK_ENCHANTMENTS
- 110, // SK_SUMMONINGS
- 130, // SK_NECROMANCY
- 130, // SK_TRANSLOCATIONS
- 120, // SK_TRANSMIGRATION
- 120, // SK_DIVINATIONS
- 100, // SK_FIRE_MAGIC
- 100, // SK_ICE_MAGIC
- 170, // SK_AIR_MAGIC
- 60, // SK_EARTH_MAGIC
- 130, // SK_POISON_MAGIC
- 120, // SK_INVOCATIONS
- 60, // SK_EVOCATIONS
- },
-
- { // SP_OGRE (15)
- 100, // SK_FIGHTING
- 140, // SK_SHORT_BLADES
- 120, // SK_LONG_SWORDS
- 110, // SK_UNUSED_1
- 100, // SK_AXES
- 100, // SK_MACES_FLAILS
- 110, // SK_POLEARMS
- 120, // SK_STAVES
- 150, // SK_SLINGS
- 150, // SK_BOWS
- 180, // SK_CROSSBOWS
- 150, // SK_DARTS
- 100, // SK_RANGED_COMBAT
- 140, // SK_ARMOUR
- 150, // SK_DODGING
- 200, // SK_STEALTH
- 150, // SK_STABBING
- 110, // SK_SHIELDS
- 200, // SK_TRAPS_DOORS
- 130, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 220, // SK_SPELLCASTING
- 180, // SK_CONJURATIONS
- 220, // SK_ENCHANTMENTS
- 200, // SK_SUMMONINGS
- 150, // SK_NECROMANCY
- 200, // SK_TRANSLOCATIONS
- 200, // SK_TRANSMIGRATION
- 200, // SK_DIVINATIONS
- 150, // SK_FIRE_MAGIC
- 150, // SK_ICE_MAGIC
- 200, // SK_AIR_MAGIC
- 120, // SK_EARTH_MAGIC
- 150, // SK_POISON_MAGIC
- 130, // SK_INVOCATIONS
- 170, // SK_EVOCATIONS
- },
-
- { // SP_TROLL (16)
- 140, // SK_FIGHTING
- 150, // SK_SHORT_BLADES
- 150, // SK_LONG_SWORDS
- 150, // SK_UNUSED_1
- 150, // SK_AXES
- 130, // SK_MACES_FLAILS
- 150, // SK_POLEARMS
- 150, // SK_STAVES
- 180, // SK_SLINGS
- 180, // SK_BOWS
- 180, // SK_CROSSBOWS
- 180, // SK_DARTS
- 130, // SK_RANGED_COMBAT
- 150, // SK_ARMOUR
- 130, // SK_DODGING
- 250, // SK_STEALTH
- 150, // SK_STABBING
- 150, // SK_SHIELDS
- 200, // SK_TRAPS_DOORS
- 100, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 200, // SK_SPELLCASTING
- 160, // SK_CONJURATIONS
- 200, // SK_ENCHANTMENTS
- 160, // SK_SUMMONINGS
- 150, // SK_NECROMANCY
- 160, // SK_TRANSLOCATIONS
- 160, // SK_TRANSMIGRATION
- 200, // SK_DIVINATIONS
- 160, // SK_FIRE_MAGIC
- 160, // SK_ICE_MAGIC
- 200, // SK_AIR_MAGIC
- 120, // SK_EARTH_MAGIC
- 160, // SK_POISON_MAGIC
- 150, // SK_INVOCATIONS
- 180, // SK_EVOCATIONS
- },
-
- { // SP_OGRE_MAGE (17)
- 100, // SK_FIGHTING
- 110, // SK_SHORT_BLADES
- 100, // SK_LONG_SWORDS
- 100, // SK_UNUSED_1
- 100, // SK_AXES
- 100, // SK_MACES_FLAILS
- 100, // SK_POLEARMS
- 100, // SK_STAVES
- 150, // SK_SLINGS
- 150, // SK_BOWS
- 150, // SK_CROSSBOWS
- 150, // SK_DARTS
- 150, // SK_RANGED_COMBAT
- 170, // SK_ARMOUR
- 130, // SK_DODGING
- 100, // SK_STEALTH
- 130, // SK_STABBING
- 150, // SK_SHIELDS
- 150, // SK_TRAPS_DOORS
- 100, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 70, // SK_SPELLCASTING
- 100, // SK_CONJURATIONS
- 80, // SK_ENCHANTMENTS
- 100, // SK_SUMMONINGS
- 100, // SK_NECROMANCY
- 100, // SK_TRANSLOCATIONS
- 100, // SK_TRANSMIGRATION
- 100, // SK_DIVINATIONS
- 100, // SK_FIRE_MAGIC
- 100, // SK_ICE_MAGIC
- 100, // SK_AIR_MAGIC
- 100, // SK_EARTH_MAGIC
- 100, // SK_POISON_MAGIC
- 100, // SK_INVOCATIONS
- 100, // SK_EVOCATIONS
- },
-
- { // SP_RED_DRACONIAN (18)
- 90, // SK_FIGHTING
- 100, // SK_SHORT_BLADES
- 100, // SK_LONG_SWORDS
- 100, // SK_UNUSED_1
- 100, // SK_AXES
- 100, // SK_MACES_FLAILS
- 100, // SK_POLEARMS
- 100, // SK_STAVES
- 120, // SK_SLINGS
- 120, // SK_BOWS
- 120, // SK_CROSSBOWS
- 120, // SK_DARTS
- 120, // SK_RANGED_COMBAT
- 200, // SK_ARMOUR
- 120, // SK_DODGING
- 120, // SK_STEALTH
- 100, // SK_STABBING
- 100, // SK_SHIELDS
- 100, // SK_TRAPS_DOORS
- 100, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // SK_SPELLCASTING
- 100, // SK_CONJURATIONS
- 120, // SK_ENCHANTMENTS
- 100, // SK_SUMMONINGS
- 100, // SK_NECROMANCY
- 100, // SK_TRANSLOCATIONS
- 100, // SK_TRANSMIGRATION
- 100, // SK_DIVINATIONS
- 70, // SK_FIRE_MAGIC
- 150, // SK_ICE_MAGIC
- 100, // SK_AIR_MAGIC
- 100, // SK_EARTH_MAGIC
- 100, // SK_POISON_MAGIC
- 100, // SK_INVOCATIONS
- 100, // SK_EVOCATIONS
- },
-
- { // SP_WHITE_DRACONIAN (19)
- 90, // SK_FIGHTING
- 100, // SK_SHORT_BLADES
- 100, // SK_LONG_SWORDS
- 100, // SK_UNUSED_1
- 100, // SK_AXES
- 100, // SK_MACES_FLAILS
- 100, // SK_POLEARMS
- 100, // SK_STAVES
- 120, // SK_SLINGS
- 120, // SK_BOWS
- 120, // SK_CROSSBOWS
- 120, // SK_DARTS
- 120, // SK_RANGED_COMBAT
- 200, // SK_ARMOUR
- 120, // SK_DODGING
- 120, // SK_STEALTH
- 100, // SK_STABBING
- 100, // SK_SHIELDS
- 100, // SK_TRAPS_DOORS
- 100, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // SK_SPELLCASTING
- 100, // SK_CONJURATIONS
- 120, // SK_ENCHANTMENTS
- 100, // SK_SUMMONINGS
- 100, // SK_NECROMANCY
- 100, // SK_TRANSLOCATIONS
- 100, // SK_TRANSMIGRATION
- 100, // SK_DIVINATIONS
- 150, // SK_FIRE_MAGIC
- 70, // SK_ICE_MAGIC
- 100, // SK_AIR_MAGIC
- 100, // SK_EARTH_MAGIC
- 100, // SK_POISON_MAGIC
- 100, // SK_INVOCATIONS
- 100, // SK_EVOCATIONS
- },
-
- { // SP_GREEN_DRACONIAN (20)
- 90, // SK_FIGHTING
- 100, // SK_SHORT_BLADES
- 100, // SK_LONG_SWORDS
- 100, // SK_UNUSED_1
- 100, // SK_AXES
- 100, // SK_MACES_FLAILS
- 100, // SK_POLEARMS
- 100, // SK_STAVES
- 120, // SK_SLINGS
- 120, // SK_BOWS
- 120, // SK_CROSSBOWS
- 120, // SK_DARTS
- 120, // SK_RANGED_COMBAT
- 200, // SK_ARMOUR
- 120, // SK_DODGING
- 120, // SK_STEALTH
- 100, // SK_STABBING
- 100, // SK_SHIELDS
- 100, // SK_TRAPS_DOORS
- 100, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // SK_SPELLCASTING
- 100, // SK_CONJURATIONS
- 120, // SK_ENCHANTMENTS
- 100, // SK_SUMMONINGS
- 100, // SK_NECROMANCY
- 100, // SK_TRANSLOCATIONS
- 100, // SK_TRANSMIGRATION
- 100, // SK_DIVINATIONS
- 100, // SK_FIRE_MAGIC
- 100, // SK_ICE_MAGIC
- 100, // SK_AIR_MAGIC
- 100, // SK_EARTH_MAGIC
- 70, // SK_POISON_MAGIC
- 100, // SK_INVOCATIONS
- 100, // SK_EVOCATIONS
- },
-
- { // SP_YELLOW_DRACONIAN (21)
- 90, // SK_FIGHTING
- 100, // SK_SHORT_BLADES
- 100, // SK_LONG_SWORDS
- 100, // SK_UNUSED_1
- 100, // SK_AXES
- 100, // SK_MACES_FLAILS
- 100, // SK_POLEARMS
- 100, // SK_STAVES
- 120, // SK_SLINGS
- 120, // SK_BOWS
- 120, // SK_CROSSBOWS
- 120, // SK_DARTS
- 120, // SK_RANGED_COMBAT
- 200, // SK_ARMOUR
- 120, // SK_DODGING
- 120, // SK_STEALTH
- 100, // SK_STABBING
- 100, // SK_SHIELDS
- 100, // SK_TRAPS_DOORS
- 100, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // SK_SPELLCASTING
- 100, // SK_CONJURATIONS
- 120, // SK_ENCHANTMENTS
- 100, // SK_SUMMONINGS
- 100, // SK_NECROMANCY
- 100, // SK_TRANSLOCATIONS
- 100, // SK_TRANSMIGRATION
- 100, // SK_DIVINATIONS
- 100, // SK_FIRE_MAGIC
- 100, // SK_ICE_MAGIC
- 100, // SK_AIR_MAGIC
- 100, // SK_EARTH_MAGIC
- 100, // SK_POISON_MAGIC
- 100, // SK_INVOCATIONS
- 100, // SK_EVOCATIONS
- },
-
- { // SP_GREY_DRACONIAN (22)
- 90, // SK_FIGHTING
- 100, // SK_SHORT_BLADES
- 100, // SK_LONG_SWORDS
- 100, // SK_UNUSED_1
- 100, // SK_AXES
- 100, // SK_MACES_FLAILS
- 100, // SK_POLEARMS
- 100, // SK_STAVES
- 120, // SK_SLINGS
- 120, // SK_BOWS
- 120, // SK_CROSSBOWS
- 120, // SK_DARTS
- 120, // SK_RANGED_COMBAT
- 200, // SK_ARMOUR
- 120, // SK_DODGING
- 120, // SK_STEALTH
- 100, // SK_STABBING
- 100, // SK_SHIELDS
- 100, // SK_TRAPS_DOORS
- 100, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // SK_SPELLCASTING
- 100, // SK_CONJURATIONS
- 120, // SK_ENCHANTMENTS
- 100, // SK_SUMMONINGS
- 100, // SK_NECROMANCY
- 100, // SK_TRANSLOCATIONS
- 100, // SK_TRANSMIGRATION
- 100, // SK_DIVINATIONS
- 100, // SK_FIRE_MAGIC
- 100, // SK_ICE_MAGIC
- 100, // SK_AIR_MAGIC
- 100, // SK_EARTH_MAGIC
- 100, // SK_POISON_MAGIC
- 100, // SK_INVOCATIONS
- 100, // SK_EVOCATIONS
- },
-
- { // SP_BLACK_DRACONIAN (23)
- 90, // SK_FIGHTING
- 100, // SK_SHORT_BLADES
- 100, // SK_LONG_SWORDS
- 100, // SK_UNUSED_1
- 100, // SK_AXES
- 100, // SK_MACES_FLAILS
- 100, // SK_POLEARMS
- 100, // SK_STAVES
- 120, // SK_SLINGS
- 120, // SK_BOWS
- 120, // SK_CROSSBOWS
- 120, // SK_DARTS
- 120, // SK_RANGED_COMBAT
- 200, // SK_ARMOUR
- 120, // SK_DODGING
- 120, // SK_STEALTH
- 100, // SK_STABBING
- 100, // SK_SHIELDS
- 100, // SK_TRAPS_DOORS
- 100, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // SK_SPELLCASTING
- 100, // SK_CONJURATIONS
- 120, // SK_ENCHANTMENTS
- 100, // SK_SUMMONINGS
- 100, // SK_NECROMANCY
- 100, // SK_TRANSLOCATIONS
- 100, // SK_TRANSMIGRATION
- 100, // SK_DIVINATIONS
- 100, // SK_FIRE_MAGIC
- 100, // SK_ICE_MAGIC
- 70, // SK_AIR_MAGIC
- 150, // SK_EARTH_MAGIC
- 100, // SK_POISON_MAGIC
- 100, // SK_INVOCATIONS
- 100, // SK_EVOCATIONS
- },
-
- { // SP_PURPLE_DRACONIAN (24)
- 90, // SK_FIGHTING
- 100, // SK_SHORT_BLADES
- 100, // SK_LONG_SWORDS
- 100, // SK_UNUSED_1
- 100, // SK_AXES
- 100, // SK_MACES_FLAILS
- 100, // SK_POLEARMS
- 100, // SK_STAVES
- 120, // SK_SLINGS
- 120, // SK_BOWS
- 120, // SK_CROSSBOWS
- 120, // SK_DARTS
- 120, // SK_RANGED_COMBAT
- 200, // SK_ARMOUR
- 120, // SK_DODGING
- 120, // SK_STEALTH
- 100, // SK_STABBING
- 100, // SK_SHIELDS
- 100, // SK_TRAPS_DOORS
- 100, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 70, // SK_SPELLCASTING
- 100, // SK_CONJURATIONS
- 90, // SK_ENCHANTMENTS
- 100, // SK_SUMMONINGS
- 100, // SK_NECROMANCY
- 100, // SK_TRANSLOCATIONS
- 100, // SK_TRANSMIGRATION
- 100, // SK_DIVINATIONS
- 100, // SK_FIRE_MAGIC
- 100, // SK_ICE_MAGIC
- 100, // SK_AIR_MAGIC
- 100, // SK_EARTH_MAGIC
- 100, // SK_POISON_MAGIC
- 100, // SK_INVOCATIONS
- 90, // SK_EVOCATIONS
- },
-
- { // SP_MOTTLED_DRACONIAN (25)
- 90, // SK_FIGHTING
- 100, // SK_SHORT_BLADES
- 100, // SK_LONG_SWORDS
- 100, // SK_UNUSED_1
- 100, // SK_AXES
- 100, // SK_MACES_FLAILS
- 100, // SK_POLEARMS
- 100, // SK_STAVES
- 120, // SK_SLINGS
- 120, // SK_BOWS
- 120, // SK_CROSSBOWS
- 120, // SK_DARTS
- 120, // SK_RANGED_COMBAT
- 200, // SK_ARMOUR
- 120, // SK_DODGING
- 120, // SK_STEALTH
- 100, // SK_STABBING
- 100, // SK_SHIELDS
- 100, // SK_TRAPS_DOORS
- 100, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // SK_SPELLCASTING
- 100, // SK_CONJURATIONS
- 120, // SK_ENCHANTMENTS
- 100, // SK_SUMMONINGS
- 100, // SK_NECROMANCY
- 100, // SK_TRANSLOCATIONS
- 100, // SK_TRANSMIGRATION
- 100, // SK_DIVINATIONS
- 80, // SK_FIRE_MAGIC
- 100, // SK_ICE_MAGIC
- 100, // SK_AIR_MAGIC
- 100, // SK_EARTH_MAGIC
- 100, // SK_POISON_MAGIC
- 100, // SK_INVOCATIONS
- 100, // SK_EVOCATIONS
- },
-
- { // SP_PALE_DRACONIAN (26)
- 90, // SK_FIGHTING
- 100, // SK_SHORT_BLADES
- 100, // SK_LONG_SWORDS
- 100, // SK_UNUSED_1
- 100, // SK_AXES
- 100, // SK_MACES_FLAILS
- 100, // SK_POLEARMS
- 100, // SK_STAVES
- 120, // SK_SLINGS
- 120, // SK_BOWS
- 120, // SK_CROSSBOWS
- 120, // SK_DARTS
- 120, // SK_RANGED_COMBAT
- 200, // SK_ARMOUR
- 120, // SK_DODGING
- 120, // SK_STEALTH
- 100, // SK_STABBING
- 100, // SK_SHIELDS
- 100, // SK_TRAPS_DOORS
- 100, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // SK_SPELLCASTING
- 100, // SK_CONJURATIONS
- 120, // SK_ENCHANTMENTS
- 100, // SK_SUMMONINGS
- 100, // SK_NECROMANCY
- 100, // SK_TRANSLOCATIONS
- 100, // SK_TRANSMIGRATION
- 100, // SK_DIVINATIONS
- 90, // SK_FIRE_MAGIC
- 100, // SK_ICE_MAGIC
- 90, // SK_AIR_MAGIC
- 100, // SK_EARTH_MAGIC
- 100, // SK_POISON_MAGIC
- 100, // SK_INVOCATIONS
- 90, // SK_EVOCATIONS
- },
-
- { // SP_UNK0_DRACONAIN (27)
- 90, // SK_FIGHTING
- 100, // SK_SHORT_BLADES
- 100, // SK_LONG_SWORDS
- 100, // SK_UNUSED_1
- 100, // SK_AXES
- 100, // SK_MACES_FLAILS
- 100, // SK_POLEARMS
- 100, // SK_STAVES
- 120, // SK_SLINGS
- 120, // SK_BOWS
- 120, // SK_CROSSBOWS
- 120, // SK_DARTS
- 120, // SK_RANGED_COMBAT
- 200, // SK_ARMOUR
- 120, // SK_DODGING
- 120, // SK_STEALTH
- 100, // SK_STABBING
- 100, // SK_SHIELDS
- 100, // SK_TRAPS_DOORS
- 100, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // SK_SPELLCASTING
- 100, // SK_CONJURATIONS
- 120, // SK_ENCHANTMENTS
- 100, // SK_SUMMONINGS
- 100, // SK_NECROMANCY
- 100, // SK_TRANSLOCATIONS
- 100, // SK_TRANSMIGRATION
- 100, // SK_DIVINATIONS
- 100, // SK_FIRE_MAGIC
- 100, // SK_ICE_MAGIC
- 100, // SK_AIR_MAGIC
- 100, // SK_EARTH_MAGIC
- 100, // SK_POISON_MAGIC
- 100, // SK_INVOCATIONS
- 100, // SK_EVOCATIONS
- },
-
- { // SP_UNK1_DRACONIAN (28)
- 90, // SK_FIGHTING
- 100, // SK_SHORT_BLADES
- 100, // SK_LONG_SWORDS
- 100, // SK_UNUSED_1
- 100, // SK_AXES
- 100, // SK_MACES_FLAILS
- 100, // SK_POLEARMS
- 100, // SK_STAVES
- 120, // SK_SLINGS
- 120, // SK_BOWS
- 120, // SK_CROSSBOWS
- 120, // SK_DARTS
- 120, // SK_RANGED_COMBAT
- 200, // SK_ARMOUR
- 120, // SK_DODGING
- 120, // SK_STEALTH
- 100, // SK_STABBING
- 100, // SK_SHIELDS
- 100, // SK_TRAPS_DOORS
- 100, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // SK_SPELLCASTING
- 100, // SK_CONJURATIONS
- 120, // SK_ENCHANTMENTS
- 100, // SK_SUMMONINGS
- 100, // SK_NECROMANCY
- 100, // SK_TRANSLOCATIONS
- 100, // SK_TRANSMIGRATION
- 100, // SK_DIVINATIONS
- 100, // SK_FIRE_MAGIC
- 100, // SK_ICE_MAGIC
- 100, // SK_AIR_MAGIC
- 100, // SK_EARTH_MAGIC
- 100, // SK_POISON_MAGIC
- 100, // SK_INVOCATIONS
- 100, // SK_EVOCATIONS
- },
-
- { // SP_UNK2_DRACONIAN (29)
- 90, // SK_FIGHTING
- 100, // SK_SHORT_BLADES
- 100, // SK_LONG_SWORDS
- 100, // SK_UNUSED_1
- 100, // SK_AXES
- 100, // SK_MACES_FLAILS
- 100, // SK_POLEARMS
- 100, // SK_STAVES
- 120, // SK_SLINGS
- 120, // SK_BOWS
- 120, // SK_CROSSBOWS
- 120, // SK_DARTS
- 120, // SK_RANGED_COMBAT
- 200, // SK_ARMOUR
- 120, // SK_DODGING
- 120, // SK_STEALTH
- 100, // SK_STABBING
- 100, // SK_SHIELDS
- 100, // SK_TRAPS_DOORS
- 100, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // SK_SPELLCASTING
- 100, // SK_CONJURATIONS
- 120, // SK_ENCHANTMENTS
- 100, // SK_SUMMONINGS
- 100, // SK_NECROMANCY
- 100, // SK_TRANSLOCATIONS
- 100, // SK_TRANSMIGRATION
- 100, // SK_DIVINATIONS
- 100, // SK_FIRE_MAGIC
- 100, // SK_ICE_MAGIC
- 100, // SK_AIR_MAGIC
- 100, // SK_EARTH_MAGIC
- 100, // SK_POISON_MAGIC
- 100, // SK_INVOCATIONS
- 100, // SK_EVOCATIONS
- },
-
- { // SP_CENTAUR (30)
- 100, // SK_FIGHTING
- 120, // SK_SHORT_BLADES
- 110, // SK_LONG_SWORDS
- 110, // SK_UNUSED_1
- 110, // SK_AXES
- 110, // SK_MACES_FLAILS
- 110, // SK_POLEARMS
- 110, // SK_STAVES
- 75, // SK_SLINGS
- 60, // SK_BOWS
- 85, // SK_CROSSBOWS
- 80, // SK_DARTS
- 60, // SK_RANGED_COMBAT
- 180, // SK_ARMOUR
- 170, // SK_DODGING
- 200, // SK_STEALTH
- 170, // SK_STABBING
- 180, // SK_SHIELDS
- 150, // SK_TRAPS_DOORS
- 100, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 140, // SK_SPELLCASTING
- 120, // SK_CONJURATIONS
- 110, // SK_ENCHANTMENTS
- 120, // SK_SUMMONINGS
- 120, // SK_NECROMANCY
- 120, // SK_TRANSLOCATIONS
- 120, // SK_TRANSMIGRATION
- 130, // SK_DIVINATIONS
- 120, // SK_FIRE_MAGIC
- 120, // SK_ICE_MAGIC
- 120, // SK_AIR_MAGIC
- 120, // SK_EARTH_MAGIC
- 130, // SK_POISON_MAGIC
- 100, // SK_INVOCATIONS
- 130, // SK_EVOCATIONS
- },
-
- { // SP_DEMIGOD (31)
- 110, // SK_FIGHTING
- 110, // SK_SHORT_BLADES
- 110, // SK_LONG_SWORDS
- 110, // SK_UNUSED_1
- 110, // SK_AXES
- 110, // SK_MACES_FLAILS
- 110, // SK_POLEARMS
- 110, // SK_STAVES
- 110, // SK_SLINGS
- 110, // SK_BOWS
- 110, // SK_CROSSBOWS
- 110, // SK_DARTS
- 110, // SK_RANGED_COMBAT
- 110, // SK_ARMOUR
- 110, // SK_DODGING
- 110, // SK_STEALTH
- 110, // SK_STABBING
- 110, // SK_SHIELDS
- 110, // SK_TRAPS_DOORS
- 110, // SK_UNARMED_COMBAT
- 110, // undefined
- 110, // undefined
- 110, // undefined
- 110, // undefined
- 110, // undefined
- 110, // SK_SPELLCASTING
- 110, // SK_CONJURATIONS
- 110, // SK_ENCHANTMENTS
- 110, // SK_SUMMONINGS
- 110, // SK_NECROMANCY
- 110, // SK_TRANSLOCATIONS
- 110, // SK_TRANSMIGRATION
- 110, // SK_DIVINATIONS
- 110, // SK_FIRE_MAGIC
- 110, // SK_ICE_MAGIC
- 110, // SK_AIR_MAGIC
- 110, // SK_EARTH_MAGIC
- 110, // SK_POISON_MAGIC
- 110, // SK_INVOCATIONS
- 110, // SK_EVOCATIONS
- },
-
- { // SP_SPRIGGAN (32)
- 150, // SK_FIGHTING
- 90, // SK_SHORT_BLADES
- 140, // SK_LONG_SWORDS
- 160, // SK_UNUSED_1
- 150, // SK_AXES
- 160, // SK_MACES_FLAILS
- 180, // SK_POLEARMS
- 150, // SK_STAVES
- 70, // SK_SLINGS
- 70, // SK_BOWS
- 100, // SK_CROSSBOWS
- 70, // SK_DARTS
- 90, // SK_RANGED_COMBAT
- 170, // SK_ARMOUR
- 50, // SK_DODGING
- 50, // SK_STEALTH
- 50, // SK_STABBING
- 180, // SK_SHIELDS
- 60, // SK_TRAPS_DOORS
- 130, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 60, // SK_SPELLCASTING
- 160, // SK_CONJURATIONS
- 50, // SK_ENCHANTMENTS
- 150, // SK_SUMMONINGS
- 120, // SK_NECROMANCY
- 50, // SK_TRANSLOCATIONS
- 60, // SK_TRANSMIGRATION
- 70, // SK_DIVINATIONS
- 140, // SK_FIRE_MAGIC
- 140, // SK_ICE_MAGIC
- 120, // SK_AIR_MAGIC
- 120, // SK_EARTH_MAGIC
- 100, // SK_POISON_MAGIC
- 130, // SK_INVOCATIONS
- 70, // SK_EVOCATIONS
- },
-
- { // SP_MINOTAUR (33)
- 70, // SK_FIGHTING
- 70, // SK_SHORT_BLADES
- 70, // SK_LONG_SWORDS
- 70, // SK_UNUSED_1
- 70, // SK_AXES
- 70, // SK_MACES_FLAILS
- 70, // SK_POLEARMS
- 70, // SK_STAVES
- 90, // SK_SLINGS
- 90, // SK_BOWS
- 90, // SK_CROSSBOWS
- 90, // SK_DARTS
- 90, // SK_RANGED_COMBAT
- 80, // SK_ARMOUR
- 80, // SK_DODGING
- 130, // SK_STEALTH
- 100, // SK_STABBING
- 80, // SK_SHIELDS
- 120, // SK_TRAPS_DOORS
- 80, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 180, // SK_SPELLCASTING
- 170, // SK_CONJURATIONS
- 170, // SK_ENCHANTMENTS
- 170, // SK_SUMMONINGS
- 170, // SK_NECROMANCY
- 170, // SK_TRANSLOCATIONS
- 170, // SK_TRANSMIGRATION
- 170, // SK_DIVINATIONS
- 170, // SK_FIRE_MAGIC
- 170, // SK_ICE_MAGIC
- 170, // SK_AIR_MAGIC
- 170, // SK_EARTH_MAGIC
- 170, // SK_POISON_MAGIC
- 130, // SK_INVOCATIONS
- 170, // SK_EVOCATIONS
- },
-
- { // SP_DEMONSPAN (34)
- 100, // SK_FIGHTING
- 110, // SK_SHORT_BLADES
- 110, // SK_LONG_SWORDS
- 110, // SK_UNUSED_1
- 110, // SK_AXES
- 110, // SK_MACES_FLAILS
- 110, // SK_POLEARMS
- 110, // SK_STAVES
- 110, // SK_SLINGS
- 110, // SK_BOWS
- 110, // SK_CROSSBOWS
- 110, // SK_DARTS
- 110, // SK_RANGED_COMBAT
- 110, // SK_ARMOUR
- 110, // SK_DODGING
- 110, // SK_STEALTH
- 110, // SK_STABBING
- 110, // SK_SHIELDS
- 110, // SK_TRAPS_DOORS
- 110, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // SK_SPELLCASTING
- 100, // SK_CONJURATIONS
- 110, // SK_ENCHANTMENTS
- 100, // SK_SUMMONINGS
- 90, // SK_NECROMANCY
- 110, // SK_TRANSLOCATIONS
- 110, // SK_TRANSMIGRATION
- 110, // SK_DIVINATIONS
- 100, // SK_FIRE_MAGIC
- 110, // SK_ICE_MAGIC
- 110, // SK_AIR_MAGIC
- 110, // SK_EARTH_MAGIC
- 100, // SK_POISON_MAGIC
- 80, // SK_INVOCATIONS
- 110, // SK_EVOCATIONS
- },
-
- { // SP_GHOUL (35)
- 80, // SK_FIGHTING
- 110, // SK_SHORT_BLADES
- 110, // SK_LONG_SWORDS
- 110, // SK_UNUSED_1
- 110, // SK_AXES
- 110, // SK_MACES_FLAILS
- 110, // SK_POLEARMS
- 110, // SK_STAVES
- 130, // SK_SLINGS
- 130, // SK_BOWS
- 130, // SK_CROSSBOWS
- 130, // SK_DARTS
- 130, // SK_RANGED_COMBAT
- 110, // SK_ARMOUR
- 110, // SK_DODGING
- 80, // SK_STEALTH
- 100, // SK_STABBING
- 110, // SK_SHIELDS
- 120, // SK_TRAPS_DOORS
- 80, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 120, // SK_SPELLCASTING
- 130, // SK_CONJURATIONS
- 130, // SK_ENCHANTMENTS
- 120, // SK_SUMMONINGS
- 100, // SK_NECROMANCY
- 120, // SK_TRANSLOCATIONS
- 120, // SK_TRANSMIGRATION
- 120, // SK_DIVINATIONS
- 150, // SK_FIRE_MAGIC
- 90, // SK_ICE_MAGIC
- 150, // SK_AIR_MAGIC
- 90, // SK_EARTH_MAGIC
- 100, // SK_POISON_MAGIC
- 110, // SK_INVOCATIONS
- 130, // SK_EVOCATIONS
- },
-
- { // SP_KENKU (36)
- 100, // SK_FIGHTING
- 75, // SK_SHORT_BLADES
- 75, // SK_LONG_SWORDS
- 75, // SK_UNUSED_1
- 75, // SK_AXES
- 75, // SK_MACES_FLAILS
- 75, // SK_POLEARMS
- 75, // SK_STAVES
- 100, // SK_SLINGS
- 80, // SK_BOWS
- 80, // SK_CROSSBOWS
- 90, // SK_DARTS
- 90, // SK_RANGED_COMBAT
- 90, // SK_ARMOUR
- 90, // SK_DODGING
- 100, // SK_STEALTH
- 80, // SK_STABBING
- 100, // SK_SHIELDS
- 100, // SK_TRAPS_DOORS
- 80, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // SK_SPELLCASTING
- 60, // SK_CONJURATIONS
- 160, // SK_ENCHANTMENTS
- 70, // SK_SUMMONINGS
- 80, // SK_NECROMANCY
- 150, // SK_TRANSLOCATIONS
- 150, // SK_TRANSMIGRATION
- 180, // SK_DIVINATIONS
- 90, // SK_FIRE_MAGIC
- 120, // SK_ICE_MAGIC
- 90, // SK_AIR_MAGIC
- 120, // SK_EARTH_MAGIC
- 100, // SK_POISON_MAGIC
- 160, // SK_INVOCATIONS
- 100, // SK_EVOCATIONS
- },
-
- { // SP_MERFOLK (37)
- 80, // SK_FIGHTING
- 70, // SK_SHORT_BLADES
- 90, // SK_LONG_SWORDS
- 100, // SK_UNUSED_1
- 140, // SK_AXES
- 150, // SK_MACES_FLAILS
- 50, // SK_POLEARMS
- 130, // SK_STAVES
- 150, // SK_SLINGS
- 140, // SK_BOWS
- 140, // SK_CROSSBOWS
- 100, // SK_DARTS
- 100, // SK_RANGED_COMBAT
- 160, // SK_ARMOUR
- 60, // SK_DODGING
- 90, // SK_STEALTH
- 70, // SK_STABBING
- 100, // SK_SHIELDS
- 120, // SK_TRAPS_DOORS
- 90, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // SK_SPELLCASTING
- 140, // SK_CONJURATIONS
- 90, // SK_ENCHANTMENTS
- 100, // SK_SUMMONINGS
- 150, // SK_NECROMANCY
- 140, // SK_TRANSLOCATIONS
- 60, // SK_TRANSMIGRATION
- 80, // SK_DIVINATIONS
- 160, // SK_FIRE_MAGIC
- 80, // SK_ICE_MAGIC
- 150, // SK_AIR_MAGIC
- 150, // SK_EARTH_MAGIC
- 80, // SK_POISON_MAGIC
- 100, // SK_INVOCATIONS
- 100, // SK_EVOCATIONS
- },
-
-
-
-/* ******************************************************
-
-// base draconian
- {
- 90, // SK_FIGHTING
- 100, // SK_SHORT_BLADES
- 100, // SK_LONG_SWORDS
- 100, // SK_UNUSED_1
- 100, // SK_AXES
- 100, // SK_MACES_FLAILS
- 100, // SK_POLEARMS
- 100, // SK_STAVES
- 120, // SK_SLINGS
- 120, // SK_BOWS
- 120, // SK_CROSSBOWS
- 120, // SK_DARTS
- 120, // SK_RANGED_COMBAT
- 200, // SK_ARMOUR
- 120, // SK_DODGING
- 120, // SK_STEALTH
- 100, // SK_STABBING
- 100, // SK_SHIELDS
- 100, // SK_TRAPS_DOORS
- 100, // SK_UNARMED_COMBAT
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // undefined
- 100, // SK_SPELLCASTING
- 100, // SK_CONJURATIONS
- 120, // SK_ENCHANTMENTS
- 100, // SK_SUMMONINGS
- 100, // SK_NECROMANCY
- 100, // SK_TRANSLOCATIONS
- 100, // SK_TRANSMIGRATION
- 100, // SK_DIVINATIONS
- 100, // SK_FIRE_MAGIC
- 100, // SK_ICE_MAGIC
- 100, // SK_AIR_MAGIC
- 100, // SK_EARTH_MAGIC
- 100, // SK_POISON_MAGIC
- 100, // SK_INVOCATIONS
- 100, // SK_EVOCATIONS
- },
-
-****************************************************** */
-
-};
-
-
-
-
-/* *************************************************************
-
-// these were unimplemented "level titles" for two classes {dlb}
-
-JOB_PRIEST
- "Preacher";
- "Priest";
- "Evangelist";
- "Pontifex";
-
-JOB_PALADIN:
- "Holy Warrior";
- "Holy Crusader";
- "Paladin";
- "Scourge of Evil";
-
-************************************************************* */
-
-void show_skills(void)
-{
- int i;
- int x;
- char lcount;
-
- const int num_lines = get_number_of_lines();
-
-#ifdef DOS_TERM
- window(1, 1, 80, 25);
- char buffer[4600];
-
- gettext(1, 1, 80, 25, buffer);
-#endif
-
- clrscr();
-
- reprint_stuff:
- lcount = 'a';
-
- gotoxy(1, 1);
- textcolor(LIGHTGREY);
-
-#if DEBUG_DIAGNOSTICS
- cprintf( "You have %d points of unallocated experience (cost lvl %d; total %d)." EOL EOL,
- you.exp_available, you.skill_cost_level, you.total_skill_points );
-#else
- cprintf(" You have %d points of unallocated experience." EOL EOL,
- you.exp_available );
-#endif
-
- char scrln = 3, scrcol = 1;
-
- // Don't want the help line to appear too far down a big window.
- int bottom_line = ((num_lines > 30) ? 30 : num_lines);
-
- for (x = 0; x < NUM_SKILLS; x++)
- {
- /* spells in second column */
- if ((x == SK_SPELLCASTING && scrcol != 40) || scrln > bottom_line - 3)
- {
- scrln = 3;
- scrcol = 40;
- }
-
- gotoxy(scrcol, scrln);
-
-#if DEBUG_DIAGNOSTICS
- // In diagnostic mode we show skills at 0, but only real skills
- if (x != SK_UNUSED_1 && (x <= SK_UNARMED_COMBAT || x >= SK_SPELLCASTING))
-#else
- if (you.skills[x] > 0)
-#endif
- {
- if (you.practise_skill[x] == 0 || you.skills[x] == 0)
- textcolor(DARKGREY);
- else
- textcolor(LIGHTGREY);
-
- if (you.skills[x] == 27)
- textcolor(YELLOW);
-
-#if DEBUG_DIAGNOSTICS
- if (you.skills[x] == 0)
- putch(' ');
- else
- {
- putch(lcount);
- if (lcount == 'z')
- lcount = 'A';
- else
- lcount++;
- }
-#else
- putch(lcount);
- if (lcount == 'z')
- lcount = 'A';
- else
- lcount++;
-#endif
-
- cprintf( " %c %-14s Skill %2d",
- (you.skills[x] == 0) ? ' ' :
- (you.practise_skill[x] == 0) ? '-' : '+',
- skills[x][0], you.skills[x] );
-
- textcolor(BLUE);
-
-#if DEBUG_DIAGNOSTICS
- cprintf( " %5d", you.skill_points[x] );
-#endif
-
- if (you.skills[x] < 27)
- {
- const int needed = skill_exp_needed(you.skills[x] + 2);
- const int prev_needed = skill_exp_needed(you.skills[x] + 1);
- const int spec_abil = species_skills(x, you.species);
-
- cprintf( " (%d)",
- (((needed * spec_abil) / 100 - you.skill_points[x]) * 10) /
- (((needed - prev_needed) * spec_abil) / 100) );
- }
-
- scrln++;
- }
-
- /* Extra CR between classes of weapons and such things */
- if (x == SK_STAVES || x == SK_RANGED_COMBAT || x == SK_TRAPS_DOORS
- || x == SK_UNARMED_COMBAT || x == SK_POISON_MAGIC)
- {
- scrln++;
- }
- }
-
- // if any more skills added, must adapt letters to go into caps
- gotoxy(1, bottom_line);
- textcolor(LIGHTGREY);
- cprintf("Press the letter of a skill to choose whether you want to practise it.");
-
- char get_thing;
-
- get_thing = getch();
-
- if (get_thing == 0)
- getch();
- else
- {
- if ((get_thing >= 'a' && get_thing <= 'z')
- || (get_thing >= 'A' && get_thing <= 'Z'))
- {
- lcount = 'a'; // toggle skill practise
-
- for (i = 0; i < 50; i++)
- {
- if (you.skills[i] == 0)
- continue;
-
- if (get_thing == lcount)
- {
- you.practise_skill[i] = (you.practise_skill[i]) ? 0 : 1;
- break;
- }
-
- if (lcount == 'z')
- lcount = 'A';
- else
- lcount++;
- }
-
- goto reprint_stuff;
- }
- }
-
-#ifdef DOS_TERM
- puttext(1, 1, 80, 25, buffer);
-#endif
- return;
-}
-
-
-const char *skill_name(int which_skill)
-{
- return (skills[which_skill][0]);
-} // end skill_name()
-
-
-const char *skill_title( unsigned char best_skill, unsigned char skill_lev,
- int species, int str, int dex, int god )
-{
- unsigned char skill_rank;
- const char *tempstr = NULL;
-
- static char title_buff[80];
-
- // paranoia
- if (best_skill == SK_UNUSED_1
- || (best_skill > SK_UNARMED_COMBAT && best_skill < SK_SPELLCASTING)
- || best_skill >= NUM_SKILLS)
- {
- return ("Adventurer");
- }
-
- if (species == -1)
- species = you.species;
-
- if (str == -1)
- str = you.strength;
-
- if (dex == -1)
- dex = you.dex;
-
- if (god == -1)
- god = you.religion;
-
- // translate skill level into skill ranking {dlb}:
- // increment rank by one to "skip" skill name in array {dlb}:
- skill_rank = ((skill_lev <= 7) ? 1 :
- (skill_lev <= 14) ? 2 :
- (skill_lev <= 20) ? 3 :
- (skill_lev <= 26) ? 4
- /* level 27 */ : 5);
-
- if (best_skill < NUM_SKILLS)
- {
- // Note that ghosts default to (dex == str) and god == no_god, due
- // to a current lack of that information... the god case is probably
- // suitable for most cases (TSO/Zin/Ely at the very least). -- bwr
- switch (best_skill)
- {
- case SK_UNARMED_COMBAT:
- tempstr = (dex >= str) ? martial_arts_titles[skill_rank]
- : skills[best_skill][skill_rank];
-
- break;
-
- case SK_INVOCATIONS:
- if (god == GOD_NO_GOD)
- tempstr = "Godless";
- else
- tempstr = skills[best_skill][skill_rank];
- break;
-
- default:
- tempstr = skills[best_skill][skill_rank];
- break;
- }
- }
-
- const char *const ptr = strchr( tempstr, '%' );
- const bool species_found = (ptr != NULL);
-
- if (species_found)
- {
- // need species name
- snprintf( title_buff, sizeof(title_buff), tempstr,
- species_name(species, 0, true,
- (ptr == tempstr && best_skill != SK_NECROMANCY)) );
- // The above code only capitalises start-of-string racenames
- tempstr = title_buff;
- }
-
- return ((tempstr == NULL) ? "Invalid Title" : tempstr);
-} // end skill_title()
-
-const char *player_title( void )
-{
- const unsigned char best = best_skill( SK_FIGHTING, (NUM_SKILLS - 1), 99 );
-
- return (skill_title( best, you.skills[ best ] ));
-} // end player_title()
-
-int best_skill( int min_skill, int max_skill, int excl_skill )
-{
- int ret = SK_FIGHTING;
- unsigned int best_skill_level = 0;
- unsigned int best_position = 1000;
-
- for (int i = min_skill; i <= max_skill; i++) // careful!!!
- {
- if (i == excl_skill
- || i == SK_UNUSED_1
- || (i > SK_UNARMED_COMBAT && i < SK_SPELLCASTING))
- {
- continue;
- }
-
- if (you.skills[i] > best_skill_level)
- {
- ret = i;
- best_skill_level = you.skills[i];
- best_position = you.skill_order[i];
-
- }
- else if (you.skills[i] == best_skill_level
- && you.skill_order[i] < best_position)
- {
- ret = i;
- best_position = you.skill_order[i];
- }
- }
-
- return (ret);
-} // end best_skill()
-
-// Calculate the skill_order array from scratch.
-//
-// The skill order array is used for breaking ties in best_skill.
-// This is done by ranking each skill by the order in which it
-// has attained its current level (the values are the number of
-// skills at or above that level when the current skill reached it).
-//
-// In this way, the skill which has been at a level for the longest
-// is judged to be the best skill (thus, nicknames are sticky)...
-// other skills will have to attain the next level higher to be
-// considered a better skill (thus, the first skill to reach level 27
-// becomes the characters final nickname).
-//
-// As for other uses of best_skill: this method is still appropriate
-// in that there is no additional advantage anywhere else in the game
-// for partial skill levels. Besides, its probably best if the player
-// isn't able to micromanage at that level. -- bwr
-void init_skill_order( void )
-{
- for (int i = SK_FIGHTING; i < NUM_SKILLS; i++)
- {
- if (i == SK_UNUSED_1
- || (i > SK_UNARMED_COMBAT && i < SK_SPELLCASTING))
- {
- you.skill_order[i] = MAX_SKILL_ORDER;
- continue;
- }
-
- const int i_diff = species_skills( i, you.species );
- const unsigned int i_points = (you.skill_points[i] * 100) / i_diff;
-
- you.skill_order[i] = 0;
-
- for (int j = SK_FIGHTING; j < NUM_SKILLS; j++)
- {
- if (i == j
- || j == SK_UNUSED_1
- || (j > SK_UNARMED_COMBAT && j < SK_SPELLCASTING))
- {
- continue;
- }
-
- const int j_diff = species_skills( j, you.species );
- const unsigned int j_points = (you.skill_points[j] * 100) / j_diff;
-
- if (you.skills[j] == you.skills[i]
- && (j_points > i_points
- || (j_points == i_points && j > i)))
- {
- you.skill_order[i]++;
- }
- }
- }
-}
-
-int calc_hp(void)
-{
- int hitp;
-
- hitp = (you.base_hp - 5000) + (you.base_hp2 - 5000);
- hitp += (you.experience_level * you.skills[SK_FIGHTING]) / 5;
-
- // being berserk makes you resistant to damage. I don't know why.
- if (you.berserker)
- {
- hitp *= 15;
- hitp /= 10;
- }
-
- // some transformations give you extra hp
- switch (you.attribute[ATTR_TRANSFORMATION])
- {
- case TRAN_STATUE:
- hitp *= 15;
- hitp /= 10;
- break;
- case TRAN_ICE_BEAST:
- hitp *= 12;
- hitp /= 10;
- break;
- case TRAN_DRAGON:
- hitp *= 16;
- hitp /= 10;
- break;
- }
-
- // frail and robust mutations
- hitp *= (10 + you.mutation[MUT_ROBUST] - you.mutation[MUT_FRAIL]);
- hitp /= 10;
-
- you.hp_max = hitp;
-
- deflate_hp( you.hp_max, false );
-
- return (hitp);
-} // end calc_hp()
-
-
-int calc_mp(void)
-{
- int enp;
-
- // base_magic_points2 accounts for species and magic potions
- enp = (you.base_magic_points2 - 5000);
-
- int spell_extra = (you.experience_level * you.skills[SK_SPELLCASTING]) / 4;
- int invoc_extra = (you.experience_level * you.skills[SK_INVOCATIONS]) / 6;
-
- if (spell_extra > invoc_extra)
- enp += spell_extra;
- else
- enp += invoc_extra;
-
- you.max_magic_points = stepdown_value( enp, 9, 18, 45, 100 );
-
- // this is our "rotted" base (applied after scaling):
- you.max_magic_points += (you.base_magic_points - 5000);
-
- // Yes, we really do want this duplication... this is so the stepdown
- // doesn't truncate before we apply the rotted base. We're doing this
- // the nice way. -- bwr
- if (you.max_magic_points > 50)
- you.max_magic_points = 50;
-
- // now applied after scaling so that power items are more useful -- bwr
- you.max_magic_points += player_magical_power();
-
- if (you.max_magic_points > 50)
- you.max_magic_points = 50 + ((you.max_magic_points - 50) / 2);
-
- if (you.max_magic_points < 0)
- you.max_magic_points = 0;
-
- if (you.magic_points > you.max_magic_points)
- you.magic_points = you.max_magic_points;
-
- you.redraw_magic_points = 1;
-
- return (you.max_magic_points);
-} // end calc_mp()
-
-
-unsigned int skill_exp_needed(int lev)
-{
- lev--;
- switch (lev)
- {
- case 0:
- return 0; // old: 0
- case 1:
- return 200; // old: 20
- case 2:
- return 300; // old: 30
- case 3:
- return 500; // old: 50
- case 4:
- return 750; // old: 75
- case 5:
- return 1050; // old: 105
- case 6:
- return 1350; // old: 145
- case 7:
- return 1700; // old: 200
- case 8:
- return 2100; // old: 275
- case 9:
- return 2550; // old: 355
- case 10:
- return 3150; // old: 440
- case 11:
- return 3750; // old: 560
- case 12:
- return 4400; // old: 680
- case 13:
- return 5250; // old: 850
- default:
- return 6200 + 1800 * (lev - 14);
- // old: 1100 + 300 * (lev - 14)
- // older: 1200 * (lev - 11) + ((lev - 11) * (lev - 11));// * (lev - 11))
- }
-
- return 0;
-}
-
-
-int species_skills(int skill, int species)
-{
- // Spellcasting is more expensive, invocations and evocations are cheaper
- if (skill == SK_SPELLCASTING)
- return (spec_skills[species - 1][skill] * 130) / 100;
- else if (skill == SK_INVOCATIONS || skill == SK_EVOCATIONS)
- return (spec_skills[species - 1][skill] * 75) / 100;
- else
- return (spec_skills[species - 1][skill]);
-} // end species_skills()
-
-// new: inform player if they need more throwing skill (GDL)
-void wield_warning(bool newWeapon)
-{
- // hold weapon name
- char wepstr[ITEMNAME_SIZE];
- char wepstr2[ITEMNAME_SIZE];
-
- // early out - no weapon
- if (you.equip[EQ_WEAPON] == -1)
- return;
-
- if (newWeapon)
- strcpy(wepstr, "this ");
- else
- strcpy(wepstr, "your ");
-
- int wepType = you.inv[you.equip[EQ_WEAPON]].sub_type;
-
- // early out - don't warn for non-weapons
- if (you.inv[you.equip[EQ_WEAPON]].base_type != OBJ_WEAPONS)
- return;
-
- // put the standard wep name in.
- standard_name_weap(wepType, wepstr2);
- strcat(wepstr, wepstr2);
-
- // only warn about str/dex for non-launcher weapons
- if (!launches_things(wepType))
- {
-#ifdef USE_NEW_COMBAT_STATS
- const int stat_bonus = effective_stat_bonus();
-
- if (stat_bonus <= -4)
- {
- if (you.strength < you.dex)
- {
- if (you.strength < 11)
- snprintf( info, INFO_SIZE, "You have %strouble swinging %s.",
- (you.strength < 7)?"":"a little ", wepstr);
- else
- snprintf( info, INFO_SIZE, "You'd be more effective with "
- "%s if you were stronger.", wepstr);
- }
- else
- {
- if (you.dex < 11)
- {
- snprintf( info, INFO_SIZE, "Wielding %s is %s awkward.",
- wepstr, (you.dex < 7) ? "fairly" : "a little" );
- }
- else
- {
- snprintf( info, INFO_SIZE, "You'd be more effective with "
- "%s if you were nimbler.", wepstr );
- }
- }
-
- mpr( info, MSGCH_WARN );
- }
-#endif
- return;
- }
-
- // [dshaligram] No more annoying throwing skill warnings.
-#ifdef OBSOLETE_THROW_SKILL_WARNING
- // must be a launcher
- int effSkill = you.skills[SK_RANGED_COMBAT] * 2 + 1;
- int shoot_skill = 0;
-
- switch (wepType)
- {
- case WPN_SLING:
- shoot_skill = you.skills[SK_SLINGS];
- break;
- case WPN_BOW:
- shoot_skill = you.skills[SK_BOWS];
- break;
- case WPN_CROSSBOW:
- case WPN_HAND_CROSSBOW:
- shoot_skill = you.skills[SK_CROSSBOWS];
- break;
- case WPN_BLOWGUN:
- shoot_skill = you.skills[SK_DARTS];
- break;
- default:
- shoot_skill = 0;
- break;
- }
-
- if (shoot_skill > effSkill)
- {
- strcpy( info, "Your low throwing skill limits the effectiveness of ");
- strcat( info, wepstr );
- mpr( info, MSGCH_WARN );
- }
-#endif
-}
diff --git a/stone_soup/crawl-ref/source/skills2.h b/stone_soup/crawl-ref/source/skills2.h
deleted file mode 100644
index 73658f31af..0000000000
--- a/stone_soup/crawl-ref/source/skills2.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * File: skills2.cc
- * Summary: More skill related functions.
- * Written by: Linley Henzell
- *
- * Modified for Crawl Reference by $Author$ on $Date$
- *
- * Change History (most recent first):
- *
- * <2> -/--/-- WL Extensive mods from Wladimir van der Laan.
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef SKILLS2_H
-#define SKILLS2_H
-
-#include <stddef.h> // For NULL
-
-#define MAX_SKILL_ORDER 100
-
-// last_updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: chardump - it_use3 - itemname - skills
- * *********************************************************************** */
-const char *skill_name(int which_skill);
-
-
-// last_updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: describe
- * *********************************************************************** */
-const char * skill_title( unsigned char best_skill, unsigned char skill_lev,
- // these used for ghosts and hiscores:
- int species = -1, int str = -1, int dex = -1, int god = -1 );
-
-// last_updated Sept 20 -- bwr
-/* ***********************************************************************
- * called from: acr - chardump - player - skills - stuff
- * *********************************************************************** */
-const char *player_title( void );
-
-
-// last_updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - chardump - effects - files - player - skills -
- * skills2 - stuff
- * *********************************************************************** */
-int best_skill(int min_skill, int max_skill, int excl_skill = -1);
-
-void init_skill_order( void );
-
-
-// last_updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - it_use2 - item_use - newgame - ouch - player - skills
- * *********************************************************************** */
-int calc_mp(void);
-
-
-// last_updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: ability - acr - food - it_use2 - misc - mutation -
- * newgame - ouch - player - skills - spells1 - transfor
- * *********************************************************************** */
-int calc_hp(void);
-
-
-// last_updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: newgame - skills - skills2
- * *********************************************************************** */
-int species_skills(int skill, int species);
-
-
-// last_updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: newgame - skills - skills2
- * *********************************************************************** */
-unsigned int skill_exp_needed(int lev);
-
-
-// last_updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void show_skills(void);
-
-
-// last_updated 14jan2001 {gdl}
-/* ***********************************************************************
- * called from: item_use
- * *********************************************************************** */
-void wield_warning(bool newWeapon = true);
-
-
-#endif
diff --git a/stone_soup/crawl-ref/source/spells1.cc b/stone_soup/crawl-ref/source/spells1.cc
deleted file mode 100644
index a559b66f84..0000000000
--- a/stone_soup/crawl-ref/source/spells1.cc
+++ /dev/null
@@ -1,1199 +0,0 @@
-/*
- * File: spells1.cc
- * Summary: Implementations of some additional spells.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <4> 06-mar-2000 bwr confusing_touch, sure_blade
- * <3> 9/11/99 LRH Can't blink in the Abyss
- * <3> 6/22/99 BWR Removed teleport control from
- * random_blink().
- * <2> 5/20/99 BWR Increased greatest healing.
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "spells1.h"
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "externs.h"
-
-#include "abyss.h"
-#include "beam.h"
-#include "cloud.h"
-#include "direct.h"
-#include "invent.h"
-#include "it_use2.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "misc.h"
-#include "monplace.h"
-#include "monstuff.h"
-#include "mon-util.h"
-#include "player.h"
-#include "skills2.h"
-#include "spells3.h"
-#include "spells4.h"
-#include "spl-util.h"
-#include "stuff.h"
-#include "view.h"
-#include "wpn-misc.h"
-
-void blink(void)
-{
- struct dist beam;
-
- // yes, there is a logic to this ordering {dlb}:
- if (scan_randarts(RAP_PREVENT_TELEPORTATION))
- mpr("You feel a weird sense of stasis.");
- else if (you.level_type == LEVEL_ABYSS && !one_chance_in(3))
- mpr("The power of the Abyss keeps you in your place!");
- else if (you.conf)
- random_blink(false);
- else if (!allow_control_teleport(true))
- {
- mpr("A powerful magic interferes with your control of the blink.");
- random_blink(false);
- }
- else
- {
- // query for location {dlb}:
- for (;;)
- {
- mpr("Blink to where?", MSGCH_PROMPT);
-
- direction( beam, DIR_TARGET );
-
- if (!beam.isValid)
- {
- canned_msg(MSG_SPELL_FIZZLES);
- return; // early return {dlb}
- }
-
- if (see_grid(beam.tx, beam.ty))
- break;
- else
- {
- mesclr();
- mpr("You can't blink there!");
- }
- }
-
- if (grid_is_solid(grd[beam.tx][beam.ty])
- || mgrd[beam.tx][beam.ty] != NON_MONSTER)
- {
- mpr("Oops! Maybe something was there already.");
- random_blink(false);
- }
- else if (you.level_type == LEVEL_ABYSS)
- {
- abyss_teleport( false );
- you.pet_target = MHITNOT;
- }
- else
- {
- you.x_pos = beam.tx;
- you.y_pos = beam.ty;
-
- // controlling teleport contaminates the player -- bwr
- contaminate_player( 1 );
- }
-
- if (you.duration[DUR_CONDENSATION_SHIELD] > 0)
- {
- you.duration[DUR_CONDENSATION_SHIELD] = 0;
- you.redraw_armour_class = 1;
- }
- }
-
- return;
-} // end blink()
-
-void random_blink(bool allow_partial_control)
-{
- int tx, ty;
- bool succ = false;
-
- if (scan_randarts(RAP_PREVENT_TELEPORTATION))
- mpr("You feel a weird sense of stasis.");
- else if (you.level_type == LEVEL_ABYSS && !one_chance_in(3))
- {
- mpr("The power of the Abyss keeps you in your place!");
- }
- else if (!random_near_space(you.x_pos, you.y_pos, tx, ty))
- {
- mpr("You feel jittery for a moment.");
- }
-
-#ifdef USE_SEMI_CONTROLLED_BLINK
- //jmf: add back control, but effect is cast_semi_controlled_blink(pow)
- else if (you.attribute[ATTR_CONTROL_TELEPORT] && !you.conf
- && allow_partial_control && allow_control_teleport())
- {
- mpr("You may select the general direction of your translocation.");
- cast_semi_controlled_blink(100);
- succ = true;
- }
-#endif
-
- else
- {
- mpr("You blink.");
-
- succ = true;
- you.x_pos = tx;
- you.y_pos = ty;
-
- if (you.level_type == LEVEL_ABYSS)
- {
- abyss_teleport( false );
- you.pet_target = MHITNOT;
- }
- }
-
- if (succ && you.duration[DUR_CONDENSATION_SHIELD] > 0)
- {
- you.duration[DUR_CONDENSATION_SHIELD] = 0;
- you.redraw_armour_class = 1;
- }
-
- return;
-} // end random_blink()
-
-void fireball(int power)
-{
- struct dist fire_ball;
-
- mpr( STD_DIRECTION_PROMPT, MSGCH_PROMPT );
-
- message_current_target();
-
- direction( fire_ball, DIR_NONE, TARG_ENEMY );
-
- if (!fire_ball.isValid)
- canned_msg(MSG_SPELL_FIZZLES);
- else
- {
- struct bolt beam;
-
- beam.source_x = you.x_pos;
- beam.source_y = you.y_pos;
- beam.target_x = fire_ball.tx;
- beam.target_y = fire_ball.ty;
-
- zapping(ZAP_FIREBALL, power, beam);
- }
-
- return;
-} // end fireball()
-
-void cast_fire_storm(int powc)
-{
- struct bolt beam;
- struct dist targ;
-
- mpr("Where?");
-
- direction( targ, DIR_TARGET, TARG_ENEMY );
-
- beam.target_x = targ.tx;
- beam.target_y = targ.ty;
-
- if (!targ.isValid)
- {
- canned_msg(MSG_SPELL_FIZZLES);
- return;
- }
-
- beam.ex_size = 2 + (random2(powc) > 75);
- beam.flavour = BEAM_LAVA;
- beam.type = SYM_ZAP;
- beam.colour = RED;
- beam.beam_source = MHITYOU;
- beam.thrower = KILL_YOU_MISSILE;
- beam.aux_source = NULL;
- beam.obvious_effect = false;
- beam.is_beam = false;
- beam.is_tracer = false;
- beam.is_explosion = true;
- beam.ench_power = powc; // used for radius
- strcpy( beam.beam_name, "great blast of fire" );
- beam.hit = 20 + powc / 10;
- beam.damage = calc_dice( 6, 15 + powc );
-
- explosion( beam );
- mpr("A raging storm of fire appears!");
-
- viewwindow(1, false);
-} // end cast_fire_storm()
-
-
-void cast_chain_lightning( int powc )
-{
- struct bolt beam;
-
- // initialize beam structure
- strcpy( beam.beam_name, "lightning arc" );
- beam.aux_source = "chain lightning";
- beam.beam_source = MHITYOU;
- beam.thrower = KILL_YOU_MISSILE;
- beam.range = 8;
- beam.rangeMax = 8;
- beam.hit = AUTOMATIC_HIT;
- beam.type = SYM_ZAP;
- beam.flavour = BEAM_ELECTRICITY;
- beam.obvious_effect = true;
- beam.is_beam = false; // since we want to stop at our target
- beam.is_explosion = false;
- beam.is_tracer = false;
-
- int sx, sy;
- int tx, ty;
- int i;
-
- for (sx = you.x_pos, sy = you.y_pos;
- powc > 0;
- powc -= 8 + random2(13), sx = tx, sy = ty)
- {
- // infinity as far as this spell is concerned
- // (Range - 1) is used because the distance is randomized and
- // may be shifted by one.
- int min_dist = MONSTER_LOS_RANGE - 1;
-
- int dist;
- int count = 0;
-
- tx = -1;
- ty = -1;
-
- for (i = 0; i < MAX_MONSTERS; i++)
- {
- struct monsters *monster = &menv[i];
-
- if (monster->type == -1)
- continue;
-
- dist = grid_distance( sx, sy, monster->x, monster->y );
-
- // check for the source of this arc
- if (!dist)
- continue;
-
- // randomize distance (arcs don't care about a couple of feet)
- dist += (random2(3) - 1);
-
- // always ignore targets further than current one
- if (dist > min_dist)
- continue;
-
- if (!check_line_of_sight( sx, sy, monster->x, monster->y ))
- continue;
-
- count++;
-
- if (dist < min_dist)
- {
- // switch to looking for closer targets (but not always)
- if (!one_chance_in(10))
- {
- min_dist = dist;
- tx = monster->x;
- ty = monster->y;
- count = 0;
- }
- }
- else if (tx == -1 || one_chance_in( count ))
- {
- // either first target, or new selected target at min_dist
- tx = monster->x;
- ty = monster->y;
-
- // need to set min_dist for first target case
- if (dist < min_dist)
- min_dist = dist;
- }
- }
-
- // now check if the player is a target:
- dist = grid_distance( sx, sy, you.x_pos, you.y_pos );
-
- if (dist) // ie player was not the source
- {
- // distance randomized (as above)
- dist += (random2(3) - 1);
-
- // select player if only, closest, or randomly selected
- if ((tx == -1
- || dist < min_dist
- || (dist == min_dist && one_chance_in( count + 1 )))
- && check_line_of_sight( sx, sy, you.x_pos, you.y_pos ))
- {
- tx = you.x_pos;
- ty = you.y_pos;
- }
- }
-
- const bool see_source = see_grid( sx, sy );
- const bool see_targ = see_grid( tx, ty );
-
- if (tx == -1)
- {
- if (see_source)
- mpr( "The lightning grounds out." );
-
- break;
- }
-
- // Trying to limit message spamming here so we'll only mention
- // the thunder when it's out of LoS.
- if (noisy( 25, sx, sy ) && !see_source)
- mpr( "You hear a mighty clap of thunder!", MSGCH_SOUND );
-
- if (see_source && !see_targ)
- mpr( "The lightning arcs out of your line of sight!" );
- else if (!see_source && see_targ)
- mpr( "The lightning arc suddenly appears!" );
-
- beam.source_x = sx;
- beam.source_y = sy;
- beam.target_x = tx;
- beam.target_y = ty;
- beam.colour = LIGHTBLUE;
- beam.damage = calc_dice( 2, 10 + powc / 2 ); // from beam.cc
- fire_beam( beam );
- }
-
- more();
-}
-
-void identify(int power)
-{
- int id_used = 1;
- int item_slot;
- char str_pass[ ITEMNAME_SIZE ];
-
- // scrolls of identify *may* produce "extra" identifications {dlb}:
- if (power == -1 && one_chance_in(5))
- id_used += (coinflip()? 1 : 2);
-
- do
- {
- item_slot = prompt_invent_item( "Identify which item?", -1, true,
- false, false );
- if (item_slot == PROMPT_ABORT)
- {
- canned_msg( MSG_OK );
- return;
- }
-
- set_ident_type( you.inv[item_slot].base_type,
- you.inv[item_slot].sub_type, ID_KNOWN_TYPE );
-
- set_ident_flags( you.inv[item_slot], ISFLAG_IDENT_MASK );
-
- // output identified item
- in_name( item_slot, DESC_INVENTORY_EQUIP, str_pass );
- mpr( str_pass );
-
- if (item_slot == you.equip[EQ_WEAPON])
- you.wield_change = true;
-
- id_used--;
- }
- while (id_used > 0);
-} // end identify()
-
-void conjure_flame(int pow)
-{
- struct dist spelld;
-
- bool done_first_message = false;
-
- for (;;)
- {
- if (done_first_message)
- mpr("Where would you like to place the cloud?", MSGCH_PROMPT);
- else
- {
- mpr("You cast a flaming cloud spell! But where?", MSGCH_PROMPT);
- done_first_message = true;
- }
-
- direction( spelld, DIR_TARGET, TARG_ENEMY );
-
- if (!spelld.isValid)
- {
- canned_msg(MSG_SPELL_FIZZLES);
- return;
- }
-
- if (!see_grid(spelld.tx, spelld.ty))
- {
- mpr("You can't see that place!");
- continue;
- }
-
- if (grid_is_solid(grd[ spelld.tx ][ spelld.ty ])
- || mgrd[ spelld.tx ][ spelld.ty ] != NON_MONSTER
- || env.cgrid[ spelld.tx ][ spelld.ty ] != EMPTY_CLOUD)
- {
- mpr( "There's already something there!" );
- continue;
- }
-
- break;
- }
-
- int durat = 5 + (random2(pow) / 2) + (random2(pow) / 2);
-
- if (durat > 23)
- durat = 23;
-
- place_cloud( CLOUD_FIRE, spelld.tx, spelld.ty, durat );
-} // end cast_conjure_flame()
-
-void stinking_cloud( int pow )
-{
- struct dist spelld;
- struct bolt beem;
-
- mpr( STD_DIRECTION_PROMPT, MSGCH_PROMPT );
-
- message_current_target();
-
- direction( spelld, DIR_NONE, TARG_ENEMY );
-
- if (!spelld.isValid)
- {
- canned_msg(MSG_SPELL_FIZZLES);
- return;
- }
-
- beem.target_x = spelld.tx;
- beem.target_y = spelld.ty;
-
- beem.source_x = you.x_pos;
- beem.source_y = you.y_pos;
-
- strcpy(beem.beam_name, "ball of vapour");
- beem.colour = GREEN;
- beem.range = 6;
- beem.rangeMax = 6;
- beem.damage = dice_def( 1, 0 );
- beem.hit = 20;
- beem.type = SYM_ZAP;
- beem.flavour = BEAM_MMISSILE;
- beem.ench_power = pow;
- beem.beam_source = MHITYOU;
- beem.thrower = KILL_YOU;
- beem.aux_source = NULL;
- beem.is_beam = false;
- beem.is_tracer = false;
-
- fire_beam(beem);
-} // end stinking_cloud()
-
-void cast_big_c(int pow, char cty)
-{
- struct dist cdis;
-
- mpr("Where do you want to put it?", MSGCH_PROMPT);
- direction( cdis, DIR_TARGET, TARG_ENEMY );
-
- if (!cdis.isValid)
- {
- canned_msg(MSG_SPELL_FIZZLES);
- return;
- }
-
- big_cloud( cty, cdis.tx, cdis.ty, pow, 8 + random2(3) );
-} // end cast_big_c()
-
-void big_cloud(char clouds, char cl_x, char cl_y, int pow, int size)
-{
- apply_area_cloud(make_a_normal_cloud, cl_x, cl_y, pow, size, clouds);
-} // end big_cloud()
-
-static char healing_spell( int healed )
-{
- int mgr = 0;
- struct monsters *monster = 0; // NULL {dlb}
- struct dist bmove;
-
- mpr("Which direction?", MSGCH_PROMPT);
- direction( bmove, DIR_DIR, TARG_FRIEND );
-
- if (!bmove.isValid)
- {
- canned_msg( MSG_HUH );
- return 0;
- }
-
- mgr = mgrd[you.x_pos + bmove.dx][you.y_pos + bmove.dy];
-
- if (bmove.dx == 0 && bmove.dy == 0)
- {
- mpr("You are healed.");
- inc_hp(healed, false);
- return 1;
- }
-
- if (mgr == NON_MONSTER)
- {
- mpr("There isn't anything there!");
- return -1;
- }
-
- monster = &menv[mgr];
-
- if (heal_monster(monster, healed, false))
- {
- strcpy(info, "You heal ");
- strcat(info, ptr_monam( monster, DESC_NOCAP_THE ));
- strcat(info, ".");
- mpr(info);
-
- if (monster->hit_points == monster->max_hit_points)
- simple_monster_message( monster, " is completely healed." );
- else
- print_wounds(monster);
- }
- else
- {
- canned_msg(MSG_NOTHING_HAPPENS);
- }
-
- return 1;
-} // end healing_spell()
-
-#if 0
-char cast_lesser_healing( int pow )
-{
- return healing_spell(5 + random2avg(7, 2));
-} // end lesser healing()
-
-char cast_greater_healing( int pow )
-{
- return healing_spell(15 + random2avg(29, 2));
-} // end cast_greater_healing()
-
-char cast_greatest_healing( int pow )
-{
- return healing_spell(50 + random2avg(49, 2));
-} // end cast_greatest_healing()
-#endif
-
-char cast_healing( int pow )
-{
- if (pow > 50)
- pow = 50;
-
- return (healing_spell( pow + roll_dice( 2, pow ) - 2 ));
-}
-
-bool cast_revivification(int power)
-{
- int loopy = 0; // general purpose loop variable {dlb}
- bool success = false;
- int loss = 0;
-
- if (you.hp == you.hp_max)
- canned_msg(MSG_NOTHING_HAPPENS);
- else if (you.hp_max < 21)
- mpr("You lack the resilience to cast this spell.");
- else
- {
- mpr("Your body is healed in an amazingly painful way.");
-
- loss = 2;
- for (loopy = 0; loopy < 9; loopy++)
- {
- if (random2(power) < 8)
- loss++;
- }
-
- dec_max_hp( loss );
- set_hp( you.hp_max, false );
- success = true;
- }
-
- return (success);
-} // end cast_revivification()
-
-void cast_cure_poison(int mabil)
-{
- if (!you.poison)
- canned_msg(MSG_NOTHING_HAPPENS);
- else
- reduce_poison_player( 2 + random2(mabil) + random2(3) );
-
- return;
-} // end cast_cure_poison()
-
-void purification(void)
-{
- mpr("You feel purified!");
-
- you.poison = 0;
- you.rotting = 0;
- you.conf = 0;
- you.slow = 0;
- you.disease = 0;
- you.paralysis = 0; // can't currently happen -- bwr
-} // end purification()
-
-int allowed_deaths_door_hp(void)
-{
- int hp = you.skills[SK_NECROMANCY] / 2;
-
- if (you.religion == GOD_KIKUBAAQUDGHA && !player_under_penance())
- hp += you.piety / 15;
-
- return (hp);
-}
-
-void cast_deaths_door(int pow)
-{
- if (you.is_undead)
- mpr("You're already dead!");
- else if (you.deaths_door)
- mpr("Your appeal for an extension has been denied.");
- else
- {
- mpr("You feel invincible!");
- mpr("You seem to hear sand running through an hourglass...");
-
- set_hp( allowed_deaths_door_hp(), false );
- deflate_hp( you.hp_max, false );
-
- you.deaths_door = 10 + random2avg(13, 3) + (random2(pow) / 10);
-
- if (you.deaths_door > 25)
- you.deaths_door = 23 + random2(5);
- }
-
- return;
-}
-
-// can't use beam variables here, because of monster_die and the puffs of smoke
-void abjuration(int pow)
-{
- struct monsters *monster = 0; // NULL {dlb}
-
- mpr("Send 'em back where they came from!");
-
- for (int ab = 0; ab < MAX_MONSTERS; ab++)
- {
- monster = &menv[ab];
-
- int abjLevel;
-
- if (monster->type == -1 || !mons_near(monster))
- continue;
-
- if (mons_friendly(monster))
- continue;
-
- abjLevel = mons_del_ench(monster, ENCH_ABJ_I, ENCH_ABJ_VI);
- if (abjLevel != ENCH_NONE)
- {
- abjLevel -= 1 + (random2(pow) / 8);
-
- if (abjLevel < ENCH_ABJ_I)
- monster_die(monster, KILL_RESET, 0);
- else
- {
- simple_monster_message(monster, " shudders.");
- mons_add_ench(monster, abjLevel);
- }
- }
- }
-} // end abjuration()
-
-// Antimagic is sort of an anti-extension... it sets a lot of magical
-// durations to 1 so it's very nasty at times (and potentially lethal,
-// that's why we reduce levitation to 2, so that the player has a chance
-// to stop insta-death... sure the others could lead to death, but that's
-// not as direct as falling into deep water) -- bwr
-void antimagic( void )
-{
- if (you.haste)
- you.haste = 1;
-
- if (you.slow)
- you.slow = 1;
-
- if (you.paralysis)
- you.paralysis = 1;
-
- if (you.conf)
- you.conf = 1;
-
- if (you.might)
- you.might = 1;
-
- if (you.levitation > 2)
- you.levitation = 2;
-
- if (you.invis)
- you.invis = 1;
-
- if (you.duration[DUR_WEAPON_BRAND])
- you.duration[DUR_WEAPON_BRAND] = 1;
-
- if (you.duration[DUR_ICY_ARMOUR])
- you.duration[DUR_ICY_ARMOUR] = 1;
-
- if (you.duration[DUR_REPEL_MISSILES])
- you.duration[DUR_REPEL_MISSILES] = 1;
-
- if (you.duration[DUR_REGENERATION])
- you.duration[DUR_REGENERATION] = 1;
-
- if (you.duration[DUR_DEFLECT_MISSILES])
- you.duration[DUR_DEFLECT_MISSILES] = 1;
-
- if (you.fire_shield)
- you.fire_shield = 1;
-
- if (you.duration[DUR_SWIFTNESS])
- you.duration[DUR_SWIFTNESS] = 1;
-
- if (you.duration[DUR_INSULATION])
- you.duration[DUR_INSULATION] = 1;
-
- if (you.duration[DUR_STONEMAIL])
- you.duration[DUR_STONEMAIL] = 1;
-
- if (you.duration[DUR_CONTROLLED_FLIGHT])
- you.duration[DUR_CONTROLLED_FLIGHT] = 1;
-
- if (you.duration[DUR_CONTROL_TELEPORT])
- you.duration[DUR_CONTROL_TELEPORT] = 1;
-
- if (you.duration[DUR_RESIST_POISON])
- you.duration[DUR_RESIST_POISON] = 1;
-
- if (you.duration[DUR_TRANSFORMATION])
- you.duration[DUR_TRANSFORMATION] = 1;
-
- //jmf: added following
- if (you.duration[DUR_STONESKIN])
- you.duration[DUR_STONESKIN] = 1;
-
- if (you.duration[DUR_FORESCRY])
- you.duration[DUR_FORESCRY] = 1;
-
- if (you.duration[DUR_SEE_INVISIBLE])
- you.duration[DUR_SEE_INVISIBLE] = 1;
-
- if (you.duration[DUR_SILENCE])
- you.duration[DUR_SILENCE] = 1;
-
- if (you.duration[DUR_CONDENSATION_SHIELD])
- you.duration[DUR_CONDENSATION_SHIELD] = 1;
-
- contaminate_player( -1 * (1+random2(5)));
-} // end antimagic()
-
-void extension(int pow)
-{
- int contamination = random2(2);
-
- if (you.haste)
- {
- potion_effect(POT_SPEED, pow);
- contamination++;
- }
-
- if (you.slow)
- potion_effect(POT_SLOWING, pow);
-
-#if 0
- if (you.paralysis)
- potion_effect(POT_PARALYSIS, pow); // how did you cast extension?
-
- if (you.conf)
- potion_effect(POT_CONFUSION, pow); // how did you cast extension?
-#endif
-
- if (you.might)
- {
- potion_effect(POT_MIGHT, pow);
- contamination++;
- }
-
- if (you.levitation)
- potion_effect(POT_LEVITATION, pow);
-
- if (you.invis)
- {
- potion_effect(POT_INVISIBILITY, pow);
- contamination++;
- }
-
- if (you.duration[DUR_ICY_ARMOUR])
- ice_armour(pow, true);
-
- if (you.duration[DUR_REPEL_MISSILES])
- missile_prot(pow);
-
- if (you.duration[DUR_REGENERATION])
- cast_regen(pow);
-
- if (you.duration[DUR_DEFLECT_MISSILES])
- deflection(pow);
-
- if (you.fire_shield)
- {
- you.fire_shield += random2(pow / 20);
-
- if (you.fire_shield > 50)
- you.fire_shield = 50;
-
- mpr("Your ring of flames roars with new vigour!");
- }
-
- if ( !(you.duration[DUR_WEAPON_BRAND] < 1
- || you.duration[DUR_WEAPON_BRAND] > 80) )
- {
- you.duration[DUR_WEAPON_BRAND] += 5 + random2(8);
- }
-
- if (you.duration[DUR_SWIFTNESS])
- cast_swiftness(pow);
-
- if (you.duration[DUR_INSULATION])
- cast_insulation(pow);
-
- if (you.duration[DUR_STONEMAIL])
- stone_scales(pow);
-
- if (you.duration[DUR_CONTROLLED_FLIGHT])
- cast_fly(pow);
-
- if (you.duration[DUR_CONTROL_TELEPORT])
- cast_teleport_control(pow);
-
- if (you.duration[DUR_RESIST_POISON])
- cast_resist_poison(pow);
-
- if (you.duration[DUR_TRANSFORMATION])
- {
- mpr("Your transformation has been extended.");
- you.duration[DUR_TRANSFORMATION] += random2(pow);
- if (you.duration[DUR_TRANSFORMATION] > 100)
- you.duration[DUR_TRANSFORMATION] = 100;
- }
-
- //jmf: added following
- if (you.duration[DUR_STONESKIN])
- cast_stoneskin(pow);
-
- if (you.duration[DUR_FORESCRY])
- cast_forescry(pow);
-
- if (you.duration[DUR_SEE_INVISIBLE])
- cast_see_invisible(pow);
-
- if (you.duration[DUR_SILENCE]) //how precisely did you cast extension?
- cast_silence(pow);
-
- if (you.duration[DUR_CONDENSATION_SHIELD])
- cast_condensation_shield(pow);
-
- if (contamination)
- contaminate_player( contamination );
-} // end extension()
-
-void ice_armour(int pow, bool extending)
-{
- if (!player_light_armour())
- {
- if (!extending)
- mpr("You are wearing too much armour.");
-
- return;
- }
-
- if (you.duration[DUR_STONEMAIL] || you.duration[DUR_STONESKIN])
- {
- if (!extending)
- mpr("The spell conflicts with another spell still in effect.");
-
- return;
- }
-
- if (you.duration[DUR_ICY_ARMOUR])
- mpr( "Your icy armour thickens." );
- else
- {
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_ICE_BEAST)
- mpr( "Your icy body feels more resilient." );
- else
- mpr( "A film of ice covers your body!" );
-
- you.redraw_armour_class = 1;
- }
-
- you.duration[DUR_ICY_ARMOUR] += 20 + random2(pow) + random2(pow);
-
- if (you.duration[DUR_ICY_ARMOUR] > 50)
- you.duration[DUR_ICY_ARMOUR] = 50;
-} // end ice_armour()
-
-void stone_scales(int pow)
-{
- int dur_change = 0;
-
- if (you.duration[DUR_ICY_ARMOUR] || you.duration[DUR_STONESKIN])
- {
- mpr("The spell conflicts with another spell still in effect.");
- return;
- }
-
- if (you.duration[DUR_STONEMAIL])
- mpr("Your scaly armour looks firmer.");
- else
- {
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_STATUE)
- mpr( "Your stone body feels more resilient." );
- else
- mpr( "A set of stone scales covers your body!" );
-
- you.redraw_evasion = 1;
- you.redraw_armour_class = 1;
- }
-
- dur_change = 20 + random2(pow) + random2(pow);
-
- if (dur_change + you.duration[DUR_STONEMAIL] >= 100)
- you.duration[DUR_STONEMAIL] = 100;
- else
- you.duration[DUR_STONEMAIL] += dur_change;
-
- burden_change();
-} // end stone_scales()
-
-void missile_prot(int pow)
-{
- mpr("You feel protected from missiles.");
-
- you.duration[DUR_REPEL_MISSILES] += 8 + roll_dice( 2, pow );
-
- if (you.duration[DUR_REPEL_MISSILES] > 100)
- you.duration[DUR_REPEL_MISSILES] = 100;
-} // end missile_prot()
-
-void deflection(int pow)
-{
- mpr("You feel very safe from missiles.");
-
- you.duration[DUR_DEFLECT_MISSILES] += 15 + random2(pow);
-
- if (you.duration[DUR_DEFLECT_MISSILES] > 100)
- you.duration[DUR_DEFLECT_MISSILES] = 100;
-} // end cast_deflection()
-
-void cast_regen(int pow)
-{
- //if (pow > 150) pow = 150;
- mpr("Your skin crawls.");
-
- you.duration[DUR_REGENERATION] += 5 + roll_dice( 2, pow / 3 + 1 );
-
- if (you.duration[DUR_REGENERATION] > 100)
- you.duration[DUR_REGENERATION] = 100;
-} // end cast_regen()
-
-void cast_berserk(void)
-{
- go_berserk(true);
-} // end cast_berserk()
-
-void cast_swiftness(int power)
-{
- int dur_incr = 0;
-
- if (player_in_water())
- {
- if (you.species == SP_MERFOLK)
- mpr("This spell will not benefit you while you're swimming!");
- else
- mpr("This spell will not benefit you while you're in water!");
-
- return;
- }
-
- if (!you.duration[DUR_SWIFTNESS] && player_movement_speed() <= 6)
- {
- mpr( "You can't move any more quickly." );
- return;
- }
-
- // Reduced the duration: -- bwr
- // dur_incr = random2(power) + random2(power) + 20;
- dur_incr = 20 + random2( power );
-
- // Centaurs do have feet and shouldn't get here anyways -- bwr
- snprintf( info, INFO_SIZE, "You feel quick%s",
- (you.species == SP_NAGA) ? "." : " on your feet." );
-
- mpr(info);
-
- if (dur_incr + you.duration[DUR_SWIFTNESS] > 100)
- you.duration[DUR_SWIFTNESS] = 100;
- else
- you.duration[DUR_SWIFTNESS] += dur_incr;
-} // end cast_swiftness()
-
-void cast_fly(int power)
-{
- int dur_change = 25 + random2(power) + random2(power);
-
- if (!player_is_levitating())
- mpr("You fly up into the air.");
- else
- mpr("You feel more buoyant.");
-
- if (you.levitation + dur_change > 100)
- you.levitation = 100;
- else
- you.levitation += dur_change;
-
- if (you.duration[DUR_CONTROLLED_FLIGHT] + dur_change > 100)
- you.duration[DUR_CONTROLLED_FLIGHT] = 100;
- else
- you.duration[DUR_CONTROLLED_FLIGHT] += dur_change;
-
- // duration[DUR_CONTROLLED_FLIGHT] makes the game think player
- // wears an amulet of controlled flight
-
- burden_change();
-}
-
-void cast_insulation(int power)
-{
- int dur_incr = 10 + random2(power);
-
- mpr("You feel insulated.");
-
- if (dur_incr + you.duration[DUR_INSULATION] > 100)
- you.duration[DUR_INSULATION] = 100;
- else
- you.duration[DUR_INSULATION] += dur_incr;
-} // end cast_insulation()
-
-void cast_resist_poison(int power)
-{
- int dur_incr = 10 + random2(power);
-
- mpr("You feel resistant to poison.");
-
- if (dur_incr + you.duration[DUR_RESIST_POISON] > 100)
- you.duration[DUR_RESIST_POISON] = 100;
- else
- you.duration[DUR_RESIST_POISON] += dur_incr;
-} // end cast_resist_poison()
-
-void cast_teleport_control(int power)
-{
- int dur_incr = 10 + random2(power);
-
- if (you.duration[DUR_CONTROL_TELEPORT] == 0)
- you.attribute[ATTR_CONTROL_TELEPORT]++;
-
- mpr("You feel in control.");
-
- if (dur_incr + you.duration[DUR_CONTROL_TELEPORT] >= 50)
- you.duration[DUR_CONTROL_TELEPORT] = 50;
- else
- you.duration[DUR_CONTROL_TELEPORT] += dur_incr;
-} // end cast_teleport_control()
-
-void cast_ring_of_flames(int power)
-{
- you.fire_shield += 5 + (power / 10) + (random2(power) / 5);
-
- if (you.fire_shield > 50)
- you.fire_shield = 50;
-
- mpr("The air around you leaps into flame!");
-
- manage_fire_shield();
-} // end cast_ring_of_flames()
-
-void cast_confusing_touch(int power)
-{
- snprintf( info, INFO_SIZE, "Your %s begin to glow %s.",
- your_hand(true), (you.confusing_touch ? "brighter" : "red") );
-
- mpr( info );
-
- you.confusing_touch += 5 + (random2(power) / 5);
-
- if (you.confusing_touch > 50)
- you.confusing_touch = 50;
-
-} // end cast_confusing_touch()
-
-bool cast_sure_blade(int power)
-{
- bool success = false;
-
- if (you.equip[EQ_WEAPON] == -1)
- mpr("You aren't wielding a weapon!");
- else if (weapon_skill( you.inv[you.equip[EQ_WEAPON]].base_type,
- you.inv[you.equip[EQ_WEAPON]].sub_type) != SK_SHORT_BLADES)
- {
- mpr("You cannot bond with this weapon.");
- }
- else
- {
- if (!you.sure_blade)
- mpr("You become one with your weapon.");
- else if (you.sure_blade < 25)
- mpr("Your bond becomes stronger.");
-
- you.sure_blade += 8 + (random2(power) / 10);
-
- if (you.sure_blade > 25)
- you.sure_blade = 25;
-
- success = true;
- }
-
- return (success);
-} // end cast_sure_blade()
-
-void manage_fire_shield(void)
-{
- you.fire_shield--;
-
- if (!you.fire_shield)
- return;
-
- char stx = 0, sty = 0;
-
- for (stx = -1; stx < 2; stx++)
- {
- for (sty = -1; sty < 2; sty++)
- {
- if (sty == 0 && stx == 0)
- continue;
-
- //if ( one_chance_in(3) ) beam.range ++;
-
- if (!grid_is_solid(grd[you.x_pos + stx][you.y_pos + sty])
- && env.cgrid[you.x_pos + stx][you.y_pos + sty] == EMPTY_CLOUD)
- {
- place_cloud( CLOUD_FIRE, you.x_pos + stx, you.y_pos + sty,
- 1 + random2(6) );
- }
- }
- }
-} // end manage_fire_shield()
diff --git a/stone_soup/crawl-ref/source/spells1.h b/stone_soup/crawl-ref/source/spells1.h
deleted file mode 100644
index dc98a1b133..0000000000
--- a/stone_soup/crawl-ref/source/spells1.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * File: spells1.cc
- * Summary: Implementations of some additional spells.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef SPELLS1_H
-#define SPELLS1_H
-
-
-#include "externs.h"
-#include "direct.h"
-
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: spell
- * *********************************************************************** */
-bool cast_sure_blade(int power);
-
-
-#if 0
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: ability - spell
- * *********************************************************************** */
-char cast_greater_healing(void);
-
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: ability
- * *********************************************************************** */
-char cast_greatest_healing(void);
-
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: ability - spell
- * *********************************************************************** */
-char cast_lesser_healing(void);
-#endif
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: ability - spell
- * *********************************************************************** */
-char cast_healing(int power);
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: beam - it_use3 - spells - spells1
- * *********************************************************************** */
-void big_cloud(char clouds, char cl_x, char cl_y, int pow, int size);
-
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: acr (WIZARD only) - item_use - spell
- * *********************************************************************** */
-void blink(void);
-
-
-/* ***********************************************************************
- * called from: spell
- * *********************************************************************** */
-void cast_big_c(int pow, char cty);
-void cast_confusing_touch(int power);
-void cast_cure_poison(int mabil);
-int allowed_deaths_door_hp(void);
-void cast_deaths_door(int pow);
-void cast_fire_storm(int powc);
-bool cast_revivification(int power);
-void cast_berserk(void);
-void cast_ring_of_flames(int power);
-void conjure_flame(int pow);
-void extension(int pow);
-void fireball(int power);
-void stinking_cloud(int pow);
-void abjuration(int pow);
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: ability - spell - spells1
- * *********************************************************************** */
-void cast_fly(int power);
-
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: spell - spells1
- * *********************************************************************** */
-void cast_insulation(int power);
-void cast_regen(int pow);
-void cast_resist_poison(int power);
-void cast_swiftness(int power);
-void cast_teleport_control(int power);
-void deflection(int pow);
-void ice_armour(int pow, bool extending);
-void missile_prot(int pow);
-void stone_scales(int pow);
-
-// last updated sept 18
-/* ***********************************************************************
- * called from: religion
- * *********************************************************************** */
-void antimagic(void);
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: acr (WIZARD only) - item_use - spell
- * *********************************************************************** */
-void identify(int power);
-
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - spells1
- * *********************************************************************** */
-void manage_fire_shield(void);
-
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: ability - spell
- * *********************************************************************** */
-void purification(void);
-
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: ability - decks - fight - spell - spells - spells1
- * *********************************************************************** */
-void random_blink(bool);
-
-
-#endif
diff --git a/stone_soup/crawl-ref/source/spells2.cc b/stone_soup/crawl-ref/source/spells2.cc
deleted file mode 100644
index 3c61fc2aa7..0000000000
--- a/stone_soup/crawl-ref/source/spells2.cc
+++ /dev/null
@@ -1,1602 +0,0 @@
-/*
- * File: spells2.cc
- * Summary: Implementations of some additional spells.
- * Written by: Linley Henzell
- *
- * Modified for Crawl Reference by $Author$ on $Date$
- *
- * Change History (most recent first):
- *
- * <4> 03jan1999 jmf Changed summon_small_mammals so at
- * higher levels it indeed summons in plural.
- * Removed some IMHO unnecessary failure msgs.
- * (from e.g. animate_dead).
- * Added protection by special deities.
- * <3> 10/11/99 BCR fixed range bug in burn_freeze,
- * vamp_drain, and summon_elemental
- * <2> 5/26/99 JDJ detect_items uses '~' instead of '*'.
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "spells2.h"
-
-#include <stdio.h>
-#include <string.h>
-
-#include "externs.h"
-
-#include "beam.h"
-#include "cloud.h"
-#include "direct.h"
-#include "dungeon.h"
-#include "effects.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "items.h"
-#include "misc.h"
-#include "monplace.h"
-#include "monstuff.h"
-#include "mon-util.h"
-#include "ouch.h"
-#include "player.h"
-#include "randart.h"
-#include "spells4.h"
-#include "spl-cast.h"
-#include "stuff.h"
-#include "view.h"
-#include "wpn-misc.h"
-
-int raise_corpse( int corps, int corx, int cory, int corps_beh,
- int corps_hit, int actual );
-
-unsigned char detect_traps( int pow )
-{
- unsigned char traps_found = 0;
-
- if (pow > 50)
- pow = 50;
-
- const int range = 8 + random2(8) + pow;
-
- for (int count_x = 0; count_x < MAX_TRAPS; count_x++)
- {
- const int etx = env.trap[ count_x ].x;
- const int ety = env.trap[ count_x ].y;
-
- // Used to just be visible screen:
- // if (etx > you.x_pos - 15 && etx < you.x_pos + 15
- // && ety > you.y_pos - 8 && ety < you.y_pos + 8)
-
- if (grid_distance( you.x_pos, you.y_pos, etx, ety ) < range)
- {
- if (grd[ etx ][ ety ] == DNGN_UNDISCOVERED_TRAP)
- {
- traps_found++;
-
- grd[ etx ][ ety ] = trap_category( env.trap[count_x].type );
- env.map[etx - 1][ety - 1] = '^';
- }
- }
- }
-
- return (traps_found);
-} // end detect_traps()
-
-unsigned char detect_items( int pow )
-{
- if (pow > 50)
- pow = 50;
-
- unsigned char items_found = 0;
- const int map_radius = 8 + random2(8) + pow;
-
- mpr("You detect items!");
-
- for (int i = you.x_pos - map_radius; i < you.x_pos + map_radius; i++)
- {
- for (int j = you.y_pos - map_radius; j < you.y_pos + map_radius; j++)
- {
- if (i < 5 || j < 5 || i > (GXM - 5) || j > (GYM - 5))
- continue;
-
- if (igrd[i][j] != NON_ITEM)
- {
- unsigned short flags = env.map[i - 1][j - 1];
- flags = !flags || (flags & ENVF_DETECTED)?
- ENVF_DETECTED
- : 0;
- env.map[i - 1][j - 1] = '~' | ENVF_DETECT_ITEM | flags;
- }
- }
- }
-
- return (items_found);
-} // end detect_items()
-
-static void fuzz_detect_creatures(int pow, int *fuzz_radius, int *fuzz_chance)
-{
-#ifdef DEBUG_DIAGNOSTICS
- mprf(MSGCH_DIAGNOSTICS, "dc_fuzz: Power is %d", pow);
-#endif
-
- if (pow < 1)
- pow = 1;
-
- *fuzz_radius = pow >= 50? 1 : 2;
-
- // Fuzz chance starts off at 100% and declines to a low of 10% for obscenely
- // powerful castings (pow caps around the 60 mark).
- *fuzz_chance = 100 - 90 * (pow - 1) / 59;
- if (*fuzz_chance < 10)
- *fuzz_chance = 10;
-}
-
-static void mark_detected_creature(int gridx, int gridy, const monsters *mon,
- int fuzz_chance, int fuzz_radius)
-{
- if (fuzz_radius && fuzz_chance > random2(100))
- {
- const int fuzz_diam = 2 * fuzz_radius + 1;
-
- int gx, gy;
- bool found_good = false;
- for (int itry = 0; itry < 5; ++itry)
- {
- gx = gridx + random2(fuzz_diam) - fuzz_radius;
- gy = gridy + random2(fuzz_diam) - fuzz_radius;
-
- if (in_map_grid(gx, gy) && !feat_blocks_movement(grd[gx][gy]))
- {
- found_good = true;
- break;
- }
- }
-
- if (found_good)
- {
- gridx = gx;
- gridy = gy;
- }
- }
-
- const int envx = gridx - 1,
- envy = gridy - 1;
-
- unsigned short flags = env.map[envx][envy];
- flags = !flags || (flags & ENVF_DETECTED)?
- ENVF_DETECTED
- : 0;
-
- env.map[envx][envy] =
- mons_char( mon->type ) | ENVF_DETECT_MONS | flags;
-}
-
-unsigned char detect_creatures( int pow )
-{
- int fuzz_radius = 0, fuzz_chance = 0;
- fuzz_detect_creatures(pow, &fuzz_radius, &fuzz_chance);
-
- if (pow > 50)
- pow = 50;
-
- unsigned char creatures_found = 0;
- const int map_radius = 8 + random2(8) + pow;
-
- // Clear the map so detect creatures is more useful and the detection
- // fuzz is harder to analyse by averaging.
- clear_map();
-
- mpr("You detect creatures!");
-
- for (int i = you.x_pos - map_radius; i < you.x_pos + map_radius; i++)
- {
- for (int j = you.y_pos - map_radius; j < you.y_pos + map_radius; j++)
- {
- if (i < 5 || j < 5 || i > (GXM - 5) || j > (GYM - 5))
- continue;
-
- if (mgrd[i][j] != NON_MONSTER)
- {
- struct monsters *mon = &menv[ mgrd[i][j] ];
- mark_detected_creature(i, j, mon, fuzz_chance, fuzz_radius);
-
- // Assuming that highly intelligent spellcasters can
- // detect scyring. -- bwr
- if (mons_intel( mon->type ) == I_HIGH
- && mons_class_flag( mon->type, M_SPELLCASTER ))
- {
- behaviour_event( mon, ME_DISTURB, MHITYOU,
- you.x_pos, you.y_pos );
- }
- }
- }
- }
-
- return (creatures_found);
-} // end detect_creatures()
-
-int corpse_rot(int power)
-{
- UNUSED( power );
-
- char adx = 0;
- char ady = 0;
-
- char minx = you.x_pos - 6;
- char maxx = you.x_pos + 7;
- char miny = you.y_pos - 6;
- char maxy = you.y_pos + 7;
- char xinc = 1;
- char yinc = 1;
-
- if (coinflip())
- {
- minx = you.x_pos + 6;
- maxx = you.x_pos - 7;
- xinc = -1;
- }
-
- if (coinflip())
- {
- miny = you.y_pos + 6;
- maxy = you.y_pos - 7;
- yinc = -1;
- }
-
- for (adx = minx; adx != maxx; adx += xinc)
- {
- if (adx == 7 || adx == -7)
- return 0;
-
- for (ady = miny; ady != maxy; ady += yinc)
- {
- if (see_grid(adx, ady))
- {
- if (igrd[adx][ady] == NON_ITEM
- || env.cgrid[adx][ady] != EMPTY_CLOUD)
- {
- continue;
- }
-
- int objl = igrd[adx][ady];
- int hrg = 0;
-
- while (objl != NON_ITEM)
- {
- if (mitm[objl].base_type == OBJ_CORPSES
- && mitm[objl].sub_type == CORPSE_BODY)
- {
- if (!mons_skeleton(mitm[objl].plus))
- destroy_item(objl);
- else
- {
- mitm[objl].sub_type = CORPSE_SKELETON;
- mitm[objl].special = 200;
- mitm[objl].colour = LIGHTGREY;
- }
-
- place_cloud(CLOUD_MIASMA, adx, ady,
- 4 + random2avg(16, 3));
-
- goto out_of_raise;
- }
- hrg = mitm[objl].link;
- objl = hrg;
- }
-
- out_of_raise:
- objl = 1;
- }
- }
- }
-
- if (you.species != SP_MUMMY) // josh declares mummies cannot smell {dlb}
- mpr("You smell decay.");
-
- // should make zombies decay into skeletons
-
- return 0;
-} // end corpse_rot()
-
-int animate_dead( int power, int corps_beh, int corps_hit, int actual )
-{
- UNUSED( power );
-
- int adx = 0;
- int ady = 0;
-
- int minx = you.x_pos - 6;
- int maxx = you.x_pos + 7;
- int miny = you.y_pos - 6;
- int maxy = you.y_pos + 7;
- int xinc = 1;
- int yinc = 1;
-
- int number_raised = 0;
-
- if (coinflip())
- {
- minx = you.x_pos + 6;
- maxx = you.x_pos - 7;
- xinc = -1;
- }
-
- if (coinflip())
- {
- miny = you.y_pos + 6;
- maxy = you.y_pos - 7;
- yinc = -1;
- }
-
- for (adx = minx; adx != maxx; adx += xinc)
- {
- if ((adx == 7) || (adx == -7))
- return 0;
-
- for (ady = miny; ady != maxy; ady += yinc)
- {
- if (see_grid(adx, ady))
- {
- if (igrd[adx][ady] != NON_ITEM)
- {
- int objl = igrd[adx][ady];
- int hrg = 0;
-
- //this searches all the items on the ground for a corpse
- while (objl != NON_ITEM)
- {
- if (mitm[objl].base_type == OBJ_CORPSES)
- {
- number_raised += raise_corpse(objl, adx, ady,
- corps_beh, corps_hit, actual);
- break;
- }
-
- hrg = mitm[objl].link;
- objl = hrg;
- }
-
- objl = 1;
- }
- }
- }
- }
-
- if (actual == 0)
- return number_raised;
-
- if (number_raised > 0)
- {
- mpr("The dead are walking!");
- //else
- // mpr("The dark energy consumes the dead!"); - no, this
- // means that no corpses were found. Better to say:
- // mpr("You receive no reply.");
- //jmf: Why do I have to get an uninformative message when some random
- //jmf: monster fails to do something?
- // IMHO there's too much noise already.
- }
-
- return number_raised;
-} // end animate_dead()
-
-int animate_a_corpse( int axps, int ayps, int corps_beh, int corps_hit,
- int class_allowed )
-{
- if (igrd[axps][ayps] == NON_ITEM)
- return 0;
-
- int objl = igrd[axps][ayps];
- // This searches all the items on the ground for a corpse
- while (objl != NON_ITEM)
- {
- if (mitm[objl].base_type != OBJ_CORPSES
- || (class_allowed == CORPSE_SKELETON
- && mitm[objl].sub_type != CORPSE_SKELETON))
- {
- objl = mitm[objl].link;
- continue;
- }
-
- if (raise_corpse(objl, axps, ayps,
- corps_beh, corps_hit, 1 ) > 0)
- mpr("The dead are walking!");
- break;
- }
-
- return 0;
-} // end animate_a_corpse()
-
-int raise_corpse( int corps, int corx, int cory,
- int corps_beh, int corps_hit, int actual )
-{
- int returnVal = 1;
-
- if (!mons_zombie_size(mitm[corps].plus))
- returnVal = 0;
- else if (actual != 0)
- {
- int type;
- if (mitm[corps].sub_type == CORPSE_BODY)
- {
- if (mons_zombie_size(mitm[corps].plus) == Z_SMALL)
- type = MONS_ZOMBIE_SMALL;
- else
- type = MONS_ZOMBIE_LARGE;
- }
- else
- {
- if (mons_zombie_size(mitm[corps].plus) == Z_SMALL)
- type = MONS_SKELETON_SMALL;
- else
- type = MONS_SKELETON_LARGE;
- }
-
- create_monster( type, 0, corps_beh, corx, cory, corps_hit,
- mitm[corps].plus );
-
- destroy_item(corps);
- }
-
- return returnVal;
-} // end raise_corpse()
-
-void cast_twisted(int power, int corps_beh, int corps_hit)
-{
- int total_mass = 0;
- int num_corpses = 0;
- int type_resurr = MONS_ABOMINATION_SMALL;
- char colour;
-
- unsigned char rotted = 0;
-
- if (igrd[you.x_pos][you.y_pos] == NON_ITEM)
- {
- mpr("There's nothing here!");
- return;
- }
-
- int objl = igrd[you.x_pos][you.y_pos];
- int next;
-
- while (objl != NON_ITEM)
- {
- next = mitm[objl].link;
-
- if (mitm[objl].base_type == OBJ_CORPSES
- && mitm[objl].sub_type == CORPSE_BODY)
- {
- total_mass += mons_weight( mitm[objl].plus );
-
- num_corpses++;
- if (mitm[objl].special < 100)
- rotted++;
-
- destroy_item( objl );
- }
-
- objl = next;
- }
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "Mass for abomination: %d", total_mass);
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- // This is what the old statement pretty much boils down to,
- // the average will be approximately 10 * power (or about 1000
- // at the practical maximum). That's the same as the mass
- // of a hippogriff, a spiny frog, or a steam dragon. Thus,
- // material components are far more important to this spell. -- bwr
- total_mass += roll_dice( 20, power );
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "Mass including power bonus: %d", total_mass);
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- if (total_mass < 400 + roll_dice( 2, 500 )
- || num_corpses < (coinflip() ? 3 : 2))
- {
- mpr("The spell fails.");
- mpr("The corpses collapse into a pulpy mess.");
- return;
- }
-
- if (total_mass > 500 + roll_dice( 3, 1000 ))
- type_resurr = MONS_ABOMINATION_LARGE;
-
- if (rotted == num_corpses)
- colour = BROWN;
- else if (rotted >= random2( num_corpses ))
- colour = RED;
- else
- colour = LIGHTRED;
-
- int mon = create_monster( type_resurr, 0, corps_beh, you.x_pos, you.y_pos,
- corps_hit, colour );
-
- if (mon == -1)
- mpr("The corpses collapse into a pulpy mess.");
- else
- {
- mpr("The heap of corpses melds into an agglomeration of writhing flesh!");
- if (type_resurr == MONS_ABOMINATION_LARGE)
- {
- menv[mon].hit_dice = 8 + total_mass / ((colour == LIGHTRED) ? 500 :
- (colour == RED) ? 1000
- : 2500);
-
- if (menv[mon].hit_dice > 30)
- menv[mon].hit_dice = 30;
-
- // XXX: No convenient way to get the hit dice size right now.
- menv[mon].hit_points = hit_points( menv[mon].hit_dice, 2, 5 );
- menv[mon].max_hit_points = menv[mon].hit_points;
-
- if (colour == LIGHTRED)
- menv[mon].armour_class += total_mass / 1000;
- }
- }
-} // end cast_twisted()
-
-bool brand_weapon(int which_brand, int power)
-{
- int temp_rand; // probability determination {dlb}
- int duration_affected = 0; //jmf: NB: now HOW LONG, not WHICH BRAND.
-
- const int wpn = you.equip[EQ_WEAPON];
-
- if (you.duration[DUR_WEAPON_BRAND])
- return false;
-
- if (wpn == -1)
- return false;
-
- if (you.inv[wpn].base_type != OBJ_WEAPONS
- || launches_things(you.inv[wpn].sub_type))
- {
- return false;
- }
-
- if (is_fixed_artefact( you.inv[wpn] )
- || is_random_artefact( you.inv[wpn] )
- || get_weapon_brand( you.inv[wpn] ) != SPWPN_NORMAL )
- {
- return false;
- }
-
- char str_pass[ ITEMNAME_SIZE ];
- in_name( wpn, DESC_CAP_YOUR, str_pass );
- strcpy( info, str_pass );
-
- const int wpn_type = damage_type(you.inv[wpn]);
-
- switch (which_brand) // use SPECIAL_WEAPONS here?
- {
- case SPWPN_FLAMING:
- strcat(info, " bursts into flame!");
- duration_affected = 7;
- break;
-
- case SPWPN_FREEZING:
- strcat(info, " glows blue.");
- duration_affected = 7;
- break;
-
- case SPWPN_VENOM:
- if (wpn_type == DVORP_CRUSHING)
- return false;
-
- strcat(info, " starts dripping with poison.");
- duration_affected = 15;
- break;
-
- case SPWPN_DRAINING:
- strcat(info, " crackles with unholy energy.");
- duration_affected = 12;
- break;
-
- case SPWPN_VORPAL:
- if (wpn_type != DVORP_SLICING)
- return false;
-
- strcat(info, " glows silver and looks extremely sharp.");
- duration_affected = 10;
- break;
-
- case SPWPN_DISTORTION: //jmf: added for Warp Weapon
- strcat(info, " seems to ");
-
- temp_rand = random2(6);
- strcat(info, (temp_rand == 0) ? "twist" :
- (temp_rand == 1) ? "bend" :
- (temp_rand == 2) ? "vibrate" :
- (temp_rand == 3) ? "flex" :
- (temp_rand == 4) ? "wobble"
- : "twang");
-
- strcat( info, coinflip() ? " oddly." : " strangely." );
- duration_affected = 5;
-
- // [dshaligram] Clamping power to 2.
- power = 2;
-
- // This brand is insanely powerful, this isn't even really
- // a start to balancing it, but it needs something. -- bwr
- // [dshaligram] At level 7 it's costly enough to experiment
- // with removing the miscast effect. We may need to revise the spell
- // to level 8 or 9. XXX.
- // miscast_effect(SPTYP_TRANSLOCATION,
- // 9, 90, 100, "a distortion effect");
- break;
-
- case SPWPN_DUMMY_CRUSHING: //jmf: added for Maxwell's Silver Hammer
- if (wpn_type != DVORP_CRUSHING)
- return false;
-
- which_brand = SPWPN_VORPAL;
- strcat(info, " glows silver and feels heavier.");
- duration_affected = 7;
- break;
- }
-
- set_item_ego_type( you.inv[wpn], OBJ_WEAPONS, which_brand );
-
- mpr(info);
- you.wield_change = true;
-
- int dur_change = duration_affected + roll_dice( 2, power );
-
- you.duration[DUR_WEAPON_BRAND] += dur_change;
-
- if (you.duration[DUR_WEAPON_BRAND] > 50)
- you.duration[DUR_WEAPON_BRAND] = 50;
-
- return true;
-} // end brand_weapon()
-
-bool restore_stat(unsigned char which_stat, bool suppress_msg)
-{
- bool statRestored = false;
-
- // a bit hackish, but cut me some slack, man! --
- // besides, a little recursion never hurt anyone {dlb}:
- if (which_stat == STAT_ALL)
- {
- for (unsigned char loopy = STAT_STRENGTH; loopy < NUM_STATS; loopy++)
- {
- if (restore_stat(loopy, suppress_msg) == true)
- statRestored = true;
- }
- return statRestored; // early return {dlb}
- }
-
- // the real function begins here {dlb}:
- char *ptr_stat = 0; // NULL {dlb}
- char *ptr_stat_max = 0; // NULL {dlb}
- char *ptr_redraw = 0; // NULL {dlb}
-
- if (!suppress_msg)
- strcpy(info, "You feel your ");
-
- if (which_stat == STAT_RANDOM)
- which_stat = random2(NUM_STATS);
-
- switch (which_stat)
- {
- case STAT_STRENGTH:
- if (!suppress_msg)
- strcat(info, "strength");
-
- ptr_stat = &you.strength;
- ptr_stat_max = &you.max_strength;
- ptr_redraw = &you.redraw_strength;
- break;
-
- case STAT_DEXTERITY:
- if (!suppress_msg)
- strcat(info, "dexterity");
-
- ptr_stat = &you.dex;
- ptr_stat_max = &you.max_dex;
- ptr_redraw = &you.redraw_dexterity;
- break;
-
- case STAT_INTELLIGENCE:
- if (!suppress_msg)
- strcat(info, "intelligence");
-
- ptr_stat = &you.intel;
- ptr_stat_max = &you.max_intel;
- ptr_redraw = &you.redraw_intelligence;
- break;
- }
-
- if (*ptr_stat < *ptr_stat_max)
- {
- if (!suppress_msg)
- {
- strcat(info, " returning.");
- mpr(info);
- }
-
- *ptr_stat = *ptr_stat_max;
- *ptr_redraw = 1;
- statRestored = true;
-
- if (ptr_stat == &you.strength)
- burden_change();
- }
-
- return statRestored;
-} // end restore_stat()
-
-void turn_undead(int pow)
-{
- struct monsters *monster;
-
- mpr("You attempt to repel the undead.");
-
- for (int tu = 0; tu < MAX_MONSTERS; tu++)
- {
- monster = &menv[tu];
-
- if (monster->type == -1 || !mons_near(monster))
- continue;
-
- // used to inflict random2(5) + (random2(pow) / 20) damage,
- // in addition {dlb}
- if (mons_holiness(monster) == MH_UNDEAD)
- {
- if (check_mons_resist_magic( monster, pow ))
- {
- simple_monster_message( monster, " resists." );
- continue;
- }
-
- if (!mons_add_ench(monster, ENCH_FEAR))
- continue;
-
- simple_monster_message( monster, " is repelled!" );
-
- //mv: must be here to work
- behaviour_event( monster, ME_SCARE, MHITYOU );
-
- // reduce power based on monster turned
- pow -= monster->hit_dice * 3;
- if (pow <= 0)
- break;
-
- } // end "if mons_holiness"
- } // end "for tu"
-} // end turn_undead()
-
-void holy_word(int pow, bool silent)
-{
- struct monsters *monster;
-
- if (!silent)
- mpr("You speak a Word of immense power!");
-
- // doubt this will ever happen, but it's here as a safety -- bwr
- if (pow > 300)
- pow = 300;
-
- for (int tu = 0; tu < MAX_MONSTERS; tu++)
- {
- monster = &menv[tu];
-
- if (monster->type == -1 || !mons_near(monster))
- continue;
-
- if (mons_holiness(monster) == MH_UNDEAD
- || mons_holiness(monster) == MH_DEMONIC)
- {
- simple_monster_message(monster, " convulses!");
-
- hurt_monster( monster, roll_dice( 2, 15 ) + (random2(pow) / 3) );
-
- if (monster->hit_points < 1)
- {
- monster_die(monster, KILL_YOU, 0);
- continue;
- }
-
- if (monster->speed_increment >= 25)
- monster->speed_increment -= 20;
-
- mons_add_ench(monster, ENCH_FEAR);
- } // end "if mons_holiness"
- } // end "for tu"
-} // end holy_word()
-
-// poisonous light passes right through invisible players
-// and monsters, and so, they are unaffected by this spell --
-// assumes only you can cast this spell (or would want to)
-void cast_toxic_radiance(void)
-{
- struct monsters *monster;
-
- mpr("You radiate a sickly green light!");
-
- show_green = GREEN;
- viewwindow(1, false);
- more();
- mesclr();
-
- // determine whether the player is hit by the radiance: {dlb}
- if (you.invis)
- {
- mpr("The light passes straight through your body.");
- }
- else if (!player_res_poison())
- {
- mpr("You feel rather sick.");
- poison_player(2);
- }
-
- // determine which monsters are hit by the radiance: {dlb}
- for (int toxy = 0; toxy < MAX_MONSTERS; toxy++)
- {
- monster = &menv[toxy];
-
- if (monster->type != -1 && mons_near(monster))
- {
- if (!mons_has_ench(monster, ENCH_INVIS))
- {
- poison_monster(monster, true);
-
- if (coinflip()) // 50-50 chance for a "double hit" {dlb}
- poison_monster(monster, true);
-
- }
- else if (player_see_invis())
- {
- // message player re:"miss" where appropriate {dlb}
- strcpy(info, "The light passes through ");
- strcat(info, ptr_monam( monster, DESC_NOCAP_THE ));
- strcat(info, ".");
- mpr(info);
- }
- }
- }
-} // end cast_toxic_radiance()
-
-void cast_refrigeration(int pow)
-{
- struct monsters *monster = 0; // NULL {dlb}
- int hurted = 0;
- struct bolt beam;
- int toxy;
-
- beam.flavour = BEAM_COLD;
-
- const dice_def dam_dice( 3, 5 + pow / 10 );
-
- mpr("The heat is drained from your surroundings.");
-
- show_green = LIGHTCYAN;
- viewwindow(1, false);
- more();
- mesclr();
-
- // Do the player:
- hurted = roll_dice( dam_dice );
- hurted = check_your_resists( hurted, beam.flavour );
-
- if (hurted > 0)
- {
- mpr("You feel very cold.");
- ouch( hurted, 0, KILLED_BY_FREEZING );
-
- // Note: this used to be 12!... and it was also applied even if
- // the player didn't take damage from the cold, so we're being
- // a lot nicer now. -- bwr
- scrolls_burn( 5, OBJ_POTIONS );
- }
-
- // Now do the monsters:
- for (toxy = 0; toxy < MAX_MONSTERS; toxy++)
- {
- monster = &menv[toxy];
-
- if (monster->type == -1)
- continue;
-
- if (mons_near(monster))
- {
- snprintf( info, INFO_SIZE, "You freeze %s.",
- ptr_monam( monster, DESC_NOCAP_THE ));
-
- mpr(info);
-
- hurted = roll_dice( dam_dice );
- hurted = mons_adjust_flavoured( monster, beam, hurted );
-
- if (hurted > 0)
- {
- hurt_monster( monster, hurted );
-
- if (monster->hit_points < 1)
- monster_die(monster, KILL_YOU, 0);
- else
- {
- print_wounds(monster);
-
- //jmf: "slow snakes" finally available
- if (mons_class_flag( monster->type, M_COLD_BLOOD ) && coinflip())
- mons_add_ench(monster, ENCH_SLOW);
- }
- }
- }
- }
-} // end cast_refrigeration()
-
-void drain_life(int pow)
-{
- int hp_gain = 0;
- int hurted = 0;
- struct monsters *monster = 0; // NULL {dlb}
-
- mpr("You draw life from your surroundings.");
-
- // Incoming power to this function is skill in INVOCATIONS, so
- // we'll add an assert here to warn anyone who tries to use
- // this function with spell level power.
- ASSERT( pow <= 27 );
-
- show_green = DARKGREY;
- viewwindow(1, false);
- more();
- mesclr();
-
- for (int toxy = 0; toxy < MAX_MONSTERS; toxy++)
- {
- monster = &menv[toxy];
-
- if (monster->type == -1)
- continue;
-
- if (mons_holiness(monster) != MH_NATURAL)
- continue;
-
- if (mons_res_negative_energy( monster ))
- continue;
-
- if (mons_near(monster))
- {
- strcpy(info, "You draw life from ");
- strcat(info, ptr_monam( monster, DESC_NOCAP_THE ));
- strcat(info, ".");
- mpr(info);
-
- hurted = 3 + random2(7) + random2(pow);
-
- hurt_monster(monster, hurted);
-
- hp_gain += hurted;
-
- if (monster->hit_points < 1)
- monster_die(monster, KILL_YOU, 0);
- else
- print_wounds(monster);
- }
- }
-
- hp_gain /= 2;
-
- if (hp_gain > pow * 2)
- hp_gain = pow * 2;
-
- if (hp_gain)
- {
- mpr( "You feel life flooding into your body." );
- inc_hp( hp_gain, false );
- }
-} // end drain_life()
-
-int vampiric_drain(int pow)
-{
- int inflicted = 0;
- int mgr = 0;
- struct monsters *monster = 0; // NULL
- struct dist vmove;
-
- dirc:
- mpr("Which direction?", MSGCH_PROMPT);
- direction( vmove, DIR_DIR, TARG_ENEMY );
-
- if (!vmove.isValid)
- {
- canned_msg(MSG_SPELL_FIZZLES);
- return -1;
- }
-
- mgr = mgrd[you.x_pos + vmove.dx][you.y_pos + vmove.dy];
-
- if (vmove.dx == 0 && vmove.dy == 0)
- {
- mpr("You can't do that.");
- goto dirc;
- }
-
- if (mgr == NON_MONSTER)
- {
- mpr("There isn't anything there!");
- return -1;
- }
-
- monster = &menv[mgr];
-
- const int holy = mons_holiness(monster);
-
- if (holy == MH_UNDEAD || holy == MH_DEMONIC)
- {
- mpr("Aaaarggghhhhh!");
- dec_hp(random2avg(39, 2) + 10, false);
- return -1;
- }
-
- if (mons_res_negative_energy( monster ))
- {
- canned_msg(MSG_NOTHING_HAPPENS);
- return -1;
- }
-
- // The practical maximum of this is about 25 (pow @ 100). -- bwr
- inflicted = 3 + random2avg( 9, 2 ) + random2(pow) / 7;
-
- if (inflicted >= monster->hit_points)
- inflicted = monster->hit_points;
-
- if (inflicted >= you.hp_max - you.hp)
- inflicted = you.hp_max - you.hp;
-
- if (inflicted == 0)
- {
- canned_msg(MSG_NOTHING_HAPPENS);
- return -1;
- }
-
- hurt_monster(monster, inflicted);
-
- strcpy(info, "You feel life coursing from ");
- strcat(info, ptr_monam( monster, DESC_NOCAP_THE ));
- strcat(info, " into your body!");
- mpr(info);
-
- print_wounds(monster);
-
- if (monster->hit_points < 1)
- monster_die(monster, KILL_YOU, 0);
-
- inc_hp(inflicted / 2, false);
-
- return 1;
-} // end vampiric_drain()
-
-// Note: this function is currently only used for Freeze. -- bwr
-char burn_freeze(int pow, char flavour)
-{
- int mgr = NON_MONSTER;
- struct monsters *monster = 0; // NULL {dlb}
- struct dist bmove;
-
- if (pow > 25)
- pow = 25;
-
- while (mgr == NON_MONSTER)
- {
- mpr("Which direction?", MSGCH_PROMPT);
- direction( bmove, DIR_DIR, TARG_ENEMY );
-
- if (!bmove.isValid)
- {
- canned_msg(MSG_SPELL_FIZZLES);
- return -1;
- }
-
- if (bmove.isMe)
- {
- canned_msg(MSG_UNTHINKING_ACT);
- return -1;
- }
-
- mgr = mgrd[you.x_pos + bmove.dx][you.y_pos + bmove.dy];
-
- // Yes, this is strange, but it does maintain the original behaviour
- if (mgr == NON_MONSTER)
- {
- mpr("There isn't anything close enough!");
- return -1;
- }
- }
-
- monster = &menv[mgr];
-
- strcpy(info, "You ");
- strcat(info, (flavour == BEAM_FIRE) ? "burn" :
- (flavour == BEAM_COLD) ? "freeze" :
- (flavour == BEAM_MISSILE) ? "crush" :
- (flavour == BEAM_ELECTRICITY) ? "zap"
- : "______");
-
- strcat(info, " ");
- strcat(info, ptr_monam( monster, DESC_NOCAP_THE ));
- strcat(info, ".");
- mpr(info);
-
- int hurted = roll_dice( 1, 3 + pow / 3 );
-
- struct bolt beam;
-
- beam.flavour = flavour;
-
- if (flavour != BEAM_MISSILE)
- hurted = mons_adjust_flavoured(monster, beam, hurted);
-
- if (hurted)
- {
- hurt_monster(monster, hurted);
-
- if (monster->hit_points < 1)
- monster_die(monster, KILL_YOU, 0);
- else
- {
- print_wounds(monster);
-
- if (flavour == BEAM_COLD)
- {
- if (mons_class_flag( monster->type, M_COLD_BLOOD ) && coinflip())
- mons_add_ench(monster, ENCH_SLOW);
-
- const int cold_res = mons_res_cold( monster );
- if (cold_res <= 0)
- {
- const int stun = (1 - cold_res) * random2( 2 + pow / 5 );
- monster->speed_increment -= stun;
- }
- }
- }
- }
-
- return 1;
-} // end burn_freeze()
-
-// 'unfriendly' is percentage chance summoned elemental goes
-// postal on the caster (after taking into account
-// chance of that happening to unskilled casters
-// anyway)
-int summon_elemental(int pow, int restricted_type,
- unsigned char unfriendly)
-{
- int type_summoned = MONS_PROGRAM_BUG; // error trapping {dlb}
- char summ_success = 0;
- struct dist smove;
-
- int dir_x;
- int dir_y;
- int targ_x;
- int targ_y;
-
- int numsc = ENCH_ABJ_II + (random2(pow) / 5);
-
- if (numsc > ENCH_ABJ_VI)
- numsc = ENCH_ABJ_VI;
-
- for (;;)
- {
- mpr("Summon from material in which direction?", MSGCH_PROMPT);
-
- direction( smove, DIR_DIR );
-
- if (!smove.isValid)
- {
- canned_msg(MSG_NOTHING_HAPPENS);
- return (-1);
- }
-
- dir_x = smove.dx;
- dir_y = smove.dy;
- targ_x = you.x_pos + dir_x;
- targ_y = you.y_pos + dir_y;
-
- if (mgrd[ targ_x ][ targ_y ] != NON_MONSTER)
- mpr("Not there!");
- else if (dir_x == 0 && dir_y == 0)
- mpr("You can't summon an elemental from yourself!");
- else
- break;
- }
-
- if (grd[ targ_x ][ targ_y ] == DNGN_ROCK_WALL
- && (restricted_type == 0 || restricted_type == MONS_EARTH_ELEMENTAL))
- {
- type_summoned = MONS_EARTH_ELEMENTAL;
-
- if (targ_x > 6 && targ_x < 74 && targ_y > 6 && targ_y < 64)
- grd[ targ_x ][ targ_y ] = DNGN_FLOOR;
- }
- else if ((env.cgrid[ targ_x ][ targ_y ] != EMPTY_CLOUD
- && (env.cloud[env.cgrid[ targ_x ][ targ_y ]].type == CLOUD_FIRE
- || env.cloud[env.cgrid[ targ_x ][ targ_y ]].type == CLOUD_FIRE_MON))
- && (restricted_type == 0 || restricted_type == MONS_FIRE_ELEMENTAL))
- {
- type_summoned = MONS_FIRE_ELEMENTAL;
- delete_cloud( env.cgrid[ targ_x ][ targ_y ] );
- }
- else if ((grd[ targ_x ][ targ_y ] == DNGN_LAVA)
- && (restricted_type == 0 || restricted_type == MONS_FIRE_ELEMENTAL))
- {
- type_summoned = MONS_FIRE_ELEMENTAL;
- }
- else if ((grd[ targ_x ][ targ_y ] == DNGN_DEEP_WATER
- || grd[ targ_x ][ targ_y ] == DNGN_SHALLOW_WATER
- || grd[ targ_x ][ targ_y ] == DNGN_BLUE_FOUNTAIN)
- && (restricted_type == 0 || restricted_type == MONS_WATER_ELEMENTAL))
- {
- type_summoned = MONS_WATER_ELEMENTAL;
- }
- else if ((grd[ targ_x ][ targ_y ] >= DNGN_FLOOR
- && env.cgrid[ targ_x ][ targ_y ] == EMPTY_CLOUD)
- && (restricted_type == 0 || restricted_type == MONS_AIR_ELEMENTAL))
- {
- type_summoned = MONS_AIR_ELEMENTAL;
- }
-
- // found something to summon
- if (type_summoned == MONS_PROGRAM_BUG)
- {
- canned_msg(MSG_NOTHING_HAPPENS);
- return (-1);
- }
-
- // silly - ice for water? 15jan2000 {dlb}
- // little change here to help with the above... and differentiate
- // elements a bit... {bwr}
- // - Water elementals are now harder to be made reliably friendly
- // - Air elementals are harder because they're more dynamic/dangerous
- // - Earth elementals are more static and easy to tame (as before)
- // - Fire elementals fall in between the two (10 is still fairly easy)
- if ((type_summoned == MONS_FIRE_ELEMENTAL
- && random2(10) >= you.skills[SK_FIRE_MAGIC])
-
- || (type_summoned == MONS_WATER_ELEMENTAL
- && random2((you.species == SP_MERFOLK) ? 5 : 15)
- >= you.skills[SK_ICE_MAGIC])
-
- || (type_summoned == MONS_AIR_ELEMENTAL
- && random2(15) >= you.skills[SK_AIR_MAGIC])
-
- || (type_summoned == MONS_EARTH_ELEMENTAL
- && random2(5) >= you.skills[SK_EARTH_MAGIC])
-
- || random2(100) < unfriendly)
- {
- summ_success = create_monster( type_summoned, numsc, BEH_HOSTILE,
- targ_x, targ_y, MHITYOU, 250 );
-
- if (summ_success >= 0)
- mpr( "The elemental doesn't seem to appreciate being summoned." );
- }
- else
- {
- summ_success = create_monster( type_summoned, numsc, BEH_FRIENDLY,
- targ_x, targ_y, you.pet_target, 250 );
- }
-
- return (summ_success >= 0);
-} // end summon_elemental()
-
-//jmf: beefed up higher-level casting of this (formerly lame) spell
-void summon_small_mammals(int pow)
-{
- int thing_called = MONS_PROGRAM_BUG; // error trapping{dlb}
-
- int pow_spent = 0;
- int pow_left = pow + 1;
- int summoned = 0;
- int summoned_max = pow / 16;
-
- if (summoned_max > 5)
- summoned_max = 5;
- if (summoned_max < 1)
- summoned_max = 1;
-
- while (pow_left > 0 && summoned < summoned_max)
- {
- summoned++;
- pow_spent = 1 + random2(pow_left);
- pow_left -= pow_spent;
-
- switch (pow_spent)
- {
- case 75:
- case 74:
- case 38:
- thing_called = MONS_ORANGE_RAT;
- break;
-
- case 65:
- case 64:
- case 63:
- case 27:
- case 26:
- case 25:
- thing_called = MONS_GREEN_RAT;
- break;
-
- case 57:
- case 56:
- case 55:
- case 54:
- case 53:
- case 52:
- case 20:
- case 18:
- case 16:
- case 14:
- case 12:
- case 10:
- thing_called = coinflip() ? MONS_QUOKKA : MONS_GREY_RAT;
- break;
-
- default:
- thing_called = coinflip() ? MONS_GIANT_BAT : MONS_RAT;
- break;
- }
-
- create_monster( thing_called, ENCH_ABJ_III, BEH_FRIENDLY,
- you.x_pos, you.y_pos, you.pet_target, 250 );
- }
-} // end summon_small_mammals()
-
-void summon_scorpions(int pow)
-{
- int numsc = 1 + random2(pow) / 10 + random2(pow) / 10;
-
- numsc = stepdown_value(numsc, 2, 2, 6, 8); //see stuff.cc - 12jan2000 {dlb}
-
- for (int scount = 0; scount < numsc; scount++)
- {
- if (random2(pow) <= 3)
- {
- if (create_monster( MONS_SCORPION, ENCH_ABJ_III, BEH_HOSTILE,
- you.x_pos, you.y_pos, MHITYOU, 250 ) != -1)
- {
- mpr("A scorpion appears. It doesn't look very happy.");
- }
- }
- else
- {
- if (create_monster( MONS_SCORPION, ENCH_ABJ_III, BEH_FRIENDLY,
- you.x_pos, you.y_pos,
- you.pet_target, 250 ) != -1)
- {
- mpr("A scorpion appears.");
- }
- }
- }
-} // end summon_scorpions()
-
-void summon_ice_beast_etc(int pow, int ibc, bool divine_gift)
-{
- int numsc = ENCH_ABJ_II + (random2(pow) / 4);
- int beha = divine_gift? BEH_GOD_GIFT : BEH_FRIENDLY;
-
- if (numsc > ENCH_ABJ_VI)
- numsc = ENCH_ABJ_VI;
-
- switch (ibc)
- {
- case MONS_ICE_BEAST:
- mpr("A chill wind blows around you.");
- break;
-
- case MONS_IMP:
- mpr("A beastly little devil appears in a puff of flame.");
- break;
-
- case MONS_WHITE_IMP:
- mpr("A beastly little devil appears in a puff of frigid air.");
- break;
-
- case MONS_SHADOW_IMP:
- mpr("A shadowy apparition takes form in the air.");
- break;
-
- case MONS_ANGEL:
- mpr("You open a gate to the realm of Zin!");
- break;
-
- case MONS_DAEVA:
- mpr("You are momentarily dazzled by a brilliant golden light.");
- break;
-
- default:
- mpr("A demon appears!");
- if (random2(pow) < 4)
- {
- beha = BEH_HOSTILE;
- mpr("It doesn't look very happy.");
- }
- break;
-
- }
-
- create_monster( ibc, numsc, beha, you.x_pos, you.y_pos, MHITYOU, 250 );
-} // end summon_ice_beast_etc()
-
-bool summon_swarm( int pow, bool unfriendly, bool god_gift )
-{
- int thing_called = MONS_PROGRAM_BUG; // error trapping {dlb}
- int numsc = 2 + random2(pow) / 10 + random2(pow) / 25;
- bool summoned = false;
-
- // see stuff.cc - 12jan2000 {dlb}
- numsc = stepdown_value( numsc, 2, 2, 6, 8 );
-
- for (int scount = 0; scount < numsc; scount++)
- {
- switch (random2(14))
- {
- case 0:
- case 1: // prototypical swarming creature {dlb}
- thing_called = MONS_KILLER_BEE;
- break;
-
- case 2: // comment said "larva", code read scorpion {dlb}
- thing_called = MONS_SCORPION;
- break; // think: "The Arrival" {dlb}
-
- case 3: //jmf: technically not insects but still cool
- thing_called = MONS_WORM;
- break; // but worms kinda "swarm" so s'ok {dlb}
-
- case 4: // comment read "larva", code was for scorpion
- thing_called = MONS_GIANT_MOSQUITO;
- break; // changed into giant mosquito 12jan2000 {dlb}
-
- case 5: // think: scarabs in "The Mummy" {dlb}
- thing_called = MONS_GIANT_BEETLE;
- break;
-
- case 6: //jmf: blowfly instead of queen bee
- thing_called = MONS_GIANT_BLOWFLY;
- break;
-
- // queen bee added if more than x bees in swarm? {dlb}
- // the above would require code rewrite - worth it? {dlb}
-
- case 8: //jmf: changed to red wasp; was wolf spider
- thing_called = MONS_WOLF_SPIDER; //jmf: spiders aren't insects
- break; // think: "Kingdom of the Spiders" {dlb}
- // not just insects!!! - changed back {dlb}
-
- case 9:
- thing_called = MONS_BUTTERFLY; // comic relief? {dlb}
- break;
-
- case 10: // change into some kind of snake -- {dlb}
- thing_called = MONS_YELLOW_WASP; // do wasps swarm? {dlb}
- break; // think: "Indiana Jones" and snakepit? {dlb}
-
- default: // 3 in 14 chance, 12jan2000 {dlb}
- thing_called = MONS_GIANT_ANT;
- break;
- } // end switch
-
- int behaviour = BEH_HOSTILE; // default to unfriendly
-
- // Note: friendly, non-god_gift means spell.
- if (god_gift)
- behaviour = BEH_GOD_GIFT;
- else if (!unfriendly && random2(pow) > 7)
- behaviour = BEH_FRIENDLY;
-
- if (create_monster( thing_called, ENCH_ABJ_III, behaviour,
- you.x_pos, you.y_pos, MHITYOU, 250 ))
- {
- summoned = true;
- }
- }
-
- return (summoned);
-} // end summon_swarm()
-
-void summon_undead(int pow)
-{
- int temp_rand = 0;
- int thing_called = MONS_PROGRAM_BUG; // error trapping {dlb}
-
- int numsc = 1 + random2(pow) / 30 + random2(pow) / 30;
- numsc = stepdown_value(numsc, 2, 2, 6, 8); //see stuff.cc {dlb}
-
- mpr("You call on the undead to aid you!");
-
- for (int scount = 0; scount < numsc; scount++)
- {
- temp_rand = random2(25);
-
- thing_called = ((temp_rand > 8) ? MONS_WRAITH : // 64%
- (temp_rand > 3) ? MONS_SPECTRAL_WARRIOR // 20%
- : MONS_FREEZING_WRAITH); // 16%
-
- if (random2(pow) < 6)
- {
- if (create_monster( thing_called, ENCH_ABJ_V, BEH_HOSTILE,
- you.x_pos, you.y_pos, MHITYOU, 250 ) != -1)
- {
- mpr("You sense a hostile presence.");
- }
- }
- else
- {
- if (create_monster( thing_called, ENCH_ABJ_V, BEH_FRIENDLY,
- you.x_pos, you.y_pos, you.pet_target, 250 ) != -1)
- {
- mpr("An insubstantial figure forms in the air.");
- }
- }
- } // end for loop
-
- //jmf: Kiku sometimes deflects this
- if (!you.is_undead
- && !(you.religion == GOD_KIKUBAAQUDGHA
- && (!player_under_penance()
- && you.piety >= 100 && random2(200) <= you.piety)))
- {
- disease_player( 25 + random2(50) );
- }
-} // end summon_undead()
-
-void summon_things( int pow )
-{
- int big_things = 0;
- int numsc = 2 + (random2(pow) / 10) + (random2(pow) / 10);
-
- if (one_chance_in(3) && !lose_stat( STAT_INTELLIGENCE, 1, true ))
- mpr("Your call goes unanswered.");
- else
- {
- numsc = stepdown_value( numsc, 2, 2, 6, -1 );
-
- while (numsc > 2)
- {
- if (one_chance_in(4))
- break;
-
- numsc -= 2;
- big_things++;
- }
-
- if (numsc > 8)
- numsc = 8;
-
- if (big_things > 8)
- big_things = 8;
-
- while (big_things > 0)
- {
- create_monster( MONS_TENTACLED_MONSTROSITY, 0, BEH_FRIENDLY,
- you.x_pos, you.y_pos, you.pet_target, 250 );
- big_things--;
- }
-
- while (numsc > 0)
- {
- create_monster( MONS_ABOMINATION_LARGE, 0, BEH_FRIENDLY,
- you.x_pos, you.y_pos, you.pet_target, 250 );
- numsc--;
- }
-
- snprintf( info, INFO_SIZE, "Some Thing%s answered your call!",
- (numsc + big_things > 1) ? "s" : "" );
-
- mpr(info);
- }
-
- return;
-}
diff --git a/stone_soup/crawl-ref/source/spells2.h b/stone_soup/crawl-ref/source/spells2.h
deleted file mode 100644
index 409aff5a25..0000000000
--- a/stone_soup/crawl-ref/source/spells2.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * File: spells2.cc
- * Summary: Implementations of some additional spells.
- * Written by: Linley Henzell
- *
- * Modified for Crawl Reference by $Author$ on $Date$
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-#ifndef SPELLS2_H
-#define SPELLS2_H
-
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: spell
- * *********************************************************************** */
-bool brand_weapon(int which_brand, int power);
-
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: ability - spell
- * *********************************************************************** */
-int animate_a_corpse(int axps, int ayps, int corps_beh, int corps_hit, int class_allowed);
-
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: ability - it_use3 - monstuff - mstuff2 - spell
- * *********************************************************************** */
-int animate_dead(int power, int corps_beh, int corps_hit, int actual);
-
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: spell
- * *********************************************************************** */
-char burn_freeze(int pow, char b_f);
-
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: spell
- * *********************************************************************** */
-int corpse_rot(int power);
-
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: it_use3 - spell
- * *********************************************************************** */
-int summon_elemental(int pow, int restricted_type, unsigned char unfriendly);
-
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: spell
- * *********************************************************************** */
-int vampiric_drain(int pow);
-
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: spell
- * *********************************************************************** */
-unsigned char detect_creatures( int pow );
-
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: spell
- * *********************************************************************** */
-unsigned char detect_items( int pow );
-
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: spell
- * *********************************************************************** */
-unsigned char detect_traps( int pow );
-
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: item_use - spell
- * *********************************************************************** */
-void cast_refrigeration(int pow);
-
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: item_use - spell
- * *********************************************************************** */
-void cast_toxic_radiance(void);
-
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: spell
- * *********************************************************************** */
-void cast_twisted(int power, int corps_beh, int corps_hit);
-
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: ability
- * *********************************************************************** */
-void drain_life(int pow);
-
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: ability - spell
- * *********************************************************************** */
-void holy_word(int pow, bool silent = false);
-
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: ability - food - it_use2 - spell
- * returns TRUE if a stat was restored.
- * *********************************************************************** */
-bool restore_stat(unsigned char which_stat, bool suppress_msg);
-
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: ability - spell
- * *********************************************************************** */
-void summon_ice_beast_etc(int pow, int ibc, bool divine_gift = false);
-
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: spell
- * *********************************************************************** */
-void summon_scorpions(int pow);
-
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: spell
- * *********************************************************************** */
-void summon_small_mammals(int pow);
-
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: ability - religion - spell
- * *********************************************************************** */
-bool summon_swarm( int pow, bool unfriendly, bool god_gift );
-
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: spell
- * *********************************************************************** */
-void summon_things(int pow);
-
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: spell
- * *********************************************************************** */
-void summon_undead(int pow);
-
-
-// last updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: ability - spell
- * *********************************************************************** */
-void turn_undead(int pow); // what should I use for pow?
-
-
-#endif
diff --git a/stone_soup/crawl-ref/source/spells3.cc b/stone_soup/crawl-ref/source/spells3.cc
deleted file mode 100644
index 1d6f710b05..0000000000
--- a/stone_soup/crawl-ref/source/spells3.cc
+++ /dev/null
@@ -1,1093 +0,0 @@
-/*
- * File: spells3.cc
- * Summary: Implementations of some additional spells.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <2> 9/11/99 LRH Teleportation takes longer in the Abyss
- * <2> 8/05/99 BWR Added allow_control_teleport
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "spells3.h"
-
-#include <ctype.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "externs.h"
-
-#include "abyss.h"
-#include "beam.h"
-#include "cloud.h"
-#include "direct.h"
-#include "debug.h"
-#include "delay.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "items.h"
-#include "it_use2.h"
-#include "misc.h"
-#include "monplace.h"
-#include "mon-pick.h"
-#include "monstuff.h"
-#include "mon-util.h"
-#include "player.h"
-#include "randart.h"
-#include "spells1.h"
-#include "spl-cast.h"
-#include "spl-util.h"
-#include "stuff.h"
-#include "view.h"
-#include "wpn-misc.h"
-
-static bool monster_on_level(int monster);
-
-void cast_selective_amnesia(bool force)
-{
- char ep_gain = 0;
- unsigned char keyin = 0;
-
- if (you.spell_no == 0)
- mpr("You don't know any spells."); // re: sif muna {dlb}
- else
- {
- // query - conditional ordering is important {dlb}:
- for (;;)
- {
- mpr( "Forget which spell ([?*] list [ESC] exit)? ", MSGCH_PROMPT );
-
- keyin = (unsigned char) get_ch();
-
- if (keyin == ESCAPE)
- return; // early return {dlb}
-
- if (keyin == '?' || keyin == '*')
- {
- // this reassignment is "key" {dlb}
- keyin = (unsigned char) list_spells();
-
- redraw_screen();
- }
-
- if (!isalpha( keyin ))
- mesclr( true );
- else
- break;
- }
-
- // actual handling begins here {dlb}:
- const int spell = get_spell_by_letter( keyin );
- const int slot = get_spell_slot_by_letter( keyin );
-
- if (spell == SPELL_NO_SPELL)
- mpr( "You don't know that spell." );
- else
- {
- if (!force
- && (you.religion != GOD_SIF_MUNA
- && random2(you.skills[SK_SPELLCASTING])
- < random2(spell_difficulty( spell ))))
- {
- mpr("Oops! This spell sure is a blunt instrument.");
- forget_map(20 + random2(50));
- }
- else
- {
- ep_gain = spell_mana( spell );
- del_spell_from_memory_by_slot( slot );
-
- if (ep_gain > 0)
- {
- inc_mp(ep_gain, false);
- mpr( "The spell releases its latent energy back to you as "
- "it unravels." );
- }
- }
- }
- }
-
- return;
-} // end cast_selective_amnesia()
-
-bool remove_curse(bool suppress_msg)
-{
- int loopy = 0; // general purpose loop variable {dlb}
- bool success = false; // whether or not curse(s) removed {dlb}
-
- // special "wield slot" case - see if you can figure out why {dlb}:
- // because only cursed weapons in hand only count as cursed -- bwr
- if (you.equip[EQ_WEAPON] != -1
- && you.inv[you.equip[EQ_WEAPON]].base_type == OBJ_WEAPONS)
- {
- if (item_cursed( you.inv[you.equip[EQ_WEAPON]] ))
- {
- do_uncurse_item( you.inv[you.equip[EQ_WEAPON]] );
- success = true;
- you.wield_change = true;
- }
- }
-
- // everything else uses the same paradigm - are we certain?
- // what of artefact rings and amulets? {dlb}:
- for (loopy = EQ_CLOAK; loopy < NUM_EQUIP; loopy++)
- {
- if (you.equip[loopy] != -1 && item_cursed(you.inv[you.equip[loopy]]))
- {
- do_uncurse_item( you.inv[you.equip[loopy]] );
- success = true;
- }
- }
-
- // messaging output {dlb}:
- if (!suppress_msg)
- {
- if (success)
- mpr("You feel as if something is helping you.");
- else
- canned_msg(MSG_NOTHING_HAPPENS);
- }
-
- return (success);
-} // end remove_curse()
-
-bool detect_curse(bool suppress_msg)
-{
- int loopy = 0; // general purpose loop variable {dlb}
- bool success = false; // whether or not any curses found {dlb}
-
- for (loopy = 0; loopy < ENDOFPACK; loopy++)
- {
- if (you.inv[loopy].quantity
- && (you.inv[loopy].base_type == OBJ_WEAPONS
- || you.inv[loopy].base_type == OBJ_ARMOUR
- || you.inv[loopy].base_type == OBJ_JEWELLERY))
- {
- if (!item_ident( you.inv[loopy], ISFLAG_KNOW_CURSE ))
- success = true;
-
- set_ident_flags( you.inv[loopy], ISFLAG_KNOW_CURSE );
- }
- }
-
- // messaging output {dlb}:
- if (!suppress_msg)
- {
- if (success)
- mpr("You sense the presence of curses on your possessions.");
- else
- canned_msg(MSG_NOTHING_HAPPENS);
- }
-
- return (success);
-} // end detect_curse()
-
-bool cast_smiting(int power)
-{
- bool success = false;
- struct dist beam;
- struct monsters *monster = 0; // NULL {dlb}
-
- mpr("Smite whom?", MSGCH_PROMPT);
-
- direction( beam, DIR_TARGET, TARG_ENEMY );
-
- if (!beam.isValid
- || mgrd[beam.tx][beam.ty] == NON_MONSTER
- || beam.isMe)
- {
- canned_msg(MSG_SPELL_FIZZLES);
- }
- else
- {
- monster = &menv[mgrd[beam.tx][beam.ty]];
-
- strcpy(info, "You smite ");
- strcat(info, ptr_monam( monster, DESC_NOCAP_THE ));
- strcat(info, "!");
- mpr(info);
-
- hurt_monster(monster, random2(8) + (random2(power) / 3));
-
- if (monster->hit_points < 1)
- monster_die(monster, KILL_YOU, 0);
- else
- print_wounds(monster);
-
- success = true;
- }
-
- return (success);
-} // end cast_smiting()
-
-bool airstrike(int power)
-{
- bool success = false;
- struct dist beam;
- struct monsters *monster = 0; // NULL {dlb}
- int hurted = 0;
-
- mpr("Strike whom?", MSGCH_PROMPT);
-
- direction( beam, DIR_TARGET, TARG_ENEMY );
-
- if (!beam.isValid
- || mgrd[beam.tx][beam.ty] == NON_MONSTER
- || beam.isMe)
- {
- canned_msg(MSG_SPELL_FIZZLES);
- }
- else
- {
- monster = &menv[mgrd[beam.tx][beam.ty]];
-
- strcpy(info, "The air twists around and strikes ");
- strcat(info, ptr_monam( monster, DESC_NOCAP_THE ));
- strcat(info, "!");
- mpr(info);
-
- hurted = random2( random2(12) + (random2(power) / 6)
- + (random2(power) / 7) );
- hurted -= random2(1 + monster->armour_class);
-
- if (hurted < 0)
- hurted = 0;
- else
- {
- hurt_monster(monster, hurted);
-
- if (monster->hit_points < 1)
- monster_die(monster, KILL_YOU, 0);
- else
- print_wounds(monster);
- }
-
- success = true;
- }
-
- return (success);
-} // end airstrike()
-
-bool cast_bone_shards(int power)
-{
- bool success = false;
- struct bolt beam;
- struct dist spelld;
-
- if (you.equip[EQ_WEAPON] == -1
- || you.inv[you.equip[EQ_WEAPON]].base_type != OBJ_CORPSES)
- {
- canned_msg(MSG_SPELL_FIZZLES);
- }
- else if (you.inv[you.equip[EQ_WEAPON]].sub_type != CORPSE_SKELETON)
- mpr("The corpse collapses into a mass of pulpy flesh.");
- else if (spell_direction(spelld, beam) != -1)
- {
- // practical max of 100 * 15 + 3000 = 4500
- // actual max of 200 * 15 + 3000 = 6000
- power *= 15;
- power += mons_weight( you.inv[you.equip[EQ_WEAPON]].plus );
-
- mpr("The skeleton explodes into sharp fragments of bone!");
-
- dec_inv_item_quantity( you.equip[EQ_WEAPON], 1 );
- zapping(ZAP_BONE_SHARDS, power, beam);
-
- success = true;
- }
-
- return (success);
-} // end cast_bone_shards()
-
-void sublimation(int power)
-{
- unsigned char loopy = 0; // general purpose loop variable {dlb}
-
- if (you.equip[EQ_WEAPON] == -1
- || you.inv[you.equip[EQ_WEAPON]].base_type != OBJ_FOOD
- || you.inv[you.equip[EQ_WEAPON]].sub_type != FOOD_CHUNK)
- {
- if (you.deaths_door)
- {
- mpr( "A conflicting enchantment prevents the spell from "
- "coming into effect." );
- }
- else if (!enough_hp( 2, true ))
- {
- mpr("Your attempt to draw power from your own body fails.");
- }
- else
- {
- mpr("You draw magical energy from your own body!");
-
- while (you.magic_points < you.max_magic_points && you.hp > 1)
- {
- inc_mp(1, false);
- dec_hp(1, false);
-
- for (loopy = 0; loopy < (you.hp > 1 ? 3 : 0); loopy++)
- {
- if (random2(power) < 6)
- dec_hp(1, false);
- }
-
- if (random2(power) < 6)
- break;
- }
- }
- }
- else
- {
- mpr("The chunk of flesh you are holding crumbles to dust.");
- mpr("A flood of magical energy pours into your mind!");
-
- inc_mp( 7 + random2(7), false );
-
- dec_inv_item_quantity( you.equip[EQ_WEAPON], 1 );
- }
-
- return;
-} // end sublimation()
-
-// Simulacrum
-//
-// This spell extends creating undead to Ice mages, as such it's high
-// level, requires wielding of the material component, and the undead
-// aren't overly powerful (they're also vulnerable to fire). I've put
-// back the abjuration level in order to keep down the army sizes again.
-//
-// As for what it offers necromancers considering all the downsides
-// above... it allows the turning of a single corpse into an army of
-// monsters (one per food chunk)... which is also a good reason for
-// why it's high level.
-//
-// Hides and other "animal part" items are intentionally left out, it's
-// unrequired complexity, and fresh flesh makes more "sense" for a spell
-// reforming the original monster out of ice anyways.
-void simulacrum(int power)
-{
- int max_num = 4 + random2(power) / 20;
- if (max_num > 8)
- max_num = 8;
-
- const int chunk = you.equip[EQ_WEAPON];
-
- if (chunk != -1
- && is_valid_item( you.inv[ chunk ] )
- && (you.inv[ chunk ].base_type == OBJ_CORPSES
- || (you.inv[ chunk ].base_type == OBJ_FOOD
- && you.inv[ chunk ].sub_type == FOOD_CHUNK)))
- {
- const int mons_type = you.inv[ chunk ].plus;
-
- // Can't create more than the available chunks
- if (you.inv[ chunk ].quantity < max_num)
- max_num = you.inv[ chunk ].quantity;
-
- dec_inv_item_quantity( chunk, max_num );
-
- int summoned = 0;
-
- for (int i = 0; i < max_num; i++)
- {
- if (create_monster( MONS_SIMULACRUM_SMALL, ENCH_ABJ_VI,
- BEH_FRIENDLY, you.x_pos, you.y_pos,
- you.pet_target, mons_type ) != -1)
- {
- summoned++;
- }
- }
-
- if (summoned)
- {
- strcpy( info, (summoned == 1) ? "An icy figure forms "
- : "Some icy figures form " );
- strcat( info, "before you!" );
- mpr( info );
- }
- else
- mpr( "You feel cold for a second." );
- }
- else
- {
- mpr( "You need to wield a piece of raw flesh for this spell "
- "to be effective!" );
- }
-} // end sublimation()
-
-void dancing_weapon(int pow, bool force_hostile)
-{
- int numsc = ENCH_ABJ_II + (random2(pow) / 5);
- char str_pass[ ITEMNAME_SIZE ];
-
- if (numsc > ENCH_ABJ_VI)
- numsc = ENCH_ABJ_VI;
-
- int i;
- int summs = 0;
- char behavi = BEH_FRIENDLY;
-
- const int wpn = you.equip[EQ_WEAPON];
-
- // See if weilded item is appropriate:
- if (wpn == -1
- || you.inv[wpn].base_type != OBJ_WEAPONS
- || launches_things( you.inv[wpn].sub_type )
- || is_fixed_artefact( you.inv[wpn] ))
- {
- goto failed_spell;
- }
-
- // See if we can get an mitm for the dancing weapon:
- i = get_item_slot();
- if (i == NON_ITEM)
- goto failed_spell;
-
- // cursed weapons become hostile
- if (item_cursed( you.inv[wpn] ) || force_hostile)
- behavi = BEH_HOSTILE;
-
- summs = create_monster( MONS_DANCING_WEAPON, numsc, behavi,
- you.x_pos, you.y_pos, you.pet_target, 1 );
-
- if (summs < 0)
- {
- // must delete the item before failing!
- mitm[i].base_type = OBJ_UNASSIGNED;
- mitm[i].quantity = 0;
- goto failed_spell;
- }
-
- // We are successful:
- unwield_item( wpn ); // remove wield effects
-
- // copy item (done here after any wield effects are removed)
- mitm[i] = you.inv[wpn];
- mitm[i].quantity = 1;
- mitm[i].x = 0;
- mitm[i].y = 0;
- mitm[i].link = NON_ITEM;
-
- in_name( wpn, DESC_CAP_YOUR, str_pass );
- strcpy( info, str_pass );
- strcat( info, " dances into the air!" );
- mpr( info );
-
- you.inv[ wpn ].quantity = 0;
- you.equip[EQ_WEAPON] = -1;
-
- menv[summs].inv[MSLOT_WEAPON] = i;
- menv[summs].number = mitm[i].colour;
-
- return;
-
-failed_spell:
- mpr("Your weapon vibrates crazily for a second.");
-} // end dancing_weapon()
-
-static bool monster_on_level(int monster)
-{
- for (int i = 0; i < MAX_MONSTERS; i++)
- {
- if (menv[i].type == monster)
- return true;
- }
-
- return false;
-} // end monster_on_level()
-
-//
-// This function returns true if the player can use controlled
-// teleport here.
-//
-bool allow_control_teleport( bool silent )
-{
- bool ret = true;
-
- if (you.level_type == LEVEL_ABYSS || you.level_type == LEVEL_LABYRINTH)
- ret = false;
- else
- {
- switch (you.where_are_you)
- {
- case BRANCH_TOMB:
- // The tomb is a laid out maze, it'd be a shame if the player
- // just teleports through any of it... so we only allow
- // teleport once they have the rune.
- ret = false;
- for (int i = 0; i < ENDOFPACK; i++)
- {
- if (is_valid_item( you.inv[i] )
- && you.inv[i].base_type == OBJ_MISCELLANY
- && you.inv[i].sub_type == MISC_RUNE_OF_ZOT
- && you.inv[i].plus == BRANCH_TOMB)
- {
- ret = true;
- break;
- }
- }
- break;
-
- case BRANCH_SLIME_PITS:
- // Cannot teleport into the slime pit vaults until
- // royal jelly is gone.
- if (monster_on_level(MONS_ROYAL_JELLY))
- ret = false;
- break;
-
- case BRANCH_ELVEN_HALLS:
- // Cannot raid the elven halls vaults until fountain drained
- if (you.branch_stairs[STAIRS_ELVEN_HALLS] +
- branch_depth(STAIRS_ELVEN_HALLS) == you.your_level)
- {
- for (int x = 5; x < GXM - 5; x++)
- {
- for (int y = 5; y < GYM - 5; y++)
- {
- if (grd[x][y] == DNGN_SPARKLING_FOUNTAIN)
- ret = false;
- }
- }
- }
- break;
-
- case BRANCH_HALL_OF_ZOT:
- // Cannot control teleport until the Orb is picked up
- if (you.branch_stairs[STAIRS_HALL_OF_ZOT] +
- branch_depth(STAIRS_HALL_OF_ZOT) == you.your_level
- && you.char_direction != DIR_ASCENDING)
- {
- ret = false;
- }
- break;
- }
- }
-
- // Tell the player why if they have teleport control.
- if (!ret && you.attribute[ATTR_CONTROL_TELEPORT] && !silent)
- mpr("A powerful magic prevents control of your teleportation.");
-
- return ret;
-} // end allow_control_teleport()
-
-void you_teleport(void)
-{
- if (scan_randarts(RAP_PREVENT_TELEPORTATION))
- mpr("You feel a weird sense of stasis.");
- else if (you.duration[DUR_TELEPORT])
- {
- mpr("You feel strangely stable.");
- you.duration[DUR_TELEPORT] = 0;
- }
- else
- {
- mpr("You feel strangely unstable.");
-
- you.duration[DUR_TELEPORT] = 3 + random2(3);
-
- if (you.level_type == LEVEL_ABYSS && !one_chance_in(5))
- {
- mpr("You have a feeling this translocation may take a while to kick in...");
- you.duration[DUR_TELEPORT] += 5 + random2(10);
- }
- }
-
- return;
-} // end you_teleport()
-
-void you_teleport2( bool allow_control, bool new_abyss_area )
-{
- bool is_controlled = (allow_control && !you.conf
- && you.attribute[ATTR_CONTROL_TELEPORT]
- && allow_control_teleport());
-
- if (scan_randarts(RAP_PREVENT_TELEPORTATION))
- {
- mpr("You feel a strange sense of stasis.");
- return;
- }
-
- // after this point, we're guaranteed to teleport. Turn off auto-butcher.
- // corpses still get butchered, but at least we don't get a silly message.
- if (current_delay_action() == DELAY_BUTCHER)
- stop_delay();
-
- interrupt_activity( AI_TELEPORT );
-
- if (you.duration[DUR_CONDENSATION_SHIELD] > 0)
- {
- you.duration[DUR_CONDENSATION_SHIELD] = 0;
- you.redraw_armour_class = 1;
- }
-
- if (you.level_type == LEVEL_ABYSS)
- {
- abyss_teleport( new_abyss_area );
- you.pet_target = MHITNOT;
- return;
- }
-
- FixedVector < int, 2 > plox;
-
- plox[0] = 1;
- plox[1] = 0;
-
- if (is_controlled)
- {
- mpr("You may choose your destination (press '.' or delete to select).");
- mpr("Expect minor deviation.");
- more();
-
- show_map(plox);
-
- redraw_screen();
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "Target square (%d,%d)", plox[0], plox[1] );
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- plox[0] += random2(3) - 1;
- plox[1] += random2(3) - 1;
-
- if (one_chance_in(4))
- {
- plox[0] += random2(3) - 1;
- plox[1] += random2(3) - 1;
- }
-
- if (plox[0] < 6 || plox[1] < 6 || plox[0] > (GXM - 5)
- || plox[1] > (GYM - 5))
- {
- mpr("Nearby solid objects disrupt your rematerialisation!");
- is_controlled = false;
- }
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "Scattered target square (%d,%d)", plox[0], plox[1] );
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- if (is_controlled)
- {
- you.x_pos = plox[0];
- you.y_pos = plox[1];
-
- if ((grd[you.x_pos][you.y_pos] != DNGN_FLOOR
- && grd[you.x_pos][you.y_pos] != DNGN_SHALLOW_WATER)
- || mgrd[you.x_pos][you.y_pos] != NON_MONSTER
- || env.cgrid[you.x_pos][you.y_pos] != EMPTY_CLOUD)
- {
- is_controlled = false;
- }
- else
- {
- // controlling teleport contaminates the player -- bwr
- contaminate_player(1);
- }
- }
- } // end "if is_controlled"
-
- if (!is_controlled)
- {
- mpr("Your surroundings suddenly seem different.");
-
- do
- {
- you.x_pos = 5 + random2( GXM - 10 );
- you.y_pos = 5 + random2( GYM - 10 );
- }
- while ((grd[you.x_pos][you.y_pos] != DNGN_FLOOR
- && grd[you.x_pos][you.y_pos] != DNGN_SHALLOW_WATER)
- || mgrd[you.x_pos][you.y_pos] != NON_MONSTER
- || env.cgrid[you.x_pos][you.y_pos] != EMPTY_CLOUD);
- }
-} // end you_teleport()
-
-bool entomb(void)
-{
- int loopy = 0; // general purpose loop variable {dlb}
- bool proceed = false; // loop management varaiable {dlb}
- int which_trap = 0; // used in clearing out certain traps {dlb}
- char srx = 0, sry = 0;
- char number_built = 0;
-
- FixedVector < unsigned char, 7 > safe_to_overwrite;
-
- // hack - passing chars through '...' promotes them to ints, which
- // barfs under gcc in fixvec.h. So don't.
- safe_to_overwrite[0] = DNGN_FLOOR;
- safe_to_overwrite[1] = DNGN_SHALLOW_WATER;
- safe_to_overwrite[2] = DNGN_OPEN_DOOR;
- safe_to_overwrite[3] = DNGN_TRAP_MECHANICAL;
- safe_to_overwrite[4] = DNGN_TRAP_MAGICAL;
- safe_to_overwrite[5] = DNGN_TRAP_III;
- safe_to_overwrite[6] = DNGN_UNDISCOVERED_TRAP;
-
-
- for (srx = you.x_pos - 1; srx < you.x_pos + 2; srx++)
- {
- for (sry = you.y_pos - 1; sry < you.y_pos + 2; sry++)
- {
- proceed = false;
-
- // tile already occupied by monster or yourself {dlb}:
- if (mgrd[srx][sry] != NON_MONSTER
- || (srx == you.x_pos && sry == you.y_pos))
- {
- continue;
- }
-
- // the break here affects innermost containing loop {dlb}:
- for (loopy = 0; loopy < 7; loopy++)
- {
- if (grd[srx][sry] == safe_to_overwrite[loopy])
- {
- proceed = true;
- break;
- }
- }
-
- // checkpoint one - do we have a legitimate tile? {dlb}
- if (!proceed)
- continue;
-
- int objl = igrd[srx][sry];
- int hrg = 0;
-
- while (objl != NON_ITEM)
- {
- // hate to see the orb get detroyed by accident {dlb}:
- if (mitm[objl].base_type == OBJ_ORBS)
- {
- proceed = false;
- break;
- }
-
- hrg = mitm[objl].link;
- objl = hrg;
- }
-
- // checkpoint two - is the orb resting in the tile? {dlb}:
- if (!proceed)
- continue;
-
- objl = igrd[srx][sry];
- hrg = 0;
-
- while (objl != NON_ITEM)
- {
- hrg = mitm[objl].link;
- destroy_item(objl);
- objl = hrg;
- }
-
- // deal with clouds {dlb}:
- if (env.cgrid[srx][sry] != EMPTY_CLOUD)
- delete_cloud( env.cgrid[srx][sry] );
-
- // mechanical traps are destroyed {dlb}:
- if ((which_trap = trap_at_xy(srx, sry)) != -1)
- {
- if (trap_category(env.trap[which_trap].type)
- == DNGN_TRAP_MECHANICAL)
- {
- env.trap[which_trap].type = TRAP_UNASSIGNED;
- env.trap[which_trap].x = 1;
- env.trap[which_trap].y = 1;
- }
- }
-
- // finally, place the wall {dlb}:
- grd[srx][sry] = DNGN_ROCK_WALL;
- number_built++;
- } // end "for srx,sry"
- }
-
- if (number_built > 0)
- mpr("Walls emerge from the floor!");
- else
- canned_msg(MSG_NOTHING_HAPPENS);
-
- return (number_built > 0);
-} // end entomb()
-
-void cast_poison_ammo(void)
-{
- const int ammo = you.equip[EQ_WEAPON];
- char str_pass[ ITEMNAME_SIZE ];
-
- if (ammo == -1
- || you.inv[ammo].base_type != OBJ_MISSILES
- || get_ammo_brand( you.inv[ammo] ) != SPMSL_NORMAL
- || you.inv[ammo].sub_type == MI_STONE
- || you.inv[ammo].sub_type == MI_LARGE_ROCK)
- {
- canned_msg(MSG_NOTHING_HAPPENS);
- return;
- }
-
- if (set_item_ego_type( you.inv[ammo], OBJ_MISSILES, SPMSL_POISONED ))
- {
- in_name(ammo, DESC_CAP_YOUR, str_pass);
- strcpy(info, str_pass);
- strcat(info, (you.inv[ammo].quantity == 1) ? " is" : " are");
- strcat(info, " covered in a thin film of poison.");
- mpr(info);
-
- you.wield_change = true;
- }
- else
- {
- canned_msg(MSG_NOTHING_HAPPENS);
- }
-} // end cast_poison_ammo()
-
-bool project_noise(void)
-{
- bool success = false;
- FixedVector < int, 2 > plox;
-
- plox[0] = 1;
- plox[1] = 0;
-
- mpr( "Choose the noise's source (press '.' or delete to select)." );
- more();
- show_map(plox);
-
- redraw_screen();
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "Target square (%d,%d)", plox[0], plox[1] );
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- if (!silenced( plox[0], plox[1] ))
- {
- // player can use this spell to "sound out" the dungeon -- bwr
- if (plox[0] > 1 && plox[0] < (GXM - 2)
- && plox[1] > 1 && plox[1] < (GYM - 2)
- && !grid_is_solid(grd[ plox[0] ][ plox[1] ]))
- {
- noisy( 30, plox[0], plox[1] );
- success = true;
- }
-
- if (!silenced( you.x_pos, you.y_pos ))
- {
- if (!success)
- mpr("You hear a dull thud.", MSGCH_SOUND);
- else
- {
- snprintf( info, INFO_SIZE, "You hear a %svoice call your name.",
- (see_grid( plox[0], plox[1] ) ? "distant " : "") );
- mpr( info , MSGCH_SOUND );
- }
- }
- }
-
- return (success);
-} // end project_noise()
-
-/*
- Type recalled:
- 0 = anything
- 1 = undead only (Kiku religion ability)
- */
-bool recall(char type_recalled)
-{
- int loopy = 0; // general purpose looping variable {dlb}
- bool success = false; // more accurately: "apparent success" {dlb}
- int start_count = 0;
- int step_value = 1;
- int end_count = (MAX_MONSTERS - 1);
- FixedVector < char, 2 > empty;
- struct monsters *monster = 0; // NULL {dlb}
-
- empty[0] = empty[1] = 0;
-
-// someone really had to make life difficult {dlb}:
-// sometimes goes through monster list backwards
- if (coinflip())
- {
- start_count = (MAX_MONSTERS - 1);
- end_count = 0;
- step_value = -1;
- }
-
- for (loopy = start_count; loopy != end_count; loopy += step_value)
- {
- monster = &menv[loopy];
-
- if (monster->type == -1)
- continue;
-
- if (!mons_friendly(monster))
- continue;
-
- if (monster_habitat(monster->type) != DNGN_FLOOR)
- continue;
-
- if (type_recalled == 1)
- {
- /* abomin created by twisted res, although it gets others too */
- if ( !((monster->type == MONS_ABOMINATION_SMALL
- || monster->type == MONS_ABOMINATION_LARGE)
- && (monster->number == BROWN
- || monster->number == RED
- || monster->number == LIGHTRED)) )
- {
- if (monster->type != MONS_REAPER
- && mons_holiness(monster) != MH_UNDEAD)
- {
- continue;
- }
- }
- }
-
- if (empty_surrounds(you.x_pos, you.y_pos, DNGN_FLOOR, false, empty))
- {
- // clear old cell pointer -- why isn't there a function for moving a monster?
- mgrd[monster->x][monster->y] = NON_MONSTER;
- // set monster x,y to new value
- monster->x = empty[0];
- monster->y = empty[1];
- // set new monster grid pointer to this monster.
- mgrd[monster->x][monster->y] = monster_index(monster);
-
- // only informed if monsters recalled are visible {dlb}:
- if (simple_monster_message(monster, " is recalled."))
- success = true;
- }
- else
- {
- break; // no more room to place monsters {dlb}
- }
- }
-
- if (!success)
- mpr("Nothing appears to have answered your call.");
-
- return (success);
-} // end recall()
-
-void portal(void)
-{
- char dir_sign = 0;
- unsigned char keyi;
- int target_level = 0;
- int old_level = you.your_level;
-
- if (!player_in_branch( BRANCH_MAIN_DUNGEON ))
- {
- mpr("This spell doesn't work here.");
- }
- else if (grd[you.x_pos][you.y_pos] != DNGN_FLOOR)
- {
- mpr("You must find a clear area in which to cast this spell.");
- }
- else
- {
- // the first query {dlb}:
- mpr("Which direction ('<' for up, '>' for down, 'x' to quit)?", MSGCH_PROMPT);
-
- for (;;)
- {
- keyi = (unsigned char) get_ch();
-
- if (keyi == '<')
- {
- if (you.your_level == 0)
- mpr("You can't go any further upwards with this spell.");
- else
- {
- dir_sign = -1;
- break;
- }
- }
-
- if (keyi == '>')
- {
- if (you.your_level == 35)
- mpr("You can't go any further downwards with this spell.");
- else
- {
- dir_sign = 1;
- break;
- }
- }
-
- if (keyi == 'x')
- {
- canned_msg(MSG_OK);
- return; // an early return {dlb}
- }
- }
-
- // the second query {dlb}:
- mpr("How many levels (1 - 9, 'x' to quit)?", MSGCH_PROMPT);
-
- for (;;)
- {
- keyi = (unsigned char) get_ch();
-
- if (keyi == 'x')
- {
- canned_msg(MSG_OK);
- return; // another early return {dlb}
- }
-
- if (!(keyi < '1' || keyi > '9'))
- {
- target_level = you.your_level + ((keyi - '0') * dir_sign);
- break;
- }
- }
-
- // actual handling begins here {dlb}:
- if (player_in_branch( BRANCH_MAIN_DUNGEON ))
- {
- if (target_level < 0)
- target_level = 0;
- else if (target_level > 26)
- target_level = 26;
- }
-
- mpr( "You fall through a mystic portal, and materialise at the "
- "foot of a staircase." );
- more();
-
- you.your_level = target_level - 1;
- grd[you.x_pos][you.y_pos] = DNGN_STONE_STAIRS_DOWN_I;
-
- down_stairs( true, old_level, true );
- untag_followers();
- }
-
- return;
-} // end portal()
-
-bool cast_death_channel(int power)
-{
- bool success = false;
-
- if (you.duration[DUR_DEATH_CHANNEL] < 30)
- {
- mpr("Malign forces permeate your being, awaiting release.");
-
- you.duration[DUR_DEATH_CHANNEL] += 15 + random2(1 + (power / 3));
-
- if (you.duration[DUR_DEATH_CHANNEL] > 100)
- you.duration[DUR_DEATH_CHANNEL] = 100;
-
- success = true;
- }
- else
- {
- canned_msg(MSG_NOTHING_HAPPENS);
- }
-
- return (success);
-} // end cast_death_channel()
diff --git a/stone_soup/crawl-ref/source/spells3.h b/stone_soup/crawl-ref/source/spells3.h
deleted file mode 100644
index 5b10dd3026..0000000000
--- a/stone_soup/crawl-ref/source/spells3.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * File: spells3.cc
- * Summary: Implementations of some additional spells.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef SPELLS3_H
-#define SPELLS3_H
-
-
-// updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: spells1 - spells3
- * *********************************************************************** */
-bool allow_control_teleport( bool silent = false );
-
-
-// updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: spell
- * *********************************************************************** */
-bool airstrike(int power);
-
-
-// updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: spell
- * *********************************************************************** */
-bool cast_bone_shards(int power);
-
-
-// updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: spell - spells1
- * *********************************************************************** */
-bool cast_death_channel(int power);
-
-
-// updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: spell
- * *********************************************************************** */
-void cast_poison_ammo(void);
-
-
-// updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: ability - spell
- * *********************************************************************** */
-void cast_selective_amnesia(bool force);
-
-
-// updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: ability - spell
- * *********************************************************************** */
-bool cast_smiting(int power);
-
-
-// updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: spell
- * *********************************************************************** */
-bool project_noise(void);
-
-
-// updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: religion - spell
- * *********************************************************************** */
-void dancing_weapon(int pow, bool force_hostile);
-
-
-// updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: item_use - spell
- * *********************************************************************** */
-bool detect_curse(bool suppress_msg);
-
-
-// updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: decks - spell
- * *********************************************************************** */
-bool entomb(void);
-
-
-// updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: spell
- * *********************************************************************** */
-void portal(void);
-
-
-// updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: ability - spell
- * *********************************************************************** */
-bool recall(char type_recalled);
-
-
-// updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: item_use - spell
- * *********************************************************************** */
-bool remove_curse(bool suppress_msg);
-
-
-// updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: spell
- * *********************************************************************** */
-void sublimation(int power);
-
-
-// updated Oct 2 -- bwr
-/* ***********************************************************************
- * called from: spell
- * *********************************************************************** */
-void simulacrum(int power);
-
-
-// updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: ability - beam - decks - fight - item_use - spell
- * *********************************************************************** */
-void you_teleport(void);
-
-
-// updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: ability - acr - decks - effects - fight - misc - spells
- * *********************************************************************** */
-void you_teleport2( bool allow_control, bool new_abyss_area = false );
-
-
-#endif
diff --git a/stone_soup/crawl-ref/source/spells4.cc b/stone_soup/crawl-ref/source/spells4.cc
deleted file mode 100644
index 076be063a6..0000000000
--- a/stone_soup/crawl-ref/source/spells4.cc
+++ /dev/null
@@ -1,3155 +0,0 @@
-/*
- * File: spells4.cc
- * Summary: new spells, focusing on transmigration, divination and
- * other neglected areas of Crawl magic ;^)
- * Written by: Copyleft Josh Fishman 1999-2000, All Rights Preserved
- *
- * Change History (most recent first):
- *
- * <2> 29jul2000 jdj Made a zillion functions static.
- * <1> 06jan2000 jmf Created
- */
-
-#include "AppHdr.h"
-
-#include <string>
-#include <stdio.h>
-
-#include "externs.h"
-
-#include "abyss.h"
-#include "beam.h"
-#include "cloud.h"
-#include "debug.h"
-#include "delay.h"
-#include "describe.h"
-#include "direct.h"
-#include "dungeon.h"
-#include "effects.h"
-#include "it_use2.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "items.h"
-#include "invent.h"
-#include "misc.h"
-#include "monplace.h"
-#include "monstuff.h"
-#include "mon-util.h"
-#include "mstuff2.h"
-#include "ouch.h"
-#include "player.h"
-#include "randart.h"
-#include "religion.h"
-#include "skills.h"
-#include "spells1.h"
-#include "spells4.h"
-#include "spl-cast.h"
-#include "spl-util.h"
-#include "stuff.h"
-#include "view.h"
-
-enum DEBRIS // jmf: add for shatter, dig, and Giants to throw
-{
- DEBRIS_METAL, // 0
- DEBRIS_ROCK,
- DEBRIS_STONE,
- DEBRIS_WOOD,
- DEBRIS_CRYSTAL,
- NUM_DEBRIS
-}; // jmf: ...and I'll actually implement the items Real Soon Now...
-
-// static int make_a_random_cloud(int x, int y, int pow, int ctype);
-static int make_a_rot_cloud(int x, int y, int pow, int ctype);
-static int quadrant_blink(int x, int y, int pow, int garbage);
-
-//void cast_animate_golem(int pow); // see actual function for reasoning {dlb}
-//void cast_detect_magic(int pow); //jmf: as above...
-//void cast_eringyas_surprising_bouquet(int powc);
-void do_monster_rot(int mon);
-
-//jmf: FIXME: put somewhere else (misc.cc?)
-// A feeble attempt at Nethack-like completeness for cute messages.
-const char *your_hand( bool plural )
-{
- static char hand_buff[80];
-
- switch (you.attribute[ATTR_TRANSFORMATION])
- {
- default:
- mpr("ERROR: unknown transformation in your_hand() (spells4.cc)");
- case TRAN_NONE:
- case TRAN_STATUE:
- if (you.species == SP_TROLL || you.species == SP_GHOUL)
- {
- strcpy(hand_buff, "claw");
- break;
- }
- // or fall-through
- case TRAN_ICE_BEAST:
- case TRAN_LICH:
- strcpy(hand_buff, "hand");
- break;
- case TRAN_SPIDER:
- strcpy(hand_buff, "front leg");
- break;
- case TRAN_SERPENT_OF_HELL:
- case TRAN_DRAGON:
- strcpy(hand_buff, "foreclaw");
- break;
- case TRAN_BLADE_HANDS:
- strcpy(hand_buff, "scythe-like blade");
- break;
- case TRAN_AIR:
- strcpy(hand_buff, "misty tendril");
- break;
- }
-
- if (plural)
- strcat(hand_buff, "s");
-
- return (hand_buff);
-}
-
-// I need to make some debris for metal, crystal and stone.
-// They could go in OBJ_MISSILES, but I think I'd rather move
-// MI_LARGE_ROCK into OBJ_DEBRIS and code giants to throw any
-// OBJ_DEBRIS they get their meaty mits on.
-static void place_debris(int x, int y, int debris_type)
-{
-#ifdef USE_DEBRIS_CODE
- switch (debris_type)
- {
- // hate to say this, but the first parameter only allows specific quantity
- // for *food* and nothing else -- and I would hate to see that parameter
- // (force_unique) abused any more than it already has been ... {dlb}:
- case DEBRIS_STONE:
- large = items( random2(3), OBJ_MISSILES, MI_LARGE_ROCK, true, 1, 250 );
- small = items( 3 + random2(6) + random2(6) + random2(6),
- OBJ_MISSILES, MI_STONE, true, 1, 250 );
- break;
- case DEBRIS_METAL:
- case DEBRIS_WOOD:
- case DEBRIS_CRYSTAL:
- break;
- }
-
- if (small != NON_ITEM)
- move_item_to_grid( &small, x, y );
-
- if (large != NON_ITEM)
- move_item_to_grid( &large, x, y );
-
-#else
- UNUSED( x );
- UNUSED( y );
- UNUSED( debris_type );
- return;
-#endif
-} // end place_debris()
-
-// just to avoid typing this over and over
-// now returns true if monster died -- bwr
-inline bool player_hurt_monster(int monster, int damage)
-{
- ASSERT( monster != NON_MONSTER );
-
- if (damage > 0)
- {
- hurt_monster( &menv[monster], damage );
-
- if (menv[monster].hit_points > 0)
- print_wounds( &menv[monster] );
- else
- {
- monster_die( &menv[monster], KILL_YOU, 0 );
- return (true);
- }
- }
-
- return (false);
-} // end player_hurt_monster()
-
-
-// Here begin the actual spells:
-static int shatter_monsters(int x, int y, int pow, int garbage)
-{
- UNUSED( garbage );
-
- dice_def dam_dice( 0, 5 + pow / 4 ); // number of dice set below
- const int monster = mgrd[x][y];
-
- if (monster == NON_MONSTER)
- return (0);
-
- // Removed a lot of silly monsters down here... people, just because
- // it says ice, rock, or iron in the name doesn't mean it's actually
- // made out of the substance. -- bwr
- switch (menv[monster].type)
- {
- case MONS_ICE_BEAST: // 3/2 damage
- case MONS_SIMULACRUM_SMALL:
- case MONS_SIMULACRUM_LARGE:
- dam_dice.num = 4;
- break;
-
- case MONS_SKELETON_SMALL: // double damage
- case MONS_SKELETON_LARGE:
- case MONS_CURSE_SKULL:
- case MONS_CLAY_GOLEM:
- case MONS_STONE_GOLEM:
- case MONS_IRON_GOLEM:
- case MONS_CRYSTAL_GOLEM:
- case MONS_EARTH_ELEMENTAL:
- case MONS_GARGOYLE:
- case MONS_SKELETAL_DRAGON:
- case MONS_SKELETAL_WARRIOR:
- dam_dice.num = 6;
- break;
-
- case MONS_VAPOUR:
- case MONS_INSUBSTANTIAL_WISP:
- case MONS_AIR_ELEMENTAL:
- case MONS_FIRE_ELEMENTAL:
- case MONS_WATER_ELEMENTAL:
- case MONS_SPECTRAL_WARRIOR:
- case MONS_FREEZING_WRAITH:
- case MONS_WRAITH:
- case MONS_PHANTOM:
- case MONS_PLAYER_GHOST:
- case MONS_SHADOW:
- case MONS_HUNGRY_GHOST:
- case MONS_FLAYED_GHOST:
- case MONS_SMOKE_DEMON: //jmf: I hate these bastards...
- dam_dice.num = 0;
- break;
-
- case MONS_PULSATING_LUMP:
- case MONS_JELLY:
- case MONS_SLIME_CREATURE:
- case MONS_BROWN_OOZE:
- case MONS_AZURE_JELLY:
- case MONS_DEATH_OOZE:
- case MONS_ACID_BLOB:
- case MONS_ROYAL_JELLY:
- case MONS_OOZE:
- case MONS_SPECTRAL_THING:
- case MONS_JELLYFISH:
- dam_dice.num = 1;
- dam_dice.size /= 2;
- break;
-
- case MONS_DANCING_WEAPON: // flies, but earth based
- case MONS_MOLTEN_GARGOYLE:
- case MONS_QUICKSILVER_DRAGON:
- // Soft, earth creatures... would normally resist to 1 die, but
- // are sensitive to this spell. -- bwr
- dam_dice.num = 2;
- break;
-
- default: // normal damage
- if (mons_flies( &menv[monster] ))
- dam_dice.num = 1;
- else
- dam_dice.num = 3;
- break;
- }
-
- int damage = roll_dice( dam_dice ) - random2( menv[monster].armour_class );
-
- if (damage > 0)
- player_hurt_monster( monster, damage );
- else
- damage = 0;
-
- return (damage);
-} // end shatter_monsters()
-
-static int shatter_items(int x, int y, int pow, int garbage)
-{
- UNUSED( pow );
- UNUSED( garbage );
-
- int broke_stuff = 0, next, obj = igrd[x][y];
-
- if (obj == NON_ITEM)
- return 0;
-
- while (obj != NON_ITEM)
- {
- next = mitm[obj].link;
-
- switch (mitm[obj].base_type)
- {
- case OBJ_POTIONS:
- if (!one_chance_in(10))
- {
- broke_stuff++;
- destroy_item(obj);
- }
- break;
-
- default:
- break;
- }
-
- obj = next;
- }
-
- if (broke_stuff)
- {
- if (!silenced(x, y) && !silenced(you.x_pos, you.y_pos))
- mpr("You hear glass break.", MSGCH_SOUND);
-
- return 1;
- }
-
- return 0;
-} // end shatter_items()
-
-static int shatter_walls(int x, int y, int pow, int garbage)
-{
- UNUSED( garbage );
-
- int chance = 0;
- int stuff = 0;
-
- // if not in-bounds then we can't really shatter it -- bwr
- if (x <= 5 || x >= GXM - 5 || y <= 5 || y >= GYM - 5)
- return (0);
-
- switch (grd[x][y])
- {
- case DNGN_SECRET_DOOR:
- if (see_grid(x, y))
- mpr("A secret door shatters!");
- grd[x][y] = DNGN_FLOOR;
- stuff = DEBRIS_WOOD;
- chance = 100;
- break;
-
- case DNGN_CLOSED_DOOR:
- case DNGN_OPEN_DOOR:
- if (see_grid(x, y))
- mpr("A door shatters!");
- grd[x][y] = DNGN_FLOOR;
- stuff = DEBRIS_WOOD;
- chance = 100;
- break;
-
- case DNGN_METAL_WALL:
- case DNGN_SILVER_STATUE:
- stuff = DEBRIS_METAL;
- chance = pow / 10;
- break;
-
- case DNGN_ORCISH_IDOL:
- case DNGN_GRANITE_STATUE:
- chance = 50;
- stuff = DEBRIS_STONE;
- break;
-
- case DNGN_STONE_WALL:
- chance = pow / 6;
- stuff = DEBRIS_STONE;
- break;
-
- case DNGN_ROCK_WALL:
- chance = pow / 4;
- stuff = DEBRIS_ROCK;
- break;
-
- case DNGN_ORANGE_CRYSTAL_STATUE:
- chance = pow / 6;
- stuff = DEBRIS_CRYSTAL;
- break;
-
- case DNGN_GREEN_CRYSTAL_WALL:
- chance = 50;
- stuff = DEBRIS_CRYSTAL;
- break;
-
- default:
- break;
- }
-
- if (stuff && random2(100) < chance)
- {
- if (!silenced( x, y ))
- noisy( 30, x, y );
-
- grd[x][y] = DNGN_FLOOR;
- place_debris(x, y, stuff);
- return (1);
- }
-
- return (0);
-} // end shatter_walls()
-
-void cast_shatter(int pow)
-{
- int damage = 0;
- const bool sil = silenced( you.x_pos, you.y_pos );
-
- if (!sil)
- noisy( 30, you.x_pos, you.y_pos );
-
- snprintf(info, INFO_SIZE, "The dungeon %s!", (sil ? "shakes" : "rumbles"));
- mpr(info, (sil? MSGCH_PLAIN : MSGCH_SOUND));
-
- switch (you.attribute[ATTR_TRANSFORMATION])
- {
- case TRAN_NONE:
- case TRAN_SPIDER:
- case TRAN_LICH:
- case TRAN_DRAGON:
- case TRAN_AIR:
- case TRAN_SERPENT_OF_HELL:
- break;
-
- case TRAN_STATUE: // full damage
- damage = 15 + random2avg( (pow / 5), 4 );
- break;
-
- case TRAN_ICE_BEAST: // 1/2 damage
- damage = 10 + random2avg( (pow / 5), 4 ) / 2;
- break;
-
- case TRAN_BLADE_HANDS: // 2d3 damage
- mpr("Your scythe-like blades vibrate painfully!");
- damage = 2 + random2avg(5, 2);
- break;
-
- default:
- mpr("cast_shatter(): unknown transformation in spells4.cc");
- }
-
- if (damage)
- ouch(damage, 0, KILLED_BY_TARGETTING);
-
- int rad = 3 + (you.skills[SK_EARTH_MAGIC] / 5);
-
- apply_area_within_radius(shatter_items, you.x_pos, you.y_pos, pow, rad, 0);
- apply_area_within_radius(shatter_monsters, you.x_pos, you.y_pos, pow, rad, 0);
- int dest = apply_area_within_radius( shatter_walls, you.x_pos, you.y_pos,
- pow, rad, 0 );
-
- if (dest && !sil)
- mpr("Ka-crash!", MSGCH_SOUND);
-} // end cast_shatter()
-
-// cast_forescry: raises evasion (by 8 currently) via divination
-void cast_forescry(int pow)
-{
- if (!you.duration[DUR_FORESCRY])
- mpr("You begin to receive glimpses of the immediate future...");
-
- you.duration[DUR_FORESCRY] += 5 + random2(pow);
-
- if (you.duration[DUR_FORESCRY] > 30)
- you.duration[DUR_FORESCRY] = 30;
-
- you.redraw_evasion = 1;
-} // end cast_forescry()
-
-void cast_see_invisible(int pow)
-{
- if (player_see_invis())
- mpr("Nothing seems to happen.");
- else
- mpr("Your vision seems to sharpen.");
-
- // no message if you already are under the spell
- you.duration[DUR_SEE_INVISIBLE] += 10 + random2(2 + (pow / 2));
-
- if (you.duration[DUR_SEE_INVISIBLE] > 100)
- you.duration[DUR_SEE_INVISIBLE] = 100;
-} // end cast_see_invisible()
-
-#if 0
-// FIXME: This would be kinda cool if implemented right.
-// The idea is that, like detect_secret_doors, the spell gathers all
-// sorts of information about a thing and then tells the caster a few
-// cryptic hints. So for a (+3,+5) Mace of Flaming, one might detect
-// "enchantment and heat", but for a cursed ring of hunger, one might
-// detect "enchantment and ice" (since it gives you a 'deathly cold'
-// feeling when you put it on) or "necromancy" (since it's evil).
-// A weapon of Divine Wrath and a randart that makes you angry might
-// both give similar messages. The key would be to not tell more than
-// hints about whether an item is benign or cursed, but give info
-// on how strong its enchantment is (and therefore how valuable it
-// probably is).
-static void cast_detect_magic(int pow)
-{
- struct dist bmove;
- int x, y;
- int monster = 0, item = 0, next; //int max;
- FixedVector < int, NUM_SPELL_TYPES > found;
- int strong = 0; // int curse = 0;
-
- for (next = 0; next < NUM_SPELL_TYPES; next++)
- {
- found[next] = 0;
- }
-
- mpr("Which direction?", MSGCH_PROMPT);
- direction( bmove, DIR_DIR );
-
- if (!bmove.isValid)
- {
- canned_msg(MSG_SPELL_FIZZLES);
- return;
- }
-
- if (bmove.dx == 0 && bmove.dy == 0)
- {
- mpr("You detect a divination in progress.");
- return;
- }
-
- x = you.x_pos + bmove.dx;
- y = you.y_pos + bmove.dy;
-
- monster = mgrd[x][y];
- if (monster == NON_MONSTER)
- goto do_items;
- else
- goto all_done;
-
- do_items:
- item = igrd[x][y];
-
- if (item == NON_ITEM)
- goto all_done;
-
- while (item != NON_ITEM)
- {
- next = mitm[item].link;
- if (is_dumpable_artifact
- (mitm[item].base_type, mitm[item].sub_type, mitm[item].plus,
- mitm[item].plus2, mitm[item].special, 0, 0))
- {
- strong++;
- //FIXME: do checks for randart properties
- }
- else
- {
- switch (mitm[item].base_type)
- {
- case OBJ_WEAPONS:
- found[SPTYP_ENCHANTMENT] += (mitm[item].plus > 50);
- found[SPTYP_ENCHANTMENT] += (mitm[item].plus2 > 50);
- break;
-
- case OBJ_MISSILES:
- found[SPTYP_ENCHANTMENT] += (mitm[item].plus > 50);
- found[SPTYP_ENCHANTMENT] += (mitm[item].plus2 > 50);
- break;
-
- case OBJ_ARMOUR:
- found[SPTYP_ENCHANTMENT] += mitm[item].plus;
- }
- }
- }
-
- all_done:
- if (monster)
- {
- mpr("You detect a morphogenic field, such as a monster might have.");
- }
- if (strong)
- {
- mpr("You detect very strong enchantments.");
- return;
- }
- else
- {
- //FIXME:
- }
- return;
-}
-#endif
-
-// The description idea was okay, but this spell just isn't that exciting.
-// So I'm converting it to the more practical expose secret doors. -- bwr
-void cast_detect_secret_doors(int pow)
-{
- int found = 0;
-
- for (int x = you.x_pos - 8; x <= you.x_pos + 8; x++)
- {
- for (int y = you.y_pos - 8; y <= you.y_pos + 8; y++)
- {
- if (x < 5 || x > GXM - 5 || y < 5 || y > GYM - 5)
- continue;
-
- if (!see_grid(x, y))
- continue;
-
- if (grd[x][y] == DNGN_SECRET_DOOR && random2(pow) > random2(15))
- {
- grd[x][y] = DNGN_CLOSED_DOOR;
- found++;
- }
- }
- }
-
- if (found)
- {
- redraw_screen();
-
- snprintf( info, INFO_SIZE, "You detect %s secret door%s.",
- (found > 1) ? "some" : "a", (found > 1) ? "s" : "" );
- mpr( info );
- }
-} // end cast_detect_secret_doors()
-
-void cast_summon_butterflies(int pow)
-{
- // explicitly limiting the number
- int num = 4 + random2(3) + random2( pow ) / 10;
- if (num > 16)
- num = 16;
-
- for (int scount = 1; scount < num; scount++)
- {
- create_monster( MONS_BUTTERFLY, ENCH_ABJ_III, BEH_FRIENDLY,
- you.x_pos, you.y_pos, MHITYOU, 250 );
- }
-}
-
-void cast_summon_large_mammal(int pow)
-{
- int mon;
- int temp_rand = random2(pow);
-
- if (temp_rand < 10)
- mon = MONS_JACKAL;
- else if (temp_rand < 15)
- mon = MONS_HOUND;
- else
- {
- switch (temp_rand % 7)
- {
- case 0:
- if (you.species == SP_HILL_ORC && one_chance_in(3))
- mon = MONS_WARG;
- else
- mon = MONS_WOLF;
- break;
- case 1:
- case 2:
- mon = MONS_WAR_DOG;
- break;
- case 3:
- case 4:
- mon = MONS_HOUND;
- break;
- default:
- mon = MONS_JACKAL;
- break;
- }
- }
-
- create_monster( mon, ENCH_ABJ_III, BEH_FRIENDLY, you.x_pos, you.y_pos,
- you.pet_target, 250 );
-}
-
-void cast_sticks_to_snakes(int pow)
-{
- int mon, i, behaviour;
-
- int how_many = 0;
-
- int max = 1 + random2( 1 + you.skills[SK_TRANSMIGRATION] ) / 4;
-
- int dur = ENCH_ABJ_III + random2(pow) / 20;
- if (dur > ENCH_ABJ_V)
- dur = ENCH_ABJ_V;
-
- const int weapon = you.equip[EQ_WEAPON];
-
- if (weapon == -1)
- {
- snprintf( info, INFO_SIZE, "Your %s feel slithery!", your_hand(true));
- mpr(info);
- return;
- }
-
- behaviour = item_cursed( you.inv[ weapon ] ) ? BEH_HOSTILE
- : BEH_FRIENDLY;
-
- if ((you.inv[ weapon ].base_type == OBJ_MISSILES
- && (you.inv[ weapon ].sub_type == MI_ARROW)))
- {
- if (you.inv[ weapon ].quantity < max)
- max = you.inv[ weapon ].quantity;
-
- for (i = 0; i <= max; i++)
- {
- //jmf: perhaps also check for poison ammo?
- if (pow > 50 || (pow > 25 && one_chance_in(3)))
- mon = MONS_SNAKE;
- else
- mon = MONS_SMALL_SNAKE;
-
- if (create_monster( mon, dur, behaviour, you.x_pos, you.y_pos,
- MHITYOU, 250 ) != -1)
- {
- how_many++;
- }
- }
- }
-
- if (you.inv[ weapon ].base_type == OBJ_WEAPONS
- && (you.inv[ weapon ].sub_type == WPN_CLUB
- || you.inv[ weapon ].sub_type == WPN_SPEAR
- || you.inv[ weapon ].sub_type == WPN_QUARTERSTAFF
- || you.inv[ weapon ].sub_type == WPN_SCYTHE
- || you.inv[ weapon ].sub_type == WPN_GIANT_CLUB
- || you.inv[ weapon ].sub_type == WPN_GIANT_SPIKED_CLUB
- || you.inv[ weapon ].sub_type == WPN_BOW
- || you.inv[ weapon ].sub_type == WPN_LONGBOW
- || you.inv[ weapon ].sub_type == WPN_ANCUS
- || you.inv[ weapon ].sub_type == WPN_HALBERD
- || you.inv[ weapon ].sub_type == WPN_GLAIVE
- || you.inv[ weapon ].sub_type == WPN_BLOWGUN))
- {
- how_many = 1;
-
- // Upsizing Snakes to Brown Snakes as the base class for using
- // the really big sticks (so bonus applies really only to trolls,
- // ogres, and most importantly ogre magi). Still it's unlikely
- // any character is strong enough to bother lugging a few of
- // these around. -- bwr
- if (item_mass( you.inv[ weapon ] ) < 500)
- mon = MONS_SNAKE;
- else
- mon = MONS_BROWN_SNAKE;
-
- if (pow > 90 && one_chance_in(3))
- mon = MONS_GREY_SNAKE;
-
- if (pow > 70 && one_chance_in(3))
- mon = MONS_BLACK_SNAKE;
-
- if (pow > 40 && one_chance_in(3))
- mon = MONS_YELLOW_SNAKE;
-
- if (pow > 20 && one_chance_in(3))
- mon = MONS_BROWN_SNAKE;
-
- create_monster(mon, dur, behaviour, you.x_pos, you.y_pos, MHITYOU, 250);
- }
-
-#ifdef USE_DEBRIS_CODE
- if (you.inv[ weapon ].base_type == OBJ_DEBRIS
- && (you.inv[ weapon ].sub_type == DEBRIS_WOOD))
- {
- // this is how you get multiple big snakes
- how_many = 1;
- mpr("FIXME: implement OBJ_DEBRIS conversion! (spells4.cc)");
- }
-#endif // USE_DEBRIS_CODE
-
- if (how_many > you.inv[you.equip[EQ_WEAPON]].quantity)
- how_many = you.inv[you.equip[EQ_WEAPON]].quantity;
-
- if (how_many)
- {
- dec_inv_item_quantity( you.equip[EQ_WEAPON], how_many );
-
- snprintf( info, INFO_SIZE, "You create %s snake%s!",
- how_many > 1 ? "some" : "a", how_many > 1 ? "s" : "");
- }
- else
- {
- snprintf( info, INFO_SIZE, "Your %s feel slithery!", your_hand(true));
- }
-
- mpr(info);
- return;
-} // end cast_sticks_to_snakes()
-
-void cast_summon_dragon(int pow)
-{
- int happy;
-
- // Removed the chance of multiple dragons... one should be more
- // than enough, and if it isn't, the player can cast again...
- // especially since these aren't on the Abjuration plan... they'll
- // last until they die (maybe that should be changed, but this is
- // a very high level spell so it might be okay). -- bwr
- happy = (random2(pow) > 5);
-
- if (create_monster( MONS_DRAGON, ENCH_ABJ_III,
- (happy ? BEH_FRIENDLY : BEH_HOSTILE),
- you.x_pos, you.y_pos, MHITYOU, 250 ) != -1)
- {
- strcpy(info, "A dragon appears.");
-
- if (!happy)
- strcat(info, " It doesn't look very happy.");
- }
- else
- strcpy(info, "Nothing happens.");
-
- mpr(info);
-} // end cast_summon_dragon()
-
-void cast_conjure_ball_lightning( int pow )
-{
- int num = 3 + random2( 2 + pow / 50 );
-
- // but restricted so that the situation doesn't get too gross.
- // Each of these will explode for 3d20 damage. -- bwr
- if (num > 8)
- num = 8;
-
- bool summoned = false;
-
- for (int i = 0; i < num; i++)
- {
- int tx = -1, ty = -1;
-
- for (int j = 0; j < 10; j++)
- {
- if (!random_near_space( you.x_pos, you.y_pos, tx, ty, true, true)
- && distance( you.x_pos, you.y_pos, tx, ty ) <= 5)
- {
- break;
- }
- }
-
- // if we fail, we'll try the ol' summon next to player trick.
- if (tx == -1 || ty == -1)
- {
- tx = you.x_pos;
- ty = you.y_pos;
- }
-
- int mon = mons_place( MONS_BALL_LIGHTNING, BEH_FRIENDLY, MHITNOT,
- true, tx, ty );
-
- // int mon = create_monster( MONS_BALL_LIGHTNING, 0, BEH_FRIENDLY,
- // tx, ty, MHITNOT, 250 );
-
- if (mon != -1)
- {
- mons_add_ench( &menv[mon], ENCH_SHORT_LIVED );
- summoned = true;
- }
- }
-
- if (summoned)
- mpr( "You create some ball lightning!" );
- else
- canned_msg( MSG_NOTHING_HAPPENS );
-}
-
-static int sleep_monsters(int x, int y, int pow, int garbage)
-{
- UNUSED( garbage );
- int mnstr = mgrd[x][y];
-
- if (mnstr == NON_MONSTER) return 0;
- if (mons_holiness(&menv[mnstr]) != MH_NATURAL) return 0;
- if (check_mons_resist_magic( &menv[mnstr], pow )) return 0;
-
- // Why shouldn't we be able to sleep friendly monsters? -- bwr
- // if (mons_friendly( &menv[mnstr] )) return 0;
-
- //jmf: now that sleep == hibernation:
- if (mons_res_cold( &menv[mnstr] ) > 0 && coinflip()) return 0;
- if (mons_has_ench( &menv[mnstr], ENCH_SLEEP_WARY )) return 0;
-
- menv[mnstr].behaviour = BEH_SLEEP;
- mons_add_ench( &menv[mnstr], ENCH_SLEEP_WARY );
-
- if (mons_class_flag( menv[mnstr].type, M_COLD_BLOOD ) && coinflip())
- mons_add_ench( &menv[mnstr], ENCH_SLOW );
-
- return 1;
-} // end sleep_monsters()
-
-void cast_mass_sleep(int pow)
-{
- apply_area_visible(sleep_monsters, pow);
-} // end cast_mass_sleep()
-
-static int tame_beast_monsters(int x, int y, int pow, int garbage)
-{
- UNUSED( garbage );
- int which_mons = mgrd[x][y];
-
- if (which_mons == NON_MONSTER) return 0;
-
- struct monsters *monster = &menv[which_mons];
-
- if (mons_holiness(monster) != MH_NATURAL) return 0;
- if (mons_intel_type(monster->type) != I_ANIMAL) return 0;
- if (mons_friendly(monster)) return 0;
-
- // 50% bonus for dogs, add cats if they get implemented
- if (monster->type == MONS_HOUND || monster->type == MONS_WAR_DOG
- || monster->type == MONS_BLACK_BEAR)
- {
- pow += (pow / 2);
- }
-
- if (you.species == SP_HILL_ORC && monster->type == MONS_WARG)
- pow += (pow / 2);
-
- if (check_mons_resist_magic(monster, pow))
- return 0;
-
- // I'd like to make the monsters affected permanently, but that's
- // pretty powerful. Maybe a small (pow/10) chance of being permanently
- // tamed, large chance of just being enslaved.
- simple_monster_message(monster, " is tamed!");
-
- if (random2(100) < random2(pow / 10))
- monster->attitude = ATT_FRIENDLY; // permanent, right?
- else
- mons_add_ench(monster, ENCH_CHARM);
-
- return 1;
-} // end tame_beast_monsters()
-
-void cast_tame_beasts(int pow)
-{
- apply_area_visible(tame_beast_monsters, pow);
-} // end cast_tame_beasts()
-
-static int ignite_poison_objects(int x, int y, int pow, int garbage)
-{
- UNUSED( pow );
- UNUSED( garbage );
-
- int obj = igrd[x][y], next, strength = 0;
-
- if (obj == NON_ITEM)
- return (0);
-
- while (obj != NON_ITEM)
- {
- next = mitm[obj].link;
- if (mitm[obj].base_type == OBJ_POTIONS)
- {
- switch (mitm[obj].sub_type)
- {
- // intentional fall-through all the way down
- case POT_STRONG_POISON:
- strength += 20;
- case POT_DEGENERATION:
- strength += 10;
- case POT_POISON:
- strength += 10;
- destroy_item(obj);
- default:
- break;
- }
- }
-
- // FIXME: impliment burning poisoned ammo
- // else if ( it's ammo that's poisoned) {
- // strength += number_of_ammo;
- // destroy_item(ammo);
- // }
- obj = next;
- }
-
- if (strength > 0)
- place_cloud(CLOUD_FIRE, x, y, strength + roll_dice(3, strength / 4) );
-
- return (strength);
-} // end ignite_poison_objects()
-
-static int ignite_poison_clouds( int x, int y, int pow, int garbage )
-{
- UNUSED( pow );
- UNUSED( garbage );
-
- bool did_anything = false;
-
- const int cloud = env.cgrid[x][y];
-
- if (cloud != EMPTY_CLOUD)
- {
- if (env.cloud[ cloud ].type == CLOUD_STINK
- || env.cloud[ cloud ].type == CLOUD_STINK_MON)
- {
- did_anything = true;
- env.cloud[ cloud ].type = CLOUD_FIRE;
-
- env.cloud[ cloud ].decay /= 2;
-
- if (env.cloud[ cloud ].decay < 1)
- env.cloud[ cloud ].decay = 1;
- }
- else if (env.cloud[ cloud ].type == CLOUD_POISON
- || env.cloud[ cloud ].type == CLOUD_POISON_MON)
- {
- did_anything = true;
- env.cloud[ cloud ].type = CLOUD_FIRE;
- }
- }
-
- return ((int) did_anything);
-} // end ignite_poison_clouds()
-
-static int ignite_poison_monsters(int x, int y, int pow, int garbage)
-{
- UNUSED( garbage );
-
- struct bolt beam;
- beam.flavour = BEAM_FIRE; // this is dumb, only used for adjust!
-
- dice_def dam_dice( 0, 5 + pow / 7 ); // dice added below if applicable
-
- const int mon_index = mgrd[x][y];
- if (mon_index == NON_MONSTER)
- return (0);
-
- struct monsters *const mon = &menv[ mon_index ];
-
- // Monsters which have poison corpses or poisonous attacks:
- if (mons_corpse_effect( mon->type ) == CE_POISONOUS
- || mon->type == MONS_GIANT_ANT
- || mon->type == MONS_SMALL_SNAKE
- || mon->type == MONS_SNAKE
- || mon->type == MONS_JELLYFISH
- || mons_is_mimic( mon->type ))
- {
- dam_dice.num = 3;
- }
-
- // Monsters which are poisoned:
- int strength = 0;
-
- // first check for player poison:
- int ench = mons_has_ench( mon, ENCH_YOUR_POISON_I, ENCH_YOUR_POISON_IV );
- if (ench != ENCH_NONE)
- strength += ench - ENCH_YOUR_POISON_I + 1;
-
- // ... now monster poison:
- ench = mons_has_ench( mon, ENCH_POISON_I, ENCH_POISON_IV );
- if (ench != ENCH_NONE)
- strength += ench - ENCH_POISON_I + 1;
-
- // strength is now the sum of both poison types (although only
- // one should actually be present at a given time):
- dam_dice.num += strength;
-
- int damage = roll_dice( dam_dice );
- if (damage > 0)
- {
- damage = mons_adjust_flavoured( mon, beam, damage );
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "Dice: %dd%d; Damage: %d",
- dam_dice.num, dam_dice.size, damage );
-
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- if (!player_hurt_monster( mon_index, damage ))
- {
- // Monster survived, remove any poison.
- mons_del_ench( mon, ENCH_POISON_I, ENCH_POISON_IV );
- mons_del_ench( mon, ENCH_YOUR_POISON_I, ENCH_YOUR_POISON_IV );
- }
-
- return (1);
- }
-
- return (0);
-}
-
-void cast_ignite_poison(int pow)
-{
- int damage = 0, strength = 0, pcount = 0, acount = 0, totalstrength = 0;
- char item;
- bool wasWielding = false;
- char str_pass[ ITEMNAME_SIZE ];
-
- // temp weapon of venom => temp fire brand
- const int wpn = you.equip[EQ_WEAPON];
-
- if (wpn != -1
- && you.duration[DUR_WEAPON_BRAND]
- && get_weapon_brand( you.inv[wpn] ) == SPWPN_VENOM)
- {
- if (set_item_ego_type( you.inv[wpn], OBJ_WEAPONS, SPWPN_FLAMING ))
- {
- in_name( wpn, DESC_CAP_YOUR, str_pass );
- strcpy( info, str_pass );
- strcat( info, " bursts into flame!" );
- mpr(info);
-
- you.wield_change = true;
- you.duration[DUR_WEAPON_BRAND] += 1 + you.duration[DUR_WEAPON_BRAND] / 2;
- if (you.duration[DUR_WEAPON_BRAND] > 80)
- you.duration[DUR_WEAPON_BRAND] = 80;
- }
- }
-
- totalstrength = 0;
-
- for (item = 0; item < ENDOFPACK; item++)
- {
- if (!you.inv[item].quantity)
- continue;
-
- strength = 0;
-
- if (you.inv[item].base_type == OBJ_MISSILES)
- {
- if (you.inv[item].special == 3)
- { // burn poison ammo
- strength = you.inv[item].quantity;
- acount += you.inv[item].quantity;
- }
- }
-
- if (you.inv[item].base_type == OBJ_POTIONS)
- {
- switch (you.inv[item].sub_type)
- {
- case POT_STRONG_POISON:
- strength += 20 * you.inv[item].quantity;
- break;
- case POT_DEGENERATION:
- case POT_POISON:
- strength += 10 * you.inv[item].quantity;
- break;
- default:
- break;
- } // end switch
-
- if (strength)
- pcount += you.inv[item].quantity;
- }
-
- if (strength)
- {
- you.inv[item].quantity = 0;
- if (item == you.equip[EQ_WEAPON])
- {
- you.equip[EQ_WEAPON] = -1;
- wasWielding = true;
- }
- }
-
- totalstrength += strength;
- }
-
- if (acount > 0)
- mpr("Some ammo you are carrying burns!");
-
- if (pcount > 0)
- {
- snprintf( info, INFO_SIZE, "%s potion%s you are carrying explode%s!",
- pcount > 1 ? "Some" : "A",
- pcount > 1 ? "s" : "",
- pcount > 1 ? "" : "s");
- mpr(info);
- }
-
- if (wasWielding == true)
- canned_msg( MSG_EMPTY_HANDED );
-
- if (totalstrength)
- {
- place_cloud(CLOUD_FIRE, you.x_pos, you.y_pos,
- random2(totalstrength / 4 + 1) + random2(totalstrength / 4 + 1) +
- random2(totalstrength / 4 + 1) + random2(totalstrength / 4 + 1) + 1);
- }
-
- // player is poisonous
- if (you.mutation[MUT_SPIT_POISON] || you.mutation[MUT_STINGER]
- || you.attribute[ATTR_TRANSFORMATION] == TRAN_SPIDER // poison attack
- || (!player_is_shapechanged()
- && (you.species == SP_GREEN_DRACONIAN // poison breath
- || you.species == SP_KOBOLD // poisonous corpse
- || you.species == SP_NAGA))) // spit poison
- {
- damage = roll_dice( 3, 5 + pow / 7 );
- }
-
- // player is poisoned
- damage += roll_dice( you.poison, 6 );
-
- if (damage)
- {
- const int resist = player_res_fire();
-
- if (resist > 0)
- {
- mpr("You feel like your blood is boiling!");
- damage = damage / 3;
- }
- else if (resist < 0)
- {
- damage *= 3;
- mpr("The poison in your system burns terribly!");
- }
- else
- {
- mpr("The poison in your system burns!");
- }
-
- ouch( damage, 0, KILLED_BY_TARGETTING );
-
- if (you.poison > 0)
- {
- mpr( "You feel that the poison has left your system." );
- you.poison = 0;
- }
- }
-
- apply_area_visible(ignite_poison_clouds, pow);
- apply_area_visible(ignite_poison_objects, pow);
- apply_area_visible(ignite_poison_monsters, pow);
-} // end cast_ignite_poison()
-
-void cast_silence(int pow)
-{
- if (!you.attribute[ATTR_WAS_SILENCED])
- mpr("A profound silence engulfs you.");
-
- you.attribute[ATTR_WAS_SILENCED] = 1;
-
- you.duration[DUR_SILENCE] += 10 + random2avg( pow, 2 );
-
- if (you.duration[DUR_SILENCE] > 100)
- you.duration[DUR_SILENCE] = 100;
-} // end cast_silence()
-
-
-/* ******************************************************************
-// no hooks for this anywhere {dlb}:
-
-void cast_animate_golem(int pow)
-{
- // must have more than 20 max_hitpoints
-
- // must be wielding a Scroll of Paper (for chem)
-
- // must be standing on a pile of <foo> (for foo in: wood, metal, rock, stone)
-
- // Will cost you 5-10% of max_hitpoints, or 20 + some, whichever is more
- mpr("You imbue the inanimate form with a portion of your life force.");
-
- naughty(NAUGHTY_CREATED_LIFE, 10);
-}
-
-****************************************************************** */
-
-static int discharge_monsters( int x, int y, int pow, int garbage )
-{
- UNUSED( garbage );
-
- const int mon = mgrd[x][y];
- int damage = 0;
-
- struct bolt beam;
- beam.flavour = BEAM_ELECTRICITY; // used for mons_adjust_flavoured
-
- if (x == you.x_pos && y == you.y_pos)
- {
- mpr( "You are struck by lightning." );
- damage = 3 + random2( 5 + pow / 10 );
- damage = check_your_resists( damage, BEAM_ELECTRICITY );
- ouch( damage, 0, KILLED_BY_WILD_MAGIC );
- }
- else if (mon == NON_MONSTER)
- return (0);
- else if (mons_res_elec(&menv[mon]) > 0 || mons_flies(&menv[mon]))
- return (0);
- else
- {
- damage = 3 + random2( 5 + pow / 10 );
- damage = mons_adjust_flavoured( &menv[mon], beam, damage );
-
- if (damage)
- {
- strcpy( info, ptr_monam( &(menv[mon]), DESC_CAP_THE ) );
- strcat( info, " is struck by lightning." );
- mpr( info );
-
- player_hurt_monster( mon, damage );
- }
- }
-
- // Recursion to give us chain-lightning -- bwr
- // Low power slight chance added for low power characters -- bwr
- if ((pow >= 10 && !one_chance_in(3)) || (pow >= 3 && one_chance_in(10)))
- {
- mpr( "The lightning arcs!" );
- pow /= (coinflip() ? 2 : 3);
- damage += apply_random_around_square( discharge_monsters, x, y,
- true, pow, 1 );
- }
- else if (damage > 0)
- {
- // Only printed if we did damage, so that the messages in
- // cast_discharge() are clean. -- bwr
- mpr( "The lightning grounds out." );
- }
-
- return (damage);
-} // end discharge_monsters()
-
-void cast_discharge( int pow )
-{
- int num_targs = 1 + random2( 1 + pow / 25 );
- int dam;
-
- dam = apply_random_around_square( discharge_monsters, you.x_pos, you.y_pos,
- true, pow, num_targs );
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "Arcs: %d Damage: %d", num_targs, dam );
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- if (dam == 0)
- {
- if (coinflip())
- mpr("The air around you crackles with electrical energy.");
- else
- {
- bool plural = coinflip();
- snprintf( info, INFO_SIZE, "%s blue arc%s ground%s harmlessly %s you.",
- plural ? "Some" : "A",
- plural ? "s" : "",
- plural ? " themselves" : "s itself",
- plural ? "around" : (coinflip() ? "beside" :
- coinflip() ? "behind" : "before")
- );
-
- mpr(info);
- }
- }
-} // end cast_discharge()
-
-// NB: this must be checked against the same effects
-// in fight.cc for all forms of attack !!! {dlb}
-// This function should be currently unused (the effect is too powerful)
-static int distortion_monsters(int x, int y, int pow, int message)
-{
- int specdam = 0;
- int monster_attacked = mgrd[x][y];
-
- if (monster_attacked == NON_MONSTER)
- return 0;
-
- struct monsters *defender = &menv[monster_attacked];
-
- if (pow > 100)
- pow = 100;
-
- if (x == you.x_pos && y == you.y_pos)
- {
- if (you.skills[SK_TRANSLOCATIONS] < random2(8))
- {
- miscast_effect( SPTYP_TRANSLOCATION, pow / 9 + 1, pow, 100,
- "a distortion effect" );
- }
- else
- {
- miscast_effect( SPTYP_TRANSLOCATION, 1, 1, 100,
- "a distortion effect" );
- }
-
- return 1;
- }
-
- if (defender->type == MONS_BLINK_FROG) // any others resist?
- {
- int hp = defender->hit_points;
- int max_hp = defender->max_hit_points;
-
- mpr("The blink frog basks in the translocular energy.");
-
- if (hp < max_hp)
- hp += 1 + random2(1 + pow / 4) + random2(1 + pow / 7);
-
- if (hp > max_hp)
- hp = max_hp;
-
- defender->hit_points = hp;
- return 1;
- }
- else if (coinflip())
- {
- strcpy(info, "Space bends around ");
- strcat(info, ptr_monam(defender, DESC_NOCAP_THE));
- strcat(info, ".");
- mpr(info);
- specdam += 1 + random2avg( 7, 2 ) + random2(pow) / 40;
- }
- else if (coinflip())
- {
- strcpy(info, "Space warps horribly around ");
- strcat(info, ptr_monam( defender, DESC_NOCAP_THE ));
- strcat(info, "!");
- mpr(info);
-
- specdam += 3 + random2avg( 12, 2 ) + random2(pow) / 25;
- }
- else if (one_chance_in(3))
- {
- monster_blink(defender);
- return 1;
- }
- else if (one_chance_in(3))
- {
- monster_teleport(defender, coinflip());
- return 1;
- }
- else if (one_chance_in(3))
- {
- monster_die(defender, KILL_RESET, 0);
- return 1;
- }
- else if (message)
- {
- mpr("Nothing seems to happen.");
- return 1;
- }
-
- player_hurt_monster(monster_attacked, specdam);
-
- return (specdam);
-} // end distortion_monsters()
-
-void cast_bend(int pow)
-{
- apply_one_neighbouring_square( distortion_monsters, pow );
-} // end cast_bend()
-
-// Really this is just applying the best of Band/Warp weapon/Warp field
-// into a spell that gives the "make monsters go away" benefit without
-// the insane damage potential. -- bwr
-int disperse_monsters(int x, int y, int pow, int message)
-{
- UNUSED( message );
-
- const int monster_attacked = mgrd[x][y];
-
- if (monster_attacked == NON_MONSTER)
- return 0;
-
- struct monsters *defender = &menv[monster_attacked];
-
- if (defender->type == MONS_BLINK_FROG)
- {
- simple_monster_message(defender, " resists.");
- return 1;
- }
- else if (check_mons_resist_magic(defender, pow))
- {
- if (coinflip())
- {
- simple_monster_message(defender, " partially resists.");
- monster_blink(defender);
- }
- else
- simple_monster_message(defender, " resists.");
-
- return 1;
- }
- else
- {
- monster_teleport( defender, true );
- return 1;
- }
-
- return 0;
-}
-
-void cast_dispersal(int pow)
-{
- if (apply_area_around_square( disperse_monsters,
- you.x_pos, you.y_pos, pow ) == 0)
- {
- mpr( "There is a brief shimmering in the air around you." );
- }
-}
-
-static int spell_swap_func(int x, int y, int pow, int message)
-{
- UNUSED( message );
-
- int monster_attacked = mgrd[x][y];
-
- if (monster_attacked == NON_MONSTER)
- return 0;
-
- struct monsters *defender = &menv[monster_attacked];
-
- if (defender->type == MONS_BLINK_FROG
- || check_mons_resist_magic( defender, pow ))
- {
- simple_monster_message( defender, " resists." );
- }
- else
- {
- // Swap doesn't seem to actually swap, but just sets the
- // monster's location equal to the players... this being because
- // the acr.cc call is going to move the player afterwards (for
- // the regular friendly monster swap). So we'll go through
- // standard swap procedure here... since we really want to apply
- // the same swap_places function as with friendly monsters...
- // see note over there. -- bwr
- int old_x = defender->x;
- int old_y = defender->y;
-
- if (swap_places( defender ))
- {
- you.x_pos = old_x;
- you.y_pos = old_y;
- }
- }
-
- return 1;
-}
-
-void cast_swap(int pow)
-{
- apply_one_neighbouring_square( spell_swap_func, pow );
-}
-
-static int make_a_rot_cloud(int x, int y, int pow, int ctype)
-{
- int next = 0, obj = mgrd[x][y];
-
- if (obj == NON_MONSTER)
- return 0;
-
- while (obj != NON_ITEM)
- {
- next = mitm[obj].link;
-
- if (mitm[obj].base_type == OBJ_CORPSES
- && mitm[obj].sub_type == CORPSE_BODY)
- {
- if (!mons_skeleton(mitm[obj].plus))
- destroy_item(obj);
- else
- {
- mitm[obj].sub_type = CORPSE_SKELETON;
- mitm[obj].special = 200;
- mitm[obj].colour = LIGHTGREY;
- }
-
- place_cloud(ctype, x, y,
- (3 + random2(pow / 4) + random2(pow / 4) +
- random2(pow / 4)));
- return 1;
- }
-
- obj = next;
- }
-
- return 0;
-} // end make_a_rot_cloud()
-
-int make_a_normal_cloud(int x, int y, int pow, int ctype)
-{
- place_cloud( ctype, x, y,
- (3 + random2(pow / 4) + random2(pow / 4) + random2(pow / 4)) );
-
- return 1;
-} // end make_a_normal_cloud()
-
-#if 0
-
-static int make_a_random_cloud(int x, int y, int pow, int ctype)
-{
- if (ctype == CLOUD_NONE)
- ctype = CLOUD_BLACK_SMOKE;
-
- unsigned char cloud_material;
-
- switch (random2(9))
- {
- case 0:
- cloud_material = CLOUD_FIRE;
- break;
- case 1:
- cloud_material = CLOUD_STINK;
- break;
- case 2:
- cloud_material = CLOUD_COLD;
- break;
- case 3:
- cloud_material = CLOUD_POISON;
- break;
- case 4:
- cloud_material = CLOUD_BLUE_SMOKE;
- break;
- case 5:
- cloud_material = CLOUD_STEAM;
- break;
- case 6:
- cloud_material = CLOUD_PURP_SMOKE;
- break;
- default:
- cloud_material = ctype;
- break;
- }
-
- // that last bit is equivalent to "random2(pow/4) + random2(pow/4)
- // + random2(pow/4)" {dlb}
- // can you see the pattern? {dlb}
- place_cloud(cloud_material, x, y, 3 + random2avg(3 * (pow / 4) - 2, 3));
-
- return 1;
-} // end make_a_random_cloud()
-
-#endif
-
-static int passwall(int x, int y, int pow, int garbage)
-{
- UNUSED( garbage );
-
- char dx, dy, nx = x, ny = y;
- int howdeep = 0;
- bool done = false;
- int shallow = 1 + (you.skills[SK_EARTH_MAGIC] / 8);
-
- // allow statues as entry points?
- if (grd[x][y] != DNGN_ROCK_WALL)
- // Irony: you can start on a secret door but not a door.
- // Worked stone walls are out, they're not diggable and
- // are used for impassable walls... I'm not sure we should
- // even allow statues (should be contiguous rock) -- bwr
- {
- mpr("That's not a passable wall.");
- return 0;
- }
-
- dx = x - you.x_pos;
- dy = y - you.y_pos;
-
- while (!done)
- {
- // I'm trying to figure proper borders out {dlb}
- // FIXME: dungeon border?
- if (nx > (GXM - 1) || ny > (GYM - 1) || nx < 2 || ny < 2)
- {
- mpr("You sense an overwhelming volume of rock.");
- return 0;
- }
-
- switch (grd[nx][ny])
- {
- default:
- done = true;
- break;
- case DNGN_ROCK_WALL:
- case DNGN_ORCISH_IDOL:
- case DNGN_GRANITE_STATUE:
- case DNGN_SECRET_DOOR:
- nx += dx;
- ny += dy;
- howdeep++;
- break;
- }
- }
-
- int range = shallow + random2(pow) / 25;
-
- if (howdeep > shallow)
- {
- mpr("This rock feels deep.");
-
- if (yesno("Try anyway?"))
- {
- if (howdeep > range)
- {
- ouch(1 + you.hp, 0, KILLED_BY_PETRIFICATION);
- //jmf: not return; if wizard, successful transport is option
- }
- }
- else
- {
- if (one_chance_in(30))
- mpr("Wuss.");
- else
- canned_msg(MSG_OK);
- return 1;
- }
- }
-
- // Note that the delay was (1 + howdeep * 2), but now that the
- // delay is stopped when the player is attacked it can be much
- // shorter since its harder to use for quick escapes. -- bwr
- start_delay( DELAY_PASSWALL, 2 + howdeep, nx, ny );
-
- return 1;
-} // end passwall()
-
-void cast_passwall(int pow)
-{
- apply_one_neighbouring_square(passwall, pow);
-} // end cast_passwall()
-
-static int intoxicate_monsters(int x, int y, int pow, int garbage)
-{
- UNUSED( pow );
- UNUSED( garbage );
-
- int mon = mgrd[x][y];
-
- if (mon == NON_MONSTER)
- return 0;
- if (mons_intel(menv[mon].type) < I_NORMAL)
- return 0;
- if (mons_holiness(&menv[mon]) != MH_NATURAL)
- return 0;
- if (mons_res_poison(&menv[mon]) > 0)
- return 0;
-
- mons_add_ench(&menv[mon], ENCH_CONFUSION);
- return 1;
-} // end intoxicate_monsters()
-
-void cast_intoxicate(int pow)
-{
- potion_effect( POT_CONFUSION, 10 + (100 - pow) / 10);
-
- if (one_chance_in(20) && lose_stat( STAT_INTELLIGENCE, 1 + random2(3) ))
- mpr("Your head spins!");
-
- apply_area_visible(intoxicate_monsters, pow);
-} // end cast_intoxicate()
-
-// intended as a high-level Elven (a)bility
-static int glamour_monsters(int x, int y, int pow, int garbage)
-{
- UNUSED( garbage );
-
- int mon = mgrd[x][y];
-
- // Power in this function is already limited by a function of
- // experience level (10 + level / 2) since it's only an ability,
- // never an actual spell. -- bwr
-
- if (mon == NON_MONSTER)
- return (0);
-
- if (one_chance_in(5))
- return (0);
-
- if (mons_intel(menv[mon].type) < I_NORMAL)
- return (0);
-
- if (mons_class_holiness(mon) != MH_NATURAL)
- return (0);
-
- if (!mons_is_humanoid( menv[mon].type ))
- return (0);
-
- const char show_char = mons_char( menv[mon].type );
-
- // gargoyles are immune.
- if (menv[mon].type == MONS_GARGOYLE
- || menv[mon].type == MONS_METAL_GARGOYLE
- || menv[mon].type == MONS_MOLTEN_GARGOYLE)
- {
- return (0);
- }
-
- // orcs resist thru hatred of elves
- // elves resist cause they're elves
- // boggarts are malevolent highly magical wee-folk
- if (show_char == 'o' || show_char == 'e' || menv[mon].type == MONS_BOGGART)
- pow = (pow / 2) + 1;
-
- if (check_mons_resist_magic(&menv[mon], pow))
- return (0);
-
- switch (random2(6))
- {
- case 0:
- mons_add_ench(&menv[mon], ENCH_FEAR);
- break;
- case 1:
- case 4:
- mons_add_ench(&menv[mon], ENCH_CONFUSION);
- break;
- case 2:
- case 5:
- mons_add_ench(&menv[mon], ENCH_CHARM);
- break;
- case 3:
- menv[mon].behaviour = BEH_SLEEP;
- break;
- }
-
- // why no, there's no message as to which effect happened >:^)
- if (!one_chance_in(4))
- {
- strcpy(info, ptr_monam( &(menv[mon]), DESC_CAP_THE));
-
- switch (random2(4))
- {
- case 0:
- strcat(info, " looks dazed.");
- break;
- case 1:
- strcat(info, " blinks several times.");
- break;
- case 2:
- strcat(info, " rubs its eye");
- if (menv[mon].type != MONS_CYCLOPS)
- strcat(info, "s");
- strcat(info, ".");
- break;
- case 4:
- strcat(info, " tilts its head.");
- break;
- }
-
- mpr(info);
- }
-
- return (1);
-} // end glamour_monsters()
-
-void cast_glamour(int pow)
-{
- apply_area_visible(glamour_monsters, pow);
-} // end cast_glamour()
-
-bool backlight_monsters(int x, int y, int pow, int garbage)
-{
- UNUSED( pow );
- UNUSED( garbage );
-
- int mon = mgrd[x][y];
-
- if (mon == NON_MONSTER)
- return (false);
-
- switch (menv[mon].type)
- {
- //case MONS_INSUBSTANTIAL_WISP: //jmf: I'm not sure if these glow or not
- //case MONS_VAPOUR:
- case MONS_UNSEEN_HORROR: // consider making this visible? probably not.
- return (false);
-
- case MONS_FIRE_VORTEX:
- case MONS_ANGEL:
- case MONS_FIEND:
- case MONS_SHADOW:
- case MONS_EFREET:
- case MONS_HELLION:
- case MONS_GLOWING_SHAPESHIFTER:
- case MONS_FIRE_ELEMENTAL:
- case MONS_AIR_ELEMENTAL:
- case MONS_SHADOW_FIEND:
- case MONS_SPECTRAL_WARRIOR:
- case MONS_ORANGE_RAT:
- case MONS_BALRUG:
- case MONS_SPATIAL_VORTEX:
- case MONS_PIT_FIEND:
- case MONS_SHINING_EYE:
- case MONS_DAEVA:
- case MONS_SPECTRAL_THING:
- case MONS_ORB_OF_FIRE:
- case MONS_EYE_OF_DEVASTATION:
- return (false); // already glowing or invisible
- default:
- break;
- }
-
- int lvl = mons_has_ench( &menv[mon], ENCH_BACKLIGHT_I, ENCH_BACKLIGHT_IV );
-
- if (lvl == ENCH_NONE)
- simple_monster_message( &menv[mon], " is outlined in light." );
- else if (lvl == ENCH_BACKLIGHT_IV)
- simple_monster_message( &menv[mon], " glows brighter for a moment." );
- else
- {
- // remove old level
- mons_del_ench( &menv[mon], ENCH_BACKLIGHT_I, ENCH_BACKLIGHT_III, true );
- simple_monster_message( &menv[mon], " glows brighter." );
- }
-
- // this enchantment wipes out invisibility (neat)
- mons_del_ench( &menv[mon], ENCH_INVIS );
- mons_add_ench( &menv[mon], ENCH_BACKLIGHT_IV );
-
- return (true);
-} // end backlight_monsters()
-
-void cast_evaporate(int pow)
-{
- // experimenting with allowing the potion to be thrown... we're
- // still making it have to be "in hands" at this point. -- bwr
- struct dist spelld;
- struct bolt beem;
-
- const int potion = prompt_invent_item( "Throw which potion?", OBJ_POTIONS );
-
- if (potion == -1)
- {
- snprintf( info, INFO_SIZE, "Wisps of steam play over your %s!",
- your_hand(true) );
-
- mpr(info);
- return;
- }
- else if (you.inv[potion].base_type != OBJ_POTIONS)
- {
- mpr( "This spell works only on potions!" );
- canned_msg(MSG_SPELL_FIZZLES);
- return;
- }
-
- mpr( STD_DIRECTION_PROMPT, MSGCH_PROMPT );
-
- message_current_target();
-
- direction( spelld, DIR_NONE, TARG_ENEMY );
-
- if (!spelld.isValid)
- {
- canned_msg(MSG_SPELL_FIZZLES);
- return;
- }
-
- beem.target_x = spelld.tx;
- beem.target_y = spelld.ty;
-
- beem.source_x = you.x_pos;
- beem.source_y = you.y_pos;
-
- strcpy( beem.beam_name, "potion" );
- beem.colour = you.inv[potion].colour;
- beem.range = 9;
- beem.rangeMax = 9;
- beem.type = SYM_FLASK;
- beem.beam_source = MHITYOU;
- beem.thrower = KILL_YOU_MISSILE;
- beem.aux_source = NULL;
- beem.is_beam = false;
- beem.is_tracer = false;
-
- beem.hit = you.dex / 2 + roll_dice( 2, you.skills[SK_RANGED_COMBAT] / 2 + 1 );
- beem.damage = dice_def( 1, 0 ); // no damage, just producing clouds
- beem.ench_power = pow; // used for duration only?
-
- beem.flavour = BEAM_POTION_STINKING_CLOUD;
-
- switch (you.inv[potion].sub_type)
- {
- case POT_STRONG_POISON:
- beem.flavour = BEAM_POTION_POISON;
- beem.ench_power *= 2;
- break;
-
- case POT_DEGENERATION:
- beem.flavour = (coinflip() ? BEAM_POTION_POISON : BEAM_POTION_MIASMA);
- beem.ench_power *= 2;
- break;
-
- case POT_POISON:
- beem.flavour = BEAM_POTION_POISON;
- break;
-
- case POT_DECAY:
- beem.flavour = BEAM_POTION_MIASMA;
- beem.ench_power *= 2;
- break;
-
- case POT_PARALYSIS:
- beem.ench_power *= 2;
- // fall through
- case POT_CONFUSION:
- case POT_SLOWING:
- beem.flavour = BEAM_POTION_STINKING_CLOUD;
- break;
-
- case POT_WATER:
- case POT_PORRIDGE:
- beem.flavour = BEAM_POTION_STEAM;
- break;
-
- case POT_BERSERK_RAGE:
- beem.flavour = (coinflip() ? BEAM_POTION_FIRE : BEAM_POTION_STEAM);
- break;
-
- case POT_MUTATION:
- case POT_GAIN_STRENGTH:
- case POT_GAIN_DEXTERITY:
- case POT_GAIN_INTELLIGENCE:
- case POT_EXPERIENCE:
- case POT_MAGIC:
- switch (random2(5))
- {
- case 0: beem.flavour = BEAM_POTION_FIRE; break;
- case 1: beem.flavour = BEAM_POTION_COLD; break;
- case 2: beem.flavour = BEAM_POTION_POISON; break;
- case 3: beem.flavour = BEAM_POTION_MIASMA; break;
- default: beem.flavour = BEAM_POTION_RANDOM; break;
- }
- break;
-
- default:
- switch (random2(12))
- {
- case 0: beem.flavour = BEAM_POTION_FIRE; break;
- case 1: beem.flavour = BEAM_POTION_STINKING_CLOUD; break;
- case 2: beem.flavour = BEAM_POTION_COLD; break;
- case 3: beem.flavour = BEAM_POTION_POISON; break;
- case 4: beem.flavour = BEAM_POTION_RANDOM; break;
- case 5: beem.flavour = BEAM_POTION_BLUE_SMOKE; break;
- case 6: beem.flavour = BEAM_POTION_BLACK_SMOKE; break;
- case 7: beem.flavour = BEAM_POTION_PURP_SMOKE; break;
- default: beem.flavour = BEAM_POTION_STEAM; break;
- }
- break;
- }
-
- if (coinflip())
- exercise( SK_RANGED_COMBAT, 1 );
-
- fire_beam(beem);
-
- // both old and new code use up a potion:
- dec_inv_item_quantity( potion, 1 );
-
- return;
-} // end cast_evaporate()
-
-// The intent of this spell isn't to produce helpful potions
-// for drinking, but rather to provide ammo for the Evaporate
-// spell out of corpses, thus potentially making it useful.
-// Producing helpful potions would break game balance here...
-// and producing more than one potion from a corpse, or not
-// using up the corpse might also lead to game balance problems. -- bwr
-void cast_fulsome_distillation( int powc )
-{
- char str_pass[ ITEMNAME_SIZE ];
-
- if (powc > 50)
- powc = 50;
-
- int corpse = -1;
-
- // Search items at the players location for corpses.
- // XXX: Turn this into a separate function and merge with
- // the messes over in butchery, animating, and maybe even
- // item pickup from stacks (which would make it easier to
- // create a floor stack menu system later) -- bwr
- for (int curr_item = igrd[you.x_pos][you.y_pos];
- curr_item != NON_ITEM;
- curr_item = mitm[curr_item].link)
- {
- if (mitm[curr_item].base_type == OBJ_CORPSES
- && mitm[curr_item].sub_type == CORPSE_BODY)
- {
- it_name( curr_item, DESC_NOCAP_THE, str_pass );
- snprintf( info, INFO_SIZE, "Distill a potion from %s?", str_pass );
-
- if (yesno( info, true, 0, false ))
- {
- corpse = curr_item;
- break;
- }
- }
- }
-
- if (corpse == -1)
- {
- canned_msg(MSG_SPELL_FIZZLES);
- return;
- }
-
- const bool rotten = (mitm[corpse].special < 100);
- const bool big_monster = (mons_type_hit_dice( mitm[corpse].plus ) >= 5);
- const bool power_up = (rotten && big_monster);
-
- int potion_type = POT_WATER;
-
- switch (mitm[corpse].plus)
- {
- case MONS_GIANT_BAT: // extracting batty behaviour : 1
- case MONS_UNSEEN_HORROR: // extracting batty behaviour : 7
- case MONS_GIANT_BLOWFLY: // extracting batty behaviour : 5
- potion_type = POT_CONFUSION;
- break;
-
- case MONS_RED_WASP: // paralysis attack : 8
- case MONS_YELLOW_WASP: // paralysis attack : 4
- potion_type = POT_PARALYSIS;
- break;
-
- case MONS_SNAKE: // clean meat, but poisonous attack : 2
- case MONS_GIANT_ANT: // clean meat, but poisonous attack : 3
- potion_type = (power_up ? POT_POISON : POT_CONFUSION);
- break;
-
- case MONS_ORANGE_RAT: // poisonous meat, but draining attack : 3
- potion_type = (power_up ? POT_DECAY : POT_POISON);
- break;
-
- case MONS_SPINY_WORM: // 12
- potion_type = (power_up ? POT_DECAY : POT_STRONG_POISON);
- break;
-
- default:
- switch (mons_corpse_effect( mitm[corpse].plus ))
- {
- case CE_CLEAN:
- potion_type = (power_up ? POT_CONFUSION : POT_WATER);
- break;
-
- case CE_CONTAMINATED:
- potion_type = (power_up ? POT_DEGENERATION : POT_POISON);
- break;
-
- case CE_POISONOUS:
- potion_type = (power_up ? POT_STRONG_POISON : POT_POISON);
- break;
-
- case CE_MUTAGEN_RANDOM:
- case CE_MUTAGEN_GOOD: // unused
- case CE_RANDOM: // unused
- potion_type = POT_MUTATION;
- break;
-
- case CE_MUTAGEN_BAD: // unused
- case CE_ROTTEN: // actually this only occurs via mangling
- case CE_HCL: // necrophage
- potion_type = (power_up ? POT_DECAY : POT_STRONG_POISON);
- break;
-
- case CE_NOCORPSE: // shouldn't occur
- default:
- break;
- }
- break;
- }
-
- // If not powerful enough, we downgrade the potion
- if (random2(50) > powc + 10 * rotten)
- {
- switch (potion_type)
- {
- case POT_DECAY:
- case POT_DEGENERATION:
- case POT_STRONG_POISON:
- potion_type = POT_POISON;
- break;
-
- case POT_MUTATION:
- case POT_POISON:
- potion_type = POT_CONFUSION;
- break;
-
- case POT_PARALYSIS:
- potion_type = POT_SLOWING;
- break;
-
- case POT_CONFUSION:
- case POT_SLOWING:
- default:
- potion_type = POT_WATER;
- break;
- }
- }
-
- // We borrow the corpse's object to make our potion:
- mitm[corpse].base_type = OBJ_POTIONS;
- mitm[corpse].sub_type = potion_type;
- mitm[corpse].quantity = 1;
- mitm[corpse].plus = 0;
- mitm[corpse].plus2 = 0;
- item_colour( mitm[corpse] ); // sets special as well
-
- it_name( corpse, DESC_NOCAP_A, str_pass );
- snprintf( info, INFO_SIZE, "You extract %s from the corpse.",
- str_pass );
- mpr( info );
-
- // try to move the potion to the player (for convenience)
- if (move_item_to_player( corpse, 1 ) != 1)
- {
- mpr( "Unfortunately, you can't carry it right now!" );
- }
-}
-
-void make_shuggoth(int x, int y, int hp)
-{
- int mon = create_monster( MONS_SHUGGOTH, 100 + random2avg(58, 3),
- BEH_HOSTILE, x, y, MHITNOT, 250 );
-
- if (mon != -1)
- {
- menv[mon].hit_points = hp;
- menv[mon].max_hit_points = hp;
- }
-
- return;
-} // end make_shuggoth()
-
-static int rot_living(int x, int y, int pow, int message)
-{
- UNUSED( message );
-
- int mon = mgrd[x][y];
- int ench;
-
- if (mon == NON_MONSTER)
- return 0;
-
- if (mons_holiness(&menv[mon]) != MH_NATURAL)
- return 0;
-
- if (check_mons_resist_magic(&menv[mon], pow))
- return 0;
-
- ench = ((random2(pow) + random2(pow) + random2(pow) + random2(pow)) / 4);
-
- if (ench >= 50)
- ench = ENCH_YOUR_ROT_IV;
- else if (ench >= 35)
- ench = ENCH_YOUR_ROT_III;
- else if (ench >= 20)
- ench = ENCH_YOUR_ROT_II;
- else
- ench = ENCH_YOUR_ROT_I;
-
- mons_add_ench(&menv[mon], ench);
-
- return 1;
-} // end rot_living()
-
-static int rot_undead(int x, int y, int pow, int garbage)
-{
- UNUSED( garbage );
-
- int mon = mgrd[x][y];
- int ench;
-
- if (mon == NON_MONSTER)
- return 0;
-
- if (mons_holiness(&menv[mon]) != MH_UNDEAD)
- return 0;
-
- if (check_mons_resist_magic(&menv[mon], pow))
- return 0;
-
- // this does not make sense -- player mummies are
- // immune to rotting (or have been) -- so what is
- // the schema in use here to determine rotting??? {dlb}
-
- //jmf: up for discussion. it is clearly unfair to
- // rot player mummies.
- // the `shcema' here is: corporeal non-player undead
- // rot, discorporeal undead don't rot. if you wanna
- // insist that monsters get the same treatment as
- // players, I demand my player mummies get to worship
- // the evil mummy & orc god.
- switch (menv[mon].type)
- {
- case MONS_NECROPHAGE:
- case MONS_ZOMBIE_SMALL:
- case MONS_LICH:
- case MONS_MUMMY:
- case MONS_VAMPIRE:
- case MONS_ZOMBIE_LARGE:
- case MONS_WIGHT:
- case MONS_GHOUL:
- case MONS_BORIS:
- case MONS_ANCIENT_LICH:
- case MONS_VAMPIRE_KNIGHT:
- case MONS_VAMPIRE_MAGE:
- case MONS_GUARDIAN_MUMMY:
- case MONS_GREATER_MUMMY:
- case MONS_MUMMY_PRIEST:
- break;
- case MONS_ROTTING_HULK:
- default:
- return 0; // immune (no flesh) or already rotting
- }
-
- ench = ((random2(pow) + random2(pow) + random2(pow) + random2(pow)) / 4);
-
- if (ench >= 50)
- ench = ENCH_YOUR_ROT_IV;
- else if (ench >= 35)
- ench = ENCH_YOUR_ROT_III;
- else if (ench >= 20)
- ench = ENCH_YOUR_ROT_II;
- else
- ench = ENCH_YOUR_ROT_I;
-
- mons_add_ench(&menv[mon], ench);
-
- return 1;
-} // end rot_undead()
-
-static int rot_corpses(int x, int y, int pow, int garbage)
-{
- UNUSED( garbage );
-
- return make_a_rot_cloud(x, y, pow, CLOUD_MIASMA);
-} // end rot_corpses()
-
-void cast_rotting(int pow)
-{
- apply_area_visible(rot_living, pow);
- apply_area_visible(rot_undead, pow);
- apply_area_visible(rot_corpses, pow);
- return;
-} // end cast_rotting()
-
-void do_monster_rot(int mon)
-{
- int damage = 1 + random2(3);
-
- if (mons_holiness(&menv[mon]) == MH_UNDEAD && random2(5))
- {
- apply_area_cloud(make_a_normal_cloud, menv[mon].x, menv[mon].y,
- 10, 1, CLOUD_MIASMA);
- }
-
- player_hurt_monster( mon, damage );
- return;
-} // end do_monster_rot()
-
-static int snake_charm_monsters(int x, int y, int pow, int message)
-{
- UNUSED( message );
-
- int mon = mgrd[x][y];
-
- if (mon == NON_MONSTER) return 0;
- if (mons_friendly(&menv[mon])) return 0;
- if (one_chance_in(4)) return 0;
- if (mons_char(menv[mon].type) != 'S') return 0;
- if (check_mons_resist_magic(&menv[mon], pow)) return 0;
-
- menv[mon].attitude = ATT_FRIENDLY;
- snprintf( info, INFO_SIZE, "%s sways back and forth.", ptr_monam( &(menv[mon]), DESC_CAP_THE ));
- mpr(info);
-
- return 1;
-}
-
-void cast_snake_charm(int pow)
-{
- // powc = (you.experience_level * 2) + (you.skills[SK_INVOCATIONS] * 3);
- apply_one_neighbouring_square(snake_charm_monsters, pow);
-}
-
-void cast_fragmentation(int pow) // jmf: ripped idea from airstrike
-{
- struct dist beam;
- struct bolt blast;
- int debris = 0;
- int trap;
- bool explode = false;
- bool hole = true;
- const char *what = NULL;
-
- mpr("Fragment what (e.g. a wall)?", MSGCH_PROMPT);
- direction( beam, DIR_TARGET, TARG_ENEMY );
-
- if (!beam.isValid)
- {
- canned_msg(MSG_SPELL_FIZZLES);
- return;
- }
-
- //FIXME: if (player typed '>' to attack floor) goto do_terrain;
- blast.beam_source = MHITYOU;
- blast.thrower = KILL_YOU;
- blast.aux_source = NULL;
- blast.ex_size = 1; // default
- blast.type = '#';
- blast.colour = 0;
- blast.target_x = beam.tx;
- blast.target_y = beam.ty;
- blast.is_tracer = false;
- blast.flavour = BEAM_FRAG;
-
- // Number of dice vary... 3 is easy/common, but it can get as high as 6.
- blast.damage = dice_def( 0, 5 + pow / 10 );
-
- const int grid = grd[beam.tx][beam.ty];
- const int mon = mgrd[beam.tx][beam.ty];
-
- const bool okay_to_dest = ((beam.tx > 5 && beam.tx < GXM - 5)
- && (beam.ty > 5 && beam.ty < GYM - 5));
-
- if (mon != NON_MONSTER)
- {
- // This needs its own hand_buff... we also need to do it first
- // in case the target dies. -- bwr
- char explode_msg[80];
-
- snprintf( explode_msg, sizeof( explode_msg ), "%s explodes!",
- ptr_monam( &(menv[mon]), DESC_CAP_THE ) );
-
- switch (menv[mon].type)
- {
- case MONS_ICE_BEAST: // blast of ice fragments
- case MONS_SIMULACRUM_SMALL:
- case MONS_SIMULACRUM_LARGE:
- explode = true;
- strcpy(blast.beam_name, "icy blast");
- blast.colour = WHITE;
- blast.damage.num = 2;
- blast.flavour = BEAM_ICE;
- if (player_hurt_monster(mon, roll_dice( blast.damage )))
- blast.damage.num += 1;
- break;
-
- case MONS_FLYING_SKULL:
- case MONS_SKELETON_SMALL:
- case MONS_SKELETON_LARGE: // blast of bone
- explode = true;
-
- snprintf( info, INFO_SIZE, "The sk%s explodes into sharp fragments of bone!",
- (menv[mon].type == MONS_FLYING_SKULL) ? "ull" : "eleton");
-
- strcpy(blast.beam_name, "blast of bone shards");
-
- blast.colour = LIGHTGREY;
-
- if (random2(50) < (pow / 5)) // potential insta-kill
- {
- monster_die(&menv[mon], KILL_YOU, 0);
- blast.damage.num = 4;
- }
- else
- {
- blast.damage.num = 2;
- if (player_hurt_monster(mon, roll_dice( blast.damage )))
- blast.damage.num = 4;
- }
- goto all_done; // i.e. no "Foo Explodes!"
-
- case MONS_WOOD_GOLEM:
- explode = false;
- simple_monster_message(&menv[mon], " shudders violently!");
-
- // We use blast.damage not only for inflicting damage here,
- // but so that later on we'll know that the spell didn't
- // fizzle (since we don't actually explode wood golems). -- bwr
- blast.damage.num = 2;
- player_hurt_monster( mon, roll_dice( blast.damage ) );
- break;
-
- case MONS_IRON_GOLEM:
- case MONS_METAL_GARGOYLE:
- explode = true;
- strcpy( blast.beam_name, "blast of metal fragments" );
- blast.colour = CYAN;
- blast.damage.num = 4;
- if (player_hurt_monster(mon, roll_dice( blast.damage )))
- blast.damage.num += 2;
- break;
-
- case MONS_CLAY_GOLEM: // assume baked clay and not wet loam
- case MONS_STONE_GOLEM:
- case MONS_EARTH_ELEMENTAL:
- case MONS_GARGOYLE:
- explode = true;
- blast.ex_size = 2;
- strcpy(blast.beam_name, "blast of rock fragments");
- blast.colour = BROWN;
- blast.damage.num = 3;
- if (player_hurt_monster(mon, roll_dice( blast.damage )))
- blast.damage.num += 1;
- break;
-
- case MONS_CRYSTAL_GOLEM:
- explode = true;
- blast.ex_size = 2;
- strcpy(blast.beam_name, "blast of crystal shards");
- blast.colour = WHITE;
- blast.damage.num = 4;
- if (player_hurt_monster(mon, roll_dice( blast.damage )))
- blast.damage.num += 2;
- break;
-
- default:
- blast.damage.num = 1; // to mark that a monster was targetted
-
- // Yes, this spell does lousy damage if the
- // monster isn't susceptable. -- bwr
- player_hurt_monster( mon, roll_dice( 1, 5 + pow / 25 ) );
- goto do_terrain;
- }
-
- mpr( explode_msg );
- goto all_done;
- }
-
- do_terrain:
- // FIXME: do nothing in Abyss & Pandemonium?
-
- switch (grid)
- {
- //
- // Stone and rock terrain
- //
- case DNGN_ROCK_WALL:
- case DNGN_SECRET_DOOR:
- blast.colour = env.rock_colour;
- // fall-through
- case DNGN_STONE_WALL:
- what = "wall";
- if (player_in_branch( BRANCH_HALL_OF_ZOT ))
- blast.colour = env.rock_colour;
- // fall-through
- case DNGN_ORCISH_IDOL:
- if (what == NULL)
- what = "stone idol";
- if (blast.colour == 0)
- blast.colour = DARKGREY;
- // fall-through
- case DNGN_GRANITE_STATUE: // normal rock -- big explosion
- if (what == NULL)
- what = "statue";
-
- explode = true;
-
- strcpy(blast.beam_name, "blast of rock fragments");
- blast.damage.num = 3;
- if (blast.colour == 0)
- blast.colour = LIGHTGREY;
-
- if (okay_to_dest
- && (grid == DNGN_ORCISH_IDOL
- || grid == DNGN_GRANITE_STATUE
- || (pow >= 40 && grid == DNGN_ROCK_WALL && one_chance_in(3))
- || (pow >= 60 && grid == DNGN_STONE_WALL && one_chance_in(10))))
- {
- // terrain blew up real good:
- blast.ex_size = 2;
- grd[beam.tx][beam.ty] = DNGN_FLOOR;
- debris = DEBRIS_ROCK;
- }
- break;
-
- //
- // Metal -- small but nasty explosion
- //
-
- case DNGN_METAL_WALL:
- what = "metal wall";
- blast.colour = CYAN;
- // fallthru
- case DNGN_SILVER_STATUE:
- if (what == NULL)
- {
- what = "silver statue";
- blast.colour = WHITE;
- }
-
- explode = true;
- strcpy( blast.beam_name, "blast of metal fragments" );
- blast.damage.num = 4;
-
- if (okay_to_dest && pow >= 80 && random2(500) < pow / 5)
- {
- blast.damage.num += 2;
- grd[beam.tx][beam.ty] = DNGN_FLOOR;
- debris = DEBRIS_METAL;
- }
- break;
-
- //
- // Crystal
- //
-
- case DNGN_GREEN_CRYSTAL_WALL: // crystal -- large & nasty explosion
- what = "crystal wall";
- blast.colour = GREEN;
- // fallthru
- case DNGN_ORANGE_CRYSTAL_STATUE:
- if (what == NULL)
- {
- what = "crystal statue";
- blast.colour = LIGHTRED; //jmf: == orange, right?
- }
-
- explode = true;
- blast.ex_size = 2;
- strcpy(blast.beam_name, "blast of crystal shards");
- blast.damage.num = 5;
-
- if (okay_to_dest
- && ((grid == DNGN_GREEN_CRYSTAL_WALL && coinflip())
- || (grid == DNGN_ORANGE_CRYSTAL_STATUE
- && pow >= 50 && one_chance_in(10))))
- {
- blast.ex_size = coinflip() ? 3 : 2;
- grd[beam.tx][beam.ty] = DNGN_FLOOR;
- debris = DEBRIS_CRYSTAL;
- }
- break;
-
- //
- // Traps
- //
-
- case DNGN_UNDISCOVERED_TRAP:
- case DNGN_TRAP_MECHANICAL:
- trap = trap_at_xy( beam.tx, beam.ty );
- if (trap != -1
- && trap_category( env.trap[trap].type ) != DNGN_TRAP_MECHANICAL)
- {
- // non-mechanical traps don't explode with this spell -- bwr
- break;
- }
-
- // undiscovered traps appear as exploding from the floor -- bwr
- what = ((grid == DNGN_UNDISCOVERED_TRAP) ? "floor" : "trap");
-
- explode = true;
- hole = false; // to hit monsters standing on traps
- strcpy( blast.beam_name, "blast of fragments" );
- blast.colour = env.floor_colour; // in order to blend in
- blast.damage.num = 2;
-
- // Exploded traps are nonfunctional, ammo is also ruined -- bwr
- if (okay_to_dest)
- {
- grd[beam.tx][beam.ty] = DNGN_FLOOR;
- env.trap[trap].type = TRAP_UNASSIGNED;
- }
- break;
-
- //
- // Stone doors and arches
- //
-
- case DNGN_OPEN_DOOR:
- case DNGN_CLOSED_DOOR:
- // Doors always blow up, stone arches never do (would cause problems)
- if (okay_to_dest)
- grd[beam.tx][beam.ty] = DNGN_FLOOR;
-
- // fall-through
- case DNGN_STONE_ARCH: // floor -- small explosion
- explode = true;
- hole = false; // to hit monsters standing on doors
- strcpy( blast.beam_name, "blast of rock fragments" );
- blast.colour = LIGHTGREY;
- blast.damage.num = 2;
- break;
-
- //
- // Permarock and floor are unaffected -- bwr
- //
- case DNGN_PERMAROCK_WALL:
- case DNGN_FLOOR:
- explode = false;
- snprintf( info, INFO_SIZE, "%s seems to be unnaturally hard.",
- (grid == DNGN_PERMAROCK_WALL) ? "That wall"
- : "The dungeon floor" );
- explode = false;
- break;
-
- case DNGN_TRAP_III: // What are these? Should they explode? -- bwr
- default:
- // FIXME: cute message for water?
- break;
- }
-
- all_done:
- if (explode && blast.damage.num > 0)
- {
- if (what != NULL)
- {
- snprintf( info, INFO_SIZE, "The %s explodes!", what);
- mpr(info);
- }
-
- explosion( blast, hole );
- }
- else if (blast.damage.num == 0)
- {
- // if damage dice are zero we assume that nothing happened at all.
- canned_msg(MSG_SPELL_FIZZLES);
- }
-
- if (debris)
- place_debris(beam.tx, beam.ty, debris);
-} // end cast_fragmentation()
-
-void cast_twist(int pow)
-{
- struct dist targ;
- struct bolt tmp; // used, but ignored
-
- // level one power cap -- bwr
- if (pow > 25)
- pow = 25;
-
- // Get target, using DIR_TARGET for targetting only,
- // since we don't use fire_beam() for this spell.
- if (spell_direction(targ, tmp, DIR_TARGET) == -1)
- return;
-
- const int mons = mgrd[ targ.tx ][ targ.ty ];
-
- // anything there?
- if (mons == NON_MONSTER || targ.isMe)
- {
- mpr("There is no monster there!");
- return;
- }
-
- // Monster can magically save vs attack.
- if (check_mons_resist_magic( &menv[ mons ], pow * 2 ))
- {
- simple_monster_message( &menv[ mons ], " resists." );
- return;
- }
-
- // Roll the damage... this spell is pretty low on damage, because
- // it can target any monster in LOS (high utility). This is
- // similar to the damage done by Magic Dart (although, the
- // distribution is much more uniform). -- bwr
- int damage = 1 + random2( 3 + pow / 5 );
-
- // Inflict the damage
- player_hurt_monster( mons, damage );
- return;
-} // end cast_twist()
-
-//
-// This version of far strike is a bit too creative for level one, in
-// order to make it work we needed to put a lot of restrictions on it
-// (like the damage limitation), which wouldn't be necessary if it were
-// a higher level spell. This code might come back as a high level
-// translocation spell later (maybe even with special effects if it's
-// using some of Josh's ideas about occasionally losing the weapon).
-// Would potentially make a good high-level, second book Warper spell
-// (since Translocations is a utility school, it should be higher level
-// that usual... especially if it turns into a flavoured smiting spell).
-// This can all wait until after the next release (as it would be better
-// to have a proper way to do a single weapon strike here (you_attack
-// does far more than we need or want here)). --bwr
-//
-
-void cast_far_strike(int pow)
-{
- struct dist targ;
- struct bolt tmp; // used, but ignored
-
- // Get target, using DIR_TARGET for targetting only,
- // since we don't use fire_beam() for this spell.
- if (spell_direction(targ, tmp, DIR_TARGET) == -1)
- return;
-
- // Get the target monster...
- if (mgrd[targ.tx][targ.ty] == NON_MONSTER
- || targ.isMe)
- {
- mpr("There is no monster there!");
- return;
- }
-
- // Start with weapon base damage...
- const int weapon = you.equip[ EQ_WEAPON ];
-
- int damage = 3; // default unarmed damage
- int speed = 10; // default unarmed time
-
- if (weapon != -1) // if not unarmed
- {
- // look up the damage base
- if (you.inv[ weapon ].base_type == OBJ_WEAPONS)
- {
- damage = property( you.inv[ weapon ], PWPN_DAMAGE );
- speed = property( you.inv[ weapon ], PWPN_SPEED );
-
- if (get_weapon_brand( you.inv[ weapon ] ) == SPWPN_SPEED)
- {
- speed *= 5;
- speed /= 10;
- }
- }
- else if (item_is_staff( you.inv[ weapon ] ))
- {
- damage = property( you.inv[ weapon ], PWPN_DAMAGE );
- speed = property( you.inv[ weapon ], PWPN_SPEED );
- }
- }
-
- // Because we're casting a spell (and don't want to make this level
- // one spell too good), we're not applying skill speed bonuses and at
- // the very least guaranteeing one full turn (speed == 10) like the
- // other spells (if any thing else related to speed is changed, at
- // least leave this right before the application to you.time_taken).
- // Leaving skill out of the speed bonus is an important part of
- // keeping this spell from becoming a "better than actual melee"
- // spell... although, it's fine if that's the case for early Warpers,
- // Fighter types, and such that pick up this trivial first level spell,
- // shouldn't be using it instead of melee (but rather as an accessory
- // long range plinker). Therefore, we tone things down to try and
- // guarantee that the spell is never begins to approach real combat
- // (although the magic resistance check might end up with a higher
- // hit rate than attacking against EV for high level Warpers). -- bwr
- if (speed < 10)
- speed = 10;
-
- you.time_taken *= speed;
- you.time_taken /= 10;
-
- // Apply strength only to damage (since we're only interested in
- // force here, not finesse... the dex/to-hit part of combat is
- // instead handled via magical ability). This part could probably
- // just be removed, as it's unlikely to make any real difference...
- // if it is, the Warper stats in newgame.cc should be changed back
- // to the standard 6 int-4 dex of spellcasters. -- bwr
- int dammod = 78;
- const int dam_stat_val = you.strength;
-
- if (dam_stat_val > 11)
- dammod += (random2(dam_stat_val - 11) * 2);
- else if (dam_stat_val < 9)
- dammod -= (random2(9 - dam_stat_val) * 3);
-
- damage *= dammod;
- damage /= 78;
-
- struct monsters *monster = &menv[ mgrd[targ.tx][targ.ty] ];
-
- // apply monster's AC
- if (monster->armour_class > 0)
- damage -= random2( 1 + monster->armour_class );
-
-#if 0
- // Removing damage limiter since it's categorized at level 4 right now.
-
- // Force transmitted is limited by skill...
- const int limit = (you.skills[SK_TRANSLOCATIONS] + 1) / 2 + 3;
- if (damage > limit)
- damage = limit;
-#endif
-
- // Roll the damage...
- damage = 1 + random2( damage );
-
- // Monster can magically save vs attack (this could be replaced or
- // augmented with an EV check).
- if (check_mons_resist_magic( monster, pow * 2 ))
- {
- simple_monster_message( monster, " resists." );
- return;
- }
-
- // Inflict the damage
- hurt_monster( monster, damage );
- if (monster->hit_points < 1)
- monster_die( monster, KILL_YOU, 0 );
- else
- print_wounds( monster );
-
- return;
-} // end cast_far_strike()
-
-void cast_apportation(int pow)
-{
- struct dist beam;
-
- mpr("Pull items from where?");
-
- direction( beam, DIR_TARGET );
-
- if (!beam.isValid)
- {
- canned_msg(MSG_SPELL_FIZZLES);
- return;
- }
-
- // it's already here!
- if (beam.isMe)
- {
- mpr( "That's just silly." );
- return;
- }
-
- // Protect the player from destroying the item
- const int grid = grd[ you.x_pos ][ you.y_pos ];
-
- if (grid == DNGN_LAVA || grid == DNGN_DEEP_WATER)
- {
- mpr( "That would be silly while over this terrain!" );
- return;
- }
-
- // If this is ever changed to allow moving objects that can't
- // be seen, it should at least only allow moving from squares
- // that have been phyisically (and maybe magically) seen and
- // should probably have a range check as well. In these cases
- // the spell should probably be upped to at least two, or three
- // if magic mapped squares are allowed. Right now it's okay
- // at one... it has a few uses, but you still have to get line
- // of sight to the object first so it will only help a little
- // with snatching runes or the orb (although it can be quite
- // useful for getting items out of statue rooms or the abyss). -- bwr
- if (!see_grid( beam.tx, beam.ty ))
- {
- mpr( "You cannot see there!" );
- return;
- }
-
- // Let's look at the top item in that square...
- const int item = igrd[ beam.tx ][ beam.ty ];
- if (item == NON_ITEM)
- {
- const int mon = mgrd[ beam.tx ][ beam.ty ];
-
- if (mon == NON_MONSTER)
- mpr( "There are no items there." );
- else if (mons_is_mimic( menv[ mon ].type ))
- {
- snprintf( info, INFO_SIZE, "%s twitches.",
- ptr_monam( &(menv[ mon ]), DESC_CAP_THE ) );
- mpr( info );
- }
- else
- mpr( "This spell does not work on creatures." );
-
- return;
- }
-
- // mass of one unit
- const int unit_mass = item_mass( mitm[ item ] );
- // assume we can pull everything
- int max_units = mitm[ item ].quantity;
-
- // item has mass: might not move all of them
- if (unit_mass > 0)
- {
- const int max_mass = pow * 30 + random2( pow * 20 );
-
- // most units our power level will allow
- max_units = max_mass / unit_mass;
- }
-
- if (max_units <= 0)
- {
- mpr( "The mass is resisting your pull." );
- return;
- }
-
- // Failure should never really happen after all the above checking,
- // but we'll handle it anyways...
- if (move_top_item( beam.tx, beam.ty, you.x_pos, you.y_pos ))
- {
- if (max_units < mitm[ item ].quantity)
- {
- mitm[ item ].quantity = max_units;
- mpr( "You feel that some mass got lost in the cosmic void." );
- }
- else
- {
- mpr( "Yoink!" );
- snprintf( info, INFO_SIZE, "You pull the item%s to yourself.",
- (mitm[ item ].quantity > 1) ? "s" : "" );
- mpr( info );
- }
- }
- else
- mpr( "The spell fails." );
-}
-
-void cast_sandblast(int pow)
-{
- bool big = true;
- struct dist spd;
- struct bolt beam;
-
- // this type of power manipulation should be done with the others,
- // currently over in it_use2.cc (ack) -- bwr
- // int hurt = 2 + random2(5) + random2(4) + random2(pow) / 20;
-
- big = false;
-
- if (you.equip[EQ_WEAPON] != -1)
- {
- int wep = you.equip[EQ_WEAPON];
- if (you.inv[wep].base_type == OBJ_MISSILES
- && (you.inv[wep].sub_type == MI_STONE || you.inv[wep].sub_type == MI_LARGE_ROCK))
- big = true;
- }
-
- if (spell_direction(spd, beam) == -1)
- return;
-
- if (spd.isMe)
- {
- canned_msg(MSG_UNTHINKING_ACT);
- return;
- }
-
- if (big)
- {
- dec_inv_item_quantity( you.equip[EQ_WEAPON], 1 );
- zapping(ZAP_SANDBLAST, pow, beam);
- }
- else
- {
- zapping(ZAP_SMALL_SANDBLAST, pow, beam);
- }
-} // end cast_sandblast()
-
-void cast_condensation_shield(int pow)
-{
- if (you.equip[EQ_SHIELD] != -1 || you.fire_shield)
- canned_msg(MSG_SPELL_FIZZLES);
- else
- {
- if (you.duration[DUR_CONDENSATION_SHIELD] > 0)
- you.duration[DUR_CONDENSATION_SHIELD] += 5 + roll_dice(2, 3);
- else
- {
- mpr("A crackling disc of dense vapour forms in the air!");
- you.redraw_armour_class = 1;
-
- you.duration[DUR_CONDENSATION_SHIELD] = 10 + roll_dice(2, pow / 5);
- }
-
- if (you.duration[DUR_CONDENSATION_SHIELD] > 30)
- you.duration[DUR_CONDENSATION_SHIELD] = 30;
- }
-
- return;
-} // end cast_condensation_shield()
-
-static int quadrant_blink(int x, int y, int pow, int garbage)
-{
- UNUSED( garbage );
-
- if (x == you.x_pos && y == you.y_pos)
- return (0);
-
- if (you.level_type == LEVEL_ABYSS)
- {
- abyss_teleport( false );
- you.pet_target = MHITNOT;
- return (1);
- }
-
- if (pow > 100)
- pow = 100;
-
- // setup: Brent's new algorithm
- // we are interested in two things: distance of a test point from
- // the ideal 'line', and the distance of a test point from two
- // actual points, one in the 'correct' direction and one in the
- // 'incorrect' direction.
-
- // scale distance by 10 for more interesting numbers.
- int l,m; // for line equation lx + my = 0
- l = (x - you.x_pos);
- m = (you.y_pos - y);
-
- int tx, ty; // test x,y
- int rx, ry; // x,y relative to you.
- int sx, sy; // test point in the correct direction
- int bx = x; // best x
- int by = y; // best y
-
- int best_dist = 10000;
-
- sx = l;
- sy = -m;
-
- // for each point (a,b), distance from the line is | la + mb |
-
- for(int tries = pow * pow / 500 + 1; tries > 0; tries--)
- {
- if (!random_near_space(you.x_pos, you.y_pos, tx, ty))
- return 0;
-
- rx = tx - you.x_pos;
- ry = ty - you.y_pos;
-
- int dist = l * rx + m * ry;
- dist *= 10 * dist; // square and multiply by 10
-
- // check distance to test points
- int dist1 = distance(rx, ry, sx, sy) * 10;
- int dist2 = distance(rx, ry, -sx, -sy) * 10;
-
- // 'good' points will always be closer to test point 1
- if (dist2 < dist1)
- dist += 80; // make the point less attractive
-
- if (dist < best_dist)
- {
- best_dist = dist;
- bx = tx;
- by = ty;
- }
- }
-
- you.x_pos = bx;
- you.y_pos = by;
-
- return (1);
-}
-
-void cast_semi_controlled_blink(int pow)
-{
- apply_one_neighbouring_square(quadrant_blink, pow);
- return;
-}
-
-void cast_stoneskin(int pow)
-{
- if (you.is_undead)
- {
- mpr("This spell does not affect your undead flesh.");
- return;
- }
-
- if (you.attribute[ATTR_TRANSFORMATION] != TRAN_NONE
- && you.attribute[ATTR_TRANSFORMATION] != TRAN_STATUE
- && you.attribute[ATTR_TRANSFORMATION] != TRAN_BLADE_HANDS)
- {
- mpr("This spell does not affect your current form.");
- return;
- }
-
- if (you.duration[DUR_STONEMAIL] || you.duration[DUR_ICY_ARMOUR])
- {
- mpr("This spell conflicts with another spell still in effect.");
- return;
- }
-
- if (you.duration[DUR_STONESKIN])
- mpr( "Your skin feels harder." );
- else
- {
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_STATUE)
- mpr( "Your stone body feels more resilient." );
- else
- mpr( "Your skin hardens." );
-
- you.redraw_armour_class = 1;
- }
-
- you.duration[DUR_STONESKIN] += 10 + random2(pow) + random2(pow);
-
- if (you.duration[DUR_STONESKIN] > 50)
- you.duration[DUR_STONESKIN] = 50;
-}
diff --git a/stone_soup/crawl-ref/source/spells4.h b/stone_soup/crawl-ref/source/spells4.h
deleted file mode 100644
index d34f83e87a..0000000000
--- a/stone_soup/crawl-ref/source/spells4.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * File: spells4.cc
- * Summary: Yet More Spell Function Declarations
- * Written by: Josh Fishman
- *
- * Change History (most recent first):
- * <2> 12jul2000 jmf Fixed random (undocumented) damage
- * <1> 07jan2000 jmf Created
- */
-
-
-#ifndef SPELLS4_H
-#define SPELLS4_H
-
-#include "externs.h"
-
-const char *your_hand(bool plural);
-bool backlight_monsters(int x, int y, int pow, int garbage);
-int make_a_normal_cloud(int x, int y, int pow, int ctype);
-int disperse_monsters(int x, int y, int pow, int message);
-
-void cast_bend(int pow);
-void cast_condensation_shield(int pow);
-void cast_detect_secret_doors(int pow);
-void cast_discharge(int pow);
-void cast_evaporate(int pow);
-void cast_fulsome_distillation(int powc);
-void cast_forescry(int pow);
-void cast_fragmentation(int powc);
-void cast_twist(int powc);
-void cast_far_strike(int powc);
-void cast_swap(int powc);
-void cast_apportation(int powc);
-void cast_glamour(int pow);
-void cast_ignite_poison(int pow);
-void cast_intoxicate(int pow);
-void cast_mass_sleep(int pow);
-void cast_passwall(int pow);
-void cast_rotting(int pow);
-void cast_sandblast(int powc);
-void cast_see_invisible(int pow);
-
-void cast_shatter(int pow);
-void cast_silence(int pow);
-void cast_sticks_to_snakes(int pow);
-void cast_summon_butterflies(int pow);
-void cast_summon_dragon(int pow);
-void cast_chain_lightning( int pow );
-void cast_conjure_ball_lightning(int pow);
-void cast_summon_large_mammal(int pow);
-void cast_tame_beasts(int pow);
-void cast_dispersal(int pow);
-void cast_snake_charm(int pow);
-void cast_stoneskin(int pow);
-
-void cast_shuggoth_seed(int powc);
-void make_shuggoth(int x, int y, int hp);
-
-void cast_semi_controlled_blink(int pow);
-
-
-#endif
diff --git a/stone_soup/crawl-ref/source/spl-book.cc b/stone_soup/crawl-ref/source/spl-book.cc
deleted file mode 100644
index 302afdab4c..0000000000
--- a/stone_soup/crawl-ref/source/spl-book.cc
+++ /dev/null
@@ -1,1597 +0,0 @@
-/*
- * File: spl-book.cc
- * Summary: Spellbook/Staff contents array and management functions
- * Written by: Josh Fishman
- *
- * Change History (most recent first):
- *
- * 24jun2000 jmf Changes to many books; addition of Assassinations;
- * alteration of type-printout to match new bitfield.
- * <1> 19mar2000 jmf Created by taking stuff from dungeon.cc, spells0.cc,
- * spells.cc, shopping.cc
- */
-
-#include "AppHdr.h"
-#include "spl-book.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#ifdef DOS
-#include <conio.h>
-#endif
-
-#include "externs.h"
-
-#include "debug.h"
-#include "delay.h"
-#include "food.h"
-#include "invent.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "items.h"
-#include "it_use3.h"
-#include "player.h"
-#include "religion.h"
-#include "spl-cast.h"
-#include "spl-util.h"
-#include "stuff.h"
-
-static int spellbook_template_array[NUMBER_SPELLBOOKS][SPELLBOOK_SIZE] =
-{
- // 0 - Minor Magic I
- {0,
- SPELL_MAGIC_DART,
- SPELL_SUMMON_SMALL_MAMMAL,
- SPELL_THROW_FLAME,
- SPELL_BLINK,
- SPELL_SLOW,
- SPELL_MEPHITIC_CLOUD,
- SPELL_CONJURE_FLAME,
- SPELL_NO_SPELL,
- },
- // 1 - Minor Magic II
- {0,
- SPELL_MAGIC_DART,
- SPELL_THROW_FROST,
- SPELL_BLINK,
- SPELL_STICKS_TO_SNAKES,
- SPELL_SLOW,
- SPELL_MEPHITIC_CLOUD,
- SPELL_OZOCUBUS_ARMOUR,
- SPELL_NO_SPELL,
- },
- // 2 - Minor Magic III
- {0,
- SPELL_MAGIC_DART,
- SPELL_SUMMON_SMALL_MAMMAL,
- SPELL_BLINK,
- SPELL_REPEL_MISSILES,
- SPELL_SLOW,
- SPELL_SUMMON_LARGE_MAMMAL,
- SPELL_MEPHITIC_CLOUD,
- SPELL_NO_SPELL,
- },
- // 3 - Book of Conjurations I - Fire and Earth
- {0,
- SPELL_MAGIC_DART,
- SPELL_THROW_FLAME,
- SPELL_STONE_ARROW,
- SPELL_CONJURE_FLAME,
- SPELL_BOLT_OF_MAGMA,
- SPELL_FIREBALL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 4 - Book of Conjurations II - Air and Ice
- {0,
- SPELL_MAGIC_DART,
- SPELL_THROW_FROST,
- SPELL_MEPHITIC_CLOUD,
- SPELL_DISCHARGE,
- SPELL_BOLT_OF_COLD,
- SPELL_FREEZING_CLOUD,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 5 - Book of Flames
- {0,
- SPELL_FLAME_TONGUE,
- SPELL_THROW_FLAME,
- SPELL_CONJURE_FLAME,
- SPELL_STICKY_FLAME,
- SPELL_BOLT_OF_FIRE,
- SPELL_FIREBALL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 6 - Book of Frost
- {0,
- SPELL_FREEZE,
- SPELL_THROW_FROST,
- SPELL_OZOCUBUS_ARMOUR,
- SPELL_ICE_BOLT,
- SPELL_SUMMON_ICE_BEAST,
- SPELL_FREEZING_CLOUD,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 7 - Book of Summonings
- {0,
- SPELL_ABJURATION_I,
- SPELL_RECALL,
- SPELL_SUMMON_LARGE_MAMMAL,
- SPELL_SHADOW_CREATURES,
- SPELL_SUMMON_WRAITHS,
- SPELL_SUMMON_HORRIBLE_THINGS,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 8 - Book of Fire
- {0,
- SPELL_EVAPORATE,
- SPELL_FIRE_BRAND,
- SPELL_SUMMON_ELEMENTAL,
- SPELL_BOLT_OF_MAGMA,
- SPELL_DELAYED_FIREBALL,
- SPELL_IGNITE_POISON,
- SPELL_RING_OF_FLAMES,
- SPELL_NO_SPELL,
- },
- // 9 - Book of Ice
- {0,
- SPELL_FREEZING_AURA,
- SPELL_SLEEP,
- SPELL_CONDENSATION_SHIELD,
- SPELL_BOLT_OF_COLD,
- SPELL_OZOCUBUS_REFRIGERATION,
- SPELL_SIMULACRUM,
- SPELL_MASS_SLEEP,
- SPELL_NO_SPELL,
- },
-
- // 10 - Book of Surveyances
- {0,
- SPELL_DETECT_SECRET_DOORS,
- SPELL_DETECT_TRAPS,
- SPELL_DETECT_ITEMS,
- SPELL_MAGIC_MAPPING,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL
- },
- // 11 - Book of Spatial Translocations
- {0,
- SPELL_APPORTATION,
- SPELL_BLINK,
- SPELL_RECALL,
- SPELL_TELEPORT_OTHER,
- SPELL_TELEPORT_SELF,
- SPELL_CONTROL_TELEPORT,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 12 - Book of Enchantments (fourth one)
- {0,
- SPELL_LEVITATION,
- SPELL_SELECTIVE_AMNESIA,
- SPELL_REMOVE_CURSE,
- SPELL_CAUSE_FEAR,
- SPELL_EXTENSION,
- SPELL_DEFLECT_MISSILES,
- SPELL_HASTE,
- SPELL_NO_SPELL,
- },
- // 13 - Young Poisoner's Handbook
- {0,
- SPELL_STING,
- SPELL_CURE_POISON_II,
- SPELL_MEPHITIC_CLOUD,
- SPELL_POISON_WEAPON,
- SPELL_VENOM_BOLT,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 14 - Book of the Tempests
- {0,
- SPELL_DISCHARGE,
- SPELL_LIGHTNING_BOLT,
- SPELL_FIREBALL,
- SPELL_SHATTER,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 15 - Book of Death
- {0,
- SPELL_CORPSE_ROT,
- SPELL_BONE_SHARDS,
- SPELL_LETHAL_INFUSION,
- SPELL_AGONY,
- SPELL_BOLT_OF_DRAINING,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 16 - Book of Hinderance
- {0,
- SPELL_CONFUSING_TOUCH,
- SPELL_SLOW,
- SPELL_CONFUSE,
- SPELL_PARALYZE,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 17 - Book of Changes
- {0,
- SPELL_FULSOME_DISTILLATION,
- SPELL_STICKS_TO_SNAKES,
- SPELL_EVAPORATE,
- SPELL_SPIDER_FORM,
- SPELL_ICE_FORM,
- SPELL_DIG,
- SPELL_BLADE_HANDS,
- SPELL_NO_SPELL,
- },
- // 18 - Book of Transfigurations
- {0,
- SPELL_SANDBLAST,
- SPELL_POLYMORPH_OTHER,
- SPELL_STATUE_FORM,
- SPELL_ALTER_SELF,
- SPELL_DRAGON_FORM,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 19 - Book of Practical Magic
- {0,
- SPELL_PROJECTED_NOISE,
- SPELL_SELECTIVE_AMNESIA,
- SPELL_DETECT_CURSE,
- SPELL_DIG,
- SPELL_REMOVE_CURSE,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
-
- // 20 - Book of War Chants
- {0,
- SPELL_FIRE_BRAND,
- SPELL_FREEZING_AURA,
- SPELL_REPEL_MISSILES,
- SPELL_BERSERKER_RAGE,
- SPELL_REGENERATION,
- SPELL_HASTE,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 21 - Book of Clouds
- {0,
- SPELL_EVAPORATE,
- SPELL_MEPHITIC_CLOUD,
- SPELL_CONJURE_FLAME,
- SPELL_POISONOUS_CLOUD,
- SPELL_FREEZING_CLOUD,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 22 - Book of Healing
- {0,
- SPELL_CURE_POISON_I,
- SPELL_LESSER_HEALING,
- SPELL_GREATER_HEALING,
- SPELL_PURIFICATION,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 23 - Book of Necromancy
- {0,
- SPELL_PAIN,
- SPELL_ANIMATE_SKELETON,
- SPELL_VAMPIRIC_DRAINING,
- SPELL_REGENERATION,
- SPELL_DISPEL_UNDEAD,
- SPELL_ANIMATE_DEAD,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 24 - Necronomicon -- Kikubaaqudgha special
- {0,
- SPELL_SYMBOL_OF_TORMENT,
- SPELL_CONTROL_UNDEAD,
- SPELL_SUMMON_WRAITHS,
- SPELL_DEATHS_DOOR,
- SPELL_NECROMUTATION,
- SPELL_DEATH_CHANNEL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 25 - Book of Callings
- {0,
- SPELL_SUMMON_SMALL_MAMMAL,
- SPELL_STICKS_TO_SNAKES,
- SPELL_CALL_IMP,
- SPELL_SUMMON_ELEMENTAL,
- SPELL_SUMMON_SCORPIONS,
- SPELL_SUMMON_ICE_BEAST,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 26 - Book of Charms
- {0,
- SPELL_BACKLIGHT,
- SPELL_REPEL_MISSILES,
- SPELL_SLEEP,
- SPELL_CONFUSE,
- SPELL_ENSLAVEMENT,
- SPELL_SILENCE,
- SPELL_INVISIBILITY,
- SPELL_NO_SPELL,
- },
- // 27 - Book of Demonology -- Vehumet special
- {0,
- SPELL_ABJURATION_I,
- SPELL_RECALL,
- SPELL_CALL_IMP,
- SPELL_SUMMON_DEMON,
- SPELL_DEMONIC_HORDE,
- SPELL_SUMMON_GREATER_DEMON,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 28 - Book of Air
- {0,
- SPELL_SHOCK,
- SPELL_SWIFTNESS,
- SPELL_REPEL_MISSILES,
- SPELL_LEVITATION,
- SPELL_MEPHITIC_CLOUD,
- SPELL_DISCHARGE,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
-
- // Removing Air Walk... it's currently broken in a number or ways:
- // - the AC/EV bonus probably means very little to any character
- // capable of casting a level nine spell
- // - the penalty of dropping inventory is a bit harsh considering
- // the above
- // - the fire/ice susceptibility doesn't work... the AC/EV bonus
- // cancel it out (so you'd hardly be wary of them since they
- // can't really do any damage).
- // - there is no need for another invulnerability spell (which is
- // what this spell is trying to be), one is more than enough...
- // let people use necromancy.
- // - there is no need for another air spell... air spells are
- // already very common (ie. this level nine spell occured in
- // two books!)
-
- // 29 - Book of the Sky
- {0,
- SPELL_SUMMON_ELEMENTAL,
- SPELL_INSULATION,
- SPELL_AIRSTRIKE,
- SPELL_FLY,
- SPELL_SILENCE,
- SPELL_DEFLECT_MISSILES,
- SPELL_LIGHTNING_BOLT,
- SPELL_CONJURE_BALL_LIGHTNING,
- },
-
- // 30 - Book of Divinations
- {0,
- SPELL_DETECT_SECRET_DOORS,
- SPELL_DETECT_CREATURES,
- SPELL_DETECT_ITEMS,
- SPELL_DETECT_CURSE,
- SPELL_SEE_INVISIBLE,
- SPELL_FORESCRY,
- SPELL_IDENTIFY,
- SPELL_NO_SPELL,
- },
- // 31 - Book of the Warp
- {0,
- SPELL_BANISHMENT,
- SPELL_WARP_BRAND,
- SPELL_DISPERSAL,
- SPELL_PORTAL,
- SPELL_CONTROLLED_BLINK,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 32 - Book of Envenomations
- {0,
- SPELL_SPIDER_FORM,
- SPELL_POISON_AMMUNITION,
- SPELL_SUMMON_SCORPIONS,
- SPELL_RESIST_POISON,
- SPELL_OLGREBS_TOXIC_RADIANCE,
- SPELL_POISONOUS_CLOUD,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 33 - Book of Annihilations -- Vehumet special
- {0,
- SPELL_ISKENDERUNS_MYSTIC_BLAST,
- SPELL_POISON_ARROW,
- SPELL_CHAIN_LIGHTNING,
- SPELL_LEHUDIBS_CRYSTAL_SPEAR,
- SPELL_ICE_STORM,
- SPELL_FIRE_STORM,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 34 - Book of Unlife
- {0,
- SPELL_SUBLIMATION_OF_BLOOD,
- SPELL_ANIMATE_DEAD,
- SPELL_TWISTED_RESURRECTION,
- SPELL_BORGNJORS_REVIVIFICATION,
- SPELL_SIMULACRUM,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
-
- // 35 - Tome of Destruction
- {0,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 36 - Book of Control
- {0,
- SPELL_ENSLAVEMENT,
- SPELL_TAME_BEASTS,
- SPELL_MASS_CONFUSION,
- SPELL_CONTROL_UNDEAD,
- SPELL_CONTROL_TELEPORT,
- SPELL_MASS_SLEEP,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 37 - Book of Mutations //jmf: now Morphology
- {0,
- SPELL_FRAGMENTATION,
- SPELL_POLYMORPH_OTHER,
- SPELL_ALTER_SELF,
- SPELL_CIGOTUVIS_DEGENERATION,
- // SPELL_IGNITE_POISON, // moved to Fire which was a bit slim -- bwr
- SPELL_SHATTER,
- // SPELL_AIR_WALK,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 38 - Book of Tukima
- {0,
- SPELL_SURE_BLADE,
- SPELL_TUKIMAS_VORPAL_BLADE,
- SPELL_TUKIMAS_DANCE,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 39 - Book of Geomancy
- {0,
- SPELL_SANDBLAST,
- SPELL_STONESKIN,
- SPELL_PASSWALL,
- SPELL_STONE_ARROW,
- SPELL_SUMMON_ELEMENTAL,
- SPELL_FRAGMENTATION,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
-
- // 40 - Book of Earth
- {0,
- // SPELL_MAXWELLS_SILVER_HAMMER,
- SPELL_MAGIC_MAPPING,
- SPELL_DIG,
- SPELL_STATUE_FORM,
- SPELL_BOLT_OF_IRON,
- SPELL_TOMB_OF_DOROKLOHE,
- SPELL_SHATTER,
- SPELL_NO_SPELL,
- },
- // 41 - manuals of all kinds
- {0,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 42 - Book of Wizardry
- {0,
- SPELL_DETECT_CREATURES,
- SPELL_SUMMON_ELEMENTAL,
- SPELL_MAGIC_MAPPING,
- SPELL_TELEPORT_SELF,
- SPELL_FIREBALL,
- SPELL_IDENTIFY,
- SPELL_HASTE,
- SPELL_NO_SPELL,
- },
- // 43 - Book of Power
- {0,
- SPELL_ANIMATE_DEAD,
- SPELL_TELEPORT_OTHER,
- SPELL_VENOM_BOLT,
- SPELL_BOLT_OF_IRON,
- SPELL_INVISIBILITY,
- SPELL_MASS_CONFUSION,
- SPELL_POISONOUS_CLOUD,
- SPELL_NO_SPELL,
- },
- // 44 - Book of Cantrips //jmf: added 04jan2000
- {0,
- SPELL_CONFUSING_TOUCH,
- SPELL_ANIMATE_SKELETON,
- SPELL_SUMMON_SMALL_MAMMAL,
- SPELL_DETECT_SECRET_DOORS,
- SPELL_APPORTATION,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
-
- // 45 - Book of Party Tricks //jmf: added 04jan2000
- {0,
- SPELL_SUMMON_BUTTERFLIES,
- SPELL_APPORTATION,
- SPELL_PROJECTED_NOISE,
- SPELL_BLINK,
- SPELL_LEVITATION,
- SPELL_INTOXICATE,
- SPELL_NO_SPELL, //jmf: SPELL_ERINGYAS_SURPRISING_BOUQUET, when finished
- SPELL_NO_SPELL,
- },
-
- // 46 - Book of Beasts //jmf: added 19mar2000
- {0,
- SPELL_SUMMON_SMALL_MAMMAL,
- SPELL_STICKS_TO_SNAKES,
- SPELL_DETECT_CREATURES,
- SPELL_SUMMON_LARGE_MAMMAL,
- SPELL_TAME_BEASTS,
- SPELL_DRAGON_FORM,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
-
- // 47 - Book of Stalking //jmf: 24jun2000
- {0,
- SPELL_STING,
- SPELL_SURE_BLADE,
- SPELL_PROJECTED_NOISE,
- SPELL_MEPHITIC_CLOUD,
- SPELL_POISON_WEAPON,
- SPELL_PARALYZE,
- SPELL_INVISIBILITY,
- SPELL_NO_SPELL,
- },
-
- // 48 -- unused
- {0,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
-
- // 49 - unused
- {0,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
-
- // 50 - Staff of Smiting //jmf: totally obsolete --- no longer looks here.
- {0,
- SPELL_SMITING,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 51 - Staff of Summoning
- {0,
- SPELL_ABJURATION_I,
- SPELL_RECALL,
- SPELL_SUMMON_ELEMENTAL,
- SPELL_SWARM,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 52 - Staff of Destruction
- {0,
- SPELL_THROW_FLAME,
- SPELL_BOLT_OF_FIRE,
- SPELL_FIREBALL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 53 - Staff of Destruction
- {0,
- SPELL_THROW_FROST,
- SPELL_ICE_BOLT,
- SPELL_FREEZING_CLOUD,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 54 - Staff of Destruction
- {0,
- SPELL_BOLT_OF_IRON,
- SPELL_FIREBALL,
- SPELL_LIGHTNING_BOLT,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 55 - Staff of Destruction
- {0,
- SPELL_BOLT_OF_INACCURACY,
- SPELL_BOLT_OF_MAGMA,
- SPELL_BOLT_OF_COLD,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 56 - Staff of Warding
- {0,
- SPELL_ABJURATION_I,
- SPELL_CONDENSATION_SHIELD,
- SPELL_CAUSE_FEAR,
- SPELL_DEFLECT_MISSILES,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 57 - Staff of Exploration
- {0,
- SPELL_DETECT_SECRET_DOORS,
- SPELL_DETECT_TRAPS,
- SPELL_DETECT_ITEMS,
- SPELL_MAGIC_MAPPING,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 58 - Staff of Demonology
- {0,
- SPELL_ABJURATION_I,
- SPELL_RECALL,
- SPELL_CALL_IMP,
- SPELL_SUMMON_DEMON,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
- // 59 - Staff of Striking -- unused like Smiting
- {0,
- SPELL_STRIKING,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- SPELL_NO_SPELL,
- },
-};
-
-static void spellbook_template( int sbook_type,
- FixedVector < int, SPELLBOOK_SIZE > &sbtemplate_pass )
-{
- ASSERT( sbook_type >= 0 );
- ASSERT( sbook_type < NUMBER_SPELLBOOKS );
-
- // no point doing anything if tome of destruction or a manual
- if (sbook_type == BOOK_DESTRUCTION || sbook_type == BOOK_MANUAL)
- return;
-
- for (int i = 0; i < SPELLBOOK_SIZE; i++) //jmf: was i = 1
- {
- sbtemplate_pass[i] = spellbook_template_array[sbook_type][i];
- }
-} // end spellbook_template()
-
-int which_spell_in_book(int sbook_type, int spl)
-{
- FixedVector < int, SPELLBOOK_SIZE > wsib_pass; // was 10 {dlb}
-
- spellbook_template(sbook_type, wsib_pass);
-
- return (wsib_pass[ spl + 1 ]);
-} // end which_spell_in_book()
-
-// If fs is not NULL, updates will be to the formatted_string instead of
-// the display.
-unsigned char spellbook_contents( item_def &book, int action,
- formatted_string *fs )
-{
- FixedVector<int, SPELLBOOK_SIZE> spell_types; // was 10 {dlb}
- int spelcount = 0;
- int i, j;
- bool update_screen = !fs;
-
- const int spell_levels = player_spell_levels();
-
- // special case for staves
- const int type = (book.base_type == OBJ_STAVES) ? book.sub_type + 40
- : book.sub_type;
-
- bool spell_skills = false;
-
- for (i = SK_SPELLCASTING; i <= SK_POISON_MAGIC; i++)
- {
- if (you.skills[i])
- {
- spell_skills = true;
- break;
- }
- }
-
- set_ident_flags( book, ISFLAG_KNOW_TYPE );
-
- spellbook_template( type, spell_types );
-
- formatted_string out;
- out.textcolor(LIGHTGREY);
-
- char str_pass[ ITEMNAME_SIZE ];
- item_name( book, DESC_CAP_THE, str_pass );
- out.cprintf( str_pass );
-
- out.cprintf( EOL EOL " Spells Type Level" EOL );
-
- for (j = 1; j < SPELLBOOK_SIZE; j++)
- {
- if (spell_types[j] == SPELL_NO_SPELL)
- continue;
-
- out.cprintf(" ");
-
- bool knowsSpell = false;
- for (i = 0; i < 25 && !knowsSpell; i++)
- {
- knowsSpell = (you.spells[i] == spell_types[j]);
- }
-
- const int level_diff = spell_difficulty( spell_types[j] );
- const int levels_req = spell_levels_required( spell_types[j] );
-
- int colour = DARKGREY;
- if (action == RBOOK_USE_STAFF)
- {
- if (you.experience_level >= level_diff
- && you.magic_points >= level_diff)
- {
- colour = LIGHTGREY;
- }
- }
- else
- {
- if (knowsSpell)
- colour = LIGHTGREY;
- else if (you.experience_level >= level_diff
- && spell_levels >= levels_req
- && spell_skills)
- {
- colour = LIGHTBLUE;
- }
- }
-
- out.textcolor( colour );
-
- // Old:
- // textcolor(knowsSpell ? DARKGREY : LIGHTGREY);
- // was: ? LIGHTGREY : LIGHTBLUE
-
- char strng[2];
-
- strng[0] = index_to_letter(spelcount);
- strng[1] = '\0';
-
- out.cprintf(strng);
- out.cprintf(" - ");
-
- out.cprintf( spell_title(spell_types[j]) );
- out.gotoxy( 35, -1 );
-
-
- if (action == RBOOK_USE_STAFF)
- out.cprintf( "Evocations" );
- else
- {
- bool already = false;
-
- for (i = 0; i <= SPTYP_LAST_EXPONENT; i++)
- {
- if (spell_typematch( spell_types[j], 1 << i ))
- {
- if (already)
- out.cprintf( "/" );
-
- out.cprintf( spelltype_name( 1 << i ) );
- already = true;
- }
- }
- }
-
- out.gotoxy( 65, -1 );
-
- char sval[3];
-
- itoa( level_diff, sval, 10 );
- out.cprintf( sval );
- out.cprintf( EOL );
- spelcount++;
- }
-
- out.textcolor(LIGHTGREY);
- out.cprintf(EOL);
-
- switch (action)
- {
- case RBOOK_USE_STAFF:
- out.cprintf( "Select a spell to cast." EOL );
- break;
-
- case RBOOK_MEMORISE:
- out.cprintf( "Select a spell to memorise (%d level%s available)." EOL,
- spell_levels, (spell_levels == 1) ? "" : "s" );
- break;
-
- case RBOOK_READ_SPELL:
- out.cprintf( "Select a spell to read its description." EOL );
- break;
-
- default:
- break;
- }
-
- if (fs)
- *fs = out;
-
- unsigned char keyn = 0;
- if (update_screen)
- {
-#ifdef DOS_TERM
- char buffer[4800];
- gettext(1, 1, 80, 25, buffer);
- window(1, 1, 80, 25);
-#endif
- clrscr();
-
- out.display();
-
- keyn = getch();
- if (keyn == 0)
- getch();
-
-#ifdef DOS_TERM
- puttext(1, 1, 80, 25, buffer);
- window(1, 18, 80, 25);
-#endif
- }
-
- return (keyn); // try to figure out that for which this is used {dlb}
-}
-
-//jmf: was in shopping.cc
-char book_rarity(unsigned char which_book)
-{
- switch (which_book)
- {
- case BOOK_MINOR_MAGIC_I:
- case BOOK_MINOR_MAGIC_II:
- case BOOK_MINOR_MAGIC_III:
- case BOOK_SURVEYANCES:
- case BOOK_HINDERANCE:
- case BOOK_CANTRIPS: //jmf: added 04jan2000
- return 1;
-
- case BOOK_CHANGES:
- case BOOK_CHARMS:
- return 2;
-
- case BOOK_CONJURATIONS_I:
- case BOOK_CONJURATIONS_II:
- case BOOK_PRACTICAL_MAGIC:
- case BOOK_NECROMANCY:
- case BOOK_CALLINGS:
- case BOOK_WIZARDRY:
- return 3;
-
- case BOOK_FLAMES:
- case BOOK_FROST:
- case BOOK_AIR:
- case BOOK_GEOMANCY:
- return 4;
-
- case BOOK_YOUNG_POISONERS:
- case BOOK_STALKING: //jmf: added 24jun2000
- case BOOK_WAR_CHANTS:
- return 5;
-
- case BOOK_CLOUDS:
- case BOOK_POWER:
- return 6;
-
- case BOOK_ENCHANTMENTS:
- case BOOK_PARTY_TRICKS: //jmf: added 04jan2000
- return 7;
-
- case BOOK_TRANSFIGURATIONS:
- case BOOK_DIVINATIONS:
- return 8;
-
- case BOOK_FIRE:
- case BOOK_ICE:
- case BOOK_SKY:
- case BOOK_EARTH:
- case BOOK_UNLIFE:
- case BOOK_CONTROL:
- case BOOK_SPATIAL_TRANSLOCATIONS:
- return 10;
-
- case BOOK_TEMPESTS:
- case BOOK_DEATH:
- return 11;
-
- case BOOK_MUTATIONS:
- case BOOK_BEASTS: //jmf: added 23mar2000
- return 12;
-
- case BOOK_ENVENOMATIONS:
- case BOOK_WARP:
- return 15;
-
- case BOOK_TUKIMA:
- return 16;
-
- case BOOK_SUMMONINGS:
- return 18;
-
- case BOOK_ANNIHILATIONS: // Vehumet special
- case BOOK_DEMONOLOGY: // Vehumet special
- case BOOK_NECRONOMICON: // Kikubaaqudgha special
- case BOOK_MANUAL:
- return 20;
-
- case BOOK_DESTRUCTION:
- return 30;
-
- case BOOK_HEALING:
- return 100;
-
- default:
- return 1;
- }
-} // end book_rarity()
-
-bool is_valid_spell_in_book( unsigned int splbook, int spell )
-{
- FixedVector< int, SPELLBOOK_SIZE > spells;
-
- spellbook_template( you.inv[ splbook ].sub_type, spells );
-
- if (spells[ spell ] != SPELL_NO_SPELL)
- return true;
-
- return false;
-} // end is_valid_spell_in_book()
-
-static bool which_spellbook( int &book, int &spell )
-{
- const int avail_levels = player_spell_levels();
-
- // Knowing delayed fireball will allow Fireball to be learned for free -bwr
- if (avail_levels < 1 && !player_has_spell(SPELL_DELAYED_FIREBALL))
- {
- mpr("You can't memorise any more spells yet.");
- return (false);
- }
- else if (inv_count() < 1)
- {
- canned_msg(MSG_NOTHING_CARRIED);
- return (false);
- }
-
- snprintf( info, INFO_SIZE, "You can memorise %d more level%s of spells.",
- avail_levels, (avail_levels > 1) ? "s" : "" );
-
- mpr( info );
-
- book = prompt_invent_item( "Memorise from which spellbook?", OBJ_BOOKS );
- if (book == PROMPT_ABORT)
- {
- canned_msg( MSG_OK );
- return (false);
- }
-
- if (you.inv[book].base_type != OBJ_BOOKS
- || you.inv[book].sub_type == BOOK_MANUAL)
- {
- mpr("That isn't a spellbook!");
- return (false);
- }
-
- if (you.inv[book].sub_type == BOOK_DESTRUCTION)
- {
- tome_of_power( book );
- return (false);
- }
-
- spell = read_book( you.inv[book], RBOOK_MEMORISE );
- clrscr();
-
- return (true);
-} // end which_spellbook()
-
-// Returns false if the player cannot read/memorize from the book,
-// and true otherwise. -- bwr
-static bool player_can_read_spellbook( const item_def &book )
-{
- if (book.base_type != OBJ_BOOKS)
- return (true);
-
- if ((book.sub_type == BOOK_ANNIHILATIONS
- && you.religion != GOD_VEHUMET
- && (you.skills[SK_CONJURATIONS] < 10
- || you.skills[SK_SPELLCASTING] < 10))
- || (book.sub_type == BOOK_DEMONOLOGY
- && you.religion != GOD_VEHUMET
- && (you.skills[SK_SUMMONINGS] < 10
- || you.skills[SK_SPELLCASTING] < 10))
- || (book.sub_type == BOOK_NECRONOMICON
- && you.religion != GOD_KIKUBAAQUDGHA
- && (you.skills[SK_NECROMANCY] < 10
- || you.skills[SK_SPELLCASTING] < 10)))
- {
- return (false);
- }
-
- return (true);
-}
-
-unsigned char read_book( item_def &book, int action )
-{
- unsigned char key2 = 0;
-
- if (book.base_type == OBJ_BOOKS && !player_can_read_spellbook( book ))
- {
- mpr( "This book is beyond your current level of understanding." );
- more();
- return (0);
- }
-
- // remember that this function is called from staff spells as well:
- key2 = spellbook_contents( book, action );
-
- if (book.base_type == OBJ_BOOKS)
- {
- you.had_book[ book.sub_type ] = 1;
-
- if ( book.sub_type == BOOK_MINOR_MAGIC_I
- || book.sub_type == BOOK_MINOR_MAGIC_II
- || book.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;
- }
- else if (book.sub_type == BOOK_CONJURATIONS_I
- || book.sub_type == BOOK_CONJURATIONS_II)
- {
- you.had_book[BOOK_CONJURATIONS_I] = 1;
- you.had_book[BOOK_CONJURATIONS_II] = 1;
- }
- }
-
- redraw_screen();
-
- /* Put special book effects in another function which can be called from
- memorise as well */
-
- // reading spell descriptions doesn't take time:
- if (action != RBOOK_READ_SPELL)
- you.turn_is_over = 1;
-
- set_ident_flags( book, ISFLAG_KNOW_TYPE );
-
- return (key2);
-} // end read_book()
-
-// recoded to answer whether an UNDEAD_STATE is
-// barred from a particular spell passed to the
-// function - note that the function can be expanded
-// to prevent memorisation of certain spells by
-// the living by setting up an US_ALIVE case returning
-// a value of false for a set of spells ... might be
-// an idea worth further consideration - 12mar2000 {dlb}
-bool undead_cannot_memorise(unsigned char spell, unsigned char being)
-{
- switch (being)
- {
- case US_HUNGRY_DEAD:
- switch (spell)
- {
- //case SPELL_REGENERATION:
- case SPELL_BORGNJORS_REVIVIFICATION:
- case SPELL_CURE_POISON_II:
- case SPELL_DEATHS_DOOR:
- case SPELL_NECROMUTATION:
- case SPELL_RESIST_POISON:
- case SPELL_SYMBOL_OF_TORMENT:
- case SPELL_TAME_BEASTS:
- case SPELL_BERSERKER_RAGE:
- return true;
- }
- break;
-
- case US_UNDEAD:
- switch (spell)
- {
- case SPELL_AIR_WALK:
- case SPELL_ALTER_SELF:
- case SPELL_BLADE_HANDS:
- case SPELL_BORGNJORS_REVIVIFICATION:
- case SPELL_CURE_POISON_II:
- case SPELL_DEATHS_DOOR:
- case SPELL_DRAGON_FORM:
- case SPELL_GLAMOUR:
- case SPELL_ICE_FORM:
- case SPELL_INTOXICATE:
- case SPELL_NECROMUTATION:
- case SPELL_PASSWALL:
- case SPELL_REGENERATION:
- case SPELL_RESIST_POISON:
- case SPELL_SPIDER_FORM:
- case SPELL_STATUE_FORM:
- case SPELL_SUMMON_HORRIBLE_THINGS:
- case SPELL_SYMBOL_OF_TORMENT:
- case SPELL_TAME_BEASTS:
- case SPELL_BERSERKER_RAGE:
- return true;
- }
- break;
- }
-
- return false;
-} // end undead_cannot_memorise()
-
-bool learn_spell(void)
-{
- int chance = 0;
- int levels_needed = 0;
- unsigned char keyin;
- int book, spell;
- int index;
-
- int i;
- int j = 0;
-
- for (i = SK_SPELLCASTING; i <= SK_POISON_MAGIC; i++)
- {
- if (you.skills[i])
- j++;
- }
-
- if (j == 0)
- {
- mpr("You can't use spell magic! I'm afraid it's scrolls only for now.");
- return (false);
- }
-
- if (!which_spellbook( book, spell ))
- return (false);
-
- if (spell < 'A' || (spell > 'Z' && spell < 'a') || spell > 'z')
- {
- whatt:
- redraw_screen();
- mpr("What?");
- return (false);
- }
-
- index = letter_to_index( spell );
-
- if (index >= SPELLBOOK_SIZE)
- goto whatt;
-
- if (!is_valid_spell_in_book( book, index ))
- goto whatt;
-
- unsigned int specspell = which_spell_in_book(you.inv[book].sub_type,index);
-
- if (specspell == SPELL_NO_SPELL)
- goto whatt;
-
- // You can always memorise selective amnesia:
- if (you.spell_no == 21 && specspell != SPELL_SELECTIVE_AMNESIA)
- {
- redraw_screen();
- mpr("Your head is already too full of spells!");
- return (false);
- }
-
- if (you.is_undead && spell_typematch(specspell, SPTYP_HOLY))
- {
- redraw_screen();
- mpr("You cannot use this type of magic!");
- return (false);
- }
-
- if (undead_cannot_memorise(specspell, you.is_undead))
- {
- redraw_screen();
- mpr("You cannot use this spell.");
- return (false);
- }
-
- for (i = 0; i < 25; i++)
- {
- if (you.spells[i] == specspell)
- {
- redraw_screen();
- mpr("You already know that spell!");
- you.turn_is_over = 1;
- return (false);
- }
- }
-
- levels_needed = spell_levels_required( specspell );
-
- if (player_spell_levels() < levels_needed)
- {
- redraw_screen();
- mpr("You can't memorise that many levels of magic yet!");
- you.turn_is_over = 1;
- return (false);
- }
-
- if (you.experience_level < spell_difficulty(specspell))
- {
- redraw_screen();
- mpr("You're too inexperienced to learn that spell!");
- you.turn_is_over = 1;
- return (false);
- }
-
- redraw_screen();
-
- chance = spell_fail(specspell);
-
- strcpy(info, "This spell is ");
-
- strcat(info, (chance >= 80) ? "very" :
- (chance >= 60) ? "quite" :
- (chance >= 45) ? "rather" :
- (chance >= 30) ? "somewhat"
- : "not that");
-
- strcat(info, " ");
-
- int temp_rand = random2(3);
-
- strcat(info, (temp_rand == 0) ? "difficult" :
- (temp_rand == 1) ? "tricky" :
- (temp_rand == 2) ? "challenging"
- : "");
-
- strcat(info, " to ");
-
- temp_rand = random2(4);
-
- strcat(info, (temp_rand == 0) ? "memorise" :
- (temp_rand == 1) ? "commit to memory" :
- (temp_rand == 2) ? "learn" :
- (temp_rand == 3) ? "absorb"
- : "");
-
- strcat(info, ".");
-
- mpr(info);
-
- strcpy(info, "Memorise ");
- strcat(info, spell_title(specspell));
- strcat(info, "?");
- mpr(info);
-
- for (;;)
- {
- keyin = getch();
-
- if (keyin == 'n' || keyin == 'N')
- {
- redraw_screen();
- return (false);
- }
-
- if (keyin == 'y' || keyin == 'Y')
- break;
- }
-
- mesclr( true );
-
- if (you.mutation[MUT_BLURRY_VISION] > 0
- && random2(4) < you.mutation[MUT_BLURRY_VISION])
- {
- mpr("The writing blurs into unreadable gibberish.");
- you.turn_is_over = 1;
- return (false);
- }
-
- if (random2(40) + random2(40) + random2(40) < chance)
- {
- redraw_screen();
- mpr("You fail to memorise the spell.");
- you.turn_is_over = 1;
-
- if (you.inv[ book ].sub_type == BOOK_NECRONOMICON)
- {
- mpr("The pages of the Necronomicon glow with a dark malevolence...");
- miscast_effect( SPTYP_NECROMANCY, 8, random2avg(88, 3), 100,
- "reading the Necronomicon" );
- }
- else if (you.inv[ book ].sub_type == BOOK_DEMONOLOGY)
- {
- mpr("This book does not appreciate being disturbed by one of your ineptitude!");
- miscast_effect( SPTYP_SUMMONING, 7, random2avg(88, 3), 100,
- "reading the book of Demonology" );
- }
- else if (you.inv[ book ].sub_type == BOOK_ANNIHILATIONS)
- {
- mpr("This book does not appreciate being disturbed by one of your ineptitude!");
- miscast_effect( SPTYP_CONJURATION, 8, random2avg(88, 3), 100,
- "reading the book of Annihilations" );
- }
-
-#if WIZARD
- if (!you.wizard)
- return (false);
- else if (!yesno("Memorize anyway?"))
- return (false);
-#else
- return (false);
-#endif
- }
-
- start_delay( DELAY_MEMORISE, spell_difficulty( specspell ), specspell );
-
- you.turn_is_over = 1;
- redraw_screen();
-
- did_god_conduct( DID_SPELL_CASTING, 2 + random2(5) );
-
- return (true);
-} // end which_spell()
-
-int count_staff_spells(const item_def &item, bool need_id)
-{
- if (item.base_type != OBJ_STAVES)
- return (-1);
-
- if (need_id && !item_ident( item, ISFLAG_KNOW_TYPE ))
- return (0);
-
- const int stype = item.sub_type;
- const int type = stype + 40;
- if (stype < STAFF_SMITING || stype >= STAFF_AIR)
- return (0);
-
- FixedVector< int, SPELLBOOK_SIZE > spell_list;
- spellbook_template( type, spell_list );
-
- int num_spells = 0;
- for (num_spells = 0; num_spells < SPELLBOOK_SIZE - 1; num_spells++)
- {
- if (spell_list[ num_spells + 1 ] == SPELL_NO_SPELL)
- break;
- }
- return (num_spells);
-}
-
-int staff_spell( int staff )
-{
- int spell;
- unsigned char specspell;
- int mana, diff, food, energy;
- FixedVector< int, SPELLBOOK_SIZE > spell_list;
-
- // converting sub_type into book index type
- const int type = you.inv[staff].sub_type + 40;
-
- // Spell staves are mostly for the benefit of non-spellcasters, so we're
- // not going to involve INT or Spellcasting skills for power. -- bwr
- const int powc = 5 + you.skills[SK_EVOCATIONS]
- + roll_dice( 2, you.skills[SK_EVOCATIONS] );
-
- const int staff_type = you.inv[staff].sub_type;
- if (staff_type < STAFF_SMITING || staff_type >= STAFF_AIR)
- {
- //mpr("That staff has no spells in it.");
- canned_msg(MSG_NOTHING_HAPPENS);
- return (0);
- }
-
- if (!item_ident( you.inv[staff], ISFLAG_KNOW_TYPE ))
- {
- set_ident_flags( you.inv[staff], ISFLAG_KNOW_TYPE );
- you.wield_change = true;
- }
-
- spellbook_template( type, spell_list );
-
- unsigned char num_spells;
- for (num_spells = 0; num_spells < SPELLBOOK_SIZE - 1; num_spells++)
- {
- if (spell_list[ num_spells + 1 ] == SPELL_NO_SPELL)
- break;
- }
-
- if (num_spells == 0)
- {
- canned_msg(MSG_NOTHING_HAPPENS); // shouldn't happen
- return (0);
- }
- else if (num_spells == 1)
- spell = 'a'; // automatically selected if its the only option
- else
- {
- snprintf( info, INFO_SIZE,
- "Evoke which spell from the rod ([a-%c] spell [?*] list)? ",
- 'a' + num_spells - 1 );
-
- mpr( info, MSGCH_PROMPT );
- spell = get_ch();
-
- if (spell == '?' || spell == '*')
- spell = read_book( you.inv[staff], RBOOK_USE_STAFF );
- }
-
- if (spell < 'A' || (spell > 'Z' && spell < 'a') || spell > 'z')
- {
- goto whattt;
- }
-
- spell = letter_to_index( spell );
-
- if (spell >= SPELLBOOK_SIZE)
- goto whattt;
-
- if (!is_valid_spell_in_book( staff, spell ))
- goto whattt;
-
- specspell = which_spell_in_book( type, spell );
-
- if (specspell == SPELL_NO_SPELL)
- goto whattt;
-
- mana = spell_mana( specspell ) * ROD_CHARGE_MULT;
- diff = spell_difficulty( specspell );
- food = spell_hunger( specspell );
-
- if (food && (you.is_undead != US_UNDEAD
- && (you.hunger_state < HS_HUNGRY || you.hunger <= food)))
- {
- mpr("You don't have the energy to cast that spell.");
- return (0);
- }
-
- if (staff_type == STAFF_STRIKING)
- mana /= ROD_CHARGE_MULT;
-
- if ((staff_type == STAFF_STRIKING?
- you.magic_points < mana
- : you.inv[staff].plus < mana)
- || you.experience_level < diff)
- {
-#ifdef DEBUG_DIAGNOSTICS
- mprf("Mana needed: %d, Staff plus: %d, Difficulty: %d, XP: %d",
- mana, you.inv[staff].plus, diff, you.experience_level);
-#endif
- if (you.experience_level < diff)
- mprf("You need to be at least level %d to use that.", diff);
- else
- mprf("%s have enough magic points.",
- staff_type == STAFF_STRIKING? "You don't" : "The rod doesn't");
-
- // confuse_player( 2 + random2(4) );
- you.turn_is_over = 1;
- return (0);
- }
-
- // Exercising the spell skills doesn't make very much sense given
- // that spell staves are largely intended to supply spells to
- // non-spellcasters, and they don't use spell skills to determine
- // power in the same way that spellcasting does. -- bwr
- //
- // exercise_spell(specspell, true, true);
-
- your_spells(specspell, powc, false);
-
-
- // [dshaligram]
- // dec_mp(spell_mana(specspell));
- if (staff_type != STAFF_STRIKING)
- you.inv[staff].plus -= mana;
- else {
- you.magic_points -= mana;
- you.redraw_magic_points = true;
- }
-
- energy = player_energy();
- if (energy <= 0 && you.is_undead != US_UNDEAD)
- {
- food -= 10 * you.skills[SK_EVOCATIONS];
- if (food < diff * 5)
- food = diff * 5;
-
- make_hungry( food, true );
- }
-
- you.wield_change = true;
-
- you.turn_is_over = 1;
-
- return (roll_dice( 1, 1 + spell_difficulty(specspell) / 2 ));
-
- whattt:
- mpr("What?");
-
- return (0);
-} // end staff_spell()
diff --git a/stone_soup/crawl-ref/source/spl-book.h b/stone_soup/crawl-ref/source/spl-book.h
deleted file mode 100644
index d6aa2843bc..0000000000
--- a/stone_soup/crawl-ref/source/spl-book.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * File: spl-book.h
- * Summary: Some spellbook related functions.
- * Written by: Josh Fishman
- *
- * Change History (most recent first):
- *
- * 22mar2000 jmf Created
- */
-
-
-#ifndef SPL_BOOK_H
-#define SPL_BOOK_H
-
-#include "externs.h"
-#include "FixVec.h"
-
-
-// used in dungeon.cc, it_use3.cc, spl-book.cc, spl-book.h - {dlb}
-#define SPELLBOOK_SIZE 9
-// used in spl-book.cc, spl-book.h - {dlb}
-#define NUMBER_SPELLBOOKS 60
-
-
-// updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: dungeon - effects - shopping
- * *********************************************************************** */
-char book_rarity(unsigned char which_book);
-
-
-// updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: it_use3 - item_use - spl-book
- * *********************************************************************** */
-bool is_valid_spell_in_book( unsigned int splbook, int spell );
-
-
-// updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: it_use3 - item_use - spl-book
- * *********************************************************************** */
-unsigned char read_book( item_def &item, int action );
-
-
-// updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-bool learn_spell(void);
-
-
-// updated 24may2000 {dlb}
-/* ***********************************************************************
- * called from: it_use3 - item_use - spl-book
- * *********************************************************************** */
-int which_spell_in_book(int sbook_type, int spl);
-
-int staff_spell( int zap_device_2 );
-
-bool undead_cannot_memorise(unsigned char spell, unsigned char being);
-
-unsigned char spellbook_contents( item_def &book, int action,
- formatted_string *fs = NULL );
-
-int count_staff_spells(const item_def &item, bool need_id);
-
-#endif
diff --git a/stone_soup/crawl-ref/source/spl-cast.cc b/stone_soup/crawl-ref/source/spl-cast.cc
deleted file mode 100644
index fb6d60bf62..0000000000
--- a/stone_soup/crawl-ref/source/spl-cast.cc
+++ /dev/null
@@ -1,3572 +0,0 @@
-/*
- * File: spl-cast.cc
- * Summary: Spell casting and miscast functions.
- * Written by: Linley Henzell
- *
- * Modified for Crawl Reference by $Author$ on $Date$
- *
- * Change History (most recent first):
- *
- * <4> 1/02/00 jmf changed values, marked //jmf:
- * <3> 6/13/99 BWR Added Staff auto identify code
- * <2> 5/20/99 BWR Added some screen redraws
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "spl-cast.h"
-
-#include "externs.h"
-
-#include "beam.h"
-#include "cloud.h"
-#include "effects.h"
-#include "fight.h"
-#include "food.h"
-#include "it_use2.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "macro.h"
-#include "monplace.h"
-#include "monstuff.h"
-#include "mutation.h"
-#include "ouch.h"
-#include "player.h"
-#include "religion.h"
-#include "skills.h"
-#include "spells1.h"
-#include "spells2.h"
-#include "spells3.h"
-#include "spells4.h"
-#include "spl-book.h"
-#include "spl-util.h"
-#include "stuff.h"
-#include "transfor.h"
-#include "view.h"
-
-#ifdef DOS
-#include <conio.h>
-#endif
-
-#define WILD_MAGIC_NASTINESS 150
-
-static void surge_power(int spell)
-{
- int enhanced = 0;
-
- //jmf: simplified
- enhanced += spell_enhancement(spell_type(spell));
-
- if (enhanced) // one way or the other {dlb}
- {
- strcpy(info, "You feel a");
-
- strcat(info, (enhanced < -2) ? "n extraordinarily" :
- (enhanced == -2) ? "n extremely" :
- (enhanced == 2) ? " strong" :
- (enhanced > 2) ? " huge"
- : "");
-
- strcat(info, (enhanced < 0) ? " numb sensation."
- : " surge of power!");
- mpr(info);
- }
-} // end surge_power()
-
-char list_spells(void)
-{
- int j;
- int lines = 0;
- unsigned int anything = 0;
- unsigned int i;
- int ki;
- bool already = false;
-
- const int num_lines = get_number_of_lines();
-
-#ifdef DOS_TERM
- char buffer[4800];
-
- gettext(1, 1, 80, 25, buffer);
-#endif
-
-#ifdef DOS_TERM
- window(1, 1, 80, 25);
-#endif
-
- clrscr();
-
- cprintf( " Your Spells Type Success Level" );
- lines++;
-
- for (j = 0; j < 52; j++)
- {
- if (lines > num_lines - 2)
- {
- gotoxy(1, num_lines);
- cprintf("-more-");
-
- ki = getch();
-
- if (ki == ESCAPE)
- {
-#ifdef DOS_TERM
- puttext(1, 1, 80, 25, buffer);
-#endif
- return (ESCAPE);
- }
-
- if (isalpha( ki ))
- {
-#ifdef DOS_TERM
- puttext(1, 1, 80, 25, buffer);
-#endif
- return (ki);
- }
-
- if (ki == 0)
- ki = getch();
-
- lines = 0;
- clrscr();
- gotoxy(1, 1);
- anything = 0;
- }
-
- const char letter = index_to_letter(j);
- const int spell = get_spell_by_letter(letter);
-
- if (spell != SPELL_NO_SPELL)
- {
- anything++;
-
- if (lines > 0)
- cprintf(EOL);
-
- lines++;
-
- cprintf( " %c - %s", letter, spell_title( spell ) );
- gotoxy(35, wherey());
-
- already = false;
-
- for (i = 0; i <= SPTYP_LAST_EXPONENT; i++)
- {
- if (spell_typematch( spell, (1 << i) ))
- {
- if (already)
- cprintf( "/" );
-
- cprintf( spelltype_name( 1 << i ) );
- already = true;
- }
- }
-
- char sval[16];
-
- //gotoxy(58, wherey());
- gotoxy(65, wherey());
-
- int spell_f = spell_fail( spell );
-
- cprintf( (spell_f == 100) ? "Useless" :
- (spell_f > 90) ? "Terrible" :
- (spell_f > 80) ? "Cruddy" :
- (spell_f > 70) ? "Bad" :
- (spell_f > 60) ? "Very Poor" :
- (spell_f > 50) ? "Poor" :
- (spell_f > 40) ? "Fair" :
- (spell_f > 30) ? "Good" :
- (spell_f > 20) ? "Very Good" :
- (spell_f > 10) ? "Great" :
- (spell_f > 0) ? "Excellent"
- : "Perfect" );
-
- gotoxy(77, wherey());
-
- itoa( (int) spell_difficulty( spell ), sval, 10 );
- cprintf(sval);
- }
- } // end of j loop
-
- if (anything > 0)
- {
- ki = getch();
-
- if (ki >= 'A' && ki <= 'z')
- {
-#ifdef DOS_TERM
- puttext(1, 1, 80, 25, buffer);
-#endif
- return (ki);
- }
-
- if (ki == 0)
- ki = getch();
-
-#ifdef DOS_TERM
- puttext(1, 1, 80, 25, buffer);
-#endif
-
- return (anything);
- }
-
-#ifdef DOS_TERM
- puttext(1, 1, 80, 25, buffer);
-#endif
- // was 35
- ki = getch();
-
- return (ki);
-} // end list_spells()
-
-int spell_fail(int spell)
-{
- int chance = 60;
- int chance2 = 0, armour = 0;
-
- chance -= 6 * calc_spell_power( spell, false, true );
- chance -= (you.intel * 2);
-
- //chance -= (you.intel - 10) * abs(you.intel - 10);
- //chance += spell_difficulty(spell) * spell_difficulty(spell) * 3; //spell_difficulty(spell);
-
- if (you.equip[EQ_BODY_ARMOUR] != -1)
- {
-
- int ev_penalty = abs(property( you.inv[you.equip[EQ_BODY_ARMOUR]],
- PARM_EVASION ));
-
- // The minus 15 is to make the -1 light armours not so bad
- armour += (20 * ev_penalty) - 15;
-
- //jmf: armour skill now reduces failure due to armour
- //bwr: this was far too good, an armour skill of 5 was
- // completely negating plate mail. Plate mail should
- // hardly be completely negated, it should still be
- // an important consideration for even high level characters.
- // Truth is, even a much worse penalty than the above can
- // easily be overcome by gaining spell skills... and a lot
- // faster than any reasonable rate of bonus here.
- int lim_str = (you.strength > 30) ? 30 :
- (you.strength < 10) ? 10 : you.strength;
-
- armour -= ((you.skills[SK_ARMOUR] * lim_str) / 15);
-
- int race_arm = get_equip_race( you.inv[you.equip[EQ_BODY_ARMOUR]] );
- int racial_type = 0;
-
- if (player_genus(GENPC_DWARVEN))
- racial_type = ISFLAG_DWARVEN;
- else if (player_genus(GENPC_ELVEN))
- racial_type = ISFLAG_ELVEN;
- else if (you.species == SP_HILL_ORC)
- racial_type = ISFLAG_ORCISH;
-
- // Elven armour gives everyone some benefit to spellcasting,
- // Dwarven armour hinders everyone.
- switch (race_arm)
- {
- case ISFLAG_ELVEN:
- armour -= 20;
- break;
- case ISFLAG_DWARVEN:
- armour += 10;
- break;
- default:
- break;
- }
-
- // Armour of the same racial type reduces penalty.
- if (racial_type && race_arm == racial_type)
- armour -= 10;
-
- if (armour > 0)
- chance += armour;
- }
-
- if (you.equip[EQ_WEAPON] != -1
- && you.inv[you.equip[EQ_WEAPON]].base_type == OBJ_WEAPONS)
- {
- int wpn_penalty = (3 * (property( you.inv[you.equip[EQ_WEAPON]], PWPN_SPEED ) - 12)) / 2;
-
- if (wpn_penalty > 0)
- chance += wpn_penalty;
- }
-
- if (you.equip[EQ_SHIELD] != -1)
- {
- switch (you.inv[you.equip[EQ_SHIELD]].sub_type)
- {
- case ARM_BUCKLER:
- chance += 5;
- break;
-
- case ARM_SHIELD:
- chance += 15;
- break;
-
- case ARM_LARGE_SHIELD:
- // *BCR* Large chars now get a lower penalty for large shields
- if ((you.species >= SP_OGRE && you.species <= SP_OGRE_MAGE)
- || player_genus(GENPC_DRACONIAN))
- {
- chance += 20;
- }
- else
- chance += 30;
- break;
- }
- }
-
- switch (spell_difficulty(spell))
- {
- case 1: chance += 3; break;
- case 2: chance += 15; break;
- case 3: chance += 35; break;
- case 4: chance += 70; break;
- case 5: chance += 100; break;
- case 6: chance += 150; break;
- case 7: chance += 200; break;
- case 8: chance += 260; break;
- case 9: chance += 330; break;
- case 10: chance += 420; break;
- case 11: chance += 500; break;
- case 12: chance += 600; break;
- default: chance += 750; break;
- }
-
- //if (chance < 1 ) chance = 0;
- if (chance > 100)
- chance = 100;
-
- chance2 = chance;
-
- if (chance < 45)
- chance2 = 45;
- if (chance < 42)
- chance2 = 43;
- if (chance < 38)
- chance2 = 41;
- if (chance < 35)
- chance2 = 40;
- if (chance < 32)
- chance2 = 38;
- if (chance < 28)
- chance2 = 36;
- if (chance < 22)
- chance2 = 34;
- if (chance < 16)
- chance2 = 32;
- if (chance < 10)
- chance2 = 30;
- if (chance < 2)
- chance2 = 28;
- if (chance < -7)
- chance2 = 26;
- if (chance < -12)
- chance2 = 24;
- if (chance < -18)
- chance2 = 22;
- if (chance < -24)
- chance2 = 20;
- if (chance < -30)
- chance2 = 18;
- if (chance < -38)
- chance2 = 16;
- if (chance < -46)
- chance2 = 14;
- if (chance < -60)
- chance2 = 12;
- if (chance < -80)
- chance2 = 10;
- if (chance < -100)
- chance2 = 8;
- if (chance < -120)
- chance2 = 6;
- if (chance < -140)
- chance2 = 4;
- if (chance < -160)
- chance2 = 2;
- if (chance < -180)
- chance2 = 0;
-
- if (you.religion == GOD_VEHUMET
- && you.duration[DUR_PRAYER]
- && (!player_under_penance() && you.piety >= 50)
- && (spell_typematch(spell, SPTYP_CONJURATION)
- || spell_typematch(spell, SPTYP_SUMMONING)))
- {
- // [dshaligram] Fail rate multiplier used to be .5, scaled
- // back to 2/3.
- chance2 = chance2 * 2 / 3;
- }
-
- if (you.duration[DUR_TRANSFORMATION] > 0)
- {
- switch (you.attribute[ATTR_TRANSFORMATION])
- {
- case TRAN_BLADE_HANDS:
- chance2 += 20;
- break;
-
- case TRAN_SPIDER:
- chance2 += 10;
- break;
- }
- }
-
- return (chance2);
-} // end spell_fail()
-
-
-int calc_spell_power( int spell, bool apply_intel, bool fail_rate_check )
-{
- unsigned int bit;
- int ndx;
- int power = (you.skills[SK_SPELLCASTING] / 2) + player_mag_abil(false);
- int enhanced = 0;
-
- unsigned int disciplines = spell_type( spell );
-
- //jmf: evil evil evil -- exclude HOLY bit
- disciplines &= (~SPTYP_HOLY);
-
- int skillcount = count_bits( disciplines );
- if (skillcount)
- {
- for (ndx = 0; ndx <= SPTYP_LAST_EXPONENT; ndx++)
- {
- bit = 1 << ndx;
- if ((bit != SPTYP_HOLY) && (disciplines & bit))
- {
- int skill = spell_type2skill( bit );
-
- power += (you.skills[skill] * 2) / skillcount;
- }
- }
- }
-
- if (apply_intel)
- power = (power * you.intel) / 10;
-
- // [dshaligram] Enhancers don't affect fail rates any more, only spell
- // power. Note that this does not affect Vehumet's boost in castability.
- if (!fail_rate_check)
- enhanced = spell_enhancement( disciplines );
-
- if (enhanced > 0)
- {
- for (ndx = 0; ndx < enhanced; ndx++)
- {
- power *= 15;
- power /= 10;
- }
- }
- else if (enhanced < 0)
- {
- for (ndx = enhanced; ndx < 0; ndx++)
- power /= 2;
- }
-
- power = stepdown_value( power, 50, 50, 150, 200 );
-
- return (power);
-} // end calc_spell_power()
-
-
-int spell_enhancement( unsigned int typeflags )
-{
- int enhanced = 0;
-
- if (typeflags & SPTYP_CONJURATION)
- enhanced += player_spec_conj();
-
- if (typeflags & SPTYP_ENCHANTMENT)
- enhanced += player_spec_ench();
-
- if (typeflags & SPTYP_SUMMONING)
- enhanced += player_spec_summ();
-
- if (typeflags & SPTYP_POISON)
- enhanced += player_spec_poison();
-
- if (typeflags & SPTYP_NECROMANCY)
- enhanced += player_spec_death() - player_spec_holy();
-
- if (typeflags & SPTYP_FIRE)
- enhanced += player_spec_fire() - player_spec_cold();
-
- if (typeflags & SPTYP_ICE)
- enhanced += player_spec_cold() - player_spec_fire();
-
- if (typeflags & SPTYP_EARTH)
- enhanced += player_spec_earth() - player_spec_air();
-
- if (typeflags & SPTYP_AIR)
- enhanced += player_spec_air() - player_spec_earth();
-
- if (you.special_wield == SPWLD_SHADOW)
- enhanced -= 2;
-
- // These are used in an exponential way, so we'll limit them a bit. -- bwr
- if (enhanced > 3)
- enhanced = 3;
- else if (enhanced < -3)
- enhanced = -3;
-
- return (enhanced);
-} // end spell_enhancement()
-
-// returns false if spell failed, and true otherwise
-bool cast_a_spell(void)
-{
- char spc = 0;
- char spc2 = 0;
- int spellh = 0;
- unsigned char keyin = 0;
- char unthing = 0;
-
- if (!you.spell_no)
- {
- mpr("You don't know any spells.");
- return (false);
- }
-
- if (you.berserker)
- {
- canned_msg(MSG_TOO_BERSERK);
- return (false);
- }
-
- if (silenced(you.x_pos, you.y_pos))
- {
- mpr("You cannot cast spells when silenced!");
- return (false);
- }
-
- // first query {dlb}:
- for (;;)
- {
- //jmf: FIXME: change to reflect range of known spells
- mpr( "Cast which spell ([?*] list)? ", MSGCH_PROMPT );
-
- keyin = get_ch();
-
- if (keyin == '?' || keyin == '*')
- {
- unthing = list_spells();
-
- redraw_screen();
- if (unthing == 2)
- return (false);
-
- if (unthing >= 'a' && unthing <= 'y')
- {
- keyin = unthing;
- break;
- }
- else
- mesclr();
- }
- else
- {
- break;
- }
-
- }
-
- if (keyin == ESCAPE)
- return (false);
-
- spc = (int) keyin;
-
- if (!isalpha(spc))
- {
- mpr("You don't know that spell.");
- return (false);
- }
-
- const int spell = get_spell_by_letter( spc );
-
- spc2 = letter_to_index(spc);
-
- if (spell == SPELL_NO_SPELL)
- {
- mpr("You don't know that spell.");
- return (false);
- }
-
- if (spell_mana( spell ) > you.magic_points)
- {
- mpr("You don't have enough magic to cast that spell.");
- return (false);
- }
-
- if (you.is_undead != US_UNDEAD
- && (you.hunger_state < HS_HUNGRY
- || you.hunger <= spell_hunger( spell )))
- {
- mpr("You don't have the energy to cast that spell.");
- return (false);
- }
-
- dec_mp( spell_mana(spell) );
-
- if (!player_energy() && you.is_undead != US_UNDEAD)
- {
- spellh = spell_hunger( spell );
-
- // I wonder if a better algorithm is called for? {dlb}
- spellh -= you.intel * you.skills[SK_SPELLCASTING];
-
- if (spellh < 1)
- spellh = 1;
- else
- make_hungry(spellh, true);
- }
-
- you.turn_is_over = 1;
- alert_nearby_monsters();
-
- if (you.conf)
- random_uselessness( 2 + random2(7), 0 );
- else
- {
- exercise_spell( spell, true, your_spells( spell ) );
- did_god_conduct( DID_SPELL_CASTING, 1 + random2(5) );
- }
-
- return (true);
-} // end cast_a_spell()
-
-// "Utility" spells for the sake of simplicity are currently ones with
-// enchantments, translocations, or divinations.
-bool spell_is_utility_spell( int spell_id )
-{
- return (spell_typematch( spell_id,
- SPTYP_ENCHANTMENT | SPTYP_TRANSLOCATION | SPTYP_DIVINATION ));
-}
-
-bool spell_is_unholy( int spell_id )
-{
- return (testbits( get_spell_flags( spell_id ), SPFLAG_UNHOLY ));
-}
-
-// returns true if spell if spell is successfully cast for purposes of
-// exercising and false otherwise (note: false == less exercise, not none).
-bool your_spells( int spc2, int powc, bool allow_fail )
-{
- int dem_hor = 0;
- int dem_hor2 = 0;
- int total_skill = 0;
- struct dist spd;
- struct bolt beam;
-
- alert_nearby_monsters();
-
- // Added this so that the passed in powc can have meaning -- bwr
- if (powc == 0)
- powc = calc_spell_power( spc2, true );
-
- if (you.equip[EQ_WEAPON] != -1
- && item_is_staff( you.inv[you.equip[EQ_WEAPON]] )
- && !item_ident( you.inv[you.equip[EQ_WEAPON]], ISFLAG_KNOW_TYPE ))
- {
- switch (you.inv[you.equip[EQ_WEAPON]].sub_type)
- {
- case STAFF_ENERGY:
- case STAFF_WIZARDRY:
- total_skill = you.skills[SK_SPELLCASTING];
- break;
- case STAFF_FIRE:
- if (spell_typematch(spc2, SPTYP_FIRE))
- total_skill = you.skills[SK_FIRE_MAGIC];
- else if (spell_typematch(spc2, SPTYP_ICE))
- total_skill = you.skills[SK_ICE_MAGIC];
- break;
- case STAFF_COLD:
- if (spell_typematch(spc2, SPTYP_ICE))
- total_skill = you.skills[SK_ICE_MAGIC];
- else if (spell_typematch(spc2, SPTYP_FIRE))
- total_skill = you.skills[SK_FIRE_MAGIC];
- break;
- case STAFF_AIR:
- if (spell_typematch(spc2, SPTYP_AIR))
- total_skill = you.skills[SK_AIR_MAGIC];
- else if (spell_typematch(spc2, SPTYP_EARTH))
- total_skill = you.skills[SK_EARTH_MAGIC];
- break;
- case STAFF_EARTH:
- if (spell_typematch(spc2, SPTYP_EARTH))
- total_skill = you.skills[SK_EARTH_MAGIC];
- else if (spell_typematch(spc2, SPTYP_AIR))
- total_skill = you.skills[SK_AIR_MAGIC];
- break;
- case STAFF_POISON:
- if (spell_typematch(spc2, SPTYP_POISON))
- total_skill = you.skills[SK_POISON_MAGIC];
- break;
- case STAFF_DEATH:
- if (spell_typematch(spc2, SPTYP_NECROMANCY))
- total_skill = you.skills[SK_NECROMANCY];
- break;
- case STAFF_CONJURATION:
- if (spell_typematch(spc2, SPTYP_CONJURATION))
- total_skill = you.skills[SK_CONJURATIONS];
- break;
- case STAFF_ENCHANTMENT:
- if (spell_typematch(spc2, SPTYP_ENCHANTMENT))
- total_skill = you.skills[SK_ENCHANTMENTS];
- break;
- case STAFF_SUMMONING:
- if (spell_typematch(spc2, SPTYP_SUMMONING))
- total_skill = you.skills[SK_SUMMONINGS];
- break;
- }
-
- if (you.skills[SK_SPELLCASTING] > total_skill)
- total_skill = you.skills[SK_SPELLCASTING];
-
- if (random2(100) < total_skill)
- {
- char str_pass[ ITEMNAME_SIZE ];
-
- set_ident_flags( you.inv[you.equip[EQ_WEAPON]], ISFLAG_KNOW_TYPE );
-
- strcpy(info, "You are wielding ");
- in_name(you.equip[EQ_WEAPON], DESC_NOCAP_A, str_pass);
- strcat(info, str_pass);
- strcat(info, ".");
- mpr(info);
-
- more();
-
- you.wield_change = true;
- }
- }
-
- surge_power(spc2);
-
- if (allow_fail)
- {
- int spfl = random2avg(100, 3);
-
- if (you.religion != GOD_SIF_MUNA
- && you.penance[GOD_SIF_MUNA] && one_chance_in(20))
- {
- god_speaks(GOD_SIF_MUNA, "You feel a surge of divine spite.");
-
- // This will cause failure and increase the miscast effect.
- spfl = -you.penance[GOD_SIF_MUNA];
-
- // Reduced penance reduction here because casting spells
- // is a player controllable act. -- bwr
- if (one_chance_in(12))
- dec_penance(GOD_SIF_MUNA, 1);
- }
-
- if (spfl < spell_fail(spc2))
- {
- mpr( "You miscast the spell." );
- flush_input_buffer( FLUSH_ON_FAILURE );
-
- if (you.religion == GOD_SIF_MUNA
- && (!player_under_penance()
- && you.piety >= 100 && random2(150) <= you.piety))
- {
- canned_msg(MSG_NOTHING_HAPPENS);
- return (false);
- }
-
- unsigned int sptype = 0;
-
- do
- {
- sptype = 1 << (random2(SPTYP_LAST_EXPONENT+1));
- } while (!spell_typematch(spc2, sptype));
-
- // all spell failures give a bit of magical radiation..
- // failure is a function of power squared multiplied
- // by how badly you missed the spell. High power
- // spells can be quite nasty: 9 * 9 * 90 / 500 = 15
- // points of contamination!
- int nastiness = spell_mana(spc2) * spell_mana(spc2)
- * (spell_fail(spc2) - spfl) + 250;
-
- int cont_points = nastiness / 500;
- // handle fraction
- if (random2(500) < (nastiness % 500))
- cont_points++;
-
- contaminate_player( cont_points );
-
- miscast_effect( sptype, spell_mana(spc2), spell_fail(spc2) - spfl, 100 );
-
- if (you.religion == GOD_XOM && random2(75) < spell_mana(spc2))
- Xom_acts(coinflip(), spell_mana(spc2), false);
-
- return (false);
- }
- }
-
- if (you.is_undead && spell_typematch( spc2, SPTYP_HOLY ))
- {
- mpr( "You can't use this type of magic!" );
- return (false); // XXX: still gets trained!
- }
-
- // Normally undead can't memorize these spells, so this check is
- // to catch those in Lich form. As such, we allow the Lich form
- // to be extended here. -- bwr
- if (spc2 != SPELL_NECROMUTATION
- && undead_cannot_memorise( spc2, you.is_undead ))
- {
- mpr( "You cannot cast that spell in your current form!" );
- return (false); // XXX: still gets trained!
- }
-
- if (!spell_is_utility_spell(spc2))
- did_god_conduct( DID_SPELL_NONUTILITY, 10 + spell_difficulty(spc2) );
-
- if (spell_is_unholy( spc2 ))
- did_god_conduct( DID_UNHOLY, 10 + spell_difficulty(spc2) );
-
- // Linley says: Condensation Shield needs some disadvantages to keep
- // it from being a no-brainer... this isn't much, but its a start -- bwr
- if (you.duration[DUR_CONDENSATION_SHIELD] > 0
- && spell_typematch( spc2, SPTYP_FIRE ))
- {
- // TODO: Pull in Brent's expose_player_to_element fn.
- mpr( "Your icy shield dissipates!", MSGCH_DURATION );
- you.duration[DUR_CONDENSATION_SHIELD] = 0;
- you.redraw_armour_class = 1;
- }
-
- if (spell_typematch( spc2, SPTYP_NECROMANCY ))
- {
- did_god_conduct( DID_NECROMANCY, 10 + spell_difficulty(spc2) );
-
- if (spc2 == SPELL_NECROMUTATION
- && (you.religion == GOD_ELYVILON
- || you.religion == GOD_SHINING_ONE
- || you.religion == GOD_ZIN))
- {
- excommunication();
- }
- }
-
- // [dshaligram] Sif Muna piety now increases only when training spell skills
- // as per bwr 4.1.
- /*
- if (you.religion == GOD_SIF_MUNA
- && you.piety < 200 && random2(12) <= spell_difficulty(spc2))
- {
- gain_piety(1);
- }
- */
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "Spell #%d, power=%d", spc2, powc );
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- switch (spc2)
- {
- case SPELL_IDENTIFY:
- identify(powc);
- break;
-
- case SPELL_TELEPORT_SELF:
- you_teleport();
- break;
-
- case SPELL_CAUSE_FEAR:
- mass_enchantment(ENCH_FEAR, powc, MHITYOU);
- break;
-
- case SPELL_CREATE_NOISE: // unused, the player can shout to do this - bwr
- if (!silenced(you.x_pos, you.y_pos))
- {
- mpr("You hear a voice call your name!", MSGCH_SOUND);
- noisy( 25, you.x_pos, you.y_pos );
- }
- break;
-
- case SPELL_REMOVE_CURSE:
- remove_curse(false);
- break;
-
- case SPELL_MAGIC_DART:
- if (spell_direction(spd, beam) == -1)
- return (false);
-
- zapping(ZAP_MAGIC_DARTS, powc, beam);
- break;
-
- case SPELL_FIREBALL:
- fireball(powc);
- break;
-
- case SPELL_DELAYED_FIREBALL:
- // This spell has two main advantages over Fireball:
- //
- // (1) The release is instantaneous, so monsters will not
- // get an action before the player... this allows the
- // player to hit monsters with a double fireball (this
- // is why we only allow one delayed fireball at a time,
- // if you want to allow for more, then the release should
- // take at least some amount of time).
- //
- // The casting of this spell still costs a turn. So
- // casting Delayed Fireball and immediately releasing
- // the fireball is only slightly different than casting
- // a regular Fireball (monsters act in the middle instead
- // of at the end). This is why we allow for the spell
- // level discount so that Fireball is free with this spell
- // (so that it only costs 7 levels instead of 13 to have
- // both).
- //
- // (2) When the fireball is released, it is guaranteed to
- // go off... the spell only fails at this point. This can
- // be a large advantage for characters who have difficulty
- // casting Fireball in their standard equipment. However,
- // the power level for the actual fireball is determined at
- // release, so if you do swap out your enhancers you'll
- // get a less powerful ball when its released. -- bwr
- //
- if (!you.attribute[ ATTR_DELAYED_FIREBALL ])
- {
- // okay, this message is weak but functional -- bwr
- mpr( "You feel magically charged." );
- you.attribute[ ATTR_DELAYED_FIREBALL ] = 1;
- }
- else
- {
- canned_msg( MSG_NOTHING_HAPPENS );
- }
- break;
-
- case SPELL_STRIKING:
- if (spell_direction( spd, beam ) == -1)
- return (false);
-
- zapping( ZAP_STRIKING, powc, beam );
- break;
-
- case SPELL_CONJURE_FLAME:
- conjure_flame(powc);
- break;
-
- case SPELL_DIG:
- if (spell_direction(spd, beam) == -1)
- return (false);
-
- if (spd.isMe)
- {
- canned_msg(MSG_UNTHINKING_ACT);
- return (false);
- }
- zapping(ZAP_DIGGING, powc, beam);
- break;
-
- case SPELL_BOLT_OF_FIRE:
- if (spell_direction(spd, beam) == -1)
- return (false);
- zapping(ZAP_FIRE, powc, beam);
- break;
-
- case SPELL_BOLT_OF_COLD:
- if (spell_direction(spd, beam) == -1)
- return (false);
- zapping(ZAP_COLD, powc, beam);
- break;
-
- case SPELL_LIGHTNING_BOLT:
- if (spell_direction(spd, beam) == -1)
- return (false);
- zapping(ZAP_LIGHTNING, powc, beam);
- break;
-
- case SPELL_BOLT_OF_MAGMA:
- if (spell_direction(spd, beam) == -1)
- return (false);
- zapping(ZAP_MAGMA, powc, beam);
- break;
-
- case SPELL_POLYMORPH_OTHER:
- if (spell_direction(spd, beam) == -1)
- return (false);
-
- if (spd.isMe)
- {
- mpr("Sorry, it doesn't work like that.");
- return (false);
- }
- zapping(ZAP_POLYMORPH_OTHER, powc, beam);
- break;
-
- case SPELL_SLOW:
- if (spell_direction(spd, beam) == -1)
- return (false);
- zapping(ZAP_SLOWING, powc, beam);
- break;
-
- case SPELL_HASTE:
- if (spell_direction(spd, beam, DIR_NONE, TARG_FRIEND) == -1)
- return (false);
- zapping(ZAP_HASTING, powc, beam);
- break;
-
- case SPELL_PARALYZE:
- if (spell_direction(spd, beam) == -1)
- return (false);
- zapping(ZAP_PARALYSIS, powc, beam);
- break;
-
- case SPELL_CONFUSE:
- if (spell_direction(spd, beam) == -1)
- return (false);
- zapping(ZAP_CONFUSION, powc, beam);
- break;
-
- case SPELL_CONFUSING_TOUCH:
- cast_confusing_touch(powc);
- break;
-
- case SPELL_SURE_BLADE:
- cast_sure_blade(powc);
- break;
-
- case SPELL_INVISIBILITY:
- if (spell_direction(spd, beam, DIR_NONE, TARG_FRIEND) == -1)
- return (false);
- zapping(ZAP_INVISIBILITY, powc, beam);
- break;
-
- case SPELL_THROW_FLAME:
- if (spell_direction(spd, beam) == -1)
- return (false);
- zapping(ZAP_FLAME, powc, beam);
- break;
-
- case SPELL_THROW_FROST:
- if (spell_direction(spd, beam) == -1)
- return (false);
- zapping(ZAP_FROST, powc, beam);
- break;
-
- case SPELL_CONTROLLED_BLINK:
- blink();
- break;
-
- case SPELL_FREEZING_CLOUD:
- cast_big_c(powc, CLOUD_COLD);
- break;
-
- case SPELL_MEPHITIC_CLOUD:
- stinking_cloud(powc);
- break;
-
- case SPELL_RING_OF_FLAMES:
- cast_ring_of_flames(powc);
- break;
-
- case SPELL_RESTORE_STRENGTH:
- restore_stat(STAT_STRENGTH, false);
- break;
-
- case SPELL_RESTORE_INTELLIGENCE:
- restore_stat(STAT_INTELLIGENCE, false);
- break;
-
- case SPELL_RESTORE_DEXTERITY:
- restore_stat(STAT_DEXTERITY, false);
- break;
-
- case SPELL_VENOM_BOLT:
- if (spell_direction(spd, beam) == -1)
- return (false);
- zapping(ZAP_VENOM_BOLT, powc, beam);
- break;
-
- case SPELL_OLGREBS_TOXIC_RADIANCE:
- cast_toxic_radiance();
- break;
-
- case SPELL_TELEPORT_OTHER:
- if (spell_direction(spd, beam) == -1)
- return (false);
-
- if (spd.isMe)
- {
- mpr("Sorry, it doesn't work like that.");
- return (false);
- }
- // teleport creature (I think)
- zapping(ZAP_TELEPORTATION, powc, beam);
- break;
-
- case SPELL_LESSER_HEALING:
- cast_healing(5);
- break;
-
- case SPELL_GREATER_HEALING:
- cast_healing(25);
- break;
-
- case SPELL_CURE_POISON_I: //jmf: `healing' version? group w/ S_C_P_II?
- cast_cure_poison(powc);
- break;
-
- case SPELL_PURIFICATION:
- purification();
- break;
-
- case SPELL_DEATHS_DOOR:
- cast_deaths_door(powc);
- break;
-
- case SPELL_SELECTIVE_AMNESIA:
- cast_selective_amnesia(false);
- break; // Sif Muna power calls with true
-
- case SPELL_MASS_CONFUSION:
- mass_enchantment(ENCH_CONFUSION, powc, MHITYOU);
- break;
-
- case SPELL_SMITING:
- cast_smiting(powc);
- break;
-
- case SPELL_REPEL_UNDEAD:
- turn_undead(50);
- break;
-
- case SPELL_HOLY_WORD:
- holy_word(50);
- break;
-
- case SPELL_DETECT_CURSE:
- detect_curse(false);
- break;
-
- case SPELL_SUMMON_SMALL_MAMMAL:
- summon_small_mammals(powc); //jmf: hmm, that's definately *plural* ;-)
- break;
-
- case SPELL_ABJURATION_I: //jmf: why not group with SPELL_ABJURATION_II?
- abjuration(powc);
- break;
-
- case SPELL_SUMMON_SCORPIONS:
- summon_scorpions(powc);
- break;
-
- case SPELL_LEVITATION:
- potion_effect( POT_LEVITATION, powc );
- break;
-
- case SPELL_BOLT_OF_DRAINING:
- if (spell_direction(spd, beam) == -1)
- return (false);
- zapping(ZAP_NEGATIVE_ENERGY, powc, beam);
- break;
-
- case SPELL_LEHUDIBS_CRYSTAL_SPEAR:
- if (spell_direction(spd, beam) == -1)
- return (false);
- zapping(ZAP_CRYSTAL_SPEAR, powc, beam);
- break;
-
- case SPELL_BOLT_OF_INACCURACY:
- if (spell_direction(spd, beam) == -1)
- return (false);
- zapping(ZAP_BEAM_OF_ENERGY, powc, beam);
- break;
-
- case SPELL_POISONOUS_CLOUD:
- cast_big_c(powc, CLOUD_POISON);
- break;
-
- case SPELL_POISON_ARROW:
- if (spell_direction(spd, beam) == -1)
- return (false);
-
- zapping( ZAP_POISON_ARROW, powc, beam );
- break;
-
- case SPELL_FIRE_STORM:
- cast_fire_storm(powc);
- break;
-
- case SPELL_DETECT_TRAPS:
- strcpy(info, "You detect ");
- strcat(info, (detect_traps(powc) > 0) ? "some traps!" : "nothing.");
- mpr(info);
- break;
-
- case SPELL_BLINK:
- random_blink(true);
- break;
-
- case SPELL_ISKENDERUNS_MYSTIC_BLAST:
- if (spell_direction(spd, beam) == -1)
- return (false);
-
- zapping( ZAP_MYSTIC_BLAST, powc, beam );
- break;
-
- case SPELL_SWARM:
- summon_swarm( powc, false, false );
- break;
-
- case SPELL_SUMMON_HORRIBLE_THINGS:
- summon_things(powc);
- break;
-
- case SPELL_ENSLAVEMENT:
- if (spell_direction(spd, beam) == -1)
- return (false);
- if (spd.isMe)
- {
- canned_msg(MSG_UNTHINKING_ACT);
- return (false);
- }
- zapping(ZAP_ENSLAVEMENT, powc, beam);
- break;
-
- case SPELL_MAGIC_MAPPING:
- if (you.level_type == LEVEL_LABYRINTH || you.level_type == LEVEL_ABYSS)
- mpr("You feel momentarily disoriented.");
- else if (you.level_type == LEVEL_PANDEMONIUM)
- mpr("Your Earth magic cannot map Pandemonium.");
- else
- {
- mpr( "You feel aware of your surroundings." );
- powc = stepdown_value( powc, 10, 10, 40, 45 );
- magic_mapping( 5 + powc, 50 + random2avg( powc * 2, 2 ) );
- }
- break;
-
- case SPELL_HEAL_OTHER:
- if (spell_direction(spd, beam, DIR_NONE, TARG_FRIEND) == -1)
- return (false);
-
- if (spd.isMe)
- {
- mpr("Sorry, it doesn't work like that.");
- return (false);
- }
- zapping(ZAP_HEALING, powc, beam);
- break;
-
- case SPELL_ANIMATE_DEAD:
- mpr("You call on the dead to walk for you.");
- animate_dead(powc + 1, BEH_FRIENDLY, you.pet_target, 1);
- break;
-
- case SPELL_PAIN:
- if (spell_direction(spd, beam) == -1)
- return (false);
- dec_hp(1, false);
- zapping(ZAP_PAIN, powc, beam);
- break;
-
- case SPELL_EXTENSION:
- extension(powc);
- break;
-
- case SPELL_CONTROL_UNDEAD:
- mass_enchantment(ENCH_CHARM, powc, MHITYOU);
- break;
-
- case SPELL_ANIMATE_SKELETON:
- mpr("You attempt to give life to the dead...");
- animate_a_corpse(you.x_pos, you.y_pos, BEH_FRIENDLY, you.pet_target,
- CORPSE_SKELETON);
- break;
-
- case SPELL_VAMPIRIC_DRAINING:
- vampiric_drain(powc);
- break;
-
- case SPELL_SUMMON_WRAITHS:
- summon_undead(powc);
- break;
-
- case SPELL_DETECT_ITEMS:
- detect_items(powc);
- break;
-
- case SPELL_BORGNJORS_REVIVIFICATION:
- cast_revivification(powc);
- break;
-
- case SPELL_BURN:
- burn_freeze(powc, BEAM_FIRE);
- break;
-
- case SPELL_FREEZE:
- burn_freeze(powc, BEAM_COLD);
- break;
-
- case SPELL_SUMMON_ELEMENTAL:
- summon_elemental(powc, 0, 2);
- break;
-
- case SPELL_OZOCUBUS_REFRIGERATION:
- cast_refrigeration(powc);
- break;
-
- case SPELL_STICKY_FLAME:
- if (spell_direction(spd, beam) == -1)
- return (false);
- zapping(ZAP_STICKY_FLAME, powc, beam);
- break;
-
- case SPELL_SUMMON_ICE_BEAST:
- summon_ice_beast_etc(powc, MONS_ICE_BEAST);
- break;
-
- case SPELL_OZOCUBUS_ARMOUR:
- ice_armour(powc, false);
- break;
-
- case SPELL_CALL_IMP:
- if (one_chance_in(3))
- summon_ice_beast_etc(powc, MONS_WHITE_IMP);
- else if (one_chance_in(7))
- summon_ice_beast_etc(powc, MONS_SHADOW_IMP);
- else
- summon_ice_beast_etc(powc, MONS_IMP);
- break;
-
- case SPELL_REPEL_MISSILES:
- missile_prot(powc);
- break;
-
- case SPELL_BERSERKER_RAGE:
- cast_berserk();
- break;
-
- case SPELL_DISPEL_UNDEAD:
- if (spell_direction(spd, beam) == -1)
- return (false);
- zapping(ZAP_DISPEL_UNDEAD, powc, beam);
- break;
-
- case SPELL_GUARDIAN:
- summon_ice_beast_etc(powc, MONS_ANGEL);
- break;
-
- //jmf: FIXME: SPELL_PESTILENCE?
-
- case SPELL_THUNDERBOLT:
- if (spell_direction(spd, beam) == -1)
- return (false);
- zapping(ZAP_LIGHTNING, powc, beam);
- break;
-
- case SPELL_FLAME_OF_CLEANSING:
- if (spell_direction(spd, beam) == -1)
- return (false);
- zapping(ZAP_CLEANSING_FLAME, powc, beam);
- break;
-
- //jmf: FIXME: SPELL_SHINING_LIGHT?
-
- case SPELL_SUMMON_DAEVA:
- summon_ice_beast_etc(powc, MONS_DAEVA);
- break;
-
- case SPELL_ABJURATION_II:
- abjuration(powc);
- break;
-
- // Remember that most holy spells above don't yet use powc!
-
- case SPELL_TWISTED_RESURRECTION:
- cast_twisted(powc, BEH_FRIENDLY, you.pet_target);
- break;
-
- case SPELL_REGENERATION:
- cast_regen(powc);
- break;
-
- case SPELL_BONE_SHARDS:
- cast_bone_shards(powc);
- break;
-
- case SPELL_BANISHMENT:
- if (spell_direction(spd, beam) == -1)
- return (false);
- zapping(ZAP_BANISHMENT, powc, beam);
- break;
-
- case SPELL_CIGOTUVIS_DEGENERATION:
- if (spell_direction(spd, beam) == -1)
- return (false);
-
- if (spd.isMe)
- {
- canned_msg(MSG_UNTHINKING_ACT);
- return (false);
- }
- zapping(ZAP_DEGENERATION, powc, beam);
- break;
-
- case SPELL_STING:
- if (spell_direction(spd, beam) == -1)
- return (false);
- zapping(ZAP_STING, powc, beam);
- break;
-
- case SPELL_SUBLIMATION_OF_BLOOD:
- sublimation(powc);
- break;
-
- case SPELL_TUKIMAS_DANCE:
- dancing_weapon(powc, false);
- break;
-
- case SPELL_HELLFIRE:
- // should only be available from:
- // staff of Dispater & Sceptre of Asmodeus
- if (spell_direction(spd, beam) == -1)
- return (false);
-
- zapping(ZAP_HELLFIRE, powc, beam);
- break;
-
- case SPELL_SUMMON_DEMON:
- mpr("You open a gate to Pandemonium!");
- summon_ice_beast_etc(powc, summon_any_demon(DEMON_COMMON));
- break;
-
- case SPELL_DEMONIC_HORDE:
- mpr("You open a gate to Pandemonium!");
- dem_hor2 = 3 + random2(5);
- for (dem_hor = 0; dem_hor < 4 + dem_hor2; dem_hor++)
- {
- summon_ice_beast_etc(powc, summon_any_demon(DEMON_LESSER));
- }
- break;
-
- case SPELL_SUMMON_GREATER_DEMON:
- mpr("You open a gate to Pandemonium!");
-
- dem_hor = ((random2(powc) <= 5) ? BEH_HOSTILE : BEH_CHARMED);
-
- if (dem_hor == BEH_CHARMED)
- mpr("You don't feel so good about this...");
-
- create_monster( summon_any_demon(DEMON_GREATER), ENCH_ABJ_V, dem_hor,
- you.x_pos, you.y_pos, MHITYOU, 250 );
-
- break;
-
- case SPELL_CORPSE_ROT:
- corpse_rot(0);
- break;
-
- case SPELL_TUKIMAS_VORPAL_BLADE:
- if (!brand_weapon(SPWPN_VORPAL, powc))
- canned_msg(MSG_SPELL_FIZZLES);
- break;
-
- case SPELL_FIRE_BRAND:
- if (!brand_weapon(SPWPN_FLAMING, powc))
- canned_msg(MSG_SPELL_FIZZLES);
- break;
-
- case SPELL_FREEZING_AURA:
- if (!brand_weapon(SPWPN_FREEZING, powc))
- canned_msg(MSG_SPELL_FIZZLES);
- break;
-
- case SPELL_LETHAL_INFUSION:
- if (!brand_weapon(SPWPN_DRAINING, powc))
- canned_msg(MSG_SPELL_FIZZLES);
- break;
-
- case SPELL_MAXWELLS_SILVER_HAMMER:
- if (!brand_weapon(SPWPN_DUMMY_CRUSHING, powc))
- canned_msg(MSG_SPELL_FIZZLES);
- break;
-
- case SPELL_POISON_WEAPON:
- if (!brand_weapon(SPWPN_VENOM, powc))
- canned_msg(MSG_SPELL_FIZZLES);
- break;
-
- case SPELL_CRUSH:
- burn_freeze(powc, BEAM_MISSILE);
- break;
-
- case SPELL_BOLT_OF_IRON:
- if (spell_direction(spd, beam) == -1)
- return (false);
- zapping(ZAP_IRON_BOLT, powc, beam);
- break;
-
- case SPELL_STONE_ARROW:
- if (spell_direction(spd, beam) == -1)
- return (false);
- zapping(ZAP_STONE_ARROW, powc, beam);
- break;
-
- case SPELL_TOMB_OF_DOROKLOHE:
- entomb();
- break;
-
- case SPELL_STONEMAIL:
- stone_scales(powc);
- break;
-
- case SPELL_SHOCK:
- if (spell_direction(spd, beam) == -1)
- return (false);
- zapping(ZAP_ELECTRICITY, powc, beam);
- break;
-
- case SPELL_SWIFTNESS:
- cast_swiftness(powc);
- break;
-
- case SPELL_FLY:
- cast_fly(powc);
- break;
-
- case SPELL_INSULATION:
- cast_insulation(powc);
- break;
-
- case SPELL_ORB_OF_ELECTROCUTION:
- if (spell_direction(spd, beam) == -1)
- return (false);
- zapping(ZAP_ORB_OF_ELECTRICITY, powc, beam);
- break;
-
- case SPELL_DETECT_CREATURES:
- detect_creatures(powc);
- break;
-
- case SPELL_CURE_POISON_II: // poison magic version of cure poison
- cast_cure_poison(powc);
- break;
-
- case SPELL_CONTROL_TELEPORT:
- cast_teleport_control(powc);
- break;
-
- case SPELL_POISON_AMMUNITION:
- cast_poison_ammo();
- break;
-
- case SPELL_RESIST_POISON:
- cast_resist_poison(powc);
- break;
-
- case SPELL_PROJECTED_NOISE:
- project_noise();
- break;
-
- case SPELL_ALTER_SELF:
- if (!enough_hp( you.hp_max / 2, true ))
- {
- mpr( "Your body is in too poor a condition "
- "for this spell to function." );
-
- return (false);
- }
-
- mpr("Your body is suffused with transfigurative energy!");
-
- set_hp( 1 + random2(you.hp), false );
-
- if (!mutate(100, false))
- mpr("Odd... you don't feel any different.");
- break;
-
- case SPELL_DEBUGGING_RAY:
- if (spell_direction(spd, beam, DIR_NONE, TARG_ANY) == -1)
- return (false);
- zapping(ZAP_DEBUGGING_RAY, powc, beam);
- break;
-
- case SPELL_RECALL:
- recall(0);
- break;
-
- case SPELL_PORTAL:
- portal();
- break;
-
- case SPELL_AGONY:
- if (spell_direction(spd, beam) == -1)
- return (false);
-
- if (spd.isMe)
- {
- canned_msg(MSG_UNTHINKING_ACT);
- return (false);
- }
- zapping(ZAP_AGONY, powc, beam);
- break;
-
- case SPELL_SPIDER_FORM:
- transform(powc, TRAN_SPIDER);
- break;
-
- case SPELL_DISRUPT:
- if (spell_direction(spd, beam) == -1)
- return (false);
-
- zapping(ZAP_DISRUPTION, powc, beam);
- break;
-
- case SPELL_DISINTEGRATE:
- if (spell_direction(spd, beam) == -1)
- return (false);
-
- if (spd.isMe)
- {
- canned_msg(MSG_UNTHINKING_ACT);
- return (false);
- }
- zapping(ZAP_DISINTEGRATION, powc, beam);
- break;
-
- case SPELL_BLADE_HANDS:
- transform(powc, TRAN_BLADE_HANDS);
- break;
-
- case SPELL_STATUE_FORM:
- transform(powc, TRAN_STATUE);
- break;
-
- case SPELL_ICE_FORM:
- transform(powc, TRAN_ICE_BEAST);
- break;
-
- case SPELL_DRAGON_FORM:
- transform(powc, TRAN_DRAGON);
- break;
-
- case SPELL_NECROMUTATION:
- transform(powc, TRAN_LICH);
- break;
-
- case SPELL_DEATH_CHANNEL:
- cast_death_channel(powc);
- break;
-
- case SPELL_SYMBOL_OF_TORMENT:
- if (you.is_undead || you.mutation[MUT_TORMENT_RESISTANCE])
- {
- mpr("To torment others, one must first know what torment means. ");
- return (false);
- }
- torment(you.x_pos, you.y_pos);
- break;
-
- case SPELL_DEFLECT_MISSILES:
- deflection(powc);
- break;
-
- case SPELL_ORB_OF_FRAGMENTATION:
- if (spell_direction(spd, beam) == -1)
- return (false);
- zapping(ZAP_ORB_OF_FRAGMENTATION, powc, beam);
- break;
-
- case SPELL_ICE_BOLT:
- if (spell_direction(spd, beam) == -1)
- return (false);
- zapping(ZAP_ICE_BOLT, powc, beam);
- break;
-
- case SPELL_ARC:
- burn_freeze(powc, BEAM_ELECTRICITY);
- break;
-
- case SPELL_AIRSTRIKE:
- airstrike(powc);
- break;
-
- case SPELL_ICE_STORM:
- if (spell_direction(spd, beam) == -1)
- return (false);
- zapping(ZAP_ICE_STORM, powc, beam);
- break;
-
- case SPELL_SHADOW_CREATURES:
- mpr( "Wisps of shadow whirl around you..." );
- create_monster( RANDOM_MONSTER, ENCH_ABJ_II, BEH_FRIENDLY,
- you.x_pos, you.y_pos, you.pet_target, 250 );
- break;
-
- //jmf: new spells 19mar2000
- case SPELL_FLAME_TONGUE:
- if (spell_direction(spd, beam) == -1)
- return (false);
-
- if (spd.isMe)
- {
- canned_msg(MSG_UNTHINKING_ACT);
- return (false);
- }
- zapping(ZAP_FLAME_TONGUE, powc, beam);
-
- /*
- // This is not the place for this sort of power adjustment,
- // it just makes it harder to balance -- bwr
- zapping(ZAP_FLAME_TONGUE, 2 + random2(4) + random2(4)
- + random2(powc) / 25, beam);
- */
- break;
-
- case SPELL_PASSWALL:
- cast_passwall(powc);
- break;
-
- case SPELL_IGNITE_POISON:
- cast_ignite_poison(powc);
- break;
-
- case SPELL_STICKS_TO_SNAKES:
- cast_sticks_to_snakes(powc);
- break;
-
- case SPELL_SUMMON_LARGE_MAMMAL:
- cast_summon_large_mammal(powc);
- break;
-
- case SPELL_SUMMON_DRAGON:
- cast_summon_dragon(powc);
- break;
-
- case SPELL_TAME_BEASTS:
- cast_tame_beasts(powc);
- break;
-
- case SPELL_SLEEP:
- if (spell_direction(spd, beam) == -1)
- return (false);
-
- if (spd.isMe)
- {
- canned_msg(MSG_UNTHINKING_ACT);
- return (false);
- }
-
- zapping(ZAP_SLEEP, powc, beam);
- break;
-
- case SPELL_MASS_SLEEP:
- cast_mass_sleep(powc);
- break;
-
- case SPELL_DETECT_MAGIC:
- mpr("FIXME: implement!");
- break;
-
- case SPELL_DETECT_SECRET_DOORS:
- cast_detect_secret_doors(powc);
- break;
-
- case SPELL_SEE_INVISIBLE:
- cast_see_invisible(powc);
- break;
-
- case SPELL_FORESCRY:
- cast_forescry(powc);
- break;
-
- case SPELL_SUMMON_BUTTERFLIES:
- cast_summon_butterflies(powc);
- break;
-
- case SPELL_WARP_BRAND:
- if (!brand_weapon(SPWPN_DISTORTION, powc))
- canned_msg(MSG_SPELL_FIZZLES);
- break;
-
- case SPELL_SILENCE:
- cast_silence(powc);
- break;
-
- case SPELL_SHATTER:
- cast_shatter(powc);
- break;
-
- case SPELL_DISPERSAL:
- cast_dispersal(powc);
- break;
-
- case SPELL_DISCHARGE:
- cast_discharge(powc);
- break;
-
- case SPELL_BEND:
- cast_bend(powc);
- break;
-
- case SPELL_BACKLIGHT:
- if (spell_direction(spd, beam) == -1)
- return (false);
- if (spd.isMe)
- {
- canned_msg(MSG_UNTHINKING_ACT);
- return (false);
- }
- zapping(ZAP_BACKLIGHT, powc + 10, beam);
- break;
-
- case SPELL_INTOXICATE:
- cast_intoxicate(powc);
- break;
-
- case SPELL_GLAMOUR:
- cast_glamour(powc);
- break;
-
- case SPELL_EVAPORATE:
- cast_evaporate(powc);
- break;
-
- case SPELL_FULSOME_DISTILLATION:
- cast_fulsome_distillation(powc);
- break;
-
- case SPELL_FRAGMENTATION:
- cast_fragmentation(powc);
- break;
-
- case SPELL_AIR_WALK:
- transform(powc, TRAN_AIR);
- break;
-
- case SPELL_SANDBLAST:
- cast_sandblast(powc);
- break;
-
- case SPELL_ROTTING:
- cast_rotting(powc);
- break;
-
- case SPELL_CONDENSATION_SHIELD:
- cast_condensation_shield(powc);
- break;
-
- case SPELL_SEMI_CONTROLLED_BLINK:
- cast_semi_controlled_blink(powc); //jmf: powc is ignored
- break;
-
- case SPELL_STONESKIN:
- cast_stoneskin(powc);
- break;
-
- case SPELL_SIMULACRUM:
- simulacrum(powc);
- break;
-
- case SPELL_CONJURE_BALL_LIGHTNING:
- cast_conjure_ball_lightning(powc);
- break;
-
- case SPELL_CHAIN_LIGHTNING:
- cast_chain_lightning(powc);
- break;
-
- case SPELL_TWIST:
- cast_twist(powc);
- break;
-
- case SPELL_FAR_STRIKE:
- cast_far_strike(powc);
- break;
-
- case SPELL_SWAP:
- cast_swap(powc);
- break;
-
- case SPELL_APPORTATION:
- cast_apportation(powc);
- break;
-
- default:
- mpr("Invalid spell!");
- break;
- } // end switch
-
- return (true);
-} // end you_spells()
-
-void exercise_spell( int spell, bool spc, bool success )
-{
- // (!success) reduces skill increase for miscast spells
- int ndx = 0;
- int skill;
- int exer = 0;
- int workout = 0;
-
- unsigned int disciplines = spell_type(spell);
-
- //jmf: evil evil evil -- exclude HOLY bit
- disciplines &= (~SPTYP_HOLY);
-
- int skillcount = count_bits( disciplines );
-
- if (!success)
- skillcount += 4 + random2(10);
-
- const int diff = spell_difficulty(spell);
- for (ndx = 0; ndx <= SPTYP_LAST_EXPONENT; ndx++)
- {
- if (!spell_typematch( spell, 1 << ndx ))
- continue;
-
- skill = spell_type2skill( 1 << ndx );
- workout = (random2(1 + diff) / skillcount);
-
- if (!one_chance_in(5))
- workout++; // most recently, this was an automatic add {dlb}
-
- exer += exercise( skill, workout );
- }
-
- /* ******************************************************************
- Other recent formulae for the above:
-
- * workout = random2(spell_difficulty(spell_ex)
- * (10 + (spell_difficulty(spell_ex) * 2 )) / 10 / spellsy + 1);
-
- * workout = spell_difficulty(spell_ex)
- * (15 + spell_difficulty(spell_ex)) / 15 / spellsy;
-
- spellcasting had also been generally exercised at the same time
- ****************************************************************** */
-
- if (spc)
- {
- exer += exercise(SK_SPELLCASTING, one_chance_in(3) ? 1
- : random2(1 + random2(diff)));
- }
-
- if (exer)
- did_god_conduct( DID_SPELL_PRACTISE, exer );
-} // end exercise_spell()
-
-static bool send_abyss()
-{
- if (you.level_type != LEVEL_ABYSS)
- {
- mpr("You are cast into the Abyss!");
- more();
- banished(DNGN_ENTER_ABYSS); // sends you to the abyss
- return (true);
- }
- else
- {
- mpr("The world appears momentarily distorted.");
- return (false);
- }
-}
-
-/* This determines how likely it is that more powerful wild magic effects
- * will occur. Set to 100 for the old probabilities (although the individual
- * effects have been made much nastier since then).
- */
-
-bool miscast_effect( unsigned int sp_type, int mag_pow, int mag_fail,
- int force_effect, const char *cause )
-{
-/* sp_type is the type of the spell
- * mag_pow is overall power of the spell or effect (ie its level)
- * mag_fail is the degree to which you failed
- * force_effect forces a certain effect to occur. Currently unused.
- */
- struct bolt beam;
- bool failMsg = true;
-
- int loopj = 0;
- int spec_effect = 0;
- int hurted = 0;
-
- if (sp_type == SPTYP_RANDOM)
- sp_type = 1 << (random2(12));
-
- spec_effect = (mag_pow * mag_fail * (10 + mag_pow) / 7
- * WILD_MAGIC_NASTINESS) / 100;
-
- if (force_effect == 100
- && random2(40) > spec_effect && random2(40) > spec_effect)
- {
- canned_msg(MSG_NOTHING_HAPPENS);
- return (false);
- }
-
- // setup beam
- beam.is_tracer = false;
-
- spec_effect = spec_effect / 100;
-
-#if DEBUG_DIAGNOSTICS
- const int old_fail = spec_effect;
-#endif
-
- spec_effect = random2(spec_effect);
-
- if (spec_effect > 3)
- spec_effect = 3;
- else if (spec_effect < 0)
- spec_effect = 0;
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "Sptype: %d, failure1: %d, failure2: %d",
- sp_type, old_fail, spec_effect );
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- if (force_effect != 100)
- spec_effect = force_effect;
-
- switch (sp_type)
- {
- case SPTYP_CONJURATION:
- switch (spec_effect)
- {
- case 0: // just a harmless message
- switch (random2(10))
- {
- case 0:
- snprintf( info, INFO_SIZE, "Sparks fly from your %s!",
- your_hand(true) );
- mpr(info);
- break;
-
- case 1:
- mpr("The air around you crackles with energy!");
- break;
-
- case 2:
- snprintf( info, INFO_SIZE, "Wisps of smoke drift from your %s.",
- your_hand(true));
- mpr(info);
- break;
- case 3:
- mpr("You feel a strange surge of energy!");
- break;
- case 4:
- mpr("You are momentarily dazzled by a flash of light!");
- break;
- case 5:
- mpr("Strange energies run through your body.");
- break;
- case 6:
- mpr("Your skin tingles.");
- break;
- case 7:
- mpr("Your skin glows momentarily.");
- break;
- case 8:
- canned_msg(MSG_NOTHING_HAPPENS);
- break;
- case 9:
- // josh declares mummies cannot smell {dlb}
- if (you.species != SP_MUMMY)
- mpr("You smell something strange.");
- else
- mpr("Your bandages flutter.");
- }
- break;
-
- case 1: // a bit less harmless stuff
- switch (random2(2))
- {
- case 0:
- snprintf( info, INFO_SIZE, "Smoke pours from your %s!",
- your_hand(true));
- mpr(info);
-
- big_cloud( CLOUD_GREY_SMOKE, you.x_pos, you.y_pos, 20,
- 7 + random2(7) );
- break;
- case 1:
- mpr("A wave of violent energy washes through your body!");
- ouch(6 + random2avg(7, 2), 0, KILLED_BY_WILD_MAGIC, cause);
- break;
- }
- break;
-
- case 2: // rather less harmless stuff
- switch (random2(2))
- {
- case 0:
- mpr("Energy rips through your body!");
- ouch(9 + random2avg(17, 2), 0, KILLED_BY_WILD_MAGIC, cause);
- break;
- case 1:
- mpr("You are caught in a violent explosion!");
- beam.type = SYM_BURST;
- beam.damage = dice_def( 3, 12 );
- beam.flavour = BEAM_MISSILE; // unsure about this
- // BEAM_EXPLOSION instead? {dlb}
-
- beam.target_x = you.x_pos;
- beam.target_y = you.y_pos;
- strcpy(beam.beam_name, "explosion");
- beam.colour = random_colour();
- beam.beam_source = NON_MONSTER;
- beam.thrower = (cause) ? KILL_MISC : KILL_YOU;
- beam.aux_source = cause;
- beam.ex_size = 1;
-
- explosion(beam);
- break;
- }
- break;
-
- case 3: // considerably less harmless stuff
- switch (random2(2))
- {
- case 0:
- mpr("You are blasted with magical energy!");
- ouch(12 + random2avg(29, 2), 0, KILLED_BY_WILD_MAGIC, cause);
- break;
- case 1:
- mpr("There is a sudden explosion of magical energy!");
- beam.type = SYM_BURST;
- beam.damage = dice_def( 3, 20 );
- beam.flavour = BEAM_MISSILE; // unsure about this
- // BEAM_EXPLOSION instead? {dlb}
- beam.target_x = you.x_pos;
- beam.target_y = you.y_pos;
- strcpy(beam.beam_name, "explosion");
- beam.colour = random_colour();
- beam.beam_source = NON_MONSTER;
- beam.thrower = (cause) ? KILL_MISC : KILL_YOU;
- beam.aux_source = cause;
- beam.ex_size = coinflip()?1:2;
-
- explosion(beam);
- break;
- }
- break;
- }
- break; // end conjuration
-
- case SPTYP_ENCHANTMENT:
- switch (spec_effect)
- {
- case 0: // harmless messages only
- switch (random2(10))
- {
- case 0:
- snprintf( info, INFO_SIZE, "Your %s glow momentarily.",
- your_hand(true) );
- mpr(info);
- break;
- case 1:
- mpr("The air around you crackles with energy!");
- break;
- case 2:
- mpr("Multicolored lights dance before your eyes!");
- break;
- case 3:
- mpr("You feel a strange surge of energy!");
- break;
- case 4:
- mpr("Waves of light ripple over your body.");
- break;
- case 5:
- mpr("Strange energies run through your body.");
- break;
- case 6:
- mpr("Your skin tingles.");
- break;
- case 7:
- mpr("Your skin glows momentarily.");
- break;
- case 8:
- canned_msg(MSG_NOTHING_HAPPENS);
- break;
- case 9:
- if (!silenced(you.x_pos, you.y_pos))
- mpr("You hear something strange.", MSGCH_SOUND);
- else if (you.attribute[ATTR_TRANSFORMATION] != TRAN_AIR)
- mpr("Your skull vibrates slightly.");
- else
- canned_msg(MSG_NOTHING_HAPPENS);
- break;
- }
- break;
-
- case 1: // slightly annoying
- switch (random2(2))
- {
- case 0:
- potion_effect(POT_LEVITATION, 20);
- break;
- case 1:
- random_uselessness(2 + random2(7), 0);
- break;
- }
- break;
-
- case 2: // much more annoying
- switch (random2(7))
- {
- case 0:
- case 1:
- case 2:
- mpr("You sense a malignant aura.");
- curse_an_item(0, 0);
- break;
- case 3:
- case 4:
- case 5:
- potion_effect(POT_SLOWING, 10);
- break;
- case 6:
- potion_effect(POT_BERSERK_RAGE, 10);
- break;
- }
- break;
-
- case 3: // potentially lethal
- switch (random2(4))
- {
- case 0:
- do
- {
- curse_an_item(0, 0);
- loopj = random2(3);
- }
- while (loopj != 0);
-
- mpr("You sense an overwhelmingly malignant aura!");
- break;
- case 1:
- potion_effect(POT_PARALYSIS, 10);
- break;
- case 2:
- potion_effect(POT_CONFUSION, 10);
- break;
- case 3:
- mpr("You feel saturated with unharnessed energies!");
- you.magic_contamination += random2avg(19,3);
- break;
- }
- break;
- }
- break; // end enchantments
-
- case SPTYP_TRANSLOCATION:
- switch (spec_effect)
- {
- case 0: // harmless messages only
- switch (random2(10))
- {
- case 0:
- mpr("Space warps around you.");
- break;
- case 1:
- mpr("The air around you crackles with energy!");
- break;
- case 2:
- mpr("You feel a wrenching sensation.");
- break;
- case 3:
- mpr("You feel a strange surge of energy!");
- break;
- case 4:
- mpr("You spin around.");
- break;
- case 5:
- mpr("Strange energies run through your body.");
- break;
- case 6:
- mpr("Your skin tingles.");
- break;
- case 7:
- mpr("The world appears momentarily distorted!");
- break;
- case 8:
- canned_msg(MSG_NOTHING_HAPPENS);
- break;
- case 9:
- mpr("You feel uncomfortable.");
- break;
- }
- break;
-
- case 1: // mostly harmless
- switch (random2(6))
- {
- case 0:
- case 1:
- case 2:
- mpr("You are caught in a localised field of spatial distortion.");
- ouch(4 + random2avg(9, 2), 0, KILLED_BY_WILD_MAGIC, cause);
- break;
- case 3:
- case 4:
- mpr("Space bends around you!");
- random_blink(false);
- ouch(4 + random2avg(7, 2), 0, KILLED_BY_WILD_MAGIC, cause);
- break;
- case 5:
- mpr("Space twists in upon itself!");
- create_monster( MONS_SPATIAL_VORTEX, ENCH_ABJ_III, BEH_HOSTILE,
- you.x_pos, you.y_pos, MHITYOU, 250 );
- break;
- }
- break;
-
- case 2: // less harmless
- switch (random2(7))
- {
- case 0:
- case 1:
- case 2:
- mpr("You are caught in a strong localised spatial distortion.");
- ouch(9 + random2avg(23, 2), 0, KILLED_BY_WILD_MAGIC, cause);
- break;
- case 3:
- case 4:
- mpr("Space warps around you!");
-
- if (one_chance_in(3))
- you_teleport2( true );
- else
- random_blink( false );
-
- ouch(5 + random2avg(9, 2), 0, KILLED_BY_WILD_MAGIC, cause);
- potion_effect(POT_CONFUSION, 40);
- break;
- case 5:
- mpr("Space twists in upon itself!");
-
- for (loopj = 0; loopj < 2 + random2(3); loopj++)
- {
- create_monster( MONS_SPATIAL_VORTEX, ENCH_ABJ_III,
- BEH_HOSTILE, you.x_pos, you.y_pos,
- MHITYOU, 250 );
- }
- break;
- case 6:
- send_abyss();
- break;
- }
- break;
-
- case 3: // much less harmless
-
- switch (random2(4))
- {
- case 0:
- mpr("You are caught in an extremely strong localised spatial distortion!");
- ouch(15 + random2avg(29, 2), 0, KILLED_BY_WILD_MAGIC, cause);
- break;
- case 1:
- mpr("Space warps crazily around you!");
- you_teleport2( true );
-
- ouch(9 + random2avg(17, 2), 0, KILLED_BY_WILD_MAGIC, cause);
- potion_effect(POT_CONFUSION, 60);
- break;
- case 2:
- send_abyss();
- break;
- case 3:
- mpr("You feel saturated with unharnessed energies!");
- you.magic_contamination += random2avg(19,3);
- break;
- }
- break;
- }
- break; // end translocations
-
- case SPTYP_SUMMONING:
- switch (spec_effect)
- {
- case 0: // harmless messages only
- switch (random2(10))
- {
- case 0:
- mpr("Shadowy shapes form in the air around you, then vanish.");
- break;
- case 1:
- if (!silenced(you.x_pos, you.y_pos))
- mpr("You hear strange voices.", MSGCH_SOUND);
- else
- mpr("You feel momentarily dizzy.");
- break;
- case 2:
- mpr("Your head hurts.");
- break;
- case 3:
- mpr("You feel a strange surge of energy!");
- break;
- case 4:
- mpr("Your brain hurts!");
- break;
- case 5:
- mpr("Strange energies run through your body.");
- break;
- case 6:
- mpr("The world appears momentarily distorted.");
- break;
- case 7:
- mpr("Space warps around you.");
- break;
- case 8:
- canned_msg(MSG_NOTHING_HAPPENS);
- break;
- case 9:
- mpr("Distant voices call out to you!");
- break;
- }
- break;
-
- case 1: // a little bad
- switch (random2(6))
- {
- case 0: // identical to translocation
- case 1:
- case 2:
- mpr("You are caught in a localised spatial distortion.");
- ouch(5 + random2avg(9, 2), 0, KILLED_BY_WILD_MAGIC, cause);
- break;
-
- case 3:
- mpr("Space twists in upon itself!");
- create_monster( MONS_SPATIAL_VORTEX, ENCH_ABJ_III, BEH_HOSTILE,
- you.x_pos, you.y_pos, MHITYOU, 250 );
- break;
-
- case 4:
- case 5:
- if (create_monster( summon_any_demon(DEMON_LESSER), ENCH_ABJ_V,
- BEH_HOSTILE, you.x_pos, you.y_pos,
- MHITYOU, 250 ) != -1)
- {
- mpr("Something appears in a flash of light!");
- }
- break;
- }
-
- case 2: // more bad
- switch (random2(6))
- {
- case 0:
- mpr("Space twists in upon itself!");
-
- for (loopj = 0; loopj < 2 + random2(3); loopj++)
- {
- create_monster( MONS_SPATIAL_VORTEX, ENCH_ABJ_III,
- BEH_HOSTILE, you.x_pos, you.y_pos,
- MHITYOU, 250 );
- }
- break;
-
- case 1:
- case 2:
- if (create_monster( summon_any_demon(DEMON_COMMON), ENCH_ABJ_V,
- BEH_HOSTILE, you.x_pos, you.y_pos,
- MHITYOU, 250) != -1)
- {
- mpr("Something forms out of thin air!");
- }
- break;
-
- case 3:
- case 4:
- case 5:
- mpr("A chorus of chattering voices calls out to you!");
- create_monster( summon_any_demon(DEMON_LESSER), ENCH_ABJ_V,
- BEH_HOSTILE, you.x_pos, you.y_pos,
- MHITYOU, 250 );
-
- create_monster( summon_any_demon(DEMON_LESSER), ENCH_ABJ_V,
- BEH_HOSTILE, you.x_pos, you.y_pos,
- MHITYOU, 250 );
-
- if (coinflip())
- {
- create_monster( summon_any_demon(DEMON_LESSER), ENCH_ABJ_V,
- BEH_HOSTILE, you.x_pos, you.y_pos,
- MHITYOU, 250 );
- }
-
- if (coinflip())
- {
- create_monster( summon_any_demon(DEMON_LESSER), ENCH_ABJ_V,
- BEH_HOSTILE, you.x_pos, you.y_pos,
- MHITYOU, 250 );
- }
- break;
- }
- break;
-
- case 3: // more bad
- switch (random2(4))
- {
- case 0:
- if (create_monster( MONS_ABOMINATION_SMALL, 0, BEH_HOSTILE,
- you.x_pos, you.y_pos, MHITYOU, 250 ) != -1)
- {
- mpr("Something forms out of thin air.");
- }
- break;
-
- case 1:
- if (create_monster( summon_any_demon(DEMON_GREATER), 0,
- BEH_HOSTILE, you.x_pos, you.y_pos,
- MHITYOU, 250 ) != -1)
- {
- mpr("You sense a hostile presence.");
- }
- break;
-
- case 2:
- mpr("Something turns its malign attention towards you...");
-
- create_monster( summon_any_demon(DEMON_COMMON), ENCH_ABJ_III,
- BEH_HOSTILE, you.x_pos, you.y_pos,
- MHITYOU, 250 );
-
- create_monster( summon_any_demon(DEMON_COMMON), ENCH_ABJ_III,
- BEH_HOSTILE, you.x_pos, you.y_pos,
- MHITYOU, 250);
-
- if (coinflip())
- {
- create_monster(summon_any_demon(DEMON_COMMON), ENCH_ABJ_III,
- BEH_HOSTILE, you.x_pos, you.y_pos,
- MHITYOU, 250);
- }
- break;
-
- case 3:
- send_abyss();
- break;
- }
- break;
- } // end Summonings
- break;
-
- case SPTYP_DIVINATION:
- switch (spec_effect)
- {
- case 0: // just a harmless message
- switch (random2(10))
- {
- case 0:
- mpr("Weird images run through your mind.");
- break;
- case 1:
- if (!silenced(you.x_pos, you.y_pos))
- mpr("You hear strange voices.", MSGCH_SOUND);
- else
- mpr("Your nose twitches.");
- break;
- case 2:
- mpr("Your head hurts.");
- break;
- case 3:
- mpr("You feel a strange surge of energy!");
- break;
- case 4:
- mpr("Your brain hurts!");
- break;
- case 5:
- mpr("Strange energies run through your body.");
- break;
- case 6:
- mpr("Everything looks hazy for a moment.");
- break;
- case 7:
- mpr("You seem to have forgotten something, but you can't remember what it was!");
- break;
- case 8:
- canned_msg(MSG_NOTHING_HAPPENS);
- break;
- case 9:
- mpr("You feel uncomfortable.");
- break;
- }
- break;
-
- case 1: // more annoying things
- switch (random2(2))
- {
- case 0:
- mpr("You feel slightly disoriented.");
- forget_map(10 + random2(10));
- break;
- case 1:
- potion_effect(POT_CONFUSION, 10);
- break;
- }
- break;
-
- case 2: // even more annoying things
- switch (random2(2))
- {
- case 0:
- if (you.is_undead)
- mpr("You suddenly recall your previous life!");
- else if (lose_stat(STAT_INTELLIGENCE, 1 + random2(3)))
- mpr("You have damaged your brain!");
- else
- mpr("You have a terrible headache.");
- break;
- case 1:
- mpr("You feel lost.");
- forget_map(40 + random2(40));
- break;
- }
-
- potion_effect(POT_CONFUSION, 1); // common to all cases here {dlb}
- break;
-
- case 3: // nasty
- switch (random2(3))
- {
- case 0:
- mpr( forget_spell() ? "You have forgotten a spell!"
- : "You get a splitting headache." );
- break;
- case 1:
- mpr("You feel completely lost.");
- forget_map(100);
- break;
- case 2:
- if (you.is_undead)
- mpr("You suddenly recall your previous life.");
- else if (lose_stat(STAT_INTELLIGENCE, 3 + random2(3)))
- mpr("You have damaged your brain!");
- else
- mpr("You have a terrible headache.");
- break;
- }
-
- potion_effect(POT_CONFUSION, 1); // common to all cases here {dlb}
- break;
- }
- break; // end divinations
-
- case SPTYP_NECROMANCY:
- if (you.religion == GOD_KIKUBAAQUDGHA
- && (!player_under_penance() && you.piety >= 50
- && random2(150) <= you.piety))
- {
- canned_msg(MSG_NOTHING_HAPPENS);
- break;
- }
-
- switch (spec_effect)
- {
- case 0:
- switch (random2(10))
- {
- case 0:
- // mummies cannot smell {dlb}
- if (you.species != SP_MUMMY)
- mpr("You smell decay.");
- break;
- case 1:
- if (!silenced(you.x_pos, you.y_pos))
- mpr("You hear strange and distant voices.", MSGCH_SOUND);
- else
- mpr("You feel homesick.");
- break;
- case 2:
- mpr("Pain shoots through your body.");
- break;
- case 3:
- mpr("Your bones ache.");
- break;
- case 4:
- mpr("The world around you seems to dim momentarily.");
- break;
- case 5:
- mpr("Strange energies run through your body.");
- break;
- case 6:
- mpr("You shiver with cold.");
- break;
- case 7:
- mpr("You sense a malignant aura.");
- break;
- case 8:
- canned_msg(MSG_NOTHING_HAPPENS);
- break;
- case 9:
- mpr("You feel very uncomfortable.");
- break;
- }
- break;
-
- case 1: // a bit nasty
- switch (random2(3))
- {
- case 0:
- if (you.is_undead)
- {
- mpr("You feel weird for a moment.");
- break;
- }
- mpr("Pain shoots through your body!");
- ouch(5 + random2avg(15, 2), 0, KILLED_BY_WILD_MAGIC, cause);
- break;
- case 1:
- mpr("You feel horribly lethargic.");
- potion_effect(POT_SLOWING, 15);
- break;
- case 2:
- // josh declares mummies cannot smell {dlb}
- if (you.species != SP_MUMMY)
- {
- mpr("You smell decay."); // identical to a harmless message
- you.rotting++;
- }
- break;
- }
- break;
-
- case 2: // much nastier
- switch (random2(3))
- {
- case 0:
- mpr("Flickering shadows surround you.");
-
- create_monster( MONS_SHADOW, ENCH_ABJ_II, BEH_HOSTILE,
- you.x_pos, you.y_pos, MHITYOU, 250 );
-
- if (coinflip())
- {
- create_monster( MONS_SHADOW, ENCH_ABJ_II, BEH_HOSTILE,
- you.x_pos, you.y_pos, MHITYOU, 250 );
- }
-
- if (coinflip())
- {
- create_monster( MONS_SHADOW, ENCH_ABJ_II, BEH_HOSTILE,
- you.x_pos, you.y_pos, MHITYOU, 250 );
- }
- break;
-
- case 1:
- if (!player_prot_life() && one_chance_in(3))
- {
- drain_exp();
- break;
- } // otherwise it just flows through...
-
- case 2:
- if (you.is_undead)
- {
- mpr("You feel weird for a moment.");
- break;
- }
- mpr("You convulse helplessly as pain tears through your body!");
- ouch(15 + random2avg(23, 2), 0, KILLED_BY_WILD_MAGIC, cause);
- break;
- }
- break;
-
- case 3: // even nastier
- switch (random2(6))
- {
- case 0:
- if (you.is_undead)
- {
- mpr("Something just walked over your grave. No, really!");
- break;
- }
- mpr("Your body is wracked with pain!");
-
- dec_hp((you.hp / 2) - 1, false);
- break;
-
- case 1:
- mpr("You are engulfed in negative energy!");
-
- if (!player_prot_life())
- {
- drain_exp();
- break;
- } // otherwise it just flows through...
-
- case 2:
- lose_stat(STAT_RANDOM, 1 + random2avg(7, 2));
- break;
-
- case 3:
- if (you.is_undead)
- {
- mpr("You feel terrible.");
- break;
- }
-
- rot_player( random2avg(7, 2) + 1 );
- break;
-
- case 4:
- if (create_monster( MONS_SOUL_EATER, ENCH_ABJ_IV, BEH_HOSTILE,
- you.x_pos, you.y_pos, MHITYOU, 250) != -1)
- {
- mpr("Something reaches out for you...");
- }
- break;
-
- case 5:
- if (create_monster( MONS_REAPER, ENCH_ABJ_IV, BEH_HOSTILE,
- you.x_pos, you.y_pos, MHITYOU, 250) != -1)
- {
- mpr("Death has come for you...");
- }
- break;
- }
- break;
- }
- break; // end necromancy
-
- case SPTYP_TRANSMIGRATION:
- switch (spec_effect)
- {
- case 0: // just a harmless message
- switch (random2(10))
- {
- case 0:
- snprintf( info, INFO_SIZE, "Your %s glow momentarily.",
- your_hand(true));
- mpr(info);
- break;
- case 1:
- mpr("The air around you crackles with energy!");
- break;
- case 2:
- mpr("Multicolored lights dance before your eyes!");
- break;
- case 3:
- mpr("You feel a strange surge of energy!");
- break;
- case 4:
- mpr("Waves of light ripple over your body.");
- break;
- case 5:
- mpr("Strange energies run through your body.");
- break;
- case 6:
- mpr("Your skin tingles.");
- break;
- case 7:
- mpr("Your skin glows momentarily.");
- break;
- case 8:
- canned_msg(MSG_NOTHING_HAPPENS);
- break;
- case 9:
- // mummies cannot smell
- if (you.species != SP_MUMMY)
- mpr("You smell something strange.");
- break;
- }
- break;
-
- case 1: // slightly annoying
- switch (random2(2))
- {
- case 0:
- mpr("Your body is twisted painfully.");
- ouch(1 + random2avg(11, 2), 0, KILLED_BY_WILD_MAGIC, cause);
- break;
- case 1:
- random_uselessness(2 + random2(7), 0);
- break;
- }
- break;
-
- case 2: // much more annoying
- switch (random2(4))
- {
- case 0:
- mpr("Your body is twisted very painfully!");
- ouch(3 + random2avg(23, 2), 0, KILLED_BY_WILD_MAGIC, cause);
- break;
- case 1:
- mpr("You feel saturated with unharnessed energies!");
- you.magic_contamination += random2avg(19,3);
- break;
- case 2:
- potion_effect(POT_PARALYSIS, 10);
- break;
- case 3:
- potion_effect(POT_CONFUSION, 10);
- break;
- }
- break;
-
- case 3: // even nastier
-
- switch (random2(3))
- {
- case 0:
- mpr("Your body is flooded with distortional energies!");
- you.magic_contamination += random2avg(35, 3);
-
- ouch(3 + random2avg(18, 2), 0, KILLED_BY_WILD_MAGIC, cause);
- break;
-
- case 1:
- mpr("You feel very strange.");
- delete_mutation(100);
- ouch(5 + random2avg(23, 2), 0, KILLED_BY_WILD_MAGIC, cause);
- break;
-
- case 2:
- mpr("Your body is distorted in a weirdly horrible way!");
- failMsg = !give_bad_mutation();
- if (coinflip())
- give_bad_mutation(false, failMsg);
-
- ouch(5 + random2avg(23, 2), 0, KILLED_BY_WILD_MAGIC, cause);
- break;
- }
- break;
- }
- break; // end transmigrations
-
- case SPTYP_FIRE:
- switch (spec_effect)
- {
- case 0: // just a harmless message
- switch (random2(10))
- {
- case 0:
- snprintf( info, INFO_SIZE, "Sparks fly from your %s!",
- your_hand(true));
- mpr(info);
- break;
- case 1:
- mpr("The air around you burns with energy!");
- break;
- case 2:
- snprintf( info, INFO_SIZE, "Wisps of smoke drift from your %s.",
- your_hand(true));
- mpr(info);
- break;
- case 3:
- mpr("You feel a strange surge of energy!");
- break;
- case 4:
- // mummies cannot smell
- if (you.species != SP_MUMMY)
- mpr("You smell smoke.");
- break;
- case 5:
- mpr("Heat runs through your body.");
- break;
- case 6:
- mpr("You feel uncomfortably hot.");
- break;
- case 7:
- mpr("Lukewarm flames ripple over your body.");
- break;
- case 8:
- canned_msg(MSG_NOTHING_HAPPENS);
- break;
- case 9:
- if (!silenced(you.x_pos, you.y_pos))
- mpr("You hear a sizzling sound.", MSGCH_SOUND);
- else
- mpr("You feel like you have heartburn.");
- break;
- }
- break;
-
- case 1: // a bit less harmless stuff
- switch (random2(2))
- {
- case 0:
- snprintf( info, INFO_SIZE, "Smoke pours from your %s!",
- your_hand(true) );
- mpr(info);
-
- big_cloud( CLOUD_GREY_SMOKE + random2(3),
- you.x_pos, you.y_pos, 20, 7 + random2(7) );
- break;
-
- case 1:
- mpr("Flames sear your flesh.");
- scrolls_burn(3, OBJ_SCROLLS);
-
- if (player_res_fire() < 0)
- {
- ouch(2 + random2avg(13, 2), 0, KILLED_BY_WILD_MAGIC, cause);
- }
- break;
- }
- break;
-
- case 2: // rather less harmless stuff
- switch (random2(2))
- {
- case 0:
- mpr("You are blasted with fire.");
-
- ouch( check_your_resists( 5 + random2avg(29, 2), 2 ), 0,
- KILLED_BY_WILD_MAGIC, cause );
-
- scrolls_burn( 5, OBJ_SCROLLS );
- break;
-
- case 1:
- mpr("You are caught a fiery explosion!");
-
- beam.type = SYM_BURST;
- beam.damage = dice_def( 3, 14 );
- beam.flavour = BEAM_FIRE;
- beam.target_x = you.x_pos;
- beam.target_y = you.y_pos;
- strcpy(beam.beam_name, "explosion");
- beam.colour = RED;
- beam.beam_source = NON_MONSTER;
- beam.thrower = (cause) ? KILL_MISC : KILL_YOU;
- beam.aux_source = cause;
- beam.ex_size = 1;
-
- explosion(beam);
- break;
- }
- break;
-
- case 3: // considerably less harmless stuff
- switch (random2(3))
- {
- case 0:
- mpr("You are blasted with searing flames!");
-
- ouch( check_your_resists( 9 + random2avg(33, 2), 2 ), 0,
- KILLED_BY_WILD_MAGIC, cause );
-
- scrolls_burn( 10, OBJ_SCROLLS );
- break;
- case 1:
- mpr("There is a sudden and violent explosion of flames!");
-
- beam.type = SYM_BURST;
- beam.damage = dice_def( 3, 20 );
- beam.flavour = BEAM_FIRE;
- beam.target_x = you.x_pos;
- beam.target_y = you.y_pos;
- strcpy( beam.beam_name, "fireball" );
- beam.colour = RED;
- beam.beam_source = NON_MONSTER;
- beam.thrower = (cause) ? KILL_MISC : KILL_YOU;
- beam.aux_source = cause;
- beam.ex_size = coinflip()?1:2;
-
- explosion(beam);
- break;
-
- case 2:
- mpr("You are covered in liquid fire!");
- you.duration[DUR_LIQUID_FLAMES] += random2avg(7, 3) + 1;
- break;
- }
- break;
- }
- break; // end fire
-
- case SPTYP_ICE:
- switch (spec_effect)
- {
- case 0: // just a harmless message
- switch (random2(10))
- {
- case 0:
- mpr("You shiver with cold.");
- break;
- case 1:
- mpr("A chill runs through your body.");
- break;
- case 2:
- snprintf( info, INFO_SIZE, "Wisps of condensation drift from your %s.",
- your_hand(true));
- mpr(info);
- break;
- case 3:
- mpr("You feel a strange surge of energy!");
- break;
- case 4:
- snprintf( info, INFO_SIZE,"Your %s feel numb with cold.",
- your_hand(true));
- mpr(info);
- break;
- case 5:
- mpr("A chill runs through your body.");
- break;
- case 6:
- mpr("You feel uncomfortably cold.");
- break;
- case 7:
- mpr("Frost covers your body.");
- break;
- case 8:
- canned_msg(MSG_NOTHING_HAPPENS);
- break;
- case 9:
- if (!silenced(you.x_pos, you.y_pos))
- mpr("You hear a crackling sound.", MSGCH_SOUND);
- else
- mpr("A snowflake lands on your nose.");
- break;
- }
- break;
-
- case 1: // a bit less harmless stuff
- switch (random2(2))
- {
- case 0:
- mpr("You feel extremely cold.");
- break;
- case 1:
- mpr("You are covered in a thin layer of ice");
- scrolls_burn(2, OBJ_POTIONS);
-
- if (player_res_cold() < 0)
- ouch(4 + random2avg(5, 2), 0, KILLED_BY_WILD_MAGIC, cause);
- break;
- }
- break;
-
- case 2: // rather less harmless stuff
- switch (random2(2))
- {
- case 0:
- mpr("Heat is drained from your body.");
-
- ouch(check_your_resists(5 + random2(6) + random2(7), 3), 0,
- KILLED_BY_WILD_MAGIC, cause);
-
- scrolls_burn(4, OBJ_POTIONS);
- break;
-
- case 1:
- mpr("You are caught in an explosion of ice and frost!");
-
- beam.type = SYM_BURST;
- beam.damage = dice_def( 3, 11 );
- beam.flavour = BEAM_COLD;
- beam.target_x = you.x_pos;
- beam.target_y = you.y_pos;
- strcpy(beam.beam_name, "explosion");
- beam.colour = WHITE;
- beam.beam_source = NON_MONSTER;
- beam.thrower = (cause) ? KILL_MISC : KILL_YOU;
- beam.aux_source = cause;
- beam.ex_size = 1;
-
- explosion(beam);
- break;
- }
- break;
-
- case 3: // less harmless stuff
- switch (random2(2))
- {
- case 0:
- mpr("You are blasted with ice!");
-
- ouch(check_your_resists(9 + random2avg(23, 2), 3), 0,
- KILLED_BY_WILD_MAGIC, cause);
-
- scrolls_burn(9, OBJ_POTIONS);
- break;
- case 1:
- snprintf( info, INFO_SIZE,"Freezing gasses pour from your %s!",
- your_hand(true));
- mpr(info);
-
- big_cloud(CLOUD_COLD, you.x_pos, you.y_pos, 20,
- 8 + random2(4));
- break;
- }
- break;
- }
- break; // end ice
-
- case SPTYP_EARTH:
- switch (spec_effect)
- {
- case 0: // just a harmless message
- case 1:
- switch (random2(10))
- {
- case 0:
- mpr("You feel earthy.");
- break;
- case 1:
- mpr("You are showered with tiny particles of grit.");
- break;
- case 2:
- snprintf( info, INFO_SIZE,"Sand pours from your %s.",
- your_hand(true));
- mpr(info);
- break;
- case 3:
- mpr("You feel a surge of energy from the ground.");
- break;
- case 4:
- if (!silenced(you.x_pos, you.y_pos))
- mpr("You hear a distant rumble.", MSGCH_SOUND);
- else
- mpr("You sympathise with the stones.");
- break;
- case 5:
- mpr("You feel gritty.");
- break;
- case 6:
- mpr("You feel momentarily lethargic.");
- break;
- case 7:
- mpr("Motes of dust swirl before your eyes.");
- break;
- case 8:
- canned_msg(MSG_NOTHING_HAPPENS);
- break;
- case 9:
- strcpy(info, "Your ");
- strcat(info, (you.species == SP_NAGA) ? "underbelly feels" :
- (you.species == SP_CENTAUR) ? "hooves feel"
- : "feet feel");
- strcat(info, " warm.");
- mpr(info);
- break;
- }
- break;
-
- case 2: // slightly less harmless stuff
- switch (random2(1))
- {
- case 0:
- switch (random2(3))
- {
- case 0:
- mpr("You are hit by flying rocks!");
- break;
- case 1:
- mpr("You are blasted with sand!");
- break;
- case 2:
- mpr("Rocks fall onto you out of nowhere!");
- break;
- }
-
- hurted = random2avg(13, 2) + 10;
- hurted -= random2(1 + player_AC());
-
- ouch(hurted, 0, KILLED_BY_WILD_MAGIC, cause);
- break;
- }
- break;
-
- case 3: // less harmless stuff
- switch (random2(1))
- {
- case 0:
- mpr("You are caught in an explosion of flying shrapnel!");
-
- beam.type = SYM_BURST;
- beam.damage = dice_def( 3, 15 );
- beam.flavour = BEAM_FRAG;
- beam.target_x = you.x_pos;
- beam.target_y = you.y_pos;
- strcpy(beam.beam_name, "explosion");
- beam.colour = CYAN;
-
- if (one_chance_in(5))
- beam.colour = BROWN;
- if (one_chance_in(5))
- beam.colour = LIGHTCYAN;
-
- beam.beam_source = NON_MONSTER;
- beam.thrower = (cause) ? KILL_MISC : KILL_YOU;
- beam.aux_source = cause;
- beam.ex_size = 1;
-
- explosion(beam);
- break;
- }
- break;
- }
- break; // end Earth
-
- case SPTYP_AIR:
- switch (spec_effect)
- {
- case 0: // just a harmless message
- switch (random2(10))
- {
- case 0:
- mpr("Ouch! You gave yourself an electric shock.");
- break;
- case 1:
- mpr("You feel momentarily weightless.");
- break;
- case 2:
- snprintf( info, INFO_SIZE, "Wisps of vapour drift from your %s.",
- your_hand(true));
- mpr(info);
- break;
- case 3:
- mpr("You feel a strange surge of energy!");
- break;
- case 4:
- mpr("You feel electric!");
- break;
- case 5:
- snprintf( info, INFO_SIZE, "Sparks of electricity dance between your %s.",
- your_hand(true));
- mpr(info);
- break;
- case 6:
- mpr("You are blasted with air!");
- break;
- case 7:
- // mummies cannot smell
- if (!silenced(you.x_pos, you.y_pos))
- mpr("You hear a whooshing sound.", MSGCH_SOUND);
- else if (you.species != SP_MUMMY)
- mpr("You smell ozone.");
- break;
- case 8:
- canned_msg(MSG_NOTHING_HAPPENS);
- break;
- case 9:
- // mummies cannot smell
- if (!silenced(you.x_pos, you.y_pos))
- mpr("You hear a crackling sound.", MSGCH_SOUND);
- else if (you.species != SP_MUMMY)
- mpr("You smell something musty.");
- break;
- }
- break;
-
- case 1: // a bit less harmless stuff
- switch (random2(2))
- {
- case 0:
- mpr("There is a short, sharp shower of sparks.");
- break;
- case 1:
- snprintf( info, INFO_SIZE, "The wind %s around you!",
- silenced(you.x_pos, you.y_pos) ? "whips" : "howls");
- mpr(info);
- break;
- }
- break;
-
- case 2: // rather less harmless stuff
- switch (random2(2))
- {
- case 0:
- mpr("Electricity courses through your body.");
- ouch(check_your_resists(4 + random2avg(9, 2), 5), 0,
- KILLED_BY_WILD_MAGIC, cause);
- break;
- case 1:
- snprintf( info, INFO_SIZE, "Noxious gasses pour from your %s!",
- your_hand(true));
- mpr(info);
-
- big_cloud(CLOUD_STINK, you.x_pos, you.y_pos, 20,
- 9 + random2(4));
- break;
- }
- break;
-
- case 3: // less harmless stuff
- switch (random2(2))
- {
- case 0:
- mpr("You are caught in an explosion of electrical discharges!");
-
- beam.type = SYM_BURST;
- beam.damage = dice_def( 3, 8 );
- beam.flavour = BEAM_ELECTRICITY;
- beam.target_x = you.x_pos;
- beam.target_y = you.y_pos;
- strcpy(beam.beam_name, "explosion");
- beam.colour = LIGHTBLUE;
- beam.beam_source = NON_MONSTER;
- beam.thrower = (cause) ? KILL_MISC : KILL_YOU;
- beam.aux_source = cause;
- beam.ex_size = one_chance_in(4)?1:2;
-
- explosion(beam);
- break;
- case 1:
- snprintf( info, INFO_SIZE, "Venomous gasses pour from your %s!",
- your_hand(true));
- mpr(info);
-
- big_cloud( CLOUD_POISON, you.x_pos, you.y_pos, 20,
- 8 + random2(5) );
- break;
- }
- break;
- }
- break; // end air
-
- case SPTYP_POISON:
- switch (spec_effect)
- {
- case 0: // just a harmless message
- switch (random2(10))
- {
- case 0:
- mpr("You feel mildly nauseous.");
- break;
- case 1:
- mpr("You feel slightly ill.");
- break;
- case 2:
- snprintf( info, INFO_SIZE, "Wisps of poison gas drift from your %s.",
- your_hand(true) );
- mpr(info);
- break;
- case 3:
- mpr("You feel a strange surge of energy!");
- break;
- case 4:
- mpr("You feel faint for a moment.");
- break;
- case 5:
- mpr("You feel sick.");
- break;
- case 6:
- mpr("You feel odd.");
- break;
- case 7:
- mpr("You feel weak for a moment.");
- break;
- case 8:
- canned_msg(MSG_NOTHING_HAPPENS);
- break;
- case 9:
- if (!silenced(you.x_pos, you.y_pos))
- mpr("You hear a slurping sound.", MSGCH_SOUND);
- else if (you.species != SP_MUMMY)
- mpr("You taste almonds.");
- break;
- }
- break;
-
- case 1: // a bit less harmless stuff
- switch (random2(2))
- {
- case 0:
- if (player_res_poison())
- {
- canned_msg(MSG_NOTHING_HAPPENS);
- return (false);
- }
-
- mpr("You feel sick.");
- poison_player( 2 + random2(3) );
- break;
-
- case 1:
- snprintf( info, INFO_SIZE, "Noxious gasses pour from your %s!",
- your_hand(true) );
- mpr(info);
-
- place_cloud(CLOUD_STINK, you.x_pos, you.y_pos,
- 2 + random2(4));
- break;
- }
- break;
-
- case 2: // rather less harmless stuff
- switch (random2(3))
- {
- case 0:
- if (player_res_poison())
- {
- canned_msg(MSG_NOTHING_HAPPENS);
- return (false);
- }
-
- mpr("You feel very sick.");
- poison_player( 3 + random2avg(9, 2) );
- break;
-
- case 1:
- mpr("Noxious gasses pour from your hands!");
- big_cloud(CLOUD_STINK, you.x_pos, you.y_pos, 20,
- 8 + random2(5));
- break;
-
- case 2:
- if (player_res_poison())
- {
- canned_msg(MSG_NOTHING_HAPPENS);
- return (false);
- }
- lose_stat(STAT_RANDOM, 1);
- break;
- }
- break;
-
- case 3: // less harmless stuff
- switch (random2(3))
- {
- case 0:
- if (player_res_poison())
- {
- canned_msg(MSG_NOTHING_HAPPENS);
- return (false);
- }
-
- mpr("You feel incredibly sick.");
- poison_player( 10 + random2avg(19, 2) );
- break;
- case 1:
- snprintf( info, INFO_SIZE, "Venomous gasses pour from your %s!",
- your_hand(true));
- mpr(info);
-
- big_cloud(CLOUD_POISON, you.x_pos, you.y_pos, 20,
- 7 + random2(7));
- break;
- case 2:
- if (player_res_poison())
- {
- canned_msg(MSG_NOTHING_HAPPENS);
- return (false);
- }
-
- lose_stat(STAT_RANDOM, 1 + random2avg(5, 2));
- break;
- }
- break;
- }
- break; // end poison
- }
-
- return (true);
-} // end miscast_effect()
diff --git a/stone_soup/crawl-ref/source/spl-cast.h b/stone_soup/crawl-ref/source/spl-cast.h
deleted file mode 100644
index f04efa7332..0000000000
--- a/stone_soup/crawl-ref/source/spl-cast.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * File: spl-cast.cc
- * Summary: Spell casting functions.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef SPL_CAST_H
-#define SPL_CAST_H
-
-char list_spells( void );
-int spell_fail( int spell );
-int calc_spell_power( int spell, bool apply_intel, bool fail_rate_chk = false );
-int spell_enhancement( unsigned int typeflags );
-
-// last updaetd 12may2000 {dlb}
-/* ***********************************************************************
- * called from: it_use3 - spell
- * *********************************************************************** */
-void exercise_spell( int spell_ex, bool spc, bool divide );
-
-
-// last updaetd 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-bool cast_a_spell( void );
-
-
-// last updaetd 12may2000 {dlb}
-/* ***********************************************************************
- * called from: ability - debug - it_use3 - spell
- * *********************************************************************** */
-bool your_spells( int spc2, int powc = 0, bool allow_fail = true );
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - decks - fight - it_use2 - it_use3 - item_use - items -
- * misc - mstuff2 - religion - spell - spl-book - spells4
- * *********************************************************************** */
-bool miscast_effect( unsigned int sp_type, int mag_pow, int mag_fail,
- int force_effect, const char *cause = NULL );
-
-
-#endif
diff --git a/stone_soup/crawl-ref/source/spl-data.h b/stone_soup/crawl-ref/source/spl-data.h
deleted file mode 100644
index b016ecb552..0000000000
--- a/stone_soup/crawl-ref/source/spl-data.h
+++ /dev/null
@@ -1,1468 +0,0 @@
-/*
- In case anyone ever wants to add new spells, or just understand my reasons
- for putting a particular spell into a particular type, read on:
-
- Guidelines for typing spells
-
- Conjuration
- This type has a near monopoly on effective and relatively risk-free combat
- spells. All other types of combat spells are either indirect (enchantments),
- risky/detrimental/not versatile (necromancy) or just plain crappy (burn and
- freeze), although smiting (holy) is not too bad.
- Conjuration spells all involve the magical creation of matter and/or energy
- (which are the same thing anyway, right?). They are distinguished from
- summoning spells in that they do not involve the summoning of an entire
- creature from another place.
-
- Enchantment
- These spells mostly cause some kind of durational effect, which lasts only
- until the magic wears off. Enchantments are distinguished from trans-
- migrations in that the latter cause a permanent alteration in something
- which persists even after the magic has faded, while the effects of the
- former last only so long as the magic does. Sometimes enchantments may take
- advantage of the more powerful aspects of transmigration to induce some
- kind of radical change (eg polymorph).
- Some enchantments would also fall under the description of 'meta-magic'
- spells, like Selective Amnesia and Remove Curse (and if I ever implement
- Dispel Magic, it will be an enchantment).
- It is possible that some divinations could be retyped as
- divination/enchantment, as they appear to be primarily concerned with
- detecting enchantments. Detect Curse and Identify are what I'm thinking
- of here.
-
- Fire and Ice
- These are quite obvious. I'm trying to keep these two balanced with each
- other, but it can be difficult. I have to weigh up some useful fire spells,
- like Sticky Flame, Fireball, Ring of Flames and Firestorm, and the fact that
- Fire wizards have an advantage when summoning fire elementals by either
- spell or device, with the also quite useful Refrigeration, Ice Armour and
- Freezing Cloud. Ice wizards don't have a corresponding advantage with
- water elementals, because water and ice are two different things (ice is not
- necessarily water ice, for example).
- Generally, Fire spells tend towards chaos, disorder and entropy, while
- Ice spells tend towards order and stasis. But these trends are rather
- underdeveloped at the moment.
- Note that just about the only reason one would ever choose an ice or fire
- wizard over a conjurer would be the resistance gained at level 12.
- Especially because having a fire specialisation basically removes any chance
- of ever using ice spells effectively, and vice versa.
-
- Transmigration
- See enchantments.
-
- Necromancy
- This is the fun stuff. Necromancy is a mixed bag of many and various
- different kinds of spells, with a few common themes:
- -Differentiation of living, dead and undead. Some necromancy affects only
- the living (pain, vampiric draining etc), some affects only the dead
- (animate dead, twisted resurrection etc), and some affects only undead
- (dispel and control undead).
- -Actual or potential harm: eg risk in Death's Door, hp loss with Pain,
- disease with summon greater undead, etc. Also loss of potential experience
- gain with bolt of draining and degeneration.
- -Material components are central to many of the spells.
- -Some spells duplicate effects of other types, but do so in a different
- (neither superior or inferior) way. Eg bone shards is a very powerful spell
- for only 3 magic points, but requires preparation. Also, necromantic
- healing spells are different and more idiosyncratic than holy healing.
- Although regeneration is usually less useful than lesser healing and is
- level 3 instead of 2, it can be cast before combat (when 1 turn spent
- casting is less important), and is affected by extension.
- -Generally unholy theme of spells (I mean, Twisted Resurrection?).
-
- Holy
- The Holy type is also fairly various, but is rather less interesting than
- necromancy (after all, priests are better at fighting than necromancers).
- Holy spells do things like driving off undead and healing. Note that I
- consider item stickycursing to be more of an issue for enchantments rather
- than holy magic, which is why remove curse is enchantment.
-
- Summoning
- These spells involve bringing a creature from somewhere else (possibly on
- another plane of existence) to this world to do battle for the caster. Some
- future summonings could potentially be combination conjuration/summoning
- spells, eg the ball lightning spell I keep planning to implement.
- Also, potential exists for some risky high-level spells, maybe demon
- summoning?
-
- Divination
- These spells provide information to the caster. A diviner class would be
- possible (and having detect curse and identify would be very handy), but
- would be extremely difficult to play - there is no potential in this type
- for combat spells.
-
- Translocation
- Translocation spells deal with teleportation etc, also interplanar travel
- (eg Banishment, and the planned Gate spell).
- It is possible that I may give summoners some special access to trans-
- locations due to the obvious similarities.
-
- Poison
- These spells all involve poison. Most are also conjurations.
- I don't plan to implement a 'Poisoner' class, as it would become unplayable
- deep in the dungeon where most monsters are poison resistant.
-
- Many spells use magic from two types. These spells are equally
- available to either type; a conjurer is no worse at a fire/conjuration than
- at a pure conjuration. I guess a spell could be of three types, but they
- would have to be types with short names (limited space in the spell
- windows).
- - Note : this is no longer true, with the implementation of magic skills.
- Your skill for a spell is effectively the average of all types used in it.
- Poison has no skills, but still has a staff
-
-
-*/
-
-/*
- * When adding enchantments, must add them to extension as well!
- *
- * spells to do:
- * Contingency?
- * Trigger contingency
- * Preserve Corpses
- * Permanency
- * Ball Lightning
- * Explosive rune?
- * Fennel wands
- * More summonings!
- */
-
-#ifndef SPLDATA_H
-#define SPLDATA_H
-
-
-{
- SPELL_IDENTIFY, "Identify",
- SPTYP_DIVINATION,
- SPFLAG_NONE,
- 6
-},
-
-{
- SPELL_TELEPORT_SELF, "Teleport Self",
- SPTYP_TRANSLOCATION,
- SPFLAG_NONE,
- 5
-},
-
-{
- SPELL_CAUSE_FEAR, "Cause Fear",
- SPTYP_ENCHANTMENT,
- SPFLAG_NONE,
- 5
-},
-
-{
- SPELL_CREATE_NOISE, "Create Noise",
- SPTYP_ENCHANTMENT,
- SPFLAG_NONE,
- 1
-},
-
-{
- SPELL_REMOVE_CURSE, "Remove Curse",
- SPTYP_ENCHANTMENT,
- SPFLAG_NONE,
- 5
-},
-
-{
- SPELL_MAGIC_DART, "Magic Dart",
- SPTYP_CONJURATION,
- SPFLAG_DIR_OR_TARGET,
- 1
-},
-
-{
- SPELL_FIREBALL, "Fireball",
- SPTYP_CONJURATION | SPTYP_FIRE,
- SPFLAG_DIR_OR_TARGET,
- 6
-},
-
-{
- SPELL_SWAP, "Swap",
- SPTYP_TRANSLOCATION,
- SPFLAG_NONE,
- 4
-},
-
-{
- SPELL_APPORTATION, "Apportation",
- SPTYP_TRANSLOCATION,
- SPFLAG_NONE,
- 1
-},
-
-{
- SPELL_TWIST, "Twist",
- SPTYP_TRANSLOCATION,
- SPFLAG_DIR_OR_TARGET,
- 1
-},
-
-{
- SPELL_CONJURE_FLAME, "Conjure Flame",
- SPTYP_CONJURATION | SPTYP_FIRE,
- SPFLAG_GRID | SPFLAG_NOT_SELF,
- 3
-},
-
-{
- SPELL_DIG, "Dig",
- SPTYP_TRANSMIGRATION | SPTYP_EARTH,
- SPFLAG_DIR_OR_TARGET | SPFLAG_NOT_SELF,
- 4
-},
-
-{
- SPELL_BOLT_OF_FIRE, "Bolt of Fire",
- SPTYP_CONJURATION | SPTYP_FIRE,
- SPFLAG_DIR_OR_TARGET,
- 5
-},
-
-{
- SPELL_BOLT_OF_COLD, "Bolt of Cold",
- SPTYP_CONJURATION | SPTYP_ICE,
- SPFLAG_DIR_OR_TARGET,
- 5
-},
-
-{
- SPELL_LIGHTNING_BOLT, "Lightning Bolt",
- SPTYP_CONJURATION | SPTYP_AIR,
- SPFLAG_DIR_OR_TARGET,
- 6
-},
-
-{
- SPELL_BOLT_OF_MAGMA, "Bolt of Magma",
- SPTYP_CONJURATION | SPTYP_FIRE | SPTYP_EARTH,
- SPFLAG_DIR_OR_TARGET,
- 5
-},
-
-{
- SPELL_POLYMORPH_OTHER, "Polymorph Other",
- SPTYP_TRANSMIGRATION, // removed enchantment, wasn't needed -- bwr
- SPFLAG_DIR_OR_TARGET | SPFLAG_NOT_SELF,
- 5
-},
-
-{
- SPELL_SLOW, "Slow",
- SPTYP_ENCHANTMENT,
- SPFLAG_DIR_OR_TARGET,
- 3
-},
-
-{
- SPELL_HASTE, "Haste",
- SPTYP_ENCHANTMENT,
- SPFLAG_DIR_OR_TARGET | SPFLAG_HELPFUL,
- 6 // lowered to 6 from 8, since its easily available from various items
- // and Swiftness is level 2 (and gives a similar effect). Its also
- // not that much better than Invisibility. -- bwr
-},
-
-{
- SPELL_PARALYZE, "Paralyze",
- SPTYP_ENCHANTMENT,
- SPFLAG_DIR_OR_TARGET,
- 4
-},
-
-{
- SPELL_CONFUSE, "Confuse",
- SPTYP_ENCHANTMENT,
- SPFLAG_DIR_OR_TARGET,
- 3
-},
-
-{
- SPELL_INVISIBILITY, "Invisibility",
- SPTYP_ENCHANTMENT,
- SPFLAG_DIR_OR_TARGET | SPFLAG_HELPFUL,
- 6
-},
-
-{
- SPELL_THROW_FLAME, "Throw Flame",
- SPTYP_CONJURATION | SPTYP_FIRE,
- SPFLAG_DIR_OR_TARGET,
- 2
-},
-
-{
- SPELL_THROW_FROST, "Throw Frost",
- SPTYP_CONJURATION | SPTYP_ICE,
- SPFLAG_DIR_OR_TARGET,
- 2
-},
-
-{
- SPELL_CONTROLLED_BLINK, "Controlled Blink",
- SPTYP_TRANSLOCATION,
- SPFLAG_NONE,
- 8
-},
-
-{
- SPELL_FREEZING_CLOUD, "Freezing Cloud",
- SPTYP_CONJURATION | SPTYP_ICE | SPTYP_AIR,
- SPFLAG_GRID,
- 7
-},
-
-{
- SPELL_MEPHITIC_CLOUD, "Mephitic Cloud",
- SPTYP_CONJURATION | SPTYP_POISON | SPTYP_AIR,
- SPFLAG_DIR_OR_TARGET,
- 3
-},
-
-{
- SPELL_RING_OF_FLAMES, "Ring of Flames",
- SPTYP_ENCHANTMENT | SPTYP_FIRE,
- SPFLAG_NONE,
- 8
-},
-
-{
- SPELL_RESTORE_STRENGTH, "Restore Strength",
- SPTYP_HOLY,
- SPFLAG_NONE,
- 2
-},
-
-{
- SPELL_RESTORE_INTELLIGENCE, "Restore Intelligence",
- SPTYP_HOLY,
- SPFLAG_NONE,
- 2
-},
-
-{
- SPELL_RESTORE_DEXTERITY, "Restore Dexterity",
- SPTYP_HOLY,
- SPFLAG_NONE,
- 2
-},
-
-{
- SPELL_VENOM_BOLT, "Venom Bolt",
- SPTYP_CONJURATION | SPTYP_POISON,
- SPFLAG_DIR_OR_TARGET,
- 5
-},
-
-{
- SPELL_OLGREBS_TOXIC_RADIANCE, "Olgreb's Toxic Radiance",
- SPTYP_POISON,
- SPFLAG_NONE,
- 4
-},
-
-{
- SPELL_TELEPORT_OTHER, "Teleport Other",
- SPTYP_TRANSLOCATION,
- SPFLAG_DIR_OR_TARGET | SPFLAG_NOT_SELF,
- 4
-},
-
-{
- SPELL_LESSER_HEALING, "Lesser Healing",
- SPTYP_HOLY,
- SPFLAG_NONE,
- 2
-},
-
-{
- SPELL_GREATER_HEALING, "Greater Healing",
- SPTYP_HOLY,
- SPFLAG_NONE,
- 6
-},
-
-{
- SPELL_CURE_POISON_I, "Cure Poison",
- SPTYP_HOLY,
- SPFLAG_NONE,
- 3
-},
-
-{
- SPELL_PURIFICATION, "Purification",
- SPTYP_HOLY,
- SPFLAG_NONE,
- 5
-},
-
-{
- SPELL_DEATHS_DOOR, "Death's Door",
- SPTYP_ENCHANTMENT | SPTYP_NECROMANCY,
- SPFLAG_NONE,
- 8
-},
-
-{
- SPELL_SELECTIVE_AMNESIA, "Selective Amnesia",
- SPTYP_ENCHANTMENT,
- SPFLAG_NONE,
- 3
-},
-
-{
- SPELL_MASS_CONFUSION, "Mass Confusion",
- SPTYP_ENCHANTMENT,
- SPFLAG_NONE,
- 6
-},
-
-{
- SPELL_SMITING, "Smiting",
- SPTYP_HOLY,
- SPFLAG_NONE,
- 4
-},
-
-{
- SPELL_REPEL_UNDEAD, "Repel Undead",
- SPTYP_HOLY,
- SPFLAG_NONE,
- 3
-},
-
-{
- SPELL_HOLY_WORD, "Holy Word",
- SPTYP_HOLY,
- SPFLAG_NONE,
- 7
-},
-
-{
- SPELL_DETECT_CURSE, "Detect Curse",
- SPTYP_DIVINATION,
- SPFLAG_NONE,
- 3
-},
-
-{
- SPELL_SUMMON_SMALL_MAMMAL, "Summon Small Mammals",
- SPTYP_SUMMONING,
- SPFLAG_NONE,
- 1
-},
-
-{
- SPELL_ABJURATION_I, "Abjuration",
- SPTYP_SUMMONING,
- SPFLAG_NONE,
- 3
-},
-
-{
- SPELL_SUMMON_SCORPIONS, "Summon Scorpions",
- SPTYP_SUMMONING | SPTYP_POISON,
- SPFLAG_NONE,
- 4
-},
-
-{
- SPELL_LEVITATION, "Levitation",
- SPTYP_ENCHANTMENT | SPTYP_AIR,
- SPFLAG_NONE,
- 2
-},
-
-{
- SPELL_BOLT_OF_DRAINING, "Bolt of Draining",
- SPTYP_CONJURATION | SPTYP_NECROMANCY,
- SPFLAG_DIR_OR_TARGET,
- 6
-},
-
-{
- SPELL_LEHUDIBS_CRYSTAL_SPEAR, "Lehudib's Crystal Spear",
- SPTYP_CONJURATION | SPTYP_EARTH,
- SPFLAG_DIR_OR_TARGET,
- 8
-},
-
-{
- SPELL_BOLT_OF_INACCURACY, "Bolt of Inaccuracy",
- SPTYP_CONJURATION,
- SPFLAG_DIR_OR_TARGET,
- 2
-},
-
-{
- SPELL_POISONOUS_CLOUD, "Poisonous Cloud",
- SPTYP_CONJURATION | SPTYP_POISON | SPTYP_AIR,
- SPFLAG_GRID,
- 6
-}
-,
-
-{
- SPELL_FIRE_STORM, "Fire Storm",
- SPTYP_CONJURATION | SPTYP_FIRE,
- SPFLAG_GRID,
- 9
-},
-
-{
- SPELL_DETECT_TRAPS, "Detect Traps",
- SPTYP_DIVINATION,
- SPFLAG_NONE,
- 2
-},
-
-{
- SPELL_BLINK, "Blink",
- SPTYP_TRANSLOCATION,
- SPFLAG_NONE,
- 2
-},
-
-
-// The following name was found in the hack.exe file of an early version
-// of PCHACK - credit goes to its creator (whoever that may be):
-{
- SPELL_ISKENDERUNS_MYSTIC_BLAST, "Iskenderun's Mystic Blast",
- SPTYP_CONJURATION,
- SPFLAG_DIR_OR_TARGET,
- 4
-},
-
-{
- SPELL_SWARM, "Summon Swarm",
- SPTYP_SUMMONING,
- SPFLAG_NONE,
- 6
-},
-
-{
- SPELL_SUMMON_HORRIBLE_THINGS, "Summon Horrible Things",
- SPTYP_SUMMONING,
- SPFLAG_UNHOLY,
- 8
-},
-
-{
- SPELL_ENSLAVEMENT, "Enslavement",
- SPTYP_ENCHANTMENT,
- SPFLAG_DIR_OR_TARGET | SPFLAG_NOT_SELF,
- 4
-},
-
-{
- SPELL_MAGIC_MAPPING, "Magic Mapping",
- SPTYP_DIVINATION | SPTYP_EARTH,
- SPFLAG_NONE,
- 4
-},
-
-{
- SPELL_HEAL_OTHER, "Heal Other",
- SPTYP_HOLY,
- SPFLAG_DIR_OR_TARGET | SPFLAG_HELPFUL | SPFLAG_NOT_SELF,
- 3
-},
-
-{
- SPELL_ANIMATE_DEAD, "Animate Dead",
- SPTYP_NECROMANCY,
- SPFLAG_NONE,
- 4
-},
-
-{
- SPELL_PAIN, "Pain",
- SPTYP_NECROMANCY,
- SPFLAG_DIR_OR_TARGET,
- 1
-},
-
-{
- SPELL_EXTENSION, "Extension",
- SPTYP_ENCHANTMENT,
- SPFLAG_NONE,
- 5
-},
-
-{
- SPELL_CONTROL_UNDEAD, "Control Undead",
- SPTYP_ENCHANTMENT | SPTYP_NECROMANCY,
- SPFLAG_NONE,
- 6
-},
-
-{
- SPELL_ANIMATE_SKELETON, "Animate Skeleton",
- SPTYP_NECROMANCY,
- SPFLAG_NONE,
- 1
-},
-
-{
- SPELL_VAMPIRIC_DRAINING, "Vampiric Draining",
- SPTYP_NECROMANCY,
- SPFLAG_DIR | SPFLAG_NOT_SELF,
- 3
-},
-
-{
- SPELL_SUMMON_WRAITHS, "Summon Wraiths",
- SPTYP_NECROMANCY | SPTYP_SUMMONING,
- SPFLAG_NONE,
- 7
-},
-
-{
- SPELL_DETECT_ITEMS, "Detect Items",
- SPTYP_DIVINATION,
- SPFLAG_NONE,
- 2
-},
-
-{
- SPELL_BORGNJORS_REVIVIFICATION, "Borgnjor's Revivification",
- SPTYP_NECROMANCY,
- SPFLAG_NONE,
- 5
-},
-
-{
- SPELL_BURN, "Burn", // used by wanderers
- SPTYP_FIRE,
- SPFLAG_DIR | SPFLAG_NOT_SELF,
- 1
-},
-
-{
- SPELL_FREEZE, "Freeze",
- SPTYP_ICE,
- SPFLAG_DIR | SPFLAG_NOT_SELF,
- 1
-},
-
-{
- SPELL_SUMMON_ELEMENTAL, "Summon Elemental",
- SPTYP_SUMMONING,
- SPFLAG_NONE,
- 4
-},
-
-{
- SPELL_OZOCUBUS_REFRIGERATION, "Ozocubu's Refrigeration",
- SPTYP_ICE,
- SPFLAG_NONE,
- 5
-},
-
-{
- SPELL_STICKY_FLAME, "Sticky Flame",
- SPTYP_CONJURATION | SPTYP_FIRE,
- SPFLAG_DIR_OR_TARGET,
- 4
-},
-
-{
- SPELL_SUMMON_ICE_BEAST, "Summon Ice Beast",
- SPTYP_ICE | SPTYP_SUMMONING,
- SPFLAG_NONE,
- 5
-},
-
-{
- SPELL_OZOCUBUS_ARMOUR, "Ozocubu's Armour",
- SPTYP_ENCHANTMENT | SPTYP_ICE,
- SPFLAG_NONE,
- 3
-},
-
-{
- SPELL_CALL_IMP, "Call Imp",
- SPTYP_SUMMONING,
- SPFLAG_UNHOLY,
- 3
-},
-
-{
- SPELL_REPEL_MISSILES, "Repel Missiles",
- SPTYP_ENCHANTMENT | SPTYP_AIR,
- SPFLAG_NONE,
- 2
-},
-
-{
- SPELL_BERSERKER_RAGE, "Berserker Rage",
- SPTYP_ENCHANTMENT,
- SPFLAG_NONE,
- 3
-},
-
-{
- SPELL_DISPEL_UNDEAD, "Dispel Undead",
- SPTYP_NECROMANCY,
- SPFLAG_DIR_OR_TARGET,
- 4
-},
-
-{
- SPELL_GUARDIAN, "Guardian",
- SPTYP_HOLY,
- SPFLAG_NONE,
- 7
-},
-
-{
- SPELL_PESTILENCE, "Pestilence",
- SPTYP_HOLY,
- SPFLAG_NONE,
- 4
-},
-
-{
- SPELL_THUNDERBOLT, "Thunderbolt",
- SPTYP_HOLY | SPTYP_AIR,
- SPFLAG_DIR_OR_TARGET,
- 6 // why is this the only holy spell with a secondary? {dlb}
-}
-,
-
-{
- SPELL_FLAME_OF_CLEANSING, "Flame of Cleansing",
- SPTYP_HOLY,
- SPFLAG_DIR_OR_TARGET,
- 8
-},
-
-{
- SPELL_SHINING_LIGHT, "Shining Light",
- SPTYP_HOLY,
- SPFLAG_NONE,
- 7
-},
-
-{
- SPELL_SUMMON_DAEVA, "Summon Daeva",
- SPTYP_HOLY,
- SPFLAG_NONE,
- 8
-},
-
-{
- SPELL_ABJURATION_II, "Abjuration",
- SPTYP_HOLY,
- SPFLAG_NONE,
- 4
-},
-
-{
- SPELL_TWISTED_RESURRECTION, "Twisted Resurrection",
- SPTYP_NECROMANCY,
- SPFLAG_NONE,
- 5
-},
-
-{
- SPELL_REGENERATION, "Regeneration",
- SPTYP_ENCHANTMENT | SPTYP_NECROMANCY,
- SPFLAG_NONE,
- 3
-},
-
-{
- SPELL_BONE_SHARDS, "Bone Shards",
- SPTYP_NECROMANCY,
- SPFLAG_NONE,
- 3
-},
-
-{
- SPELL_BANISHMENT, "Banishment",
- SPTYP_TRANSLOCATION,
- SPFLAG_DIR_OR_TARGET | SPFLAG_UNHOLY,
- 5
-},
-
-{
- SPELL_CIGOTUVIS_DEGENERATION, "Cigotuvi's Degeneration",
- SPTYP_TRANSMIGRATION | SPTYP_NECROMANCY,
- SPFLAG_DIR_OR_TARGET | SPFLAG_NOT_SELF,
- 5
-},
-
-{
- SPELL_STING, "Sting",
- SPTYP_CONJURATION | SPTYP_POISON,
- SPFLAG_DIR_OR_TARGET,
- 1
-},
-
-{
- SPELL_SUBLIMATION_OF_BLOOD, "Sublimation of Blood",
- SPTYP_NECROMANCY,
- SPFLAG_NONE,
- 2
-},
-
-{
- SPELL_TUKIMAS_DANCE, "Tukima's Dance",
- SPTYP_ENCHANTMENT,
- SPFLAG_NONE,
- 3
-},
-
-{
- SPELL_HELLFIRE, "Hellfire",
- SPTYP_CONJURATION | SPTYP_FIRE,
- SPFLAG_DIR_OR_TARGET | SPFLAG_UNHOLY,
- 9
-},
-
-{
- SPELL_SUMMON_DEMON, "Summon Demon",
- SPTYP_SUMMONING,
- SPFLAG_UNHOLY,
- 5
-},
-
-{
- SPELL_DEMONIC_HORDE, "Demonic Horde",
- SPTYP_SUMMONING,
- SPFLAG_UNHOLY,
- 6
-},
-
-{
- SPELL_SUMMON_GREATER_DEMON, "Summon Greater Demon",
- SPTYP_SUMMONING,
- SPFLAG_UNHOLY,
- 7
-},
-
-{
- SPELL_CORPSE_ROT, "Corpse Rot",
- SPTYP_NECROMANCY,
- SPFLAG_NONE,
- 2
-},
-
-{
- SPELL_TUKIMAS_VORPAL_BLADE, "Tukima's Vorpal Blade",
- SPTYP_ENCHANTMENT,
- SPFLAG_NONE,
- 2
-},
-
-{
- SPELL_FIRE_BRAND, "Fire Brand",
- SPTYP_ENCHANTMENT | SPTYP_FIRE,
- SPFLAG_NONE,
- 2
-},
-
-{
- SPELL_FREEZING_AURA, "Freezing Aura",
- SPTYP_ENCHANTMENT | SPTYP_ICE,
- SPFLAG_NONE,
- 2
-},
-
-{
- SPELL_LETHAL_INFUSION, "Lethal Infusion",
- SPTYP_ENCHANTMENT | SPTYP_NECROMANCY,
- SPFLAG_NONE,
- 2
-},
-
-{
- SPELL_CRUSH, "Crush",
- SPTYP_EARTH,
- SPFLAG_DIR | SPFLAG_NOT_SELF,
- 1
-},
-
-{
- SPELL_BOLT_OF_IRON, "Bolt of Iron",
- SPTYP_CONJURATION | SPTYP_EARTH,
- SPFLAG_DIR_OR_TARGET,
- 6
-},
-
-{
- SPELL_STONE_ARROW, "Stone Arrow",
- SPTYP_CONJURATION | SPTYP_EARTH,
- SPFLAG_DIR_OR_TARGET,
- 3
-},
-
-{
- SPELL_TOMB_OF_DOROKLOHE, "Tomb of Doroklohe",
- SPTYP_CONJURATION | SPTYP_EARTH, // conj makes more sense than tmig -- bwr
- SPFLAG_NONE,
- 7
-}
-,
-
-{
- SPELL_STONEMAIL, "Stonemail",
- SPTYP_ENCHANTMENT | SPTYP_EARTH,
- SPFLAG_NONE,
- 6
-},
-
-{
- SPELL_SHOCK, "Shock",
- SPTYP_CONJURATION | SPTYP_AIR,
- SPFLAG_DIR_OR_TARGET,
- 1
-},
-
-{
- SPELL_SWIFTNESS, "Swiftness",
- SPTYP_ENCHANTMENT | SPTYP_AIR,
- SPFLAG_NONE,
- 2
-},
-
-{
- SPELL_FLY, "Fly",
- SPTYP_ENCHANTMENT | SPTYP_AIR,
- SPFLAG_NONE,
- 4
-},
-
-{
- SPELL_INSULATION, "Insulation",
- SPTYP_ENCHANTMENT | SPTYP_AIR,
- SPFLAG_NONE,
- 4
-},
-
-{
- SPELL_ORB_OF_ELECTROCUTION, "Orb of Electrocution",
- SPTYP_CONJURATION | SPTYP_AIR,
- SPFLAG_DIR_OR_TARGET,
- 7
-},
-
-{
- SPELL_DETECT_CREATURES, "Detect Creatures",
- SPTYP_DIVINATION,
- SPFLAG_NONE,
- 2
-},
-
-{
- SPELL_CURE_POISON_II, "Cure Poison",
- SPTYP_POISON,
- SPFLAG_NONE,
- 2
-}
-,
-
-{
- SPELL_CONTROL_TELEPORT, "Control Teleport",
- SPTYP_ENCHANTMENT | SPTYP_TRANSLOCATION,
- SPFLAG_NONE,
- 5
-},
-
-{
- SPELL_POISON_AMMUNITION, "Poison Ammunition",
- SPTYP_ENCHANTMENT | SPTYP_POISON,
- SPFLAG_NONE,
- 4 // jmf: SPTYP_TRANSMIGRATION vs SPTYP_ENCHANTMENT?
-}
-,
-
-{
- SPELL_POISON_WEAPON, "Poison Weapon",
- SPTYP_ENCHANTMENT | SPTYP_POISON,
- SPFLAG_NONE,
- 4
-},
-
-{
- SPELL_RESIST_POISON, "Resist Poison",
- SPTYP_ENCHANTMENT | SPTYP_POISON,
- SPFLAG_NONE,
- 4
-},
-
-{
- SPELL_PROJECTED_NOISE, "Projected Noise",
- SPTYP_ENCHANTMENT,
- SPFLAG_NONE,
- 2
-},
-
-{
- SPELL_ALTER_SELF, "Alter Self",
- SPTYP_TRANSMIGRATION,
- SPFLAG_NONE,
- 7
-},
-
-{
- SPELL_DEBUGGING_RAY, "Debugging Ray",
- SPTYP_CONJURATION,
- SPFLAG_DIR_OR_TARGET,
- 7
-},
-
-{
- SPELL_RECALL, "Recall",
- SPTYP_SUMMONING | SPTYP_TRANSLOCATION,
- SPFLAG_NONE,
- 3
-},
-
-{
- SPELL_PORTAL, "Portal",
- SPTYP_TRANSLOCATION,
- SPFLAG_NONE,
- 7
-},
-
-{
- SPELL_AGONY, "Agony",
- SPTYP_NECROMANCY,
- SPFLAG_DIR_OR_TARGET | SPFLAG_NOT_SELF,
- 5
-},
-
-{
- SPELL_SPIDER_FORM, "Spider Form",
- SPTYP_TRANSMIGRATION | SPTYP_POISON,
- SPFLAG_NONE,
- 3
-},
-
-{
- SPELL_DISRUPT, "Disrupt",
- SPTYP_TRANSMIGRATION,
- SPFLAG_DIR_OR_TARGET,
- 1
-},
-
-{
- SPELL_DISINTEGRATE, "Disintegrate",
- SPTYP_TRANSMIGRATION,
- SPFLAG_DIR_OR_TARGET | SPFLAG_NOT_SELF,
- 6
-},
-
-{
- SPELL_BLADE_HANDS, "Blade Hands",
- SPTYP_TRANSMIGRATION,
- SPFLAG_NONE,
- 5 // only removes weapon, so I raised this from 4 -- bwr
-},
-
-{
- SPELL_STATUE_FORM, "Statue Form",
- SPTYP_TRANSMIGRATION | SPTYP_EARTH,
- SPFLAG_NONE,
- 6
-},
-
-{
- SPELL_ICE_FORM, "Ice Form",
- SPTYP_ICE | SPTYP_TRANSMIGRATION,
- SPFLAG_NONE,
- 4 // doesn't allow for equipment, so I lowered this from 5 -- bwr
-},
-
-{
- SPELL_DRAGON_FORM, "Dragon Form",
- SPTYP_FIRE | SPTYP_TRANSMIGRATION,
- SPFLAG_NONE,
- 8
-},
-
-{
- SPELL_NECROMUTATION, "Necromutation",
- SPTYP_TRANSMIGRATION | SPTYP_NECROMANCY,
- SPFLAG_NONE,
- 8
-},
-
-{
- SPELL_DEATH_CHANNEL, "Death Channel",
- SPTYP_NECROMANCY,
- SPFLAG_NONE,
- 9
-},
-
-{
- SPELL_SYMBOL_OF_TORMENT, "Symbol of Torment",
- SPTYP_NECROMANCY,
- SPFLAG_NONE,
- 6
-},
-
-{
- SPELL_DEFLECT_MISSILES, "Deflect Missiles",
- SPTYP_ENCHANTMENT | SPTYP_AIR,
- SPFLAG_NONE,
- 6
-},
-
-{
- SPELL_ORB_OF_FRAGMENTATION, "Orb of Fragmentation",
- SPTYP_CONJURATION | SPTYP_EARTH,
- SPFLAG_DIR_OR_TARGET,
- 7
-},
-
-{
- SPELL_ICE_BOLT, "Ice Bolt",
- SPTYP_CONJURATION | SPTYP_ICE,
- SPFLAG_DIR_OR_TARGET,
- 4
-},
-
-{
- SPELL_ICE_STORM, "Ice Storm",
- SPTYP_CONJURATION | SPTYP_ICE,
- SPFLAG_DIR_OR_TARGET,
- 9
-},
-
-{
- SPELL_ARC, "Arc",
- SPTYP_AIR,
- SPFLAG_DIR | SPFLAG_NOT_SELF,
- 1
-},
-
-{
- SPELL_AIRSTRIKE, "Airstrike",
- SPTYP_AIR,
- SPFLAG_TARGET | SPFLAG_NOT_SELF,
- 4
-},
-
-{
- SPELL_SHADOW_CREATURES, "Shadow Creatures",
- SPTYP_SUMMONING, // jmf: or SPTYP_SUMMONING | SPTYP_CONJURATION
- SPFLAG_NONE,
- 5
-}
-,
-
-{
- SPELL_CONFUSING_TOUCH, "Confusing Touch",
- SPTYP_ENCHANTMENT,
- SPFLAG_NONE,
- 1
-},
-
-{
- SPELL_SURE_BLADE, "Sure Blade",
- SPTYP_ENCHANTMENT,
- SPFLAG_NONE,
- 2
-},
-
-
-
- //jmf: new spells
-
-
-{
- SPELL_FLAME_TONGUE, "Flame Tongue",
- SPTYP_CONJURATION | SPTYP_FIRE,
- SPFLAG_DIR_OR_TARGET | SPFLAG_NOT_SELF,
- 1
-},
-
-{
- SPELL_PASSWALL, "Passwall",
- SPTYP_TRANSMIGRATION | SPTYP_EARTH,
- SPFLAG_NONE,
- 3
-},
-
-{
- SPELL_IGNITE_POISON, "Ignite Poison",
- SPTYP_FIRE | SPTYP_TRANSMIGRATION,
- SPFLAG_NONE,
- 7
-},
-
-{
- SPELL_STICKS_TO_SNAKES, "Sticks to Snakes",
- SPTYP_TRANSMIGRATION | SPTYP_SUMMONING,
- SPFLAG_NONE,
- 2
-},
-
-{
- SPELL_SUMMON_LARGE_MAMMAL, "Call Canine Familiar",
- SPTYP_SUMMONING,
- SPFLAG_NONE,
- 3
-},
-
-{
- SPELL_SUMMON_DRAGON, "Summon Dragon",
- SPTYP_FIRE | SPTYP_SUMMONING,
- SPFLAG_NONE,
- 9
-},
-
-{
- SPELL_TAME_BEASTS, "Tame Beasts",
- SPTYP_ENCHANTMENT,
- SPFLAG_NONE,
- 5
-},
-
-{
- SPELL_SLEEP, "Ensorcelled Hibernation",
- SPTYP_ENCHANTMENT | SPTYP_ICE,
- SPFLAG_DIR_OR_TARGET | SPFLAG_NOT_SELF,
- 2
-},
-
-{
- SPELL_MASS_SLEEP, "Metabolic Englaciation",
- SPTYP_ENCHANTMENT | SPTYP_ICE,
- SPFLAG_NONE,
- 7
-},
-
-{
- SPELL_DETECT_MAGIC, "Detect Magic",
- SPTYP_DIVINATION,
- SPFLAG_NONE,
- 1
-},
-
-{
- SPELL_DETECT_SECRET_DOORS, "Detect Secret Doors",
- SPTYP_DIVINATION,
- SPFLAG_NONE,
- 1
-},
-
-{
- SPELL_SEE_INVISIBLE, "See Invisible",
- SPTYP_ENCHANTMENT | SPTYP_DIVINATION,
- SPFLAG_NONE,
- 4
-},
-
-{
- SPELL_FORESCRY, "Forescry",
- SPTYP_DIVINATION,
- SPFLAG_NONE,
- 5
-},
-
-{
- SPELL_SUMMON_BUTTERFLIES, "Summon Butterflies",
- SPTYP_SUMMONING,
- SPFLAG_NONE,
- 1
-},
-
-{
- SPELL_WARP_BRAND, "Warp Weapon",
- SPTYP_ENCHANTMENT | SPTYP_TRANSLOCATION,
- SPFLAG_NONE,
- 7 // this is high for a reason - Warp brands are very powerful.
-},
-
-{
- SPELL_SILENCE, "Silence",
- SPTYP_ENCHANTMENT | SPTYP_AIR,
- SPFLAG_NONE,
- 5
-},
-
-{
- SPELL_SHATTER, "Shatter",
- SPTYP_TRANSMIGRATION | SPTYP_EARTH,
- SPFLAG_NONE,
- 9
-},
-
-{
- SPELL_DISPERSAL, "Dispersal",
- SPTYP_TRANSLOCATION,
- SPFLAG_NONE,
- 7
-},
-
-{
- SPELL_DISCHARGE, "Static Discharge",
- SPTYP_CONJURATION | SPTYP_AIR,
- SPFLAG_NONE,
- 4
-},
-
-{
- SPELL_BEND, "Bend",
- SPTYP_TRANSLOCATION,
- SPFLAG_NONE,
- 1
-},
-
-{
- SPELL_BACKLIGHT, "Corona",
- SPTYP_ENCHANTMENT,
- SPFLAG_DIR_OR_TARGET | SPFLAG_NOT_SELF,
- 1
-},
-
-{
- SPELL_INTOXICATE, "Alistair's Intoxication",
- SPTYP_TRANSMIGRATION | SPTYP_POISON,
- SPFLAG_NONE,
- 4
-},
-
-{
- SPELL_GLAMOUR, "Glamour",
- SPTYP_ENCHANTMENT,
- SPFLAG_NONE,
- 5
-},
-
-{
- SPELL_EVAPORATE, "Evaporate",
- SPTYP_FIRE | SPTYP_TRANSMIGRATION,
- SPFLAG_NONE,
- 2 // XXX: level 2 or 3, what should it be now? -- bwr
-},
-
-{
- SPELL_ERINGYAS_SURPRISING_BOUQUET, "Eringya's Surprising Bouquet",
- SPTYP_TRANSMIGRATION | SPTYP_EARTH,
- SPFLAG_NONE,
- 4
-},
-
-{
- SPELL_FRAGMENTATION, "Lee's Rapid Deconstruction",
- SPTYP_TRANSMIGRATION | SPTYP_EARTH,
- SPFLAG_NONE,
- 5
-},
-
-{
- SPELL_AIR_WALK, "Air Walk",
- SPTYP_TRANSMIGRATION | SPTYP_AIR,
- SPFLAG_NONE,
- 9
-},
-
-{
- SPELL_SANDBLAST, "Sandblast",
- SPTYP_TRANSMIGRATION | SPTYP_EARTH,
- SPFLAG_DIR_OR_TARGET | SPFLAG_NOT_SELF,
- 1
-},
-
-{
- SPELL_ROTTING, "Rotting",
- SPTYP_TRANSMIGRATION | SPTYP_NECROMANCY,
- SPFLAG_NONE,
- 5
-},
-
-{
- SPELL_MAXWELLS_SILVER_HAMMER, "Maxwell's Silver Hammer",
- SPTYP_TRANSMIGRATION | SPTYP_EARTH,
- SPFLAG_NONE,
- 2
-},
-
-{
- SPELL_CONDENSATION_SHIELD, "Condensation Shield",
- SPTYP_ICE | SPTYP_TRANSMIGRATION,
- SPFLAG_NONE,
- 4
-},
-
-{
- SPELL_SEMI_CONTROLLED_BLINK, "Semi-Controlled Blink",
- SPTYP_TRANSLOCATION,
- SPFLAG_NONE,
- 3
-},
-
-{
- SPELL_STONESKIN, "Stoneskin",
- SPTYP_EARTH | SPTYP_TRANSMIGRATION, // was ench -- bwr
- SPFLAG_NONE,
- 2
-},
-
-{
- SPELL_SIMULACRUM, "Simulacrum",
- SPTYP_ICE | SPTYP_NECROMANCY,
- SPFLAG_NONE,
- 6
-},
-
-{
- SPELL_CONJURE_BALL_LIGHTNING, "Conjure Ball Lightning",
- SPTYP_AIR | SPTYP_CONJURATION,
- SPFLAG_NONE,
- 8
-},
-
-{
- SPELL_CHAIN_LIGHTNING, "Chain Lightning",
- SPTYP_AIR | SPTYP_CONJURATION,
- SPFLAG_NONE,
- 8
-},
-
-{
- SPELL_DELAYED_FIREBALL, "Delayed Fireball",
- SPTYP_FIRE | SPTYP_CONJURATION,
- SPFLAG_NONE,
- 7
-},
-
-{
- SPELL_FULSOME_DISTILLATION, "Fulsome Distillation",
- SPTYP_TRANSMIGRATION | SPTYP_NECROMANCY,
- SPFLAG_NONE,
- 1
-},
-
-{
- SPELL_POISON_ARROW, "Poison Arrow",
- SPTYP_CONJURATION | SPTYP_POISON,
- SPFLAG_DIR_OR_TARGET,
- 6
-},
-
-{
- SPELL_STRIKING, "Striking",
- 0,
- SPFLAG_DIR_OR_TARGET,
- 1
-},
-
-{
- SPELL_NO_SPELL, "nonexistent spell",
- 0,
- 0,
- 0,
-},
-
-
-#endif
diff --git a/stone_soup/crawl-ref/source/spl-util.cc b/stone_soup/crawl-ref/source/spl-util.cc
deleted file mode 100644
index d024fada5b..0000000000
--- a/stone_soup/crawl-ref/source/spl-util.cc
+++ /dev/null
@@ -1,792 +0,0 @@
-/*
- * File: spl-util.h *
- * Summary: data handlers for player-avilable spell list *
- * Written by: don brodale <dbrodale@bigfootinteractive.com> *
- * *
- * Changelog(most recent first): *
- *
- * <3> 04oct2001 bwr absorbed spells0.cc
- * <2> 24jun2000 jmf changed to use new data structure
- * <1> 12jun2000 dlb created after much thought
- */
-
-#include "AppHdr.h"
-#include "spl-util.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <string.h>
-#include <limits.h>
-
-#include "externs.h"
-
-#include "direct.h"
-#include "debug.h"
-#include "stuff.h"
-#include "itemname.h"
-#include "macro.h"
-#include "misc.h"
-#include "monstuff.h"
-#include "player.h"
-#include "spl-book.h"
-#include "view.h"
-
-
-#ifdef DOS
-#include <conio.h>
-#endif
-
-
-static struct playerspell spelldata[] = {
-#include "spl-data.h"
-};
-
-static int plyrspell_list[NUM_SPELLS];
-
-#define PLYRSPELLDATASIZE (sizeof(spelldata)/sizeof(struct playerspell))
-
-static struct playerspell *seekspell(int spellid);
-static bool cloud_helper( int (*func) (int, int, int, int), int x, int y,
- int pow, int ctype );
-
-/*
- * BEGIN PUBLIC FUNCTIONS
- */
-
-// all this does is merely refresh the internal spell list {dlb}:
-void init_playerspells(void)
-{
- unsigned int x = 0;
-
- for (x = 0; x < NUM_SPELLS; x++)
- plyrspell_list[x] = -1;
-
- // can only use up to PLYRSPELLDATASIZE _MINUS ONE_, or the
- // last entry tries to set plyrspell_list[SPELL_NO_SPELL]
- // which corrupts the heap.
- for (x = 0; x < PLYRSPELLDATASIZE - 1; x++)
- plyrspell_list[spelldata[x].id] = x;
-
- for (x = 0; x < NUM_SPELLS; x++)
- {
- if (plyrspell_list[x] == -1)
- plyrspell_list[x] = plyrspell_list[SPELL_NO_SPELL];
- }
-
- return; // return value should not matter here {dlb}
-} // end init_playerspells()
-
-int get_spell_slot_by_letter( char letter )
-{
- ASSERT( isalpha( letter ) );
-
- const int index = letter_to_index( letter );
-
- if (you.spell_letter_table[ index ] == -1)
- return (-1);
-
- return (you.spell_letter_table[index]);
-}
-
-int get_spell_by_letter( char letter )
-{
- ASSERT( isalpha( letter ) );
-
- const int slot = get_spell_slot_by_letter( letter );
-
- return ((slot == -1) ? SPELL_NO_SPELL : you.spells[slot]);
-}
-
-bool add_spell_to_memory( int spell )
-{
- int i, j;
-
- // first we find a slot in our head:
- for (i = 0; i < 25; i++)
- {
- if (you.spells[i] == SPELL_NO_SPELL)
- break;
- }
-
- you.spells[i] = spell;
-
- // now we find an available label:
- for (j = 0; j < 52; j++)
- {
- if (you.spell_letter_table[j] == -1)
- break;
- }
-
- you.spell_letter_table[j] = i;
-
- you.spell_no++;
-
- return (true);
-}
-
-bool del_spell_from_memory_by_slot( int slot )
-{
- int j;
-
- you.spells[ slot ] = SPELL_NO_SPELL;
-
- for (j = 0; j < 52; j++)
- {
- if (you.spell_letter_table[j] == slot)
- you.spell_letter_table[j] = -1;
-
- }
-
- you.spell_no--;
-
- return (true);
-}
-
-
-int spell_hunger(int which_spell)
-{
- int level = seekspell(which_spell)->level;
-
- switch (level)
- {
- case 1: return 50;
- case 2: return 95;
- case 3: return 160;
- case 4: return 250;
- case 5: return 350;
- case 6: return 550;
- case 7: return 700;
- case 8: return 850;
- case 9: return 1000;
- case 10: return 1000;
- case 11: return 1100;
- case 12: return 1250;
- case 13: return 1380;
- case 14: return 1500;
- case 15: return 1600;
- default: return 1600 + (20 * level);
- }
-} // end spell_hunger();
-
-// applied to spell misfires (more power = worse) and triggers
-// for Xom acting (more power = more likely to grab his attention) {dlb}
-int spell_mana(int which_spell)
-{
- return (seekspell(which_spell)->level);
-}
-
-// applied in naughties (more difficult = higher level knowledge = worse)
-// and triggers for Sif acting (same reasoning as above, just good) {dlb}
-int spell_difficulty(int which_spell)
-{
- return (seekspell(which_spell)->level);
-}
-
-int spell_levels_required( int which_spell )
-{
- int levels = spell_difficulty( which_spell );
-
- if (which_spell == SPELL_DELAYED_FIREBALL
- && player_has_spell( SPELL_FIREBALL ))
- {
- levels -= spell_difficulty( SPELL_FIREBALL );
- }
- else if (which_spell == SPELL_FIREBALL
- && player_has_spell( SPELL_DELAYED_FIREBALL ))
- {
- levels = 0;
- }
-
- return (levels);
-}
-
-unsigned int get_spell_flags( int which_spell )
-{
- return (seekspell(which_spell)->flags);
-}
-
-bool spell_typematch(int which_spell, unsigned int which_discipline)
-{
- return (seekspell(which_spell)->disciplines & which_discipline);
-}
-
-//jmf: next two for simple bit handling
-unsigned int spell_type(int spell)
-{
- return (seekspell(spell)->disciplines);
-}
-
-int count_bits(unsigned int bits)
-{
- unsigned int n;
- int c = 0;
-
- for (n = 1; n < INT_MAX; n <<= 1)
- {
- if (n & bits)
- c++;
- }
-
- return (c);
-}
-
-// this will probably be used often, so rather than use malloc/free
-// (which may lead to memory fragmentation) I'll just use a static
-// array of characters -- if/when the String changeover takes place,
-// this will all shift, no doubt {dlb}
-/*
- const char *spell_title( int which_spell )
- {
- static char this_title[41] = ""; // this is generous, to say the least {dlb}
- strncpy(this_title, seekspell(which_spell)->title, 41);
- // truncation better than overrun {dlb}
- return ( this_title );
- } // end spell_title()
-*/
-
-const char *spell_title(int spell) //jmf: ah the joys of driving ms. data
-{
- return (seekspell(spell)->title);
-}
-
-
-// FUNCTION APPLICATORS: Idea from Juho Snellman <jsnell@lyseo.edu.ouka.fi>
-// on the Roguelike News pages, Development section.
-// <URL:http://www.skoardy.demon.co.uk/rlnews/>
-// Here are some function applicators: sort of like brain-dead,
-// home-grown iterators for the container "dungeon".
-
-// Apply a function-pointer to all visible squares
-// Returns summation of return values from passed in function.
-int apply_area_visible( int (*func) (int, int, int, int), int power )
-{
- int x, y;
- int rv = 0;
-
- //jmf: FIXME: randomly start from other quadrants, like raise_dead?
- for (x = you.x_pos - 8; x <= you.x_pos + 8; x++)
- {
- for (y = you.y_pos - 8; y <= you.y_pos + 8; y++)
- {
- if (see_grid(x, y))
- rv += func(x, y, power, 0);
- }
- }
-
- return (rv);
-} // end apply_area_visible()
-
-// Applies the effect to all nine squares around/including the target.
-// Returns summation of return values from passed in function.
-int apply_area_square( int (*func) (int, int, int, int), int cx, int cy,
- int power )
-{
- int x, y;
- int rv = 0;
-
- for (x = cx - 1; x <= cx + 1; x++)
- {
- for (y = cy - 1; y <= cy + 1; y++)
- {
- rv += func(x, y, power, 0);
- }
- }
-
- return (rv);
-} // end apply_area_square()
-
-
-// Applies the effect to the eight squares beside the target.
-// Returns summation of return values from passed in function.
-int apply_area_around_square( int (*func) (int, int, int, int),
- int targ_x, int targ_y, int power)
-{
- int x, y;
- int rv = 0;
-
- for (x = targ_x - 1; x <= targ_x + 1; x++)
- {
- for (y = targ_y - 1; y <= targ_y + 1; y++)
- {
- if (x == targ_x && y == targ_y)
- continue;
- else
- rv += func(x, y, power, 0);
- }
- }
- return (rv);
-} // end apply_area_around_square()
-
-// Effect up to max_targs monsters around a point, chosen randomly
-// Return varies with the function called; return values will be added up.
-int apply_random_around_square( int (*func) (int, int, int, int),
- int targ_x, int targ_y,
- bool hole_in_middle, int power, int max_targs )
-{
- int rv = 0;
-
- if (max_targs <= 0)
- return 0;
-
- if (max_targs >= 9 && !hole_in_middle)
- {
- return (apply_area_square( func, targ_x, targ_y, power ));
- }
-
- if (max_targs >= 8 && hole_in_middle)
- {
- return (apply_area_around_square( func, targ_x, targ_y, power ));
- }
-
- FixedVector< coord_def, 8 > targs;
- int count = 0;
-
- for (int x = targ_x - 1; x <= targ_x + 1; x++)
- {
- for (int y = targ_y - 1; y <= targ_y + 1; y++)
- {
- if (hole_in_middle && (x == targ_x && y == targ_y))
- continue;
-
- if (mgrd[x][y] == NON_MONSTER
- && !(x == you.x_pos && y == you.y_pos))
- {
- continue;
- }
-
- // Found target
- count++;
-
- // Slight differece here over the basic algorithm...
- //
- // For cases where the number of choices <= max_targs it's
- // obvious (all available choices will be selected).
- //
- // For choices > max_targs, here's a brief proof:
- //
- // Let m = max_targs, k = choices - max_targs, k > 0.
- //
- // Proof, by induction (over k):
- //
- // 1) Show n = m + 1 (k = 1) gives uniform distribution,
- // P(new one not chosen) = 1 / (m + 1).
- // m 1 1
- // P(specific previous one replaced) = --- * --- = ---
- // m+1 m m+1
- //
- // So the probablity is uniform (ie. any element has
- // a 1/(m+1) chance of being in the unchosen slot).
- //
- // 2) Assume the distribution is uniform at n = m+k.
- // (ie. the probablity that any of the found elements
- // was chosen = m / (m+k) (the slots are symetric,
- // so it's the sum of the probabilities of being in
- // any of them)).
- //
- // 3) Show n = m + k + 1 gives a uniform distribution.
- // P(new one chosen) = m / (m + k + 1)
- // P(any specific previous choice remaining chosen)
- // = [1 - P(swaped into m+k+1 position)] * P(prev. chosen)
- // m 1 m
- // = [ 1 - ----- * --- ] * ---
- // m+k+1 m m+k
- //
- // m+k m m
- // = ----- * --- = -----
- // m+k+1 m+k m+k+1
- //
- // Therefore, it's uniform for n = m + k + 1. QED
- //
- // The important thing to note in calculating the last
- // probability is that the chosen elements have already
- // passed tests which verify that they *don't* belong
- // in slots m+1...m+k, so the only positions an already
- // chosen element can end up in are it's original
- // position (in one of the chosen slots), or in the
- // new slot.
- //
- // The new item can, of course, be placed in any slot,
- // swapping the value there into the new slot... we
- // just don't care about the non-chosen slots enough
- // to store them, so it might look like the item
- // automatically takes the new slot when not chosen
- // (although, by symetry all the non-chosen slots are
- // the same... and similarly, by symetry, all chosen
- // slots are the same).
- //
- // Yes, that's a long comment for a short piece of
- // code, but I want people to have an understanding
- // of why this works (or at least make them wary about
- // changing it without proof and breaking this code). -- bwr
-
- // Accept the first max_targs choices, then when
- // new choices come up, replace one of the choices
- // at random, max_targs/count of the time (the rest
- // of the time it replaces an element in an unchosen
- // slot -- but we don't care about them).
- if (count <= max_targs)
- {
- targs[ count - 1 ].x = x;
- targs[ count - 1 ].y = y;
- }
- else if (random2( count ) < max_targs)
- {
- const int pick = random2( max_targs );
- targs[ pick ].x = x;
- targs[ pick ].y = y;
- }
- }
- }
-
- const int targs_found = (count < max_targs) ? count : max_targs;
-
- if (targs_found)
- {
- // Used to divide the power up among the targets here, but
- // it's probably better to allow the full power through and
- // balance the called function. -- bwr
- for (int i = 0; i < targs_found; i++)
- {
- ASSERT( targs[i].x && targs[i].y );
- rv += func( targs[i].x, targs[i].y, power, 0 );
- }
- }
-
- return (rv);
-} // end apply_random_around_square()
-
-// apply func to one square of player's choice beside the player
-int apply_one_neighbouring_square(int (*func) (int, int, int, int), int power)
-{
- struct dist bmove;
-
- mpr("Which direction? [ESC to cancel]", MSGCH_PROMPT);
- direction( bmove, DIR_DIR, TARG_ENEMY );
-
- if (!bmove.isValid)
- {
- canned_msg(MSG_SPELL_FIZZLES);
- return (0);
- }
-
- int rv = func(you.x_pos + bmove.dx, you.y_pos + bmove.dy, power, 1);
-
- if (rv == 0)
- canned_msg(MSG_NOTHING_HAPPENS);
-
- return (rv);
-} // end apply_one_neighbouring_square()
-
-int apply_area_within_radius( int (*func) (int, int, int, int),
- int x, int y, int pow, int radius, int ctype )
-{
- int ix, iy;
- int sq_radius = radius * radius;
- int sx, sy, ex, ey; // start and end x, y - bounds checked
- int rv = 0;
-
- // begin x,y
- sx = x - radius;
- sy = y - radius;
- if (sx < 0) sx = 0;
- if (sy < 0) sy = 0;
-
- // end x,y
- ex = x + radius;
- ey = y + radius;
- if (ex > GXM) ex = GXM;
- if (ey > GYM) ey = GYM;
-
- for (ix = sx; ix < ex; ix++)
- {
- for (iy = sy; iy < ey; iy++)
- {
- if (distance(x, y, ix, iy) <= sq_radius)
- rv += func(ix, iy, pow, ctype);
- }
- }
-
- return (rv);
-} // end apply_area_within_radius()
-
-// apply_area_cloud:
-// Try to make a realistic cloud by expanding from a point, filling empty
-// floor tiles until we run out of material (passed in as number).
-// We really need some sort of a queue structure, since ideally I'd like
-// to do a (shallow) breadth-first-search of the dungeon floor.
-// This ought to work okay for small clouds.
-void apply_area_cloud( int (*func) (int, int, int, int), int x, int y,
- int pow, int number, int ctype )
-{
- int spread, clouds_left = number;
- int good_squares = 0, neighbours[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
- int dx = 1, dy = 1;
- bool x_first;
-
- if (clouds_left && cloud_helper(func, x, y, pow, ctype))
- clouds_left--;
-
- if (!clouds_left)
- return;
-
- if (coinflip())
- dx *= -1;
- if (coinflip())
- dy *= -1;
-
- x_first = coinflip();
-
- if (x_first)
- {
- if (clouds_left && cloud_helper(func, x + dx, y, pow, ctype))
- {
- clouds_left--;
- good_squares++;
- neighbours[0]++;
- }
-
- if (clouds_left && cloud_helper(func, x - dx, y, pow, ctype))
- {
- clouds_left--;
- good_squares++;
- neighbours[1]++;
- }
-
- if (clouds_left && cloud_helper(func, x, y + dy, pow, ctype))
- {
- clouds_left--;
- good_squares++;
- neighbours[2]++;
- }
-
- if (clouds_left && cloud_helper(func, x, y - dy, pow, ctype))
- {
- clouds_left--;
- good_squares++;
- neighbours[3]++;
- }
- }
- else
- {
- if (clouds_left && cloud_helper(func, x, y + dy, pow, ctype))
- {
- clouds_left--;
- good_squares++;
- neighbours[2]++;
- }
-
- if (clouds_left && cloud_helper(func, x, y - dy, pow, ctype))
- {
- clouds_left--;
- good_squares++;
- neighbours[3]++;
- }
-
- if (clouds_left && cloud_helper(func, x + dx, y, pow, ctype))
- {
- clouds_left--;
- good_squares++;
- neighbours[0]++;
- }
-
- if (clouds_left && cloud_helper(func, x - dx, y, pow, ctype))
- {
- clouds_left--;
- good_squares++;
- neighbours[1]++;
- }
- }
-
- // now diagonals; we could randomize dx & dy again here
- if (clouds_left && cloud_helper(func, x + dx, y + dy, pow, ctype))
- {
- clouds_left--;
- good_squares++;
- neighbours[4]++;
- }
-
- if (clouds_left && cloud_helper(func, x - dx, y + dy, pow, ctype))
- {
- clouds_left--;
- good_squares++;
- neighbours[5]++;
- }
-
- if (clouds_left && cloud_helper(func, x + dx, y - dy, pow, ctype))
- {
- clouds_left--;
- good_squares++;
- neighbours[6]++;
- }
-
- if (clouds_left && cloud_helper(func, x - dx, y - dy, pow, ctype))
- {
- clouds_left--;
- good_squares++;
- neighbours[7]++;
- }
-
- if (!(clouds_left && good_squares))
- return;
-
- for (int i = 0; i < 8 && clouds_left; i++)
- {
- if (neighbours[i] == 0)
- continue;
-
- spread = clouds_left / good_squares;
- clouds_left -= spread;
- good_squares--;
-
- switch (i)
- {
- case 0:
- apply_area_cloud(func, x + dx, y, pow, spread, ctype);
- break;
- case 1:
- apply_area_cloud(func, x - dx, y, pow, spread, ctype);
- break;
- case 2:
- apply_area_cloud(func, x, y + dy, pow, spread, ctype);
- break;
- case 3:
- apply_area_cloud(func, x, y - dy, pow, spread, ctype);
- break;
- case 4:
- apply_area_cloud(func, x + dx, y + dy, pow, spread, ctype);
- break;
- case 5:
- apply_area_cloud(func, x - dx, y + dy, pow, spread, ctype);
- break;
- case 6:
- apply_area_cloud(func, x + dx, y - dy, pow, spread, ctype);
- break;
- case 7:
- apply_area_cloud(func, x - dx, y - dy, pow, spread, ctype);
- break;
- }
- }
-} // end apply_area_cloud()
-
-char spell_direction( struct dist &spelld, struct bolt &pbolt,
- int restrict, int mode )
-{
- if (restrict == DIR_TARGET)
- mpr( "Choose a target (+/- for next/prev monster)", MSGCH_PROMPT );
- else
- mpr( STD_DIRECTION_PROMPT, MSGCH_PROMPT );
-
- message_current_target();
-
- direction( spelld, restrict, mode );
-
- if (!spelld.isValid)
- {
- // check for user cancel
- canned_msg(MSG_SPELL_FIZZLES);
- return -1;
- }
-
- pbolt.target_x = spelld.tx;
- pbolt.target_y = spelld.ty;
- pbolt.source_x = you.x_pos;
- pbolt.source_y = you.y_pos;
-
- return 1;
-} // end spell_direction()
-
-const char *spelltype_name(unsigned int which_spelltype)
-{
- static char bug_string[80];
-
- switch (which_spelltype)
- {
- case SPTYP_CONJURATION:
- return ("Conjuration");
- case SPTYP_ENCHANTMENT:
- return ("Enchantment");
- case SPTYP_FIRE:
- return ("Fire");
- case SPTYP_ICE:
- return ("Ice");
- case SPTYP_TRANSMIGRATION:
- return ("Transmigration");
- case SPTYP_NECROMANCY:
- return ("Necromancy");
- case SPTYP_HOLY:
- return ("Holy");
- case SPTYP_SUMMONING:
- return ("Summoning");
- case SPTYP_DIVINATION:
- return ("Divination");
- case SPTYP_TRANSLOCATION:
- return ("Translocation");
- case SPTYP_POISON:
- return ("Poison");
- case SPTYP_EARTH:
- return ("Earth");
- case SPTYP_AIR:
- return ("Air");
- default:
- snprintf( bug_string, sizeof(bug_string),
- "invalid(%d)", which_spelltype );
-
- return (bug_string);
- }
-} // end spelltype_name()
-
-int spell_type2skill(unsigned int spelltype)
-{
- char buffer[80];
-
- switch (spelltype)
- {
- case SPTYP_CONJURATION: return (SK_CONJURATIONS);
- case SPTYP_ENCHANTMENT: return (SK_ENCHANTMENTS);
- case SPTYP_FIRE: return (SK_FIRE_MAGIC);
- case SPTYP_ICE: return (SK_ICE_MAGIC);
- case SPTYP_TRANSMIGRATION: return (SK_TRANSMIGRATION);
- case SPTYP_NECROMANCY: return (SK_NECROMANCY);
- case SPTYP_SUMMONING: return (SK_SUMMONINGS);
- case SPTYP_DIVINATION: return (SK_DIVINATIONS);
- case SPTYP_TRANSLOCATION: return (SK_TRANSLOCATIONS);
- case SPTYP_POISON: return (SK_POISON_MAGIC);
- case SPTYP_EARTH: return (SK_EARTH_MAGIC);
- case SPTYP_AIR: return (SK_AIR_MAGIC);
-
- default:
- case SPTYP_HOLY:
- snprintf( buffer, sizeof(buffer),
- "spell_type2skill: called with spelltype %d", spelltype );
-
- mpr( buffer );
- return (-1);
- }
-} // end spell_type2skill()
-
-/*
- **************************************************
- * *
- * END PUBLIC FUNCTIONS *
- * *
- **************************************************
- */
-
-//jmf: simplified; moved init code to top function, init_playerspells()
-static struct playerspell *seekspell(int spell)
-{
- return (&spelldata[plyrspell_list[spell]]);
-}
-
-static bool cloud_helper( int (*func) (int, int, int, int), int x, int y,
- int pow, int ctype )
-{
- if (!grid_is_solid(grd[x][y]) && env.cgrid[x][y] == EMPTY_CLOUD)
- {
- func(x, y, pow, ctype);
- return true;
- }
-
- return false;
-}
diff --git a/stone_soup/crawl-ref/source/spl-util.h b/stone_soup/crawl-ref/source/spl-util.h
deleted file mode 100644
index c79268bacb..0000000000
--- a/stone_soup/crawl-ref/source/spl-util.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * File: spl-util.h
- * Summary: data handlers for player spell list
- * Written by: don brodale <dbrodale@bigfootinteractive.com>
- *
- * Changelog(most recent first):
- *
- * 24jun2000 jmf simplified structures
- * <00> 12jun2000 dlb created after much thought
- */
-
-
-#ifndef SPL_UTIL_H
-#define SPL_UTIL_H
-
-#include "enum.h" // just for NUM_SPELL_TYPES and TARG_ENEMY
-#include "direct.h" // just for DIR_NONE
-
-struct playerspell
-{
- int id;
- const char *title;
- unsigned int disciplines; // bitfield
- unsigned int flags; // bitfield
- unsigned int level;
-};
-
-
-//* * called from: acr
-void init_playerspells(void);
-
-int get_spell_slot_by_letter( char letter );
-int get_spell_by_letter( char letter );
-
-bool add_spell_to_memory( int spell );
-bool del_spell_from_memory_by_slot( int slot );
-
-// * called from: spell
-int spell_hunger(int which_spell);
-
-// * called from: it_use3 - spell - spells3
-int spell_mana(int which_spell);
-
-// * called from: chardump - it_use3 - player - spell - spl-book -
-// * spells0 - spells3
-int spell_difficulty(int which_spell);
-
-int spell_levels_required(int which_spell);
-
-unsigned int get_spell_flags( int which_spell );
-
-// * called from: chardump - spell - spl-book - spells0
-bool spell_typematch(int which_spell, unsigned int which_discipline);
-unsigned int spell_type( int which_spell ); //jmf: simplification of above
-int count_bits( unsigned int bits );
-
-// * called from: chardump - command - debug - spl-book - spells0
-const char *spell_title(int which_spell);
-
-//int spell_restriction(int which_spell, int which_restriction);
-
-int apply_area_visible(int (*func) (int, int, int, int), int power);
-
-int apply_area_square(int (*func) (int, int, int, int),
- int cx, int cy, int power);
-
-int apply_area_around_square( int (*func) (int, int, int, int),
- int targ_x, int targ_y, int power );
-
-int apply_random_around_square( int (*func) (int, int, int, int),
- int targ_x, int targ_y, bool hole_in_middle,
- int power, int max_targs );
-
-int apply_one_neighbouring_square(int (*func) (int, int, int, int),
- int power);
-
-int apply_area_within_radius(int (*func) (int, int, int, int),
- int x, int y, int pow, int radius, int ctype);
-
-char spell_direction( struct dist &spelld, struct bolt &pbolt,
- int restrict = DIR_NONE, int mode = TARG_ENEMY );
-
-void apply_area_cloud(int (*func) (int, int, int, int), int x, int y,
- int pow, int number, int ctype);
-
-const char *spelltype_name(unsigned int which_spelltype);
-
-int spell_type2skill (unsigned int which_spelltype);
-
-#endif
diff --git a/stone_soup/crawl-ref/source/stash.cc b/stone_soup/crawl-ref/source/stash.cc
deleted file mode 100644
index dbdfef440d..0000000000
--- a/stone_soup/crawl-ref/source/stash.cc
+++ /dev/null
@@ -1,1607 +0,0 @@
-/*
- * File: stash.cc
- * Summary: Classes tracking player stashes
- * Written by: Darshan Shaligram
- */
-
-#include "AppHdr.h"
-#include "chardump.h"
-#include "clua.h"
-#include "describe.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "files.h"
-#include "invent.h"
-#include "items.h"
-#include "Kills.h"
-#include "libutil.h"
-#include "menu.h"
-#include "shopping.h"
-#include "spl-book.h"
-#include "stash.h"
-#include "stuff.h"
-#include "tags.h"
-#include "travel.h"
-
-#include <cctype>
-#include <cstdio>
-#include <fstream>
-#include <algorithm>
-
-#ifdef STASH_TRACKING
-
-#define ST_MAJOR_VER ((unsigned char) 4)
-#define ST_MINOR_VER ((unsigned char) 4)
-
-#define LUA_SEARCH_ANNOTATE "ch_stash_search_annotate_item"
-#define LUA_DUMP_ANNOTATE "ch_stash_dump_annotate_item"
-#define LUA_VIEW_ANNOTATE "ch_stash_view_annotate_item"
-
-std::string short_place_name(level_id id)
-{
- return short_place_name(
- get_packed_place(id.branch, id.depth, LEVEL_DUNGEON));
-}
-
-std::string userdef_annotate_item(const char *s, const item_def *item,
- bool exclusive)
-{
-#ifdef CLUA_BINDINGS
- if (exclusive)
- lua_set_exclusive_item(item);
- std::string ann;
- clua.callfn(s, "u>s", item, &ann);
- if (exclusive)
- lua_set_exclusive_item(NULL);
- return (ann);
-
-#else
- return ("");
-#endif
-}
-
-std::string stash_annotate_item(const char *s,
- const item_def *item,
- bool exclusive = false)
-{
- std::string text = userdef_annotate_item(s, item, exclusive);
- if ( (item->base_type == OBJ_BOOKS &&
- item_type_known(*item) &&
- item->sub_type != BOOK_MANUAL &&
- item->sub_type != BOOK_DESTRUCTION)
- || count_staff_spells(*item, true) > 1 )
- {
- formatted_string fs;
- item_def dup = *item;
- spellbook_contents( dup,
- item->base_type == OBJ_BOOKS?
- RBOOK_READ_SPELL
- : RBOOK_USE_STAFF,
- &fs );
- text += EOL;
- text += fs.tostring(2, -2);
- }
- return text;
-}
-
-bool is_stash(int x, int y)
-{
- LevelStashes *ls = stashes.find_current_level();
- if (ls)
- {
- Stash *s = ls->find_stash(x, y);
- return s && s->enabled;
- }
- return false;
-}
-
-void describe_stash(int x, int y)
-{
- LevelStashes *ls = stashes.find_current_level();
- if (ls)
- {
- Stash *s = ls->find_stash(x, y);
- if (s)
- {
- std::string desc = "[Stash: "
- + s->description() + "]";
- mpr(desc.c_str());
- }
- }
-}
-
-static void fully_identify_item(item_def *item)
-{
- if (!item || !is_valid_item(*item))
- return;
-
- set_ident_flags( *item, ISFLAG_IDENT_MASK );
- if (item->base_type != OBJ_WEAPONS)
- set_ident_type( item->base_type,
- item->sub_type,
- ID_KNOWN_TYPE );
-}
-
-static void save_item(FILE *file, const item_def &item)
-{
- writeByte(file, item.base_type);
- writeByte(file, item.sub_type);
- writeShort(file, item.plus);
- writeShort(file, item.plus2);
- writeLong(file, item.special);
- writeShort(file, item.quantity);
- writeByte(file, item.colour);
- writeLong(file, item.flags);
-}
-
-static void load_item(FILE *file, item_def &item)
-{
- item.base_type = readByte(file);
- item.sub_type = readByte(file);
- item.plus = readShort(file);
- item.plus2 = readShort(file);
- item.special = readLong(file);
- item.quantity = readShort(file);
- item.colour = readByte(file);
- item.flags = readLong(file);
-}
-
-bool Stash::aggressive_verify = true;
-std::vector<item_def> Stash::filters;
-
-Stash::Stash(int xp, int yp) : enabled(true), items()
-{
- // First, fix what square we're interested in
- if (xp == -1)
- {
- xp = you.x_pos;
- yp = you.y_pos;
- }
- x = (unsigned char) xp;
- y = (unsigned char) yp;
- abspos = GXM * (int) y + x;
-
- update();
-}
-
-bool Stash::are_items_same(const item_def &a, const item_def &b)
-{
- return a.base_type == b.base_type &&
- a.sub_type == b.sub_type &&
- a.plus == b.plus &&
- a.plus2 == b.plus2 &&
- a.special == b.special &&
- a.colour == b.colour &&
- a.flags == b.flags &&
- a.quantity == b.quantity;
-}
-
-void Stash::filter(const std::string &str)
-{
- std::string base = str;
-
- base.erase(base.find_last_not_of(" \n\t") + 1);
- base.erase(0, base.find_first_not_of(" \n\t"));
-
- unsigned char subc = 255;
- std::string::size_type cpos = base.find(":", 0);
- if (cpos != std::string::npos)
- {
- std::string subs = base.substr(cpos + 1);
- subc = atoi(subs.c_str());
-
- base = base.substr(0, cpos);
- }
-
- unsigned char basec = atoi(base.c_str());
- filter(basec, subc);
-}
-
-void Stash::filter(unsigned char base, unsigned char sub)
-{
- item_def item;
- item.base_type = base;
- item.sub_type = sub;
-
- filters.push_back(item);
-}
-
-bool Stash::is_filtered(const item_def &item)
-{
- for (int i = 0, count = filters.size(); i < count; ++i)
- {
- const item_def &filter = filters[i];
- if (item.base_type == filter.base_type &&
- (filter.sub_type == 255 ||
- item.sub_type == filter.sub_type))
- return true;
- }
- return false;
-}
-
-void Stash::update()
-{
- int objl = igrd[x][y];
- // If this is your position, you know what's on this square
- if (x == you.x_pos && y == you.y_pos)
- {
- // Zap existing items
- items.clear();
-
- // Now, grab all items on that square and fill our vector
- while (objl != NON_ITEM)
- {
- if (!is_filtered(mitm[objl]))
- items.push_back(mitm[objl]);
- objl = mitm[objl].link;
- }
-
- verified = true;
- }
- // If this is not your position, the only thing we can do is verify that
- // what the player sees on the square is the first item in this vector.
- else
- {
- if (objl == NON_ITEM)
- {
- items.clear();
- verified = true;
- return ;
- }
-
- // There's something on this square. Take a squint at it.
- item_def &item = mitm[objl];
-
- if (item.link == NON_ITEM) items.clear();
-
- // We knew of nothing on this square, so we'll assume this is the
- // only item here, but mark it as unverified unless we can see nothing
- // under the item.
- if (items.size() == 0)
- {
- if (!is_filtered(item))
- items.push_back(item);
- verified = (item.link == NON_ITEM);
- return ;
- }
-
- // There's more than one item in this pile. As long as the top item is
- // not filtered, we can check to see if it matches what we think the
- // top item is.
-
- if (is_filtered(item)) return;
-
- item_def &first = items[0];
- // Compare these items
- if (!are_items_same(first, item))
- {
- if (aggressive_verify)
- {
- // See if 'item' matches any of the items we have. If it does,
- // we'll just make that the first item and leave 'verified'
- // unchanged.
-
- // Start from 1 because we've already checked items[0]
- for (int i = 1, count = items.size(); i < count; ++i)
- {
- if (are_items_same(items[i], item))
- {
- // Found it. Swap it to the front of the vector.
- item_def temp = items[i];
- items[i] = items[0];
- items[0] = temp;
-
- // We don't set verified to true. If this stash was
- // already unverified, it remains so.
- return;
- }
- }
- }
-
- // If this is unverified, forget last item on stack. This isn't
- // terribly clever, but it prevents the vector swelling forever.
- if (!verified) items.pop_back();
-
- // Items are different. We'll put this item in the front of our
- // vector, and mark this as unverified
- items.insert(items.begin(), item);
- verified = false;
- }
- }
-}
-
-// Returns the item name for a given item, with any appropriate
-// stash-tracking pre/suffixes.
-std::string Stash::stash_item_name(const item_def &item)
-{
- char buf[ITEMNAME_SIZE];
-
- if (item.base_type == OBJ_GOLD)
- snprintf(buf, sizeof buf, "%d gold piece%s", item.quantity,
- (item.quantity > 1? "s" : ""));
- else
- item_name(item, DESC_NOCAP_A, buf, false);
-
- return buf;
-}
-
-class StashMenu : public Menu
-{
-public:
- StashMenu() : Menu(MF_SINGLESELECT), can_travel(false) { }
-public:
- bool can_travel;
-protected:
- void draw_title();
- bool process_key(int key);
-};
-
-void StashMenu::draw_title()
-{
- if (title)
- {
- gotoxy(1, 1);
- textcolor(title->colour);
- cprintf(title->text.c_str());
- if (title->quantity)
- cprintf(", %d item%s", title->quantity,
- title->quantity == 1? "" : "s");
- cprintf(")");
- if (can_travel)
- cprintf(" [ENTER - travel]");
- }
-}
-
-bool StashMenu::process_key(int key)
-{
- if (key == CK_ENTER)
- {
- // Travel activates.
- lastch = 1;
- return false;
- }
- return Menu::process_key(key);
-}
-
-static void stash_menu_fixup(MenuEntry *me)
-{
- const item_def *item = static_cast<const item_def *>( me->data );
- if (item->base_type == OBJ_GOLD)
- {
- me->quantity = 0;
- me->colour = DARKGREY;
- }
-}
-
-bool Stash::show_menu(const std::string &prefix, bool can_travel) const
-{
- StashMenu menu;
-
- MenuEntry *mtitle = new MenuEntry(" Stash (" + prefix);
- menu.can_travel = can_travel;
- mtitle->colour = WHITE;
- mtitle->quantity = items.size();
- menu.set_title(mtitle);
-
- populate_item_menu(&menu, items, stash_menu_fixup);
- std::vector<MenuEntry*> sel;
- while (true)
- {
- sel = menu.show();
- if (menu.getkey() == 1)
- return true;
-
- if (sel.size() != 1)
- break;
-
- const item_def *item =
- static_cast<const item_def *>( sel[0]->data );
- describe_item(*item);
- }
- return false;
-}
-
-std::string Stash::description() const
-{
- if (!enabled || items.empty())
- return ("");
-
- const item_def &item = items[0];
- std::string desc = stash_item_name(item);
-
- size_t sz = items.size();
- if (sz > 1)
- {
- char additionals[50];
- snprintf(additionals, sizeof additionals, " (+%lu)", (unsigned long) (sz - 1));
- desc += additionals;
- }
- return (desc);
-}
-
-bool Stash::matches_search(const std::string &prefix,
- const base_pattern &search,
- stash_search_result &res) const
-{
- if (!enabled || items.empty()) return false;
-
- for (unsigned i = 0; i < items.size(); ++i)
- {
- const item_def &item = items[i];
- std::string s = stash_item_name(item);
- std::string ann = stash_annotate_item(
- LUA_SEARCH_ANNOTATE, &item);
- if (search.matches(prefix + " " + ann + s))
- {
- if (!res.count++)
- res.match = s;
- res.matches += item.quantity;
- continue;
- }
-
- if (is_dumpable_artifact(item, Options.verbose_dump))
- {
- std::string desc = munge_description(get_item_description(item,
- Options.verbose_dump,
- true ));
- if (search.matches(desc))
- {
- if (!res.count++)
- res.match = s;
- res.matches += item.quantity;
- }
- }
- }
- if (res.matches)
- {
- res.stash = this;
- res.pos.x = x;
- res.pos.y = y;
- }
-
- return !!res.matches;
-}
-
-void Stash::write(std::ostream &os,
- int refx, int refy,
- std::string place,
- bool identify)
- const
-{
- if (!enabled || (items.size() == 0 && verified)) return;
- os << "(" << ((int) x - refx) << ", " << ((int) y - refy)
- << (place.length()? ", " + place : "")
- << ")"
- << std::endl;
-
- char buf[ITEMNAME_SIZE];
- for (int i = 0; i < (int) items.size(); ++i)
- {
- item_def item = items[i];
-
- if (identify)
- fully_identify_item(&item);
-
- std::string s = stash_item_name(item);
- strncpy(buf, s.c_str(), sizeof buf);
-
- std::string ann = userdef_annotate_item(
- LUA_DUMP_ANNOTATE, &item);
-
- if (!ann.empty())
- {
- trim_string(ann);
- ann = " " + ann;
- }
-
- os << " " << buf
- << (!ann.empty()? ann : std::string())
- << (!verified && (items.size() > 1 || i)? " (still there?)" : "")
- << std::endl;
-
- if (is_dumpable_artifact(item, Options.verbose_dump))
- {
- std::string desc = munge_description(get_item_description(item,
- Options.verbose_dump,
- true ));
- // Kill leading and trailing whitespace
- desc.erase(desc.find_last_not_of(" \n\t") + 1);
- desc.erase(0, desc.find_first_not_of(" \n\t"));
- // If string is not-empty, pad out to a neat indent
- if (desc.length())
- {
- // Walk backwards and prepend indenting spaces to \n characters
- for (int j = desc.length() - 1; j >= 0; --j)
- if (desc[j] == '\n')
- desc.insert(j + 1, " ");
- os << " " << desc << std::endl;
- }
- }
- }
-
- if (items.size() <= 1 && !verified)
- os << " (unseen)" << std::endl;
-}
-
-void Stash::save(FILE *file) const
-{
- // How many items on this square?
- writeShort(file, (short) items.size());
-
- writeByte(file, x);
- writeByte(file, y);
-
- // Note: Enabled save value is inverted logic, so that it defaults to true
- writeByte(file,
- (unsigned char) ((verified? 1 : 0) | (!enabled? 2 : 0)) );
-
- // And dump the items individually. We don't bother saving fields we're
- // not interested in (and don't anticipate being interested in).
- for (unsigned i = 0; i < items.size(); ++i)
- save_item(file, items[i]);
-}
-
-void Stash::load(FILE *file)
-{
- // How many items?
- int count = readShort(file);
-
- x = readByte(file);
- y = readByte(file);
-
- unsigned char flags = readByte(file);
- verified = (flags & 1) != 0;
-
- // Note: Enabled save value is inverted so it defaults to true.
- enabled = (flags & 2) == 0;
-
- abspos = GXM * (int) y + x;
-
- // Zap out item vector, in case it's in use (however unlikely)
- items.clear();
- // Read in the items
- for (int i = 0; i < count; ++i)
- {
- item_def item;
- load_item(file, item);
-
- items.push_back(item);
- }
-}
-
-std::ostream &operator << (std::ostream &os, const Stash &s)
-{
- s.write(os);
- return os;
-}
-
-ShopInfo::ShopInfo(int xp, int yp) : x(xp), y(yp), name(), shoptype(-1),
- visited(false), items()
-{
- // Most of our initialization will be done externally; this class is really
- // a mildly glorified struct.
- const shop_struct *sh = get_shop(x, y);
- if (sh)
- shoptype = sh->type;
-}
-
-ShopInfo::ShopId::ShopId(int stype) : shoptype(stype), id()
-{
- shop_init_id_type( shoptype, id );
-}
-
-ShopInfo::ShopId::~ShopId()
-{
- shop_uninit_id_type( shoptype, id );
-}
-
-void ShopInfo::add_item(const item_def &sitem, unsigned price)
-{
- shop_item it;
- it.item = sitem;
- it.price = price;
- items.push_back(it);
-}
-
-std::string ShopInfo::shop_item_name(const shop_item &si) const
-{
- char shopitem[ITEMNAME_SIZE * 2];
- std::string itemname = Stash::stash_item_name(si.item);
- snprintf(shopitem, sizeof shopitem, "%s (%u gold)",
- itemname.c_str(), si.price);
- return shopitem;
-}
-
-std::string ShopInfo::shop_item_desc(const shop_item &si) const
-{
- std::string desc;
- if (is_dumpable_artifact(si.item, Options.verbose_dump))
- {
- desc = munge_description(get_item_description(si.item,
- Options.verbose_dump,
- true));
-
- // trim leading whitespace
- std::string::size_type notwhite = desc.find_first_not_of(" \t\n");
- desc.erase(0, notwhite);
-
- // trim trailing whitespace
- notwhite = desc.find_last_not_of(" \t\n");
- desc.erase(notwhite + 1);
-
- // Walk backwards and prepend indenting spaces to \n characters
- for (int i = desc.length() - 1; i >= 0; --i)
- if (desc[i] == '\n')
- desc.insert(i + 1, " ");
- }
- return desc;
-}
-
-void ShopInfo::describe_shop_item(const shop_item &si) const
-{
- describe_item( si.item );
-}
-
-bool ShopInfo::show_menu(const std::string &place,
- bool can_travel) const
-{
- ShopId id(shoptype);
- StashMenu menu;
-
- MenuEntry *mtitle = new MenuEntry(" " + name + " (" + place);
- menu.can_travel = can_travel;
- mtitle->colour = WHITE;
- mtitle->quantity = items.size();
- menu.set_title(mtitle);
-
- menu_letter hotkey;
- if (items.empty())
- {
- MenuEntry *me = new MenuEntry(
- visited? " (Shop is empty)" : " (Shop contents are unknown)",
- MEL_ITEM,
- 0,
- 0);
- me->colour = DARKGREY;
- menu.add_entry(me);
- }
- else
- {
- for (int i = 0, count = items.size(); i < count; ++i)
- {
- MenuEntry *me = new MenuEntry(shop_item_name(items[i]),
- MEL_ITEM,
- 1,
- hotkey++);
- me->data = const_cast<shop_item *>( &items[i] );
- menu.add_entry(me);
- }
- }
-
- std::vector<MenuEntry*> sel;
- while (true)
- {
- sel = menu.show();
- if (menu.getkey() == 1)
- return true;
-
- if (sel.size() != 1)
- break;
-
- const shop_item *item =
- static_cast<const shop_item *>( sel[0]->data );
- describe_shop_item(*item);
- }
- return false;
-}
-
-std::string ShopInfo::description() const
-{
- return (name);
-}
-
-bool ShopInfo::matches_search(const std::string &prefix,
- const base_pattern &search,
- stash_search_result &res) const
-{
- if (items.empty() && visited) return false;
-
- ShopId id(shoptype);
- bool match = false;
-
- for (unsigned i = 0; i < items.size(); ++i)
- {
- std::string name = shop_item_name(items[i]);
- std::string ann = stash_annotate_item(
- LUA_SEARCH_ANNOTATE, &items[i].item, true);
-
- bool thismatch = false;
- if (search.matches(prefix + " " + ann + name))
- thismatch = true;
- else
- {
- std::string desc = shop_item_desc(items[i]);
- if (search.matches(desc))
- thismatch = true;
- }
-
- if (thismatch)
- {
- if (!res.count++)
- res.match = name;
- res.matches++;
- }
- }
-
- if (!res.matches)
- {
- std::string shoptitle = prefix + " {shop} " + name;
- if (!visited && items.empty())
- shoptitle += "*";
- if (search.matches(shoptitle))
- {
- match = true;
- res.match = name;
- }
- }
-
- if (match || res.matches)
- {
- res.shop = this;
- res.pos.x = x;
- res.pos.y = y;
- }
-
- return match || res.matches;
-}
-
-void ShopInfo::write(std::ostream &os, bool identify) const
-{
- ShopId id(shoptype);
-
- os << "[Shop] " << name << std::endl;
- if (items.size() > 0)
- {
- for (unsigned i = 0; i < items.size(); ++i)
- {
- shop_item item = items[i];
-
- if (identify)
- fully_identify_item(&item.item);
-
- os << " " << shop_item_name(item) << std::endl;
- std::string desc = shop_item_desc(item);
- if (desc.length() > 0)
- os << " " << desc << std::endl;
- }
- }
- else if (visited)
- os << " (Shop is empty)" << std::endl;
- else
- os << " (Shop contents are unknown)" << std::endl;
-}
-
-void ShopInfo::save(FILE *file) const
-{
- writeShort(file, shoptype);
-
- int mangledx = (short) x;
- if (!visited)
- mangledx |= 1024;
- writeShort(file, mangledx);
- writeShort(file, (short) y);
-
- writeShort(file, (short) items.size());
-
- writeString(file, name);
-
- for (unsigned i = 0; i < items.size(); ++i)
- {
- save_item(file, items[i].item);
- writeShort(file, (short) items[i].price );
- }
-}
-
-void ShopInfo::load(FILE *file)
-{
- shoptype = readShort(file);
-
- x = readShort(file);
- visited = !(x & 1024);
- x &= 0xFF;
-
- y = readShort(file);
-
- int itemcount = readShort(file);
-
- name = readString(file);
- for (int i = 0; i < itemcount; ++i)
- {
- shop_item item;
- load_item(file, item.item);
- item.price = (unsigned) readShort(file);
- items.push_back(item);
- }
-}
-
-std::ostream &operator << (std::ostream &os, const ShopInfo &s)
-{
- s.write(os);
- return os;
-}
-
-LevelStashes::LevelStashes()
-{
- branch = you.where_are_you;
- depth = you.your_level;
-}
-
-bool LevelStashes::operator < (const LevelStashes &lev) const
-{
- return branch < lev.branch || (branch == lev.branch && depth < lev.depth);
-}
-
-bool LevelStashes::isBelowPlayer() const
-{
- return branch > you.where_are_you
- || (branch == you.where_are_you && depth > you.your_level);
-}
-
-Stash *LevelStashes::find_stash(int x, int y)
-{
- if (x == -1 || y == -1)
- {
- x = you.x_pos;
- y = you.y_pos;
- }
- const int abspos = (GXM * y) + x;
- c_stashes::iterator st = stashes.find(abspos);
- return (st == stashes.end()? NULL : &st->second);
-}
-
-const ShopInfo *LevelStashes::find_shop(int x, int y) const
-{
- for (unsigned i = 0; i < shops.size(); ++i)
- {
- if (shops[i].isAt(x, y))
- return (&shops[i]);
- }
- return (NULL);
-}
-
-ShopInfo &LevelStashes::get_shop(int x, int y)
-{
- for (unsigned i = 0; i < shops.size(); ++i)
- {
- if (shops[i].isAt(x, y))
- return shops[i];
- }
- ShopInfo si(x, y);
- si.set_name(shop_name(x, y));
- shops.push_back(si);
- return get_shop(x, y);
-}
-
-// Updates the stash at (x,y). Returns true if there was a stash at (x,y), false
-// otherwise.
-bool LevelStashes::update_stash(int x, int y)
-{
- Stash *s = find_stash(x, y);
- if (s)
- {
- s->update();
- if (s->empty())
- kill_stash(*s);
- return true;
- }
- return false;
-}
-
-// Removes a Stash from the level.
-void LevelStashes::kill_stash(const Stash &s)
-{
- stashes.erase(s.abs_pos());
-}
-
-void LevelStashes::no_stash(int x, int y)
-{
- Stash *s = find_stash(x, y);
- bool en = false;
- if (s)
- {
- en = s->enabled = !s->enabled;
- s->update();
- if (s->empty())
- kill_stash(*s);
- }
- else
- {
- Stash newStash(x, y);
- newStash.enabled = false;
-
- stashes[ newStash.abs_pos() ] = newStash;
- }
-
- mpr(en? "I'll no longer ignore what I see on this square."
- : "Ok, I'll ignore what I see on this square.");
-}
-
-void LevelStashes::add_stash(int x, int y)
-{
- Stash *s = find_stash(x, y);
- if (s)
- {
- s->update();
- if (s->empty())
- kill_stash(*s);
- }
- else
- {
- Stash newStash(x, y);
- if (!newStash.empty())
- stashes[ newStash.abs_pos() ] = newStash;
- }
-}
-
-bool LevelStashes::isCurrent() const
-{
- return branch == you.where_are_you && depth == you.your_level;
-}
-
-bool LevelStashes::in_hell() const
-{
- return branch >= BRANCH_DIS
- && branch <= BRANCH_THE_PIT
- && branch != BRANCH_VESTIBULE_OF_HELL;
-}
-
-bool LevelStashes::in_branch(int branchid) const
-{
- return branch == branchid;
-}
-
-
-std::string LevelStashes::level_name() const
-{
- int curr_subdungeon_level = subdungeon_depth( branch, depth );
- return (branch_level_name(branch, curr_subdungeon_level));
-}
-
-std::string LevelStashes::short_level_name() const
-{
- return (short_place_name(
- get_packed_place( branch,
- subdungeon_depth( branch, depth ),
- LEVEL_DUNGEON ) ));
-}
-
-int LevelStashes::count_stashes() const
-{
- int rawcount = stashes.size();
- if (!rawcount)
- return (0);
-
- for (c_stashes::const_iterator iter = stashes.begin();
- iter != stashes.end(); iter++)
- {
- if (!iter->second.enabled)
- --rawcount;
- }
- return rawcount;
-}
-
-void LevelStashes::get_matching_stashes(
- const base_pattern &search,
- std::vector<stash_search_result> &results)
- const
-{
- level_id clid(branch, subdungeon_depth(branch, depth));
- std::string lplace = "{" + short_place_name(clid) + "}";
- for (c_stashes::const_iterator iter = stashes.begin();
- iter != stashes.end(); iter++)
- {
- if (iter->second.enabled)
- {
- stash_search_result res;
- if (iter->second.matches_search(lplace, search, res))
- {
- res.level = clid;
- results.push_back(res);
- }
- }
- }
-
- for (unsigned i = 0; i < shops.size(); ++i)
- {
- stash_search_result res;
- if (shops[i].matches_search(lplace, search, res))
- {
- res.level = clid;
- results.push_back(res);
- }
- }
-}
-
-void LevelStashes::write(std::ostream &os, bool identify) const
-{
- if (visible_stash_count() == 0) return ;
- os << level_name() << std::endl;
-
- for (unsigned i = 0; i < shops.size(); ++i)
- {
- shops[i].write(os, identify);
- }
-
- if (stashes.size())
- {
- const Stash &s = stashes.begin()->second;
- int refx = s.getX(), refy = s.getY();
- std::string level_name = short_level_name();
- for (c_stashes::const_iterator iter = stashes.begin();
- iter != stashes.end(); iter++)
- {
- iter->second.write(os, refx, refy, level_name, identify);
- }
- }
- os << std::endl;
-}
-
-void LevelStashes::save(FILE *file) const
-{
- // How many stashes on this level?
- writeShort(file, (short) stashes.size());
-
- writeByte(file, branch);
- writeShort(file, (short) depth);
-
- // And write the individual stashes
- for (c_stashes::const_iterator iter = stashes.begin();
- iter != stashes.end(); iter++)
- iter->second.save(file);
-
- writeShort(file, (short) shops.size());
- for (unsigned i = 0; i < shops.size(); ++i)
- shops[i].save(file);
-}
-
-void LevelStashes::load(FILE *file)
-{
- int size = readShort(file);
-
- branch = readByte(file);
- depth = readShort(file);
-
- stashes.clear();
- for (int i = 0; i < size; ++i)
- {
- Stash s;
- s.load(file);
- if (!s.empty())
- stashes[ s.abs_pos() ] = s;
- }
-
- shops.clear();
- int shopc = readShort(file);
- for (int i = 0; i < shopc; ++i)
- {
- ShopInfo si(0, 0);
- si.load(file);
- shops.push_back(si);
- }
-}
-
-std::ostream &operator << (std::ostream &os, const LevelStashes &ls)
-{
- ls.write(os);
- return os;
-}
-
-LevelStashes &StashTracker::get_current_level()
-{
- std::vector<LevelStashes>::iterator iter = levels.begin();
- for ( ; iter != levels.end() && !iter->isBelowPlayer(); iter++)
- {
- if (iter->isCurrent()) return *iter;
- }
- if (iter == levels.end())
- levels.push_back(LevelStashes());
- else
- levels.insert(iter, LevelStashes());
- return get_current_level();
-}
-
-LevelStashes *StashTracker::find_current_level()
-{
- std::vector<LevelStashes>::iterator iter = levels.begin();
- for ( ; iter != levels.end() && !iter->isBelowPlayer(); iter++)
- {
- if (iter->isCurrent()) return &*iter;
- }
- return NULL;
-}
-
-
-bool StashTracker::update_stash(int x, int y)
-{
- LevelStashes *lev = find_current_level();
- if (lev)
- {
- bool res = lev->update_stash(x, y);
- if (!lev->stash_count())
- remove_level(*lev);
- return res;
- }
- return false;
-}
-
-void StashTracker::remove_level(const LevelStashes &ls)
-{
- std::vector<LevelStashes>::iterator iter = levels.begin();
- for ( ; iter != levels.end(); ++iter)
- {
- if (&ls == &*iter)
- {
- levels.erase(iter);
- break ;
- }
- }
-}
-
-void StashTracker::no_stash(int x, int y)
-{
- if (is_level_untrackable())
- return ;
- LevelStashes &current = get_current_level();
- current.no_stash(x, y);
- if (!current.stash_count())
- remove_level(current);
-}
-
-void StashTracker::add_stash(int x, int y, bool verbose)
-{
- if (is_level_untrackable())
- return ;
- LevelStashes &current = get_current_level();
- current.add_stash(x, y);
-
- if (verbose)
- {
- Stash *s = current.find_stash(x, y);
- if (s && s->enabled)
- mpr("Added stash.");
- }
-
- if (!current.stash_count())
- remove_level(current);
-}
-
-void StashTracker::dump(const char *filename, bool identify) const
-{
- std::ofstream outf(filename);
- if (outf)
- {
- write(outf, identify);
- outf.close();
- }
-}
-
-void StashTracker::write(std::ostream &os, bool identify) const
-{
- os << you.your_name << std::endl << std::endl;
- if (!levels.size())
- os << " You have no stashes." << std::endl;
- else
- {
- std::vector<LevelStashes>::const_iterator iter = levels.begin();
- for ( ; iter != levels.end(); iter++)
- {
- iter->write(os, identify);
- }
- }
-}
-
-void StashTracker::save(FILE *file) const
-{
- // Write version info first - major + minor
- writeByte(file, ST_MAJOR_VER);
- writeByte(file, ST_MINOR_VER);
-
- // How many levels have we?
- writeShort(file, (short) levels.size());
-
- // And ask each level to write itself to the tag
- std::vector<LevelStashes>::const_iterator iter = levels.begin();
- for ( ; iter != levels.end(); iter++)
- iter->save(file);
-}
-
-void StashTracker::load(FILE *file)
-{
- // Check version. Compatibility isn't important, since stash-tracking
- // is non-critical.
- unsigned char major = readByte(file),
- minor = readByte(file);
- if (major != ST_MAJOR_VER || minor != ST_MINOR_VER) return ;
-
- int count = readShort(file);
-
- levels.clear();
- for (int i = 0; i < count; ++i)
- {
- LevelStashes st;
- st.load(file);
- if (st.stash_count()) levels.push_back(st);
- }
-}
-
-void StashTracker::update_visible_stashes(
- StashTracker::stash_update_mode mode)
-{
- if (is_level_untrackable())
- return ;
-
- LevelStashes *lev = find_current_level();
- for (int cy = 1; cy <= 17; ++cy)
- {
- for (int cx = 9; cx <= 25; ++cx)
- {
- int x = you.x_pos + cx - 17, y = you.y_pos + cy - 9;
- if (x < 0 || x >= GXM || y < 0 || y >= GYM)
- continue;
-
- if (!env.show[cx - 8][cy] && !(cx == 17 && cy == 9))
- continue;
-
- if ((!lev || !lev->update_stash(x, y))
- && mode == ST_AGGRESSIVE
- && igrd[x][y] != NON_ITEM)
- {
- if (!lev)
- lev = &get_current_level();
- lev->add_stash(x, y);
- }
-
- if (grd[x][y] == DNGN_ENTER_SHOP)
- get_shop(x, y);
- }
- }
-
- if (lev && !lev->stash_count())
- remove_level(*lev);
-}
-
-#define SEARCH_SPAM_THRESHOLD 400
-static std::string lastsearch;
-static input_history search_history(15);
-
-void StashTracker::search_stashes()
-{
- char prompt[200];
- if (lastsearch.length())
- snprintf(prompt, sizeof prompt,
- "Search your stashes for what item [Enter for \"%s\"]?",
- lastsearch.c_str());
- else
- snprintf(prompt, sizeof prompt,
- "Search your stashes for what item?");
-
- mpr(prompt, MSGCH_PROMPT);
- // Push the cursor down to the next line.
- mpr("", MSGCH_PROMPT);
-
- char buf[400];
- bool validline = cancelable_get_line(buf, sizeof buf, 80, &search_history);
- mesclr();
- if (!validline || (!*buf && !lastsearch.length()))
- return;
-
- std::string csearch = *buf? buf : lastsearch;
- std::vector<stash_search_result> results;
-
- base_pattern *search = NULL;
-
- text_pattern tpat( csearch, true );
- search = &tpat;
-
-#ifdef CLUA_BINDINGS
- lua_text_pattern ltpat( csearch );
-
- if (lua_text_pattern::is_lua_pattern(csearch))
- search = &ltpat;
-#endif
-
- if (!search->valid())
- {
- mpr("Your search expression is invalid.", MSGCH_PLAIN);
- return ;
- }
-
- lastsearch = csearch;
-
- get_matching_stashes(*search, results);
-
- if (results.empty())
- {
- mpr("That item is not present in any of your stashes.",
- MSGCH_PLAIN);
- return;
- }
-
- if (results.size() > SEARCH_SPAM_THRESHOLD)
- {
- mpr("Too many matches; use a more specific search.", MSGCH_PLAIN);
- return ;
- }
-
- display_search_results(results);
-}
-
-void StashTracker::get_matching_stashes(
- const base_pattern &search,
- std::vector<stash_search_result> &results)
- const
-{
- std::vector<LevelStashes>::const_iterator iter = levels.begin();
- for ( ; iter != levels.end(); iter++)
- {
- iter->get_matching_stashes(search, results);
- if (results.size() > SEARCH_SPAM_THRESHOLD)
- return;
- }
-
- level_id curr = level_id::get_current_level_id();
- for (unsigned i = 0; i < results.size(); ++i)
- {
- results[i].player_distance = level_distance(curr, results[i].level);
- }
-
- // Sort stashes so that closer stashes come first and stashes on the same
- // levels with more items come first.
- std::sort(results.begin(), results.end());
-}
-
-class StashSearchMenu : public Menu
-{
-public:
- StashSearchMenu() : Menu(), can_travel(true), meta_key(0) { }
-
-public:
- bool can_travel;
- int meta_key;
-
-protected:
- bool process_key(int key);
- void draw_title();
-};
-
-void StashSearchMenu::draw_title()
-{
- if (title)
- {
- gotoxy(1, 1);
- textcolor(title->colour);
- cprintf(" %d %s%s", title->quantity, title->text.c_str(),
- title->quantity > 1? "es" : "");
-
- if (meta_key)
- draw_title_suffix(" (x - examine stash)", false);
- else
- draw_title_suffix(" (x - go to stash; ? - examine stash)", false);
- }
-}
-
-bool StashSearchMenu::process_key(int key)
-{
- if (key == '?')
- {
- if (sel)
- sel->clear();
- meta_key = !meta_key;
- update_title();
- return true;
- }
-
- return Menu::process_key(key);
-}
-
-void StashTracker::display_search_results(
- std::vector<stash_search_result> &results)
-{
- if (results.empty())
- return;
-
- bool travelable = can_travel_interlevel();
-
- StashSearchMenu stashmenu;
- stashmenu.can_travel = travelable;
- std::string title = "matching stash";
-
- MenuEntry *mtitle = new MenuEntry(title);
- mtitle->colour = WHITE;
- // Abuse of the quantity field.
- mtitle->quantity = results.size();
- stashmenu.set_title(mtitle);
-
- menu_letter hotkey;
- for (unsigned i = 0; i < results.size(); ++i, ++hotkey)
- {
- stash_search_result &res = results[i];
- char matchtitle[ITEMNAME_SIZE];
- std::string place = short_place_name(res.level);
- if (res.matches > 1 && res.count > 1)
- {
- snprintf(matchtitle, sizeof matchtitle,
- "[%s] %s (%d)",
- place.c_str(),
- res.match.c_str(),
- res.matches);
- }
- else
- {
- snprintf(matchtitle, sizeof matchtitle,
- "[%s] %s",
- place.c_str(),
- res.match.c_str());
- }
- std::string mename = matchtitle;
-
- MenuEntry *me = new MenuEntry(mename, MEL_ITEM, 1, hotkey);
- me->data = &res;
- if (res.shop && !res.shop->is_visited())
- me->colour = CYAN;
- stashmenu.add_entry(me);
- }
-
- stashmenu.set_flags( MF_SINGLESELECT );
-
- std::vector<MenuEntry*> sel;
- while (true)
- {
- sel = stashmenu.show();
-
- if (sel.size() == 1 && stashmenu.meta_key)
- {
- stash_search_result *res =
- static_cast<stash_search_result *>(sel[0]->data);
-
- bool dotravel = false;
- if (res->shop)
- {
- dotravel = res->shop->show_menu(short_place_name(res->level),
- travelable);
- }
- else if (res->stash)
- {
- dotravel = res->stash->show_menu(short_place_name(res->level),
- travelable);
- }
-
- if (dotravel && travelable)
- {
- redraw_screen();
- level_pos lp;
- lp.id = res->level;
- lp.pos = res->pos;
- start_translevel_travel(lp);
- return ;
- }
- continue;
- }
- break;
- }
-
- redraw_screen();
- if (travelable && sel.size() == 1 && !stashmenu.meta_key)
- {
- const stash_search_result *res =
- static_cast<stash_search_result *>(sel[0]->data);
- level_pos lp;
- lp.id = res->level;
- lp.pos = res->pos;
- start_translevel_travel(lp);
- return ;
- }
-
-}
-
-// Global
-StashTracker stashes;
-
-#endif
-
-std::string branch_level_name(unsigned char branch, int sub_depth)
-{
- int ltype = sub_depth == 0xFF? branch : 0;
- if (ltype == LEVEL_PANDEMONIUM)
- return ("Pandemonium");
- else if (ltype == LEVEL_ABYSS)
- return ("The Abyss");
- else if (ltype == LEVEL_LABYRINTH)
- return ("A Labyrinth");
- else
- {
- char buf[200];
- const char *s = NULL;
- *buf = 0;
- // level_type == LEVEL_DUNGEON
- if (branch != BRANCH_VESTIBULE_OF_HELL
- && branch != BRANCH_ECUMENICAL_TEMPLE
- && branch != BRANCH_HALL_OF_BLADES)
- snprintf(buf, sizeof buf, "Level %d", sub_depth);
-
- switch (branch)
- {
- case BRANCH_MAIN_DUNGEON:
- s = " of the Dungeon";
- break;
- case BRANCH_DIS:
- s = " of Dis";
- break;
- case BRANCH_GEHENNA:
- s = " of Gehenna";
- break;
- case BRANCH_VESTIBULE_OF_HELL:
- s = "The Vestibule of Hell";
- break;
- case BRANCH_COCYTUS:
- s = " of Cocytus";
- break;
- case BRANCH_TARTARUS:
- s = " of Tartarus";
- break;
- case BRANCH_INFERNO:
- s = " of the Inferno";
- break;
- case BRANCH_THE_PIT:
- s = " of the Pit";
- break;
- case BRANCH_ORCISH_MINES:
- s = " of the Orcish Mines";
- break;
- case BRANCH_HIVE:
- s = " of the Hive";
- break;
- case BRANCH_LAIR:
- s = " of the Lair";
- break;
- case BRANCH_SLIME_PITS:
- s = " of the Slime Pits";
- break;
- case BRANCH_VAULTS:
- s = " of the Vaults";
- break;
- case BRANCH_CRYPT:
- s = " of the Crypt";
- break;
- case BRANCH_HALL_OF_BLADES:
- s = "The Hall of Blades";
- break;
- case BRANCH_HALL_OF_ZOT:
- s = " of the Realm of Zot";
- break;
- case BRANCH_ECUMENICAL_TEMPLE:
- s = "The Ecumenical Temple";
- break;
- case BRANCH_SNAKE_PIT:
- s = " of the Snake Pit";
- break;
- case BRANCH_ELVEN_HALLS:
- s = " of the Elven Halls";
- break;
- case BRANCH_TOMB:
- s = " of the Tomb";
- break;
- case BRANCH_SWAMP:
- s = " of the Swamp";
- break;
- }
- if (s)
- strncat(buf, s, sizeof(buf) - 1);
- return (buf);
- }
-}
-
-std::string branch_level_name(unsigned short packed_place)
-{
- return branch_level_name(packed_place >> 8, packed_place & 0xFF);
-}
diff --git a/stone_soup/crawl-ref/source/stash.h b/stone_soup/crawl-ref/source/stash.h
deleted file mode 100644
index 5e36eb4a61..0000000000
--- a/stone_soup/crawl-ref/source/stash.h
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * File: stash.h
- * Summary: Classes tracking player stashes
- * Written by: Darshan Shaligram
- */
-#ifndef STASH_H
-#define STASH_H
-
-#include "AppHdr.h"
-#include "shopping.h"
-#include <string>
-
-#ifdef STASH_TRACKING
-
-#include <iostream>
-#include <map>
-#include <vector>
-
-#include "externs.h"
-#include "travel.h"
-
-// Stash definitions
-
-enum STASH_TRACK_MODES
-{
- STM_NONE, // Stashes are not tracked
- STM_EXPLICIT, // Only explicitly marked stashes are tracked
- STM_DROPPED, // Dropped items and explicitly marked stashes are
- // tracked
- STM_ALL // All seen items are tracked
-};
-
-struct stash_search_result;
-class Stash
-{
-public:
- Stash(int xp = -1, int yp = -1);
-
- static void filter(unsigned char base_type, unsigned char sub_type);
- static void filter(const std::string &filt);
-
- static std::string stash_item_name(const item_def &item);
- void update();
- void save(FILE*) const;
- void load(FILE*);
-
- std::string description() const;
-
- bool show_menu(const std::string &place, bool can_travel) const;
-
- bool matches_search(const std::string &prefix,
- const base_pattern &search,
- stash_search_result &res)
- const;
-
- void write(std::ostream &os, int refx = 0, int refy = 0,
- std::string place = "",
- bool identify = false) const;
-
- bool empty() const
- {
- return items.empty() && enabled;
- }
-
- bool isAt(int xp, int yp) const { return x == xp && y == yp; }
- int abs_pos() const { return abspos; }
- int getX() const { return (int) x; }
- int getY() const { return (int) y; }
-
- bool is_verified() const { return verified; }
-
- bool enabled; // If false, this Stash will neither track
- // items nor dump itself. Disabled stashes are
- // also never removed from the level's map of
- // stashes.
-private:
- bool verified; // Is this correct to the best of our knowledge?
- unsigned char x, y;
- int abspos;
- std::vector<item_def> items;
-
- /*
- * If true (the default), the stash-tracker is a lot more likely to consider
- * squares that the player is not standing on as correctly-verified. This
- * will lead to cleaner dumps, but the chance of stashes not accurately
- * reflecting what's in the dungeon also increases.
- */
- static bool aggressive_verify;
- static std::vector<item_def> filters;
-
- static bool are_items_same(const item_def &, const item_def &);
- static bool is_filtered(const item_def &item);
-};
-
-class ShopInfo
-{
-public:
- ShopInfo(int xp, int yp);
-
- bool matches_search(const std::string &prefix,
- const base_pattern &search,
- stash_search_result &res)
- const;
-
- std::string description() const;
-
- // Note that we aren't bothering to use virtual functions here.
- void save(FILE*) const;
- void load(FILE*);
-
- bool show_menu(const std::string &place, bool can_travel) const;
- bool is_visited() const { return items.size() || visited; }
-
- void write(std::ostream &os, bool identify = false) const;
-
- void reset() { items.clear(); visited = true; }
- void set_name(const char *s) { name = s; }
-
- void add_item(const item_def &item, unsigned price);
-
- bool isAt(int xp, int yp) const { return x == xp && y == yp; }
-
-private:
- int x, y;
- std::string name;
-
- int shoptype;
-
- // Set true if the player has visited this shop
- bool visited;
-
- // Messy!
- struct shop_item
- {
- item_def item;
- unsigned price;
- };
- std::vector<shop_item> items;
-
- std::string shop_item_name(const shop_item &si) const;
- std::string shop_item_desc(const shop_item &si) const;
- void describe_shop_item(const shop_item &si) const;
-
- class ShopId {
- public:
- ShopId(int stype);
- ~ShopId();
- private:
- int shoptype;
- id_fix_arr id;
- };
-};
-
-struct stash_search_result
-{
- // What level is this stash or shop on.
- level_id level;
-
- coord_def pos;
-
- // Number of levels the player must cross to reach the level the stash/shop
- // is on.
- int player_distance;
-
- // Number of items in the stash that match the search.
- int matches;
-
- // Count of items stacks in the stash that matched. This will be the same as
- // matches if each matching stack's quantity is 1.
- int count;
-
- // First item in stash that matched
- std::string match;
-
- // The stash or shop in question.
- const Stash *stash;
- const ShopInfo *shop;
-
- stash_search_result() : level(), player_distance(0), matches(0),
- count(0), match(), stash(NULL), shop(NULL)
- {
- }
-
- bool operator < ( const stash_search_result &ssr ) const
- {
- return player_distance < ssr.player_distance ||
- (player_distance == ssr.player_distance &&
- matches > ssr.matches);
- }
-};
-
-extern std::ostream &operator << (std::ostream &, const Stash &);
-
-class LevelStashes
-{
-public:
- LevelStashes();
-
- Stash *find_stash(int x = -1, int y = -1);
- ShopInfo &get_shop(int x, int y);
- const ShopInfo *find_shop(int x, int y) const;
-
- void get_matching_stashes(const base_pattern &search,
- std::vector<stash_search_result> &results) const;
-
- // Update stash at (x,y) on current level, defaulting to player's current
- // location if no parameters are supplied.
- bool update_stash(int x = -1, int y = -1);
-
- // Add stash at (x,y), or player's current location if no parameters are
- // supplied
- void add_stash(int x = -1, int y = -1);
-
- // Mark square (x,y) as not stashworthy. The player's current location is
- // used if no parameters are supplied.
- void no_stash(int x = -1, int y = -1);
-
- void kill_stash(const Stash &s);
-
- void save(FILE *) const;
- void load(FILE *);
-
- void write(std::ostream &os, bool identify = false) const;
- std::string level_name() const;
- std::string short_level_name() const;
- bool in_hell() const;
- bool in_branch(int) const;
-
- int stash_count() const { return stashes.size() + shops.size(); }
- int visible_stash_count() const { return count_stashes() + shops.size(); }
-
- bool isCurrent() const;
- bool isBelowPlayer() const;
- bool operator < (const LevelStashes &lev) const;
-private:
- // which level
- unsigned char branch;
- int depth;
-
- typedef std::map<int, Stash> c_stashes;
- typedef std::vector<ShopInfo> c_shops;
-
- c_stashes stashes;
- c_shops shops;
-
- int count_stashes() const;
-};
-
-extern std::ostream &operator << (std::ostream &, const LevelStashes &);
-
-class StashTracker
-{
-public:
- static bool is_level_untrackable()
- {
- return you.level_type == LEVEL_LABYRINTH
- || you.level_type == LEVEL_ABYSS;
- }
-
- StashTracker() : levels()
- {
- }
-
- void search_stashes();
-
- LevelStashes &get_current_level();
- LevelStashes *find_current_level();
-
- ShopInfo &get_shop(int x, int y)
- {
- return get_current_level().get_shop(x, y);
- }
-
- void remove_level(const LevelStashes &ls);
-
- enum stash_update_mode
- {
- ST_PASSIVE, // Maintain existing stashes only.
- ST_AGGRESSIVE // Create stashes for each square containing
- // objects, even if those squares were not
- // previously marked as stashes.
- };
-
- void update_visible_stashes(StashTracker::stash_update_mode = ST_PASSIVE);
-
- // Update stash at (x,y) on current level, defaulting to player's current
- // location if no parameters are supplied, return true if a stash was
- // updated.
- bool update_stash(int x = -1, int y = -1);
-
- // Add stash at (x,y), or player's current location if no parameters are
- // supplied
- void add_stash(int x = -1, int y = -1, bool verbose = false);
-
- // Mark square (x,y) as not stashworthy. The player's current location is
- // used if no parameters are supplied.
- void no_stash(int x = -1, int y = -1);
-
- void save(FILE*) const;
- void load(FILE*);
-
- void write(std::ostream &os, bool identify = false) const;
-
- void dump(const char *filename, bool identify = false) const;
-private:
- std::vector<LevelStashes> levels;
-
- void get_matching_stashes(const base_pattern &search,
- std::vector<stash_search_result> &results) const;
- void display_search_results(std::vector<stash_search_result> &results);
-};
-
-extern StashTracker stashes;
-
-bool is_stash(int x, int y);
-void describe_stash(int x, int y);
-
-#endif // STASH_TRACKING
-
-std::string branch_level_name(unsigned char branch, int sub_depth);
-
-std::string branch_level_name(unsigned short packed_place);
-
-std::string userdef_annotate_item(const char *s, const item_def *item,
- bool exclusive = false);
-
-#endif
diff --git a/stone_soup/crawl-ref/source/stuff.cc b/stone_soup/crawl-ref/source/stuff.cc
deleted file mode 100644
index 1b241bb807..0000000000
--- a/stone_soup/crawl-ref/source/stuff.cc
+++ /dev/null
@@ -1,1047 +0,0 @@
-/*
- * File: stuff.cc
- * Summary: Misc stuff.
- * Written by: Linley Henzell
- *
- * Modified for Crawl Reference by $Author$ on $Date$
- *
- * Change History (most recent first):
- *
- * <4> 11/14/99 cdl added random40(), made arg to random*() signed
- * <3> 11/06/99 cdl added random22()
- * <2> 9/25/99 cdl linuxlib -> liblinux
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "direct.h"
-#include "stuff.h"
-#include "view.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-
-#include <time.h>
-
-#include <stack>
-
-#ifdef USE_MORE_SECURE_SEED
-
-// for times()
-#include <sys/times.h>
-
-// for getpid()
-#include <sys/types.h>
-#include <unistd.h>
-
-#endif
-
-
-// may need this later for something else {dlb}:
-// required for table_lookup() {dlb}
-//#include <stdarg.h>
-// required for table_lookup() {dlb}
-
-#ifdef DOS
-#include <conio.h>
-#endif
-
-#ifdef UNIX
-#include "libunix.h"
-#endif
-
-#include "externs.h"
-
-#include "macro.h"
-#include "misc.h"
-#include "monstuff.h"
-#include "mon-util.h"
-#include "mt19937ar.h"
-#include "player.h"
-#include "output.h"
-#include "skills2.h"
-#include "view.h"
-
-
-// required for stuff::coinflip() and cf_setseed()
-unsigned long cfseed;
-
-// unfortunately required for near_stairs(ugh!):
-extern unsigned char (*mapch) (unsigned char);
-
-// Crude, but functional.
-char *const make_time_string( time_t abs_time, char *const buff, int buff_size,
- bool terse )
-{
- const int days = abs_time / 86400;
- const int hours = (abs_time % 86400) / 3600;
- const int mins = (abs_time % 3600) / 60;
- const int secs = abs_time % 60;
-
- char day_buff[32];
-
- if (days > 0)
- {
- if (terse)
- snprintf(day_buff, sizeof day_buff, "%d, ", days);
- else
- snprintf( day_buff, sizeof(day_buff), "%d day%s, ",
- days, (days > 1) ? "s" : "" );
- }
-
- snprintf( buff, buff_size, "%s%02d:%02d:%02d",
- (days > 0) ? day_buff : "", hours, mins, secs );
-
- return (buff);
-}
-
-void set_redraw_status( unsigned long flags )
-{
- you.redraw_status_flags |= flags;
-}
-
-void tag_followers( void )
-{
- int count_x, count_y;
-
- for (count_x = you.x_pos - 1; count_x <= you.x_pos + 1; count_x++)
- {
- for (count_y = you.y_pos - 1; count_y <= you.y_pos + 1; count_y++)
- {
- if (count_x == you.x_pos && count_y == you.y_pos)
- continue;
-
- if (mgrd[count_x][count_y] == NON_MONSTER)
- continue;
-
- struct monsters *fmenv = &menv[mgrd[count_x][count_y]];
-
- if ((fmenv->type == MONS_PANDEMONIUM_DEMON)
- || (fmenv->type == MONS_PLANT)
- || (fmenv->type == MONS_FUNGUS)
- || (fmenv->type == MONS_OKLOB_PLANT)
- || (fmenv->type == MONS_CURSE_SKULL)
- || (fmenv->type == MONS_PLAYER_GHOST) // cdl
- || (fmenv->type == MONS_CURSE_TOE)
- || (fmenv->type == MONS_POTION_MIMIC)
- || (fmenv->type == MONS_WEAPON_MIMIC)
- || (fmenv->type == MONS_ARMOUR_MIMIC)
- || (fmenv->type == MONS_SCROLL_MIMIC)
- || (fmenv->type == MONS_GOLD_MIMIC)
- || (fmenv->type == -1))
- {
- continue;
- }
-
- if (monster_habitat(fmenv->type) != DNGN_FLOOR)
- continue;
-
- if (fmenv->speed_increment < 50)
- continue;
-
- // only friendly monsters, or those actively seeking the
- // player, will follow up/down stairs.
- if (!(mons_friendly(fmenv) ||
- (fmenv->behaviour == BEH_SEEK && fmenv->foe == MHITYOU)))
- {
- continue;
- }
-
- // monster is chasing player through stairs:
- fmenv->flags |= MF_TAKING_STAIRS;
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "%s is marked for following.",
- ptr_monam( fmenv, DESC_CAP_THE ) );
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
- }
- }
-}
-
-void untag_followers( void )
-{
- for (int m = 0; m < MAX_MONSTERS; m++)
- {
- struct monsters *mon = &menv[m];
- mon->flags &= (~MF_TAKING_STAIRS);
- }
-}
-
-unsigned char get_ch(void)
-{
- unsigned char gotched = getch();
-
- if (gotched == 0)
- gotched = getch();
-
- return gotched;
-} // end get_ch()
-
-void seed_rng(long seed)
-{
-#ifdef USE_SYSTEM_RAND
- srand(seed);
-#else
- // MT19937 -- see mt19937ar.cc for details/licence
- init_genrand(seed);
-#endif
-}
-
-void seed_rng()
-{
- unsigned long seed = time( NULL );
-#ifdef USE_MORE_SECURE_SEED
- struct tms buf;
- seed += times( &buf ) + getpid();
-#endif
-
- seed_rng(seed);
-#ifdef USE_SYSTEM_RAND
- cf_setseed();
-#endif
-}
-
-#ifdef USE_SYSTEM_RAND
-int random2(int max)
-{
-#ifdef USE_NEW_RANDOM
- //return (int) ((((float) max) * rand()) / RAND_MAX); - this is bad!
- // Uses FP, so is horribly slow on computers without coprocessors.
- // Taken from comp.lang.c FAQ. May have problems as max approaches
- // RAND_MAX, but this is rather unlikely.
- // We've used rand() rather than random() for the portability, I think.
-
- if (max < 1 || max >= RAND_MAX)
- return 0;
- else
- return (int) rand() / (RAND_MAX / max + 1);
-#else
-
- if (max < 1)
- return 0;
-
- return rand() % max;
-#endif
-}
-
-// required for stuff::coinflip()
-#define IB1 1
-#define IB2 2
-#define IB5 16
-#define IB18 131072
-#define MASK (IB1 + IB2 + IB5)
-// required for stuff::coinflip()
-
-// I got to thinking a bit more about how much people talk
-// about RNGs and RLs and also about the issue of performance
-// when it comes to Crawl's RNG ... turning to *Numerical
-// Recipies in C* (Chapter 7-4, page 298), I hit upon what
-// struck me as a fine solution.
-
-// You can read all the details about this function (pretty
-// much stolen shamelessly from NRinC) elsewhere, but having
-// tested it out myself I think it satisfies Crawl's incessant
-// need to decide things on a 50-50 flip of the coin. No call
-// to random2() required -- along with all that wonderful math
-// and type casting -- and only a single variable its pointer,
-// and some bitwise operations to randomly generate 1s and 0s!
-// No parameter passing, nothing. Too good to be true, but it
-// works as long as cfseed is not set to absolute zero when it
-// is initialized ... good for 2**n-1 random bits before the
-// pattern repeats (n = long's bitlength on your platform).
-// It also avoids problems with poor implementations of rand()
-// on some platforms in regards to low-order bits ... a big
-// problem if one is only looking for a 1 or a 0 with random2()!
-
-// Talk about a hard sell! Anyway, it returns bool, so please
-// use appropriately -- I set it to bool to prevent such
-// tomfoolery, as I think that pure RNG and quickly grabbing
-// either a value of 1 or 0 should be separated where possible
-// to lower overhead in Crawl ... at least until it assembles
-// itself into something a bit more orderly :P 16jan2000 {dlb}
-
-// NB(1): cfseed is defined atop stuff.cc
-// NB(2): IB(foo) and MASK are defined somewhere in defines.h
-// NB(3): the function assumes that cf_setseed() has been called
-// beforehand - the call is presently made in acr::initialise()
-// right after srandom() and srand() are called (note also
-// that cf_setseed() requires rand() - random2 returns int
-// but a long can't hurt there).
-bool coinflip(void)
-{
- extern unsigned long cfseed; // defined atop stuff.cc
- unsigned long *ptr_cfseed = &cfseed;
-
- if (*ptr_cfseed & IB18)
- {
- *ptr_cfseed = ((*ptr_cfseed ^ MASK) << 1) | IB1;
- return true;
- }
- else
- {
- *ptr_cfseed <<= 1;
- return false;
- }
-} // end coinflip()
-
-// cf_setseed should only be called but once in all of Crawl!!! {dlb}
-void cf_setseed(void)
-{
- extern unsigned long cfseed; // defined atop stuff.cc
- unsigned long *ptr_cfseed = &cfseed;
-
- do
- {
- // using rand() here makes these predictable -- bwr
- *ptr_cfseed = rand();
- }
- while (*ptr_cfseed == 0);
-}
-
-static std::stack<long> rng_states;
-void push_rng_state()
-{
- // XXX: Does this even work? randart.cc uses it, but I can't find anything
- // that says this will restore the RNG to its original state. Anyway, we're
- // now using MT with a deterministic push/pop.
- rng_states.push(rand());
-}
-
-void pop_rng_state()
-{
- if (!rng_states.empty())
- {
- seed_rng(rng_states.top());
- rng_states.pop();
- }
-}
-
-unsigned long random_int( void )
-{
- return rand();
-}
-
-#else // USE_SYSTEM_RAND
-
-// MT19937 -- see mt19937ar.cc for details
-unsigned long random_int( void )
-{
- return (genrand_int32());
-}
-
-int random2( int max )
-{
- if (max <= 1)
- return (0);
-
- return (static_cast<int>( genrand_int32() / (0xFFFFFFFFUL / max + 1) ));
-}
-
-bool coinflip( void )
-{
- return (static_cast<bool>( random2(2) ));
-}
-
-void push_rng_state()
-{
- push_mt_state();
-}
-
-void pop_rng_state()
-{
- pop_mt_state();
-}
-
-#endif // USE_SYSTEM_RAND
-
-// Attempts to make missile weapons nicer to the player by
-// reducing the extreme variance in damage done.
-void scale_dice( dice_def &dice, int threshold )
-{
- while (dice.size > threshold)
- {
- dice.num *= 2;
- // If it's an odd number, lose one; this is more than
- // compensated by the increase in number of dice.
- dice.size /= 2;
- }
-}
-
-int bestroll(int max, int rolls)
-{
- int best = 0;
- for (int i = 0; i < rolls; i++)
- {
- int curr = random2(max);
- if (curr > best)
- best = curr;
- }
- return (best);
-}
-
-// random2avg() returns same mean value as random2() but with a lower variance
-// never use with rolls < 2 as that would be silly - use random2() instead {dlb}
-int random2avg(int max, int rolls)
-{
- int sum = 0;
-
- sum += random2(max);
-
- for (int i = 0; i < (rolls - 1); i++)
- {
- sum += random2(max + 1);
- }
-
- return (sum / rolls);
-}
-
-int roll_dice( int num, int size )
-{
- int ret = 0;
- int i;
-
- // If num <= 0 or size <= 0, then we'll just return the default
- // value of zero. This is good behaviour in that it will be
- // appropriate for calculated values that might be passed in.
- if (num > 0 && size > 0)
- {
- ret += num; // since random2() is zero based
-
- for (i = 0; i < num; i++)
- ret += random2( size );
- }
-
- return (ret);
-}
-
-int roll_dice( const struct dice_def &dice )
-{
- return (roll_dice( dice.num, dice.size ));
-}
-
-// originally designed to randomize evasion -
-// values are slightly lowered near (max) and
-// approach an upper limit somewhere near (limit/2)
-int random2limit(int max, int limit)
-{
- int i;
- int sum = 0;
-
- if (max < 1)
- return 0;
-
- for (i = 0; i < max; i++)
- {
- if (random2(limit) >= i)
- sum++;
- }
-
- return sum;
-} // end random2limit()
-
-// answers the question: "Is a grid within character's line of sight?"
-bool see_grid(unsigned char grx, unsigned char gry)
-{
- if (grx > you.x_pos - 9 && grx < you.x_pos + 9
- && gry > you.y_pos - 9 && gry < you.y_pos + 9)
- {
- if (env.show[grx - you.x_pos + 9][gry - you.y_pos + 9] != 0)
- return true;
-
- // rare case: can player see self? (of course!)
- if (grx == you.x_pos && gry == you.y_pos)
- return true;
- }
-
- return false;
-} // end see_grid()
-
-void end(int end_arg)
-{
-#ifdef UNIX
- unixcurses_shutdown();
-#endif
-
-#ifdef MAC
- deinit_mac();
-#endif
-
-#ifdef WIN32CONSOLE
- deinit_libw32c();
-#endif
-
- exit(end_arg);
-}
-
-void redraw_screen(void)
-{
-#ifdef PLAIN_TERM
-// this function is used for systems without gettext/puttext to redraw the
-// playing screen after a call to for example inventory.
- draw_border();
-
- you.redraw_hit_points = 1;
- you.redraw_magic_points = 1;
- you.redraw_strength = 1;
- you.redraw_intelligence = 1;
- you.redraw_dexterity = 1;
- you.redraw_armour_class = 1;
- you.redraw_evasion = 1;
- you.redraw_gold = 1;
- you.redraw_experience = 1;
- you.wield_change = true;
-
- set_redraw_status( REDRAW_LINE_1_MASK | REDRAW_LINE_2_MASK | REDRAW_LINE_3_MASK );
-
- print_stats();
-
- if (Options.delay_message_clear)
- mesclr( true );
-
- new_level();
-
- viewwindow(1, false);
-#endif
-} // end redraw_screen()
-
-// STEPDOWN FUNCTION to replace conditional chains in spells2.cc 12jan2000 {dlb}
-// it is a bit more extensible and optimizes the logical structure, as well
-// usage: summon_swarm() summon_undead() summon_scorpions() summon_things()
-// ex(1): stepdown_value (foo, 2, 2, 6, 8) replaces the following block:
-//
-
-/*
- if (foo > 2)
- foo = (foo - 2) / 2 + 2;
- if (foo > 4)
- foo = (foo - 4) / 2 + 4;
- if (foo > 6)
- foo = (foo - 6) / 2 + 6;
- if (foo > 8)
- foo = 8;
- */
-
-//
-// ex(2): bar = stepdown_value(bar, 2, 2, 6, -1) replaces the following block:
-//
-
-/*
- if (bar > 2)
- bar = (bar - 2) / 2 + 2;
- if (bar > 4)
- bar = (bar - 4) / 2 + 4;
- if (bar > 6)
- bar = (bar - 6) / 2 + 6;
- */
-
-// I hope this permits easier/more experimentation with value stepdowns in
-// the code it really needs to be rewritten to accept arbitrary (unevenly
-// spaced) steppings
-int stepdown_value(int base_value, int stepping, int first_step,
- int last_step, int ceiling_value)
-{
- int return_value = base_value;
-
- // values up to the first "step" returned unchanged:
- if (return_value <= first_step)
- return return_value;
-
- for (int this_step = first_step; this_step <= last_step;
- this_step += stepping)
- {
- if (return_value > this_step)
- return_value = ((return_value - this_step) / 2) + this_step;
- else
- break; // exit loop iff value fully "stepped down"
- }
-
- // "no final ceiling" == -1
- if (ceiling_value != -1 && return_value > ceiling_value)
- return ceiling_value; // highest value to return is "ceiling"
- else
- return return_value; // otherwise, value returned "as is"
-
-} // end stepdown_value()
-
-int skill_bump( int skill )
-{
- return ((you.skills[skill] < 3) ? you.skills[skill] * 2
- : you.skills[skill] + 3);
-}
-
-// Calculates num/den and randomly adds one based on the remainder.
-int div_rand_round( int num, int den )
-{
- return (num / den + (random2(den) < num % den));
-}
-
-// I got so tired of seeing: ".. && random2(foo) == 0 && .." in the code
-// that I broke down and wrote this little -- very little -- function.
-// anyway, I think improving the readability of the code offsets whatever
-// overhead the additional (intermediary) function call added to Crawl -
-// we'll just make it up by tightening code elsewhere, right guys?
-// [use with == and != only .. never directly with comparisons or math]
-// -- 14jan2000 {dlb}
-bool one_chance_in(int a_million)
-{
- return (random2(a_million) == 0);
-} // end one_chance_in() - that's it? :P {dlb}
-
-
-// simple little function to quickly modify all three stats
-// at once - does check for '0' modifiers to prevent needless
-// adding .. could use checking for sums less than zero, I guess.
-// used in conjunction with newgame::species_stat_init() and
-// newgame::job_stat_init() routines 24jan2000 {dlb}
-void modify_all_stats(int STmod, int IQmod, int DXmod)
-{
- if (STmod)
- {
- you.strength += STmod;
- you.max_strength += STmod;
- you.redraw_strength = 1;
- }
-
- if (IQmod)
- {
- you.intel += IQmod;
- you.max_intel += IQmod;
- you.redraw_intelligence = 1;
- }
-
- if (DXmod)
- {
- you.dex += DXmod;
- you.max_dex += DXmod;
- you.redraw_dexterity = 1;
- }
-
- return;
-} // end modify_stat()
-
-void canned_msg(unsigned char which_message)
-{
- switch (which_message)
- {
- case MSG_SOMETHING_APPEARS:
- strcpy(info, "Something appears ");
- strcat(info, (you.species == SP_NAGA || you.species == SP_CENTAUR)
- ? "before you" : "at your feet");
- strcat(info, "!");
- mpr(info);
- break;
-
- case MSG_NOTHING_HAPPENS:
- mpr("Nothing appears to happen.");
- break;
- case MSG_YOU_RESIST:
- mpr("You resist.");
- break;
- case MSG_TOO_BERSERK:
- mpr("You are too berserk!");
- break;
- case MSG_NOTHING_CARRIED:
- mpr("You aren't carrying anything.");
- break;
- case MSG_CANNOT_DO_YET:
- mpr("You can't do that yet.");
- break;
- case MSG_OK:
- mpr("Okay, then.");
- break;
- case MSG_UNTHINKING_ACT:
- mpr("Why would you want to do that?");
- break;
- case MSG_SPELL_FIZZLES:
- mpr("The spell fizzles.");
- break;
- case MSG_HUH:
- mpr("Huh?");
- break;
- case MSG_EMPTY_HANDED:
- mpr("You are now empty-handed.");
- break;
- }
-
- return;
-} // end canned_msg()
-
-// jmf: general helper (should be used all over in code)
-// -- idea borrowed from Nethack
-bool yesno( const char *str, bool safe, int safeanswer, bool clear_after )
-{
- unsigned char tmp;
-
- interrupt_activity( AI_FORCE_INTERRUPT );
- for (;;)
- {
- mpr(str, MSGCH_PROMPT);
-
- tmp = (unsigned char) getch();
-
- if ((tmp == ' ' || tmp == 27 || tmp == '\r' || tmp == '\n')
- && safeanswer)
- tmp = safeanswer;
-
- if (Options.easy_confirm == CONFIRM_ALL_EASY
- || tmp == safeanswer
- || (Options.easy_confirm == CONFIRM_SAFE_EASY && safe))
- {
- tmp = toupper( tmp );
- }
-
- if (clear_after)
- mesclr();
-
- if (tmp == 'N')
- return false;
- else if (tmp == 'Y')
- return true;
- else
- mpr("[Y]es or [N]o only, please.");
- }
-} // end yesno()
-
-// More accurate than distance() given the actual movement geonmetry -- bwr
-int grid_distance( int x, int y, int x2, int y2 )
-{
- const int dx = abs( x - x2 );
- const int dy = abs( y - y2 );
-
- // returns distance in terms of moves:
- return ((dx > dy) ? dx : dy);
-}
-
-int distance( int x, int y, int x2, int y2 )
-{
- //jmf: now accurate, but remember to only compare vs. pre-squared distances.
- // thus, next to == (distance(m1.x,m1.y, m2.x,m2.y) <= 2)
- const int dx = x - x2;
- const int dy = y - y2;
-
- return ((dx * dx) + (dy * dy));
-} // end distance()
-
-bool adjacent( int x, int y, int x2, int y2 )
-{
- return (abs(x - x2) <= 1 && abs(y - y2) <= 1);
-}
-
-bool silenced(char x, char y)
-{
- if (you.duration[DUR_SILENCE] > 0
- && distance(x, y, you.x_pos, you.y_pos) <= 36) // (6 * 6)
- {
- return true;
- }
- else
- {
- //else // FIXME: implement, and let monsters cast, too
- // for (int i = 0; i < MAX_SILENCES; i++)
- // {
- // if (distance(x, y, silencer[i].x, silencer[i].y) <= 36)
- // return true;
- // }
- return false;
- }
-} // end silenced()
-
-bool player_can_hear(char x, char y)
-{
- return (!silenced(x, y) && !silenced(you.x_pos, you.y_pos));
-} // end player_can_hear()
-
-unsigned char random_colour(void)
-{
- return (1 + random2(15));
-} // end random_colour()
-
-// returns if a colour is one of the special element colours (ie not regular)
-bool is_element_colour( int col )
-{
- // striping any COLFLAGS (just in case)
- return ((col & 0x007f) >= EC_FIRE);
-}
-
-int element_colour( int element, bool no_random )
-{
- // Doing this so that we don't have to do recursion here at all
- // (these were the only cases which had possible double evaluation):
- if (element == EC_FLOOR)
- element = env.floor_colour;
- else if (element == EC_ROCK)
- element = env.rock_colour;
-
- // pass regular colours through for safety.
- if (!is_element_colour( element ))
- return (element);
-
- int ret = BLACK;
-
- // Setting no_random to true will get the first colour in the cases
- // below. This is potentially useful for calls to this function
- // which might want a consistant result.
- int tmp_rand = (no_random ? 0 : random2(120));
-
- switch (element & 0x007f) // strip COLFLAGs just in case
- {
- case EC_FIRE:
- ret = (tmp_rand < 40) ? RED :
- (tmp_rand < 80) ? YELLOW
- : LIGHTRED;
- break;
-
- case EC_ICE:
- ret = (tmp_rand < 40) ? LIGHTBLUE :
- (tmp_rand < 80) ? BLUE
- : WHITE;
- break;
-
- case EC_EARTH:
- ret = (tmp_rand < 60) ? BROWN : LIGHTRED;
- break;
-
- case EC_AIR:
- ret = (tmp_rand < 60) ? LIGHTGREY : WHITE;
- break;
-
- case EC_ELECTRICITY:
- ret = (tmp_rand < 40) ? LIGHTCYAN :
- (tmp_rand < 80) ? LIGHTBLUE
- : CYAN;
- break;
-
- case EC_POISON:
- ret = (tmp_rand < 60) ? LIGHTGREEN : GREEN;
- break;
-
- case EC_WATER:
- ret = (tmp_rand < 60) ? BLUE : CYAN;
- break;
-
- case EC_MAGIC:
- ret = (tmp_rand < 30) ? LIGHTMAGENTA :
- (tmp_rand < 60) ? LIGHTBLUE :
- (tmp_rand < 90) ? MAGENTA
- : BLUE;
- break;
-
- case EC_MUTAGENIC:
- case EC_WARP:
- ret = (tmp_rand < 60) ? LIGHTMAGENTA : MAGENTA;
- break;
-
- case EC_ENCHANT:
- ret = (tmp_rand < 60) ? LIGHTBLUE : BLUE;
- break;
-
- case EC_HEAL:
- ret = (tmp_rand < 60) ? LIGHTBLUE : YELLOW;
- break;
-
- case EC_BLOOD:
- ret = (tmp_rand < 60) ? RED : DARKGREY;
- break;
-
- case EC_DEATH: // assassin
- case EC_NECRO: // necromancer
- ret = (tmp_rand < 80) ? DARKGREY : MAGENTA;
- break;
-
- case EC_UNHOLY: // ie demonology
- ret = (tmp_rand < 80) ? DARKGREY : RED;
- break;
-
- case EC_DARK:
- ret = DARKGREY;
- break;
-
- case EC_HOLY:
- ret = (tmp_rand < 60) ? YELLOW : WHITE;
- break;
-
- case EC_VEHUMET:
- ret = (tmp_rand < 40) ? LIGHTRED :
- (tmp_rand < 80) ? LIGHTMAGENTA
- : LIGHTBLUE;
- break;
-
- case EC_CRYSTAL:
- ret = (tmp_rand < 40) ? LIGHTGREY :
- (tmp_rand < 80) ? GREEN
- : LIGHTRED;
- break;
-
- case EC_SLIME:
- ret = (tmp_rand < 40) ? GREEN :
- (tmp_rand < 80) ? BROWN
- : LIGHTGREEN;
- break;
-
- case EC_SMOKE:
- ret = (tmp_rand < 30) ? LIGHTGREY :
- (tmp_rand < 60) ? DARKGREY :
- (tmp_rand < 90) ? LIGHTBLUE
- : MAGENTA;
- break;
-
- case EC_JEWEL:
- ret = (tmp_rand < 12) ? WHITE :
- (tmp_rand < 24) ? YELLOW :
- (tmp_rand < 36) ? LIGHTMAGENTA :
- (tmp_rand < 48) ? LIGHTRED :
- (tmp_rand < 60) ? LIGHTGREEN :
- (tmp_rand < 72) ? LIGHTBLUE :
- (tmp_rand < 84) ? MAGENTA :
- (tmp_rand < 96) ? RED :
- (tmp_rand < 108) ? GREEN
- : BLUE;
- break;
-
- case EC_ELVEN:
- ret = (tmp_rand < 40) ? LIGHTGREEN :
- (tmp_rand < 80) ? GREEN :
- (tmp_rand < 100) ? LIGHTBLUE
- : BLUE;
- break;
-
- case EC_DWARVEN:
- ret = (tmp_rand < 40) ? BROWN :
- (tmp_rand < 80) ? LIGHTRED :
- (tmp_rand < 100) ? LIGHTGREY
- : CYAN;
- break;
-
- case EC_ORCISH:
- ret = (tmp_rand < 40) ? DARKGREY :
- (tmp_rand < 80) ? RED :
- (tmp_rand < 100) ? BROWN
- : MAGENTA;
- break;
-
- case EC_GILA:
- ret = (tmp_rand < 30) ? LIGHTMAGENTA :
- (tmp_rand < 60) ? MAGENTA :
- (tmp_rand < 90) ? YELLOW :
- (tmp_rand < 105) ? LIGHTRED
- : RED;
- break;
-
- case EC_STONE:
- if (player_in_branch( BRANCH_HALL_OF_ZOT ))
- ret = env.rock_colour;
- else
- ret = LIGHTGREY;
- break;
-
- case EC_RANDOM:
- ret = 1 + random2(15); // always random
- break;
-
- case EC_FLOOR: // should alredy be handled
- case EC_ROCK: // should alredy be handled
- default:
- break;
- }
-
- ASSERT( !is_element_colour( ret ) );
-
- return ((ret == BLACK) ? GREEN : ret);
-}
-
-char index_to_letter(int the_index)
-{
- return (the_index + ((the_index < 26) ? 'a' : ('A' - 26)));
-} // end index_to_letter()
-
-int letter_to_index(int the_letter)
-{
- if (the_letter >= 'a' && the_letter <= 'z')
- // returns range [0-25] {dlb}
- the_letter -= 'a';
- else if (the_letter >= 'A' && the_letter <= 'Z')
- // returns range [26-51] {dlb}
- the_letter -= ('A' - 26);
-
- return the_letter;
-} // end letter_to_index()
-
-// returns 0 if the point is not near stairs
-// returns 1 if the point is near unoccupied stairs
-// returns 2 if the point is near player-occupied stairs
-
-int near_stairs(int px, int py, int max_dist, unsigned char &stair_gfx)
-{
- int i,j;
-
- for(i=-max_dist; i<=max_dist; i++)
- {
- for(j=-max_dist; j<=max_dist; j++)
- {
- int x = px + i;
- int y = py + j;
-
- if (x<0 || x>=GXM || y<0 || y>=GYM)
- continue;
-
- // very simple check
- if (grd[x][y] >= DNGN_STONE_STAIRS_DOWN_I
- && grd[x][y] <= DNGN_RETURN_FROM_SWAMP
- && grd[x][y] != DNGN_ENTER_SHOP) // silly
- {
- stair_gfx = mapch(grd[x][y]);
- return ((x == you.x_pos && y == you.y_pos) ? 2 : 1);
- }
- }
- }
-
- return false;
-}
-
-bool is_trap_square(int x, int y)
-{
- return (grd[x][y] >= DNGN_TRAP_MECHANICAL
- && grd[x][y] <= DNGN_UNDISCOVERED_TRAP);
-}
-
-// Does the equivalent of KILL_RESET on all monsters in LOS. Should only be
-// applied to new games.
-void zap_los_monsters()
-{
- losight(env.show, grd, you.x_pos, you.y_pos);
-
- for (int y = LOS_SY; y <= LOS_EY; ++y)
- {
- for (int x = LOS_SX; x <= LOS_EX; ++x)
- {
- if (!in_vlos(x, y))
- continue;
-
- const int gx = view2gridX(x),
- gy = view2gridY(y);
-
- if (!in_map_grid(gx, gy))
- continue;
-
- if (gx == you.x_pos && gy == you.y_pos)
- continue;
-
- int imon = mgrd[gx][gy];
- if (imon == NON_MONSTER || imon == MHITYOU)
- continue;
-
- // If we ever allow starting with a friendly monster,
- // we'll have to check here.
- monsters *mon = &menv[imon];
-#ifdef DEBUG_DIAGNOSTICS
- char mname[ITEMNAME_SIZE];
- moname(mon->type, true, DESC_PLAIN, mname);
- mprf(MSGCH_DIAGNOSTICS, "Dismissing %s", mname);
-#endif
- monster_die(mon, KILL_DISMISSED, 0);
- }
- }
-}
diff --git a/stone_soup/crawl-ref/source/stuff.h b/stone_soup/crawl-ref/source/stuff.h
deleted file mode 100644
index 4c9bf4474e..0000000000
--- a/stone_soup/crawl-ref/source/stuff.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * File: stuff.cc
- * Summary: Misc stuff.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <3> 11/14/99 cdl added random40
- * <2> 11/06/99 cdl added random22
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef STUFF_H
-#define STUFF_H
-
-#include "externs.h"
-
-char *const make_time_string(time_t abs_time, char *const buff, int buff_size, bool terse = false);
-void set_redraw_status( unsigned long flags );
-void tag_followers( void );
-void untag_followers( void );
-
-void seed_rng(void);
-void seed_rng(long seed);
-void push_rng_state();
-void pop_rng_state();
-
-void cf_setseed(void);
-bool coinflip(void);
-int div_rand_round( int num, int den );
-bool one_chance_in(int a_million);
-int random2(int randmax);
-unsigned long random_int(void);
-int random2avg( int max, int rolls );
-int bestroll(int max, int rolls);
-
-int roll_dice( int num, int size );
-int roll_dice( const struct dice_def &dice );
-void scale_dice( dice_def &dice, int threshold = 24 );
-
-
-int random2limit(int max, int limit);
-bool see_grid(unsigned char grx, unsigned char gry);
-int stepdown_value(int base_value, int stepping, int first_step, int last_step, int ceiling_value);
-int skill_bump( int skill );
-unsigned char get_ch(void);
-
-void end(int end_arg);
-
-void modify_all_stats(int STmod, int IQmod, int DXmod);
-
-void redraw_screen(void);
-
-void canned_msg(unsigned char which_message);
-
-bool yesno( const char * str, bool safe = true, int safeanswer = 0,
- bool clear_after = true );
-
-int grid_distance( int x, int y, int x2, int y2 );
-int distance( int x, int y, int x2, int y2);
-bool adjacent( int x, int y, int x2, int y2 );
-
-bool silenced(char x, char y);
-
-bool player_can_hear(char x, char y);
-
-unsigned char random_colour(void);
-bool is_element_colour( int col );
-int element_colour( int element, bool no_random = false );
-
-char index_to_letter (int the_index);
-
-int letter_to_index(int the_letter);
-
-int near_stairs(int px, int py, int max_dist, unsigned char &stair_gfx);
-
-inline bool testbits(unsigned int flags, unsigned int test)
-{
- return ((flags & test) == test);
-}
-
-bool is_trap_square(int x, int y);
-
-void zap_los_monsters();
-
-#endif
-
diff --git a/stone_soup/crawl-ref/source/tags.cc b/stone_soup/crawl-ref/source/tags.cc
deleted file mode 100644
index 25e4382274..0000000000
--- a/stone_soup/crawl-ref/source/tags.cc
+++ /dev/null
@@ -1,1894 +0,0 @@
-/*
- * File: tags.cc
- * Summary: Auxilary functions to make savefile versioning simpler.
- * Written by: Gordon Lipford
- *
- * Modified for Crawl Reference by $Author$ on $Date$
- *
- * Change History (most recent first):
- *
- * <2> 16 Mar 2001 GDL Added TAG_LEVEL_ATTITUDE
- * <1> 27 Jan 2001 GDL Created
- */
-
-/* ------------------------- how tags work ----------------------------------
-
-1. Tag types are enumerated in enum.h, from TAG_VERSION (more a placeholder
- than anything else, it is not actually saved as a tag) to TAG_XXX. NUM_TAGS
- is equal to the actual number of defined tags.
-
-2. Tags are created with tag_construct(), which forwards the construction
- request appropriately. tag_write() is then used to write the tag to an
- output stream.
-
-3. Tags are parsed with tag_read(), which tries to read a tag header and then
- forwards the request appropriately, returning the ID of the tag it found,
- or zero if no tag was found.
-
-4. In order to know which tags are used by a particular file type, a client
- calls tag_set_expected( fileType ), which sets up an array of chars.
- Within the array, a value of 1 means the tag is expected; -1 means that
- the tag is not expected. A client can then set values in this array to
- anything other than 1 to indicate a successful tag_read() of that tag.
-
-5. A case should be provided in tag_missing() for any tag which might be
- missing from a tagged save file. For example, if a developer adds
- TAG_YOU_NEW_STUFF to the player save file, he would have to provide a
- case in tag_missing() for this tag since it might not be there in
- earlier savefiles. The tags defined with the original tag system (and
- so not needing cases in tag_missing()) are as follows:
-
- TAG_YOU = 1, // 'you' structure
- TAG_YOU_ITEMS, // your items
- TAG_YOU_DUNGEON, // dungeon specs (stairs, branches, features)
- TAG_LEVEL, // various grids & clouds
- TAG_LEVEL_ITEMS, // items/traps
- TAG_LEVEL_MONSTERS, // monsters
- TAG_GHOST, // ghost
-
-6. The marshalling and unmarshalling of data is done in network order and
- is meant to keep savefiles cross-platform. They are non-ascii - always
- FTP in binary mode. Note also that the marshalling sizes are 1,2, and 4
- for byte, short, and long - assuming that 'int' would have been
- insufficient on 16 bit systems (and that Crawl otherwise lacks
- system-indepedent data types).
-
-*/
-
-#include <stdio.h>
-#include <string.h> // for memcpy
-
-#ifdef UNIX
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#endif
-
-#ifdef USE_EMX
-#include <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
-#endif
-
-#ifdef OS9
-#include <stat.h>
-#else
-#include <sys/stat.h>
-#endif
-
-#include "AppHdr.h"
-
-#include "abl-show.h"
-#include "enum.h"
-#include "externs.h"
-#include "files.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "monstuff.h"
-#include "mon-util.h"
-#include "randart.h"
-#include "skills.h"
-#include "skills2.h"
-#include "stuff.h"
-#include "tags.h"
-
-// THE BIG IMPORTANT TAG CONSTRUCTION/PARSE BUFFER
-static char *tagBuffer = NULL;
-
-// These three are defined in overmap.cc
-extern FixedArray < unsigned char, MAX_LEVELS, MAX_BRANCHES > altars_present;
-extern FixedVector < char, MAX_BRANCHES > stair_level;
-extern FixedArray < unsigned char, MAX_LEVELS, MAX_BRANCHES > feature;
-
-extern unsigned char your_sign; /* these two are defined in view.cc */
-extern unsigned char your_colour;
-
-// temp file pairs used for file level cleanup
-FixedArray < bool, MAX_LEVELS, MAX_BRANCHES > tmp_file_pairs;
-
-
-// static helpers
-static void tag_construct_you(struct tagHeader &th);
-static void tag_construct_you_items(struct tagHeader &th);
-static void tag_construct_you_dungeon(struct tagHeader &th);
-static void tag_read_you(struct tagHeader &th, char minorVersion);
-static void tag_read_you_items(struct tagHeader &th, char minorVersion);
-static void tag_read_you_dungeon(struct tagHeader &th);
-
-static void tag_construct_level(struct tagHeader &th);
-static void tag_construct_level_items(struct tagHeader &th);
-static void tag_construct_level_monsters(struct tagHeader &th);
-static void tag_construct_level_attitude(struct tagHeader &th);
-static void tag_read_level(struct tagHeader &th, char minorVersion);
-static void tag_read_level_items(struct tagHeader &th, char minorVersion);
-static void tag_read_level_monsters(struct tagHeader &th, char minorVersion);
-static void tag_read_level_attitude(struct tagHeader &th);
-static void tag_missing_level_attitude();
-
-static void tag_construct_ghost(struct tagHeader &th);
-static void tag_read_ghost(struct tagHeader &th, char minorVersion);
-
-// provide a wrapper for file writing, just in case.
-int write2(FILE * file, const char *buffer, unsigned int count)
-{
- return fwrite(buffer, 1, count, file);
-}
-
-// provide a wrapper for file reading, just in case.
-int read2(FILE * file, char *buffer, unsigned int count)
-{
- return fread(buffer, 1, count, file);
-}
-
-void marshallByte(struct tagHeader &th, char data)
-{
- tagBuffer[th.offset] = data;
- th.offset += 1;
-}
-
-char unmarshallByte(struct tagHeader &th)
-{
- char data = tagBuffer[th.offset];
- th.offset += 1;
- return data;
-}
-
-// marshall 2 byte short in network order
-void marshallShort(struct tagHeader &th, short data)
-{
- char b2 = (char)(data & 0x00FF);
- char b1 = (char)((data & 0xFF00) >> 8);
-
- tagBuffer[th.offset] = b1;
- tagBuffer[th.offset + 1] = b2;
-
- th.offset += 2;
-}
-
-// unmarshall 2 byte short in network order
-short unmarshallShort(struct tagHeader &th)
-{
- short b1 = tagBuffer[th.offset];
- short b2 = tagBuffer[th.offset + 1];
-
- short data = (b1 << 8) | (b2 & 0x00FF);
-
- th.offset += 2;
- return data;
-}
-
-// marshall 4 byte int in network order
-void marshallLong(struct tagHeader &th, long data)
-{
- char b4 = (char) (data & 0x000000FF);
- char b3 = (char)((data & 0x0000FF00) >> 8);
- char b2 = (char)((data & 0x00FF0000) >> 16);
- char b1 = (char)((data & 0xFF000000) >> 24);
-
- tagBuffer[th.offset] = b1;
- tagBuffer[th.offset + 1] = b2;
- tagBuffer[th.offset + 2] = b3;
- tagBuffer[th.offset + 3] = b4;
-
- th.offset += 4;
-}
-
-// unmarshall 4 byte int in network order
-long unmarshallLong(struct tagHeader &th)
-{
- long b1 = tagBuffer[th.offset];
- long b2 = tagBuffer[th.offset + 1];
- long b3 = tagBuffer[th.offset + 2];
- long b4 = tagBuffer[th.offset + 3];
-
- long data = (b1 << 24) | ((b2 & 0x000000FF) << 16);
- data |= ((b3 & 0x000000FF) << 8) | (b4 & 0x000000FF);
-
- th.offset += 4;
- return data;
-}
-
-// single precision float -- marshall in network order.
-void marshallFloat(struct tagHeader &th, float data)
-{
- long intBits = *((long *)(&data));
- marshallLong(th, intBits);
-}
-
-// single precision float -- unmarshall in network order.
-float unmarshallFloat(struct tagHeader &th)
-{
- long intBits = unmarshallLong(th);
-
- return *((float *)(&intBits));
-}
-
-// string -- marshall length & string data
-void marshallString(struct tagHeader &th, char *data, int maxSize)
-{
- // allow for very long strings.
- short len = strlen(data);
- if (maxSize > 0 && len > maxSize)
- len = maxSize;
- marshallShort(th, len);
-
- // put in the actual string -- we'll null terminate on
- // unmarshall.
- memcpy(&tagBuffer[th.offset], data, len);
-
- th.offset += len;
-}
-
-// string -- unmarshall length & string data
-void unmarshallString(struct tagHeader &th, char *data, int maxSize)
-{
- // get length
- short len = unmarshallShort(th);
- int copylen = len;
- if (len > maxSize && maxSize > 0)
- copylen = maxSize;
-
- // read the actual string and null terminate
- memcpy(data, &tagBuffer[th.offset], copylen);
- data[copylen] = '\0';
-
- th.offset += len;
-}
-
-// boolean (to avoid system-dependant bool implementations)
-void marshallBoolean(struct tagHeader &th, bool data)
-{
- char charRep = 0; // for false
- if (data)
- charRep = 1;
-
- tagBuffer[th.offset] = charRep;
- th.offset += 1;
-}
-
-// boolean (to avoid system-dependant bool implementations)
-bool unmarshallBoolean(struct tagHeader &th)
-{
- bool data;
-
- if (tagBuffer[th.offset] == 1)
- data = true;
- else
- data = false;
-
- th.offset += 1;
- return data;
-}
-
-// Saving the date as a string so we're not reliant on a particular epoch.
-void make_date_string( time_t in_date, char buff[20] )
-{
- if (in_date <= 0)
- {
- buff[0] = '\0';
- return;
- }
-
-
- struct tm *date = localtime( &in_date );
-
- snprintf( buff, 20,
- "%4d%02d%02d%02d%02d%02d%s",
- date->tm_year + 1900, date->tm_mon, date->tm_mday,
- date->tm_hour, date->tm_min, date->tm_sec,
- ((date->tm_isdst > 0) ? "D" : "S") );
-}
-
-static int get_val_from_string( const char *ptr, int len )
-{
- int ret = 0;
- int pow = 1;
-
- for (const char *chr = ptr + len - 1; chr >= ptr; chr--)
- {
- ret += (*chr - '0') * pow;
- pow *= 10;
- }
-
- return (ret);
-}
-
-time_t parse_date_string( char buff[20] )
-{
- struct tm date;
-
- date.tm_year = get_val_from_string( &buff[0], 4 ) - 1900;
- date.tm_mon = get_val_from_string( &buff[4], 2 );
- date.tm_mday = get_val_from_string( &buff[6], 2 );
- date.tm_hour = get_val_from_string( &buff[8], 2 );
- date.tm_min = get_val_from_string( &buff[10], 2 );
- date.tm_sec = get_val_from_string( &buff[12], 2 );
-
- date.tm_isdst = (buff[14] == 'D');
-
- return (mktime( &date ));
-}
-
-// PUBLIC TAG FUNCTIONS
-void tag_init(long largest_tag)
-{
- if (tagBuffer != NULL)
- return;
-
- tagBuffer = (char *)malloc(largest_tag);
-}
-
-void tag_construct(struct tagHeader &th, int tagID)
-{
- th.offset = 0;
- th.tagID = tagID;
-
- switch(tagID)
- {
- case TAG_YOU:
- tag_construct_you(th);
- break;
- case TAG_YOU_ITEMS:
- tag_construct_you_items(th);
- break;
- case TAG_YOU_DUNGEON:
- tag_construct_you_dungeon(th);
- break;
- case TAG_LEVEL:
- tag_construct_level(th);
- break;
- case TAG_LEVEL_ITEMS:
- tag_construct_level_items(th);
- break;
- case TAG_LEVEL_MONSTERS:
- tag_construct_level_monsters(th);
- break;
- case TAG_LEVEL_ATTITUDE:
- tag_construct_level_attitude(th);
- break;
- case TAG_GHOST:
- tag_construct_ghost(th);
- break;
- default:
- // I don't know how to make that!
- break;
- }
-}
-
-void tag_write(struct tagHeader &th, FILE *saveFile)
-{
- const int tagHdrSize = 6;
- int tagSize=0;
-
- char swap[tagHdrSize];
-
- // make sure there is some data to write!
- if (th.offset == 0)
- return;
-
- // special case: TAG_VERSION. Skip tag header.
- if (th.tagID != TAG_VERSION)
- {
- // swap out first few bytes
- memcpy(swap, tagBuffer, tagHdrSize);
-
- // save tag size
- tagSize = th.offset;
-
- // swap in the header
- th.offset = 0;
- marshallShort(th, th.tagID);
- marshallLong(th, tagSize);
-
- // write header
- write2(saveFile, tagBuffer, th.offset);
-
- // swap real data back in
- memcpy(tagBuffer, swap, tagHdrSize);
-
- // reset tag size
- th.offset = tagSize;
- }
-
- // write tag data
- write2(saveFile, tagBuffer, th.offset);
- return;
-}
-
-// minorVersion is available for any sub-readers that need it
-// (like TAG_LEVEL_MONSTERS)
-int tag_read(FILE *fp, char minorVersion)
-{
- const int tagHdrSize = 6;
- struct tagHeader hdr, th;
- th.offset = 0;
-
- // read tag header
- if (read2(fp, tagBuffer, tagHdrSize) != tagHdrSize)
- return 0;
-
- // unmarshall tag type and length (not including header)
- hdr.tagID = unmarshallShort(th);
- hdr.offset = unmarshallLong(th);
-
- // sanity check
- if (hdr.tagID <= 0 || hdr.offset <= 0)
- return 0;
-
- // now reset th and read actual data
- th.offset = 0;
- if (read2(fp, tagBuffer, hdr.offset) != hdr.offset)
- return 0;
-
- // ok, we have data now.
- switch(hdr.tagID)
- {
- case TAG_YOU:
- tag_read_you(th, minorVersion);
- break;
- case TAG_YOU_ITEMS:
- tag_read_you_items(th, minorVersion);
- break;
- case TAG_YOU_DUNGEON:
- tag_read_you_dungeon(th);
- break;
- case TAG_LEVEL:
- tag_read_level(th, minorVersion);
- break;
- case TAG_LEVEL_ITEMS:
- tag_read_level_items(th, minorVersion);
- break;
- case TAG_LEVEL_MONSTERS:
- tag_read_level_monsters(th, minorVersion);
- break;
- case TAG_LEVEL_ATTITUDE:
- tag_read_level_attitude(th);
- break;
- case TAG_GHOST:
- tag_read_ghost(th, minorVersion);
- break;
- default:
- // I don't know how to read that!
- return 0;
- }
-
- return hdr.tagID;
-}
-
-
-// older savefiles might want to call this to get a tag
-// properly initialized if it wasn't part of the savefile.
-// For now, none are supported.
-
-// This function will be called AFTER all other tags for
-// the savefile are read, so everything that can be
-// initialized should have been by now.
-
-// minorVersion is available for any child functions that need
-// it (currently none)
-void tag_missing(int tag, char minorVersion)
-{
- UNUSED( minorVersion );
-
- switch(tag)
- {
- case TAG_LEVEL_ATTITUDE:
- tag_missing_level_attitude();
- break;
- default:
- perror("Tag %d is missing; file is likely corrupt.");
- end(-1);
- }
-}
-
-// utility
-void tag_set_expected(char tags[], int fileType)
-{
- int i;
-
- for(i=0; i<NUM_TAGS; i++)
- {
- tags[i] = -1;
- switch(fileType)
- {
- case TAGTYPE_PLAYER:
- if (i >= TAG_YOU && i <=TAG_YOU_DUNGEON)
- tags[i] = 1;
- break;
- case TAGTYPE_LEVEL:
- if (i >= TAG_LEVEL && i <= TAG_LEVEL_ATTITUDE)
- tags[i] = 1;
- break;
- case TAGTYPE_GHOST:
- if (i == TAG_GHOST)
- tags[i] = 1;
- default:
- // I don't know what kind of file that is!
- break;
- }
- }
-}
-
-// NEVER _MODIFY_ THE CONSTRUCT/READ FUNCTIONS, EVER. THAT IS THE WHOLE POINT
-// OF USING TAGS. Apologies for the screaming.
-
-// Note anyway that the formats are somewhat flexible; you could change map
-// size, the # of slots in player inventory, etc. Constants like GXM,
-// NUM_EQUIP, and NUM_DURATIONS are saved, so the appropriate amount will
-// be restored even if a later version increases these constants.
-
-// --------------------------- player tags (foo.sav) -------------------- //
-static void tag_construct_you(struct tagHeader &th)
-{
- char buff[20]; // used for date string
- int i,j;
-
- marshallString(th, you.your_name, 30);
-
- marshallByte(th,you.religion);
- marshallByte(th,you.piety);
- marshallByte(th,you.invis);
- marshallByte(th,you.conf);
- marshallByte(th,you.paralysis);
- marshallByte(th,you.slow);
- marshallByte(th,you.fire_shield);
- marshallByte(th,you.rotting);
- marshallByte(th,you.exhausted);
- marshallByte(th,you.deaths_door);
- marshallByte(th,your_sign);
- marshallByte(th,your_colour);
- marshallByte(th,you.pet_target);
-
- marshallByte(th,you.max_level);
- marshallByte(th,you.where_are_you);
- marshallByte(th,you.char_direction);
- marshallByte(th,you.your_level);
- marshallByte(th,you.is_undead);
- marshallByte(th,you.special_wield);
- marshallByte(th,you.berserker);
- marshallByte(th,you.berserk_penalty);
- marshallByte(th,you.level_type);
- marshallByte(th,you.synch_time);
- marshallByte(th,you.disease);
- marshallByte(th,you.species);
-
- marshallShort(th, you.hp);
-
- if (you.haste > 215)
- you.haste = 215;
-
- marshallByte(th,you.haste);
-
- if (you.might > 215)
- you.might = 215;
-
- marshallByte(th,you.might);
-
- if (you.levitation > 215)
- you.levitation = 215;
-
- marshallByte(th,you.levitation);
-
- if (you.poison > 215)
- you.poison = 215;
-
- marshallByte(th,you.poison);
-
- marshallShort(th, you.hunger);
-
- // how many you.equip?
- marshallByte(th, NUM_EQUIP);
- for (i = 0; i < NUM_EQUIP; ++i)
- marshallByte(th,you.equip[i]);
-
- marshallByte(th,you.magic_points);
- marshallByte(th,you.max_magic_points);
- marshallByte(th,you.strength);
- marshallByte(th,you.intel);
- marshallByte(th,you.dex);
- marshallByte(th,you.confusing_touch);
- marshallByte(th,you.sure_blade);
- marshallByte(th,you.hit_points_regeneration);
- marshallByte(th,you.magic_points_regeneration);
-
- marshallShort(th, you.hit_points_regeneration * 100);
- marshallLong(th, you.experience);
- marshallLong(th, you.gold);
-
- marshallByte(th,you.char_class);
- marshallByte(th,you.experience_level);
- marshallLong(th, you.exp_available);
-
- /* max values */
- marshallByte(th,you.max_strength);
- marshallByte(th,you.max_intel);
- marshallByte(th,you.max_dex);
-
- marshallShort(th, you.base_hp);
- marshallShort(th, you.base_hp2);
- marshallShort(th, you.base_magic_points);
- marshallShort(th, you.base_magic_points2);
-
- marshallShort(th, you.x_pos);
- marshallShort(th, you.y_pos);
-
- marshallString(th, you.class_name, 30);
-
- marshallShort(th, you.burden);
-
- // how many spells?
- marshallByte(th, 25);
- for (i = 0; i < 25; ++i)
- marshallByte(th, you.spells[i]);
-
- marshallByte(th, 52);
- for (i = 0; i < 52; i++)
- marshallByte( th, you.spell_letter_table[i] );
-
- marshallByte(th, 52);
- for (i = 0; i < 52; i++)
- marshallShort( th, you.ability_letter_table[i] );
-
- // how many skills?
- marshallByte(th, 50);
- for (j = 0; j < 50; ++j)
- {
- marshallByte(th,you.skills[j]); /* skills! */
- marshallByte(th,you.practise_skill[j]); /* skills! */
- marshallLong(th,you.skill_points[j]);
- marshallByte(th,you.skill_order[j]); /* skills ordering */
- }
-
- // how many durations?
- marshallByte(th, NUM_DURATIONS);
- for (j = 0; j < NUM_DURATIONS; ++j)
- marshallByte(th,you.duration[j]);
-
- // how many attributes?
- marshallByte(th, 30);
- for (j = 0; j < 30; ++j)
- marshallByte(th,you.attribute[j]);
-
- // how many mutations/demon powers?
- marshallShort(th, 100);
- for (j = 0; j < 100; ++j)
- {
- marshallByte(th,you.mutation[j]);
- marshallByte(th,you.demon_pow[j]);
- }
-
- // how many penances?
- marshallByte(th, MAX_NUM_GODS);
- for (i = 0; i < MAX_NUM_GODS; i++)
- marshallByte(th, you.penance[i]);
-
- // which gods have been worshipped by this character?
- marshallByte(th, MAX_NUM_GODS);
- for (i = 0; i < MAX_NUM_GODS; i++)
- marshallByte(th, you.worshipped[i]);
-
- // what is the extent of divine generosity?
- for (i = 0; i < MAX_NUM_GODS; i++)
- marshallShort(th, you.num_gifts[i]);
-
- marshallByte(th, you.gift_timeout);
- marshallByte(th, you.normal_vision);
- marshallByte(th, you.current_vision);
- marshallByte(th, you.hell_exit);
-
- // elapsed time
- marshallFloat(th, (float)you.elapsed_time);
-
- // wizard mode used
- marshallByte(th, you.wizard);
-
- // time of game start
- make_date_string( you.birth_time, buff );
- marshallString(th, buff, 20);
-
- // real_time == -1 means game was started before this feature
- if (you.real_time != -1)
- {
- const time_t now = time(NULL);
- you.real_time += (now - you.start_time);
-
- // Reset start_time now that real_time is being saved out...
- // this may just be a level save.
- you.start_time = now;
- }
-
- marshallLong( th, you.real_time );
- marshallLong( th, you.num_turns );
-
- // you.magic_contamination 05/03/05
- marshallShort(th, you.magic_contamination);
-}
-
-static void tag_construct_you_items(struct tagHeader &th)
-{
- int i,j;
-
- // how many inventory slots?
- marshallByte(th, ENDOFPACK);
- for (i = 0; i < ENDOFPACK; ++i)
- {
- marshallByte(th,you.inv[i].base_type);
- marshallByte(th,you.inv[i].sub_type);
- marshallShort(th,you.inv[i].plus);
- marshallLong(th,you.inv[i].special);
- marshallByte(th,you.inv[i].colour);
- marshallLong(th,you.inv[i].flags);
- marshallShort(th,you.inv[i].quantity);
- marshallShort(th,you.inv[i].plus2);
- marshallShort(th, you.inv[i].orig_place);
- marshallShort(th, you.inv[i].orig_monnum);
- }
-
- // item descrip for each type & subtype
- // how many types?
- marshallByte(th, 5);
- // how many subtypes?
- marshallByte(th, 50);
- for (i = 0; i < 5; ++i)
- {
- for (j = 0; j < 50; ++j)
- marshallByte(th, you.item_description[i][j]);
- }
-
- // identification status
- // how many types?
- marshallByte(th, 4);
- // how many subtypes?
- marshallByte(th, 50);
-
- // this is really dumb. We copy the id[] array from itemname
- // to the stack, for no good reason that I can see.
- char identy[4][50];
-
- save_id(identy);
-
- for (i = 0; i < 4; ++i)
- {
- for (j = 0; j < 50; ++j)
- marshallByte(th, identy[i][j]);
- }
-
- // how many unique items?
- marshallByte(th, 50);
- for (j = 0; j < 50; ++j)
- {
- marshallByte(th,you.unique_items[j]); /* unique items */
- marshallByte(th,you.had_book[j]);
- }
-
- // how many unrandarts?
- marshallShort(th, NO_UNRANDARTS);
-
- for (j = 0; j < NO_UNRANDARTS; ++j)
- marshallBoolean(th, does_unrandart_exist(j));
-}
-
-static void tag_construct_you_dungeon(struct tagHeader &th)
-{
- int i,j;
-
- // how many unique creatures?
- marshallByte(th, 50);
- for (j = 0; j < 50; ++j)
- marshallByte(th,you.unique_creatures[j]); /* unique beasties */
-
- // how many branches?
- marshallByte(th, MAX_BRANCHES);
- for (j = 0; j < 30; ++j)
- {
- marshallByte(th,you.branch_stairs[j]);
- marshallByte(th,stair_level[j]);
- }
-
- // how many levels?
- marshallShort(th, MAX_LEVELS);
- for (i = 0; i < MAX_LEVELS; ++i)
- {
- for (j = 0; j < MAX_BRANCHES; ++j)
- {
- marshallByte(th,altars_present[i][j]);
- marshallByte(th,feature[i][j]);
- marshallBoolean(th,tmp_file_pairs[i][j]);
- }
- }
-}
-
-static void tag_read_you(struct tagHeader &th, char minorVersion)
-{
- char buff[20]; // For birth date
- int i,j;
- char count_c;
- short count_s;
-
- unmarshallString(th, you.your_name, 30);
-
- you.religion = unmarshallByte(th);
- you.piety = unmarshallByte(th);
- you.invis = unmarshallByte(th);
- you.conf = unmarshallByte(th);
- you.paralysis = unmarshallByte(th);
- you.slow = unmarshallByte(th);
- you.fire_shield = unmarshallByte(th);
- you.rotting = unmarshallByte(th);
- you.exhausted = unmarshallByte(th);
- you.deaths_door = unmarshallByte(th);
- your_sign = unmarshallByte(th);
- your_colour = unmarshallByte(th);
- you.pet_target = unmarshallByte(th);
-
- you.max_level = unmarshallByte(th);
- you.where_are_you = unmarshallByte(th);
- you.char_direction = unmarshallByte(th);
- you.your_level = unmarshallByte(th);
- you.is_undead = unmarshallByte(th);
- you.special_wield = unmarshallByte(th);
- you.berserker = unmarshallByte(th);
- you.berserk_penalty = unmarshallByte(th);
- you.level_type = unmarshallByte(th);
- you.synch_time = unmarshallByte(th);
- you.disease = unmarshallByte(th);
- you.species = unmarshallByte(th);
- you.hp = unmarshallShort(th);
- you.haste = unmarshallByte(th);
- you.might = unmarshallByte(th);
- you.levitation = unmarshallByte(th);
- you.poison = unmarshallByte(th);
- you.hunger = unmarshallShort(th);
-
- // how many you.equip?
- count_c = unmarshallByte(th);
- for (i = 0; i < count_c; ++i)
- you.equip[i] = unmarshallByte(th);
-
- you.magic_points = unmarshallByte(th);
- you.max_magic_points = unmarshallByte(th);
- you.strength = unmarshallByte(th);
- you.intel = unmarshallByte(th);
- you.dex = unmarshallByte(th);
- you.confusing_touch = unmarshallByte(th);
- you.sure_blade = unmarshallByte(th);
- you.hit_points_regeneration = unmarshallByte(th);
- you.magic_points_regeneration = unmarshallByte(th);
-
- you.hit_points_regeneration = unmarshallShort(th) / 100;
- you.experience = unmarshallLong(th);
- you.gold = unmarshallLong(th);
-
- you.char_class = unmarshallByte(th);
- you.experience_level = unmarshallByte(th);
- you.exp_available = unmarshallLong(th);
-
- /* max values */
- you.max_strength = unmarshallByte(th);
- you.max_intel = unmarshallByte(th);
- you.max_dex = unmarshallByte(th);
-
- you.base_hp = unmarshallShort(th);
- you.base_hp2 = unmarshallShort(th);
- you.base_magic_points = unmarshallShort(th);
- you.base_magic_points2 = unmarshallShort(th);
-
- you.x_pos = unmarshallShort(th);
- you.y_pos = unmarshallShort(th);
-
- unmarshallString(th, you.class_name, 30);
-
- you.burden = unmarshallShort(th);
-
- // how many spells?
- you.spell_no = 0;
- count_c = unmarshallByte(th);
- for (i = 0; i < count_c; ++i)
- {
- you.spells[i] = unmarshallByte(th);
- if (you.spells[i] != SPELL_NO_SPELL)
- you.spell_no++;
- }
-
- if (minorVersion >= 2)
- {
- count_c = unmarshallByte(th);
- for (i = 0; i < count_c; i++)
- you.spell_letter_table[i] = unmarshallByte(th);
-
- count_c = unmarshallByte(th);
- for (i = 0; i < count_c; i++)
- you.ability_letter_table[i] = unmarshallShort(th);
- }
- else
- {
- for (i = 0; i < 52; i++)
- {
- you.spell_letter_table[i] = -1;
- you.ability_letter_table[i] = ABIL_NON_ABILITY;
- }
-
- for (i = 0; i < 25; i++)
- {
- if (you.spells[i] != SPELL_NO_SPELL)
- you.spell_letter_table[i] = i;
- }
-
- if (you.religion != GOD_NO_GOD)
- set_god_ability_slots();
- }
-
- // how many skills?
- count_c = unmarshallByte(th);
- for (j = 0; j < count_c; ++j)
- {
- you.skills[j] = unmarshallByte(th);
- you.practise_skill[j] = unmarshallByte(th);
- you.skill_points[j] = unmarshallLong(th);
-
- if (minorVersion >= 2)
- you.skill_order[j] = unmarshallByte(th);
- }
-
- // initialize ordering when we don't read it in:
- if (minorVersion < 2)
- init_skill_order();
-
- // set up you.total_skill_points and you.skill_cost_level
- calc_total_skill_points();
-
- // how many durations?
- count_c = unmarshallByte(th);
- for (j = 0; j < count_c; ++j)
- you.duration[j] = unmarshallByte(th);
-
- // how many attributes?
- count_c = unmarshallByte(th);
- for (j = 0; j < count_c; ++j)
- you.attribute[j] = unmarshallByte(th);
-
- // how many mutations/demon powers?
- count_s = unmarshallShort(th);
- for (j = 0; j < count_s; ++j)
- {
- you.mutation[j] = unmarshallByte(th);
- you.demon_pow[j] = unmarshallByte(th);
- }
-
- // how many penances?
- count_c = unmarshallByte(th);
- for (i = 0; i < count_c; i++)
- you.penance[i] = unmarshallByte(th);
-
- if (minorVersion >= 2)
- {
- count_c = unmarshallByte(th);
- for (i = 0; i < count_c; i++)
- you.worshipped[i] = unmarshallByte(th);
-
- if (minorVersion >= 5)
- for (i = 0; i < count_c; i++)
- you.num_gifts[i] = unmarshallShort(th);
-
- }
- else
- {
- for (i = 0; i < count_c; i++)
- you.worshipped[i] = false;
-
- if (you.religion != GOD_NO_GOD)
- you.worshipped[you.religion] = true;
- }
-
- you.gift_timeout = unmarshallByte(th);
- you.normal_vision = unmarshallByte(th);
- you.current_vision = unmarshallByte(th);
- you.hell_exit = unmarshallByte(th);
-
- // elapsed time
- you.elapsed_time = (double)unmarshallFloat(th);
-
- if (minorVersion >= 1)
- {
- // wizard mode
- you.wizard = (bool) unmarshallByte(th);
-
- // time of character creation
- unmarshallString( th, buff, 20 );
- you.birth_time = parse_date_string( buff );
- }
-
- if (minorVersion >= 2)
- {
- you.real_time = unmarshallLong(th);
- you.num_turns = unmarshallLong(th);
- }
- else
- {
- you.real_time = -1;
- you.num_turns = -1;
- }
-
- // you.magic_contamination 05/03/05
- if (minorVersion >= 3)
- {
- you.magic_contamination = unmarshallShort(th);
- }
-}
-
-static void tag_convert_to_4_3_item( item_def &item )
-{
- const unsigned char plus = item.plus;
- const unsigned char plus2 = item.plus2;
- const unsigned char ident = item.flags;
- const unsigned char special = item.special;
-
- if (item.quantity <= 0)
- return;
-
- // First, convert ident into flags:
- item.flags = (ident == 3) ? ISFLAG_IDENT_MASK :
- (ident > 0) ? ISFLAG_KNOW_CURSE
- : 0;
-
- switch (item.base_type)
- {
- case OBJ_ARMOUR:
- if ((ident == 1 && special % 30 >= 25) || ident == 2)
- item.flags |= ISFLAG_KNOW_TYPE;
-
- // Convert special values
- item.special %= 30;
- if (item.special < 25)
- {
- if (item.sub_type == ARM_HELMET)
- {
- item.plus2 = plus2 % 30;
- set_helmet_desc( item, (special / 30) << 8 );
- }
- else
- {
- switch (special / 30)
- {
- case DARM_EMBROIDERED_SHINY:
- set_equip_desc( item, ISFLAG_EMBROIDERED_SHINY );
- break;
- case DARM_RUNED:
- set_equip_desc( item, ISFLAG_RUNED );
- break;
- case DARM_GLOWING:
- set_equip_desc( item, ISFLAG_GLOWING );
- break;
- case DARM_ELVEN:
- set_equip_race( item, ISFLAG_ELVEN );
- break;
- case DARM_DWARVEN:
- set_equip_race( item, ISFLAG_DWARVEN );
- break;
- case DARM_ORCISH:
- set_equip_race( item, ISFLAG_ORCISH );
- break;
- default:
- break;
- }
- }
- }
- else if (item.special == 25)
- {
- item.flags |= ISFLAG_UNRANDART;
- item.special = 0;
- }
- else
- {
- item.flags |= ISFLAG_RANDART;
-
- // calc old seed
- item.special = item.base_type * special
- + item.sub_type * (plus % 100)
- + plus2 * 100;
- }
- break;
-
- case OBJ_WEAPONS:
- if ((ident == 1 && (special < 180 && special % 30 >= 25)) || ident == 2)
- item.flags |= ISFLAG_KNOW_TYPE;
-
- // Convert special values
- if (special < 181) // don't mangle fixed artefacts
- {
- item.special %= 30;
- if (item.special < 25)
- {
- switch (special / 30)
- {
- case DWPN_RUNED:
- set_equip_desc( item, ISFLAG_RUNED );
- break;
- case DWPN_GLOWING:
- set_equip_desc( item, ISFLAG_GLOWING );
- break;
- case DWPN_ORCISH:
- set_equip_race( item, ISFLAG_ORCISH );
- break;
- case DWPN_ELVEN:
- set_equip_race( item, ISFLAG_ELVEN );
- break;
- case DWPN_DWARVEN:
- set_equip_race( item, ISFLAG_DWARVEN );
- break;
- default:
- break;
- }
- }
- else if (item.special == 25)
- {
- item.flags |= ISFLAG_UNRANDART;
- item.special = 0;
- }
- else
- {
- item.flags |= ISFLAG_RANDART;
-
- // calc old seed
- item.special = item.base_type * special
- + item.sub_type * (plus % 100)
- + plus2 * 100;
- }
- }
- break;
-
- case OBJ_MISSILES:
- // Needles were moved into the bonus eggplant spot. -- bwr
- if (item.sub_type == 6)
- item.sub_type = MI_NEEDLE;
-
- if (ident == 2)
- item.flags |= ISFLAG_KNOW_TYPE;
-
- // Convert special values
- item.special %= 30;
- switch (special / 30)
- {
- case DAMMO_ORCISH:
- set_equip_race( item, ISFLAG_ORCISH );
- break;
- case DAMMO_ELVEN:
- set_equip_race( item, ISFLAG_ELVEN );
- break;
- case DAMMO_DWARVEN:
- set_equip_race( item, ISFLAG_DWARVEN );
- break;
- default:
- break;
- }
- break;
-
- case OBJ_WANDS:
- if (ident == 2)
- item.flags |= ISFLAG_KNOW_PLUSES;
- break;
-
- case OBJ_JEWELLERY:
- if (ident == 1 && (special == 200 || special == 201))
- item.flags |= ISFLAG_KNOW_TYPE;
- else if (ident == 2)
- item.flags |= (ISFLAG_KNOW_TYPE | ISFLAG_KNOW_PLUSES);
-
- if (special == 201)
- {
- item.flags |= ISFLAG_UNRANDART;
- item.special = 0;
- }
- else if (special == 200)
- {
- item.flags |= ISFLAG_RANDART;
-
- // calc old seed
- item.special = item.base_type * special
- + item.sub_type * (plus % 100)
- + plus2 * 100;
- }
- break;
-
- default:
- if (ident > 0)
- item.flags |= ISFLAG_KNOW_TYPE;
- break;
- }
-
-
- // Second, convert plus and plus2
- if (item.base_type == OBJ_WEAPONS
- || item.base_type == OBJ_MISSILES
- || item.base_type == OBJ_ARMOUR
- || item.base_type == OBJ_JEWELLERY)
- {
- item.plus = plus;
-
- // item is cursed:
- if (plus > 100)
- {
- item.plus -= 100;
- item.flags |= ISFLAG_CURSED;
- }
-
- // Weapons use both as pluses.
- // Non-artefact jewellery uses both as pluses.
- // Artefact jewellery has literal values for both pluses.
- // Armour and Missiles only use plus for their plus value.
- // Armour has literal usage of plus2 for sub-subtypes.
- if (item.base_type != OBJ_JEWELLERY)
- {
- item.plus -= 50;
-
- if (item.base_type == OBJ_WEAPONS)
- item.plus2 -= 50;
- }
- else if (special != 200)
- {
- // regular jewellery & unrandarts -- unused pluses were 0s
- if (item.plus)
- item.plus -= 50;
-
- if (item.plus2)
- item.plus2 -= 50;
- }
- else if (special == 200)
- {
- // Randart jewellery used pluses only as seeds, right now
- // they're always zero (since random artefact rings avoid
- // base types with pluses).
- item.plus = 0;
- item.plus2 = 0;
- }
- }
-}
-
-static void tag_read_you_items(struct tagHeader &th, char minorVersion)
-{
- int i,j;
- char count_c, count_c2;
- short count_s;
-
- // how many inventory slots?
- count_c = unmarshallByte(th);
- for (i = 0; i < count_c; ++i)
- {
- you.inv[i].orig_monnum = you.inv[i].orig_place = 0;
- if (minorVersion < 1)
- {
- you.inv[i].base_type = (unsigned char) unmarshallByte(th);
- you.inv[i].sub_type = (unsigned char) unmarshallByte(th);
- you.inv[i].plus = (unsigned char) unmarshallByte(th);
- you.inv[i].special = (unsigned char) unmarshallByte(th);
- you.inv[i].colour = (unsigned char) unmarshallByte(th);
- you.inv[i].flags = (unsigned char) unmarshallByte(th);
- you.inv[i].quantity = unmarshallShort(th);
- you.inv[i].plus2 = (unsigned char) unmarshallByte(th);
-
- tag_convert_to_4_3_item( you.inv[i] );
- }
- else
- {
- you.inv[i].base_type = (unsigned char) unmarshallByte(th);
- you.inv[i].sub_type = (unsigned char) unmarshallByte(th);
- you.inv[i].plus = unmarshallShort(th);
- you.inv[i].special = unmarshallLong(th);
- you.inv[i].colour = (unsigned char) unmarshallByte(th);
- you.inv[i].flags = (unsigned long) unmarshallLong(th);
- you.inv[i].quantity = unmarshallShort(th);
- you.inv[i].plus2 = unmarshallShort(th);
-
- if (minorVersion >= 4)
- {
- you.inv[i].orig_place = unmarshallShort(th);
- you.inv[i].orig_monnum = unmarshallShort(th);
- }
- }
-
- // these never need to be saved for items in the inventory -- bwr
- you.inv[i].x = -1;
- you.inv[i].y = -1;
- you.inv[i].link = i;
- you.inv[i].slot = index_to_letter(i);
- }
-
- // item descrip for each type & subtype
- // how many types?
- count_c = unmarshallByte(th);
- // how many subtypes?
- count_c2 = unmarshallByte(th);
- for (i = 0; i < count_c; ++i)
- {
- for (j = 0; j < count_c2; ++j)
- you.item_description[i][j] = unmarshallByte(th);
- }
-
- // identification status
- // how many types?
- count_c = unmarshallByte(th);
- // how many subtypes?
- count_c2 = unmarshallByte(th);
-
- // argh.. this is awful.
- for (i = 0; i < count_c; ++i)
- {
- for (j = 0; j < count_c2; ++j)
- {
- char ch;
- ch = unmarshallByte(th);
-
- switch (i)
- {
- case IDTYPE_WANDS:
- set_ident_type(OBJ_WANDS, j, ch);
- break;
- case IDTYPE_SCROLLS:
- set_ident_type(OBJ_SCROLLS, j, ch);
- break;
- case IDTYPE_JEWELLERY:
- set_ident_type(OBJ_JEWELLERY, j, ch);
- break;
- case IDTYPE_POTIONS:
- set_ident_type(OBJ_POTIONS, j, ch);
- break;
- }
- }
- }
-
- // how many unique items?
- count_c = unmarshallByte(th);
- for (j = 0; j < count_c; ++j)
- {
- you.unique_items[j] = unmarshallByte(th);
- you.had_book[j] = unmarshallByte(th);
- }
-
- // how many unrandarts?
- count_s = unmarshallShort(th);
- for (j = 0; j < count_s; ++j)
- set_unrandart_exist(j, unmarshallBoolean(th));
-
- // # of unrandarts could certainly change. If it does,
- // the new ones won't exist yet - zero them out.
- for (; j < NO_UNRANDARTS; j++)
- set_unrandart_exist(j, 0);
-}
-
-static void tag_read_you_dungeon(struct tagHeader &th)
-{
- int i,j;
- char count_c;
- short count_s;
-
- // how many unique creatures?
- count_c = unmarshallByte(th);
- for (j = 0; j < count_c; ++j)
- you.unique_creatures[j] = unmarshallByte(th);
-
- // how many branches?
- count_c = unmarshallByte(th);
- for (j = 0; j < count_c; ++j)
- {
- you.branch_stairs[j] = unmarshallByte(th);
- stair_level[j] = unmarshallByte(th);
- }
-
- // how many levels?
- count_s = unmarshallShort(th);
- for (i = 0; i < count_s; ++i)
- {
- for (j = 0; j < count_c; ++j)
- {
- altars_present[i][j] = unmarshallByte(th);
- feature[i][j] = unmarshallByte(th);
- tmp_file_pairs[i][j] = unmarshallBoolean(th);
- }
- }
-}
-
-// ------------------------------- level tags ---------------------------- //
-
-static void tag_construct_level(struct tagHeader &th)
-{
- int i;
- int count_x, count_y;
-
- marshallFloat(th, (float)you.elapsed_time);
-
- // map grids
- // how many X?
- marshallShort(th, GXM);
- // how many Y?
- marshallShort(th, GYM);
- for (count_x = 0; count_x < GXM; count_x++)
- {
- for (count_y = 0; count_y < GYM; count_y++)
- {
- marshallByte(th, grd[count_x][count_y]);
- marshallShort(th, env.map[count_x][count_y]);
- marshallByte(th, env.cgrid[count_x][count_y]);
- }
- }
-
- marshallShort(th, env.cloud_no);
-
- // how many clouds?
- marshallShort(th, MAX_CLOUDS);
- for (i = 0; i < MAX_CLOUDS; i++)
- {
- marshallByte(th, env.cloud[i].x);
- marshallByte(th, env.cloud[i].y);
- marshallByte(th, env.cloud[i].type);
- marshallShort(th, env.cloud[i].decay);
- }
-
- // how many shops?
- marshallByte(th, 5);
- for (i = 0; i < 5; i++)
- {
- marshallByte(th, env.shop[i].keeper_name[0]);
- marshallByte(th, env.shop[i].keeper_name[1]);
- marshallByte(th, env.shop[i].keeper_name[2]);
- marshallByte(th, env.shop[i].x);
- marshallByte(th, env.shop[i].y);
- marshallByte(th, env.shop[i].greed);
- marshallByte(th, env.shop[i].type);
- marshallByte(th, env.shop[i].level);
- }
-}
-
-static void tag_construct_level_items(struct tagHeader &th)
-{
- int i;
-
- // how many traps?
- marshallShort(th, MAX_TRAPS);
- for (i = 0; i < MAX_TRAPS; ++i)
- {
- marshallByte(th, env.trap[i].type);
- marshallByte(th, env.trap[i].x);
- marshallByte(th, env.trap[i].y);
- }
-
- // how many items?
- marshallShort(th, MAX_ITEMS);
- for (i = 0; i < MAX_ITEMS; ++i)
- {
- marshallByte(th, mitm[i].base_type);
- marshallByte(th, mitm[i].sub_type);
- marshallShort(th, mitm[i].plus);
- marshallShort(th, mitm[i].plus2);
- marshallLong(th, mitm[i].special);
- marshallShort(th, mitm[i].quantity);
-
- marshallByte(th, mitm[i].colour);
- marshallShort(th, mitm[i].x);
- marshallShort(th, mitm[i].y);
- marshallLong(th, mitm[i].flags);
-
- marshallShort(th, mitm[i].link); // unused
- marshallShort(th, igrd[mitm[i].x][mitm[i].y]); // unused
-
- marshallByte(th, mitm[i].slot);
-
- marshallShort(th, mitm[i].orig_place);
- marshallShort(th, mitm[i].orig_monnum);
- }
-}
-
-static void tag_construct_level_monsters(struct tagHeader &th)
-{
- int i,j;
-
- // how many mons_alloc?
- marshallByte(th, 20);
- for (i = 0; i < 20; ++i)
- marshallShort(th, env.mons_alloc[i]);
-
- // how many monsters?
- marshallShort(th, MAX_MONSTERS);
- // how many monster enchantments?
- marshallByte(th, NUM_MON_ENCHANTS);
- // how many monster inventory slots?
- marshallByte(th, NUM_MONSTER_SLOTS);
-
- for (i = 0; i < MAX_MONSTERS; i++)
- {
- marshallByte(th, menv[i].armour_class);
- marshallByte(th, menv[i].evasion);
- marshallByte(th, menv[i].hit_dice);
- marshallByte(th, menv[i].speed);
- marshallByte(th, menv[i].speed_increment);
- marshallByte(th, menv[i].behaviour);
- marshallByte(th, menv[i].x);
- marshallByte(th, menv[i].y);
- marshallByte(th, menv[i].target_x);
- marshallByte(th, menv[i].target_y);
- marshallByte(th, menv[i].flags);
-
- for (j = 0; j < NUM_MON_ENCHANTS; j++)
- marshallByte(th, menv[i].enchantment[j]);
-
- marshallShort(th, menv[i].type);
- marshallShort(th, menv[i].hit_points);
- marshallShort(th, menv[i].max_hit_points);
- marshallShort(th, menv[i].number);
-
- for (j = 0; j < NUM_MONSTER_SLOTS; j++)
- marshallShort(th, menv[i].inv[j]);
- }
-}
-
-void tag_construct_level_attitude(struct tagHeader &th)
-{
- int i;
-
- // how many monsters?
- marshallShort(th, MAX_MONSTERS);
-
- for (i = 0; i < MAX_MONSTERS; i++)
- {
- marshallByte(th, menv[i].attitude);
- marshallShort(th, menv[i].foe);
- }
-}
-
-
-static void tag_read_level( struct tagHeader &th, char minorVersion )
-{
- int i,j;
- int gx, gy;
-
- env.elapsed_time = (double)unmarshallFloat(th);
-
- // map grids
- // how many X?
- gx = unmarshallShort(th);
- // how many Y?
- gy = unmarshallShort(th);
- for (i = 0; i < gx; i++)
- {
- for (j = 0; j < gy; j++)
- {
- grd[i][j] = unmarshallByte(th);
-
- if (minorVersion < 8)
- env.map[i][j] = (unsigned char) unmarshallByte(th);
- else
- env.map[i][j] = (unsigned short) unmarshallShort(th);
-
- if ((env.map[i][j] & 0xFF) == 201) // what is this??
- env.map[i][j] = (env.map[i][j] & 0xFF00U) | 239;
-
- mgrd[i][j] = NON_MONSTER;
- env.cgrid[i][j] = unmarshallByte(th);
-
- if (minorVersion < 3)
- {
- // increased number of clouds to 100 in 4.3
- if (env.cgrid[i][j] > 30)
- env.cgrid[i][j] = 101;
- }
- }
- }
-
- env.cloud_no = unmarshallShort(th);
-
- // how many clouds?
- gx = unmarshallShort(th);
- for (i = 0; i < gx; i++)
- {
- env.cloud[i].x = unmarshallByte(th);
- env.cloud[i].y = unmarshallByte(th);
- env.cloud[i].type = unmarshallByte(th);
- env.cloud[i].decay = unmarshallShort(th);
- }
-
- // how many shops?
- gx = unmarshallByte(th);
- for (i = 0; i < gx; i++)
- {
- env.shop[i].keeper_name[0] = unmarshallByte(th);
- env.shop[i].keeper_name[1] = unmarshallByte(th);
- env.shop[i].keeper_name[2] = unmarshallByte(th);
- env.shop[i].x = unmarshallByte(th);
- env.shop[i].y = unmarshallByte(th);
- env.shop[i].greed = unmarshallByte(th);
- env.shop[i].type = unmarshallByte(th);
- env.shop[i].level = unmarshallByte(th);
- }
-}
-
-static void tag_read_level_items(struct tagHeader &th, char minorVersion)
-{
- int i;
- int count;
-
- // how many traps?
- count = unmarshallShort(th);
- for (i = 0; i < count; ++i)
- {
- env.trap[i].type = unmarshallByte(th);
- env.trap[i].x = unmarshallByte(th);
- env.trap[i].y = unmarshallByte(th);
- }
-
- // how many items?
- count = unmarshallShort(th);
- for (i = 0; i < count; ++i)
- {
- if (minorVersion < 3)
- {
- mitm[i].base_type = (unsigned char) unmarshallByte(th);
- mitm[i].sub_type = (unsigned char) unmarshallByte(th);
- mitm[i].plus = (unsigned char) unmarshallByte(th);
- mitm[i].plus2 = (unsigned char) unmarshallByte(th);
- mitm[i].special = (unsigned char) unmarshallByte(th);
- mitm[i].quantity = unmarshallLong(th);
- mitm[i].colour = (unsigned char) unmarshallByte(th);
- mitm[i].x = (unsigned char) unmarshallByte(th);
- mitm[i].y = (unsigned char) unmarshallByte(th);
- mitm[i].flags = (unsigned char) unmarshallByte(th);
-
- tag_convert_to_4_3_item( mitm[i] );
- }
- else
- {
- mitm[i].base_type = (unsigned char) unmarshallByte(th);
- mitm[i].sub_type = (unsigned char) unmarshallByte(th);
- mitm[i].plus = unmarshallShort(th);
- mitm[i].plus2 = unmarshallShort(th);
- mitm[i].special = unmarshallLong(th);
- mitm[i].quantity = unmarshallShort(th);
- mitm[i].colour = (unsigned char) unmarshallByte(th);
- mitm[i].x = unmarshallShort(th);
- mitm[i].y = unmarshallShort(th);
- mitm[i].flags = (unsigned long) unmarshallLong(th);
- }
-
- // [dshaligram] FIXME, remove this kludge when ARM_CAP is fully
- // integrated.
- if (mitm[i].base_type == OBJ_ARMOUR && mitm[i].sub_type == ARM_CAP)
- mitm[i].sub_type = ARM_HELMET;
-
- // pre 4.2 files had monster items stacked at (2,2) -- moved to (0,0)
- if (minorVersion < 2 && mitm[i].x == 2 && mitm[i].y == 2)
- {
- mitm[i].x = 0;
- mitm[i].y = 0;
- }
-
- unmarshallShort(th); // mitm[].link -- unused
- unmarshallShort(th); // igrd[mitm[i].x][mitm[i].y] -- unused
-
- if (minorVersion >= 6)
- {
- mitm[i].slot = unmarshallByte(th);
- }
-
- if (minorVersion >= 7)
- {
- mitm[i].orig_place = unmarshallShort(th);
- mitm[i].orig_monnum = unmarshallShort(th);
- }
- else
- {
- mitm[i].orig_place = 0;
- mitm[i].orig_monnum = 0;
- }
- }
-}
-
-static void tag_read_level_monsters(struct tagHeader &th, char minorVersion)
-{
- int i,j;
- int count, ecount, icount;
-
- // how many mons_alloc?
- count = unmarshallByte(th);
- for (i = 0; i < count; ++i)
- env.mons_alloc[i] = unmarshallShort(th);
-
- // how many monsters?
- count = unmarshallShort(th);
- // how many monster enchantments?
- ecount = unmarshallByte(th);
- // how many monster inventory slots?
- icount = unmarshallByte(th);
-
- for (i = 0; i < count; i++)
- {
- menv[i].armour_class = unmarshallByte(th);
- menv[i].evasion = unmarshallByte(th);
- menv[i].hit_dice = unmarshallByte(th);
- menv[i].speed = unmarshallByte(th);
- // Avoid sign extension when loading files (Elethiomel's hang)
- menv[i].speed_increment = (unsigned char) unmarshallByte(th);
- menv[i].behaviour = unmarshallByte(th);
- menv[i].x = unmarshallByte(th);
- menv[i].y = unmarshallByte(th);
- menv[i].target_x = unmarshallByte(th);
- menv[i].target_y = unmarshallByte(th);
- menv[i].flags = unmarshallByte(th);
-
- // VERSION NOTICE: for pre 4.2 files, flags was either 0
- // or 1. Now, we can transfer ENCH_CREATED_FRIENDLY over
- // from the enchantments array to flags.
- // Also need to take care of ENCH_FRIEND_ABJ_xx flags
-
- for (j = 0; j < ecount; j++)
- menv[i].enchantment[j] = unmarshallByte(th);
-
- if (minorVersion < 2)
- {
- menv[i].flags = 0;
- for(j=0; j<NUM_MON_ENCHANTS; j++)
- {
- if (j>=ecount)
- menv[i].enchantment[j] = ENCH_NONE;
- else
- {
- if (menv[i].enchantment[j] == 71) // old ENCH_CREATED_FRIENDLY
- {
- menv[i].enchantment[j] = ENCH_NONE;
- menv[i].flags |= MF_CREATED_FRIENDLY;
- }
- if (menv[i].enchantment[j] >= 65 // old ENCH_FRIEND_ABJ_I
- && menv[i].enchantment[j] <= 70) // old ENCH_FRIEND_ABJ_VI
- {
- menv[i].enchantment[j] -= (65 - ENCH_ABJ_I);
- menv[i].flags |= MF_CREATED_FRIENDLY;
- }
- }
- }
- } // end minorversion < 2
-
- menv[i].type = unmarshallShort(th);
- menv[i].hit_points = unmarshallShort(th);
- menv[i].max_hit_points = unmarshallShort(th);
- menv[i].number = unmarshallShort(th);
-
- for (j = 0; j < icount; j++)
- menv[i].inv[j] = unmarshallShort(th);
-
- // place monster
- if (menv[i].type != -1)
- mgrd[menv[i].x][menv[i].y] = i;
- }
-}
-
-void tag_read_level_attitude(struct tagHeader &th)
-{
- int i, count;
-
- // how many monsters?
- count = unmarshallShort(th);
-
- for (i = 0; i < count; i++)
- {
- menv[i].attitude = unmarshallByte(th);
- menv[i].foe = unmarshallShort(th);
- }
-}
-
-void tag_missing_level_attitude()
-{
- // we don't really have to do a lot here.
- // just set foe to MHITNOT; they'll pick up
- // a foe first time through handle_monster() if
- // there's one around.
-
- // as for attitude, a couple simple checks
- // can be used to determine friendly/neutral/
- // hostile.
- int i;
- bool isFriendly;
- unsigned int new_beh = BEH_WANDER;
-
- for(i=0; i<MAX_MONSTERS; i++)
- {
- // only do actual monsters
- if (menv[i].type < 0)
- continue;
-
- isFriendly = testbits(menv[i].flags, MF_CREATED_FRIENDLY);
-
- menv[i].foe = MHITNOT;
-
- switch(menv[i].behaviour)
- {
- case 0: // old BEH_SLEEP
- new_beh = BEH_SLEEP; // don't wake sleepers
- break;
- case 3: // old BEH_FLEE
- case 10: // old BEH_FLEE_FRIEND
- new_beh = BEH_FLEE;
- break;
- case 1: // old BEH_CHASING_I
- case 6: // old BEH_FIGHT
- new_beh = BEH_SEEK;
- break;
- case 7: // old BEH_ENSLAVED
- if (!mons_has_ench(&menv[i], ENCH_CHARM))
- isFriendly = true;
- break;
- default:
- break;
- }
-
- menv[i].attitude = (isFriendly)?ATT_FRIENDLY : ATT_HOSTILE;
- menv[i].behaviour = new_beh;
- menv[i].foe_memory = 0;
- }
-}
-
-
-// ------------------------------- ghost tags ---------------------------- //
-
-static void tag_construct_ghost(struct tagHeader &th)
-{
- int i;
-
- marshallString(th, ghost.name, 20);
-
- // how many ghost values?
- marshallByte(th, 20);
-
- for (i = 0; i < 20; i++)
- marshallShort( th, ghost.values[i] );
-}
-
-static void tag_read_ghost(struct tagHeader &th, char minorVersion)
-{
- int i, count_c;
-
- snprintf( info, INFO_SIZE, "minor version = %d", minorVersion );
-
- unmarshallString(th, ghost.name, 20);
-
- // how many ghost values?
- count_c = unmarshallByte(th);
-
- for (i = 0; i < count_c; i++)
- {
- // for version 4.4 we moved from unsigned char to shorts -- bwr
- if (minorVersion < 4)
- ghost.values[i] = unmarshallByte(th);
- else
- ghost.values[i] = unmarshallShort(th);
- }
-
- if (minorVersion < 4)
- {
- // Getting rid 9of hopefulling the last) of this silliness -- bwr
- if (ghost.values[ GVAL_RES_FIRE ] >= 97)
- ghost.values[ GVAL_RES_FIRE ] -= 100;
-
- if (ghost.values[ GVAL_RES_COLD ] >= 97)
- ghost.values[ GVAL_RES_COLD ] -= 100;
- }
-}
-
-// ----------------------------------------------------------------------- //
diff --git a/stone_soup/crawl-ref/source/tags.h b/stone_soup/crawl-ref/source/tags.h
deleted file mode 100644
index 7c84709ebf..0000000000
--- a/stone_soup/crawl-ref/source/tags.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * File: tags.h
- * Summary: Auxilary functions to make savefile versioning simpler.
- * Written by: Gordon Lipford
- *
- * Change History (most recent first):
- *
- * <1> 27 Jan 2001 GDL Created
- */
-
-#ifndef TAGS_H
-#define TAGS_H
-
-#include <stdio.h>
-#include "externs.h"
-
-// last updated 22jan2001 {gdl}
-/* ***********************************************************************
- * called from: files tags
- * *********************************************************************** */
-int write2(FILE * file, const char *buffer, unsigned int count);
-
-
-// last updated 22jan2001 {gdl}
-/* ***********************************************************************
- * called from: files tags
- * *********************************************************************** */
-int read2(FILE * file, char *buffer, unsigned int count);
-
-
-// last updated 22jan2001 {gdl}
-/* ***********************************************************************
- * called from: files tags
- * *********************************************************************** */
-void marshallByte(struct tagHeader &th, char data);
-void marshallShort(struct tagHeader &th, short data);
-void marshallLong(struct tagHeader &th, long data);
-void marshallFloat(struct tagHeader &th, float data);
-void marshallBoolean(struct tagHeader &th, bool data);
-void marshallString(struct tagHeader &th, char *data, int maxSize = 0);
-
-// last updated 22jan2001 {gdl}
-/* ***********************************************************************
- * called from: tags files
- * *********************************************************************** */
-char unmarshallByte(struct tagHeader &th);
-short unmarshallShort(struct tagHeader &th);
-long unmarshallLong(struct tagHeader &th);
-float unmarshallFloat(struct tagHeader &th);
-bool unmarshallBoolean(struct tagHeader &th);
-void unmarshallString(struct tagHeader &th, char *data, int maxSize);
-
-void make_date_string( time_t in_date, char buff[20] );
-time_t parse_date_string( char[20] );
-
-// last updated 22jan2001 {gdl}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void tag_init(long largest_tag = 50000);
-
-
-// last updated 22jan2001 {gdl}
-/* ***********************************************************************
- * called from: files
- * *********************************************************************** */
-void tag_construct(struct tagHeader &th, int i);
-
-
-// last updated 22jan2001 {gdl}
-/* ***********************************************************************
- * called from: files
- * *********************************************************************** */
-void tag_write(struct tagHeader &th, FILE *saveFile);
-
-
-// last updated 22jan2001 {gdl}
-/* ***********************************************************************
- * called from: files
- * *********************************************************************** */
-void tag_set_expected(char tags[], int fileType);
-
-
-// last updated 22jan2001 {gdl}
-/* ***********************************************************************
- * called from: files
- * *********************************************************************** */
-void tag_missing(int tag, char minorVersion);
-
-
-// last updated 22jan2001 {gdl}
-/* ***********************************************************************
- * called from: files
- * *********************************************************************** */
-int tag_read(FILE *fp, char minorVersion);
-
-#endif // TAGS_H
diff --git a/stone_soup/crawl-ref/source/transfor.cc b/stone_soup/crawl-ref/source/transfor.cc
deleted file mode 100644
index 144a838bb2..0000000000
--- a/stone_soup/crawl-ref/source/transfor.cc
+++ /dev/null
@@ -1,574 +0,0 @@
-/*
- * File: transfor.cc
- * Summary: Misc function related to player transformations.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <2> 5/26/99 JDJ transform() and untransform() set you.wield_change so
- * the weapon line updates.
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "transfor.h"
-
-#include <stdio.h>
-#include <string.h>
-
-#include "externs.h"
-
-#include "it_use2.h"
-#include "itemname.h"
-#include "items.h"
-#include "misc.h"
-#include "player.h"
-#include "skills2.h"
-#include "stuff.h"
-
-extern unsigned char your_sign; // defined in view.cc
-extern unsigned char your_colour; // defined in view.cc
-void drop_everything(void);
-void extra_hp(int amount_extra);
-
-bool remove_equipment(FixedVector < char, 8 > &remove_stuff)
-{
- char str_pass[ ITEMNAME_SIZE ];
-
- // if we're removing body armour, the cloak will come off as well -- bwr
- if (remove_stuff[EQ_BODY_ARMOUR] == 1 && you.equip[EQ_BODY_ARMOUR] != -1)
- remove_stuff[EQ_CLOAK] = 1;
-
- // if we're removing gloves, the weapon will come off as well -- bwr
- if (remove_stuff[EQ_GLOVES] == 1 && you.equip[EQ_GLOVES] != -1)
- remove_stuff[EQ_WEAPON] = 1;
-
- if (remove_stuff[EQ_WEAPON] == 1 && you.equip[EQ_WEAPON] != -1)
- {
- unwield_item(you.equip[EQ_WEAPON]);
- you.equip[EQ_WEAPON] = -1;
- mpr("You are empty-handed.");
- you.wield_change = true;
- }
-
- for (int i = EQ_CLOAK; i < EQ_LEFT_RING; i++)
- {
- if (remove_stuff[i] == 0 || you.equip[i] == -1)
- continue;
-
- in_name( you.equip[i], DESC_CAP_YOUR, str_pass );
-
- snprintf( info, INFO_SIZE, "%s falls away.", str_pass );
- mpr(info);
-
- unwear_armour( you.equip[i] );
- you.equip[i] = -1;
- }
-
- return true;
-} // end remove_equipment()
-
-// Returns true if any piece of equipment that has to be removed is cursed.
-// Useful for keeping low level transformations from being too useful.
-static bool check_for_cursed_equipment( FixedVector < char, 8 > &remove_stuff )
-{
- for (int i = EQ_WEAPON; i < EQ_LEFT_RING; i++)
- {
- if (remove_stuff[i] == 0 || you.equip[i] == -1)
- continue;
-
- if (item_cursed( you.inv[ you.equip[i] ] ))
- {
- mpr( "Your cursed equipment won't allow you to complete the "
- "transformation." );
-
- return (true);
- }
- }
-
- return (false);
-} // end check_for_cursed_equipment()
-
-bool transform(int pow, char which_trans)
-{
- if (you.species == SP_MERFOLK && player_is_swimming()
- && which_trans != TRAN_DRAGON)
- {
- // This might by overkill, but it's okay because obviously
- // whatever magical ability that let's them walk on land is
- // removed when they're in water (in this case, their natural
- // form is completely over-riding any other... goes well with
- // the forced transform when entering water)... but merfolk can
- // transform into dragons, because dragons fly. -- bwr
- mpr("You cannot transform out of your normal form while in water.");
- return (false);
- }
-
- // This must occur before the untransform() and the is_undead check.
- if (you.attribute[ATTR_TRANSFORMATION] == which_trans)
- {
- if (you.duration[DUR_TRANSFORMATION] < 100)
- {
- mpr( "You extend your transformation's duration." );
- you.duration[DUR_TRANSFORMATION] += random2(pow);
-
- if (you.duration[DUR_TRANSFORMATION] > 100)
- you.duration[DUR_TRANSFORMATION] = 100;
-
- return (true);
- }
- else
- {
- mpr( "You cannot extend your transformation any further!" );
- return (false);
- }
- }
-
- if (you.attribute[ATTR_TRANSFORMATION] != TRAN_NONE)
- untransform();
-
- if (you.is_undead)
- {
- mpr("Your unliving flesh cannot be transformed in this way.");
- return (false);
- }
-
- //jmf: silently discard this enchantment
- you.duration[DUR_STONESKIN] = 0;
-
- FixedVector < char, 8 > rem_stuff;
-
- for (int i = EQ_WEAPON; i < EQ_RIGHT_RING; i++)
- rem_stuff[i] = 1;
-
- you.redraw_evasion = 1;
- you.redraw_armour_class = 1;
- you.wield_change = true;
-
- /* Remember, it can still fail in the switch below... */
- switch (which_trans)
- {
- case TRAN_SPIDER: // also AC +3, ev +3, fast_run
- if (check_for_cursed_equipment( rem_stuff ))
- return (false);
-
- mpr("You turn into a venomous arachnid creature.");
- remove_equipment( rem_stuff );
-
- you.attribute[ATTR_TRANSFORMATION] = TRAN_SPIDER;
- you.duration[DUR_TRANSFORMATION] = 10 + random2(pow) + random2(pow);
-
- if (you.duration[DUR_TRANSFORMATION] > 60)
- you.duration[DUR_TRANSFORMATION] = 60;
-
- modify_stat( STAT_DEXTERITY, 5, true );
-
- your_sign = 's';
- your_colour = BROWN;
- return (true);
-
- case TRAN_ICE_BEAST: // also AC +3, cold +3, fire -1, pois +1
- mpr( "You turn into a creature of crystalline ice." );
-
- rem_stuff[ EQ_CLOAK ] = 0;
-
- remove_equipment( rem_stuff );
-
- you.attribute[ATTR_TRANSFORMATION] = TRAN_ICE_BEAST;
- you.duration[DUR_TRANSFORMATION] = 30 + random2(pow) + random2(pow);
-
- if (you.duration[ DUR_TRANSFORMATION ] > 100)
- you.duration[ DUR_TRANSFORMATION ] = 100;
-
- extra_hp(12); // must occur after attribute set
-
- if (you.duration[DUR_ICY_ARMOUR])
- mpr( "Your new body merges with your icy armour." );
-
- your_sign = 'I';
- your_colour = WHITE;
- return (true);
-
- case TRAN_BLADE_HANDS:
- rem_stuff[EQ_CLOAK] = 0;
- rem_stuff[EQ_HELMET] = 0;
- rem_stuff[EQ_BOOTS] = 0;
- rem_stuff[EQ_BODY_ARMOUR] = 0;
-
- if (check_for_cursed_equipment( rem_stuff ))
- return (false);
-
- mpr("Your hands turn into razor-sharp scythe blades.");
- remove_equipment( rem_stuff );
-
- you.attribute[ATTR_TRANSFORMATION] = TRAN_BLADE_HANDS;
- you.duration[DUR_TRANSFORMATION] = 10 + random2(pow);
-
- if (you.duration[ DUR_TRANSFORMATION ] > 100)
- you.duration[ DUR_TRANSFORMATION ] = 100;
- return (true);
-
- case TRAN_STATUE: // also AC +20, ev -5, elec +1, pois +1, neg +1, slow
- if (you.species == SP_GNOME && coinflip())
- mpr( "Look, a garden gnome. How cute!" );
- else if (player_genus(GENPC_DWARVEN) && one_chance_in(10))
- mpr( "You inwardly fear your resemblance to a lawn ornament." );
- else
- mpr( "You turn into a living statue of rough stone." );
-
- rem_stuff[ EQ_WEAPON ] = 0; /* can still hold a weapon */
- rem_stuff[ EQ_CLOAK ] = 0;
- rem_stuff[ EQ_HELMET ] = 0;
- rem_stuff[ EQ_BOOTS ] = 0;
- // too stiff to make use of shields, gloves, or armour -- bwr
-
- remove_equipment( rem_stuff );
-
- you.attribute[ATTR_TRANSFORMATION] = TRAN_STATUE;
- you.duration[DUR_TRANSFORMATION] = 20 + random2(pow) + random2(pow);
-
- if (you.duration[ DUR_TRANSFORMATION ] > 100)
- you.duration[ DUR_TRANSFORMATION ] = 100;
-
- modify_stat( STAT_DEXTERITY, -2, true );
- modify_stat( STAT_STRENGTH, 2, true );
- extra_hp(15); // must occur after attribute set
-
- if (you.duration[DUR_STONEMAIL] || you.duration[DUR_STONESKIN])
- mpr( "Your new body merges with your stone armour." );
-
- your_sign = '8';
- your_colour = LIGHTGREY;
- return (true);
-
- case TRAN_DRAGON: // also AC +10, ev -3, cold -1, fire +2, pois +1, flight
- if (you.species == SP_MERFOLK && player_is_swimming())
- mpr("You fly out of the water as you turn into a fearsome dragon!");
- else
- mpr("You turn into a fearsome dragon!");
-
- remove_equipment(rem_stuff);
-
- you.attribute[ATTR_TRANSFORMATION] = TRAN_DRAGON;
- you.duration[DUR_TRANSFORMATION] = 20 + random2(pow) + random2(pow);
-
- if (you.duration[ DUR_TRANSFORMATION ] > 100)
- you.duration[ DUR_TRANSFORMATION ] = 100;
-
- modify_stat( STAT_STRENGTH, 10, true );
- extra_hp(16); // must occur after attribute set
-
- your_sign = 'D';
- your_colour = GREEN;
- return (true);
-
- case TRAN_LICH:
- // also AC +3, cold +1, neg +3, pois +1, is_undead, res magic +50,
- // spec_death +1, and drain attack (if empty-handed)
- if (you.deaths_door)
- {
- mpr( "The transformation conflicts with an enchantment "
- "already in effect." );
-
- return (false);
- }
-
- mpr("Your body is suffused with negative energy!");
-
- // undead cannot regenerate -- bwr
- if (you.duration[DUR_REGENERATION])
- {
- mpr( "You stop regenerating.", MSGCH_DURATION );
- you.duration[DUR_REGENERATION] = 0;
- }
-
- // silently removed since undead automatically resist poison -- bwr
- you.duration[DUR_RESIST_POISON] = 0;
-
- /* no remove_equip */
- you.attribute[ATTR_TRANSFORMATION] = TRAN_LICH;
- you.duration[DUR_TRANSFORMATION] = 20 + random2(pow) + random2(pow);
-
- if (you.duration[ DUR_TRANSFORMATION ] > 100)
- you.duration[ DUR_TRANSFORMATION ] = 100;
-
- modify_stat( STAT_STRENGTH, 3, true );
- your_sign = 'L';
- your_colour = LIGHTGREY;
- you.is_undead = US_UNDEAD;
- you.hunger_state = HS_SATIATED; // no hunger effects while transformed
- set_redraw_status( REDRAW_HUNGER );
- return (true);
-
- case TRAN_AIR:
- // also AC 20, ev +20, regen/2, no hunger, fire -2, cold -2, air +2,
- // pois +1, spec_earth -1
- mpr( "You feel diffuse..." );
-
- remove_equipment(rem_stuff);
-
- drop_everything();
-
- you.attribute[ATTR_TRANSFORMATION] = TRAN_AIR;
- you.duration[DUR_TRANSFORMATION] = 35 + random2(pow) + random2(pow);
-
- if (you.duration[ DUR_TRANSFORMATION ] > 150)
- you.duration[ DUR_TRANSFORMATION ] = 150;
-
- modify_stat( STAT_DEXTERITY, 8, true );
- your_sign = '#';
- your_colour = DARKGREY;
- return (true);
-
- case TRAN_SERPENT_OF_HELL:
- // also AC +10, ev -5, fire +2, pois +1, life +2, slow
- mpr( "You transform into a huge demonic serpent!" );
-
- remove_equipment(rem_stuff);
-
- you.attribute[ATTR_TRANSFORMATION] = TRAN_SERPENT_OF_HELL;
- you.duration[DUR_TRANSFORMATION] = 20 + random2(pow) + random2(pow);
-
- if (you.duration[ DUR_TRANSFORMATION ] > 120)
- you.duration[ DUR_TRANSFORMATION ] = 120;
-
- modify_stat( STAT_STRENGTH, 13, true );
- extra_hp(17); // must occur after attribute set
-
- your_sign = 'S';
- your_colour = RED;
- return (true);
- }
-
- return (false);
-} // end transform()
-
-void untransform(void)
-{
- FixedVector < char, 8 > rem_stuff;
-
- for (int i = EQ_WEAPON; i < EQ_RIGHT_RING; i++)
- rem_stuff[i] = 0;
-
- you.redraw_evasion = 1;
- you.redraw_armour_class = 1;
- you.wield_change = true;
-
- your_sign = '@';
- your_colour = LIGHTGREY;
-
- // must be unset first or else infinite loops might result -- bwr
- const int old_form = you.attribute[ ATTR_TRANSFORMATION ];
- you.attribute[ ATTR_TRANSFORMATION ] = TRAN_NONE;
- you.duration[ DUR_TRANSFORMATION ] = 0;
-
- switch (old_form)
- {
- case TRAN_SPIDER:
- mpr("Your transformation has ended.", MSGCH_DURATION);
- modify_stat( STAT_DEXTERITY, -5, true );
- break;
-
- case TRAN_BLADE_HANDS:
- mpr( "Your hands revert to their normal proportions.", MSGCH_DURATION );
- you.wield_change = true;
- break;
-
- case TRAN_STATUE:
- mpr( "You revert to your normal fleshy form.", MSGCH_DURATION );
- modify_stat( STAT_DEXTERITY, 2, true );
- modify_stat( STAT_STRENGTH, -2, true );
-
- // Note: if the core goes down, the combined effect soon disappears,
- // but the reverse isn't true. -- bwr
- if (you.duration[DUR_STONEMAIL])
- you.duration[DUR_STONEMAIL] = 1;
-
- if (you.duration[DUR_STONESKIN])
- you.duration[DUR_STONESKIN] = 1;
- break;
-
- case TRAN_ICE_BEAST:
- mpr( "You warm up again.", MSGCH_DURATION );
-
- // Note: if the core goes down, the combined effect soon disappears,
- // but the reverse isn't true. -- bwr
- if (you.duration[DUR_ICY_ARMOUR])
- you.duration[DUR_ICY_ARMOUR] = 1;
- break;
-
- case TRAN_DRAGON:
- mpr( "Your transformation has ended.", MSGCH_DURATION );
- modify_stat(STAT_STRENGTH, -10, true);
-
- if (!player_is_levitating()
- && (grd[you.x_pos][you.y_pos] == DNGN_LAVA
- || grd[you.x_pos][you.y_pos] == DNGN_DEEP_WATER
- || grd[you.x_pos][you.y_pos] == DNGN_SHALLOW_WATER))
- {
- if (you.species == SP_MERFOLK
- && grd[you.x_pos][you.y_pos] != DNGN_LAVA)
- {
- mpr("You dive into the water and return to your normal form.");
- merfolk_start_swimming();
- }
-
- if (grd[you.x_pos][you.y_pos] != DNGN_SHALLOW_WATER)
- fall_into_a_pool( true, grd[you.x_pos][you.y_pos] );
- }
- break;
-
- case TRAN_LICH:
- mpr( "You feel yourself come back to life.", MSGCH_DURATION );
- modify_stat(STAT_STRENGTH, -3, true);
- you.is_undead = US_ALIVE;
- break;
-
- case TRAN_AIR:
- mpr( "Your body solidifies.", MSGCH_DURATION );
- modify_stat(STAT_DEXTERITY, -8, true);
- break;
-
- case TRAN_SERPENT_OF_HELL:
- mpr( "Your transformation has ended.", MSGCH_DURATION );
- modify_stat(STAT_STRENGTH, -13, true);
- break;
- }
-
- // If nagas wear boots while transformed, they fall off again afterwards:
- // I don't believe this is currently possible, and if it is we
- // probably need something better to cover all possibilities. -bwr
- if ((you.species == SP_NAGA || you.species == SP_CENTAUR)
- && you.equip[ EQ_BOOTS ] != -1
- && you.inv[ you.equip[EQ_BOOTS] ].sub_type != ARM_NAGA_BARDING)
- {
- rem_stuff[EQ_BOOTS] = 1;
- remove_equipment(rem_stuff);
- }
-
- calc_hp();
-} // end untransform()
-
-// XXX: This whole system is a mess as it still relies on special
-// cases to handle a large number of things (see wear_armour()) -- bwr
-bool can_equip( equipment_type use_which )
-{
-
- // if more cases are added to this if must also change in
- // item_use for naga barding
- if (!player_is_shapechanged())
- /* or a transformation which doesn't change overall shape */
- {
- if (use_which == EQ_BOOTS)
- {
- switch (you.species)
- {
- case SP_NAGA:
- case SP_CENTAUR:
- case SP_KENKU:
- return (false);
- default:
- break;
- }
- }
- else if (use_which == EQ_HELMET)
- {
- switch (you.species)
- {
- case SP_MINOTAUR:
- case SP_KENKU:
- return (false);
- default:
- break;
- }
- }
- }
-
- if (use_which == EQ_HELMET && you.mutation[MUT_HORNS])
- return (false);
-
- if (use_which == EQ_BOOTS && you.mutation[MUT_HOOVES])
- return (false);
-
- if (use_which == EQ_GLOVES && you.mutation[MUT_CLAWS] >= 3)
- return (false);
-
- switch (you.attribute[ATTR_TRANSFORMATION])
- {
- case TRAN_NONE:
- case TRAN_LICH:
- return (true);
-
- case TRAN_BLADE_HANDS:
- return (use_which != EQ_WEAPON
- && use_which != EQ_GLOVES
- && use_which != EQ_SHIELD);
-
- case TRAN_STATUE:
- return (use_which == EQ_WEAPON
- || use_which == EQ_CLOAK
- || use_which == EQ_HELMET);
-
- case TRAN_ICE_BEAST:
- return (use_which == EQ_CLOAK);
-
- default:
- return (false);
- }
-
- return (true);
-} // end can_equip()
-
-// raw comparison of an item, must use check_armour_shape for full version
-bool transform_can_equip_type( int eq_slot )
-{
- // FIXME FIXME FIXME
- return (false);
-
- // const int form = you.attribute[ATTR_TRANSFORMATION];
- // return (!must_remove( Trans[form].rem_stuff, eq_slot ));
-}
-
-void extra_hp(int amount_extra) // must also set in calc_hp
-{
- calc_hp();
-
- you.hp *= amount_extra;
- you.hp /= 10;
-
- deflate_hp(you.hp_max, false);
-} // end extra_hp()
-
-void drop_everything(void)
-{
- int i = 0;
-
- if (inv_count() < 1)
- return;
-
- mpr( "You find yourself unable to carry your possessions!" );
-
- for (i = 0; i < ENDOFPACK; i++)
- {
- if (is_valid_item( you.inv[i] ))
- {
- copy_item_to_grid( you.inv[i], you.x_pos, you.y_pos );
- you.inv[i].quantity = 0;
- }
- }
-
- return;
-} // end drop_everything()
-
-// Used to mark transformations which override species/mutation intrinsics.
-// If phys_scales is true then we're checking to see if the form keeps
-// the physical (AC/EV) properties from scales... the special intrinsic
-// features (resistances, etc) are lost in those forms however.
-bool transform_changed_physiology( bool phys_scales )
-{
- return (you.attribute[ATTR_TRANSFORMATION] != TRAN_NONE
- && you.attribute[ATTR_TRANSFORMATION] != TRAN_BLADE_HANDS
- && (!phys_scales
- || (you.attribute[ATTR_TRANSFORMATION] != TRAN_LICH
- && you.attribute[ATTR_TRANSFORMATION] != TRAN_STATUE)));
-}
diff --git a/stone_soup/crawl-ref/source/transfor.h b/stone_soup/crawl-ref/source/transfor.h
deleted file mode 100644
index 4fbbe1aaa7..0000000000
--- a/stone_soup/crawl-ref/source/transfor.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * File: transfor.cc
- * Summary: Misc function related to player transformations.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef TRANSFOR_H
-#define TRANSFOR_H
-
-#include "FixVec.h"
-#include "enum.h"
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - transfor
- * *********************************************************************** */
-void untransform(void);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: item_use
- * *********************************************************************** */
-bool can_equip(equipment_type use_which);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: ability - spell
- * *********************************************************************** */
-bool transform(int pow, char which_trans);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: mutation - transfor
- * *********************************************************************** */
-bool remove_equipment( FixedVector<char, 8>& remove_stuff );
-
-bool transform_changed_physiology( bool phys_scales = false );
-
-#endif
diff --git a/stone_soup/crawl-ref/source/travel.cc b/stone_soup/crawl-ref/source/travel.cc
deleted file mode 100644
index 5958e8fbf3..0000000000
--- a/stone_soup/crawl-ref/source/travel.cc
+++ /dev/null
@@ -1,2928 +0,0 @@
-/*
- * File: travel.cc
- * Summary: Travel stuff
- * Written by: Darshan Shaligram
- *
- * Known issues:
- * Hardcoded dungeon features all over the place - this thing is a devil to
- * refactor.
- */
-#include "AppHdr.h"
-#include "files.h"
-#include "FixAry.h"
-#include "clua.h"
-#include "mon-util.h"
-#include "player.h"
-#include "stash.h"
-#include "stuff.h"
-#include "travel.h"
-#include "view.h"
-#include <stdarg.h>
-#include <ctype.h>
-#include <stdio.h>
-
-#ifdef DOS
-#include <dos.h>
-#endif
-
-#define TC_MAJOR_VERSION ((unsigned char) 4)
-#define TC_MINOR_VERSION ((unsigned char) 4)
-
-enum IntertravelDestination
-{
- // Go down a level
- ID_DOWN = -100,
-
- // Go up a level
- ID_UP = -99,
-
- // Repeat last travel
- ID_REPEAT = -101,
-
- // Cancel interlevel travel
- ID_CANCEL = -1000
-};
-
-TravelCache travel_cache;
-
-// Tracks the distance between the target location on the target level and the
-// stairs on the level.
-static std::vector<stair_info> curr_stairs;
-
-// Squares that are not safe to travel to on the current level.
-static std::vector<coord_def> curr_excludes;
-
-// This is where we last tried to take a stair during interlevel travel.
-// Note that last_stair.depth should be set to -1 before initiating interlevel
-// travel.
-static level_id last_stair;
-
-// Where travel wants to get to.
-static level_pos travel_target;
-
-// The place in the Vestibule of Hell where all portals to Hell land.
-static level_pos travel_hell_entry;
-
-static bool traps_inited = false;
-
-// TODO: Do we need this or would a different header be better?
-inline int sgn(int x)
-{
- return x < 0? -1 : (x > 0);
-}
-
-/* These are defined in view.cc. BWR says these may become obsolete in next
- * release? */
-extern unsigned char (*mapch) (unsigned char);
-extern unsigned char (*mapch2) (unsigned char);
-extern unsigned char mapchar(unsigned char ldfk);
-extern unsigned char mapchar2(unsigned char ldfk);
-
-
-// Array of points on the map, each value being the distance the character
-// would have to travel to get there. Negative distances imply that the point
-// is a) a trap or hostile terrain or b) only reachable by crossing a trap or
-// hostile terrain.
-short point_distance[GXM][GYM];
-
-unsigned char curr_waypoints[GXM][GYM];
-
-signed char curr_traps[GXM][GYM];
-
-static FixedArray< unsigned short, GXM, GYM > mapshadow;
-
-// Clockwise, around the compass from north (same order as enum RUN_DIR)
-// Copied from acr.cc
-static const struct coord_def Compass[8] =
-{
- { 0, -1 }, { 1, -1 }, { 1, 0 }, { 1, 1 },
- { 0, 1 }, { -1, 1 }, { -1, 0 }, { -1, -1 },
-};
-
-#define TRAVERSABLE 1
-#define IMPASSABLE 0
-#define FORBIDDEN -1
-
-// Map of terrain types that are traversable.
-static signed char traversable_terrain[256];
-
-static int trans_negotiate_stairs();
-static int find_transtravel_square(const level_pos &pos, bool verbose = true);
-
-static bool loadlev_populate_stair_distances(const level_pos &target);
-static void populate_stair_distances(const level_pos &target);
-
-// Determines whether the player has seen this square, given the user-visible
-// character.
-//
-// The player is assumed to have seen the square if:
-// a. The square is mapped (the env map char is not zero)
-// b. The square was *not* magic-mapped.
-//
-bool is_player_mapped(unsigned char envch)
-{
- // Note that we're relying here on mapch(DNGN_FLOOR) != mapch2(DNGN_FLOOR)
- // and that no *other* dungeon feature renders as mapch(DNGN_FLOOR).
- // The check for a ~ is to ensure explore stops for items turned up by
- // detect items.
- return envch && envch != mapch(DNGN_FLOOR) && envch != '~';
-}
-
-inline bool is_trap(unsigned char grid)
-{
- return (grid == DNGN_TRAP_MECHANICAL || grid == DNGN_TRAP_MAGICAL
- || grid == DNGN_TRAP_III);
-}
-
-// Returns true if there is a known trap at (x,y). Returns false for non-trap
-// squares as also for undiscovered traps.
-//
-inline bool is_trap(int x, int y)
-{
- return is_trap( grd[x][y] );
-}
-
-// Returns true if this feature takes extra time to cross.
-inline int feature_traverse_cost(unsigned char feature)
-{
- return (feature == DNGN_SHALLOW_WATER || feature == DNGN_CLOSED_DOOR? 2 :
- is_trap(feature) ? 3 : 1);
-}
-
-// Returns true if the dungeon feature supplied is an altar.
-inline bool is_altar(unsigned char grid)
-{
- return grid >= DNGN_ALTAR_ZIN && grid <= DNGN_ALTAR_ELYVILON;
-}
-
-inline bool is_altar(const coord_def &c)
-{
- return is_altar(grd[c.x][c.y]);
-}
-
-inline bool is_player_altar(unsigned char grid)
-{
- // An ugly hack, but that's what religion.cc does.
- return you.religion
- && grid == DNGN_ALTAR_ZIN - 1 + you.religion;
-}
-
-inline bool is_player_altar(const coord_def &c)
-{
- return is_player_altar(grd[c.x][c.y]);
-}
-
-// Copies FixedArray src to FixedArray dest.
-//
-inline void copy(const FixedArray<unsigned short, GXM, GYM> &src,
- FixedArray<unsigned short, GXM, GYM> &dest)
-{
- dest = src;
-}
-
-#ifdef CLUA_BINDINGS
-static void init_traps()
-{
- memset(curr_traps, -1, sizeof curr_traps);
- for (int i = 0; i < MAX_TRAPS; ++i)
- {
- int x = env.trap[i].x,
- y = env.trap[i].y;
- if (x > 0 && x < GXM && y > 0 && y < GYM)
- curr_traps[x][y] = i;
- }
- traps_inited = true;
-}
-
-static const char *trap_names[] =
-{
- "dart", "arrow", "spear", "axe",
- "teleport", "amnesia", "blade",
- "bolt", "zot", "needle",
-};
-
-static const char *trap_name(int x, int y)
-{
- if (!traps_inited)
- init_traps();
-
- const int ti = curr_traps[x][y];
- if (ti != -1)
- {
- int type = env.trap[ti].type;
- if (type >= 0 && type < NUM_TRAPS)
- return (trap_names[type]);
- }
- return ("");
-}
-#endif
-
-/*
- * Returns true if the character can cross this dungeon feature.
- */
-inline bool is_traversable(unsigned char grid)
-{
- return traversable_terrain[(int) grid] == TRAVERSABLE;
-}
-
-static bool is_excluded(int x, int y)
-{
- for (int i = 0, count = curr_excludes.size(); i < count; ++i)
- {
- const coord_def &c = curr_excludes[i];
- int dx = c.x - x,
- dy = c.y - y;
- if (dx * dx + dy * dy <= Options.travel_exclude_radius2)
- return true;
- }
- return false;
-}
-
-static bool is_exclude_root(int x, int y)
-{
- for (int i = 0, count = curr_excludes.size(); i < count; ++i)
- {
- const coord_def &c = curr_excludes[i];
- if (c.x == x && c.y == y)
- return true;
- }
- return false;
-}
-
-const char *run_mode_name(int runmode)
-{
- return runmode == RUN_TRAVEL? "travel" :
- runmode == RUN_INTERLEVEL? "intertravel" :
- runmode == RUN_EXPLORE? "explore" :
- runmode > 0? "run" :
- "";
-}
-
-unsigned char is_waypoint(int x, int y)
-{
- if (you.level_type == LEVEL_LABYRINTH || you.level_type == LEVEL_ABYSS
- || you.level_type == LEVEL_PANDEMONIUM)
- return 0;
- return curr_waypoints[x][y];
-}
-
-#ifdef STASH_TRACKING
-inline bool is_stash(LevelStashes *ls, int x, int y)
-{
- if (!ls)
- return (false);
- Stash *s = ls->find_stash(x, y);
- return s && s->enabled;
-}
-#endif
-
-void clear_excludes()
-{
- // Sanity checks
- if (you.level_type == LEVEL_LABYRINTH || you.level_type == LEVEL_ABYSS)
- return;
-
- curr_excludes.clear();
-
- if (can_travel_interlevel())
- {
- LevelInfo &li = travel_cache.get_level_info(
- level_id::get_current_level_id());
- li.update();
- }
-}
-
-void toggle_exclude(int x, int y)
-{
- // Sanity checks
- if (you.level_type == LEVEL_LABYRINTH || you.level_type == LEVEL_ABYSS)
- return;
-
- if (x <= 0 || x >= GXM || y <= 0 || y >= GYM) return;
- if (!env.map[x - 1][y - 1]) return;
-
- if (is_exclude_root(x, y))
- {
- for (int i = 0, count = curr_excludes.size(); i < count; ++i)
- {
- const coord_def &c = curr_excludes[i];
- if (c.x == x && c.y == y)
- {
- curr_excludes.erase( curr_excludes.begin() + i );
- break ;
- }
- }
- }
- else
- {
- coord_def c = { x, y };
- curr_excludes.push_back(c);
- }
-
- if (can_travel_interlevel())
- {
- LevelInfo &li = travel_cache.get_level_info(
- level_id::get_current_level_id());
- li.update();
- }
-}
-
-void update_excludes()
-{
- // Sanity checks
- if (you.level_type == LEVEL_LABYRINTH || you.level_type == LEVEL_ABYSS)
- return;
- for (int i = curr_excludes.size() - 1; i >= 0; --i)
- {
- int x = curr_excludes[i].x,
- y = curr_excludes[i].y;
- if (!env.map[x - 1][y - 1])
- curr_excludes.erase( curr_excludes.begin() + i );
- }
-}
-
-void forget_square(int x, int y)
-{
- if (you.level_type == LEVEL_LABYRINTH || you.level_type == LEVEL_ABYSS)
- return;
-
- if (is_exclude_root(x, y))
- toggle_exclude(x, y);
-}
-
-/*
- * Returns true if the square at (x,y) is a dungeon feature the character
- * can't (under normal circumstances) safely cross.
- *
- * Note: is_reseedable can return true for dungeon features that is_traversable
- * also returns true for. This is okay, because is_traversable always
- * takes precedence over is_reseedable. is_reseedable is used only to
- * decide which squares to reseed from when flood-filling outwards to
- * colour the level map. It does not affect pathing of actual
- * travel/explore.
- */
-static bool is_reseedable(int x, int y)
-{
- if (is_excluded(x, y))
- return true;
- unsigned char grid = grd[x][y];
- return (grid == DNGN_DEEP_WATER || grid == DNGN_SHALLOW_WATER ||
- grid == DNGN_LAVA || is_trap(x, y));
-}
-
-/*
- * Returns true if the square at (x,y) is okay to travel over. If ignore_hostile
- * is true, returns true even for dungeon features the character can normally
- * not cross safely (deep water, lava, traps).
- */
-static bool is_travel_ok(int x, int y, bool ignore_hostile)
-{
- unsigned char grid = grd[x][y];
-
- unsigned char envc = (unsigned char) env.map[x - 1][y - 1];
- if (!envc) return false;
-
- // Special-case secret doors so that we don't run into awkwardness when
- // a monster opens a secret door without the hero seeing it, but the travel
- // code paths through the secret door because it looks at the actual grid,
- // rather than the env overmap. Hopefully there won't be any more such
- // cases.
- if (envc == mapch2(DNGN_SECRET_DOOR)) return false;
-
- unsigned char mon = mgrd[x][y];
- if (mon != NON_MONSTER)
- {
- // Kludge warning: navigating around zero-exp beasties uses knowledge
- // that the player may not have (the player may not
- // know that there's a plant at any given (x,y), but we
- // know, because we're looking directly at the grid).
- // Arguably the utility of this feature is greater than
- // the information we're giving the player for free.
- // Navigate around plants and fungi. Yet another tasty hack.
- if (player_monster_visible(&menv[mon]) &&
- mons_class_flag( menv[mon].type, M_NO_EXP_GAIN ))
- {
- extern short point_distance[GXM][GYM];
-
- // We have to set the point_distance array if the level map is
- // to be properly coloured. The caller isn't going to do it because
- // we say this square is inaccessible, so in a horrible hack, we
- // do it ourselves. Ecch.
- point_distance[x][y] = ignore_hostile? -42 : 42;
- return false;
- }
- }
-
- // If 'ignore_hostile' is true, we're ignoring hazards that can be
- // navigated over if the player is willing to take damage, or levitate.
- if (ignore_hostile && is_reseedable(x, y))
- return true;
-
- return (is_traversable(grid)
-#ifdef CLUA_BINDINGS
- ||
- (is_trap(x, y) &&
- clua.callbooleanfn(false, "ch_cross_trap",
- "s", trap_name(x, y)))
-#endif
- )
- && !is_excluded(x, y);
-}
-
-// Returns true if the location at (x,y) is monster-free and contains no clouds.
-static bool is_safe(int x, int y)
-{
- unsigned char mon = mgrd[x][y];
- if (mon != NON_MONSTER)
- {
- // If this is an invisible critter, say we're safe to get here, but
- // turn off travel - the result should be that the player bashes into
- // the monster and stops travelling right there. Same treatment applies
- // to mimics.
- if (!player_monster_visible(&menv[mon]) ||
- mons_is_mimic( menv[mon].type ))
- {
- you.running = 0;
- return true;
- }
-
- // Stop before wasting energy on plants and fungi.
- if (mons_class_flag( menv[mon].type, M_NO_EXP_GAIN ))
- return false;
-
- // If this is any *other* monster, it'll be visible and
- // a) Friendly, in which case we'll displace it, no problem.
- // b) Unfriendly, in which case we're in deep trouble, since travel
- // should have been aborted already by the checks in view.cc.
- }
- const char cloud = env.cgrid[x][y];
- if (cloud == EMPTY_CLOUD)
- return true;
-
- // We can also safely run through smoke.
- const char cloud_type = env.cloud[ cloud ].type;
- return cloud_type == CLOUD_GREY_SMOKE ||
- cloud_type == CLOUD_GREY_SMOKE_MON ||
- cloud_type == CLOUD_BLUE_SMOKE ||
- cloud_type == CLOUD_BLUE_SMOKE_MON ||
- cloud_type == CLOUD_PURP_SMOKE ||
- cloud_type == CLOUD_PURP_SMOKE_MON ||
- cloud_type == CLOUD_BLACK_SMOKE ||
- cloud_type == CLOUD_BLACK_SMOKE_MON;
-}
-
-static bool player_is_permalevitating()
-{
- return you.levitation > 1 &&
- ((you.species == SP_KENKU && you.experience_level >= 15)
- || player_equip_ego_type( EQ_BOOTS, SPARM_LEVITATION ));
-}
-
-static void set_pass_feature(unsigned char grid, signed char pass)
-{
- if (traversable_terrain[(unsigned) grid] != FORBIDDEN)
- traversable_terrain[(unsigned) grid] = pass;
-}
-
-/*
- * Sets traversable terrain based on the character's role and whether or not he
- * has permanent levitation
- */
-static void init_terrain_check()
-{
- // Merfolk get deep water.
- signed char water = you.species == SP_MERFOLK? TRAVERSABLE : IMPASSABLE;
- // If the player has overridden deep water already, we'll respect that.
- set_pass_feature(DNGN_DEEP_WATER, water);
-
- // Permanently levitating players can cross most hostile terrain.
- signed char trav = player_is_permalevitating()?
- TRAVERSABLE : IMPASSABLE;
- if (you.species != SP_MERFOLK)
- set_pass_feature(DNGN_DEEP_WATER, trav);
- set_pass_feature(DNGN_LAVA, trav);
- set_pass_feature(DNGN_TRAP_MECHANICAL, trav);
-}
-
-void travel_init_new_level()
-{
- // Zero out last travel coords
- you.run_x = you.run_y = 0;
- you.travel_x = you.travel_y = 0;
-
- traps_inited = false;
- curr_excludes.clear();
- travel_cache.set_level_excludes();
- travel_cache.update_waypoints();
-}
-
-/*
- * Sets up travel-related stuff.
- */
-void initialise_travel()
-{
- // Need a better way to do this. :-(
- traversable_terrain[DNGN_FLOOR] =
- traversable_terrain[DNGN_ENTER_HELL] =
- traversable_terrain[DNGN_OPEN_DOOR] =
- traversable_terrain[DNGN_UNDISCOVERED_TRAP] =
- traversable_terrain[DNGN_ENTER_SHOP] =
- traversable_terrain[DNGN_ENTER_LABYRINTH] =
- traversable_terrain[DNGN_STONE_STAIRS_DOWN_I] =
- traversable_terrain[DNGN_STONE_STAIRS_DOWN_II] =
- traversable_terrain[DNGN_STONE_STAIRS_DOWN_III] =
- traversable_terrain[DNGN_ROCK_STAIRS_DOWN] =
- traversable_terrain[DNGN_STONE_STAIRS_UP_I] =
- traversable_terrain[DNGN_STONE_STAIRS_UP_II] =
- traversable_terrain[DNGN_STONE_STAIRS_UP_III] =
- traversable_terrain[DNGN_ROCK_STAIRS_UP] =
- traversable_terrain[DNGN_ENTER_DIS] =
- traversable_terrain[DNGN_ENTER_GEHENNA] =
- traversable_terrain[DNGN_ENTER_COCYTUS] =
- traversable_terrain[DNGN_ENTER_TARTARUS] =
- traversable_terrain[DNGN_ENTER_ABYSS] =
- traversable_terrain[DNGN_EXIT_ABYSS] =
- traversable_terrain[DNGN_STONE_ARCH] =
- traversable_terrain[DNGN_ENTER_PANDEMONIUM] =
- traversable_terrain[DNGN_EXIT_PANDEMONIUM] =
- traversable_terrain[DNGN_TRANSIT_PANDEMONIUM] =
- traversable_terrain[DNGN_ENTER_ORCISH_MINES] =
- traversable_terrain[DNGN_ENTER_HIVE] =
- traversable_terrain[DNGN_ENTER_LAIR] =
- traversable_terrain[DNGN_ENTER_SLIME_PITS] =
- traversable_terrain[DNGN_ENTER_VAULTS] =
- traversable_terrain[DNGN_ENTER_CRYPT] =
- traversable_terrain[DNGN_ENTER_HALL_OF_BLADES] =
- traversable_terrain[DNGN_ENTER_ZOT] =
- traversable_terrain[DNGN_ENTER_TEMPLE] =
- traversable_terrain[DNGN_ENTER_SNAKE_PIT] =
- traversable_terrain[DNGN_ENTER_ELVEN_HALLS] =
- traversable_terrain[DNGN_ENTER_TOMB] =
- traversable_terrain[DNGN_ENTER_SWAMP] =
- traversable_terrain[DNGN_RETURN_FROM_ORCISH_MINES] =
- traversable_terrain[DNGN_RETURN_FROM_HIVE] =
- traversable_terrain[DNGN_RETURN_FROM_LAIR] =
- traversable_terrain[DNGN_RETURN_FROM_SLIME_PITS] =
- traversable_terrain[DNGN_RETURN_FROM_VAULTS] =
- traversable_terrain[DNGN_RETURN_FROM_CRYPT] =
- traversable_terrain[DNGN_RETURN_FROM_HALL_OF_BLADES] =
- traversable_terrain[DNGN_RETURN_FROM_ZOT] =
- traversable_terrain[DNGN_RETURN_FROM_TEMPLE] =
- traversable_terrain[DNGN_RETURN_FROM_SNAKE_PIT] =
- traversable_terrain[DNGN_RETURN_FROM_ELVEN_HALLS] =
- traversable_terrain[DNGN_RETURN_FROM_TOMB] =
- traversable_terrain[DNGN_RETURN_FROM_SWAMP] =
- traversable_terrain[DNGN_ALTAR_ZIN] =
- traversable_terrain[DNGN_ALTAR_SHINING_ONE] =
- traversable_terrain[DNGN_ALTAR_KIKUBAAQUDGHA] =
- traversable_terrain[DNGN_ALTAR_YREDELEMNUL] =
- traversable_terrain[DNGN_ALTAR_XOM] =
- traversable_terrain[DNGN_ALTAR_VEHUMET] =
- traversable_terrain[DNGN_ALTAR_OKAWARU] =
- traversable_terrain[DNGN_ALTAR_MAKHLEB] =
- traversable_terrain[DNGN_ALTAR_SIF_MUNA] =
- traversable_terrain[DNGN_ALTAR_TROG] =
- traversable_terrain[DNGN_ALTAR_NEMELEX_XOBEH] =
- traversable_terrain[DNGN_ALTAR_ELYVILON] =
- traversable_terrain[DNGN_BLUE_FOUNTAIN] =
- traversable_terrain[DNGN_DRY_FOUNTAIN_I] =
- traversable_terrain[DNGN_SPARKLING_FOUNTAIN] =
- traversable_terrain[DNGN_DRY_FOUNTAIN_II] =
- traversable_terrain[DNGN_DRY_FOUNTAIN_III] =
- traversable_terrain[DNGN_DRY_FOUNTAIN_IV] =
- traversable_terrain[DNGN_DRY_FOUNTAIN_V] =
- traversable_terrain[DNGN_DRY_FOUNTAIN_VI] =
- traversable_terrain[DNGN_DRY_FOUNTAIN_VII] =
- traversable_terrain[DNGN_DRY_FOUNTAIN_VIII] =
- traversable_terrain[DNGN_PERMADRY_FOUNTAIN] =
- traversable_terrain[DNGN_CLOSED_DOOR] =
- traversable_terrain[DNGN_SHALLOW_WATER] =
- TRAVERSABLE;
-}
-
-/*
- * Given a dungeon feature description, returns the feature number. This is a
- * crude hack and currently recognises only (deep/shallow) water.
- *
- * Returns -1 if the feature named is not recognised, else returns the feature
- * number (guaranteed to be 0-255).
- */
-int get_feature_type(const std::string &feature)
-{
- if (feature.find("deep water") != std::string::npos)
- return DNGN_DEEP_WATER;
- if (feature.find("shallow water") != std::string::npos)
- return DNGN_SHALLOW_WATER;
- return -1;
-}
-
-/*
- * Given a feature description, prevents travel to locations of that feature
- * type.
- */
-void prevent_travel_to(const std::string &feature)
-{
- int feature_type = get_feature_type(feature);
- if (feature_type != -1)
- traversable_terrain[feature_type] = FORBIDDEN;
-}
-
-bool is_stair(unsigned gridc)
-{
- return (is_travelable_stair(gridc)
- || gridc == DNGN_ENTER_ABYSS
- || gridc == DNGN_ENTER_LABYRINTH
- || gridc == DNGN_ENTER_PANDEMONIUM
- || gridc == DNGN_EXIT_PANDEMONIUM
- || gridc == DNGN_TRANSIT_PANDEMONIUM);
-}
-
-/*
- * Returns true if the given dungeon feature can be considered a stair.
- */
-bool is_travelable_stair(unsigned gridc)
-{
- switch (gridc)
- {
- case DNGN_ENTER_HELL:
- case DNGN_STONE_STAIRS_DOWN_I:
- case DNGN_STONE_STAIRS_DOWN_II:
- case DNGN_STONE_STAIRS_DOWN_III:
- case DNGN_ROCK_STAIRS_DOWN:
- case DNGN_STONE_STAIRS_UP_I:
- case DNGN_STONE_STAIRS_UP_II:
- case DNGN_STONE_STAIRS_UP_III:
- case DNGN_ROCK_STAIRS_UP:
- case DNGN_ENTER_DIS:
- case DNGN_ENTER_GEHENNA:
- case DNGN_ENTER_COCYTUS:
- case DNGN_ENTER_TARTARUS:
- case DNGN_ENTER_ORCISH_MINES:
- case DNGN_ENTER_HIVE:
- case DNGN_ENTER_LAIR:
- case DNGN_ENTER_SLIME_PITS:
- case DNGN_ENTER_VAULTS:
- case DNGN_ENTER_CRYPT:
- case DNGN_ENTER_HALL_OF_BLADES:
- case DNGN_ENTER_ZOT:
- case DNGN_ENTER_TEMPLE:
- case DNGN_ENTER_SNAKE_PIT:
- case DNGN_ENTER_ELVEN_HALLS:
- case DNGN_ENTER_TOMB:
- case DNGN_ENTER_SWAMP:
- case DNGN_RETURN_FROM_ORCISH_MINES:
- case DNGN_RETURN_FROM_HIVE:
- case DNGN_RETURN_FROM_LAIR:
- case DNGN_RETURN_FROM_SLIME_PITS:
- case DNGN_RETURN_FROM_VAULTS:
- case DNGN_RETURN_FROM_CRYPT:
- case DNGN_RETURN_FROM_HALL_OF_BLADES:
- case DNGN_RETURN_FROM_ZOT:
- case DNGN_RETURN_FROM_TEMPLE:
- case DNGN_RETURN_FROM_SNAKE_PIT:
- case DNGN_RETURN_FROM_ELVEN_HALLS:
- case DNGN_RETURN_FROM_TOMB:
- case DNGN_RETURN_FROM_SWAMP:
- return true;
- default:
- return false;
- }
-}
-
-#define ES_item (Options.explore_stop & ES_ITEM)
-#define ES_shop (Options.explore_stop & ES_SHOP)
-#define ES_stair (Options.explore_stop & ES_STAIR)
-#define ES_altar (Options.explore_stop & ES_ALTAR)
-
-/*
- * Given a square that has just become visible during explore, returns true
- * if the player might consider the square worth stopping explore for.
- */
-static bool is_interesting_square(int x, int y)
-{
- if (ES_item && igrd[x + 1][y + 1] != NON_ITEM)
- return true;
-
- unsigned char grid = grd[x + 1][y + 1];
- return (ES_shop && grid == DNGN_ENTER_SHOP)
- || (ES_stair && is_stair(grid))
- || (ES_altar && is_altar(grid)
- && you.where_are_you != BRANCH_ECUMENICAL_TEMPLE);
-}
-
-static void userdef_run_stoprunning_hook(void)
-{
-#ifdef CLUA_BINDINGS
- if (you.running)
- clua.callfn("ch_stop_running", "s", run_mode_name(you.running));
-#endif
-}
-
-static void userdef_run_startrunning_hook(void)
-{
-#ifdef CLUA_BINDINGS
- if (you.running)
- clua.callfn("ch_start_running", "s", run_mode_name(you.running));
-#endif
-}
-
-/*
- * Stops shift+running and all forms of travel.
- */
-void stop_running(void)
-{
- userdef_run_stoprunning_hook();
- you.running = 0;
-}
-
-bool is_resting( void )
-{
- return (you.running > 0 && !you.run_x && !you.run_y);
-}
-
-void start_running(void)
-{
- userdef_run_startrunning_hook();
-}
-
-/*
- * Top-level travel control (called from input() in acr.cc).
- *
- * travel() is responsible for making the individual moves that constitute
- * (interlevel) travel and explore and deciding when travel and explore
- * end.
- *
- * Don't call travel() if you.running >= 0.
- */
-void travel(int *keyin, char *move_x, char *move_y)
-{
- *keyin = 128;
-
- // Abort travel/explore if you're confused or a key was pressed.
- if (kbhit() || you.conf)
- {
- stop_running();
- *keyin = 0;
- if (Options.travel_delay == -1)
- redraw_screen();
- return ;
- }
-
- if (Options.explore_stop && you.running == RUN_EXPLORE)
- {
- // Scan through the shadow map, compare it with the actual map, and if
- // there are any squares of the shadow map that have just been
- // discovered and contain an item, or have an interesting dungeon
- // feature, stop exploring.
- for (int y = 0; y < GYM - 1; ++y)
- {
- for (int x = 0; x < GXM - 1; ++x)
- {
- if (!is_player_mapped(mapshadow[x][y])
- && is_player_mapped((unsigned char) env.map[x][y])
- && is_interesting_square(x, y))
- {
- stop_running();
- y = GYM;
- break;
- }
- }
- }
- copy(env.map, mapshadow);
- }
-
- if (you.running == RUN_EXPLORE)
- {
- // Exploring
- you.run_x = 0;
- find_travel_pos(you.x_pos, you.y_pos, NULL, NULL);
- // No place to go?
- if (!you.run_x)
- stop_running();
- }
-
- if (you.running == RUN_INTERLEVEL && !you.run_x)
- {
- // Interlevel travel. Since you.run_x is zero, we've either just
- // initiated travel, or we've just climbed or descended a staircase,
- // and we need to figure out where to travel to next.
- if (!find_transtravel_square(travel_target) || !you.run_x)
- stop_running();
- }
-
- if (you.running < 0)
- {
- // Remember what run-mode we were in so that we can resume explore/
- // interlevel travel correctly.
- int runmode = you.running;
-
- // Get the next step to make. If the travel command can't find a route,
- // we turn off travel (find_travel_pos does that automatically).
- find_travel_pos(you.x_pos, you.y_pos, move_x, move_y);
-
- if (!*move_x && !*move_y)
- {
- // If we've reached the square we were traveling towards, travel
- // should stop if this is simple travel. If we're exploring, we
- // should continue doing so (explore has its own end condition
- // upstairs); if we're traveling between levels and we've reached
- // our travel target, we're on a staircase and should take it.
- if (you.x_pos == you.run_x && you.y_pos == you.run_y)
- {
- if (runmode == RUN_EXPLORE)
- you.running = RUN_EXPLORE; // Turn explore back on
-
- // For interlevel travel, we'll want to take the stairs unless
- // the interlevel travel specified a destination square and
- // we've reached that destination square.
- else if (runmode == RUN_INTERLEVEL
- && (travel_target.pos.x != you.x_pos
- || travel_target.pos.y != you.y_pos
- || travel_target.id !=
- level_id::get_current_level_id()))
- {
- if (last_stair.depth != -1
- && last_stair == level_id::get_current_level_id())
- {
- // We're trying to take the same stairs again. Baaad.
-
- // We don't directly call stop_running() because
- // you.running is probably 0, and stop_running() won't
- // notify Lua hooks if you.running == 0.
- you.running = runmode;
- stop_running();
- return;
- }
- you.running = RUN_INTERLEVEL;
- *keyin = trans_negotiate_stairs();
-
- // If, for some reason, we fail to use the stairs, we
- // need to make sure we don't go into an infinite loop
- // trying to take it again and again. We'll check
- // last_stair before attempting to take stairs again.
- last_stair = level_id::get_current_level_id();
-
- // This is important, else we'll probably stop traveling
- // the moment we clear the stairs. That's because the
- // (run_x, run_y) destination will no longer be valid on
- // the new level. Setting run_x to zero forces us to
- // recalculate our travel target next turn (see previous
- // if block).
- you.run_x = you.run_y = 0;
- }
- else
- {
- you.running = runmode;
- stop_running();
- }
- }
- else
- {
- you.running = runmode;
- stop_running();
- }
- }
- else if (Options.travel_delay > 0)
- delay(Options.travel_delay);
- }
-
- if (!you.running && Options.travel_delay == -1)
- redraw_screen();
-}
-
-/*
- * The travel algorithm is based on the NetHack travel code written by Warwick
- * Allison - used with his permission.
- */
-void find_travel_pos(int youx, int youy,
- char *move_x, char *move_y,
- std::vector<coord_def>* features)
-{
- init_terrain_check();
-
- int start_x = you.run_x, start_y = you.run_y;
- int dest_x = youx, dest_y = youy;
- bool floodout = false;
- unsigned char feature;
-#ifdef STASH_TRACKING
- LevelStashes *lev = features? stashes.find_current_level() : NULL;
-#endif
-
- // Normally we start from the destination and floodfill outwards, looking
- // for the character's current position. If we're merely trying to populate
- // the point_distance array (or exploring), we'll want to start from the
- // character's current position and fill outwards
- if (!move_x || !move_y)
- {
- start_x = youx;
- start_y = youy;
-
- dest_x = dest_y = -1;
-
- floodout = true;
- }
-
- // Abort run if we're trying to go someplace evil
- if (dest_x != -1 && !is_travel_ok(start_x, start_y, false) &&
- !is_trap(start_x, start_y))
- {
- you.running = 0;
- return ;
- }
-
- // Abort run if we're going nowhere.
- if (start_x == dest_x && start_y == dest_y)
- {
- you.running = 0;
- return ;
- }
-
- // How many points are we currently considering? We start off with just one
- // point, and spread outwards like a flood-filler.
- int points = 1;
-
- // How many points we'll consider next iteration.
- int next_iter_points = 0;
-
- // How far we've traveled from (start_x, start_y), in moves (a diagonal move
- // is no longer than an orthogonal move).
- int traveled_distance = 1;
-
- // Which index of the circumference array are we currently looking at?
- int circ_index = 0;
-
- // The circumference points of the floodfilled area, for this iteration
- // and the next (this iteration's points being circ_index amd the next one's
- // being !circ_index).
- static FixedVector<coord_def, GXM * GYM> circumference[2];
-
- // Coordinates of all discovered traps. If we're exploring instead of
- // travelling, we'll reseed from these points after we've explored the map
- std::vector<coord_def> trap_seeds;
-
- // When set to true, the travel code ignores features, traps and hostile
- // terrain, and simply tries to map contiguous floorspace. Will only be set
- // to true if we're exploring, instead of travelling.
- bool ignore_hostile = false;
-
- // Set the seed point
- circumference[circ_index][0].x = start_x;
- circumference[circ_index][0].y = start_y;
-
- // Zap out previous distances array
- memset(point_distance, 0, sizeof point_distance);
-
- for ( ; points > 0; ++traveled_distance, circ_index = !circ_index,
- points = next_iter_points, next_iter_points = 0)
- {
- for (int i = 0; i < points; ++i)
- {
- int x = circumference[circ_index][i].x,
- y = circumference[circ_index][i].y;
-
- // (x,y) is a known (explored) location - we never put unknown
- // points in the circumference vector, so we don't need to examine
- // the map array, just the grid array.
- feature = grd[x][y];
-
- // If this is a feature that'll take time to travel past, we
- // simulate that extra turn by taking this feature next turn,
- // thereby artificially increasing traveled_distance.
- //
- // Note: I don't know how slow walking through shallow water and
- // opening closed doors is - right now it's considered to have
- // the cost of two normal moves.
- int feat_cost = feature_traverse_cost(feature);
- if (feat_cost > 1
- && point_distance[x][y] > traveled_distance - feat_cost)
- {
- circumference[!circ_index][next_iter_points].x = x;
- circumference[!circ_index][next_iter_points].y = y;
- next_iter_points++;
- continue;
- }
-
- // For each point, we look at all surrounding points. Take them
- // orthogonals first so that the travel path doesn't zigzag all over
- // the map. Note the (dir = 1) is intentional assignment.
- for (int dir = 0; dir < 8; (dir += 2) == 8 && (dir = 1))
- {
- int dx = x + Compass[dir].x, dy = y + Compass[dir].y;
-
- if (dx <= 0 || dx >= GXM || dy <= 0 || dy >= GYM) continue;
-
- unsigned char envf = env.map[dx - 1][dy - 1];
-
- if (floodout && you.running == RUN_EXPLORE
- && !is_player_mapped(envf))
- {
- // Setting run_x and run_y here is evil - this function
- // should ideally not modify game state in any way.
- you.run_x = x;
- you.run_y = y;
-
- return;
- }
-
- if ((dx != dest_x || dy != dest_y)
- && !is_travel_ok(dx, dy, ignore_hostile))
- {
- // This point is not okay to travel on, but if this is a
- // trap, we'll want to put it on the feature vector anyway.
- if (is_reseedable(dx, dy)
- && !point_distance[dx][dy]
- && (dx != start_x || dy != start_y))
- {
- if (features)
- {
- coord_def c = { dx, dy };
- if (is_trap(dx, dy) || is_exclude_root(dx, dy))
- features->push_back(c);
- trap_seeds.push_back(c);
- }
-
- // Appropriate mystic number. Nobody else should check
- // this number, since this square is unsafe for travel.
- point_distance[dx][dy] =
- is_exclude_root(dx, dy)? PD_EXCLUDED :
- is_excluded(dx, dy) ? PD_EXCLUDED_RADIUS :
- PD_TRAP;
- }
- continue;
- }
-
- if (dx == dest_x && dy == dest_y)
- {
- // Hallelujah, we're home!
- if (is_safe(x, y) && move_x && move_y)
- {
- *move_x = sgn(x - dest_x);
- *move_y = sgn(y - dest_y);
- }
- return ;
- }
- else if (!point_distance[dx][dy])
- {
- // This point is going to be on the agenda for the next
- // iteration
- circumference[!circ_index][next_iter_points].x = dx;
- circumference[!circ_index][next_iter_points].y = dy;
- next_iter_points++;
-
- point_distance[dx][dy] = traveled_distance;
-
- // Negative distances here so that show_map can colour
- // the map differently for these squares.
- if (ignore_hostile)
- {
- point_distance[dx][dy] = -point_distance[dx][dy];
- if (is_exclude_root(dx, dy))
- point_distance[dx][dy] = PD_EXCLUDED;
- else if (is_excluded(dx, dy))
- point_distance[dx][dy] = PD_EXCLUDED_RADIUS;
- }
-
- feature = grd[dx][dy];
- if (features && !ignore_hostile
- && ((feature != DNGN_FLOOR
- && feature != DNGN_SHALLOW_WATER
- && feature != DNGN_DEEP_WATER
- && feature != DNGN_LAVA)
- || is_waypoint(dx, dy)
-#ifdef STASH_TRACKING
- || is_stash(lev, dx, dy)
-#endif
- )
- && (dx != start_x || dy != start_y))
- {
- coord_def c = { dx, dy };
- features->push_back(c);
- }
-
- if (features && is_exclude_root(dx, dy) && dx != start_x
- && dy != start_y)
- {
- coord_def c = { dx, dy };
- features->push_back(c);
- }
- }
- } // for (dir = 0; dir < 8 ...
- } // for (i = 0; i < points ...
-
- if (!next_iter_points && features && !move_x && !ignore_hostile
- && trap_seeds.size())
- {
- // Reseed here
- for (unsigned i = 0; i < trap_seeds.size(); ++i)
- circumference[!circ_index][i] = trap_seeds[i];
- next_iter_points = trap_seeds.size();
- ignore_hostile = true;
- }
- } // for ( ; points > 0 ...
-}
-
-// Mappings of which branches spring from which other branches, essential to
-// walk backwards up the tree. Yes, this is a horrible abuse of coord_def.
-static coord_def branch_backout[] =
-{
- { BRANCH_SWAMP, BRANCH_LAIR },
- { BRANCH_SLIME_PITS, BRANCH_LAIR },
- { BRANCH_SNAKE_PIT, BRANCH_LAIR },
-
- { BRANCH_HALL_OF_BLADES, BRANCH_VAULTS },
- { BRANCH_CRYPT, BRANCH_VAULTS },
-
- { BRANCH_TOMB, BRANCH_CRYPT },
-
- { BRANCH_ELVEN_HALLS, BRANCH_ORCISH_MINES },
-
- { BRANCH_ORCISH_MINES, BRANCH_MAIN_DUNGEON },
- { BRANCH_HIVE, BRANCH_MAIN_DUNGEON },
- { BRANCH_LAIR, BRANCH_MAIN_DUNGEON },
- { BRANCH_VAULTS, BRANCH_MAIN_DUNGEON },
- { BRANCH_HALL_OF_ZOT, BRANCH_MAIN_DUNGEON },
- { BRANCH_ECUMENICAL_TEMPLE, BRANCH_MAIN_DUNGEON },
-};
-
-/*
- * Given a branch id, returns the parent branch. If the branch id is not found,
- * returns BRANCH_MAIN_DUNGEON.
- */
-unsigned char find_parent_branch(unsigned char br)
-{
- for (unsigned i = 0;
- i < sizeof(branch_backout) / sizeof(branch_backout[0]);
- i++)
- {
- if (branch_backout[i].x == br)
- return (unsigned char) branch_backout[i].y;
- }
- return 0;
-}
-
-extern FixedVector<char, MAX_BRANCHES> stair_level;
-
-void find_parent_branch(unsigned char br, int depth,
- unsigned char *pb, int *pd)
-{
- int lev = stair_level[br];
- if (lev <= 0)
- {
- *pb = 0;
- *pd = 0; // Check depth before using *pb.
- return ;
- }
-
- *pb = find_parent_branch(br);
- *pd = subdungeon_depth(*pb, lev);
-}
-
-// Appends the passed in branch/depth to the given vector, then attempts to
-// repeat the operation with the parent branch of the given branch.
-//
-// As an example of what it does, assume this dungeon structure
-// Stairs to lair on D:11
-// Stairs to snake pit on lair:5
-//
-// If level 3 of the snake pit is the level we want to track back from,
-// we'd call trackback(vec, BRANCH_SNAKE_PIT, 3), and the resulting vector will
-// look like:
-// { BRANCH_SNAKE_PIT, 3 }, { BRANCH_LAIR, 5 }, { BRANCH_MAIN_DUNGEON, 11 }
-// (Assuming, of course, that the vector started out empty.)
-//
-void trackback(std::vector<level_id> &vec,
- unsigned char branch, int subdepth)
-{
- if (subdepth < 1 || subdepth > MAX_LEVELS) return;
-
- level_id lid( branch, subdepth );
- vec.push_back(lid);
-
- if (branch != BRANCH_MAIN_DUNGEON)
- {
- unsigned char pb;
- int pd;
- find_parent_branch(branch, subdepth, &pb, &pd);
- if (pd)
- trackback(vec, pb, pd);
- }
-}
-
-void track_intersect(std::vector<level_id> &cur,
- std::vector<level_id> &targ,
- level_id *cx)
-{
- cx->branch = 0;
- cx->depth = -1;
-
- int us = cur.size() - 1, them = targ.size() - 1;
-
- for ( ; us >= 0 && them >= 0; us--, them--)
- {
- if (cur[us].branch != targ[them].branch)
- break;
- }
-
- us++, them++;
-
- if (us < (int) cur.size() && them < (int) targ.size() && us >= 0 &&
- them >= 0)
- *cx = targ[them];
-}
-
-/*
- * Returns the number of stairs the player would need to take to go from
- * the 'first' level to the 'second' level. If there's no obvious route between
- * 'first' and 'second', returns -1. If first == second, returns 0.
- */
-int level_distance(level_id first, level_id second)
-{
- if (first == second) return 0;
-
- std::vector<level_id> fv, sv;
-
- // If in the same branch, easy.
- if (first.branch == second.branch)
- return abs(first.depth - second.depth);
-
- // Figure out the dungeon structure between the two levels.
- trackback(fv, first.branch, first.depth);
- trackback(sv, second.branch, second.depth);
-
- level_id intersect;
- track_intersect(fv, sv, &intersect);
-
- if (intersect.depth == -1) // No common ground?
- return -1;
-
- int distance = 0;
- // If the common branch is not the same as the current branch, we'll
- // have to walk up the branch tree until we get to the common branch.
- while (first.branch != intersect.branch)
- {
- distance += first.depth;
-
- find_parent_branch(first.branch, first.depth,
- &first.branch, &first.depth);
- if (!first.depth)
- return -1;
- }
-
- // Now first.branch == intersect.branch
- distance += abs(first.depth - intersect.depth);
-
- bool ignore_end = true;
- for (int i = sv.size() - 1; i >= 0; --i)
- {
- if (ignore_end)
- {
- if (sv[i].branch == intersect.branch)
- ignore_end = false;
- continue;
- }
- distance += sv[i].depth;
- }
- return distance;
-}
-
-static struct
-{
- const char *branch_name, *full_name;
- char hotkey;
-} branches [] =
-{
- { "Dungeon", "the Main Dungeon", 'D' },
- { "Dis", "Dis", 'I' },
- { "Gehenna", "Gehenna", 'W' },
- { "Hell", "Hell", 'U' },
- { "Cocytus", "Cocytus", 'X' },
- { "Tartarus", "Tartarus", 'Y' },
- { "Inferno", "", 'R' },
- { "The Pit", "", '0' },
- { "------------", "", '-' },
- { "------------", "", '-' },
- { "Orcish Mines", "the Orcish Mines", 'O' },
- { "Hive", "the Hive", 'H' },
- { "Lair", "the Lair", 'L' },
- { "Slime Pits", "the Slime Pits", 'M' },
- { "Vaults", "the Vaults", 'V' },
- { "Crypt", "the Crypt", 'C' },
- { "Hall of Blades", "the Hall of Blades", 'B' },
- { "Zot", "the Realm of Zot", 'Z' },
- { "Temple", "the Ecumenical Temple", 'T' },
- { "Snake Pit", "the Snake Pit", 'P' },
- { "Elven Halls", "the Elven Halls", 'E' },
- { "Tomb", "the Tomb", 'G' },
- { "Swamp", "the Swamp", 'S' }
-};
-
-static struct
-{
- const char *abbr;
- unsigned char branch;
-} branch_abbrvs[] =
-{
- { "D", BRANCH_MAIN_DUNGEON },
- { "Dis", BRANCH_DIS },
- { "Geh", BRANCH_GEHENNA },
- { "Hell", BRANCH_VESTIBULE_OF_HELL },
- { "Coc", BRANCH_COCYTUS },
- { "Tar", BRANCH_TARTARUS },
- { "inf", BRANCH_INFERNO },
- { "pit", BRANCH_THE_PIT },
- { "Orc", BRANCH_ORCISH_MINES },
- { "Hive", BRANCH_HIVE },
- { "Lair", BRANCH_LAIR },
- { "Slime", BRANCH_SLIME_PITS },
- { "Vault", BRANCH_VAULTS },
- { "Crypt", BRANCH_CRYPT },
- { "Blades", BRANCH_HALL_OF_BLADES },
- { "Zot", BRANCH_HALL_OF_ZOT },
- { "Temple", BRANCH_ECUMENICAL_TEMPLE },
- { "Snake", BRANCH_SNAKE_PIT },
- { "Elf", BRANCH_ELVEN_HALLS },
- { "Tomb", BRANCH_TOMB },
- { "Swamp", BRANCH_SWAMP },
-};
-
-void set_trans_travel_dest(char *buffer, int maxlen, const level_pos &target)
-{
- if (!buffer) return;
-
- const char *branch = NULL;
- for (unsigned i = 0; i < sizeof(branch_abbrvs) / sizeof(branch_abbrvs[0]);
- ++i)
- {
- if (branch_abbrvs[i].branch == target.id.branch)
- {
- branch = branch_abbrvs[i].abbr;
- break;
- }
- }
-
- if (!branch) return;
-
- unsigned char branch_id = target.id.branch;
- // Show level+depth information and tack on an @(x,y) if the player
- // wants to go to a specific square on the target level. We don't use
- // actual coordinates since that will give away level information we
- // don't want the player to have.
- if (branch_id != BRANCH_ECUMENICAL_TEMPLE
- && branch_id != BRANCH_HALL_OF_BLADES
- && branch_id != BRANCH_VESTIBULE_OF_HELL)
- snprintf(buffer, maxlen, "%s:%d%s", branch, target.id.depth,
- target.pos.x != -1? " @ (x,y)" : "");
- else
- snprintf(buffer, maxlen, "%s%s", branch,
- target.pos.x != -1? " @ (x,y)" : "");
-}
-
-// Returns the level on the given branch that's closest to the player's
-// current location.
-static int get_nearest_level_depth(unsigned char branch)
-{
- int depth = 1;
-
- // Hell needs special treatment, because we can't walk up
- // Hell and its branches to the main dungeon.
- if (branch == BRANCH_MAIN_DUNGEON &&
- (player_in_branch( BRANCH_VESTIBULE_OF_HELL ) ||
- player_in_branch( BRANCH_COCYTUS ) ||
- player_in_branch( BRANCH_TARTARUS ) ||
- player_in_branch( BRANCH_DIS ) ||
- player_in_branch( BRANCH_GEHENNA )))
- return you.hell_exit + 1;
-
- level_id id = level_id::get_current_level_id();
- do
- {
- find_parent_branch(id.branch, id.depth,
- &id.branch, &id.depth);
- if (id.depth && id.branch == branch)
- {
- depth = id.depth;
- break;
- }
- } while (id.depth);
-
- return depth;
-}
-
-static char trans_travel_dest[30];
-
-// Returns true if the player character knows of the existence of the given
-// branch (which would make the branch a valid target for interlevel travel).
-static bool is_known_branch(unsigned char branch)
-{
- // The main dungeon is always known.
- if (branch == BRANCH_MAIN_DUNGEON) return true;
-
- // If we're in the branch, it darn well is known.
- if (you.where_are_you == branch) return true;
-
- // If the overmap knows the stairs to this branch, we know the branch.
- unsigned char par;
- int pdep;
- find_parent_branch(branch, 1, &par, &pdep);
- if (pdep)
- return true;
-
- // Do a brute force search in the travel cache for this branch.
- return travel_cache.is_known_branch(branch);
-
- // Doing this to check for the reachability of a branch is slow enough to
- // be noticeable.
-
- // Ask interlevel travel if it knows how to go there. If it knows how to
- // get (partway) there, return true.
-
- // level_pos pos;
- // pos.id.branch = branch;
- // pos.id.depth = 1;
-
- // return find_transtravel_square(pos, false) != 0;
-}
-
-/*
- * Returns a list of the branches that the player knows the location of the
- * stairs to, in the same order as overmap.cc lists them.
- */
-static std::vector<unsigned char> get_known_branches()
-{
- // Lifted from overmap.cc. XXX: Move this to a better place?
- const unsigned char list_order[] =
- {
- BRANCH_MAIN_DUNGEON,
- BRANCH_ECUMENICAL_TEMPLE,
- BRANCH_ORCISH_MINES, BRANCH_ELVEN_HALLS,
- BRANCH_LAIR, BRANCH_SWAMP, BRANCH_SLIME_PITS, BRANCH_SNAKE_PIT,
- BRANCH_HIVE,
- BRANCH_VAULTS, BRANCH_HALL_OF_BLADES, BRANCH_CRYPT, BRANCH_TOMB,
- BRANCH_VESTIBULE_OF_HELL,
- BRANCH_DIS, BRANCH_GEHENNA, BRANCH_COCYTUS, BRANCH_TARTARUS,
- BRANCH_HALL_OF_ZOT
- };
-
- std::vector<unsigned char> branches;
- for (unsigned i = 0; i < sizeof list_order / sizeof(*list_order); ++i)
- {
- if (is_known_branch(list_order[i]))
- branches.push_back(list_order[i]);
- }
-
- return branches;
-}
-
-static int prompt_travel_branch()
-{
- unsigned char branch = BRANCH_MAIN_DUNGEON; // Default
- std::vector<unsigned char> br = get_known_branches();
-
- // Don't kill the prompt even if the only branch we know is the main dungeon
- // This keeps things consistent for the player.
- if (br.size() < 1) return branch;
-
- bool waypoint_list = false;
- int waycount = travel_cache.get_waypoint_count();
- for ( ; ; )
- {
- char buf[100];
- if (waypoint_list)
- travel_cache.list_waypoints();
- else
- {
- int linec = 0;
- std::string line;
- for (int i = 0, count = br.size(); i < count; ++i, ++linec)
- {
- if (linec == 4)
- {
- linec = 0;
- mpr(line.c_str());
- line = "";
- }
- snprintf(buf, sizeof buf, "(%c) %-14s ", branches[br[i]].hotkey,
- branches[br[i]].branch_name);
- line += buf;
- }
- if (line.length())
- mpr(line.c_str());
- }
-
- char shortcuts[100];
- *shortcuts = 0;
- if (*trans_travel_dest || waycount || waypoint_list)
- {
- strncpy(shortcuts, "(", sizeof shortcuts);
- if (waypoint_list)
- strncat(shortcuts, "[*] lists branches", sizeof shortcuts);
- else if (waycount)
- strncat(shortcuts, "[*] lists waypoints", sizeof shortcuts);
-
- if (*trans_travel_dest)
- {
- char travel_dest[60];
- snprintf(travel_dest, sizeof travel_dest, "[Enter] for %s",
- trans_travel_dest);
- if (waypoint_list || waycount)
- strncat( shortcuts, ", ", sizeof shortcuts);
- strncat(shortcuts, travel_dest, sizeof shortcuts);
- }
- strncat(shortcuts, ") ", sizeof shortcuts);
- }
- snprintf(buf, sizeof buf, "Where do you want to go? %s", shortcuts);
- mpr(buf, MSGCH_PROMPT);
-
- int keyin = get_ch();
- switch (keyin)
- {
- case ESCAPE:
- return (ID_CANCEL);
- case '\n': case '\r':
- return (ID_REPEAT);
- case '<':
- return (ID_UP);
- case '>':
- return (ID_DOWN);
- case '*':
- if (waypoint_list || waycount)
- {
- waypoint_list = !waypoint_list;
- mesclr();
- continue;
- }
- break;
- default:
- // Is this a branch hotkey?
- for (int i = 0, count = br.size(); i < count; ++i)
- {
- if (toupper(keyin) == branches[br[i]].hotkey)
- return (br[i]);
- }
-
- // Possibly a waypoint number?
- if (keyin >= '0' && keyin <= '9')
- return (-1 - (keyin - '0'));
- return (ID_CANCEL);
- }
- }
-}
-
-static int prompt_travel_depth(unsigned char branch)
-{
- // Handle one-level branches by not prompting.
- if (branch == BRANCH_ECUMENICAL_TEMPLE ||
- branch == BRANCH_VESTIBULE_OF_HELL ||
- branch == BRANCH_HALL_OF_BLADES)
- return 1;
-
- char buf[100];
- int depth = get_nearest_level_depth(branch);
-
- snprintf(buf, sizeof buf, "What level of %s do you want to go to? "
- "[default %d] ", branches[branch].full_name, depth);
- mesclr();
- mpr(buf, MSGCH_PROMPT);
-
- if (!cancelable_get_line( buf, sizeof buf ))
- return 0;
-
- if (*buf)
- depth = atoi(buf);
-
- return depth;
-}
-
-static bool is_hell_branch(int branch)
-{
- return branch == BRANCH_DIS || branch == BRANCH_TARTARUS
- || branch == BRANCH_COCYTUS || branch == BRANCH_GEHENNA;
-
-}
-
-static level_pos find_up_level()
-{
- level_id curr = level_id::get_current_level_id();
- curr.depth--;
-
- if (is_hell_branch(curr.branch))
- {
- curr.branch = BRANCH_VESTIBULE_OF_HELL;
- curr.depth = 1;
- return (curr);
- }
-
- if (curr.depth < 1)
- {
- if (curr.branch != BRANCH_MAIN_DUNGEON)
- {
- level_id parent;
- find_parent_branch(curr.branch, curr.depth,
- &parent.branch, &parent.depth);
- if (parent.depth > 0)
- return (parent);
- else if (curr.branch == BRANCH_VESTIBULE_OF_HELL)
- {
- parent.branch = BRANCH_MAIN_DUNGEON;
- parent.depth = you.hell_exit + 1;
- return (parent);
- }
- }
- return level_pos();
- }
-
- return (curr);
-}
-
-static level_pos find_down_level()
-{
- level_id curr = level_id::get_current_level_id();
- curr.depth++;
- return (curr);
-}
-
-static level_pos prompt_translevel_target()
-{
- level_pos target;
- int branch = prompt_travel_branch();
-
- if (branch == ID_CANCEL)
- return (target);
-
- // If user chose to repeat last travel, return that.
- if (branch == ID_REPEAT)
- return (travel_target);
-
- if (branch == ID_UP)
- {
- target = find_up_level();
- if (target.id.depth > -1)
- set_trans_travel_dest(trans_travel_dest, sizeof trans_travel_dest,
- target);
- return (target);
- }
-
- if (branch == ID_DOWN)
- {
- target = find_down_level();
- if (target.id.depth > -1)
- set_trans_travel_dest(trans_travel_dest, sizeof trans_travel_dest,
- target);
- return (target);
- }
-
- if (branch < 0)
- {
- travel_cache.travel_to_waypoint(-branch - 1);
- return target;
- }
-
- target.id.branch = branch;
-
- // User's chosen a branch, so now we ask for a level.
- target.id.depth = prompt_travel_depth(target.id.branch);
-
- if (target.id.depth < 1 || target.id.depth >= MAX_LEVELS)
- target.id.depth = -1;
-
- if (target.id.depth > -1)
- set_trans_travel_dest(trans_travel_dest, sizeof trans_travel_dest,
- target);
-
- return target;
-}
-
-void start_translevel_travel(const level_pos &pos)
-{
- travel_target = pos;
-
- if (pos.id != level_id::get_current_level_id())
- {
- if (!loadlev_populate_stair_distances(pos))
- {
- mpr("Level memory is imperfect, aborting.");
- return ;
- }
- }
- else
- populate_stair_distances(pos);
-
- set_trans_travel_dest(trans_travel_dest, sizeof trans_travel_dest,
- travel_target);
- start_translevel_travel(false);
-}
-
-void start_translevel_travel(bool prompt_for_destination)
-{
- // Update information for this level. We need it even for the prompts, so
- // we can't wait to confirm that the user chose to initiate travel.
- travel_cache.get_level_info(level_id::get_current_level_id()).update();
-
- if (prompt_for_destination)
- {
- // prompt_translevel_target may actually initiate travel directly if
- // the user chose a waypoint instead of a branch + depth. As far as
- // we're concerned, if the target depth is unset, we need to take no
- // further action.
- level_pos target = prompt_translevel_target();
- if (target.id.depth == -1) return;
-
- travel_target = target;
- }
-
- if (level_id::get_current_level_id() == travel_target.id &&
- (travel_target.pos.x == -1 ||
- (travel_target.pos.x == you.x_pos &&
- travel_target.pos.y == you.y_pos)))
- {
- mpr("You're already here!");
- return ;
- }
-
- if (travel_target.id.depth > -1)
- {
- you.running = RUN_INTERLEVEL;
- you.run_x = you.run_y = 0;
- last_stair.depth = -1;
- start_running();
- }
-}
-
-int stair_direction(int stair)
-{
- return ((stair < DNGN_STONE_STAIRS_UP_I
- || stair > DNGN_ROCK_STAIRS_UP)
- && (stair < DNGN_RETURN_FROM_ORCISH_MINES
- || stair > DNGN_RETURN_FROM_SWAMP))
- ? '>' : '<';
-}
-
-int trans_negotiate_stairs()
-{
- return stair_direction(grd[you.x_pos][you.y_pos]);
-}
-
-int absdungeon_depth(unsigned char branch, int subdepth)
-{
- int realdepth = subdepth - 1;
-
- if (branch >= BRANCH_ORCISH_MINES && branch <= BRANCH_SWAMP)
- realdepth = subdepth + you.branch_stairs[branch - 10];
-
- if (branch >= BRANCH_DIS && branch <= BRANCH_THE_PIT)
- realdepth = subdepth + 26;
-
- return realdepth;
-}
-
-int subdungeon_depth(unsigned char branch, int depth)
-{
- int curr_subdungeon_level = depth + 1;
-
- // maybe last part better expresssed as <= PIT {dlb}
- if (branch >= BRANCH_DIS && branch <= BRANCH_THE_PIT)
- curr_subdungeon_level = depth - 26;
-
- /* Remember, must add this to the death_string in ouch */
- if (branch >= BRANCH_ORCISH_MINES && branch <= BRANCH_SWAMP)
- curr_subdungeon_level = depth
- - you.branch_stairs[branch - 10];
-
- return curr_subdungeon_level;
-}
-
-static int target_distance_from(const coord_def &pos)
-{
- for (int i = 0, count = curr_stairs.size(); i < count; ++i)
- if (curr_stairs[i].position == pos)
- return curr_stairs[i].distance;
- return -1;
-}
-
-/*
- * Sets best_stair to the coordinates of the best stair on the player's current
- * level to take to get to the 'target' level. Should be called with 'distance'
- * set to 0, 'stair' set to (you.x_pos, you.y_pos) and 'best_distance' set to
- * -1. 'cur' should be the player's current level.
- *
- * If best_stair remains unchanged when this function returns, there is no
- * travel-safe path between the player's current level and the target level OR
- * the player's current level *is* the target level.
- *
- * This function relies on the point_distance array being correctly populated
- * with a floodout call to find_travel_pos starting from the player's location.
- */
-static int find_transtravel_stair( const level_id &cur,
- const level_pos &target,
- int distance,
- const coord_def &stair,
- level_id &closest_level,
- int &best_level_distance,
- coord_def &best_stair)
-{
- int local_distance = -1;
- level_id player_level = level_id::get_current_level_id();
-
- // Have we reached the target level?
- if (cur == target.id)
- {
- // If there's no target position on the target level, or we're on the
- // target, we're home.
- if (target.pos.x == -1 || target.pos == stair)
- return distance;
-
- // If there *is* a target position, we need to work out our distance
- // from it.
- int deltadist = target_distance_from(stair);
-
- if (deltadist == -1 && cur == player_level)
- {
- // Okay, we don't seem to have a distance available to us, which
- // means we're either (a) not standing on stairs or (b) whoever
- // initiated interlevel travel didn't call
- // populate_stair_distances. Assuming we're not on stairs, that
- // situation can arise only if interlevel travel has been triggered
- // for a location on the same level. If that's the case, we can get
- // the distance off the point_distance matrix.
- deltadist = point_distance[target.pos.x][target.pos.y];
- if (!deltadist &&
- (stair.x != target.pos.x || stair.y != target.pos.y))
- deltadist = -1;
- }
-
- if (deltadist != -1)
- {
- local_distance = distance + deltadist;
-
- // See if this is a degenerate case of interlevel travel:
- // A degenerate case of interlevel travel decays to normal travel;
- // we identify this by checking if:
- // a. The current level is the target level.
- // b. The target square is reachable from the 'current' square.
- // c. The current square is where the player is.
- //
- // Note that even if this *is* degenerate, interlevel travel may
- // still be able to find a shorter route, since it can consider
- // routes that leave and reenter the current level.
- if (player_level == target.id && stair.x == you.x_pos
- && stair.y == you.y_pos)
- best_stair = target.pos;
-
- // The local_distance is already set, but there may actually be
- // stairs we can take that'll get us to the target faster than the
- // direct route, so we also try the stairs.
- }
- }
-
- LevelInfo &li = travel_cache.get_level_info(cur);
- std::vector<stair_info> &stairs = li.get_stairs();
-
- // this_stair being NULL is perfectly acceptable, since we start with
- // coords as the player coords, and the player need not be standing on
- // stairs.
- stair_info *this_stair = li.get_stair(stair);
-
- if (!this_stair && cur != player_level)
- {
- // Whoops, there's no stair in the travel cache for the current
- // position, and we're not on the player's current level (i.e., there
- // certainly *should* be a stair here). Since we can't proceed in any
- // reasonable way, bail out.
- return local_distance;
- }
-
- for (int i = 0, count = stairs.size(); i < count; ++i)
- {
- stair_info &si = stairs[i];
-
- int deltadist = li.distance_between(this_stair, &si);
- if (!this_stair)
- {
- deltadist = point_distance[si.position.x][si.position.y];
- if (!deltadist &&
- (you.x_pos != si.position.x || you.y_pos != si.position.y))
- deltadist = -1;
- }
-
- // deltadist == 0 is legal (if this_stair is NULL), since the player
- // may be standing on the stairs. If two stairs are disconnected,
- // deltadist has to be negative.
- if (deltadist < 0) continue;
-
- int dist2stair = distance + deltadist;
- if (si.distance == -1 || si.distance > dist2stair)
- {
- si.distance = dist2stair;
-
- dist2stair += Options.travel_stair_cost;
- ++dist2stair; // Account for the cost of taking the stairs
-
- // Already too expensive? Short-circuit.
- if (local_distance != -1 && dist2stair >= local_distance)
- continue;
-
- const level_pos &dest = si.destination;
-
- // We can only short-circuit the stair-following process if we
- // have no exact target location. If there *is* an exact target
- // location, we can't follow stairs for which we have incomplete
- // information.
- if (target.pos.x == -1 && dest.id == target.id)
- {
- if (local_distance == -1 || local_distance > dist2stair)
- {
- local_distance = dist2stair;
- if (cur == player_level && you.x_pos == stair.x &&
- you.y_pos == stair.y)
- best_stair = si.position;
- }
- continue;
- }
-
- if (dest.id.depth > -1) { // We have a valid level descriptor.
- int dist = level_distance(dest.id, target.id);
- if (dist != -1 &&
- (dist < best_level_distance ||
- best_level_distance == -1))
- {
- best_level_distance = dist;
- closest_level = dest.id;
- }
- }
-
- // If we don't know where these stairs go, we can't take them.
- if (!dest.is_valid()) continue;
-
- // We need to get the stairs at the new location and set the
- // distance on them as well.
- LevelInfo &lo = travel_cache.get_level_info(dest.id);
- stair_info *so = lo.get_stair(dest.pos);
-
- if (so)
- {
- if (so->distance == -1 || so->distance > dist2stair)
- so->distance = dist2stair;
- else
- continue; // We've already been here.
- }
-
- // Okay, take these stairs and keep going.
- int newdist = find_transtravel_stair(dest.id, target,
- dist2stair, dest.pos, closest_level,
- best_level_distance, best_stair);
- if (newdist != -1 &&
- (local_distance == -1 || local_distance > newdist))
- {
- local_distance = newdist;
- if (cur == player_level && you.x_pos == stair.x &&
- you.y_pos == stair.y)
- best_stair = si.position;
- }
- }
- }
- return local_distance;
-}
-
-static bool loadlev_populate_stair_distances(const level_pos &target)
-{
- crawl_environment tmp = env;
- if (!travel_load_map(target.id.branch,
- absdungeon_depth(target.id.branch, target.id.depth)))
- {
- env = tmp;
- return false;
- }
-
- std::vector<coord_def> old_excludes = curr_excludes;
-
- curr_excludes.clear();
- LevelInfo &li = travel_cache.get_level_info(target.id);
- li.set_level_excludes();
-
- populate_stair_distances(target);
-
- env = tmp;
- curr_excludes = old_excludes;
- return !curr_stairs.empty();
-}
-
-static void populate_stair_distances(const level_pos &target)
-{
- // Populate point_distance.
- find_travel_pos(target.pos.x, target.pos.y, NULL, NULL, NULL);
-
- LevelInfo &li = travel_cache.get_level_info(target.id);
- const std::vector<stair_info> &stairs = li.get_stairs();
-
- curr_stairs.clear();
- for (int i = 0, count = stairs.size(); i < count; ++i)
- {
- stair_info si = stairs[i];
- si.distance = point_distance[si.position.x][si.position.y];
- if (!si.distance && target.pos != si.position)
- si.distance = -1;
- if (si.distance < -1)
- si.distance = -1;
-
- curr_stairs.push_back(si);
- }
-}
-
-static int find_transtravel_square(const level_pos &target, bool verbose)
-{
- level_id current = level_id::get_current_level_id();
-
- coord_def best_stair = { -1, -1 };
- coord_def cur_stair = { you.x_pos, you.y_pos };
- level_id closest_level;
- int best_level_distance = -1;
- travel_cache.reset_distances();
-
- find_travel_pos(you.x_pos, you.y_pos, NULL, NULL, NULL);
-
- find_transtravel_stair(current, target,
- 0, cur_stair, closest_level,
- best_level_distance, best_stair);
-
- if (best_stair.x != -1 && best_stair.y != -1)
- {
- you.run_x = best_stair.x;
- you.run_y = best_stair.y;
- return 1;
- }
- else if (best_level_distance != -1 && closest_level != current
- && target.pos.x == -1)
- {
- int current_dist = level_distance(current, target.id);
- level_pos newlev;
- newlev.id = closest_level;
- if (current_dist == -1 || best_level_distance < current_dist)
- return find_transtravel_square(newlev, verbose);
- }
-
- if (verbose && target.id != current)
- mpr("Sorry, I don't know how to get there.");
- return 0;
-}
-
-void start_travel(int x, int y)
-{
- // Redundant target?
- if (x == you.x_pos && y == you.y_pos) return ;
-
- // Start running
- you.running = RUN_TRAVEL;
- you.run_x = x;
- you.run_y = y;
-
- // Remember where we're going so we can easily go back if interrupted.
- you.travel_x = x;
- you.travel_y = y;
-
- // Check whether we can get to the square.
- find_travel_pos(you.x_pos, you.y_pos, NULL, NULL, NULL);
-
- if (point_distance[x][y] == 0 &&
- (x != you.x_pos || you.run_y != you.y_pos) &&
- is_travel_ok(x, y, false))
- {
- // We'll need interlevel travel to get here.
- travel_target.id = level_id::get_current_level_id();
- travel_target.pos.x = x;
- travel_target.pos.y = y;
-
- you.running = RUN_INTERLEVEL;
- you.run_x = you.run_y = 0;
- last_stair.depth = -1;
-
- // We need the distance of the target from the various stairs around.
- populate_stair_distances(travel_target);
-
- set_trans_travel_dest(trans_travel_dest, sizeof trans_travel_dest,
- travel_target);
- }
-
- start_running();
-}
-
-void start_explore()
-{
- you.running = RUN_EXPLORE;
- if (Options.explore_stop)
- {
- // Clone shadow array off map
- copy(env.map, mapshadow);
- }
- start_running();
-}
-
-/*
- * Given a feature vector, arranges the features in the order that the player
- * is most likely to be interested in. Currently, the only thing it does is to
- * put altars of the player's religion at the front of the list.
- */
-void arrange_features(std::vector<coord_def> &features)
-{
- for (int i = 0, count = features.size(); i < count; ++i)
- {
- if (is_player_altar(features[i]))
- {
- int place = i;
- // Shuffle this altar as far up the list as possible.
- for (int j = place - 1; j >= 0; --j)
- {
- if (is_altar(features[j]))
- {
- if (is_player_altar(features[j]))
- break;
-
- coord_def temp = features[j];
- features[j] = features[place];
- features[place] = temp;
-
- place = j;
- }
- }
- }
- }
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Interlevel travel classes
-
-static void writeCoord(FILE *file, const coord_def &pos)
-{
- writeShort(file, pos.x);
- writeShort(file, pos.y);
-}
-
-static void readCoord(FILE *file, coord_def &pos)
-{
- pos.x = readShort(file);
- pos.y = readShort(file);
-}
-
-level_id level_id::get_current_level_id()
-{
- level_id id;
- id.branch = you.where_are_you;
- id.depth = subdungeon_depth(you.where_are_you, you.your_level);
-
- return id;
-}
-
-level_id level_id::get_next_level_id(const coord_def &pos)
-{
- short gridc = grd[pos.x][pos.y];
- level_id id = get_current_level_id();
-
- switch (gridc)
- {
- case DNGN_STONE_STAIRS_DOWN_I: case DNGN_STONE_STAIRS_DOWN_II:
- case DNGN_STONE_STAIRS_DOWN_III: case DNGN_ROCK_STAIRS_DOWN:
- id.depth++;
- break;
- case DNGN_STONE_STAIRS_UP_I: case DNGN_STONE_STAIRS_UP_II:
- case DNGN_STONE_STAIRS_UP_III: case DNGN_ROCK_STAIRS_UP:
- id.depth--;
- break;
- case DNGN_ENTER_HELL:
- id.branch = BRANCH_VESTIBULE_OF_HELL;
- id.depth = 1;
- break;
- case DNGN_ENTER_DIS:
- id.branch = BRANCH_DIS;
- id.depth = 1;
- break;
- case DNGN_ENTER_GEHENNA:
- id.branch = BRANCH_GEHENNA;
- id.depth = 1;
- break;
- case DNGN_ENTER_COCYTUS:
- id.branch = BRANCH_COCYTUS;
- id.depth = 1;
- break;
- case DNGN_ENTER_TARTARUS:
- id.branch = BRANCH_TARTARUS;
- id.depth = 1;
- break;
- case DNGN_ENTER_ORCISH_MINES:
- id.branch = BRANCH_ORCISH_MINES;
- id.depth = 1;
- break;
- case DNGN_ENTER_HIVE:
- id.branch = BRANCH_HIVE;
- id.depth = 1;
- break;
- case DNGN_ENTER_LAIR:
- id.branch = BRANCH_LAIR;
- id.depth = 1;
- break;
- case DNGN_ENTER_SLIME_PITS:
- id.branch = BRANCH_SLIME_PITS;
- id.depth = 1;
- break;
- case DNGN_ENTER_VAULTS:
- id.branch = BRANCH_VAULTS;
- id.depth = 1;
- break;
- case DNGN_ENTER_CRYPT:
- id.branch = BRANCH_CRYPT;
- id.depth = 1;
- break;
- case DNGN_ENTER_HALL_OF_BLADES:
- id.branch = BRANCH_HALL_OF_BLADES;
- id.depth = 1;
- break;
- case DNGN_ENTER_ZOT:
- id.branch = BRANCH_HALL_OF_ZOT;
- id.depth = 1;
- break;
- case DNGN_ENTER_TEMPLE:
- id.branch = BRANCH_ECUMENICAL_TEMPLE;
- id.depth = 1;
- break;
- case DNGN_ENTER_SNAKE_PIT:
- id.branch = BRANCH_SNAKE_PIT;
- id.depth = 1;
- break;
- case DNGN_ENTER_ELVEN_HALLS:
- id.branch = BRANCH_ELVEN_HALLS;
- id.depth = 1;
- break;
- case DNGN_ENTER_TOMB:
- id.branch = BRANCH_TOMB;
- id.depth = 1;
- break;
- case DNGN_ENTER_SWAMP:
- id.branch = BRANCH_SWAMP;
- id.depth = 1;
- break;
- case DNGN_RETURN_FROM_ORCISH_MINES: case DNGN_RETURN_FROM_HIVE:
- case DNGN_RETURN_FROM_LAIR: case DNGN_RETURN_FROM_SLIME_PITS:
- case DNGN_RETURN_FROM_VAULTS: case DNGN_RETURN_FROM_CRYPT:
- case DNGN_RETURN_FROM_HALL_OF_BLADES: case DNGN_RETURN_FROM_ZOT:
- case DNGN_RETURN_FROM_TEMPLE: case DNGN_RETURN_FROM_SNAKE_PIT:
- case DNGN_RETURN_FROM_ELVEN_HALLS: case DNGN_RETURN_FROM_TOMB:
- case DNGN_RETURN_FROM_SWAMP:
- find_parent_branch(id.branch, id.depth, &id.branch, &id.depth);
- if (!id.depth)
- {
- id.branch = find_parent_branch(you.where_are_you);
- id.depth = -1;
- }
- break;
- }
- return id;
-}
-
-void level_id::save(FILE *file) const
-{
- writeByte(file, branch);
- writeShort(file, depth);
-}
-
-void level_id::load(FILE *file)
-{
- branch = readByte(file);
- depth = readShort(file);
-}
-
-void level_pos::save(FILE *file) const
-{
- id.save(file);
- writeCoord(file, pos);
-}
-
-void level_pos::load(FILE *file)
-{
- id.load(file);
- readCoord(file, pos);
-}
-
-void stair_info::save(FILE *file) const
-{
- writeCoord(file, position);
- destination.save(file);
- writeByte(file, guessed_pos? 1 : 0);
-}
-
-void stair_info::load(FILE *file)
-{
- readCoord(file, position);
- destination.load(file);
- guessed_pos = readByte(file) != 0;
-}
-
-LevelInfo::LevelInfo(const LevelInfo &other)
-{
- stairs = other.stairs;
- excludes = other.excludes;
- int sz = stairs.size() * stairs.size();
- stair_distances = new short [ sz ];
- if (other.stair_distances)
- memcpy(stair_distances, other.stair_distances, sz * sizeof(int));
-}
-
-const LevelInfo &LevelInfo::operator = (const LevelInfo &other)
-{
- if (&other == this)
- return *this;
-
- stairs = other.stairs;
- excludes = other.excludes;
- int sz = stairs.size() * stairs.size();
- delete [] stair_distances;
- stair_distances = new short [ sz ];
- if (other.stair_distances)
- memcpy(stair_distances, other.stair_distances, sz * sizeof(short));
- return *this;
-}
-
-LevelInfo::~LevelInfo()
-{
- delete [] stair_distances;
-}
-
-void LevelInfo::set_level_excludes()
-{
- curr_excludes = excludes;
-}
-
-void LevelInfo::update()
-{
- // We need to update all stair information and distances on this level.
- update_excludes();
-
- // First, set excludes, so that stair distances will be correctly populated.
- excludes = curr_excludes;
-
- // First, we get all known stairs
- std::vector<coord_def> stair_positions;
- get_stairs(stair_positions);
-
- // Make sure our stair list is correct.
- correct_stair_list(stair_positions);
-
- update_stair_distances();
-}
-
-void LevelInfo::update_stair_distances()
-{
- // Now we update distances for all the stairs, relative to all other
- // stairs.
- for (int s = 0, end = stairs.size(); s < end; ++s)
- {
- // For each stair, we need to ask travel to populate the distance
- // array.
- find_travel_pos(stairs[s].position.x, stairs[s].position.y,
- NULL, NULL, NULL);
-
- for (int other = 0; other < end; ++other)
- {
- int ox = stairs[other].position.x,
- oy = stairs[other].position.y;
- int dist = point_distance[ox][oy];
-
- // Note dist == 0 is illegal because we can't have two stairs on
- // the same square.
- if (dist <= 0) dist = -1;
- stair_distances[ s * stairs.size() + other ] = dist;
- stair_distances[ other * stairs.size() + s ] = dist;
- }
- }
-}
-
-void LevelInfo::update_stair(int x, int y, const level_pos &p, bool guess)
-{
- stair_info *si = get_stair(x, y);
-
- // What 'guess' signifies: whenever you take a stair from A to B, the
- // travel code knows that the stair takes you from A->B. In that case,
- // update_stair() is called with guess == false.
- //
- // Unfortunately, Crawl doesn't guarantee that A->B implies B->A, but the
- // travel code has to assume that anyway (because that's what the player
- // will expect), and call update_stair() again with guess == true.
- //
- // The idea of using 'guess' is that we'll update the stair's destination
- // with a guess only if we know that the currently set destination is
- // itself a guess.
- //
- if (si && (si->guessed_pos || !guess))
- {
- si->destination = p;
- si->guessed_pos = guess;
-
- if (!guess && p.id.branch == BRANCH_VESTIBULE_OF_HELL
- && id.branch == BRANCH_MAIN_DUNGEON)
- travel_hell_entry = p;
- }
-}
-
-stair_info *LevelInfo::get_stair(int x, int y)
-{
- coord_def c = { x, y };
- return get_stair(c);
-}
-
-stair_info *LevelInfo::get_stair(const coord_def &pos)
-{
- int index = get_stair_index(pos);
- return index != -1? &stairs[index] : NULL;
-}
-
-int LevelInfo::get_stair_index(const coord_def &pos) const
-{
- for (int i = stairs.size() - 1; i >= 0; --i)
- {
- if (stairs[i].position == pos)
- return i;
- }
- return -1;
-}
-
-void LevelInfo::add_waypoint(const coord_def &pos)
-{
- if (pos.x < 0 || pos.y < 0) return;
-
- // First, make sure we don't already have this position in our stair list.
- for (int i = 0, sz = stairs.size(); i < sz; ++i)
- if (stairs[i].position == pos)
- return;
-
- stair_info si;
- si.position = pos;
- si.destination.id.depth = -2; // Magic number for waypoints.
-
- stairs.push_back(si);
-
- delete [] stair_distances;
- stair_distances = new short [ stairs.size() * stairs.size() ];
-
- update_stair_distances();
-}
-
-void LevelInfo::remove_waypoint(const coord_def &pos)
-{
- for (std::vector<stair_info>::iterator i = stairs.begin();
- i != stairs.end(); ++i)
- {
- if (i->position == pos && i->destination.id.depth == -2)
- {
- stairs.erase(i);
- break;
- }
- }
-
- delete [] stair_distances;
- stair_distances = new short [ stairs.size() * stairs.size() ];
-
- update_stair_distances();
-}
-
-void LevelInfo::correct_stair_list(const std::vector<coord_def> &s)
-{
- // If we have a waypoint on this level, we'll always delete stair_distances
- delete [] stair_distances;
- stair_distances = NULL;
-
- // First we kill any stairs in 'stairs' that aren't there in 's'.
- for (std::vector<stair_info>::iterator i = stairs.begin();
- i != stairs.end(); ++i)
- {
- // Waypoints are not stairs, so we skip them.
- if (i->destination.id.depth == -2) continue;
-
- bool found = false;
- for (int j = s.size() - 1; j >= 0; --j)
- {
- if (s[j] == i->position)
- {
- found = true;
- break;
- }
- }
-
- if (!found)
- stairs.erase(i--);
- }
-
- // For each stair in 's', make sure we have a corresponding stair
- // in 'stairs'.
- for (int i = 0, sz = s.size(); i < sz; ++i)
- {
- bool found = false;
- for (int j = stairs.size() - 1; j >= 0; --j)
- {
- if (s[i] == stairs[j].position)
- {
- found = true;
- break;
- }
- }
-
- if (!found)
- {
- stair_info si;
- si.position = s[i];
- si.destination.id = level_id::get_next_level_id(s[i]);
- if (si.destination.id.branch == BRANCH_VESTIBULE_OF_HELL
- && id.branch == BRANCH_MAIN_DUNGEON
- && travel_hell_entry.is_valid())
- si.destination = travel_hell_entry;
-
- // We don't know where on the next level these stairs go to, but
- // that can't be helped. That information will have to be filled
- // in whenever the player takes these stairs.
- stairs.push_back(si);
- }
- }
-
- stair_distances = new short [ stairs.size() * stairs.size() ];
-}
-
-int LevelInfo::distance_between(const stair_info *s1, const stair_info *s2)
- const
-{
- if (!s1 || !s2) return 0;
- if (s1 == s2) return 0;
-
- int i1 = get_stair_index(s1->position),
- i2 = get_stair_index(s2->position);
- if (i1 == -1 || i2 == -1) return 0;
-
- return stair_distances[ i1 * stairs.size() + i2 ];
-}
-
-void LevelInfo::get_stairs(std::vector<coord_def> &st)
-{
- // These are env map coords, not grid coordinates.
- for (int y = 0; y < GYM - 1; ++y)
- {
- for (int x = 0; x < GXM - 1; ++x)
- {
- unsigned char grid = grd[x + 1][y + 1];
- unsigned char envc = (unsigned char) env.map[x][y];
-
- if (envc && is_travelable_stair(grid))
- {
- // Convert to grid coords, because that's what we use
- // everywhere else.
- coord_def stair = { x + 1, y + 1 };
- st.push_back(stair);
- }
- }
- }
-}
-
-void LevelInfo::reset_distances()
-{
- for (int i = 0, count = stairs.size(); i < count; ++i)
- {
- stairs[i].reset_distance();
- }
-}
-
-bool LevelInfo::is_known_branch(unsigned char branch) const
-{
- for (int i = 0, count = stairs.size(); i < count; ++i)
- {
- if (stairs[i].destination.id.branch == branch)
- return true;
- }
- return false;
-}
-
-void LevelInfo::travel_to_waypoint(const coord_def &pos)
-{
- stair_info *target = get_stair(pos);
- if (!target) return;
-
- curr_stairs.clear();
- for (int i = 0, sz = stairs.size(); i < sz; ++i)
- {
- if (stairs[i].destination.id.depth == -2) continue;
-
- stair_info si = stairs[i];
- si.distance = distance_between(target, &stairs[i]);
-
- curr_stairs.push_back(si);
- }
-
- start_translevel_travel(false);
-}
-
-void LevelInfo::save(FILE *file) const
-{
- int stair_count = stairs.size();
- // How many stairs do we know of?
- writeShort(file, stair_count);
- for (int i = 0; i < stair_count; ++i)
- stairs[i].save(file);
-
- if (stair_count)
- {
- // XXX Assert stair_distances != NULL?
- // Save stair distances as short ints.
- for (int i = stair_count * stair_count - 1; i >= 0; --i)
- writeShort(file, stair_distances[i]);
- }
-
- writeShort(file, excludes.size());
- if (excludes.size())
- {
- for (int i = 0, count = excludes.size(); i < count; ++i)
- {
- writeShort(file, excludes[i].x);
- writeShort(file, excludes[i].y);
- }
- }
-}
-
-#define EXCLUDE_LOAD_LIMIT 20
-void LevelInfo::load(FILE *file)
-{
- stairs.clear();
- int stair_count = readShort(file);
- for (int i = 0; i < stair_count; ++i)
- {
- stair_info si;
- si.load(file);
- stairs.push_back(si);
-
- if (id.branch == BRANCH_MAIN_DUNGEON &&
- si.destination.id.branch == BRANCH_VESTIBULE_OF_HELL &&
- !travel_hell_entry.is_valid() &&
- si.destination.is_valid())
- travel_hell_entry = si.destination;
- }
-
- if (stair_count)
- {
- delete [] stair_distances;
- stair_distances = new short [ stair_count * stair_count ];
- for (int i = stair_count * stair_count - 1; i >= 0; --i)
- stair_distances[i] = readShort(file);
- }
-
- excludes.clear();
- int nexcludes = readShort(file);
- if (nexcludes)
- {
- for (int i = 0; i < nexcludes; ++i)
- {
- coord_def c;
- c.x = readShort(file);
- c.y = readShort(file);
- excludes.push_back(c);
- }
- }
-}
-
-void LevelInfo::fixup()
-{
- // The only fixup we do now is for the hell entry.
- if (id.branch != BRANCH_MAIN_DUNGEON || !travel_hell_entry.is_valid())
- return;
- for (int i = 0, count = stairs.size(); i < count; ++i)
- {
- stair_info &si = stairs[i];
- if (si.destination.id.branch == BRANCH_VESTIBULE_OF_HELL
- && !si.destination.is_valid())
- si.destination = travel_hell_entry;
- }
-}
-
-void TravelCache::travel_to_waypoint(int num)
-{
- if (num < 0 || num >= TRAVEL_WAYPOINT_COUNT) return;
- if (waypoints[num].id.depth == -1) return;
-
- travel_target = waypoints[num];
- set_trans_travel_dest(trans_travel_dest, sizeof trans_travel_dest,
- travel_target);
- LevelInfo &li = get_level_info(travel_target.id);
- li.travel_to_waypoint(travel_target.pos);
-}
-
-void TravelCache::list_waypoints() const
-{
- std::string line;
- char dest[30];
- char choice[50];
- int count = 0;
-
- for (int i = 0; i < TRAVEL_WAYPOINT_COUNT; ++i)
- {
- if (waypoints[i].id.depth == -1) continue;
-
- set_trans_travel_dest(dest, sizeof dest, waypoints[i]);
- // All waypoints will have @ (x,y), remove that.
- char *at = strchr(dest, '@');
- if (at)
- *--at = 0;
-
- snprintf(choice, sizeof choice, "(%d) %-8s", i, dest);
- line += choice;
- if (!(++count % 5))
- {
- mpr(line.c_str());
- line = "";
- }
- }
- if (line.length())
- mpr(line.c_str());
-}
-
-unsigned char TravelCache::is_waypoint(const level_pos &lp) const
-{
- for (int i = 0; i < TRAVEL_WAYPOINT_COUNT; ++i)
- {
- if (lp == waypoints[i])
- return '0' + i;
- }
- return 0;
-}
-
-void TravelCache::update_waypoints() const
-{
- level_pos lp;
- lp.id = level_id::get_current_level_id();
-
- memset(curr_waypoints, 0, sizeof curr_waypoints);
- for (lp.pos.x = 1; lp.pos.x < GXM; ++lp.pos.x)
- {
- for (lp.pos.y = 1; lp.pos.y < GYM; ++lp.pos.y)
- {
- unsigned char wpc = is_waypoint(lp);
- if (wpc)
- curr_waypoints[lp.pos.x][lp.pos.y] = wpc;
- }
- }
-}
-
-void TravelCache::add_waypoint(int x, int y)
-{
- if (you.level_type == LEVEL_LABYRINTH || you.level_type == LEVEL_ABYSS
- || you.level_type == LEVEL_PANDEMONIUM)
- {
- mpr("Sorry, you can't set a waypoint here.");
- return;
- }
-
- mesclr();
- if (get_waypoint_count())
- {
- mpr("Existing waypoints");
- list_waypoints();
- }
-
- mpr("Assign waypoint to what number? (0-9) ", MSGCH_PROMPT);
- int keyin = get_ch();
-
- if (keyin < '0' || keyin > '9') return;
-
- int waynum = keyin - '0';
-
- if (waypoints[waynum].is_valid())
- {
- bool unique_waypoint = true;
- for (int i = 0; i < TRAVEL_WAYPOINT_COUNT; ++i)
- {
- if (i == waynum) continue;
- if (waypoints[waynum] == waypoints[i])
- {
- unique_waypoint = false;
- break;
- }
- }
-
- if (unique_waypoint)
- {
- LevelInfo &li = get_level_info(waypoints[waynum].id);
- li.remove_waypoint(waypoints[waynum].pos);
- }
- }
-
- if (x == -1 || y == -1)
- {
- x = you.x_pos;
- y = you.y_pos;
- }
- coord_def pos = { x, y };
- const level_id &lid = level_id::get_current_level_id();
-
- LevelInfo &li = get_level_info(lid);
- li.add_waypoint(pos);
-
- waypoints[waynum].id = lid;
- waypoints[waynum].pos = pos;
-
- update_waypoints();
-}
-
-int TravelCache::get_waypoint_count() const
-{
- int count = 0;
- for (int i = 0; i < TRAVEL_WAYPOINT_COUNT; ++i)
- if (waypoints[i].is_valid())
- count++;
- return count;
-}
-
-void TravelCache::reset_distances()
-{
- std::map<level_id, LevelInfo, level_id::less_than>::iterator i =
- levels.begin();
- for ( ; i != levels.end(); ++i)
- i->second.reset_distances();
-}
-
-bool TravelCache::is_known_branch(unsigned char branch) const
-{
- std::map<level_id, LevelInfo, level_id::less_than>::const_iterator i =
- levels.begin();
- for ( ; i != levels.end(); ++i)
- if (i->second.is_known_branch(branch))
- return true;
- return false;
-}
-
-void TravelCache::save(FILE *file) const
-{
- // Travel cache version information
- writeByte(file, TC_MAJOR_VERSION);
- writeByte(file, TC_MINOR_VERSION);
-
- // How many levels do we have?
- writeShort(file, levels.size());
-
- // Save all the levels we have
- std::map<level_id, LevelInfo, level_id::less_than>::const_iterator i =
- levels.begin();
- for ( ; i != levels.end(); ++i)
- {
- i->first.save(file);
- i->second.save(file);
- }
-
- for (int wp = 0; wp < TRAVEL_WAYPOINT_COUNT; ++wp)
- waypoints[wp].save(file);
-}
-
-void TravelCache::load(FILE *file)
-{
- levels.clear();
-
- // Check version. If not compatible, we just ignore the file altogether.
- unsigned char major = readByte(file),
- minor = readByte(file);
- if (major != TC_MAJOR_VERSION || minor != TC_MINOR_VERSION) return ;
-
- int level_count = readShort(file);
- for (int i = 0; i < level_count; ++i)
- {
- level_id id;
- id.load(file);
- LevelInfo linfo;
- // Must set id before load, or travel_hell_entry will not be
- // correctly set.
- linfo.id = id;
- linfo.load(file);
- levels[id] = linfo;
- }
-
- for (int wp = 0; wp < TRAVEL_WAYPOINT_COUNT; ++wp)
- waypoints[wp].load(file);
-
- fixup_levels();
-}
-
-void TravelCache::set_level_excludes()
-{
- if (can_travel_interlevel())
- get_level_info(level_id::get_current_level_id()).set_level_excludes();
-}
-
-void TravelCache::update()
-{
- if (can_travel_interlevel())
- get_level_info(level_id::get_current_level_id()).update();
- else
- update_excludes();
-}
-
-void TravelCache::fixup_levels()
-{
- std::map<level_id, LevelInfo, level_id::less_than>::iterator i =
- levels.begin();
- for ( ; i != levels.end(); ++i)
- i->second.fixup();
-}
-
-bool can_travel_interlevel()
-{
- return !(you.level_type == LEVEL_LABYRINTH || you.level_type == LEVEL_ABYSS
- || you.level_type == LEVEL_PANDEMONIUM);
-}
diff --git a/stone_soup/crawl-ref/source/travel.h b/stone_soup/crawl-ref/source/travel.h
deleted file mode 100644
index e4478af0fb..0000000000
--- a/stone_soup/crawl-ref/source/travel.h
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * File: travel.cc
- * Summary: Travel stuff
- * Written by: Darshan Shaligram
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- SD Created
- */
-#ifndef TRAVEL_H
-# define TRAVEL_H
-
-# include "externs.h"
-# include <stdio.h>
-# include <string>
-# include <vector>
-# include <map>
-
-/* ***********************************************************************
- * Initialises the travel subsystem.
- *
- * ***********************************************************************
- * called from: initfile (what's a better place to initialise stuff?)
- * *********************************************************************** */
-void initialise_travel();
-void stop_running(void);
-void travel_init_new_level();
-void toggle_exclude(int x, int y);
-void clear_excludes();
-unsigned char is_waypoint(int x, int y);
-void update_excludes();
-bool is_stair(unsigned gridc);
-bool is_travelable_stair(unsigned gridc);
-int stair_direction(int stair_feat);
-bool is_player_mapped(unsigned char envch);
-bool is_resting( void );
-bool can_travel_interlevel();
-
-inline bool is_player_mapped(int grid_x, int grid_y)
-{
- return (is_player_mapped( env.map[grid_x - 1][grid_y - 1] ));
-}
-
-void find_travel_pos(int you_x, int you_y, char *move_x, char *move_y,
- std::vector<coord_def>* coords = NULL);
-
-/* ***********************************************************************
- * Initiates explore - the character runs around the level to map it. Note
- * that the caller has to ensure that the level is mappable before calling
- * start_explore. start_explore may lock up the game on unmappable levels.
- *
- * ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void start_explore();
-
-struct level_pos;
-void start_translevel_travel(const level_pos &pos);
-
-void start_translevel_travel(bool prompt_for_destination = true);
-
-void start_travel(int x, int y);
-
-void travel(int *keyin, char *move_x, char *move_y);
-
-int travel_direction(unsigned char branch, int subdungeondepth);
-
-void prevent_travel_to(const std::string &dungeon_feature_name);
-
-int subdungeon_depth(unsigned char branch, int depth);
-
-int absdungeon_depth(unsigned char branch, int subdepth);
-
-// Sort dungeon features as appropriate.
-void arrange_features(std::vector<coord_def> &features);
-
-// Magic numbers for point_distance:
-
-// This square is a trap
-#define PD_TRAP -42
-
-// The user never wants to travel this square
-#define PD_EXCLUDED -20099
-
-// This square is within LOS radius of an excluded square
-#define PD_EXCLUDED_RADIUS -20100
-
-// This square is a waypoint
-#define PD_WAYPOINT -20200
-
-/* ***********************************************************************
- * Array of points on the map, each value being the distance the character
- * would have to travel to get there. Negative distances imply that the point
- * is a) a trap or hostile terrain or b) only reachable by crossing a trap or
- * hostile terrain.
- * ***********************************************************************
- * referenced in: travel - view
- * *********************************************************************** */
-extern short point_distance[GXM][GYM];
-
-// Possible values of you.running
-enum RUN_MODES
-{
- RUN_TRAVEL = -1, // Classic or Plain Old travel
- RUN_EXPLORE = -2, // Exploring (Ctrl+O)
- RUN_INTERLEVEL = -3 // Interlevel travel (Ctrl+G)
-};
-
-enum EXPLORE_STOP
-{
- ES_NONE = 0,
- ES_ITEM = 1,
- ES_STAIR = 2,
- ES_SHOP = 4,
- ES_ALTAR = 8
-};
-
-////////////////////////////////////////////////////////////////////////////
-// Structs for interlevel travel.
-
-struct level_id
-{
- unsigned char branch; // The branch in which the level is.
- int depth; // What depth (in this branch - starting from 1)
- // this level is.
-
- level_id() : branch(0), depth(-1) { }
-
- level_id(unsigned char br, int dep) : branch(br), depth(dep) { }
-
- // Returns the level_id of the current level.
- static level_id get_current_level_id();
-
- // Returns the level_id of the level that the stair/portal/whatever at
- // 'pos' on the current level leads to.
- static level_id get_next_level_id(const coord_def &pos);
-
- bool operator == ( const level_id &id ) const
- {
- return branch == id.branch && depth == id.depth;
- }
-
- bool operator != ( const level_id &id ) const
- {
- return branch != id.branch || depth != id.depth;
- }
-
- struct less_than
- {
- bool operator () (const level_id &first, const level_id &second) const
- {
- return first.branch < second.branch ||
- (first.branch == second.branch && first.depth < second.depth);
- }
- };
-
- void save(FILE *) const;
- void load(FILE *);
-};
-
-// A position on a particular level.
-struct level_pos
-{
- level_id id;
- coord_def pos; // The grid coordinates on this level.
-
- level_pos() : id(), pos()
- {
- pos.x = pos.y = -1;
- }
-
- level_pos(const level_id &lid, const coord_def &coord)
- : id(lid), pos(coord)
- {
- }
-
- level_pos(const level_id &lid)
- : id(lid), pos()
- {
- pos.x = pos.y = -1;
- }
-
- bool operator == ( const level_pos &lp ) const
- {
- return id == lp.id && pos == lp.pos;
- }
-
- bool operator != ( const level_pos &lp ) const
- {
- return id != lp.id || pos != lp.pos;
- }
-
- bool is_valid() const
- {
- return id.depth > -1 && pos.x != -1 && pos.y != -1;
- }
-
- void save(FILE *) const;
- void load(FILE *);
-};
-
-struct stair_info
-{
- coord_def position; // Position of stair
-
- level_pos destination; // The level and the position on the level this
- // stair leads to. This may be a guess.
-
- int distance; // The distance traveled to reach this stair.
-
- bool guessed_pos; // true if we're not sure that 'destination' is
- // correct.
-
- stair_info() : destination(), distance(-1), guessed_pos(true)
- {
- position.x = position.y = -1;
- }
-
- void reset_distance()
- {
- distance = -1;
- }
-
- void save(FILE *) const;
- void load(FILE *);
-};
-
-// Information on a level that interlevel travel needs.
-struct LevelInfo
-{
- LevelInfo() : stairs()
- {
- stair_distances = NULL;
- }
- LevelInfo(const LevelInfo &li);
-
- ~LevelInfo();
-
- const LevelInfo &operator = (const LevelInfo &other);
-
- void save(FILE *) const;
- void load(FILE *);
-
- std::vector<stair_info> &get_stairs()
- {
- return stairs;
- }
-
- stair_info *get_stair(int x, int y);
- stair_info *get_stair(const coord_def &pos);
- int get_stair_index(const coord_def &pos) const;
-
- void reset_distances();
- void set_level_excludes();
-
- // Returns the travel distance between two stairs. If either stair is NULL,
- // or does not exist in our list of stairs, returns 0.
- int distance_between(const stair_info *s1, const stair_info *s2) const;
-
- void update(); // Update LevelInfo to be correct for the
- // current level.
-
- // Updates/creates a StairInfo for the stair at (x, y) in grid coordinates
- void update_stair(int x, int y, const level_pos &p, bool guess = false);
-
- // Returns true if the given branch is known to be accessible from the
- // current level.
- bool is_known_branch(unsigned char branch) const;
-
- void add_waypoint(const coord_def &pos);
- void remove_waypoint(const coord_def &pos);
-
- void travel_to_waypoint(const coord_def &pos);
-private:
- // Gets a list of coordinates of all player-known stairs on the current
- // level.
- static void get_stairs(std::vector<coord_def> &stairs);
-
- void correct_stair_list(const std::vector<coord_def> &s);
- void update_stair_distances();
- void fixup();
-
-private:
- std::vector<stair_info> stairs;
-
- // Squares that are not safe to travel to.
- std::vector<coord_def> excludes;
-
- short *stair_distances; // Distances between the various stairs
- level_id id;
-
- friend class TravelCache;
-};
-
-#define TRAVEL_WAYPOINT_COUNT 10
-// Tracks all levels that the player has seen.
-class TravelCache
-{
-public:
- void reset_distances();
-
- // Get the LevelInfo for the specified level (defaults to the current
- // level).
- LevelInfo& get_level_info(unsigned char branch = 0, int depth = -1)
- {
- return get_level_info( level_id(branch, depth) );
- }
-
- LevelInfo& get_level_info(const level_id &lev)
- {
- LevelInfo &li = levels[lev];
- li.id = lev;
- return li;
- }
-
- bool know_level(const level_id &lev) const
- {
- return levels.find(lev) != levels.end();
- }
-
- const level_pos &get_waypoint(int number) const
- {
- return waypoints[number];
- }
-
- int get_waypoint_count() const;
-
- void set_level_excludes();
-
- void add_waypoint(int x = -1, int y = -1);
- unsigned char is_waypoint(const level_pos &lp) const;
- void list_waypoints() const;
- void travel_to_waypoint(int number);
- void update_waypoints() const;
-
-
- void update();
-
- void save(FILE *) const;
- void load(FILE *);
-
- bool is_known_branch(unsigned char branch) const;
-
-private:
- void fixup_levels();
-
-private:
- std::map<level_id, LevelInfo, level_id::less_than> levels;
- level_pos waypoints[TRAVEL_WAYPOINT_COUNT];
-};
-
-int level_distance(level_id first, level_id second);
-
-extern TravelCache travel_cache;
-
-#endif // TRAVEL_H
diff --git a/stone_soup/crawl-ref/source/unrand.h b/stone_soup/crawl-ref/source/unrand.h
deleted file mode 100644
index ae38b07de8..0000000000
--- a/stone_soup/crawl-ref/source/unrand.h
+++ /dev/null
@@ -1,1138 +0,0 @@
-/*
- * File: unrand.cc
- * Summary: Definitions for unrandom artifacts.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- * <3> 7 Aug 2001 MV Added many new items
- * <2> 5/09/99 JDJ Cekugob no longer has fire and cold
- * resistances.
- * <1> -/--/-- LRH Created
- */
-#ifndef UNRAND_H
-#define UNRAND_H
-
-#include "defines.h"
-
-/*
- List of "unrandom" artefacts. Not the same as "fixed" artefacts, which are
- completely hardcoded (eg Singing Sword, Wrath of Trog).
- note: the order of the list doesn't matter
- Because the list numbering starts at 1, the last entry is the highest value
- which can be given to NO_UNRANDARTS (eg if the list consists of randarts no
- 1, 2 or 3, NO_UNRANDARTS must be set to 3 or lower, but probably not to 0).
- Setting it higher could cause nasty problems.
-
- Okay, so the steps to adding a new unrandart go as follows:
- 1) - Fill in a new entry below, using the following guidelines:
- true name: The name which is displayed when the item is id'd
- un-id'd name: obvious
- class: weapon, armour etc
- type: long sword, plate mail etc. Jewellery unrandarts have the powers of
- their base types in addition to anything else.
- plus: For weapons, plus to-hit. For armour, plus. For jewellery, irrelevant.
- But add 100 to make the item stickycursed. Note that the values for
- wpns and armr are +50.
- plus2: For wpns, plus to-dam. Curses are irrelevant here. Mostly unused
- for armr and totally for rings. Armour: if boots, plus2 == 1 means
- naga barding; 2 means centaur barding. If headgear, 1 means helmet,
- 2 means helm, 3 means cap, 4 means wizard's hat.
- colour: Obvious. Don't use BLACK, use DARKGREY instead.
-
- * Note * any exact combination of class, type, plus & plus2 must be unique,
- so (for example) you can't have two +5, +5 long swords in the list. Curses
- don't count as distinguishing factors.
-
- brand: Weapons only. Have a look in enum.h for a list, and look in fight.cc
- and describe.cc for the effects.
- Range of possible values: see enum.h
-
- +/- to AC, ev, str, int, dex - These are pretty obvious. Be careful - a player
- with a negative str, int or dex dies instantly, so avoid high penalties
- to these stats.
- Range: any, but be careful.
-
- res fire, res cold: Resists. Can be above 1; multiple sources of fire or cold
- resist *are* cumulative. Can also be -1 (but probably not -2 or below)
- for susceptibility.
- Range: -1 to about 5, after which you'll become almost immune.
- res elec: Resist electricity. Unlike fire and cold, resist electricity
- reduces electrical damage to 0. This makes multiple resists irrelevant.
- Also is no susceptibility, so don't use -1.
- Range: 0 or 1.
- res poison: same as res electricity.
- Range: 0 or 1.
- life prot: Stops energy draining and negative energy attacks. Not cumulative,
- and no susceptibility here either.
- Range: 0 or 1.
-
- res magic: This is cumulative, but no susceptibility. To be meaningful,
- should be set to about 20 - 60.
- Range: 0 to MAXINT probably, but about 100 is a realistic ceiling.
-
- see invis: Lets you see invisible things, but not submerged water beasts.
- Range: 0 or 1.
- turn invis: Gives you the ability to turn invisible using the 'a' menu.
- levitate, blink, go berserk, sense surroundings: like turn invis.
- Ranges for all these: 0 or 1.
-
- make noise: Irritate nearby creatures and disrupts rest. Weapons only.
- Range: 1 - 4, for different types of noises (see special_wielded() in
- it_use3.cc); 0 for none.
- no spells: Prevents any spellcasting (but not scrolls or wands etc)
- Range: 0 or 1.
- teleport: Every now and then randomly teleports you. *Really* annoying.
- Weapons only.
- Range: 0 to about 15 (higher means more teleporting).
- no teleport: Prevents the player from teleporting, except rarely when they're
- forced to (eg banished to the Abyss).
- Range: 0 or 1.
-
- force berserk: Every time you attack, you go berserk. Weapons only.
- Range: 0 or 1.
- speed metabolism: Makes you consume food faster. No effect on mummies.
- Range: 0 to about 4. 4 would be horrible; 1 is annoying but tolerable.
- mutate: makes you mutate, sometimes after a long delay. No effect on some
- races (espec undead).
- Range: 0 to about 4.
- +/- to-hit/to-dam: Obvious. Affects both melee and missile. Should be left
- at 0 for weapons, which get +s normally.
-
- cursed: 0 or 1. Sets the item's initial curse status. Cursed items
- will tend to recurse themselves when rewielded. Maybe this should be
- made to be a value that determines how often it will recurse? -- bwr
-
- stealth: -100 to 80. Adds to stealth value.
-
- Some currently unused properties follow, then:
-
- First string: is appended to the unrandart's 'V' description when id'd.
-
- Second string: replaces the thing at the start of a 'V' description.
- If empty, uses the description of the unrandart's base type. Note: the
- base type of a piece of unrandart jewellery is relevant to its function, so
- don't obscure it unnecessarily.
-
- Then another unused string.
-
- 2) - Add one to the #define NO_UNRANDARTS line in randart.h
-
- 3) - Maybe increase the probability of an unrandart of the appropriate
- type being created; look in dungeon.cc for this (search for "unrand").
- Forget this step if you don't understand it; it's of very little importance.
-
- Done! Now recompile and wait years for it to turn up.
-
- Note: changing NO_UNRANDARTS probably makes savefiles incompatible.
-
- */
-
-/* This is a dummy, but still counts for NO_UNRANDARTS */
-/* 1 */
-{
- "Dum", "",
-/* class, type, plus (to-hit), plus2 (depends on class), colour */
- 250, 250, 250, 250, 0,
-/* Properties, all approx thirty of them: */
- {
-/* brand, +/- to AC, +/- to ev, +/- to str, +/- to int, +/- to dex */
- 0, 0, 0, 0, 0, 0,
-/* res fire, res cold, res elec, res poison, life protection, res magic */
- 0, 0, 0, 0, 0, 0,
-/* see invis, turn invis, levitate, blink, teleport at will, go berserk */
- 0, 0, 0, 0, 0, 0,
-/* sense surroundings, make noise, no spells, teleport, no teleprt */
- 0, 0, 0, 0, 0,
-/* force berserk, speed metabolism, mutate, +/- to hit, +/- to dam (not weapons) */
- 0, 0, 0, 0, 0,
-/* cursed, stealth */
- 0, 0
- }
- ,
-/* Special description appended to the 'V' description */
- "",
-/* Base description of item */
- "",
-/* Unused string */
- ""
-}
-,
-
-
-/* 2 */
-{
- "long sword \"Bloodbane\"", "blackened long sword",
- OBJ_WEAPONS, WPN_LONG_SWORD, +7, +8, DARKGREY,
- {
- SPWPN_VORPAL, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, // berserk
- 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, // force berserk
- 0, -20 // stealth
- }
- ,
- "",
- "",
- ""
-}
-,
-
-/* 3 */
-{
- "ring of Shadows", "black ring",
- OBJ_JEWELLERY, RING_INVISIBILITY, 0, 0, DARKGREY,
- {
- 0, 0, 4, 0, 0, 0, // EV
- 0, 0, 0, 0, 1, 0, // life prot
- 1, 0, 0, 0, 0, 0, // see invis
- 0, 0, 0, 0, 0,
- 0, 0, 0, -3, 0, // to hit
- 0, 10 // stealth
- }
- ,
- "",
- "",
- ""
-}
-,
-
-/* 4 */
-{
- "long sword of Flaming Death", "smoking long sword",
- OBJ_WEAPONS, WPN_LONG_SWORD, +6, +2, RED,
- {
- SPWPN_FLAMING, 0, 0, 0, 0, 0,
- 2, -1, 0, 1, 0, 20, // res fire, cold, poison, magic
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "",
- ""
-}
-,
-
-/* 5 */
-{
- "shield of Ignorance", "dull large shield",
- OBJ_ARMOUR, ARM_LARGE_SHIELD, +5, 0, BROWN,
- {
- 0, 2, 2, 0, -6, 0, // AC, EV, int
- 0, 0, 0, 0, 1, 0, // life prot
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 1, 0 // cursed
- }
- ,
- "",
- "",
- ""
-}
-,
-
-
-/* 6 */
-{
- "Holy Armour of Zin", "glowing golden plate mail",
- OBJ_ARMOUR, ARM_PLATE_MAIL, +6, 0, YELLOW,
- {
- 0, 0, 0, 3, 0, 0, // str
- 0, 0, 0, 0, 2, 50, // life prot, magic
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "A suit of mail and large plates of golden metal.",
- ""
-}
-,
-
-/* 7 */
-{
- "robe of Augmentation", "silk robe",
- OBJ_ARMOUR, ARM_ROBE, +4, 0, LIGHTRED,
- {
- 0, 0, 0, 2, 2, 2, // str, int, dex
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "A robe made of the finest silk.",
- ""
-}
-,
-
-/* 8 */
-{
- "mace of Brilliance", "brightly glowing mace",
- OBJ_WEAPONS, WPN_MACE, +5, +5, WHITE,
- {
- SPWPN_HOLY_WRATH, 3, 0, 0, 0, 0, // AC
- 0, 0, 0, 0, 1, 0, // life prot
- 1, 0, 0, 0, 0, 0, // see invis
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, -20 // stealth
- }
- ,
- "",
- "",
- ""
-}
-,
-
-/* 9 */
-{
- "cloak of the Thief", "tattered cloak",
- OBJ_ARMOUR, ARM_CLOAK, +1, 0, DARKGREY,
- {
- 0, 0, 2, 0, 0, 2, // EV, dex
- 0, 0, 0, 0, 0, 0,
- 1, 1, 1, 0, 0, 0, // see invis, turn invis, levitate
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, -3, // to dam
- 0, 60 // stealth
- }
- ,
- "It allows its wearer to excel in the arts of thievery.",
- "",
- ""
-}
-,
-
-
-
-
-/* 10 */
-{
- "buckler \"Bullseye\"", "round buckler",
- OBJ_ARMOUR, ARM_BUCKLER, +10, 0, RED,
- {
- 0, 0, -3, 0, 0, 0, // EV
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "",
- ""
-}
-,
-
-/* 11 */
-{
- "crown of Dyrovepreva", "jewelled bronze crown",
- OBJ_ARMOUR, ARM_HELMET, +3, THELM_SPECIAL, BROWN,
- {
- 0, 0, 0, 0, 2, 0, // int
- 0, 0, 1, 0, 0, 0, // res elec
- 1, 0, 0, 0, 0, 0, // see invis
- 0, 0, 0, 0, 0,
- 0, 1, 0, 0, 0, // speeds metabolism
- 0, 0
- }
- ,
- "",
- "A large crown of dull bronze, set with a dazzling array of gemstones.",
- ""
-}
-,
-
-
-/* 12 */
-{
- "demon blade \"Leech\"", "runed demon blade",
- OBJ_WEAPONS, WPN_DEMON_BLADE, +13, +4, MAGENTA,
- {
- SPWPN_VAMPIRICISM, -1, -1, -1, -1, -1, // AC, EV, str, int, dex
- 0, 0, 0, 0, 1, 0, // life prot
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 1, 0 // cursed
- }
- ,
- "",
- "",
- ""
-}
-,
-
-/* 13 */
-{
- "amulet of Cekugob", "crystal amulet",
- OBJ_JEWELLERY, AMU_WARDING, +0, 0, LIGHTGREY,
- {
- 0, 1, 1, 0, 0, 0, // AC, EV
- 0, 0, 1, 1, 1, 0, // res elec, poison, life prot
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, // prevent teleport
- 0, 2, 0, 0, 0, // speed metabolism
- 0, 0
- }
- ,
- "",
- "",
- ""
-}
-,
-
-
-/* 14 */
-{
- "robe of Misfortune", "fabulously ornate robe",
- OBJ_ARMOUR, ARM_ROBE, -5, 0, MAGENTA,
- {
- 0, 0, -4, -2, -2, -2, // EV, str, int, dex
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 1, 0, // prevent spellcasting, cause teleport
- 0, 0, 5, 0, 0, // radiation
- 1, -80 // cursed, stealth
- }
- ,
- "",
- "A splendid flowing robe of fur and silk.",
- ""
-}
-
-#ifdef USE_NEW_UNRANDS
-,
-/* 15 */
-{
- "dagger of Chilly Death", "sapphire dagger",
- OBJ_WEAPONS, WPN_DAGGER, +2, +6, LIGHTBLUE,
- {
- SPWPN_FREEZING, 0, 0, 0, 0, 0,
- -1, 2, 0, 1, 0, 20, // res fire, cold, poison, magic
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "A dagger made of one huge piece of sapphire.",
- ""
-}
-,
-/* 16 */
-{
- "amulet of the Four Winds", "jade amulet",
- OBJ_JEWELLERY, AMU_CLARITY, +0, 0, LIGHTGREEN,
- {
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 60, // life prot, magic resistance
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "",
- ""
-}
-,
-
-/* 17 */
-{
- "dagger \"Morg\"", "rusty dagger",
- OBJ_WEAPONS, WPN_DAGGER, -1, +4, LIGHTRED,
- {
- SPWPN_PAIN, 0, 0, 0, 5, 0, // int
- 0, 0, 0, 0, 0, 30, // res magic
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "Many years ago it was the property of a powerful mage called "
- "Boris. He got lost in the Dungeon while seeking the Orb. ",
- "An ugly rusty dagger. ",
- ""
-}
-,
-
-/* 18 */
-{
- "scythe \"Finisher\"", "blackened scythe",
- OBJ_WEAPONS, WPN_SCYTHE, +3, +5, DARKGRAY,
- {
- SPWPN_SPEED, 0, 0, 3, 0, 0, // str
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 1, 0 // cursed
- }
- ,
- "",
- "A long and sharp scythe, specially modified for combat purposes.",
- ""
-}
-,
-
-/* 19 */
-{
- "sling \"Punk\"", "blue sling",
- OBJ_WEAPONS, WPN_SLING, +3, +4, LIGHTBLUE,
- {
- SPWPN_FROST, 0, 0, 0, 0, 0,
- 0, 1, 0, 0, 0, 0, // res cold
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "A sling made of weird blue leather.",
- ""
-}
-,
-/* 20 */
-{
- "bow of Krishna \"Sharnga\"", "golden bow",
- OBJ_WEAPONS, WPN_BOW, +8, +8, YELLOW,
- {
- SPWPN_SPEED, 0, 0, 0, 0, 3, // dex
- 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, 0, // see invis
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "It once belonged to a foreign god. It works best with "
- "special arrows which are not generally available.",
- "A wonderful golden bow. ",
- ""
-}
-,
-/* 21 */
-{
- "cloak of Flash", "vibrating cloak",
- OBJ_ARMOUR, ARM_CLOAK, +2, 0, RED,
- {
- 0, 0, 4, 0, 0, 0, // EV
- 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 0, 1, 0, // levitate, teleport
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "A vibrating cloak.",
- ""
-}
-,
-/* 22 */
-{
- "giant club \"Skullcrusher\"", "brutal giant club",
- OBJ_WEAPONS, WPN_GIANT_CLUB, +0, +5, BROWN,
- {
- SPWPN_VORPAL, 0, 0, 5, 0, 0, // str
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "",
- ""
-}
-,
-/* 23 */
-{
- "boots of the Assassin", "soft boots",
- OBJ_ARMOUR, ARM_BOOTS, +2, 0, BROWN,
- {
- 0, 0, 0, 0, 0, 3, // dex
- 0, 0, 0, 0, 0, 0,
- 0, 1, 0, 0, 0, 0, // turn invis
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 80 // stealth
- }
- ,
- "These boots were specially designed by the Assassin's Guild.",
- "Some soft boots.",
- ""
-}
-,
-/* 24 */
-{
- "glaive of the Guard", "polished glaive",
- OBJ_WEAPONS, WPN_GLAIVE, +5, +8, LIGHTCYAN,
- {
- SPWPN_PROTECTION, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, 1, // see invis, go berserk
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "This weapon once belonged to Gar Dogh, the guard of a king's treasures. "
- "According to legend he was lost somewhere in the Dungeon.",
- "",
- ""
-}
-,
-/* 25 */
-{
- "sword of Jihad", "crystal sword",
- OBJ_WEAPONS, WPN_LONG_SWORD, +4, +4, WHITE,
- {
- SPWPN_HOLY_WRATH, 0, 3, 0, 0, 0, // EV
- 0, 0, 0, 0, 1, 20, // life prot, res magic
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, // force berserk
- 0, -50 // stealth (TSO hates backstab)
- }
- ,
- "This sword was The Shining One's gift to one of his paladins." ,
- "A long sword made of one huge piece of crystal.",
- ""
-}
-,
-/* 26 */
-{
- "Lear's chain mail", "golden chain mail",
- OBJ_ARMOUR, ARM_CHAIN_MAIL, -1, 0, YELLOW,
- {
- 0, 0, 0, 0, 0, -3, // dex
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 0, 0, // prevent spellcasting
- 0, 0, 0, 0, 0,
- 1, 0 // cursed
- }
- ,
- "",
- "A chain mail made of pure gold.",
- ""
-}
-,
-/* 27 */
-{
- "skin of Zhor", "smelly skin",
- OBJ_ARMOUR, ARM_ANIMAL_SKIN, +4, 0, BROWN,
- {
- 0, 0, 0, 0, 0, 0,
- 0, 2, 0, 0, 0, 0, // res cold
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "The skin of some strange animal.",
- ""
-}
-,
-/* 28 */
-{
- "crossbow \"Fiery Devil\"", "flaming crossbow",
- OBJ_WEAPONS, WPN_CROSSBOW, +4, +0, LIGHTRED,
- {
- SPWPN_FLAME, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, 0, // res fire
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "A flaming crossbow.",
- ""
-}
-,
-/* 29 */
-{
- "salamander hide armour", "red leather armour",
- OBJ_ARMOUR, ARM_LEATHER_ARMOUR, +3, 0, RED,
- {
- 0, 0, 0, 0, 0, 0,
- 2, 0, 0, 0, 0, 0, // res fire
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "A leather armour made of salamander's skin.",
- ""
-}
-,
-/* 30 */
-{
- "gauntlets of War", "thick gauntlets",
- OBJ_ARMOUR, ARM_GLOVES, +3, 0, BROWN,
- {
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 3, 3, // to hit, to dam
- 0, 0
- }
- ,
- "",
- "",
- ""
-}
-,
-/* 31 */
-{
- "sword of Doom Knight", "adamantine great sword",
- OBJ_WEAPONS, WPN_GREAT_SWORD, +4, +4, BLUE,
- {
- SPWPN_PAIN, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 50, // res magic
- 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 0, 0, // prevent spellcasting
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "An adamantine great sword.",
- ""
-}
-,
-/* 32 */
-{
- "shield of Resistance", "bronze shield",
- OBJ_ARMOUR, ARM_SHIELD, +3, 0, LIGHTRED,
- {
- 0, 0, 0, 0, 0, 0,
- 1, 1, 0, 0, 0, 40, // res fire, cold, magic
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "A bronze shield.",
- ""
-}
-,
-/* 33 */
-{
- "robe of Folly", "dull robe",
- OBJ_ARMOUR, ARM_ROBE, -1, 0, LIGHTGRAY,
- {
- 0, 0, 0, 0, -5, 0, // int
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 0, 0, // prevent spellcasting
- 0, 0, 0, 0, 0,
- 1, 0 // cursed
- }
- ,
- "",
- "A dull gray robe.",
- ""
-}
-,
-/* 34 */
-{
- "necklace of Bloodlust", "blood-stained necklace",
- OBJ_JEWELLERY, AMU_RAGE, +0, 0, RED,
- {
- 0, 0, 0, 2, -2, 0, // str, int
- 0, 0, 0, 0, 0, 30, // res magic
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 3, // force berserk, to dam
- 1, -20 // cursed, stealth
- }
- ,
- "",
- "",
- ""
-}
-,
-/* 35 */
-{
- "\"Eos\"", "encrusted morningstar",
- OBJ_WEAPONS, WPN_MORNINGSTAR, +5, +5, LIGHTCYAN,
- {
- SPWPN_ELECTROCUTION, 0, 0, 0, 0, 0, // morning -> bring light/sparks?
- 0, 0, 1, 0, 0, 0, // res elec
- 1, 0, 0, 0, 0, 0, // see invis
- 0, 0, 0, 0, 1, // prevent teleportation
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "",
- ""
-}
-,
-/* 36 */
-{
- "ring of Shaolin", "jade ring",
- OBJ_JEWELLERY, RING_EVASION, +8, 0, LIGHTGREEN,
- {
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "",
- ""
-}
-,
-/* 37 */
-{
- "ring of Robustness", "steel ring",
- OBJ_JEWELLERY, RING_PROTECTION, +8, 0, LIGHTGRAY,
- {
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "",
- ""
-}
-,
-/* 38 */
-{
- "Edison's patent armour", "weird-looking armour",
- OBJ_ARMOUR, ARM_PLATE_MAIL, +10, 0, LIGHTGREEN,
- {
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 0, 1, // prevent spellcasting, prevent teleport
- 0, 0, 0, 0, 0,
- 1, 0 // cursed
- }
- ,
- "",
- "A weird-looking armour.",
- ""
-}
-,
-/* 39 */
-{
- "spear of Voo-Doo", "ebony spear",
- OBJ_WEAPONS, WPN_SPEAR, +2, +10, DARKGRAY,
- {
- SPWPN_VAMPIRICISM, 0, 0, 0, 0, 0,
- 0, 0, 0, 1, 1, 0, // res poison, prot life
- 0, 0, 0, 0, 0, 0,
- 0, 3, 0, 0, 0, // noise
- 0, 0, 0, 0, 0,
- 0, -30 // stealth
- }
- ,
- "It's a really dark and malign artifact and no wise man would even touch it.",
- "",
- ""
-}
-,
-/* 40 */
-{
- "trident of the Octopus king", "mangy trident",
- OBJ_WEAPONS, WPN_TRIDENT, +10, +4, CYAN,
- {
- SPWPN_VENOM, 0, 0, 0, 0, 0,
- 0, 0, 0, 1, 0, 50, // res poison, res magic
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "This trident was stolen many years ago from the Octopus king's garden "
- "by a really unimportant and already dead man. But beware of "
- "the Octopus king's wrath!",
- "",
- ""
-}
-,
-/* 41 */
-{
- "mask of the Dragon", "blue mask",
- OBJ_ARMOUR, ARM_HELMET, +0, THELM_SPECIAL, BLUE,
- {
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 40, // res magic
- 1, 0, 0, 0, 0, 0, // see invis
- 0, 0, 0, 0, 0,
- 0, 0, 0, 2, 2, // to hit, to dam
- 0, 0
- }
- ,
- "",
- "A blue mask.",
- ""
-}
-,
-/* 42 */
-{
- "mithril axe \"Arga\"", "mithril axe",
- OBJ_WEAPONS, WPN_WAR_AXE, +10, +6, WHITE,
- {
- SPWPN_SPEED, 0, 0, 2, 0, 0, // str
- 0, 0, 0, 0, 0, 30, // resist magic
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "A beautiful mithril axe, probably lost by some dwarven hero.",
- ""
-}
-,
-/* 43 */
-{
- "Elemental Staff", "black staff",
- OBJ_WEAPONS, WPN_QUARTERSTAFF, +3, +1, DARKGRAY,
- {
- SPWPN_PROTECTION, 0, 0, 0, 0, 0,
- 1, 1, 0, 0, 0, 60, // res fire, cold, magic
- 0, 0, 0, 0, 0, 0,
- 0, 1, 0, 0, 0, // noise
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "This powerful staff used to belong to the leader of"
- " the Guild of Five Elements.",
- "A black glyphic staff.",
- ""
-}
-,
-/* 44 */
-{
- "hand crossbow \"Sniper\"", "black crossbow",
- OBJ_WEAPONS, WPN_HAND_CROSSBOW, +10, +0, DARKGRAY,
- {
- SPWPN_VENOM, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, 0, // see invis
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "A hand crossbow made of some black material.",
- ""
-}
-,
-/* 45 */
-{
- "bow \"Erchidel\"", "metal bow",
- OBJ_WEAPONS, WPN_BOW, +5, +3, CYAN,
- {
- SPWPN_PROTECTION, 0, 0, 3, 0, 0, // str
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "A metal bow.",
- ""
-}
-,
-/* 46 */
-{
- "robe of Night", "black robe",
- OBJ_ARMOUR, ARM_ROBE, +4, 0, DARKGRAY,
- {
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 30, // res magic
- 1, 1, 0, 0, 0, 0, // see invis, turn invis
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 50 // stealth
- }
- ,
- "According to legend this robe was the gift of Ratri the Goddess of the Night "
- "to one of her followers.",
- "A long black robe made of strange flossy material.",
- ""
-}
-,
-/* 47 */
-{
- "plutonium sword", "glowing long sword",
- OBJ_WEAPONS, WPN_LONG_SWORD, +5, +10, LIGHTGREEN,
- {
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 6, 0, 0, // radiation
- 1, -20 // cursed, stealth
- }
- ,
- "",
- "A long sword made of weird glowing metal.",
- ""
-}
-,
-/* 48 */
-{
- "mace \"Undeadhunter\"", "steel mace",
- OBJ_WEAPONS, WPN_MACE, +4, +6, LIGHTGRAY,
- {
- SPWPN_DISRUPTION, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 0, // life prot
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "",
- ""
-}
-,
-/* 49 */
-{
- "armour of the Dragon King", "shiny dragon armour",
- OBJ_ARMOUR, ARM_GOLD_DRAGON_ARMOUR, +5, 0, YELLOW,
- {
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 50, // res magic (base gives fire, cold, poison)
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "",
- ""
-}
-,
-/* 50 */
-{
- "hat of the Alchemist", "dirty hat",
- OBJ_ARMOUR, ARM_HELMET, +2, THELM_SPECIAL, MAGENTA,
- {
- 0, 0, 0, 0, 0, 0,
- 1, 1, 1, 0, 0, 30, // res fire, cold, elec, magic
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "A dirty hat.",
- ""
-}
-,
-/* 51 */
-{
- "Fencer's gloves", "silk gloves",
- OBJ_ARMOUR, ARM_GLOVES, +2, 0, WHITE,
- {
- 0, 0, 3, 0, 0, 3, // EV, dex
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 5, 0, // to hit
- 0, 0
- }
- ,
- "",
- "A pair of gloves made of white silk.",
- ""
-}
-,
-/* 52 */
-{
- "ring of the Mage", "sapphire ring",
- OBJ_JEWELLERY, RING_WIZARDRY, +0, 0, LIGHTBLUE,
- {
- 0, 0, 0, 0, 3, 0, // int
- 0, 0, 0, 0, 0, 50, // res magic
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "",
- ""
-}
-#endif // USE_NEW_UNRANDS
-,
-/* This is a dummy */
-/* 1 */
-{
- "Dum", "",
-/* class, type, plus (to-hit), plus2 (depends on class), colour */
- 250, 250, 250, 250, 0,
-/* Properties, all approx thirty of them: */
- {
-/* brand, +/- to AC, +/- to ev, +/- to str, +/- to int, +/- to dex */
- 0, 0, 0, 0, 0, 0,
-/* res fire, res cold, res elec, res poison, life protection, res magic */
- 0, 0, 0, 0, 0, 0,
-/* see invis, turn invis, levitate, blink, teleport at will, go berserk */
- 0, 0, 0, 0, 0, 0,
-/* sense surroundings, make noise, no spells, teleport, no teleprt */
- 0, 0, 0, 0, 0,
-/* force berserk, speed metabolism, mutate, +/- to hit, +/- to dam (not weapons) */
- 0, 0, 0, 0, 0,
-/* some as yet unused properties */
- 0, 0
- }
- ,
-/* 3 strings for describing the item in the 'V' display. */
- "",
- "",
- ""
-}
-#endif
diff --git a/stone_soup/crawl-ref/source/version.h b/stone_soup/crawl-ref/source/version.h
deleted file mode 100644
index 5bc1dedec4..0000000000
--- a/stone_soup/crawl-ref/source/version.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * File: version.h
- * Summary: Contains version information
- * Written by: ??
- *
- * Change History (most recent first):
- *
- * <2> 10/12/99 BCR Added BUILD_DATE #define
- * <1> -/--/-- --- Created
- */
-
-/* Crawl versioning:
- * Crawl uses three numbers to determine the version:
- * Version, which changes when the dev team makes enormous overhauls
- * to the game (which may cause savefiles from previous versions to
- * temporarily stop working, for example)
- * Release, which changes when siginficant new features have been
- * added to the game.
- * Mod, which changes with every publicly released version that
- * contains nothing more than bug fixes, cosmetic changes,
- * internal cleanup, etc.
- *
- * Further, any source or binary uploaded anywhere that is _not_ of
- * release quality should be labelled as such:
- * alpha for potentially unstable dev versions, or
- * beta for feature-complete and mostly balanced versions
- *
- * several alphas or betas in a row should be labelled incrementally;
- * alpha1 -> alpha2 -> alpha3 -> beta1 -> beta2 -> ...
- */
-
-
-#ifndef VERSION_H
-#define VERSION_H
-
-
-// last updated 07august2001 {mv}
-/* ***********************************************************************
- * called from: chardump - command - newgame
- * *********************************************************************** */
-#define VERSION "0.1 beta 1 (crawl-ref)"
-
-
-// last updated 20feb2001 {GDL}
-/* ***********************************************************************
- * called from: command
- * *********************************************************************** */
-#define BUILD_DATE __DATE__
-
-#define SAVE_MAJOR_VERSION 0
-
-#endif
diff --git a/stone_soup/crawl-ref/source/view.cc b/stone_soup/crawl-ref/source/view.cc
deleted file mode 100644
index e3e7564453..0000000000
--- a/stone_soup/crawl-ref/source/view.cc
+++ /dev/null
@@ -1,4098 +0,0 @@
-/*
- * File: view.cc
- * Summary: Misc function used to render the dungeon.
- * Written by: Linley Henzell
- *
- * Modified for Crawl Reference by $Author$ on $Date$
- *
- * Change History (most recent first):
- *
- * <10> 29 Jul 00 JDJ show_map iterates horizontally to 79 instead of 80.
- * item no longer indexes past the end of environ::grid.
- * <9> 19 Jun 00 GDL Complete rewrite of LOS code
- * <8> 11/23/99 LRH Added colour-coded play-screen map & clean_map
- * init options
- * <7> 9/29/99 BCR Removed first argument from draw_border
- * <6> 9/11/99 LRH Added calls to overmap functions
- * <5> 6/22/99 BWR Fixed and improved the stealth
- * <4> 5/20/99 BWR show_map colours all portals,
- * exits from subdungeons now
- * look like up stairs.
- * <3> 5/09/99 JDJ show_map draws shops in yellow.
- * <2> 5/09/99 JDJ show_map accepts '\r' along with '.'.
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "view.h"
-
-#include <string.h>
-
-#ifdef DOS
-#include <conio.h>
-#endif
-
-#include "externs.h"
-
-#include "clua.h"
-#include "debug.h"
-#include "insult.h"
-#include "macro.h"
-#include "monstuff.h"
-#include "mon-util.h"
-#include "overmap.h"
-#include "player.h"
-#include "skills2.h"
-#include "stuff.h"
-#include "spells4.h"
-#include "stash.h"
-#include "travel.h"
-
-#if defined(DOS_TERM)
-typedef char screen_buffer_t;
-#else
-typedef unsigned short screen_buffer_t;
-#endif
-
-unsigned char your_sign; // accessed as extern in transfor.cc and acr.cc
-unsigned char your_colour; // accessed as extern in transfor.cc and acr.cc
-
-FixedArray < unsigned int, 20, 19 > show_backup;
-
-unsigned char show_green;
-extern int stealth; // defined in acr.cc
-extern FixedVector<char, 10> Visible_Statue; // defined in acr.cc
-
-// char colour_code_map(unsigned char map_value);
-screen_buffer_t colour_code_map( int x, int y, bool item_colour = false,
- bool travel_colour = false );
-
-extern void (*viewwindow) (char, bool);
-unsigned char (*mapch) (unsigned char);
-unsigned char (*mapch2) (unsigned char);
-unsigned char mapchar(unsigned char ldfk);
-unsigned char mapchar2(unsigned char ldfk);
-unsigned char mapchar3(unsigned char ldfk);
-unsigned char mapchar4(unsigned char ldfk);
-void cloud_grid(void);
-void monster_grid(bool do_updates);
-
-static int display_glyph(int env_glyph);
-static int item_env_glyph(const item_def &item);
-
-//---------------------------------------------------------------
-//
-// get_number_of_lines
-//
-// Made this a function instead of a #define. This should help
-// considering the fact that the curses version is a macro
-// (curses tends to be implemented with a large number of
-// preprocessor macros, which can wreak havoc with things
-// like the C++ string class, so we want to isolate that
-// away to keep portability up).
-//
-// Other OSes might want to hook into reading system environment
-// variables or player set options to determine the screen size
-// (see the Options and SysEnv structures, as well as initfile.cc).
-//
-// This might be better to move to the lib*.cc files, but we
-// don't really have a standard API defined for them, or the
-// all important libdos.cc. It would be a good idea to eventually
-// head that way. -- bwr
-//
-//---------------------------------------------------------------
-int get_number_of_lines(void)
-{
-#ifdef UNIX
- return (get_number_of_lines_from_curses());
-#elif MAC
- return (MAC_NUMBER_OF_LINES);
-#else
- return (25);
-#endif
-}
-
-
-//---------------------------------------------------------------
-//
-// get_ibm_symbol
-//
-// Returns the DOS character code and color for everything drawn
-// with the IBM graphics option.
-//
-//---------------------------------------------------------------
-static void get_ibm_symbol(unsigned int object, unsigned short *ch,
- unsigned short *color)
-{
- ASSERT(color != NULL);
- ASSERT(ch != NULL);
-
- switch (object)
- {
- case DNGN_UNSEEN:
- *ch = 0;
- break;
-
- case DNGN_ROCK_WALL:
- case DNGN_PERMAROCK_WALL:
- *color = env.rock_colour;
- *ch = 177;
- break; // remember earth elementals
-
- // stone in the realm of Zot is coloured the same as rock
- case DNGN_STONE_WALL:
- *color = (player_in_branch( BRANCH_HALL_OF_ZOT ) ? env.rock_colour
- : LIGHTGREY);
- *ch = 177;
- break;
-
- case DNGN_CLOSED_DOOR:
- *ch = 254;
- break;
-
- case DNGN_METAL_WALL:
- *ch = 177;
- *color = CYAN;
- break;
-
- case DNGN_SECRET_DOOR:
- *ch = 177;
- *color = env.rock_colour;
- break;
-
- case DNGN_GREEN_CRYSTAL_WALL:
- *ch = 177;
- *color = GREEN;
- break;
-
- case DNGN_ORCISH_IDOL:
- *ch = '8';
- *color = DARKGREY;
- break;
-
- case DNGN_WAX_WALL:
- *ch = 177;
- *color = YELLOW;
- break; // wax wall
- /* Anything added here must also be added to the PLAIN_TERMINAL
- viewwindow2 below */
-
- case DNGN_SILVER_STATUE:
- *ch = '8';
- *color = WHITE;
- Visible_Statue[ STATUE_SILVER ] = 1;
- break;
-
- case DNGN_GRANITE_STATUE:
- *ch = '8';
- *color = LIGHTGREY;
- break;
-
- case DNGN_ORANGE_CRYSTAL_STATUE:
- *ch = '8';
- *color = LIGHTRED;
- Visible_Statue[ STATUE_ORANGE_CRYSTAL ] = 1;
- break;
-
- case DNGN_LAVA:
- *ch = 247;
- *color = RED;
- break;
-
- case DNGN_DEEP_WATER:
- *ch = 247; // this wavy thing also used for water elemental
- *color = BLUE;
- break;
-
- case DNGN_SHALLOW_WATER:
- *ch = 247; // this wavy thing also used for water elemental
- *color = CYAN;
- break;
-
- case DNGN_FLOOR:
- *color = env.floor_colour;
- *ch = 249;
- break;
-
- case DNGN_ENTER_HELL:
- *ch = 239;
- *color = RED;
- seen_other_thing(object);
- break;
-
- case DNGN_OPEN_DOOR:
- *ch = 39;
- break;
-
- case DNGN_TRAP_MECHANICAL:
- *color = LIGHTCYAN;
- *ch = 94;
- break;
-
- case DNGN_TRAP_MAGICAL:
- *color = MAGENTA;
- *ch = 94;
- break;
-
- case DNGN_TRAP_III:
- *color = LIGHTGREY;
- *ch = 94;
- break;
-
- case DNGN_UNDISCOVERED_TRAP:
- *ch = 249;
- *color = env.floor_colour;
- break;
-
- case DNGN_ENTER_SHOP:
- *ch = 239;
- *color = YELLOW;
-
- seen_other_thing(object);
- break;
- // if I change anything above here, must also change magic mapping!
-
- case DNGN_ENTER_LABYRINTH:
- *ch = 239;
- *color = LIGHTGREY;
- seen_other_thing(object);
- break;
-
- // not sure why we have "odd" here, but "ladders" are special in
- // that they all lead to the first staircase of the next level
- // (and returning from there will take you somewhere different)
- // ... that's why they're brown... it's a warning -- bwr
- case DNGN_ROCK_STAIRS_DOWN:
- *color = BROWN; // ladder // odd {dlb}
- case DNGN_STONE_STAIRS_DOWN_I:
- case DNGN_STONE_STAIRS_DOWN_II:
- case DNGN_STONE_STAIRS_DOWN_III:
- *ch = '>';
- break;
-
- case DNGN_ROCK_STAIRS_UP:
- *color = BROWN; // ladder // odd {dlb}
- case DNGN_STONE_STAIRS_UP_I:
- case DNGN_STONE_STAIRS_UP_II:
- case DNGN_STONE_STAIRS_UP_III:
- *ch = '<';
- break;
-
- case DNGN_ENTER_DIS:
- *color = CYAN;
- *ch = 239;
- break;
-
- case DNGN_ENTER_GEHENNA:
- *color = RED;
- *ch = 239;
- break;
-
- case DNGN_ENTER_COCYTUS:
- *color = LIGHTCYAN;
- *ch = 239;
- break;
-
- case DNGN_ENTER_TARTARUS:
- *color = DARKGREY;
- *ch = 239;
- break;
-
- case DNGN_ENTER_ABYSS:
- *color = random2(16);
- *ch = 239;
- seen_other_thing(object);
- break;
-
- case DNGN_EXIT_ABYSS:
- *color = random2(16);
- *ch = 239;
- break;
-
- case DNGN_STONE_ARCH:
- *color = LIGHTGREY;
- *ch = 239;
- break;
-
- case DNGN_ENTER_PANDEMONIUM:
- *color = LIGHTBLUE;
- *ch = 239;
- seen_other_thing(object);
- break;
-
- case DNGN_EXIT_PANDEMONIUM:
- *color = LIGHTBLUE;
- *ch = 239;
- break;
-
- case DNGN_TRANSIT_PANDEMONIUM:
- *color = LIGHTGREEN;
- *ch = 239;
- break;
-
- case DNGN_ENTER_ORCISH_MINES:
- case DNGN_ENTER_HIVE:
- case DNGN_ENTER_LAIR:
- case DNGN_ENTER_SLIME_PITS:
- case DNGN_ENTER_VAULTS:
- case DNGN_ENTER_CRYPT:
- case DNGN_ENTER_HALL_OF_BLADES:
- case DNGN_ENTER_TEMPLE:
- case DNGN_ENTER_SNAKE_PIT:
- case DNGN_ENTER_ELVEN_HALLS:
- case DNGN_ENTER_TOMB:
- case DNGN_ENTER_SWAMP:
- case 123:
- case 124:
- case 125:
- case 126:
- *color = YELLOW;
- *ch = '>';
- seen_staircase(object);
- break;
-
- case DNGN_ENTER_ZOT:
- *color = MAGENTA;
- *ch = 239;
- seen_staircase(object);
- break;
-
- case DNGN_RETURN_FROM_ORCISH_MINES:
- case DNGN_RETURN_FROM_HIVE:
- case DNGN_RETURN_FROM_LAIR:
- case DNGN_RETURN_FROM_SLIME_PITS:
- case DNGN_RETURN_FROM_VAULTS:
- case DNGN_RETURN_FROM_CRYPT:
- case DNGN_RETURN_FROM_HALL_OF_BLADES:
- case DNGN_RETURN_FROM_TEMPLE:
- case DNGN_RETURN_FROM_SNAKE_PIT:
- case DNGN_RETURN_FROM_ELVEN_HALLS:
- case DNGN_RETURN_FROM_TOMB:
- case DNGN_RETURN_FROM_SWAMP:
- case 143:
- case 144:
- case 145:
- case 146:
- *color = YELLOW;
- *ch = '<';
- break;
-
- case DNGN_RETURN_FROM_ZOT:
- *color = MAGENTA;
- *ch = 239;
- break;
-
- case DNGN_ALTAR_ZIN:
- *color = WHITE;
- *ch = 220;
- seen_altar(GOD_ZIN);
- break;
-
- case DNGN_ALTAR_SHINING_ONE:
- *color = YELLOW;
- *ch = 220;
- seen_altar(GOD_SHINING_ONE);
- break;
-
- case DNGN_ALTAR_KIKUBAAQUDGHA:
- *color = DARKGREY;
- *ch = 220;
- seen_altar(GOD_KIKUBAAQUDGHA);
- break;
-
- case DNGN_ALTAR_YREDELEMNUL:
- *color = ((one_chance_in(3)) ? RED : DARKGREY);
- *ch = 220;
- seen_altar(GOD_YREDELEMNUL);
- break;
-
- case DNGN_ALTAR_XOM:
- *color = random_colour();
- *ch = 220;
- seen_altar(GOD_XOM);
- break;
-
- case DNGN_ALTAR_VEHUMET:
- *color = LIGHTBLUE;
- if (one_chance_in(3))
- *color = LIGHTMAGENTA;
- if (one_chance_in(3))
- *color = LIGHTRED;
- *ch = 220;
- seen_altar(GOD_VEHUMET);
- break;
-
- case DNGN_ALTAR_OKAWARU:
- *color = CYAN;
- *ch = 220;
- seen_altar(GOD_OKAWARU);
- break;
-
- case DNGN_ALTAR_MAKHLEB:
- *color = RED;
- if (one_chance_in(3))
- *color = LIGHTRED;
- if (one_chance_in(3))
- *color = YELLOW;
- *ch = 220;
- seen_altar(GOD_MAKHLEB);
- break;
-
- case DNGN_ALTAR_SIF_MUNA:
- *color = BLUE;
- *ch = 220;
- seen_altar(GOD_SIF_MUNA);
- break;
-
- case DNGN_ALTAR_TROG:
- *color = RED;
- *ch = 220;
- seen_altar(GOD_TROG);
- break;
-
- case DNGN_ALTAR_NEMELEX_XOBEH:
- *color = LIGHTMAGENTA;
- *ch = 220;
- seen_altar(GOD_NEMELEX_XOBEH);
- break;
-
- case DNGN_ALTAR_ELYVILON:
- *color = LIGHTGREY;
- *ch = 220;
- seen_altar(GOD_ELYVILON);
- break;
-
- case DNGN_BLUE_FOUNTAIN:
- *color = BLUE;
- *ch = 159;
- break;
-
- case DNGN_SPARKLING_FOUNTAIN:
- *color = LIGHTBLUE;
- *ch = 159;
- break;
-
- case DNGN_DRY_FOUNTAIN_I:
- case DNGN_DRY_FOUNTAIN_II:
- case DNGN_PERMADRY_FOUNTAIN:
- *color = LIGHTGREY;
- *ch = 159;
- break;
-
- case 256:
- *ch = '0';
- break;
-
- case 257:
- *color = CYAN;
- *ch = '~';
- break; /* Invis creature walking through water */
-
- case 258:
- *ch = ')';
- break; // weapon )
-
- case 259:
- *ch = '[';
- break; // armour [
-
- case 260:
- *ch = '/';
- break; // wands, etc.
-
- case 261:
- *ch = '%';
- break; // food
-
- case 262:
- *ch = '+';
- break; // books +
-
- case 263:
- *ch = '?';
- break; // scroll ?
-
- case 264:
- *ch = '=';
- break; // ring = etc
-
- case 265:
- *ch = '!';
- break; // potions !
-
- case 266:
- *ch = '(';
- break; // stones
-
- case 267:
- *ch = '+';
- break; // book +
-
- case 268:
- *ch = '%';
- break; // corpses part 1
-
- case 269:
- *ch = '\\';
- break; // magical staves
-
- case 270:
- *ch = '}';
- break; // gems
-
- case 271:
- *ch = '%';
- break; // don't know ?
-
- case 272:
- *ch = '$';
- *color = YELLOW;
- break; // $ gold
-
- case 273:
- *ch = '"';
- break; // amulet
-
- default:
- *ch = ((object >= 297) ? mons_char(object - 297) : object);
- break;
- }
-} // end get_ibm_symbol()
-
-//---------------------------------------------------------------
-//
-// viewwindow2
-//
-// Draws the main window using the extended IBM character set.
-//
-// This function should not interfer with the game condition,
-// unless do_updates is set (ie. stealth checks for visible
-// monsters).
-//
-//---------------------------------------------------------------
-void viewwindow2(char draw_it, bool do_updates)
-{
- const long BUFFER_SIZE = 1550;
-#ifdef DOS_TERM
- // DOS functions like gettext() and puttext() can only
- // work with arrays of characters, not shorts.
- FixedVector < unsigned char, BUFFER_SIZE > buffy; //[800]; //392];
-#else
- FixedVector < unsigned short, BUFFER_SIZE > buffy; //[800]; //392];
-#endif
-
- unsigned short ch, color;
-
- losight(env.show, grd, you.x_pos, you.y_pos);
-
- int count_x, count_y;
-
- for (count_x = 0; count_x < 18; count_x++)
- {
- for (count_y = 0; count_y < 18; count_y++)
- {
- env.show_col[count_x][count_y] = LIGHTGREY;
- show_backup[count_x][count_y] = 0;
- }
- }
-
- item();
- cloud_grid();
- monster_grid(do_updates);
- int bufcount = 0;
-
- if (draw_it == 1)
- {
- _setcursortype(_NOCURSOR);
- for (count_y = you.y_pos - 8; count_y < you.y_pos + 9; count_y++)
- {
- bufcount += 16;
-
- for (count_x = you.x_pos - 8; count_x < you.x_pos + 9; count_x++)
- {
- // may be overriden by the code below
- color = env.show_col[ count_x - you.x_pos + 9 ]
- [ count_y - you.y_pos + 9 ];
-
- unsigned int object = env.show[ count_x - you.x_pos + 9 ]
- [ count_y - you.y_pos + 9 ];
-
- get_ibm_symbol(object, &ch, &color);
-
- if (count_x == you.x_pos && count_y == you.y_pos)
- {
- ch = your_sign;
-
- if (player_is_swimming())
- {
- color = (grd[you.x_pos][you.y_pos] == DNGN_DEEP_WATER)
- ? BLUE : CYAN;
- }
- else
- {
- color = your_colour;
- }
- }
-
- ASSERT(bufcount + 1 < BUFFER_SIZE);
- buffy[bufcount] = ch;
- buffy[bufcount + 1] = color;
-
- bufcount += 2;
- }
-
- bufcount += 16;
- }
-
- if (you.level_type != LEVEL_LABYRINTH && you.level_type != LEVEL_ABYSS)
- {
- bufcount = 0;
-
- for (count_y = 0; count_y < 17; count_y++)
- {
- bufcount += 16;
-
- for (count_x = 0; count_x < 17; count_x++)
- {
- ASSERT(bufcount < BUFFER_SIZE);
-
- int mapx = count_x + you.x_pos - 9;
- int mapy = count_y + you.y_pos - 9;
- if (buffy[bufcount] != 0 && mapx >= 0 && mapx + 1 < GXM
- && mapy >= 0 && mapy + 1 < GYM)
- {
- unsigned short bch = buffy[bufcount];
- if (mgrd[mapx + 1][mapy + 1] != NON_MONSTER) {
- const monsters &m = menv[mgrd[mapx + 1][mapy + 1]];
- if (!mons_is_mimic(m.type)
- && mons_char(m.type) == bch)
- {
- bch |= mons_colour(m.type) << 12;
- }
- }
- env.map[mapx][mapy] = bch;
- }
-
- if (Options.clean_map == 1
- && show_backup[count_x + 1][count_y + 1] != 0)
- {
- get_ibm_symbol(show_backup[count_x + 1][count_y + 1],
- &ch, &color);
- if (mapx >= 0 && mapx < GXM
- && mapy >= 0 && mapy < GYM)
- env.map[ count_x + you.x_pos - 9 ]
- [ count_y + you.y_pos - 9 ] = ch;
- }
- bufcount += 2;
- }
- bufcount += 16;
- }
- }
-
- bufcount = 0;
- for (count_y = 0; count_y < 17; count_y++)
- {
- for (count_x = 0; count_x < 33; count_x++)
- {
- if (count_x + you.x_pos - 17 < 3
- || count_y + you.y_pos - 9 < 3
- || count_x + you.x_pos - 14 > 77
- || count_y + you.y_pos - 9 > 67)
- {
- ASSERT(bufcount < BUFFER_SIZE);
- buffy[bufcount] = 0;
- bufcount++;
- buffy[bufcount] = 0;
- bufcount++;
- continue;
- }
-
- if (count_x >= 8 && count_x <= 24 && count_y >= 0
- && count_y <= 16 && buffy[bufcount] != 0)
- {
- bufcount += 2;
- continue;
- }
-
- ASSERT(bufcount + 1 < BUFFER_SIZE);
-
- buffy[bufcount] = (unsigned char)
- env.map[ count_x + you.x_pos - 17 ]
- [ count_y + you.y_pos - 9 ];
-
- buffy[bufcount + 1] = DARKGREY;
- if (Options.colour_map)
- {
- if (env.map[ count_x + you.x_pos - 17 ]
- [ count_y + you.y_pos - 9 ] != 0)
- {
- buffy[bufcount + 1]
- = colour_code_map( count_x + you.x_pos - 17,
- count_y + you.y_pos - 9,
- Options.item_colour );
- }
- }
-
- bufcount += 2;
- }
- }
-
- const int flash_colour =
- you.flash_colour != BLACK? you.flash_colour :
- you.berserker ? RED :
- show_green != BLACK ? show_green :
- you.special_wield == SPWLD_SHADOW? DARKGREY :
- BLACK;
- if (flash_colour != BLACK)
- {
- for (count_x = 1; count_x < 1400; count_x += 2)
- {
- if (buffy[count_x] != DARKGREY)
- buffy[count_x] = flash_colour;
- }
-
- if (show_green != BLACK)
- {
- show_green = BLACK;
- if (you.special_wield == SPWLD_SHADOW)
- show_green = DARKGREY;
- }
- }
-
- you.flash_colour = BLACK;
-
-#ifdef DOS_TERM
- puttext(2, 1, 34, 17, buffy.buffer());
-#endif
-
-#ifdef PLAIN_TERM
- gotoxy(2, 1);
- bufcount = 0;
-
- // following lines are purely optional.
- // if used, players will 'jump' move.
- // Resting will be a LOT faster too.
- if (you.running == 0 || (you.running < 0 && Options.travel_delay > -1))
- {
- for (count_x = 0; count_x < 1120; count_x += 2)
- { // 1056
- ch = buffy[count_x];
- color = buffy[count_x + 1];
-// ASSERT(color < 16);
- ASSERT(ch < 255);
-
- textcolor(color);
- putch(ch);
-
- if (count_x % 66 == 64 && count_x > 0)
- gotoxy(2, wherey() + 1);
- }
- // remember to comment out the line below if you comment out jump move.
- }
- _setcursortype(_NORMALCURSOR);
-#endif
- }
-} // end viewwindow2()
-
-static char get_travel_colour( int x, int y )
-{
- if (is_waypoint(x + 1, y + 1))
- return LIGHTGREEN;
-
- short dist = point_distance[x + 1]
- [y + 1];
- return dist > 0 ? BLUE :
- dist == PD_EXCLUDED ? LIGHTMAGENTA :
- dist == PD_EXCLUDED_RADIUS ? RED :
- dist < 0 ? CYAN :
- DARKGREY;
-}
-
-#if defined(WIN32CONSOLE) || defined(DOS)
-static unsigned short dos_reverse_brand(unsigned short colour)
-{
- if (Options.dos_use_background_intensity)
- {
- // If the console treats the intensity bit on background colours
- // correctly, we can do a very simple colour invert.
-
- // Special casery for shadows. Note this must be matched by the fix
- // to libw32c.cc (the unpatched libw32c.cc does not draw spaces of any
- // colour).
- if (colour == BLACK)
- colour = (DARKGREY << 4);
- else
- colour = (colour & 0xF) << 4;
- }
- else
- {
- // If we're on a console that takes its DOSness very seriously the
- // background high-intensity bit is actually a blink bit. Blinking is
- // evil, so we strip the background high-intensity bit. This, sadly,
- // limits us to 7 background colours.
-
- // Strip off high-intensity bit. Special case DARKGREY, since it's the
- // high-intensity counterpart of black, and we don't want black on
- // black.
- //
- // We *could* set the foreground colour to WHITE if the background
- // intensity bit is set, but I think we've carried the
- // angry-fruit-salad theme far enough already.
-
- if (colour == DARKGREY)
- colour |= (LIGHTGREY << 4);
- else if (colour == BLACK)
- colour = LIGHTGREY << 4;
- else
- {
- // Zap out any existing background colour, and the high
- // intensity bit.
- colour &= 7;
-
- // And swap the foreground colour over to the background
- // colour, leaving the foreground black.
- colour <<= 4;
- }
- }
-
- return (colour);
-}
-
-static unsigned short dos_hilite_brand(unsigned short colour,
- unsigned short hilite)
-{
- if (!hilite)
- return (colour);
-
- if (colour == hilite)
- colour = 0;
-
- colour |= (hilite << 4);
- return (colour);
-}
-
-static unsigned short dos_brand( unsigned short colour,
- unsigned brand = CHATTR_REVERSE )
-{
- if ((brand & CHATTR_ATTRMASK) == CHATTR_NORMAL)
- return (colour);
-
- colour &= 0xFF;
-
- if ((brand & CHATTR_ATTRMASK) == CHATTR_HILITE)
- return dos_hilite_brand(colour, (brand & CHATTR_COLMASK) >> 8);
- else
- return dos_reverse_brand(colour);
-
-}
-#endif
-
-screen_buffer_t colour_code_map( int x, int y, bool item_colour,
- bool travel_colour )
-{
- // XXX: Yes, the map array and the grid array are off by one. -- bwr
- const int map_value = (unsigned char) env.map[x][y];
- const unsigned short map_flags = env.map[x][y] & ENVF_FLAGS;
- const int grid_value = grd[x + 1][y + 1];
-
- char tc = travel_colour? get_travel_colour(x, y) : DARKGREY;
-
- if (map_flags & ENVF_DETECT_ITEM)
- tc = Options.detected_item_colour;
-
- if (map_flags & ENVF_DETECT_MONS) {
- tc = Options.detected_monster_colour;
- return (tc);
- }
-
- unsigned char ecol = ENVF_COLOR(map_flags);
- if (ecol) {
- unsigned rmc = Options.remembered_monster_colour & 0xFFFF;
- if (rmc == 0xFFFF) // Use real colour
- tc = ecol;
- else if (rmc == 0) // Don't colour
- ;
- else
- tc = rmc;
- }
-
- // XXX: [ds] If we've an important colour, override other feature
- // colouring. Yes, this is hacky. Story of my life.
- if (tc == LIGHTGREEN || tc == LIGHTMAGENTA)
- return tc;
-
- // XXX: Yeah, this is ugly, but until we have stored layers in the
- // map we can't tell if we've seen a square, detected it, or just
- // detected the item or monster on top... giving colour here will
- // result in detect creature/item detecting features like stairs. -- bwr
- if (map_value != mapch2( grid_value )) {
- // If there's an item on this square, change colour to indicate
- // that, iff the item's glyph matches map_value. XXX: Potentially
- // abusable? -- ds
- int item = igrd[x + 1][y + 1];
- if (item_colour && item != NON_ITEM
- && map_value == display_glyph(item_env_glyph(mitm[item])))
- {
- screen_buffer_t ic = mitm[item].colour;
-
-#if defined(WIN32CONSOLE) || defined(DOS) || defined(DOS_TERM)
- if (mitm[item].link != NON_ITEM
- && Options.heap_brand != CHATTR_NORMAL)
- {
- ic = dos_brand(ic, Options.heap_brand);
- }
-#elif defined(USE_COLOUR_OPTS)
- if (mitm[item].link != NON_ITEM )
- {
- ic |= COLFLAG_ITEM_HEAP;
- }
-#endif
- // If the item colour is the background colour, tweak it to WHITE
- // instead to catch the player's eye.
- return ic == tc? WHITE : ic;
- }
-
- return tc;
- }
-
- switch (grid_value)
- {
- case DNGN_TRAP_MECHANICAL:
- return (LIGHTCYAN);
-
- case DNGN_TRAP_MAGICAL:
- case DNGN_TRAP_III:
- return (MAGENTA);
-
- case DNGN_ENTER_SHOP:
- return (YELLOW);
-
- case DNGN_ENTER_DIS:
- return (CYAN);
-
- case DNGN_ENTER_HELL:
- case DNGN_ENTER_GEHENNA:
- return (RED);
-
- case DNGN_ENTER_COCYTUS:
- return (LIGHTCYAN);
-
- case DNGN_ENTER_ABYSS:
- return random2(16); // so it can be black - is this right? {dlb}
-
- case DNGN_ENTER_LABYRINTH:
- case DNGN_STONE_ARCH:
- return (LIGHTGREY);
-
- case DNGN_ENTER_PANDEMONIUM:
- return (LIGHTBLUE);
-
- case DNGN_EXIT_PANDEMONIUM:
- // Exit pandemonium gates won't show up on the map as light blue
- // unless the character has the "gate to pandemonium" demonspawn
- // mutation. This is so that the player can't quickly use a
- // crystal ball to find their way out. -- bwr
- return (you.mutation[MUT_PANDEMONIUM] ? LIGHTBLUE : LIGHTGREEN);
-
- case DNGN_TRANSIT_PANDEMONIUM:
- return (LIGHTGREEN);
-
- case DNGN_ENTER_ZOT:
- case DNGN_RETURN_FROM_ZOT:
- return (MAGENTA);
-
- case DNGN_STONE_STAIRS_DOWN_I:
- case DNGN_STONE_STAIRS_DOWN_II:
- case DNGN_STONE_STAIRS_DOWN_III:
- case DNGN_ROCK_STAIRS_DOWN:
- return (RED);
-
- case DNGN_STONE_STAIRS_UP_I:
- case DNGN_STONE_STAIRS_UP_II:
- case DNGN_STONE_STAIRS_UP_III:
- case DNGN_ROCK_STAIRS_UP:
- return (GREEN);
-
- case DNGN_ENTER_ORCISH_MINES:
- case DNGN_ENTER_HIVE:
- case DNGN_ENTER_LAIR:
- case DNGN_ENTER_SLIME_PITS:
- case DNGN_ENTER_VAULTS:
- case DNGN_ENTER_CRYPT:
- case DNGN_ENTER_HALL_OF_BLADES:
- case DNGN_ENTER_TEMPLE:
- case DNGN_ENTER_SNAKE_PIT:
- case DNGN_ENTER_ELVEN_HALLS:
- case DNGN_ENTER_TOMB:
- case DNGN_ENTER_SWAMP:
- case 123:
- case 124:
- case 125:
- case 126:
- return (LIGHTRED);
-
- case DNGN_RETURN_FROM_ORCISH_MINES:
- case DNGN_RETURN_FROM_HIVE:
- case DNGN_RETURN_FROM_LAIR:
- case DNGN_RETURN_FROM_SLIME_PITS:
- case DNGN_RETURN_FROM_VAULTS:
- case DNGN_RETURN_FROM_CRYPT:
- case DNGN_RETURN_FROM_HALL_OF_BLADES:
- case DNGN_RETURN_FROM_TEMPLE:
- case DNGN_RETURN_FROM_SNAKE_PIT:
- case DNGN_RETURN_FROM_ELVEN_HALLS:
- case DNGN_RETURN_FROM_TOMB:
- case DNGN_RETURN_FROM_SWAMP:
- case 143:
- case 144:
- case 145:
- case 146:
- return (LIGHTBLUE);
-
- default:
- break;
- }
-
- return tc;
-}
-
-void clear_map()
-{
- for (int y = 0; y < GYM - 1; ++y)
- {
- for (int x = 0; x < GXM - 1; ++x)
- {
- unsigned short envc = env.map[x][y];
- if (!envc)
- continue;
-
- bool unmapped = (envc & ENVF_DETECTED) != 0;
- // Discard flags at this point.
- envc = (unsigned char) envc;
-
- const unsigned char &grdc = grd[x + 1][y + 1];
- if (envc == mapch(grdc) || envc == mapch2(grdc))
- continue;
-
- int item = igrd[x + 1][y + 1];
- if (item != NON_ITEM
- && envc == display_glyph(item_env_glyph(mitm[item])))
- continue;
-
- env.map[x][y] = unmapped? 0 : mapch2(grdc);
- }
- }
-}
-
-void monster_grid(bool do_updates)
-{
- struct monsters *monster = 0; // NULL {dlb}
-
- for (int s = 0; s < MAX_MONSTERS; s++)
- {
- monster = &menv[s];
-
- if (monster->type != -1 && mons_near(monster))
- {
- if (do_updates
- && (monster->behaviour == BEH_SLEEP
- || monster->behaviour == BEH_WANDER)
- && check_awaken(s))
- {
- behaviour_event( monster, ME_ALERT, MHITYOU );
-
- if (you.turn_is_over == 1
- && mons_shouts(monster->type) > 0
- && random2(30) >= you.skills[SK_STEALTH])
- {
- int noise_level = 8;
-
- if (!mons_friendly(monster)
- && (!silenced(you.x_pos, you.y_pos)
- && !silenced(monster->x, monster->y)))
- {
- if (mons_is_demon( monster->type ) && coinflip())
- {
- if (monster->type == MONS_IMP
- || monster->type == MONS_WHITE_IMP
- || monster->type == MONS_SHADOW_IMP)
- {
- imp_taunt( monster );
- }
- else
- {
- demon_taunt( monster );
- }
- }
- else
- {
- int the_shout = mons_shouts(monster->type);
-
- strcpy(info, "You hear ");
- switch (the_shout)
- {
- case S_SILENT:
- default:
- strcat(info, "buggy behaviour!");
- break;
- case S_SHOUT:
- strcat(info, "a shout!");
- break;
- case S_BARK:
- strcat(info, "a bark!");
- break;
- case S_SHOUT2:
- strcat(info, "two shouts!");
- noise_level = 12;
- break;
- case S_ROAR:
- strcat(info, "a roar!");
- noise_level = 12;
- break;
- case S_SCREAM:
- strcat(info, "a hideous shriek!");
- break;
- case S_BELLOW:
- strcat(info, "a bellow!");
- break;
- case S_SCREECH:
- strcat(info, "a screech!");
- break;
- case S_BUZZ:
- strcat(info, "an angry buzzing noise.");
- break;
- case S_MOAN:
- strcat(info, "a chilling moan.");
- break;
- case S_WHINE:
- strcat(info,
- "an irritating high-pitched whine.");
- break;
- case S_CROAK:
- if (coinflip())
- strcat(info, "a loud, deep croak!");
- else
- strcat(info, "a croak.");
- break;
- case S_GROWL:
- strcat(info, "an angry growl!");
- break;
- case S_HISS:
- strcat(info, "an angry hiss!");
- noise_level = 4; // not very loud -- bwr
- break;
- }
-
- mpr(info);
- }
- }
-
- noisy( noise_level, monster->x, monster->y );
- }
- }
-
- if (!player_monster_visible( monster ))
- {
- // ripple effect?
- if (grd[monster->x][monster->y] == DNGN_SHALLOW_WATER
- && !mons_flies(monster))
- {
- show_backup[ monster->x - you.x_pos + 9 ]
- [ monster->y - you.y_pos + 9]
- = env.show[ monster->x - you.x_pos + 9 ]
- [ monster->y - you.y_pos + 9 ];
- env.show[monster->x - you.x_pos + 9]
- [monster->y - you.y_pos + 9] = 257;
- }
- continue;
- }
- else if (!mons_friendly( monster )
- && !mons_is_mimic( monster->type )
- && !mons_class_flag( monster->type, M_NO_EXP_GAIN ))
- {
- interrupt_activity( AI_SEE_MONSTER );
- if (you.running != 0
-#ifdef CLUA_BINDINGS
- && clua.callbooleanfn(true, "ch_stop_run",
- "M", monster)
-#endif
- )
- {
- // Friendly monsters, mimics, or harmless monsters
- // don't disturb the player's running/resting.
- //
- // Doing it this way causes players in run mode 2
- // to move one square, and in mode 1 to stop. This
- // means that the character will run one square if
- // a monster is in sight... we automatically jump
- // to zero if we're resting. -- bwr
- if (you.run_x == 0 && you.run_y == 0)
- stop_running();
- else if (you.running > 1)
- you.running--;
- else
- stop_running();
- }
- }
-
- // mimics are always left on map
- if (!mons_is_mimic( monster->type ))
- {
- show_backup[monster->x - you.x_pos + 9]
- [monster->y - you.y_pos + 9]
- = env.show[monster->x - you.x_pos + 9]
- [monster->y - you.y_pos + 9];
- }
-
- env.show[monster->x - you.x_pos + 9]
- [monster->y - you.y_pos + 9] = monster->type + 297;
-
- env.show_col[monster->x - you.x_pos + 9]
- [monster->y - you.y_pos + 9]
- = ((mcolour[monster->type] == BLACK)
- ? monster->number : mcolour[monster->type]);
-#ifdef USE_COLOUR_OPTS
- if (mons_friendly(monster))
- {
- env.show_col[monster->x - you.x_pos + 9]
- [monster->y - you.y_pos + 9]
- |= COLFLAG_FRIENDLY_MONSTER;
- }
- else if (Options.stab_brand != CHATTR_NORMAL
- && mons_looks_stabbable(monster))
- {
- env.show_col[monster->x - you.x_pos + 9]
- [monster->y - you.y_pos + 9]
- |= COLFLAG_WILLSTAB;
- }
- else if (Options.may_stab_brand != CHATTR_NORMAL
- && mons_looks_distracted(monster))
- {
- env.show_col[monster->x - you.x_pos + 9]
- [monster->y - you.y_pos + 9]
- |= COLFLAG_MAYSTAB;
- }
-
-#elif defined(WIN32CONSOLE) || defined(DOS)
- if (Options.friend_brand != CHATTR_NORMAL
- && mons_friendly(monster))
- {
- // We munge the colours right here for DOS and Windows, because
- // we know exactly how the colours will be handled, and we don't
- // want to change both DOS and Windows port code to handle
- // friend branding.
- unsigned short &colour =
- env.show_col[monster->x - you.x_pos + 9]
- [monster->y - you.y_pos + 9];
- colour = dos_brand(colour, Options.friend_brand);
- }
-
- if (Options.stab_brand != CHATTR_NORMAL
- && mons_looks_stabbable(monster))
- {
- unsigned short &colour =
- env.show_col[monster->x - you.x_pos + 9]
- [monster->y - you.y_pos + 9];
- colour = dos_brand(colour, Options.stab_brand);
- }
- else if (Options.may_stab_brand != CHATTR_NORMAL
- && mons_looks_distracted(monster))
- {
- unsigned short &colour =
- env.show_col[monster->x - you.x_pos + 9]
- [monster->y - you.y_pos + 9];
- colour = dos_brand(colour, Options.may_stab_brand);
- }
-#endif
- } // end "if (monster->type != -1 && mons_ner)"
- } // end "for s"
-} // end monster_grid()
-
-
-bool check_awaken(int mons_aw)
-{
- int mons_perc = 0;
- struct monsters *monster = &menv[mons_aw];
- const int mon_holy = mons_holiness(monster);
-
- // berserkers aren't really concerned about stealth
- if (you.berserker)
- return (true);
-
- // Repel undead is a holy aura, to which evil creatures are sensitive.
- // Note that even though demons aren't affected by repel undead, they
- // do sense this type of divine aura. -- bwr
- if (you.duration[DUR_REPEL_UNDEAD]
- && (mon_holy == MH_UNDEAD || mon_holy == MH_DEMONIC))
- {
- return (true);
- }
-
- // I assume that creatures who can see invisible are very perceptive
- mons_perc = 10 + (mons_intel(monster->type) * 4) + monster->hit_dice
- + mons_see_invis(monster) * 5;
-
- // critters that are wandering still have MHITYOU as their foe are
- // still actively on guard for the player, even if they can't see
- // him. Give them a large bonus (handle_behaviour() will nuke 'foe'
- // after a while, removing this bonus.
- if (monster->behaviour == BEH_WANDER && monster->foe == MHITYOU)
- mons_perc += 15;
-
- if (!mons_player_visible(monster))
- mons_perc -= 75;
-
- if (monster->behaviour == BEH_SLEEP)
- {
- if (mon_holy == MH_NATURAL)
- {
- // monster is "hibernating"... reduce chance of waking
- if (mons_has_ench( monster, ENCH_SLEEP_WARY ))
- mons_perc -= 10;
- }
- else // unnatural creature
- {
- // Unnatural monsters don't actually "sleep", they just
- // haven't noticed an intruder yet... we'll assume that
- // they're diligently on guard.
- mons_perc += 10;
- }
- }
-
- // glowing with magical contamination isn't very stealthy
- if (you.magic_contamination > 10)
- mons_perc += you.magic_contamination - 10;
-
- if (mons_perc < 0)
- mons_perc = 0;
-
- return (random2(stealth) <= mons_perc);
-} // end check_awaken()
-
-static int display_glyph(int env_glyph)
-{
- unsigned short ch, color;
- if (viewwindow == viewwindow2)
- get_ibm_symbol(env_glyph, &ch, &color);
- else
- get_non_ibm_symbol(env_glyph, &ch, &color);
- return ch;
-}
-
-static int item_env_glyph(const item_def &item)
-{
- switch (item.base_type)
- {
- case OBJ_ORBS:
- return 256;
- // need + 6 because show is 0 - 12, not -6 - +6
- case OBJ_WEAPONS:
- case OBJ_MISSILES:
- return 258;
- case OBJ_ARMOUR:
- return 259;
- case OBJ_WANDS:
- return 260;
- case OBJ_FOOD:
- return 261;
- case OBJ_UNKNOWN_I:
- return 262;
- case OBJ_SCROLLS:
- return 263;
- case OBJ_JEWELLERY:
- return item.sub_type >= AMU_RAGE? 273 : 264;
- case OBJ_POTIONS:
- return 265;
- case OBJ_UNKNOWN_II:
- return 266;
- case OBJ_BOOKS:
- return 267;
- case OBJ_STAVES:
- return 269;
- case OBJ_MISCELLANY:
- return 270;
- case OBJ_CORPSES:
- return 271;
- case OBJ_GOLD:
- return 272;
- default:
- return '8';
- }
-}
-
-void item()
-{
- char count_x, count_y;
-
- for (count_y = (you.y_pos - 8); (count_y < you.y_pos + 9); count_y++)
- {
- for (count_x = (you.x_pos - 8); (count_x < you.x_pos + 9); count_x++)
- {
- if (count_x >= 0 && count_x < GXM && count_y >= 0 && count_y < GYM)
- {
- if (igrd[count_x][count_y] != NON_ITEM)
- {
- if (env.show[count_x - you.x_pos + 9]
- [count_y - you.y_pos + 9] != 0)
- {
- const item_def &eitem = mitm[igrd[count_x][count_y]];
- unsigned short &ecol =
- env.show_col[count_x - you.x_pos + 9]
- [count_y - you.y_pos + 9];
-
- ecol = (grd[count_x][count_y] == DNGN_SHALLOW_WATER)?
- CYAN
- : eitem.colour;
-
-#ifdef USE_COLOUR_OPTS
- if (eitem.link != NON_ITEM)
- {
- ecol |= COLFLAG_ITEM_HEAP;
- }
-#elif defined(WIN32CONSOLE) || defined(DOS)
- if (eitem.link != NON_ITEM
- && Options.heap_brand != CHATTR_NORMAL)
- {
- // Yes, exact same code as friend-branding.
- ecol = dos_brand(ecol, Options.heap_brand);
- }
-#endif
- env.show[count_x - you.x_pos + 9]
- [count_y - you.y_pos + 9] =
- item_env_glyph( eitem );
- }
- }
- }
- } // end of "for count_y, count_x"
- }
-} // end item()
-
-
-void cloud_grid(void)
-{
- int mnc = 0;
-
- // btw, this is also the 'default' color {dlb}
- unsigned char which_color = LIGHTGREY;
-
- for (int s = 0; s < MAX_CLOUDS; s++)
- {
- // can anyone explain this??? {dlb}
- // its an optimization to avoid looking past the last cloud -bwr
- if (mnc > env.cloud_no)
- break;
-
- if (env.cloud[s].type != CLOUD_NONE)
- {
- mnc++;
-
- if (see_grid(env.cloud[s].x, env.cloud[s].y))
- {
- show_backup[env.cloud[s].x - you.x_pos + 9]
- [env.cloud[s].y - you.y_pos + 9]
- = env.show[env.cloud[s].x - you.x_pos + 9]
- [env.cloud[s].y - you.y_pos + 9];
-
- env.show[env.cloud[s].x - you.x_pos + 9]
- [env.cloud[s].y - you.y_pos + 9] = '#';
-
- switch (env.cloud[s].type)
- {
- case CLOUD_FIRE:
- case CLOUD_FIRE_MON:
- if (env.cloud[s].decay <= 20)
- which_color = RED;
- else if (env.cloud[s].decay <= 40)
- which_color = LIGHTRED;
- else if (one_chance_in(4))
- which_color = RED;
- else if (one_chance_in(4))
- which_color = LIGHTRED;
- else
- which_color = YELLOW;
- break;
-
- case CLOUD_STINK:
- case CLOUD_STINK_MON:
- which_color = GREEN;
- break;
-
- case CLOUD_COLD:
- case CLOUD_COLD_MON:
- if (env.cloud[s].decay <= 20)
- which_color = BLUE;
- else if (env.cloud[s].decay <= 40)
- which_color = LIGHTBLUE;
- else if (one_chance_in(4))
- which_color = BLUE;
- else if (one_chance_in(4))
- which_color = LIGHTBLUE;
- else
- which_color = WHITE;
- break;
-
- case CLOUD_POISON:
- case CLOUD_POISON_MON:
- which_color = (one_chance_in(3) ? LIGHTGREEN : GREEN);
- break;
-
- case CLOUD_BLUE_SMOKE:
- case CLOUD_BLUE_SMOKE_MON:
- which_color = LIGHTBLUE;
- break;
-
- case CLOUD_PURP_SMOKE:
- case CLOUD_PURP_SMOKE_MON:
- which_color = MAGENTA;
- break;
-
- case CLOUD_MIASMA:
- case CLOUD_MIASMA_MON:
- case CLOUD_BLACK_SMOKE:
- case CLOUD_BLACK_SMOKE_MON:
- which_color = DARKGREY;
- break;
-
- default:
- which_color = LIGHTGREY;
- break;
- }
-
- env.show_col[env.cloud[s].x - you.x_pos + 9]
- [env.cloud[s].y - you.y_pos + 9] = which_color;
- }
- } // end 'if != CLOUD_NONE'
- } // end 'for s' loop
-} // end cloud_grid()
-
-// Noisy now has a messenging service for giving messages to the
-// player is appropriate.
-//
-// Returns true if the PC heard the noise.
-bool noisy( int loudness, int nois_x, int nois_y, const char *msg )
-{
- int p;
- struct monsters *monster = 0; // NULL {dlb}
- bool ret = false;
-
- // If the origin is silenced there is no noise.
- if (silenced( nois_x, nois_y ))
- return (false);
-
- const int dist = loudness * loudness;
-
- // message the player
- if (distance( you.x_pos, you.y_pos, nois_x, nois_y ) <= dist
- && player_can_hear( nois_x, nois_y ))
- {
- if (msg)
- mpr( msg, MSGCH_SOUND );
-
- ret = true;
- }
-
- for (p = 0; p < MAX_MONSTERS; p++)
- {
- monster = &menv[p];
-
- if (monster->type < 0)
- continue;
-
- if (distance(monster->x, monster->y, nois_x, nois_y) <= dist
- && !silenced(monster->x, monster->y))
- {
- // If the noise came from the character, any nearby monster
- // will be jumping on top of them.
- if (nois_x == you.x_pos && nois_y == you.y_pos)
- behaviour_event( monster, ME_ALERT, MHITYOU );
- else
- behaviour_event( monster, ME_DISTURB, MHITNOT, nois_x, nois_y );
- }
- }
-
- return (ret);
-} // end noisy()
-
-/* ========================================================================
- * brand new LOS code
- * ========================================================================
- * The new LOS works via a new (I think) shadow casting algorithm,
- * plus an esthetic tweak for more pleasing corner illumination. More
- * detail can be had by contacting its author, Gordon Lipford. */
-
-#define MAX_LIGHT_RADIUS 20
-#define CIRC_MAX 32000
-#define BIG_SHADOW 32000
-
-// the following two constants represent the 'middle' of the sh array.
-// since the current shown area is 19x19, centering the view at (9,9)
-// means it will be exactly centered.
-// This is done to accomodate possible future changes in viewable screen
-// area - simply change sh_xo and sh_yo to the new view center.
-
-const int sh_xo = 9; // X and Y origins for the sh array
-const int sh_yo = 9;
-
-// the Cell class, used in the shadow-casting LOS algorithm
-class Cell
-{
-
-public:
- int up_count;
- int up_max;
- int low_count;
- int low_max;
- bool lit;
- bool lit_delay;
- bool visible; // for blockers only
- void init();
- bool reachedLower();
- bool reachedUpper();
-
- Cell()
- {
- init();
- };
-};
-
-void Cell::init()
-{
- up_count = 0;
- up_max = 0;
- low_count = 0;
- low_max = 0;
- lit = true;
- visible = true;
- lit_delay = false;
-}
-
-bool Cell::reachedLower()
-{
- // integer math: a 'step' has a value of 10
- // see if we're within a half step of the max. VERY important
- // to use 'half step' or else things look really stupid.
- if (low_max != 0 && low_count + 5 >= low_max && low_count - 5 < low_max)
- return true;
-
- return false;
-}
-
-bool Cell::reachedUpper()
-{
- // see if we're within a half step of the max. VERY important
- // to use 'half step' or else things look really stupid.
- if (up_max != 0 && up_count + 5 >= up_max && up_count - 5 < up_max)
- return true;
-
- return false;
-}
-
-// the cell array
-static FixedVector < Cell, MAX_LIGHT_RADIUS + 1 > cells;
-
-// the 'circle' array. For any given row, we won't check higher than
-// this given cell.
-static FixedVector < int, MAX_LIGHT_RADIUS + 1 > circle;
-
-// current light radius
-static int LR = 0;
-
-// View constant
-const int view = 2; // 1=widest LOS .. 5=narrowest
-
-// initialize LOS code for a given light radius
-extern void setLOSRadius(int newLR)
-{
- int i, j;
-
- // sanity check - also allows multiple calls w/out performance loss
- if (LR == newLR)
- return;
-
- LR = newLR;
- // cells should already be initted. calculate the circle array.
-
- // note that rows 0 and 1 will always go to infinity.
- circle[0] = circle[1] = CIRC_MAX;
-
- // for the rest, simply calculate max height based on light rad.
- for (i = 2; i <= LR; i++)
- {
- // check top
- if (2 * i * i <= LR * LR)
- {
- circle[i] = CIRC_MAX;
- continue;
- }
-
- for (j = i - 1; j >= 0; j--)
- {
- // check that Distance (I^2 + J^2) is no more than (R+0.5)^2
- // this rounding allows for *much* better looking circles.
- if (i * i + j * j <= LR * LR + LR)
- {
- circle[i] = j;
- break;
- }
- }
- }
-}
-
-static int calcUpper(int bX, int bY)
-{
- // got a blocker at row bX, cell bY. do all values
- // and scale by a factor of 10 for the integer math.
- int upper;
-
- upper = (10 * (10 * bX - view)) / (10 * bY + view);
- if (upper < 10) // upper bound for blocker on diagonal
- upper = 10;
-
- return upper;
-}
-
-static int calcLower(int bX, int bY)
-{
- // got a blocker at row bX, cell bY. do all values
- // and scale by a factor of 10 for the integer math.
-
- if (bY == 0)
- return BIG_SHADOW;
-
- return (10 * (10 * bX + view)) / (10 * bY - view);
-}
-
-// for easy x,y octant translation
-static int xxcomp[8] = { 1, 0, 0, -1, -1, 0, 0, 1 };
-static int xycomp[8] = { 0, 1, -1, 0, 0, -1, 1, 0 };
-static int yxcomp[8] = { 0, 1, 1, 0, 0, -1, -1, 0 };
-static int yycomp[8] = { 1, 0, 0, 1, -1, 0, 0, -1 };
-
-static void los_octant(int o, FixedArray < unsigned int, 19, 19 > &sh,
- FixedArray < unsigned char, 80, 70 > &gr, int x_p,
- int y_p)
-{
- int row, cell, top, south;
- int tx, ty; // translated x, y deltas for this octant
- unsigned char gv; // grid value
- bool row_dark, all_dark;
- bool blocker, vis_corner;
- int up_inc, low_inc;
-
- // leave [0,0] alone, because the old LOS code seems to.
-
- // init cell[0]. this is the only one that needs clearing.
- cells[0].init();
- all_dark = false;
- vis_corner = false;
-
- // loop through each row
- for (row = 1; row <= LR; row++)
- {
- row_dark = true;
-
- // loop through each cell, up to the max allowed by circle[]
- top = circle[row];
- if (top > row)
- top = row;
-
- for (cell = 0; cell <= top; cell++)
- {
- // translate X,Y co'ord + bounds check
- tx = row * xxcomp[o] + cell * xycomp[o];
- ty = row * yxcomp[o] + cell * yycomp[o];
-
- if (x_p + tx < 0 || x_p + tx > 79 || y_p + ty < 0 || y_p + ty > 69)
- continue;
-
- // check for all_dark - we've finished the octant but
- // have yet to fill in '0' for the rest of the sight grid
- if (all_dark == true)
- {
- sh[sh_xo + tx][sh_yo + ty] = 0;
- continue;
- }
-
- // get grid value.. see if it blocks LOS
- gv = gr[x_p + tx][y_p + ty];
- blocker = (gv < MINSEE);
-
- // init some other variables
- up_inc = 10;
- low_inc = 10;
- south = cell - 1;
-
- // STEP 1 - inherit values from immediate West, if possible
- if (cell < row)
- {
- // check for delayed lighting
- if (cells[cell].lit_delay)
- {
- if (!blocker)
- { // blockers don't light up with lit_delay.
- if (cells[south].lit)
- {
- if (cells[south].low_max != 0)
- {
- cells[cell].lit = false;
- // steal lower values
- cells[cell].low_max = cells[south].low_max;
- cells[cell].low_count = cells[south].low_count;
- cells[south].low_count = 0;
- cells[south].low_max = 0;
- low_inc = 0; // avoid double-inc.
- }
- else
- cells[cell].lit = true;
- }
- }
- cells[cell].lit_delay = false;
- }
- }
- else
- {
- // initialize new cell.
- cells[cell].init();
- }
-
- // STEP 2 - check for blocker
- // a dark blocker in shadow's edge will be visible
- if (blocker)
- {
- if (cells[cell].lit || (cell != 0 && cells[south].lit)
- || vis_corner)
- {
- // hack: make 'corners' visible
- vis_corner = cells[cell].lit;
-
- cells[cell].lit = false;
- cells[cell].visible = true;
-
- int upper = calcUpper(row, cell);
- int lower = calcLower(row, cell);
-
- if (upper < cells[cell].up_max || cells[cell].up_max == 0)
- {
- // new upper shadow
- cells[cell].up_max = upper;
- cells[cell].up_count = 0;
- up_inc = 0;
- }
-
- if (lower > cells[cell].low_max || cells[cell].low_max == 0)
- {
- // new lower shadow
- cells[cell].low_max = lower;
- cells[cell].low_count = -10;
- low_inc = 0;
- if (lower <= 30) // somewhat arbitrary
- cells[cell].lit_delay = true;
- // set dark_delay if lower > 20?? how to decide?
- }
- }
- else
- {
- cells[cell].visible = false;
- }
- }
- else
- {
- cells[cell].visible = false; // special flags for blockers
- }
-
- // STEP 3 - add increments to upper, lower counts
- cells[cell].up_count += up_inc;
- cells[cell].low_count += low_inc;
-
- // STEP 4 - check south for dark
- if (south >= 0)
- if (cells[south].reachedUpper() == true)
- {
- if (cells[cell].reachedUpper() == false)
- {
- cells[cell].up_max = cells[south].up_max;
- cells[cell].up_count = cells[south].up_count;
- cells[cell].up_count -= cells[south].up_max;
- }
- cells[cell].lit = false;
- cells[cell].visible = false;
- }
-
- // STEP 5 - nuke lower if south lower
- if (south >= 0)
- {
- if (cells[south].reachedLower())
- {
- cells[cell].low_max = cells[south].low_max;
- cells[cell].low_count = cells[south].low_count;
- cells[cell].low_count -= cells[south].low_max;
- cells[south].low_count = cells[south].low_max = 0;
- }
-
- if (cells[south].low_max != 0
- || (cells[south].lit == false
- && cells[south].low_max == 0))
- {
- cells[cell].low_count = cells[cell].low_max + 10;
- }
- }
-
- // STEP 6 - light up if we've reached lower bound
- if (cells[cell].reachedLower() == true)
- cells[cell].lit = true;
-
- // now place appropriate value in sh
- if (cells[cell].lit == true
- || (blocker == true && cells[cell].visible == true))
- {
- sh[sh_xo + tx][sh_yo + ty] = gv;
- }
- else
- sh[sh_xo + tx][sh_yo + ty] = 0;
-
- if (cells[cell].lit == true)
- row_dark = false;
- } // end for - cells
-
- vis_corner = false; // don't carry over to next row. :)
- if (row_dark == true)
- all_dark = true;
- } // end for - rows
-}
-
-void losight(FixedArray < unsigned int, 19, 19 > &sh,
- FixedArray < unsigned char, 80, 70 > &gr, int x_p, int y_p)
-{
- int o;
-
- for (o = 0; o < 8; o++)
- los_octant(o, sh, gr, x_p, y_p);
-}
-
-
-void draw_border(void)
-{
- textcolor( BORDER_COLOR );
- clrscr();
- redraw_skill( you.your_name, player_title() );
-
- gotoxy(40, 2);
- cprintf( "%s %s", species_name( you.species, you.experience_level ),
- (you.wizard ? "*WIZARD*" : "" ) );
-
- gotoxy(40, 3); cprintf("HP:");
- gotoxy(40, 4); cprintf("Magic:");
- gotoxy(40, 5); cprintf("AC:");
- gotoxy(40, 6); cprintf("EV:");
- gotoxy(40, 7); cprintf("Str:");
- gotoxy(40, 8); cprintf("Int:");
- gotoxy(40, 9); cprintf("Dex:");
- gotoxy(40, 10); cprintf("Gold:");
- gotoxy(40, 11); cprintf("Experience:");
- gotoxy(40, 12); cprintf("Level");
-} // end draw_border()
-
-// Determines if the given feature is present at (x, y) in _grid_ coordinates.
-// If you have map coords, add (1, 1) to get grid coords.
-// Use one of
-// 1. '<' and '>' to look for stairs
-// 2. '\t' or '\\' for shops, portals.
-// 3. '^' for traps
-// 4. '_' for altars
-// 5. Anything else will look for the exact same character in the level map.
-bool is_feature(int feature, int x, int y) {
- unsigned char envfeat = (unsigned char) env.map[x - 1][y - 1];
- if (!envfeat)
- return false;
-
- // 'grid' can fit in an unsigned char, but making this a short shuts up
- // warnings about out-of-range case values.
- short grid = grd[x][y];
-
- switch (feature) {
- case 'X':
- return (point_distance[x][y] == PD_EXCLUDED);
- case 'F':
- case 'W':
- return is_waypoint(x, y);
-#ifdef STASH_TRACKING
- case 'I':
- return is_stash(x, y);
-#endif
- case '_':
- switch (grid) {
- case DNGN_ALTAR_ZIN:
- case DNGN_ALTAR_SHINING_ONE:
- case DNGN_ALTAR_KIKUBAAQUDGHA:
- case DNGN_ALTAR_YREDELEMNUL:
- case DNGN_ALTAR_XOM:
- case DNGN_ALTAR_VEHUMET:
- case DNGN_ALTAR_OKAWARU:
- case DNGN_ALTAR_MAKHLEB:
- case DNGN_ALTAR_SIF_MUNA:
- case DNGN_ALTAR_TROG:
- case DNGN_ALTAR_NEMELEX_XOBEH:
- case DNGN_ALTAR_ELYVILON:
- return true;
- default:
- return false;
- }
- case '\t':
- case '\\':
- switch (grid) {
- case DNGN_ENTER_HELL:
- case DNGN_ENTER_LABYRINTH:
- case DNGN_ENTER_SHOP:
- case DNGN_ENTER_DIS:
- case DNGN_ENTER_GEHENNA:
- case DNGN_ENTER_COCYTUS:
- case DNGN_ENTER_TARTARUS:
- case DNGN_ENTER_ABYSS:
- case DNGN_EXIT_ABYSS:
- case DNGN_STONE_ARCH:
- case DNGN_ENTER_PANDEMONIUM:
- case DNGN_EXIT_PANDEMONIUM:
- case DNGN_TRANSIT_PANDEMONIUM:
- case DNGN_ENTER_ZOT:
- case DNGN_RETURN_FROM_ZOT:
- return true;
- default:
- return false;
- }
- case '<':
- switch (grid) {
- case DNGN_ROCK_STAIRS_UP:
- case DNGN_STONE_STAIRS_UP_I:
- case DNGN_STONE_STAIRS_UP_II:
- case DNGN_STONE_STAIRS_UP_III:
- case DNGN_RETURN_FROM_ORCISH_MINES:
- case DNGN_RETURN_FROM_HIVE:
- case DNGN_RETURN_FROM_LAIR:
- case DNGN_RETURN_FROM_SLIME_PITS:
- case DNGN_RETURN_FROM_VAULTS:
- case DNGN_RETURN_FROM_CRYPT:
- case DNGN_RETURN_FROM_HALL_OF_BLADES:
- case DNGN_RETURN_FROM_TEMPLE:
- case DNGN_RETURN_FROM_SNAKE_PIT:
- case DNGN_RETURN_FROM_ELVEN_HALLS:
- case DNGN_RETURN_FROM_TOMB:
- case DNGN_RETURN_FROM_SWAMP:
- return true;
- default:
- return false;
- }
- case '>':
- switch (grid) {
- case DNGN_ROCK_STAIRS_DOWN:
- case DNGN_STONE_STAIRS_DOWN_I:
- case DNGN_STONE_STAIRS_DOWN_II:
- case DNGN_STONE_STAIRS_DOWN_III:
- case DNGN_ENTER_ORCISH_MINES:
- case DNGN_ENTER_HIVE:
- case DNGN_ENTER_LAIR:
- case DNGN_ENTER_SLIME_PITS:
- case DNGN_ENTER_VAULTS:
- case DNGN_ENTER_CRYPT:
- case DNGN_ENTER_HALL_OF_BLADES:
- case DNGN_ENTER_TEMPLE:
- case DNGN_ENTER_SNAKE_PIT:
- case DNGN_ENTER_ELVEN_HALLS:
- case DNGN_ENTER_TOMB:
- case DNGN_ENTER_SWAMP:
- return true;
- default:
- return false;
- }
- case '^':
- switch (grid) {
- case DNGN_TRAP_MECHANICAL:
- case DNGN_TRAP_MAGICAL:
- case DNGN_TRAP_III:
- return true;
- default:
- return false;
- }
- default:
- return envfeat == feature;
- }
-}
-
-static int find_feature(unsigned char feature, int curs_x, int curs_y,
- int start_x, int start_y, int anchor_x, int anchor_y,
- int ignore_count, char *move_x, char *move_y) {
- int cx = anchor_x,
- cy = anchor_y;
-
- int firstx = -1, firsty = -1;
- int matchcount = 0;
-
- // Find the first occurrence of feature 'feature', spiralling around (x,y)
- int maxradius = GXM > GYM? GXM : GYM;
- for (int radius = 1; radius < maxradius; ++radius) {
- for (int axis = -2; axis < 2; ++axis) {
- int rad = radius - (axis < 0);
- for (int var = -rad; var <= rad; ++var) {
- int dx = radius, dy = var;
- if (axis % 2)
- dx = -dx;
- if (axis < 0) {
- int temp = dx;
- dx = dy;
- dy = temp;
- }
-
- int x = cx + dx, y = cy + dy;
- if (x < 0 || y < 0 || x >= GXM || y >= GYM) continue;
- if (is_feature(feature, x + 1, y + 1)) {
- ++matchcount;
- if (!ignore_count--) {
- // We want to cursor to (x,y)
- *move_x = x - (start_x + curs_x - 1);
- *move_y = y - (start_y + curs_y - 1);
- return matchcount;
- }
- else if (firstx == -1) {
- firstx = x;
- firsty = y;
- }
- }
- }
- }
- }
-
- // We found something, but ignored it because of an ignorecount
- if (firstx != -1) {
- *move_x = firstx - (start_x + curs_x - 1);
- *move_y = firsty - (start_y + curs_y - 1);
- return 1;
- }
- return 0;
-}
-
-void find_features(const std::vector<coord_def>& features,
- unsigned char feature, std::vector<coord_def> *found) {
- for (unsigned feat = 0; feat < features.size(); ++feat) {
- const coord_def& coord = features[feat];
- if (is_feature(feature, coord.x, coord.y))
- found->push_back(coord);
- }
-}
-
-static int find_feature( const std::vector<coord_def>& features,
- unsigned char feature, int curs_x, int curs_y,
- int start_x, int start_y,
- int ignore_count, char *move_x, char *move_y) {
- int firstx = -1, firsty = -1;
- int matchcount = 0;
-
- for (unsigned feat = 0; feat < features.size(); ++feat) {
- const coord_def& coord = features[feat];
-
- if (is_feature(feature, coord.x, coord.y)) {
- ++matchcount;
- if (!ignore_count--) {
- // We want to cursor to (x,y)
- *move_x = coord.x - (start_x + curs_x);
- *move_y = coord.y - (start_y + curs_y);
- return matchcount;
- }
- else if (firstx == -1) {
- firstx = coord.x;
- firsty = coord.y;
- }
- }
- }
-
- // We found something, but ignored it because of an ignorecount
- if (firstx != -1) {
- *move_x = firstx - (start_x + curs_x);
- *move_y = firsty - (start_y + curs_y);
- return 1;
- }
- return 0;
-}
-
-// show_map() now centers the known map along x or y. This prevents
-// the player from getting "artificial" location clues by using the
-// map to see how close to the end they are. They'll need to explore
-// to get that. This function is still a mess, though. -- bwr
-void show_map( FixedVector<int, 2> &spec_place )
-{
- int i, j;
-
- int bufcount2 = 0;
-
- char move_x = 0;
- char move_y = 0;
- char getty = 0;
-
-#ifdef DOS_TERM
- char buffer[4800];
-#endif
-
- // Vector to track all features we can travel to, in order of distance.
- std::vector<coord_def> features;
- if (!spec_place[0]) {
- travel_cache.update();
-
- find_travel_pos(you.x_pos, you.y_pos, NULL, NULL, &features);
- // Sort features into the order the player is likely to prefer.
- arrange_features(features);
- }
-
- // buffer2[GYM * GXM * 2] segfaults my box {dlb}
- screen_buffer_t buffer2[GYM * GXM * 2];
-
- char min_x = 80, max_x = 0, min_y = 0, max_y = 0;
- bool found_y = false;
-
- const int num_lines = get_number_of_lines();
- const int half_screen = num_lines / 2 - 1;
-
- for (j = 0; j < GYM; j++)
- {
- for (i = 0; i < GXM; i++)
- {
- if (env.map[i][j])
- {
- if (!found_y)
- {
- found_y = true;
- min_y = j;
- }
-
- max_y = j;
-
- if (i < min_x)
- min_x = i;
-
- if (i > max_x)
- max_x = i;
- }
- }
- }
-
- const int map_lines = max_y - min_y + 1;
-
- const int start_x = min_x + (max_x - min_x + 1) / 2 - 40; // no x scrolling
- const int block_step = Options.level_map_cursor_step;
- int start_y; // y does scroll
-
- int screen_y = you.y_pos;
-
- // if close to top of known map, put min_y on top
- // else if close to bottom of known map, put max_y on bottom.
- //
- // The num_lines comparisons are done to keep things neat, by
- // keeping things at the top of the screen. By shifting an
- // additional one in the num_lines > map_lines case, we can
- // keep the top line clear... which makes things look a whole
- // lot better for small maps.
- if (num_lines > map_lines)
- screen_y = min_y + half_screen - 1;
- else if (num_lines == map_lines || screen_y - half_screen < min_y)
- screen_y = min_y + half_screen;
- else if (screen_y + half_screen > max_y)
- screen_y = max_y - half_screen;
-
- int curs_x = you.x_pos - start_x;
- int curs_y = you.y_pos - screen_y + half_screen;
- int search_feat = 0, search_found = 0, anchor_x = -1, anchor_y = -1;
-
-#ifdef DOS_TERM
- gettext(1, 1, 80, 25, buffer);
- window(1, 1, 80, 25);
-#endif
-
- clrscr();
- textcolor(DARKGREY);
-
- put_screen:
- bufcount2 = 0;
-
- _setcursortype(_NOCURSOR);
-
-#ifdef PLAIN_TERM
- gotoxy(1, 1);
-#endif
-
- start_y = screen_y - half_screen;
-
- for (j = 0; j < num_lines; j++)
- {
- for (i = 0; i < 80; i++)
- {
- screen_buffer_t colour = DARKGREY;
- if (start_y + j >= 65 || start_y + j <= 3
- || start_x + i < 0 || start_x + i >= GXM - 1)
- {
- buffer2[bufcount2 + 1] = DARKGREY;
- buffer2[bufcount2] = 0;
- bufcount2 += 2;
-
-#ifdef PLAIN_TERM
- goto print_it;
-#endif
-
-#ifdef DOS_TERM
- continue;
-#endif
-
- }
-
- colour = colour_code_map(start_x + i, start_y + j,
- Options.item_colour,
- !spec_place[0] && Options.travel_colour);
-
- buffer2[bufcount2 + 1] = colour;
-
- if (start_x + i + 1 == you.x_pos && start_y + j + 1 == you.y_pos)
- buffer2[bufcount2 + 1] = WHITE;
-
- buffer2[bufcount2] =
- (unsigned char) env.map[start_x + i][start_y + j];
-
- // If we've a waypoint on the current square, *and* the square is
- // a normal floor square with nothing on it, show the waypoint
- // number.
- if (Options.show_waypoints)
- {
- // XXX: This is a horrible hack.
- screen_buffer_t &bc = buffer2[bufcount2];
- int gridx = start_x + i + 1, gridy = start_y + j + 1;
- unsigned char ch = is_waypoint(gridx, gridy);
- if (ch && (bc == mapch2(DNGN_FLOOR) ||
- bc == mapch(DNGN_FLOOR)))
- bc = ch;
- }
-
- bufcount2 += 2;
-
-#ifdef PLAIN_TERM
-
- print_it:
- // avoid line wrap
- if (i == 79)
- continue;
-
- // newline
- if (i == 0 && j > 0)
- gotoxy( 1, j + 1 );
-
- textcolor( buffer2[bufcount2 - 1] );
- putch( buffer2[bufcount2 - 2] );
-#endif
- }
- }
-
-#ifdef DOS_TERM
- puttext(1, 1, 80, 25, buffer2);
-#endif
-
- _setcursortype(_NORMALCURSOR);
- gotoxy(curs_x, curs_y);
-
- gettything:
- getty = getchm(KC_LEVELMAP);
-
- if (spec_place[0] == 0 && getty != 0 && getty != '+' && getty != '-'
- && getty != 'h' && getty != 'j' && getty != 'k' && getty != 'l'
- && getty != 'y' && getty != 'u' && getty != 'b' && getty != 'n'
- && getty != 'H' && getty != 'J' && getty != 'K' && getty != 'L'
- && getty != 'Y' && getty != 'U' && getty != 'B' && getty != 'N'
- // Keystrokes to initiate travel
- && getty != ',' && getty != '.' && getty != '\r' && getty != ';'
-
- // Keystrokes for jumping to features
- && getty != '<' && getty != '>' && getty != '@' && getty != '\t'
- && getty != '^' && getty != '_'
- && (getty < '0' || getty > '9')
- && getty != CONTROL('X')
- && getty != CONTROL('E')
- && getty != CONTROL('F')
- && getty != CONTROL('W')
- && getty != CONTROL('C')
- && getty != 'X' && getty != 'F' && getty != 'I' && getty != 'W')
- {
- goto putty;
- }
-
- if (spec_place[0] == 1 && getty != 0 && getty != '+' && getty != '-'
- && getty != 'h' && getty != 'j' && getty != 'k' && getty != 'l'
- && getty != 'y' && getty != 'u' && getty != 'b' && getty != 'n'
- && getty != 'H' && getty != 'J' && getty != 'K' && getty != 'L'
- && getty != 'Y' && getty != 'U' && getty != 'B' && getty != 'N'
- && getty != '.' && getty != 'S' && (getty < '0' || getty > '9')
- // Keystrokes for jumping to features
- && getty != '<' && getty != '>' && getty != '@' && getty != '\t'
- && getty != '^' && getty != '_')
- {
- goto gettything;
- }
-
- if (getty == 0)
- getty = getchm(KC_LEVELMAP);
-
-#ifdef WIN32CONSOLE
- // Translate shifted numpad to shifted vi keys. Yes,
- // this is horribly hacky.
- {
- static int win_keypad[] = { 'B', 'J', 'N',
- 'H', '5', 'L',
- 'Y', 'K', 'U' };
- if (getty >= '1' && getty <= '9')
- getty = win_keypad[ getty - '1' ];
- }
-#endif
-
- switch (getty)
- {
- case CONTROL('C'):
- clear_map();
- break;
-
- case CONTROL('F'):
- case CONTROL('W'):
- travel_cache.add_waypoint(start_x + curs_x, start_y + curs_y);
- // We need to do this all over again so that the user can jump
- // to the waypoint he just created.
- features.clear();
- find_travel_pos(you.x_pos, you.y_pos, NULL, NULL, &features);
- // Sort features into the order the player is likely to prefer.
- arrange_features(features);
- move_x = move_y = 0;
- break;
- case CONTROL('E'):
- case CONTROL('X'):
- {
- int x = start_x + curs_x, y = start_y + curs_y;
- if (getty == CONTROL('X'))
- toggle_exclude(x, y);
- else
- clear_excludes();
-
- // We now need to redo travel colours
- features.clear();
- find_travel_pos(you.x_pos, you.y_pos, NULL, NULL, &features);
- // Sort features into the order the player is likely to prefer.
- arrange_features(features);
-
- move_x = move_y = 0;
- }
- break;
-
- case 'b':
- case '1':
- move_x = -1;
- move_y = 1;
- break;
-
- case 'j':
- case '2':
- move_y = 1;
- move_x = 0;
- break;
-
- case 'u':
- case '9':
- move_x = 1;
- move_y = -1;
- break;
-
- case 'k':
- case '8':
- move_y = -1;
- move_x = 0;
- break;
-
- case 'y':
- case '7':
- move_y = -1;
- move_x = -1;
- break;
-
- case 'h':
- case '4':
- move_x = -1;
- move_y = 0;
- break;
-
- case 'n':
- case '3':
- move_y = 1;
- move_x = 1;
- break;
-
- case 'l':
- case '6':
- move_x = 1;
- move_y = 0;
- break;
-
- case 'B':
- move_x = -block_step;
- move_y = block_step;
- break;
-
- case 'J':
- move_y = block_step;
- move_x = 0;
- break;
-
- case 'U':
- move_x = block_step;
- move_y = -block_step;
- break;
-
- case 'K':
- move_y = -block_step;
- move_x = 0;
- break;
-
- case 'Y':
- move_y = -block_step;
- move_x = -block_step;
- break;
-
- case 'H':
- move_x = -block_step;
- move_y = 0;
- break;
-
- case 'N':
- move_y = block_step;
- move_x = block_step;
- break;
-
- case 'L':
- move_x = block_step;
- move_y = 0;
- break;
-
- case '+':
- move_y = 20;
- move_x = 0;
- break;
- case '-':
- move_y = -20;
- move_x = 0;
- break;
- case '<':
- case '>':
- case '@':
- case '\t':
- case '^':
- case '_':
- case 'X':
- case 'F':
- case 'W':
- case 'I':
- move_x = 0;
- move_y = 0;
- if (anchor_x == -1) {
- anchor_x = start_x + curs_x - 1;
- anchor_y = start_y + curs_y - 1;
- }
- if (search_feat != getty) {
- search_feat = getty;
- search_found = 0;
- }
- if (!spec_place[0])
- search_found = find_feature(features, getty, curs_x, curs_y,
- start_x, start_y,
- search_found, &move_x, &move_y);
- else
- search_found = find_feature(getty, curs_x, curs_y,
- start_x, start_y,
- anchor_x, anchor_y,
- search_found, &move_x, &move_y);
- break;
- case '.':
- case '\r':
- case 'S':
- case ',':
- case ';':
- {
- int x = start_x + curs_x, y = start_y + curs_y;
- if (!spec_place[0] && x == you.x_pos && y == you.y_pos)
- {
- if (you.travel_x > 0 && you.travel_y > 0) {
- move_x = you.travel_x - x;
- move_y = you.travel_y - y;
- }
- break;
- }
- else {
- spec_place[0] = x;
- spec_place[1] = y;
- goto putty;
- }
- }
- default:
- move_x = 0;
- move_y = 0;
- break;
- }
-
- if (curs_x + move_x < 1 || curs_x + move_x > 80)
- move_x = 0;
-
- curs_x += move_x;
-
- if (num_lines < map_lines)
- {
- // Scrolling only happens when we don't have a large enough
- // display to show the known map.
- if (getty == '-' || getty == '+')
- {
- if (getty == '-')
- screen_y -= 20;
-
- if (screen_y <= min_y + half_screen)
- screen_y = min_y + half_screen;
-
- if (getty == '+')
- screen_y += 20;
-
- if (screen_y >= max_y - half_screen)
- screen_y = max_y - half_screen;
-
- goto put_screen;
- }
-
- if (curs_y + move_y < 1)
- {
- // screen_y += (curs_y + move_y) - 1;
- screen_y += move_y;
-
- if (screen_y < min_y + half_screen) {
- move_y = screen_y - (min_y + half_screen);
- screen_y = min_y + half_screen;
- }
- else
- move_y = 0;
- }
-
- if (curs_y + move_y > num_lines - 1)
- {
- // screen_y += (curs_y + move_y) - num_lines + 1;
- screen_y += move_y;
-
- if (screen_y > max_y - half_screen) {
- move_y = screen_y - (max_y - half_screen);
- screen_y = max_y - half_screen;
- }
- else
- move_y = 0;
- }
- }
-
- if (curs_y + move_y < 1 || curs_y + move_y > num_lines)
- move_y = 0;
-
- curs_y += move_y;
- goto put_screen;
-
- putty:
-
-#ifdef DOS_TERM
- puttext(1, 1, 80, 25, buffer);
-#endif
-
- return;
-} // end show_map()
-
-
-void magic_mapping(int map_radius, int proportion)
-{
- int i, j, k, l, empty_count;
-
- if (map_radius > 50)
- map_radius = 50;
-
- for (i = you.x_pos - map_radius; i < you.x_pos + map_radius; i++)
- {
- for (j = you.y_pos - map_radius; j < you.y_pos + map_radius; j++)
- {
- if (random2(100) > proportion)
- continue; // note that proportion can be over 100
-
- if (i < 5 || j < 5 || i > (GXM - 5) || j > (GYM - 5))
- continue;
-
- //if (env.map[i][j] == mapch2(grd[i + 1][j + 1]))
- // continue;
- if (env.map[i][j])
- continue;
-
- empty_count = 8;
-
- if (grd[i][j] < DNGN_LAVA && grd[i][j] != DNGN_CLOSED_DOOR)
- {
- for (k = 0; k < 3; k++)
- {
- for (l = 0; l < 3; l++)
- {
- if (k == 1 && l == 1)
- continue;
-
- if (grd[i + k][j + l] <= 60
- && grd[i + k][j + l] != DNGN_CLOSED_DOOR)
- {
- empty_count--;
- }
- }
- }
- }
-
- if (empty_count > 0)
- env.map[i][j] = mapch(grd[i + 1][j + 1]);
- }
- }
-} // end magic_mapping()
-
-
-/* mapchars 3 & 4 are for non-ibm char sets */
-unsigned char mapchar(unsigned char ldfk)
-{
- unsigned char showed = 0;
-
- switch (ldfk)
- {
- case DNGN_UNSEEN:
- showed = 0;
- break;
-
- case DNGN_SECRET_DOOR:
- case DNGN_ROCK_WALL:
- case DNGN_PERMAROCK_WALL:
- case DNGN_STONE_WALL:
- case DNGN_METAL_WALL:
- case DNGN_GREEN_CRYSTAL_WALL:
- case DNGN_WAX_WALL:
- showed = 176;
- break;
-
- case DNGN_CLOSED_DOOR:
- showed = 206;
- break;
-
- case 20: // orcish idol
- case 24: // ???
- case 25: // ???
- case DNGN_SILVER_STATUE:
- case DNGN_GRANITE_STATUE:
- case DNGN_ORANGE_CRYSTAL_STATUE:
- showed = '8';
- break;
-
- case DNGN_LAVA:
- case DNGN_DEEP_WATER:
- case DNGN_SHALLOW_WATER:
- showed = 247;
- break;
-
- case DNGN_FLOOR:
- case DNGN_UNDISCOVERED_TRAP:
- showed = 250;
- break;
-
- //case 68: showed = '>'; break; // < (60)
-
- case DNGN_OPEN_DOOR:
- showed = 39;
- break;
-
- //case 72: showed = '<'; break;
-
- case DNGN_TRAP_MECHANICAL:
- case DNGN_TRAP_MAGICAL:
- case DNGN_TRAP_III:
- showed = '^';
- break;
-
- case DNGN_STONE_STAIRS_DOWN_I:
- case DNGN_STONE_STAIRS_DOWN_II:
- case DNGN_STONE_STAIRS_DOWN_III:
- case DNGN_ROCK_STAIRS_DOWN:
- case DNGN_ENTER_ORCISH_MINES:
- case DNGN_ENTER_HIVE:
- case DNGN_ENTER_LAIR:
- case DNGN_ENTER_SLIME_PITS:
- case DNGN_ENTER_VAULTS:
- case DNGN_ENTER_CRYPT:
- case DNGN_ENTER_HALL_OF_BLADES:
- case DNGN_ENTER_TEMPLE:
- case DNGN_ENTER_SNAKE_PIT:
- case DNGN_ENTER_ELVEN_HALLS:
- case DNGN_ENTER_TOMB:
- case DNGN_ENTER_SWAMP:
- case 123:
- case 124:
- case 125:
- case 126:
- showed = '>';
- break;
-
- case DNGN_STONE_STAIRS_UP_I:
- case DNGN_STONE_STAIRS_UP_II:
- case DNGN_STONE_STAIRS_UP_III:
- case DNGN_ROCK_STAIRS_UP:
- case DNGN_RETURN_FROM_ORCISH_MINES:
- case DNGN_RETURN_FROM_HIVE:
- case DNGN_RETURN_FROM_LAIR:
- case DNGN_RETURN_FROM_SLIME_PITS:
- case DNGN_RETURN_FROM_VAULTS:
- case DNGN_RETURN_FROM_CRYPT:
- case DNGN_RETURN_FROM_HALL_OF_BLADES:
- case DNGN_RETURN_FROM_TEMPLE:
- case DNGN_RETURN_FROM_SNAKE_PIT:
- case DNGN_RETURN_FROM_ELVEN_HALLS:
- case DNGN_RETURN_FROM_TOMB:
- case DNGN_RETURN_FROM_SWAMP:
- case 143:
- case 144:
- case 145:
- case 146:
- showed = '<';
- break;
-
- case DNGN_ENTER_HELL:
- case DNGN_ENTER_LABYRINTH:
- case DNGN_ENTER_SHOP:
- case DNGN_ENTER_DIS:
- case DNGN_ENTER_GEHENNA:
- case DNGN_ENTER_COCYTUS:
- case DNGN_ENTER_TARTARUS:
- case DNGN_ENTER_ABYSS:
- case DNGN_EXIT_ABYSS:
- case DNGN_STONE_ARCH:
- case DNGN_ENTER_PANDEMONIUM:
- case DNGN_EXIT_PANDEMONIUM:
- case DNGN_TRANSIT_PANDEMONIUM:
- case DNGN_ENTER_ZOT:
- case DNGN_RETURN_FROM_ZOT:
- showed = 239;
- break;
-
- case DNGN_ALTAR_ZIN:
- case DNGN_ALTAR_SHINING_ONE:
- case DNGN_ALTAR_KIKUBAAQUDGHA:
- case DNGN_ALTAR_YREDELEMNUL:
- case DNGN_ALTAR_XOM:
- case DNGN_ALTAR_VEHUMET:
- case DNGN_ALTAR_OKAWARU:
- case DNGN_ALTAR_MAKHLEB:
- case DNGN_ALTAR_SIF_MUNA:
- case DNGN_ALTAR_TROG:
- case DNGN_ALTAR_NEMELEX_XOBEH:
- case DNGN_ALTAR_ELYVILON:
- showed = 220;
- break;
-
- case DNGN_BLUE_FOUNTAIN:
- case DNGN_DRY_FOUNTAIN_I:
- case DNGN_SPARKLING_FOUNTAIN:
- case DNGN_DRY_FOUNTAIN_II:
- case DNGN_DRY_FOUNTAIN_III:
- case DNGN_DRY_FOUNTAIN_IV:
- case DNGN_DRY_FOUNTAIN_V:
- case DNGN_DRY_FOUNTAIN_VI:
- case DNGN_DRY_FOUNTAIN_VII:
- case DNGN_DRY_FOUNTAIN_VIII:
- case DNGN_PERMADRY_FOUNTAIN:
- showed = 159;
- break;
-
- default:
- showed = 0;
- break;
- }
-
- return showed;
-}
-
-
-unsigned char mapchar2(unsigned char ldfk)
-{
- unsigned char showed = 0;
-
- switch (ldfk)
- {
- case DNGN_UNSEEN:
- showed = 0;
- break;
-
- case DNGN_SECRET_DOOR:
- case DNGN_ROCK_WALL:
- case DNGN_PERMAROCK_WALL:
- case DNGN_STONE_WALL:
- case DNGN_METAL_WALL:
- case DNGN_GREEN_CRYSTAL_WALL:
- case DNGN_WAX_WALL:
- showed = 177;
- break;
-
- case DNGN_CLOSED_DOOR:
- showed = 254;
- break;
-
- case 20: // orcish idol
- case 24: // ???
- case 25: // ???
- case DNGN_SILVER_STATUE:
- case DNGN_GRANITE_STATUE:
- case DNGN_ORANGE_CRYSTAL_STATUE:
- showed = '8';
- break;
-
- case DNGN_LAVA:
- case DNGN_DEEP_WATER:
- case DNGN_SHALLOW_WATER:
- showed = 247;
- break;
-
- case DNGN_FLOOR:
- case DNGN_UNDISCOVERED_TRAP:
- showed = 249;
- break;
-
- case 68:
- showed = '>';
- break; // <
-
- case DNGN_OPEN_DOOR:
- showed = 39;
- break;
-
- case 72:
- showed = '<';
- break; // <
-
- case DNGN_TRAP_MECHANICAL:
- case DNGN_TRAP_MAGICAL:
- case DNGN_TRAP_III:
- showed = '^';
- break;
-
- case DNGN_STONE_STAIRS_DOWN_I:
- case DNGN_STONE_STAIRS_DOWN_II:
- case DNGN_STONE_STAIRS_DOWN_III:
- case DNGN_ROCK_STAIRS_DOWN:
- case DNGN_ENTER_ORCISH_MINES:
- case DNGN_ENTER_HIVE:
- case DNGN_ENTER_LAIR:
- case DNGN_ENTER_SLIME_PITS:
- case DNGN_ENTER_VAULTS:
- case DNGN_ENTER_CRYPT:
- case DNGN_ENTER_HALL_OF_BLADES:
- case DNGN_ENTER_TEMPLE:
- case DNGN_ENTER_SNAKE_PIT:
- case DNGN_ENTER_ELVEN_HALLS:
- case DNGN_ENTER_TOMB:
- case DNGN_ENTER_SWAMP:
- case 123:
- case 124:
- case 125:
- case 126:
- showed = '>';
- break;
-
- case DNGN_STONE_STAIRS_UP_I:
- case DNGN_STONE_STAIRS_UP_II:
- case DNGN_STONE_STAIRS_UP_III:
- case DNGN_ROCK_STAIRS_UP:
- case DNGN_RETURN_FROM_ORCISH_MINES:
- case DNGN_RETURN_FROM_HIVE:
- case DNGN_RETURN_FROM_LAIR:
- case DNGN_RETURN_FROM_SLIME_PITS:
- case DNGN_RETURN_FROM_VAULTS:
- case DNGN_RETURN_FROM_CRYPT:
- case DNGN_RETURN_FROM_HALL_OF_BLADES:
- case DNGN_RETURN_FROM_TEMPLE:
- case DNGN_RETURN_FROM_SNAKE_PIT:
- case DNGN_RETURN_FROM_ELVEN_HALLS:
- case DNGN_RETURN_FROM_TOMB:
- case DNGN_RETURN_FROM_SWAMP:
- case 143:
- case 144:
- case 145:
- case 146:
- showed = '<';
- break;
-
- case DNGN_ENTER_HELL:
- case DNGN_ENTER_LABYRINTH:
- case DNGN_ENTER_SHOP:
- case DNGN_ENTER_DIS:
- case DNGN_ENTER_GEHENNA:
- case DNGN_ENTER_COCYTUS:
- case DNGN_ENTER_TARTARUS:
- case DNGN_ENTER_ABYSS:
- case DNGN_EXIT_ABYSS:
- case DNGN_STONE_ARCH:
- case DNGN_ENTER_PANDEMONIUM:
- case DNGN_EXIT_PANDEMONIUM:
- case DNGN_TRANSIT_PANDEMONIUM:
- case DNGN_ENTER_ZOT:
- case DNGN_RETURN_FROM_ZOT:
- showed = 239;
- break;
-
- case DNGN_ALTAR_ZIN:
- case DNGN_ALTAR_SHINING_ONE:
- case DNGN_ALTAR_KIKUBAAQUDGHA:
- case DNGN_ALTAR_YREDELEMNUL:
- case DNGN_ALTAR_XOM:
- case DNGN_ALTAR_VEHUMET:
- case DNGN_ALTAR_OKAWARU:
- case DNGN_ALTAR_MAKHLEB:
- case DNGN_ALTAR_SIF_MUNA:
- case DNGN_ALTAR_TROG:
- case DNGN_ALTAR_NEMELEX_XOBEH:
- case DNGN_ALTAR_ELYVILON:
- showed = 220;
- break;
-
- case DNGN_BLUE_FOUNTAIN:
- case DNGN_DRY_FOUNTAIN_I:
- case DNGN_SPARKLING_FOUNTAIN:
- case DNGN_DRY_FOUNTAIN_II:
- case DNGN_DRY_FOUNTAIN_III:
- case DNGN_DRY_FOUNTAIN_IV:
- case DNGN_DRY_FOUNTAIN_V:
- case DNGN_DRY_FOUNTAIN_VI:
- case DNGN_DRY_FOUNTAIN_VII:
- case DNGN_DRY_FOUNTAIN_VIII:
- case DNGN_PERMADRY_FOUNTAIN:
- showed = 159;
- break;
- default:
- showed = 0;
- break;
- }
-
- return showed;
-}
-
-
-// realize that this is simply a repackaged version of
-// stuff::see_grid() -- make certain they correlate {dlb}:
-bool mons_near(struct monsters *monster, unsigned int foe)
-{
- // early out -- no foe!
- if (foe == MHITNOT)
- return (false);
-
- if (foe == MHITYOU)
- {
- if (monster->x > you.x_pos - 9 && monster->x < you.x_pos + 9
- && monster->y > you.y_pos - 9 && monster->y < you.y_pos + 9)
- {
- if (env.show[monster->x - you.x_pos + 9][monster->y - you.y_pos + 9])
- return (true);
- }
- return (false);
- }
-
- // must be a monster
- struct monsters *myFoe = &menv[foe];
- if (myFoe->type >= 0)
- {
- if (monster->x > myFoe->x - 9 && monster->x < myFoe->x + 9
- && monster->y > myFoe->y - 9 && monster->y < myFoe->y + 9)
- {
- return (true);
- }
- }
-
- return (false);
-} // end mons_near()
-
-
-//---------------------------------------------------------------
-//
-// get_non_ibm_symbol
-//
-// Returns the character code and color for everything drawn
-// without the IBM graphics option.
-//
-//---------------------------------------------------------------
-void get_non_ibm_symbol(unsigned int object, unsigned short *ch,
- unsigned short *color)
-{
- ASSERT(color != NULL);
- ASSERT(ch != NULL);
-
- switch (object)
- {
-
- case DNGN_UNSEEN:
- *ch = 0;
- break;
-
- case DNGN_ROCK_WALL:
- case DNGN_PERMAROCK_WALL:
- *color = env.rock_colour;
- *ch = '#';
- break;
-
- case DNGN_STONE_WALL:
- if (player_in_branch( BRANCH_HALL_OF_ZOT ))
- *color = env.rock_colour;
- else
- *color = LIGHTGREY;
- *ch = '#';
- break;
-
- case DNGN_CLOSED_DOOR:
- *ch = '+';
- break;
-
- case DNGN_METAL_WALL:
- *ch = '#';
- *color = CYAN;
- break;
-
- case DNGN_SECRET_DOOR:
- *ch = '#';
- *color = env.rock_colour;
- break;
-
- case DNGN_GREEN_CRYSTAL_WALL:
- *ch = '#';
- *color = GREEN;
- break;
-
- case DNGN_ORCISH_IDOL:
- *ch = '8';
- *color = DARKGREY;
- break;
-
- case DNGN_WAX_WALL:
- *ch = '#';
- *color = YELLOW;
- break;
-
- case DNGN_SILVER_STATUE:
- *ch = '8';
- *color = WHITE;
- Visible_Statue[ STATUE_SILVER ] = 1;
- break;
-
- case DNGN_GRANITE_STATUE:
- *ch = '8';
- *color = LIGHTGREY;
- break;
-
- case DNGN_ORANGE_CRYSTAL_STATUE:
- *ch = '8';
- *color = LIGHTRED;
- Visible_Statue[ STATUE_ORANGE_CRYSTAL ] = 1;
- break;
-
- case DNGN_LAVA:
- *ch = '{';
- *color = RED;
- break;
-
- case DNGN_DEEP_WATER:
- *ch = '{';
- // this wavy thing also used for water elemental
- // note that some monsters which use IBM graphics aren't set
- // for this function - too tricky for now.
- *color = BLUE;
- break;
-
- case DNGN_SHALLOW_WATER:
- *color = CYAN;
- *ch = '{';
- break;
-
- case DNGN_FLOOR:
- *color = env.floor_colour;
- *ch = '.';
- break;
-
- case DNGN_ENTER_HELL:
- *color = RED;
- *ch = '\\';
- seen_other_thing(DNGN_ENTER_HELL);
- break;
-
- case DNGN_OPEN_DOOR:
- *ch = '\'';
- break;
-
- case DNGN_TRAP_MECHANICAL:
- *color = 11;
- *ch = '^';
- break;
-
- case DNGN_TRAP_MAGICAL:
- *color = MAGENTA;
- *ch = '^';
- break;
-
- case DNGN_TRAP_III:
- *color = LIGHTGREY;
- *ch = '^';
- break;
-
- case DNGN_UNDISCOVERED_TRAP:
- *color = env.floor_colour;
- *ch = '.';
- break;
-
- case DNGN_ENTER_SHOP:
- *color = YELLOW;
- *ch = '\\';
- seen_other_thing(DNGN_ENTER_SHOP);
- break;
-// if I change anything above here, must also change magic mapping!
-
- case DNGN_ENTER_LABYRINTH:
- *color = LIGHTGREY;
- *ch = '\\';
- seen_other_thing(DNGN_ENTER_LABYRINTH);
- break;
-
- case DNGN_ROCK_STAIRS_DOWN:
- *color = BROWN; // ladder
- case DNGN_STONE_STAIRS_DOWN_I:
- case DNGN_STONE_STAIRS_DOWN_II:
- case DNGN_STONE_STAIRS_DOWN_III:
- *ch = '>';
- break;
-
- case DNGN_ROCK_STAIRS_UP:
- *color = BROWN; // ladder
- case DNGN_STONE_STAIRS_UP_I:
- case DNGN_STONE_STAIRS_UP_II:
- case DNGN_STONE_STAIRS_UP_III:
- *ch = '<';
- break;
-
- case DNGN_ENTER_DIS:
- *color = CYAN;
- *ch = '\\';
- break;
-
- case DNGN_ENTER_GEHENNA:
- *color = RED;
- *ch = '\\';
- break;
-
- case DNGN_ENTER_COCYTUS:
- *color = LIGHTCYAN;
- *ch = '\\';
- break;
-
- case DNGN_ENTER_TARTARUS:
- *color = DARKGREY;
- *ch = '\\';
- break;
-
- case DNGN_ENTER_ABYSS:
- *color = random2(16);
- *ch = '\\';
- seen_other_thing(DNGN_ENTER_ABYSS);
- break;
-
- case DNGN_EXIT_ABYSS:
- *color = random2(16);
- *ch = '\\';
- break;
-
- case DNGN_STONE_ARCH:
- *color = LIGHTGREY;
- *ch = '\\';
- break;
-
- case DNGN_ENTER_PANDEMONIUM:
- *color = LIGHTBLUE;
- *ch = '\\';
- seen_other_thing(DNGN_ENTER_PANDEMONIUM);
- break;
-
- case DNGN_EXIT_PANDEMONIUM:
- *color = LIGHTBLUE;
- *ch = '\\';
- break;
-
- case DNGN_TRANSIT_PANDEMONIUM:
- *color = LIGHTGREEN;
- *ch = '\\';
- break; // gate to other part of pandemonium
-
- case DNGN_ENTER_ORCISH_MINES:
- case DNGN_ENTER_HIVE:
- case DNGN_ENTER_LAIR:
- case DNGN_ENTER_SLIME_PITS:
- case DNGN_ENTER_VAULTS:
- case DNGN_ENTER_CRYPT:
- case DNGN_ENTER_HALL_OF_BLADES:
- case DNGN_ENTER_TEMPLE:
- case DNGN_ENTER_SNAKE_PIT:
- case DNGN_ENTER_ELVEN_HALLS:
- case DNGN_ENTER_TOMB:
- case DNGN_ENTER_SWAMP:
- case 123:
- case 124:
- case 125:
- case 126:
- *color = YELLOW;
- *ch = '>';
- seen_staircase(object);
- break;
-
- case DNGN_ENTER_ZOT:
- *color = MAGENTA;
- *ch = '\\';
- seen_staircase(object);
- break;
-
- case DNGN_RETURN_FROM_ORCISH_MINES:
- case DNGN_RETURN_FROM_HIVE:
- case DNGN_RETURN_FROM_LAIR:
- case DNGN_RETURN_FROM_SLIME_PITS:
- case DNGN_RETURN_FROM_VAULTS:
- case DNGN_RETURN_FROM_CRYPT:
- case DNGN_RETURN_FROM_HALL_OF_BLADES:
- case DNGN_RETURN_FROM_TEMPLE:
- case DNGN_RETURN_FROM_SNAKE_PIT:
- case DNGN_RETURN_FROM_ELVEN_HALLS:
- case DNGN_RETURN_FROM_TOMB:
- case DNGN_RETURN_FROM_SWAMP:
- case 143:
- case 144:
- case 145:
- case 146:
- *color = YELLOW;
- *ch = '<';
- break;
-
- case DNGN_RETURN_FROM_ZOT:
- *color = MAGENTA;
- *ch = '\\';
- break;
-
- case DNGN_ALTAR_ZIN:
- *color = WHITE;
- *ch = '_';
- seen_altar(GOD_ZIN);
- break;
-
- case DNGN_ALTAR_SHINING_ONE:
- *color = YELLOW;
- *ch = '_';
- seen_altar(GOD_SHINING_ONE);
- break;
-
- case DNGN_ALTAR_KIKUBAAQUDGHA:
- *color = DARKGREY;
- *ch = '_';
- seen_altar(GOD_KIKUBAAQUDGHA);
- break;
-
- case DNGN_ALTAR_YREDELEMNUL:
- *color = DARKGREY;
- if (one_chance_in(3))
- *color = RED;
- *ch = '_';
- seen_altar(GOD_YREDELEMNUL);
- break;
-
- case DNGN_ALTAR_XOM:
- *color = random_colour();
- *ch = '_';
- seen_altar(GOD_XOM);
- break;
-
- case DNGN_ALTAR_VEHUMET:
- *color = LIGHTBLUE;
- if (one_chance_in(3))
- *color = LIGHTMAGENTA;
- if (one_chance_in(3))
- *color = LIGHTRED;
- *ch = '_';
- seen_altar(GOD_VEHUMET);
- break;
-
- case DNGN_ALTAR_OKAWARU:
- *color = CYAN;
- *ch = '_';
- seen_altar(GOD_OKAWARU);
- break;
-
- case DNGN_ALTAR_MAKHLEB:
- *color = RED;
- if (one_chance_in(3))
- *color = LIGHTRED;
- if (one_chance_in(3))
- *color = YELLOW;
- *ch = '_';
- seen_altar(GOD_MAKHLEB);
- break;
-
- case DNGN_ALTAR_SIF_MUNA:
- *color = BLUE;
- *ch = '_';
- seen_altar(GOD_SIF_MUNA);
- break;
-
- case DNGN_ALTAR_TROG:
- *color = RED;
- *ch = '_';
- seen_altar(GOD_TROG);
- break;
-
- case DNGN_ALTAR_NEMELEX_XOBEH:
- *color = LIGHTMAGENTA;
- *ch = '_';
- seen_altar(GOD_NEMELEX_XOBEH);
- break;
-
- case DNGN_ALTAR_ELYVILON:
- *color = LIGHTGREY;
- *ch = '_';
- seen_altar(GOD_ELYVILON);
- break;
-
- case DNGN_BLUE_FOUNTAIN:
- *color = BLUE;
- *ch = '}';
- break;
-
- case DNGN_SPARKLING_FOUNTAIN:
- *color = LIGHTBLUE;
- *ch = '}';
- break;
-
- case DNGN_DRY_FOUNTAIN_I:
- case DNGN_DRY_FOUNTAIN_II:
- case DNGN_PERMADRY_FOUNTAIN:
- *color = LIGHTGREY;
- *ch = '}';
- break;
-
- case 256:
- *ch = '0';
- break;
-
- case 257:
- *color = CYAN;
- *ch = '~';
- break; /* Invis creature walking through water */
-
- case 258:
- *ch = ')';
- break; // weapon )
-
- case 259:
- *ch = '[';
- break; // armour [
-
- case 260:
- *ch = '/';
- break; // wands, etc.
-
- case 261:
- *ch = '%';
- break; // food
-
- case 262:
- *ch = '+';
- break; // books +
-
- case 263:
- *ch = '?';
- break; // scroll ?
-
- case 264:
- *ch = '=';
- break; // ring = etc
-
- case 265:
- *ch = '!';
- break; // potions !
-
- case 266:
- *ch = '(';
- break; // stones
-
- case 267:
- *ch = ':';
- break; // book +
-
- case 268:
- *ch = '%';
- break; // corpses part 1
-
- case 269:
- *ch = '|';
- break; // magical staves
-
- case 270:
- *ch = '}';
- break; // gems
-
- case 271:
- *ch = '%';
- break; // don't know ?
-
- case 272:
- *ch = '$';
- *color = YELLOW;
- break; // $ gold
-
- case 273:
- *ch = '"';
- break; // amulet
-
- default:
- int mnr = object;
- *ch = ((mnr >= 297) ? mons_char(mnr - 297) : object); // yeah
- break;
- }
-}
-
-
-/*
- This is the viewwindow function for computers without IBM graphic displays.
- It is activated by a command line argument, which sets a function pointer.
- */
-void viewwindow3(char draw_it, bool do_updates)
-{
- int bufcount = 0;
- FixedVector < unsigned short, 1500 > buffy; //[800]; //392];
-
- unsigned short ch, color;
-
- int count_x, count_y;
-
- losight(env.show, grd, you.x_pos, you.y_pos);
-
- for (count_x = 0; count_x < 18; count_x++)
- {
- for (count_y = 0; count_y < 18; count_y++)
- {
- env.show_col[count_x][count_y] = LIGHTGREY;
- show_backup[count_x][count_y] = 0;
- }
- }
-
- item();
- cloud_grid();
- monster_grid(do_updates);
- bufcount = 0;
-
- if (draw_it == 1)
- {
- _setcursortype(_NOCURSOR);
- for (count_y = (you.y_pos - 8); (count_y < you.y_pos + 9); count_y++)
- {
- bufcount += 16;
-
- for (count_x = (you.x_pos - 8); (count_x < you.x_pos + 9); count_x++)
- {
- color = env.show_col[count_x - you.x_pos + 9]
- [count_y - you.y_pos + 9];
-
- if (count_x == you.x_pos && count_y == you.y_pos)
- {
- ch = your_sign;
-
- if (player_is_swimming())
- {
- color = (grd[you.x_pos][you.y_pos] == DNGN_DEEP_WATER)
- ? BLUE : CYAN;
- }
- else
- {
- color = your_colour;
- }
- }
- else
- {
- unsigned int object = env.show[count_x - you.x_pos + 9]
- [count_y - you.y_pos + 9];
-
- get_non_ibm_symbol(object, &ch, &color);
- }
-
- buffy[bufcount] = ch; //showed;
- buffy[bufcount + 1] = color;
- bufcount += 2;
- }
-
- bufcount += 16;
- }
-
- bufcount = 0;
-
- if (you.level_type != LEVEL_LABYRINTH
- && you.level_type != LEVEL_ABYSS)
- {
- for (count_y = 0; count_y < 17; count_y++)
- {
- bufcount += 16;
- for (count_x = 0; count_x < 17; count_x++)
- {
- int enx = count_x + you.x_pos - 9,
- eny = count_y + you.y_pos - 9;
- if (buffy[bufcount] != 0 && enx >= 0 && eny >= 0
- && enx + 1 < GXM && eny + 1 < GYM)
- {
- unsigned short bch = buffy[bufcount];
- if (mgrd[enx + 1][eny + 1] != NON_MONSTER) {
- const monsters &m = menv[ mgrd[enx + 1][eny + 1] ];
- if (!mons_is_mimic(m.type)
- && mons_char(m.type) == bch)
- {
- bch |= mons_colour(m.type) << 12;
- }
- }
- env.map[enx][eny] = bch;
- }
-
- if (Options.clean_map == 1
- && show_backup[count_x + 1][count_y + 1] != 0
- && enx >= 0
- && eny >= 0)
- {
- get_non_ibm_symbol( show_backup[count_x + 1]
- [count_y + 1],
- &ch, &color );
- env.map[enx][eny] = ch;
- }
- bufcount += 2;
- }
- bufcount += 16;
- }
- }
-
- bufcount = 0;
-
- for (count_y = 0; count_y < 17; count_y++)
- {
- for (count_x = 0; count_x < 33; count_x++)
- {
- if (count_x + you.x_pos - 17 < 3
- || count_y + you.y_pos - 9 < 3
- || count_x + you.x_pos - 14 > (GXM - 3)
- || count_y + you.y_pos - 9 > (GYM - 3))
- {
- buffy[bufcount] = 0;
- bufcount++;
- buffy[bufcount] = 0;
- bufcount++;
- continue;
- }
-
- if (count_x >= 8 && count_x <= 24 && count_y >= 0
- && count_y <= 16 && buffy[bufcount] != 0)
- {
- bufcount += 2;
- continue;
- }
-
- buffy[bufcount] = (unsigned char)
- env.map[count_x + you.x_pos - 17]
- [count_y + you.y_pos - 9];
-
- buffy[bufcount + 1] = DARKGREY;
-
- if (Options.colour_map)
- {
- if (env.map[count_x + you.x_pos - 17]
- [count_y + you.y_pos - 9] != 0)
- {
- buffy[bufcount + 1]
- = colour_code_map( count_x + you.x_pos - 17,
- count_y + you.y_pos - 9,
- Options.item_colour );
- }
- }
-
- bufcount += 2;
- }
- }
-
- const int flash_colour =
- you.flash_colour != BLACK? you.flash_colour :
- you.berserker ? RED :
- show_green != BLACK ? show_green :
- you.special_wield == SPWLD_SHADOW? DARKGREY :
- BLACK;
- if (flash_colour != BLACK)
- {
- for (count_x = 1; count_x < 1400; count_x += 2)
- {
- if (buffy[count_x] != DARKGREY)
- buffy[count_x] = flash_colour;
- }
-
- if (show_green != BLACK)
- {
- show_green = BLACK;
- if (you.special_wield == SPWLD_SHADOW)
- show_green = DARKGREY;
- }
- }
- you.flash_colour = BLACK;
-
-#ifdef DOS_TERM
- puttext(2, 1, 34, 17, buffy.buffer());
-#endif
-
-#ifdef PLAIN_TERM
- gotoxy(2, 1);
- bufcount = 0;
-
- // this line is purely optional
- if (you.running == 0 || (you.running < 0 && Options.travel_delay > -1))
- {
- for (count_x = 0; count_x < 1120; count_x += 2) // 1056
- {
- textcolor(buffy[count_x + 1]);
- putch(buffy[count_x]);
-
- if (count_x % 66 == 64 && count_x > 0)
-#ifdef DOS_TERM
- cprintf(EOL " ");
-#endif
-
-#ifdef PLAIN_TERM
- gotoxy(2, wherey() + 1);
-#endif
- }
- }
-#endif
- _setcursortype(_NORMALCURSOR);
- } // end of (if brek...)
-} // end viewwindow3()
-
-
-unsigned char mapchar3(unsigned char ldfk)
-{
- unsigned char showed = 0;
-
- switch (ldfk)
- {
- case DNGN_UNSEEN:
- showed = 0;
- break;
-
- case DNGN_SECRET_DOOR:
- case DNGN_ROCK_WALL:
- case DNGN_PERMAROCK_WALL:
- case DNGN_STONE_WALL:
- case DNGN_METAL_WALL:
- case DNGN_GREEN_CRYSTAL_WALL:
- case DNGN_WAX_WALL:
- showed = '*';
- break;
-
- case DNGN_CLOSED_DOOR:
- showed = '+';
- break;
-
- case 20: // orcish idol
- case 24: // ???
- case 25: // ???
- case DNGN_SILVER_STATUE:
- case DNGN_GRANITE_STATUE:
- case DNGN_ORANGE_CRYSTAL_STATUE:
- showed = '8';
- break;
-
- case DNGN_LAVA:
- case DNGN_DEEP_WATER:
- case DNGN_SHALLOW_WATER:
- showed = '{';
- break;
-
- case DNGN_FLOOR:
- case DNGN_UNDISCOVERED_TRAP:
- showed = ',';
- break;
-
- //case 68: showed = '>'; break; // < (60)
-
- case DNGN_OPEN_DOOR:
- showed = 39;
- break; // open door
-
- //case 72: showed = '<'; break;
-
- case DNGN_TRAP_MECHANICAL:
- case DNGN_TRAP_MAGICAL:
- case DNGN_TRAP_III:
- showed = '^';
- break;
-
- case DNGN_STONE_STAIRS_DOWN_I:
- case DNGN_STONE_STAIRS_DOWN_II:
- case DNGN_STONE_STAIRS_DOWN_III:
- case DNGN_ROCK_STAIRS_DOWN:
- case DNGN_ENTER_ORCISH_MINES:
- case DNGN_ENTER_HIVE:
- case DNGN_ENTER_LAIR:
- case DNGN_ENTER_SLIME_PITS:
- case DNGN_ENTER_VAULTS:
- case DNGN_ENTER_CRYPT:
- case DNGN_ENTER_HALL_OF_BLADES:
- case DNGN_ENTER_TEMPLE:
- case DNGN_ENTER_SNAKE_PIT:
- case DNGN_ENTER_ELVEN_HALLS:
- case DNGN_ENTER_TOMB:
- case DNGN_ENTER_SWAMP:
- case 123:
- case 124:
- case 125:
- case 126:
- showed = '>';
- break;
-
- case DNGN_STONE_STAIRS_UP_I:
- case DNGN_STONE_STAIRS_UP_II:
- case DNGN_STONE_STAIRS_UP_III:
- case DNGN_ROCK_STAIRS_UP:
- case DNGN_RETURN_FROM_ORCISH_MINES:
- case DNGN_RETURN_FROM_HIVE:
- case DNGN_RETURN_FROM_LAIR:
- case DNGN_RETURN_FROM_SLIME_PITS:
- case DNGN_RETURN_FROM_VAULTS:
- case DNGN_RETURN_FROM_CRYPT:
- case DNGN_RETURN_FROM_HALL_OF_BLADES:
- case DNGN_RETURN_FROM_TEMPLE:
- case DNGN_RETURN_FROM_SNAKE_PIT:
- case DNGN_RETURN_FROM_ELVEN_HALLS:
- case DNGN_RETURN_FROM_TOMB:
- case DNGN_RETURN_FROM_SWAMP:
- case 143:
- case 144:
- case 145:
- case 146:
- showed = '<';
- break;
-
- case DNGN_ENTER_HELL:
- case DNGN_ENTER_LABYRINTH:
- case DNGN_ENTER_SHOP:
- case DNGN_ENTER_DIS:
- case DNGN_ENTER_GEHENNA:
- case DNGN_ENTER_COCYTUS:
- case DNGN_ENTER_TARTARUS:
- case DNGN_ENTER_ABYSS:
- case DNGN_EXIT_ABYSS:
- case DNGN_STONE_ARCH:
- case DNGN_ENTER_PANDEMONIUM:
- case DNGN_EXIT_PANDEMONIUM:
- case DNGN_TRANSIT_PANDEMONIUM:
- case DNGN_ENTER_ZOT:
- case DNGN_RETURN_FROM_ZOT:
- showed = '\\';
- break;
-
- case DNGN_ALTAR_ZIN:
- case DNGN_ALTAR_SHINING_ONE:
- case DNGN_ALTAR_KIKUBAAQUDGHA:
- case DNGN_ALTAR_YREDELEMNUL:
- case DNGN_ALTAR_XOM:
- case DNGN_ALTAR_VEHUMET:
- case DNGN_ALTAR_OKAWARU:
- case DNGN_ALTAR_MAKHLEB:
- case DNGN_ALTAR_SIF_MUNA:
- case DNGN_ALTAR_TROG:
- case DNGN_ALTAR_NEMELEX_XOBEH:
- case DNGN_ALTAR_ELYVILON:
- showed = '_';
- break;
-
- case DNGN_BLUE_FOUNTAIN:
- case DNGN_DRY_FOUNTAIN_I:
- case DNGN_SPARKLING_FOUNTAIN:
- case DNGN_DRY_FOUNTAIN_II:
- case DNGN_DRY_FOUNTAIN_III:
- case DNGN_DRY_FOUNTAIN_IV:
- case DNGN_DRY_FOUNTAIN_V:
- case DNGN_DRY_FOUNTAIN_VI:
- case DNGN_DRY_FOUNTAIN_VII:
- case DNGN_DRY_FOUNTAIN_VIII:
- case DNGN_PERMADRY_FOUNTAIN:
- showed = '}';
- break;
-
- default:
- showed = 0;
- break;
- }
-
- return showed;
-}
-
-
-unsigned char mapchar4(unsigned char ldfk)
-{
- unsigned char showed = 0;
-
- switch (ldfk)
- {
- case DNGN_UNSEEN:
- showed = 0;
- break;
-
- case DNGN_CLOSED_DOOR:
- showed = '+';
- break;
-
- case DNGN_SECRET_DOOR:
- case DNGN_ROCK_WALL:
- case DNGN_PERMAROCK_WALL:
- case DNGN_STONE_WALL:
- case DNGN_METAL_WALL:
- case DNGN_GREEN_CRYSTAL_WALL:
- case DNGN_WAX_WALL:
- showed = '#';
- break;
-
- case 20: // orcish idol
- case 24: // ???
- case 25: // ???
- case DNGN_SILVER_STATUE:
- case DNGN_GRANITE_STATUE:
- case DNGN_ORANGE_CRYSTAL_STATUE:
- showed = '8';
- break;
-
- case DNGN_LAVA:
- case DNGN_DEEP_WATER:
- case DNGN_SHALLOW_WATER:
- showed = '{';
- break;
-
- case DNGN_FLOOR:
- case DNGN_UNDISCOVERED_TRAP:
- showed = '.';
- break;
-
- case 68:
- showed = '>'; // <
- break;
-
- case DNGN_OPEN_DOOR:
- showed = 39;
- break;
-
- case 72:
- showed = '<';
- break;
-
- case DNGN_TRAP_MECHANICAL:
- case DNGN_TRAP_MAGICAL:
- case DNGN_TRAP_III:
- showed = '^';
- break;
-
- case DNGN_STONE_STAIRS_DOWN_I:
- case DNGN_STONE_STAIRS_DOWN_II:
- case DNGN_STONE_STAIRS_DOWN_III:
- case DNGN_ROCK_STAIRS_DOWN:
- case DNGN_ENTER_ORCISH_MINES:
- case DNGN_ENTER_HIVE:
- case DNGN_ENTER_LAIR:
- case DNGN_ENTER_SLIME_PITS:
- case DNGN_ENTER_VAULTS:
- case DNGN_ENTER_CRYPT:
- case DNGN_ENTER_HALL_OF_BLADES:
- case DNGN_ENTER_TEMPLE:
- case DNGN_ENTER_SNAKE_PIT:
- case DNGN_ENTER_ELVEN_HALLS:
- case DNGN_ENTER_TOMB:
- case DNGN_ENTER_SWAMP:
- case 123:
- case 124:
- case 125:
- case 126:
- showed = '>';
- break;
-
- case DNGN_STONE_STAIRS_UP_I:
- case DNGN_STONE_STAIRS_UP_II:
- case DNGN_STONE_STAIRS_UP_III:
- case DNGN_ROCK_STAIRS_UP:
- case DNGN_RETURN_FROM_ORCISH_MINES:
- case DNGN_RETURN_FROM_HIVE:
- case DNGN_RETURN_FROM_LAIR:
- case DNGN_RETURN_FROM_SLIME_PITS:
- case DNGN_RETURN_FROM_VAULTS:
- case DNGN_RETURN_FROM_CRYPT:
- case DNGN_RETURN_FROM_HALL_OF_BLADES:
- case DNGN_RETURN_FROM_TEMPLE:
- case DNGN_RETURN_FROM_SNAKE_PIT:
- case DNGN_RETURN_FROM_ELVEN_HALLS:
- case DNGN_RETURN_FROM_TOMB:
- case DNGN_RETURN_FROM_SWAMP:
- case 143:
- case 144:
- case 145:
- case 146:
- showed = '<';
- break;
-
- case DNGN_ENTER_HELL:
- case DNGN_ENTER_LABYRINTH:
- case DNGN_ENTER_SHOP:
- case DNGN_ENTER_DIS:
- case DNGN_ENTER_GEHENNA:
- case DNGN_ENTER_COCYTUS:
- case DNGN_ENTER_TARTARUS:
- case DNGN_ENTER_ABYSS:
- case DNGN_EXIT_ABYSS:
- case DNGN_STONE_ARCH:
- case DNGN_ENTER_PANDEMONIUM:
- case DNGN_EXIT_PANDEMONIUM:
- case DNGN_TRANSIT_PANDEMONIUM:
- case DNGN_ENTER_ZOT:
- case DNGN_RETURN_FROM_ZOT:
- showed = '\\';
- break;
-
- case DNGN_ALTAR_ZIN:
- case DNGN_ALTAR_SHINING_ONE:
- case DNGN_ALTAR_KIKUBAAQUDGHA:
- case DNGN_ALTAR_YREDELEMNUL:
- case DNGN_ALTAR_XOM:
- case DNGN_ALTAR_VEHUMET:
- case DNGN_ALTAR_OKAWARU:
- case DNGN_ALTAR_MAKHLEB:
- case DNGN_ALTAR_SIF_MUNA:
- case DNGN_ALTAR_TROG:
- case DNGN_ALTAR_NEMELEX_XOBEH:
- case DNGN_ALTAR_ELYVILON:
- showed = '_';
- break;
-
- case DNGN_BLUE_FOUNTAIN:
- case DNGN_DRY_FOUNTAIN_I:
- case DNGN_SPARKLING_FOUNTAIN:
- case DNGN_DRY_FOUNTAIN_II:
- case DNGN_DRY_FOUNTAIN_III:
- case DNGN_DRY_FOUNTAIN_IV:
- case DNGN_DRY_FOUNTAIN_V:
- case DNGN_DRY_FOUNTAIN_VI:
- case DNGN_DRY_FOUNTAIN_VII:
- case DNGN_DRY_FOUNTAIN_VIII:
- case DNGN_PERMADRY_FOUNTAIN:
- showed = '}';
- break;
-
- default:
- showed = 0;
- break;
- }
-
- return showed;
-}
diff --git a/stone_soup/crawl-ref/source/view.h b/stone_soup/crawl-ref/source/view.h
deleted file mode 100644
index e45186cda2..0000000000
--- a/stone_soup/crawl-ref/source/view.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * File: view.cc
- * Summary: Misc function used to render the dungeon.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <2> 9/29/99 BCR Added the BORDER_COLOR define
- * <1> -/--/-- LRH Created
- */
-
-
-#ifndef VIEW_H
-#define VIEW_H
-
-
-#include "externs.h"
-
-
-#define BORDER_COLOR BROWN
-
-int get_number_of_lines(void);
-
-/* ***********************************************************************
- * called from: dump_screenshot - chardump
- * *********************************************************************** */
-void get_non_ibm_symbol(unsigned int object, unsigned short *ch,
- unsigned short *color);
-
-// last updated 29may2000 {dlb}
-/* ***********************************************************************
- * called from: bang - beam - direct - effects - fight - monstuff -
- * mstuff2 - spells1 - spells2
- * *********************************************************************** */
-bool mons_near(struct monsters *monster, unsigned int foe = MHITYOU);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - player - stuff
- * *********************************************************************** */
-void draw_border(void);
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - view
- * *********************************************************************** */
-void item(void);
-
-void find_features(const std::vector<coord_def>& features,
- unsigned char feature, std::vector<coord_def> *found);
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: direct - monstufff - view
- * *********************************************************************** */
-void losight(FixedArray<unsigned int, 19, 19>& sh, FixedArray<unsigned char, 80, 70>& gr, int x_p, int y_p);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: ability - acr - it_use3 - item_use - spell
- * *********************************************************************** */
-void magic_mapping(int map_radius, int proportion);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - effects - it_use2 - it_use3 - item_use - spell -
- * spells - spells3 - spells4
- * *********************************************************************** */
-bool noisy( int loudness, int nois_x, int nois_y, const char *msg = NULL );
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr - spells3
- * *********************************************************************** */
-void show_map( FixedVector<int, 2>& spec_place );
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void viewwindow2(char draw_it, bool do_updates);
-
-
-// last updated 12may2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void viewwindow3(char draw_it, bool do_updates); // non-IBM graphics
-
-// last updated 19jun2000 (gdl)
-/* ***********************************************************************
- * called from: acr view
- * *********************************************************************** */
-void setLOSRadius(int newLR);
-
-// last updated 02apr2001 (gdl)
-/* ***********************************************************************
- * called from: view monstuff
- * *********************************************************************** */
-bool check_awaken(int mons_aw);
-
-void clear_map();
-
-bool is_feature(int feature, int x, int y);
-
-inline bool in_map_grid(int x, int y)
-{
- return !(x < 1 || x >= GXM || y < 1 || y >= GYM);
-}
-
-#endif
diff --git a/stone_soup/crawl-ref/source/winhdr.h b/stone_soup/crawl-ref/source/winhdr.h
deleted file mode 100644
index a8d99fb1e3..0000000000
--- a/stone_soup/crawl-ref/source/winhdr.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * File: WinHdr.h
- * Summary: OS specific stuff for inclusion into AppHdr.h.
- * Written by: Jesse Jones
- *
- * Copyright © 1999 Jesse Jones.
- *
- * Change History (most recent first):
- *
- * <1> 5/30/99 JDJ Created.
- */
-
-
-#ifndef WINHDR_H
-#define WINHDR_H
-
-
-// ===================================================================================
-// Windows Includes
-// ===================================================================================
-#define WIN32_LEAN_AND_MEAN // exclude some of the less common APIs
-#define NOSERVICE
-#define NOMCX
-#define NOIME
-
-#define STRICT 1 // enable as much type checking as the lame Windows API will allow
-#define NOMINMAX // don't let Windows define (lower case!) min and max macros (conflicts with STL)
-
-#include <windows.h>
-#include <wtypes.h>
-#include <commdlg.h>
-#include <tchar.h>
-
-
-// ===================================================================================
-// MSVC Warnings (I'm not sure if these will fly with Crawl)
-// ===================================================================================
-#if _MSC_VER
-#ifndef ENABLE_EXTRA_WARNINGS
-#define ENABLE_EXTRA_WARNINGS 1 // if non-zero selected level 4 warnings are enabled
-#endif
-
-#if ENABLE_EXTRA_WARNINGS
-#pragma warning(error : 4057) // The pointer expressions used with the given operator had different base types.
-// #pragma warning(error : 4100) // The given formal parameter was never referenced in the body of the function for which it was declared.
-#pragma warning(error : 4130) // The operator was used with the address of a string literal.
-#pragma warning(error : 4131) // The specified function declaration is not in prototype form.
-#pragma warning(error : 4132) // The constant was not initialized.
-#pragma warning(error : 4152) // A pointer to a function was converted to a pointer to data, or visa versa.
-#pragma warning(error : 4208) // nonstandard extension used : delete [exp] - exp evaluated but ignored
-#pragma warning(error : 4211) // nonstandard extension used : redefined extern to static
-#pragma warning(error : 4212) // nonstandard extension used : function declaration used ellipsis
-#pragma warning(error : 4222) // nonstandard extension used : 'identifier' : 'static' should not be used on member functions defined at file scope
-#pragma warning(error : 4223) // nonstandard extension used : non-lvalue array converted to pointer
-#pragma warning(error : 4355) // 'this' : used in base member initializer list
-#pragma warning(error : 4663) // C++ language change: to explicitly specialize class template 'identifier' use the following syntax:
-#pragma warning(error : 4665) // C++ language change: assuming 'declaration' is an explicit specialization of a function template
-#pragma warning(error : 4701) // local variable 'name' may be used without having been initialized
-#pragma warning(error : 4705) // statement has no effect
-#pragma warning(error : 4706) // assignment within conditional expression
-#endif
-
-#pragma warning(disable : 4800) // casting integer to bool
-#pragma warning(disable : 4786) // identifier was truncated to '255' characters in the browser
-
-#endif
-
-
-
-#endif
diff --git a/stone_soup/crawl-ref/source/wpn-misc.cc b/stone_soup/crawl-ref/source/wpn-misc.cc
deleted file mode 100644
index 90b9cb0d37..0000000000
--- a/stone_soup/crawl-ref/source/wpn-misc.cc
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- *********************************************************************
- * File: wpn-misc.cc *
- * Summary: temporary home for weapon f(x) until struct'ed *
- * Written by: don brodale <dbrodale@bigfootinteractive.com> *
- * *
- * Changelog(most recent first): *
- * *
- * <00> 12jun2000 dlb created after little thought *
- *********************************************************************
- */
-
-#include "AppHdr.h"
-#include "wpn-misc.h"
-
-#include "externs.h"
-
-// all of this will be replaced by a struct and data handlers {dlb}:
-
-/*
- **************************************************
- * *
- * BEGIN PUBLIC FUNCTIONS *
- * *
- **************************************************
-*/
-
-// FIXME: Remove these eventually
-
-int damage_type(const item_def &item)
-{
- return (damage_type(item.base_type, item.sub_type));
-}
-
-int damage_type(int wclass, int wtype)
-{
- int type_damage = DVORP_CRUSHING; // this is the default, btw {dlb}
-
- if (wclass == OBJ_WEAPONS)
- {
- switch (wtype)
- {
- case WPN_DAGGER:
- case WPN_DEMON_BLADE:
- case WPN_DOUBLE_SWORD:
- case WPN_GREAT_SWORD:
- case WPN_KATANA:
- case WPN_KNIFE:
- case WPN_LONG_SWORD:
- case WPN_QUICK_BLADE:
- case WPN_SABRE:
- case WPN_FALCHION:
- case WPN_SCIMITAR:
- case WPN_SCYTHE:
- case WPN_SHORT_SWORD:
- case WPN_TRIPLE_SWORD:
- case WPN_BLESSED_BLADE:
- case WPN_LAJATANG:
- type_damage = DVORP_SLICING;
- break;
-
- case WPN_DEMON_TRIDENT:
- case WPN_EVENINGSTAR:
- case WPN_GIANT_SPIKED_CLUB:
- case WPN_MORNINGSTAR:
- case WPN_SPEAR:
- case WPN_SPIKED_FLAIL:
- case WPN_TRIDENT:
- type_damage = DVORP_PIERCING;
- break;
-
- case WPN_WAR_AXE:
- case WPN_BATTLEAXE:
- case WPN_BROAD_AXE:
- case WPN_EXECUTIONERS_AXE:
- case WPN_GLAIVE:
- case WPN_HALBERD:
- case WPN_HAND_AXE:
- case WPN_LOCHABER_AXE:
- type_damage = DVORP_CHOPPING;
- break;
- }
- }
-
- return (type_damage);
-} // end damage_type()
-
-bool can_cut_meat(int wclass, int wtype)
-{
- int type = damage_type( wclass, wtype );
-
- if (type == DVORP_CHOPPING || type == DVORP_SLICING)
- return (true);
-
- return (false);
-}
-
-int hands_reqd_for_weapon(int wclass, int wtype)
-{
- int reqd_hands = HANDS_ONE;
-
- switch (wclass)
- {
- case OBJ_WEAPONS:
- switch (wtype)
- {
- case WPN_HALBERD:
- case WPN_SCYTHE:
- case WPN_GLAIVE:
- case WPN_QUARTERSTAFF:
- case WPN_LAJATANG:
- case WPN_BATTLEAXE:
- case WPN_EXECUTIONERS_AXE:
- case WPN_GREAT_SWORD:
- case WPN_TRIPLE_SWORD:
- case WPN_GREAT_MACE:
- case WPN_DIRE_FLAIL:
- case WPN_GIANT_CLUB:
- case WPN_GIANT_SPIKED_CLUB:
- case WPN_LOCHABER_AXE:
- case WPN_BOW:
- case WPN_LONGBOW:
- case WPN_CROSSBOW:
- reqd_hands = HANDS_TWO;
- break;
-
- case WPN_SPEAR:
- case WPN_TRIDENT:
- case WPN_DEMON_TRIDENT:
- case WPN_WAR_AXE:
- case WPN_BROAD_AXE:
- case WPN_KATANA:
- case WPN_DOUBLE_SWORD:
- case WPN_HAND_CROSSBOW:
- case WPN_BLOWGUN:
- case WPN_SLING:
- reqd_hands = HANDS_HALF;
- break;
- }
- break;
-
- case OBJ_STAVES:
- reqd_hands = HANDS_TWO;
- break;
- }
-
- return (reqd_hands);
-} // end hands_reqd_for_weapon()
-
-bool is_demonic(unsigned char weapon_subtype)
-{
- switch (weapon_subtype)
- {
- case WPN_DEMON_BLADE:
- case WPN_DEMON_WHIP:
- case WPN_DEMON_TRIDENT:
- return true;
-
- default:
- return false;
- }
-} // end is_demonic()
-
-bool launches_things( unsigned char weapon_subtype )
-{
- switch (weapon_subtype)
- {
- case WPN_SLING:
- case WPN_BOW:
- case WPN_LONGBOW:
- case WPN_CROSSBOW:
- case WPN_HAND_CROSSBOW:
- case WPN_BLOWGUN:
- return (true);
-
- default:
- return (false);
- }
-} // end launches_things()
-
-unsigned char launched_by(unsigned char weapon_subtype)
-{
- switch (weapon_subtype)
- {
- case WPN_BLOWGUN:
- return MI_NEEDLE;
- case WPN_SLING:
- return MI_STONE;
- case WPN_BOW:
- case WPN_LONGBOW:
- return MI_ARROW;
- case WPN_CROSSBOW:
- return MI_BOLT;
- case WPN_HAND_CROSSBOW:
- return MI_DART;
- default:
- return MI_NONE; // lame debugging code :P {dlb}
- }
-} // end launched_by()
diff --git a/stone_soup/crawl-ref/source/wpn-misc.h b/stone_soup/crawl-ref/source/wpn-misc.h
deleted file mode 100644
index 55b9e35c86..0000000000
--- a/stone_soup/crawl-ref/source/wpn-misc.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- *********************************************************************
- * File: wpn-misc.h *
- * Summary: temporary home for weapon f(x) until struct'ed *
- * Written by: don brodale <dbrodale@bigfootinteractive.com> *
- * *
- * Changelog(most recent first): *
- * *
- * <00> 12jun2000 dlb created after little thought *
- *********************************************************************
-*/
-
-
-#ifndef WPNMISC_H
-#define WPNMISC_H
-
-#include "externs.h"
-
-
-/* ***********************************************************************
- * called from: food.h
- * *********************************************************************** */
-bool can_cut_meat(int wclass, int wtype);
-
-/* ***********************************************************************
- * called from: acr - fight - food - item_use - itemname - spells2
- * *********************************************************************** */
-int damage_type(int wclass, int wtype);
-int damage_type(const item_def &item);
-
-
-// last updated: 10jun2000 {dlb}
-/* ***********************************************************************
- * called from: describe - fight - item_use
- * *********************************************************************** */
-int hands_reqd_for_weapon(int wclass, int wtype);
-
-
-// last updated: 10jun2000 {dlb}
-/* ***********************************************************************
- * called from: dungeon - fight - item_use - randart
- * *********************************************************************** */
-bool is_demonic(unsigned char weapon_subtype);
-
-
-// last updated: 10jun2000 {dlb}
-/* ***********************************************************************
- * called from: dungeon - item_use - mstuff2
- * *********************************************************************** */
-unsigned char launched_by(unsigned char weapon_subtype);
-
-
-// last updated: 10jun2000 {dlb}
-/* ***********************************************************************
- * called from: describe - dungeon - fight - item_use - mstuff2 - randart -
- * spells2 - spells3
- * *********************************************************************** */
-bool launches_things( unsigned char weapon_subtype );
-
-
-#endif