summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Vollmert <rvollmert@gmx.net>2009-11-10 12:42:34 +0100
committerRobert Vollmert <rvollmert@gmx.net>2009-11-10 12:44:19 +0100
commit3977b123c4b05ea20323805fa901a213ecaeac3e (patch)
treea18491061f515ba43c35aaff1e51366cc5f7af3b
parentba3b7dbaad47d6e41d3763ec7dd6215bd74cfb5f (diff)
downloadcrawl-ref-3977b123c4b05ea20323805fa901a213ecaeac3e.tar.gz
crawl-ref-3977b123c4b05ea20323805fa901a213ecaeac3e.zip
Split shouting and stealth code from view.cc.
-rw-r--r--crawl-ref/source/abl-show.cc1
-rw-r--r--crawl-ref/source/abyss.cc1
-rw-r--r--crawl-ref/source/acr.cc1
-rw-r--r--crawl-ref/source/arena.cc1
-rw-r--r--crawl-ref/source/artefact.cc1
-rw-r--r--crawl-ref/source/beam.cc1
-rw-r--r--crawl-ref/source/behold.cc1
-rw-r--r--crawl-ref/source/chardump.cc1
-rw-r--r--crawl-ref/source/cloud.cc1
-rw-r--r--crawl-ref/source/command.cc1
-rw-r--r--crawl-ref/source/dbg-maps.cc1
-rw-r--r--crawl-ref/source/decks.cc1
-rw-r--r--crawl-ref/source/delay.cc1
-rw-r--r--crawl-ref/source/directn.cc1
-rw-r--r--crawl-ref/source/dungeon.cc1
-rw-r--r--crawl-ref/source/effects.cc1
-rw-r--r--crawl-ref/source/exclude.cc1
-rw-r--r--crawl-ref/source/fight.cc1
-rw-r--r--crawl-ref/source/files.cc1
-rw-r--r--crawl-ref/source/format.cc1
-rw-r--r--crawl-ref/source/godabil.cc1
-rw-r--r--crawl-ref/source/godwrath.cc1
-rw-r--r--crawl-ref/source/initfile.cc1
-rw-r--r--crawl-ref/source/invent.cc1
-rw-r--r--crawl-ref/source/it_use3.cc1
-rw-r--r--crawl-ref/source/item_use.cc1
-rw-r--r--crawl-ref/source/itemname.cc1
-rw-r--r--crawl-ref/source/items.cc1
-rw-r--r--crawl-ref/source/l_crawl.cc1
-rw-r--r--crawl-ref/source/l_dgn.cc1
-rw-r--r--crawl-ref/source/libgui.cc1
-rw-r--r--crawl-ref/source/libunix.cc1
-rw-r--r--crawl-ref/source/libw32c.cc1
-rw-r--r--crawl-ref/source/makefile.obj1
-rw-r--r--crawl-ref/source/makeitem.cc1
-rw-r--r--crawl-ref/source/map_knowledge.cc1
-rw-r--r--crawl-ref/source/menu.cc1
-rw-r--r--crawl-ref/source/message.cc1
-rw-r--r--crawl-ref/source/misc.cc1
-rw-r--r--crawl-ref/source/mon-abil.cc1
-rw-r--r--crawl-ref/source/mon-act.cc1
-rw-r--r--crawl-ref/source/mon-behv.cc1
-rw-r--r--crawl-ref/source/mon-cast.cc1
-rw-r--r--crawl-ref/source/mon-util.cc1
-rw-r--r--crawl-ref/source/monplace.cc1
-rw-r--r--crawl-ref/source/monspeak.cc1
-rw-r--r--crawl-ref/source/monster.cc1
-rw-r--r--crawl-ref/source/monstuff.cc1
-rw-r--r--crawl-ref/source/mutation.cc1
-rw-r--r--crawl-ref/source/ouch.cc1
-rw-r--r--crawl-ref/source/output.cc1
-rw-r--r--crawl-ref/source/overmap.cc1
-rw-r--r--crawl-ref/source/player.cc1
-rw-r--r--crawl-ref/source/religion.cc1
-rw-r--r--crawl-ref/source/shout.cc548
-rw-r--r--crawl-ref/source/shout.h13
-rw-r--r--crawl-ref/source/spells1.cc1
-rw-r--r--crawl-ref/source/spells2.cc1
-rw-r--r--crawl-ref/source/spells3.cc1
-rw-r--r--crawl-ref/source/spells4.cc1
-rw-r--r--crawl-ref/source/spl-cast.cc1
-rw-r--r--crawl-ref/source/spl-mis.cc1
-rw-r--r--crawl-ref/source/state.cc1
-rw-r--r--crawl-ref/source/stuff.cc2
-rw-r--r--crawl-ref/source/tags.cc1
-rw-r--r--crawl-ref/source/teleport.cc1
-rw-r--r--crawl-ref/source/terrain.cc1
-rw-r--r--crawl-ref/source/tilepick.cc1
-rw-r--r--crawl-ref/source/tilereg.cc1
-rw-r--r--crawl-ref/source/tilesdl.cc1
-rw-r--r--crawl-ref/source/traps.cc1
-rw-r--r--crawl-ref/source/travel.cc1
-rw-r--r--crawl-ref/source/tutorial.cc1
-rw-r--r--crawl-ref/source/view.cc519
-rw-r--r--crawl-ref/source/view.h8
-rw-r--r--crawl-ref/source/wiz-dgn.cc1
-rw-r--r--crawl-ref/source/wiz-item.cc1
-rw-r--r--crawl-ref/source/wiz-mon.cc1
-rw-r--r--crawl-ref/source/xom.cc1
79 files changed, 638 insertions, 526 deletions
diff --git a/crawl-ref/source/abl-show.cc b/crawl-ref/source/abl-show.cc
index c0a03f1761..3e7173f8bd 100644
--- a/crawl-ref/source/abl-show.cc
+++ b/crawl-ref/source/abl-show.cc
@@ -58,6 +58,7 @@
#include "transfor.h"
#include "tutorial.h"
#include "view.h"
+#include "shout.h"
#ifdef UNIX
#include "libunix.h"
diff --git a/crawl-ref/source/abyss.cc b/crawl-ref/source/abyss.cc
index cf3f74267d..4e025bba0d 100644
--- a/crawl-ref/source/abyss.cc
+++ b/crawl-ref/source/abyss.cc
@@ -39,6 +39,7 @@
#include "tiles.h"
#include "traps.h"
#include "view.h"
+#include "shout.h"
#include "xom.h"
const coord_def abyss_center(45,35);
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc
index 12b4b348e3..ff1a1ccd3b 100644
--- a/crawl-ref/source/acr.cc
+++ b/crawl-ref/source/acr.cc
@@ -123,6 +123,7 @@
#include "travel.h"
#include "tutorial.h"
#include "view.h"
+#include "shout.h"
#include "viewchar.h"
#include "viewgeom.h"
#include "stash.h"
diff --git a/crawl-ref/source/arena.cc b/crawl-ref/source/arena.cc
index dcae744e65..8e4497b2cb 100644
--- a/crawl-ref/source/arena.cc
+++ b/crawl-ref/source/arena.cc
@@ -30,6 +30,7 @@
#include "spl-util.h"
#include "state.h"
#include "view.h"
+#include "shout.h"
#include "viewgeom.h"
#define DEBUG_DIAGNOSTICS 1
diff --git a/crawl-ref/source/artefact.cc b/crawl-ref/source/artefact.cc
index 41ac02868c..fb2687526a 100644
--- a/crawl-ref/source/artefact.cc
+++ b/crawl-ref/source/artefact.cc
@@ -31,6 +31,7 @@
#include "spl-book.h"
#include "stuff.h"
#include "view.h" // Elemental colours for unrandarts
+#include "shout.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 &
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc
index f948ca0ff5..976d62b1a5 100644
--- a/crawl-ref/source/beam.cc
+++ b/crawl-ref/source/beam.cc
@@ -62,6 +62,7 @@
#include "transfor.h"
#include "traps.h"
#include "view.h"
+#include "shout.h"
#include "viewchar.h"
#include "viewgeom.h"
#include "xom.h"
diff --git a/crawl-ref/source/behold.cc b/crawl-ref/source/behold.cc
index b4835e3090..d7dd225aa8 100644
--- a/crawl-ref/source/behold.cc
+++ b/crawl-ref/source/behold.cc
@@ -17,6 +17,7 @@
#include "state.h"
#include "stuff.h"
#include "view.h"
+#include "shout.h"
// Add a monster to the list of beholders.
void player::add_beholder(const monsters* mon)
diff --git a/crawl-ref/source/chardump.cc b/crawl-ref/source/chardump.cc
index fbbeb77e76..35e32f778b 100644
--- a/crawl-ref/source/chardump.cc
+++ b/crawl-ref/source/chardump.cc
@@ -55,6 +55,7 @@
#include "stuff.h"
#include "transfor.h"
#include "view.h"
+#include "shout.h"
#include "viewchar.h"
#include "xom.h"
diff --git a/crawl-ref/source/cloud.cc b/crawl-ref/source/cloud.cc
index d9e5b13350..89ccae3cec 100644
--- a/crawl-ref/source/cloud.cc
+++ b/crawl-ref/source/cloud.cc
@@ -26,6 +26,7 @@
#include "stuff.h"
#include "terrain.h"
#include "view.h"
+#include "shout.h"
#include "mutation.h"
#include "los.h"
diff --git a/crawl-ref/source/command.cc b/crawl-ref/source/command.cc
index 3d0ef4a04f..7ce3e38ea6 100644
--- a/crawl-ref/source/command.cc
+++ b/crawl-ref/source/command.cc
@@ -52,6 +52,7 @@
#include "terrain.h"
#include "transfor.h"
#include "view.h"
+#include "shout.h"
#include "viewchar.h"
static void _adjust_item(void);
diff --git a/crawl-ref/source/dbg-maps.cc b/crawl-ref/source/dbg-maps.cc
index cf565712dd..d5b22d0e98 100644
--- a/crawl-ref/source/dbg-maps.cc
+++ b/crawl-ref/source/dbg-maps.cc
@@ -20,6 +20,7 @@
#include "place.h"
#include "player.h"
#include "view.h"
+#include "shout.h"
#ifdef DEBUG_DIAGNOSTICS
// Map statistics generation.
diff --git a/crawl-ref/source/decks.cc b/crawl-ref/source/decks.cc
index 07016dea68..70fe3ead25 100644
--- a/crawl-ref/source/decks.cc
+++ b/crawl-ref/source/decks.cc
@@ -52,6 +52,7 @@
#include "transfor.h"
#include "traps.h"
#include "view.h"
+#include "shout.h"
#include "xom.h"
// DECK STRUCTURE: deck.plus is the number of cards the deck *started*
diff --git a/crawl-ref/source/delay.cc b/crawl-ref/source/delay.cc
index f4ffa5c2c8..85ab997616 100644
--- a/crawl-ref/source/delay.cc
+++ b/crawl-ref/source/delay.cc
@@ -52,6 +52,7 @@
#include "travel.h"
#include "tutorial.h"
#include "view.h"
+#include "shout.h"
#include "xom.h"
extern std::vector<SelItem> items_for_multidrop;
diff --git a/crawl-ref/source/directn.cc b/crawl-ref/source/directn.cc
index 23f0cba945..5e6f1f8d42 100644
--- a/crawl-ref/source/directn.cc
+++ b/crawl-ref/source/directn.cc
@@ -65,6 +65,7 @@
#include "travel.h"
#include "tutorial.h"
#include "view.h"
+#include "shout.h"
#include "viewchar.h"
#include "viewgeom.h"
#include "wiz-mon.h"
diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc
index f2f46d92ad..b5a9659482 100644
--- a/crawl-ref/source/dungeon.cc
+++ b/crawl-ref/source/dungeon.cc
@@ -57,6 +57,7 @@
#include "traps.h"
#include "travel.h"
#include "view.h"
+#include "shout.h"
#ifdef WIZARD
#include "cio.h" // for cancelable_get_line()
diff --git a/crawl-ref/source/effects.cc b/crawl-ref/source/effects.cc
index d1332a4607..cc50b7c8c3 100644
--- a/crawl-ref/source/effects.cc
+++ b/crawl-ref/source/effects.cc
@@ -64,6 +64,7 @@
#include "traps.h"
#include "tutorial.h"
#include "view.h"
+#include "shout.h"
#include "viewchar.h"
#include "xom.h"
diff --git a/crawl-ref/source/exclude.cc b/crawl-ref/source/exclude.cc
index 4b2aed3fa5..f83cf4c646 100644
--- a/crawl-ref/source/exclude.cc
+++ b/crawl-ref/source/exclude.cc
@@ -19,6 +19,7 @@
#include "travel.h"
#include "tutorial.h"
#include "view.h"
+#include "shout.h"
static bool _mon_needs_auto_exclude(const monsters *mon, bool sleepy = false)
{
diff --git a/crawl-ref/source/fight.cc b/crawl-ref/source/fight.cc
index 8b6dc76fd6..2f52f2f30c 100644
--- a/crawl-ref/source/fight.cc
+++ b/crawl-ref/source/fight.cc
@@ -63,6 +63,7 @@
#include "traps.h"
#include "tutorial.h"
#include "view.h"
+#include "shout.h"
#include "viewgeom.h"
#include "xom.h"
diff --git a/crawl-ref/source/files.cc b/crawl-ref/source/files.cc
index cd63e9cd15..7b7ed06092 100644
--- a/crawl-ref/source/files.cc
+++ b/crawl-ref/source/files.cc
@@ -79,6 +79,7 @@
#include "travel.h"
#include "tutorial.h"
#include "view.h"
+#include "shout.h"
#include "viewgeom.h"
#ifdef TARGET_COMPILER_VC
diff --git a/crawl-ref/source/format.cc b/crawl-ref/source/format.cc
index 11059cb39a..7bed575cd3 100644
--- a/crawl-ref/source/format.cc
+++ b/crawl-ref/source/format.cc
@@ -9,6 +9,7 @@
#include "format.h"
#include "showsymb.h"
#include "view.h"
+#include "shout.h"
#include "viewchar.h"
formatted_string::formatted_string(int init_colour)
diff --git a/crawl-ref/source/godabil.cc b/crawl-ref/source/godabil.cc
index a7f4c77484..6201bd88b9 100644
--- a/crawl-ref/source/godabil.cc
+++ b/crawl-ref/source/godabil.cc
@@ -39,6 +39,7 @@
#include "stuff.h"
#include "terrain.h"
#include "view.h"
+#include "shout.h"
bool yred_injury_mirror(bool actual)
{
diff --git a/crawl-ref/source/godwrath.cc b/crawl-ref/source/godwrath.cc
index 813c5debd4..235506d214 100644
--- a/crawl-ref/source/godwrath.cc
+++ b/crawl-ref/source/godwrath.cc
@@ -36,6 +36,7 @@
#include "stash.h"
#include "transfor.h"
#include "view.h"
+#include "shout.h"
#include "xom.h"
diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc
index 41cc6dcca0..eda4e11858 100644
--- a/crawl-ref/source/initfile.cc
+++ b/crawl-ref/source/initfile.cc
@@ -45,6 +45,7 @@
#include "travel.h"
#include "items.h"
#include "view.h"
+#include "shout.h"
#include "viewchar.h"
// For finding the executable's path
diff --git a/crawl-ref/source/invent.cc b/crawl-ref/source/invent.cc
index df2938cebb..923f09257d 100644
--- a/crawl-ref/source/invent.cc
+++ b/crawl-ref/source/invent.cc
@@ -38,6 +38,7 @@
#include "showsymb.h"
#include "stuff.h"
#include "view.h"
+#include "shout.h"
#include "menu.h"
#include "mon-util.h"
#include "state.h"
diff --git a/crawl-ref/source/it_use3.cc b/crawl-ref/source/it_use3.cc
index 42379cccc6..4e66d4e57b 100644
--- a/crawl-ref/source/it_use3.cc
+++ b/crawl-ref/source/it_use3.cc
@@ -44,6 +44,7 @@
#include "state.h"
#include "stuff.h"
#include "view.h"
+#include "shout.h"
#include "xom.h"
// TODO: Let artefacts besides weapons generate noise.
diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc
index 67fede953d..4fc8cbf02a 100644
--- a/crawl-ref/source/item_use.cc
+++ b/crawl-ref/source/item_use.cc
@@ -72,6 +72,7 @@
#include "traps.h"
#include "tutorial.h"
#include "view.h"
+#include "shout.h"
#include "viewchar.h"
#include "viewgeom.h"
#include "xom.h"
diff --git a/crawl-ref/source/itemname.cc b/crawl-ref/source/itemname.cc
index ff389bd869..edaf36c274 100644
--- a/crawl-ref/source/itemname.cc
+++ b/crawl-ref/source/itemname.cc
@@ -46,6 +46,7 @@
#include "stuff.h"
#include "transfor.h"
#include "view.h"
+#include "shout.h"
id_arr type_ids;
diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc
index fa9034eb99..0914663fea 100644
--- a/crawl-ref/source/items.cc
+++ b/crawl-ref/source/items.cc
@@ -64,6 +64,7 @@
#include "terrain.h"
#include "tutorial.h"
#include "view.h"
+#include "shout.h"
#include "viewgeom.h"
#include "xom.h"
diff --git a/crawl-ref/source/l_crawl.cc b/crawl-ref/source/l_crawl.cc
index 0918a9f099..f98ffe8e11 100644
--- a/crawl-ref/source/l_crawl.cc
+++ b/crawl-ref/source/l_crawl.cc
@@ -24,6 +24,7 @@
#include "random.h"
#include "stuff.h"
#include "view.h"
+#include "shout.h"
#ifdef UNIX
#include <sys/time.h>
diff --git a/crawl-ref/source/l_dgn.cc b/crawl-ref/source/l_dgn.cc
index 9a0318e1a9..a462e12a3d 100644
--- a/crawl-ref/source/l_dgn.cc
+++ b/crawl-ref/source/l_dgn.cc
@@ -18,6 +18,7 @@
#include "spl-util.h"
#include "state.h"
#include "view.h"
+#include "shout.h"
///////////////////////////////////////////////////////////////////////////
// Lua dungeon bindings (in the dgn table).
diff --git a/crawl-ref/source/libgui.cc b/crawl-ref/source/libgui.cc
index 7fafaffc2a..00298aae72 100644
--- a/crawl-ref/source/libgui.cc
+++ b/crawl-ref/source/libgui.cc
@@ -29,6 +29,7 @@
#include "tilesdl.h"
#include "travel.h"
#include "view.h"
+#include "shout.h"
#include "viewgeom.h"
#include <SDL.h>
diff --git a/crawl-ref/source/libunix.cc b/crawl-ref/source/libunix.cc
index 1479396951..828ed18a47 100644
--- a/crawl-ref/source/libunix.cc
+++ b/crawl-ref/source/libunix.cc
@@ -35,6 +35,7 @@
#include "state.h"
#include "stuff.h"
#include "view.h"
+#include "shout.h"
#include "viewgeom.h"
#ifdef DGL_ENABLE_CORE_DUMP
diff --git a/crawl-ref/source/libw32c.cc b/crawl-ref/source/libw32c.cc
index a9fff4df09..047a8ee5a1 100644
--- a/crawl-ref/source/libw32c.cc
+++ b/crawl-ref/source/libw32c.cc
@@ -71,6 +71,7 @@
#include "state.h"
#include "stuff.h"
#include "view.h"
+#include "shout.h"
#include "viewgeom.h"
char oldTitle[80];
diff --git a/crawl-ref/source/makefile.obj b/crawl-ref/source/makefile.obj
index b948deb7a4..c85450cd5f 100644
--- a/crawl-ref/source/makefile.obj
+++ b/crawl-ref/source/makefile.obj
@@ -129,6 +129,7 @@ religion.o \
rng.o \
sha256.o \
shopping.o \
+shout.o \
show.o \
showsymb.o \
skills.o \
diff --git a/crawl-ref/source/makeitem.cc b/crawl-ref/source/makeitem.cc
index d302dadc68..5d6cd56fac 100644
--- a/crawl-ref/source/makeitem.cc
+++ b/crawl-ref/source/makeitem.cc
@@ -29,6 +29,7 @@
#include "spl-book.h"
#include "travel.h"
#include "view.h"
+#include "shout.h"
void item_set_appearance(item_def &item);
diff --git a/crawl-ref/source/map_knowledge.cc b/crawl-ref/source/map_knowledge.cc
index 7db6bfb1bb..87951a4d69 100644
--- a/crawl-ref/source/map_knowledge.cc
+++ b/crawl-ref/source/map_knowledge.cc
@@ -13,6 +13,7 @@
#include "stuff.h"
#include "terrain.h"
#include "view.h"
+#include "shout.h"
// These are hidden from the rest of the world... use the functions
// below to get information about the map grid.
diff --git a/crawl-ref/source/menu.cc b/crawl-ref/source/menu.cc
index a8a310ef30..d62d120b9a 100644
--- a/crawl-ref/source/menu.cc
+++ b/crawl-ref/source/menu.cc
@@ -18,6 +18,7 @@
#include "player.h"
#include "tutorial.h"
#include "view.h"
+#include "shout.h"
#ifdef USE_TILE
#include "coord.h"
diff --git a/crawl-ref/source/message.cc b/crawl-ref/source/message.cc
index aa52c81d6c..e87a988682 100644
--- a/crawl-ref/source/message.cc
+++ b/crawl-ref/source/message.cc
@@ -38,6 +38,7 @@
#include "travel.h"
#include "tutorial.h"
#include "view.h"
+#include "shout.h"
#include "viewchar.h"
#include "viewgeom.h"
#include "menu.h"
diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc
index 4be5a39c2d..fed192cb41 100644
--- a/crawl-ref/source/misc.cc
+++ b/crawl-ref/source/misc.cc
@@ -82,6 +82,7 @@
#include "travel.h"
#include "tutorial.h"
#include "view.h"
+#include "shout.h"
#include "viewchar.h"
#include "xom.h"
diff --git a/crawl-ref/source/mon-abil.cc b/crawl-ref/source/mon-abil.cc
index aba43a7b22..5948585d3d 100644
--- a/crawl-ref/source/mon-abil.cc
+++ b/crawl-ref/source/mon-abil.cc
@@ -34,6 +34,7 @@
#include "state.h"
#include "stuff.h"
#include "view.h"
+#include "shout.h"
#include "viewchar.h"
bool ugly_thing_mutate(monsters *ugly, bool proximity)
diff --git a/crawl-ref/source/mon-act.cc b/crawl-ref/source/mon-act.cc
index 73b25f3a7d..db634705b4 100644
--- a/crawl-ref/source/mon-act.cc
+++ b/crawl-ref/source/mon-act.cc
@@ -45,6 +45,7 @@
#include "traps.h"
#include "tutorial.h"
#include "view.h"
+#include "shout.h"
#include "viewchar.h"
static bool _handle_pickup(monsters *monster);
diff --git a/crawl-ref/source/mon-behv.cc b/crawl-ref/source/mon-behv.cc
index 7e5188a40f..56dce671b0 100644
--- a/crawl-ref/source/mon-behv.cc
+++ b/crawl-ref/source/mon-behv.cc
@@ -25,6 +25,7 @@
#include "traps.h"
#include "tutorial.h"
#include "view.h"
+#include "shout.h"
static void _set_nearest_monster_foe(monsters *monster);
diff --git a/crawl-ref/source/mon-cast.cc b/crawl-ref/source/mon-cast.cc
index 23661a062d..8caa4a1737 100644
--- a/crawl-ref/source/mon-cast.cc
+++ b/crawl-ref/source/mon-cast.cc
@@ -33,6 +33,7 @@
#include "spells3.h"
#include "stuff.h"
#include "view.h"
+#include "shout.h"
#include "viewchar.h"
static bool _valid_mon_spells[NUM_SPELLS];
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index c7e0721e20..29bbfa53db 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -34,6 +34,7 @@
#include "stuff.h"
#include "terrain.h"
#include "view.h"
+#include "shout.h"
//jmf: moved from inside function
static FixedVector < int, NUM_MONSTERS > mon_entry;
diff --git a/crawl-ref/source/monplace.cc b/crawl-ref/source/monplace.cc
index 37ec0ca297..e45bad6ad5 100644
--- a/crawl-ref/source/monplace.cc
+++ b/crawl-ref/source/monplace.cc
@@ -35,6 +35,7 @@
#include "terrain.h"
#include "traps.h"
#include "view.h"
+#include "shout.h"
static std::vector<int> vault_mon_types;
static std::vector<int> vault_mon_bases;
diff --git a/crawl-ref/source/monspeak.cc b/crawl-ref/source/monspeak.cc
index 3241200ae1..8143508fed 100644
--- a/crawl-ref/source/monspeak.cc
+++ b/crawl-ref/source/monspeak.cc
@@ -31,6 +31,7 @@
#include "state.h"
#include "stuff.h"
#include "view.h"
+#include "shout.h"
// Try the exact key lookup along with the entire prefix list.
// If that fails, start ignoring hostile/religion/silence, in that order,
diff --git a/crawl-ref/source/monster.cc b/crawl-ref/source/monster.cc
index d566a40275..d2051f9f62 100644
--- a/crawl-ref/source/monster.cc
+++ b/crawl-ref/source/monster.cc
@@ -30,6 +30,7 @@
#include "traps.h"
#include "tutorial.h"
#include "view.h"
+#include "shout.h"
#include "xom.h"
struct mon_spellbook
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index 4aa5ecfa4c..2a31fcbeb8 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -50,6 +50,7 @@
#include "traps.h"
#include "tutorial.h"
#include "view.h"
+#include "shout.h"
#include "viewchar.h"
#include "stash.h"
#include "xom.h"
diff --git a/crawl-ref/source/mutation.cc b/crawl-ref/source/mutation.cc
index 8aaf5460d3..c0b7c045d8 100644
--- a/crawl-ref/source/mutation.cc
+++ b/crawl-ref/source/mutation.cc
@@ -44,6 +44,7 @@
#include "transfor.h"
#include "tutorial.h"
#include "view.h"
+#include "shout.h"
#include "xom.h"
static int _body_covered();
diff --git a/crawl-ref/source/ouch.cc b/crawl-ref/source/ouch.cc
index e7fca1e917..e4230464af 100644
--- a/crawl-ref/source/ouch.cc
+++ b/crawl-ref/source/ouch.cc
@@ -65,6 +65,7 @@
#include "stuff.h"
#include "tutorial.h"
#include "view.h"
+#include "shout.h"
#include "xom.h"
diff --git a/crawl-ref/source/output.cc b/crawl-ref/source/output.cc
index b38ecd0c80..25ab8cb7fa 100644
--- a/crawl-ref/source/output.cc
+++ b/crawl-ref/source/output.cc
@@ -51,6 +51,7 @@
#include "transfor.h"
#include "travel.h"
#include "view.h"
+#include "shout.h"
#include "viewchar.h"
#include "viewgeom.h"
diff --git a/crawl-ref/source/overmap.cc b/crawl-ref/source/overmap.cc
index e7c5c49631..6cbb4cee88 100644
--- a/crawl-ref/source/overmap.cc
+++ b/crawl-ref/source/overmap.cc
@@ -37,6 +37,7 @@
#include "stuff.h"
#include "terrain.h"
#include "view.h"
+#include "shout.h"
typedef std::map<branch_type, level_id> stair_map_type;
typedef std::map<level_pos, shop_type> shop_map_type;
diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc
index 379e9cb751..c7181c13f8 100644
--- a/crawl-ref/source/player.cc
+++ b/crawl-ref/source/player.cc
@@ -70,6 +70,7 @@
#include "travel.h"
#include "tutorial.h"
#include "view.h"
+#include "shout.h"
#include "viewgeom.h"
#include "tiles.h"
#include "xom.h"
diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc
index 1179ea5115..088c508473 100644
--- a/crawl-ref/source/religion.cc
+++ b/crawl-ref/source/religion.cc
@@ -80,6 +80,7 @@
#include "transfor.h"
#include "tutorial.h"
#include "view.h"
+#include "shout.h"
#include "xom.h"
#if DEBUG_RELIGION
diff --git a/crawl-ref/source/shout.cc b/crawl-ref/source/shout.cc
new file mode 100644
index 0000000000..1ecc0600f5
--- /dev/null
+++ b/crawl-ref/source/shout.cc
@@ -0,0 +1,548 @@
+/*
+ * File: shout.cc
+ * Summary: Stealth, noise, shouting.
+ */
+
+#include "AppHdr.h"
+
+#include "shout.h"
+
+#include "coord.h"
+#include "database.h"
+#include "env.h"
+#include "ghost.h"
+#include "jobs.h"
+#include "message.h"
+#include "misc.h"
+#include "mon-behv.h"
+#include "monplace.h"
+#include "monster.h"
+#include "monstuff.h"
+#include "options.h"
+#include "player.h"
+#include "random.h"
+#include "skills.h"
+#include "state.h"
+#include "stuff.h"
+#include "tutorial.h"
+#include "view.h"
+
+#include <sstream>
+
+extern int stealth; // defined in acr.cc
+
+void handle_monster_shouts(monsters* monster, bool force)
+{
+ if (!force && x_chance_in_y(you.skills[SK_STEALTH], 30))
+ return;
+
+ // Friendly or neutral monsters don't shout.
+ if (!force && (monster->friendly() || monster->neutral()))
+ return;
+
+ // Get it once, since monster might be S_RANDOM, in which case
+ // mons_shouts() will return a different value every time.
+ // Demon lords will insult you as a greeting, but later we'll
+ // choose a random verb and loudness for them.
+ shout_type s_type = mons_shouts(monster->type, false);
+
+ // Silent monsters can give noiseless "visual shouts" if the
+ // player can see them, in which case silence isn't checked for.
+ if (s_type == S_SILENT && !monster->visible_to(&you)
+ || s_type != S_SILENT && !player_can_hear(monster->pos()))
+ {
+ return;
+ }
+
+ mon_acting mact(monster);
+
+ std::string default_msg_key = "";
+
+ switch (s_type)
+ {
+ case S_SILENT:
+ // No default message.
+ break;
+ case S_SHOUT:
+ default_msg_key = "__SHOUT";
+ break;
+ case S_BARK:
+ default_msg_key = "__BARK";
+ break;
+ case S_SHOUT2:
+ default_msg_key = "__TWO_SHOUTS";
+ break;
+ case S_ROAR:
+ default_msg_key = "__ROAR";
+ break;
+ case S_SCREAM:
+ default_msg_key = "__SCREAM";
+ break;
+ case S_BELLOW:
+ default_msg_key = "__BELLOW";
+ break;
+ case S_SCREECH:
+ default_msg_key = "__SCREECH";
+ break;
+ case S_BUZZ:
+ default_msg_key = "__BUZZ";
+ break;
+ case S_MOAN:
+ default_msg_key = "__MOAN";
+ break;
+ case S_GURGLE:
+ default_msg_key = "__GURGLE";
+ break;
+ case S_WHINE:
+ default_msg_key = "__WHINE";
+ break;
+ case S_CROAK:
+ default_msg_key = "__CROAK";
+ break;
+ case S_GROWL:
+ default_msg_key = "__GROWL";
+ break;
+ case S_HISS:
+ default_msg_key = "__HISS";
+ break;
+ case S_DEMON_TAUNT:
+ default_msg_key = "__DEMON_TAUNT";
+ break;
+ default:
+ default_msg_key = "__BUGGY"; // S_LOUD, S_VERY_SOFT, etc. (loudness)
+ }
+
+ // Now that we have the message key, get a random verb and noise level
+ // for pandemonium lords.
+ if (s_type == S_DEMON_TAUNT)
+ s_type = mons_shouts(monster->type, true);
+
+ std::string msg, suffix;
+ std::string key = mons_type_name(monster->type, DESC_PLAIN);
+
+ // Pandemonium demons have random names, so use "pandemonium lord"
+ if (monster->type == MONS_PANDEMONIUM_DEMON)
+ key = "pandemonium lord";
+ // Search for player ghost shout by the ghost's class.
+ else if (monster->type == MONS_PLAYER_GHOST)
+ {
+ const ghost_demon &ghost = *(monster->ghost);
+ std::string ghost_class = get_class_name(ghost.job);
+
+ key = ghost_class + " player ghost";
+
+ default_msg_key = "player ghost";
+ }
+
+ // Tries to find an entry for "name seen" or "name unseen",
+ // and if no such entry exists then looks simply for "name".
+ // We don't use "you.can_see(monster)" here since that would return
+ // false for submerged monsters, but submerged monsters will be forced
+ // to surface before they shout, thus removing that source of
+ // non-visibility.
+ if (mons_near(monster) && (!monster->invisible() || you.can_see_invisible()))
+ suffix = " seen";
+ else
+ suffix = " unseen";
+
+ msg = getShoutString(key, suffix);
+
+ if (msg == "__DEFAULT" || msg == "__NEXT")
+ msg = getShoutString(default_msg_key, suffix);
+ else if (msg.empty())
+ {
+ // NOTE: Use the hardcoded glyph rather than that returned
+ // by mons_char(), since the result of mons_char() can be
+ // changed by user settings.
+ char mchar = get_monster_data(monster->type)->showchar;
+
+ // See if there's a shout for all monsters using the
+ // same glyph/symbol
+ std::string glyph_key = "'";
+
+ // Database keys are case-insensitve.
+ if (isupper(mchar))
+ glyph_key += "cap-";
+
+ glyph_key += mchar;
+ glyph_key += "'";
+ msg = getShoutString(glyph_key, suffix);
+
+ if (msg.empty() || msg == "__DEFAULT")
+ msg = getShoutString(default_msg_key, suffix);
+ }
+
+ if (default_msg_key == "__BUGGY")
+ {
+ msg::streams(MSGCH_SOUND) << "You hear something buggy!"
+ << std::endl;
+ }
+ else if (s_type == S_SILENT && (msg.empty() || msg == "__NONE"))
+ {
+ ; // No "visual shout" defined for silent monster, do nothing.
+ }
+ else if (msg.empty()) // Still nothing found?
+ {
+ msg::streams(MSGCH_DIAGNOSTICS)
+ << "No shout entry for default shout type '"
+ << default_msg_key << "'" << std::endl;
+
+ msg::streams(MSGCH_SOUND) << "You hear something buggy!"
+ << std::endl;
+ }
+ else if (msg == "__NONE")
+ {
+ msg::streams(MSGCH_DIAGNOSTICS)
+ << "__NONE returned as shout for non-silent monster '"
+ << default_msg_key << "'" << std::endl;
+ msg::streams(MSGCH_SOUND) << "You hear something buggy!"
+ << std::endl;
+ }
+ else
+ {
+ msg_channel_type channel = MSGCH_TALK;
+
+ std::string param = "";
+ std::string::size_type pos = msg.find(":");
+
+ if (pos != std::string::npos)
+ {
+ param = msg.substr(0, pos);
+ msg = msg.substr(pos + 1);
+ }
+
+ if (s_type == S_SILENT || param == "VISUAL")
+ channel = MSGCH_TALK_VISUAL;
+ else if (param == "SOUND")
+ channel = MSGCH_SOUND;
+
+ // Monster must come up from being submerged if it wants to shout.
+ if (monster->submerged())
+ {
+ if (!monster->del_ench(ENCH_SUBMERGED))
+ {
+ // Couldn't unsubmerge.
+ return;
+ }
+
+ if (you.can_see(monster))
+ {
+ if (monster->type == MONS_AIR_ELEMENTAL)
+ monster->seen_context = "thin air";
+ else if (monster->type == MONS_TRAPDOOR_SPIDER)
+ monster->seen_context = "leaps out";
+ else if (!monster_habitable_grid(monster, DNGN_FLOOR))
+ monster->seen_context = "bursts forth shouting";
+ else
+ monster->seen_context = "surfaces";
+
+ // Give interrupt message before shout message.
+ handle_seen_interrupt(monster);
+ }
+ }
+
+ if (channel != MSGCH_TALK_VISUAL || you.can_see(monster))
+ {
+ msg = do_mon_str_replacements(msg, monster, s_type);
+ msg::streams(channel) << msg << std::endl;
+
+ // Otherwise it can move away with no feedback.
+ if (you.can_see(monster))
+ {
+ if (!(monster->flags & MF_WAS_IN_VIEW))
+ handle_seen_interrupt(monster);
+ seen_monster(monster);
+ }
+ }
+ }
+
+ const int noise_level = get_shout_noise_level(s_type);
+ const bool heard = noisy(noise_level, monster->pos(), monster->mindex());
+
+ if (Options.tutorial_left && (heard || you.can_see(monster)))
+ learned_something_new(TUT_MONSTER_SHOUT, monster->pos());
+}
+
+#ifdef WIZARD
+void force_monster_shout(monsters* monster)
+{
+ handle_monster_shouts(monster, true);
+}
+#endif
+
+
+bool check_awaken(monsters* monster)
+{
+ // Monsters put to sleep by ensorcelled hibernation will sleep
+ // at least one turn.
+ if (monster->has_ench(ENCH_SLEEPY))
+ return (false);
+
+ // Berserkers aren't really concerned about stealth.
+ if (you.berserk())
+ return (true);
+
+ // I assume that creatures who can sense invisible are very perceptive.
+ int mons_perc = 10 + (mons_intel(monster) * 4) + monster->hit_dice
+ + mons_sense_invis(monster) * 5;
+
+ bool unnatural_stealthy = false; // "stealthy" only because of invisibility?
+
+ // Critters that are wandering but still have MHITYOU as their foe are
+ // still actively on guard for the player, even if they can't see you.
+ // Give them a large bonus -- handle_behaviour() will nuke 'foe' after
+ // a while, removing this bonus.
+ if (mons_is_wandering(monster) && monster->foe == MHITYOU)
+ mons_perc += 15;
+
+ if (!you.visible_to(monster))
+ {
+ mons_perc -= 75;
+ unnatural_stealthy = true;
+ }
+
+ if (monster->asleep())
+ {
+ if (monster->holiness() == MH_NATURAL)
+ {
+ // Monster is "hibernating"... reduce chance of waking.
+ if (monster->has_ench(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;
+ }
+ }
+
+ // If you've been tagged with Corona or are Glowing, the glow
+ // makes you extremely unstealthy.
+ if (you.backlit() && you.visible_to(monster))
+ mons_perc += 50;
+
+ if (mons_perc < 0)
+ mons_perc = 0;
+
+ if (x_chance_in_y(mons_perc + 1, stealth))
+ return (true); // Oops, the monster wakes up!
+
+ // You didn't wake the monster!
+ if (player_light_armour(true)
+ && you.can_see(monster) // to avoid leaking information
+ && you.burden_state == BS_UNENCUMBERED
+ && !you.attribute[ATTR_SHADOWS]
+ && !monster->wont_attack()
+ && !mons_class_flag(monster->type, M_NO_EXP_GAIN)
+ // If invisible, training happens much more rarely.
+ && (!unnatural_stealthy && one_chance_in(25) || one_chance_in(100)))
+ {
+ exercise(SK_STEALTH, 1);
+ }
+
+ return (false);
+}
+
+// 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, const coord_def& where, const char *msg, int who,
+ bool mermaid)
+{
+ bool ret = false;
+
+ if (loudness <= 0)
+ return (false);
+
+ // If the origin is silenced there is no noise.
+ if (silenced(where))
+ return (false);
+
+ const int dist = loudness * loudness;
+ const int player_distance = distance( you.pos(), where );
+
+ // Message the player.
+ if (player_distance <= dist && player_can_hear( where ))
+ {
+ if (msg)
+ mpr( msg, MSGCH_SOUND );
+
+ you.check_awaken(dist - player_distance);
+
+ if (!mermaid)
+ you.beholders_check_noise(loudness);
+
+ ret = true;
+ }
+
+ for (int p = 0; p < MAX_MONSTERS; p++)
+ {
+ monsters* monster = &menv[p];
+
+ if (!monster->alive())
+ continue;
+
+ // Monsters arent' affected by their own noise. We don't check
+ // where == monster->pos() since it might be caused by the
+ // Projected Noise spell.
+ if (p == who)
+ continue;
+
+ if (distance(monster->pos(), where) <= dist
+ && !silenced(monster->pos()))
+ {
+ // If the noise came from the character, any nearby monster
+ // will be jumping on top of them.
+ if (where == you.pos())
+ behaviour_event( monster, ME_ALERT, MHITYOU, you.pos() );
+ else if (mermaid && mons_primary_habitat(monster) == HT_WATER
+ && !monster->friendly())
+ {
+ // Mermaids/sirens call (hostile) aquatic monsters.
+ behaviour_event( monster, ME_ALERT, MHITNOT, where );
+ }
+ else
+ behaviour_event( monster, ME_DISTURB, MHITNOT, where );
+ }
+ }
+
+ return (ret);
+}
+
+bool noisy(int loudness, const coord_def& where, int who,
+ bool mermaid)
+{
+ return noisy(loudness, where, NULL, who, mermaid);
+}
+
+static const char* _player_vampire_smells_blood(int dist)
+{
+ // non-thirsty vampires get no clear indication of how close the
+ // smell is
+ if (you.hunger_state >= HS_SATIATED)
+ return "";
+
+ if (dist < 16) // 4*4
+ return " near-by";
+
+ if (you.hunger_state <= HS_NEAR_STARVING && dist > get_los_radius_sq())
+ return " in the distance";
+
+ return "";
+}
+
+void blood_smell( int strength, const coord_def& where )
+{
+ monsters *monster = NULL;
+
+ const int range = strength * strength;
+#ifdef DEBUG_DIAGNOSTICS
+ mprf(MSGCH_DIAGNOSTICS,
+ "blood stain at (%d, %d), range of smell = %d",
+ where.x, where.y, range);
+#endif
+
+ // Of the player species, only Vampires can smell blood.
+ if (you.species == SP_VAMPIRE)
+ {
+ // Whether they actually do so, depends on their hunger state.
+ int vamp_strength = strength - 2 * (you.hunger_state - 1);
+ if (vamp_strength > 0)
+ {
+ int vamp_range = vamp_strength * vamp_strength;
+
+ const int player_distance = distance( you.pos(), where );
+
+ if (player_distance <= vamp_range)
+ {
+#ifdef DEBUG_DIAGNOSTICS
+ mprf(MSGCH_DIAGNOSTICS,
+ "Player smells blood, pos: (%d, %d), dist = %d)",
+ you.pos().x, you.pos().y, player_distance);
+#endif
+ you.check_awaken(range - player_distance);
+ // Don't message if you can see the square.
+ if (!you.see_cell(where))
+ {
+ mprf("You smell fresh blood%s.",
+ _player_vampire_smells_blood(player_distance));
+ }
+ }
+ }
+ }
+
+ for (int p = 0; p < MAX_MONSTERS; p++)
+ {
+ monster = &menv[p];
+
+ if (monster->type < 0)
+ continue;
+
+ if (!mons_class_flag(monster->type, M_BLOOD_SCENT))
+ continue;
+
+ if (distance(monster->pos(), where) <= range)
+ {
+ // Let sleeping hounds lie.
+ if (monster->asleep()
+ && mons_species(monster->type) != MONS_VAMPIRE
+ && monster->type != MONS_SHARK)
+ {
+ // 33% chance of sleeping on
+ // 33% of being disturbed (start BEH_WANDER)
+ // 33% of being alerted (start BEH_SEEK)
+ if (!one_chance_in(3))
+ {
+ if (coinflip())
+ {
+#ifdef DEBUG_DIAGNOSTICS
+ mprf(MSGCH_DIAGNOSTICS, "disturbing %s (%d, %d)",
+ monster->name(DESC_PLAIN).c_str(),
+ monster->pos().x, monster->pos().y);
+#endif
+ behaviour_event(monster, ME_DISTURB, MHITNOT, where);
+ }
+ continue;
+ }
+ }
+#ifdef DEBUG_DIAGNOSTICS
+ mprf(MSGCH_DIAGNOSTICS, "alerting %s (%d, %d)",
+ monster->name(DESC_PLAIN).c_str(),
+ monster->pos().x, monster->pos().y);
+#endif
+ behaviour_event( monster, ME_ALERT, MHITNOT, where );
+
+ if (monster->type == MONS_SHARK)
+ {
+ // Sharks go into a battle frenzy if they smell blood.
+ monster_pathfind mp;
+ if (mp.init_pathfind(monster, where))
+ {
+ mon_enchant ench = monster->get_ench(ENCH_BATTLE_FRENZY);
+ const int dist = 15 - (monster->pos() - where).rdist();
+ const int dur = random_range(dist, dist*2)
+ * speed_to_duration(monster->speed);
+
+ if (ench.ench != ENCH_NONE)
+ {
+ int level = ench.degree;
+ if (level < 4 && one_chance_in(2*level))
+ ench.degree++;
+ ench.duration = std::max(ench.duration, dur);
+ monster->update_ench(ench);
+ }
+ else
+ {
+ monster->add_ench(mon_enchant(ENCH_BATTLE_FRENZY, 1,
+ KC_OTHER, dur));
+ simple_monster_message(monster, " is consumed with "
+ "blood-lust!");
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/crawl-ref/source/shout.h b/crawl-ref/source/shout.h
new file mode 100644
index 0000000000..eee25615e8
--- /dev/null
+++ b/crawl-ref/source/shout.h
@@ -0,0 +1,13 @@
+#ifndef SHOUT_H
+#define SHOUT_H
+
+bool noisy(int loudness, const coord_def& where, int who,
+ bool mermaid = false);
+bool noisy(int loudness, const coord_def& where, const char *msg = NULL,
+ int who = -1, bool mermaid = false);
+void blood_smell( int strength, const coord_def& where);
+void handle_monster_shouts(monsters* monster, bool force = false);
+bool check_awaken(monsters* monster);
+
+#endif
+
diff --git a/crawl-ref/source/spells1.cc b/crawl-ref/source/spells1.cc
index 552984f20c..71f9f071c1 100644
--- a/crawl-ref/source/spells1.cc
+++ b/crawl-ref/source/spells1.cc
@@ -50,6 +50,7 @@
#include "transfor.h"
#include "traps.h"
#include "view.h"
+#include "shout.h"
#include "viewchar.h"
static bool _abyss_blocks_teleport(bool cblink)
diff --git a/crawl-ref/source/spells2.cc b/crawl-ref/source/spells2.cc
index ddc46bf4a2..4f67a57f98 100644
--- a/crawl-ref/source/spells2.cc
+++ b/crawl-ref/source/spells2.cc
@@ -50,6 +50,7 @@
#include "terrain.h"
#include "traps.h"
#include "view.h"
+#include "shout.h"
int detect_traps(int pow)
{
diff --git a/crawl-ref/source/spells3.cc b/crawl-ref/source/spells3.cc
index facffd8eb8..b95e2fc73a 100644
--- a/crawl-ref/source/spells3.cc
+++ b/crawl-ref/source/spells3.cc
@@ -51,6 +51,7 @@
#include "traps.h"
#include "travel.h"
#include "view.h"
+#include "shout.h"
#include "viewgeom.h"
#include "xom.h"
diff --git a/crawl-ref/source/spells4.cc b/crawl-ref/source/spells4.cc
index edc060eb32..027359417e 100644
--- a/crawl-ref/source/spells4.cc
+++ b/crawl-ref/source/spells4.cc
@@ -51,6 +51,7 @@
#include "transfor.h"
#include "traps.h"
#include "view.h"
+#include "shout.h"
#include "viewchar.h"
enum DEBRIS // jmf: add for shatter, dig, and Giants to throw
diff --git a/crawl-ref/source/spl-cast.cc b/crawl-ref/source/spl-cast.cc
index 88350b834c..e0f6e525a4 100644
--- a/crawl-ref/source/spl-cast.cc
+++ b/crawl-ref/source/spl-cast.cc
@@ -55,6 +55,7 @@
#include "transfor.h"
#include "tutorial.h"
#include "view.h"
+#include "shout.h"
#ifdef TARGET_OS_DOS
#include <conio.h>
diff --git a/crawl-ref/source/spl-mis.cc b/crawl-ref/source/spl-mis.cc
index 96339da003..bbab3c230a 100644
--- a/crawl-ref/source/spl-mis.cc
+++ b/crawl-ref/source/spl-mis.cc
@@ -30,6 +30,7 @@
#include "terrain.h"
#include "transfor.h"
#include "view.h"
+#include "shout.h"
#include "viewchar.h"
#include "xom.h"
diff --git a/crawl-ref/source/state.cc b/crawl-ref/source/state.cc
index 2dfbe2582f..da7f8f0fa5 100644
--- a/crawl-ref/source/state.cc
+++ b/crawl-ref/source/state.cc
@@ -24,6 +24,7 @@
#include "state.h"
#include "tutorial.h"
#include "view.h"
+#include "shout.h"
game_state::game_state()
: game_crashed(false), mouse_enabled(false), waiting_for_command(false),
diff --git a/crawl-ref/source/stuff.cc b/crawl-ref/source/stuff.cc
index d7f211bdea..90b66b3429 100644
--- a/crawl-ref/source/stuff.cc
+++ b/crawl-ref/source/stuff.cc
@@ -18,6 +18,7 @@
#include "state.h"
#include "stuff.h"
#include "view.h"
+#include "shout.h"
#include "viewchar.h"
#include "viewgeom.h"
@@ -61,6 +62,7 @@
#include "religion.h"
#include "tutorial.h"
#include "view.h"
+#include "shout.h"
stack_iterator::stack_iterator(const coord_def& pos)
{
diff --git a/crawl-ref/source/tags.cc b/crawl-ref/source/tags.cc
index 421593bc5c..71ef7e28b0 100644
--- a/crawl-ref/source/tags.cc
+++ b/crawl-ref/source/tags.cc
@@ -83,6 +83,7 @@
#include "tilemcache.h"
#include "travel.h"
#include "view.h"
+#include "shout.h"
#if defined(DEBUG) || defined(DEBUG_MONS_SCAN)
#include "coord.h"
diff --git a/crawl-ref/source/teleport.cc b/crawl-ref/source/teleport.cc
index 83fa11fe67..11f6831fa5 100644
--- a/crawl-ref/source/teleport.cc
+++ b/crawl-ref/source/teleport.cc
@@ -18,6 +18,7 @@
#include "state.h"
#include "terrain.h"
#include "view.h"
+#include "shout.h"
bool random_near_space(const coord_def& origin, coord_def& target,
bool allow_adjacent, bool restrict_los,
diff --git a/crawl-ref/source/terrain.cc b/crawl-ref/source/terrain.cc
index 16b7db05b7..6239562763 100644
--- a/crawl-ref/source/terrain.cc
+++ b/crawl-ref/source/terrain.cc
@@ -35,6 +35,7 @@
#include "transfor.h"
#include "traps.h"
#include "view.h"
+#include "shout.h"
actor* actor_at(const coord_def& c)
{
diff --git a/crawl-ref/source/tilepick.cc b/crawl-ref/source/tilepick.cc
index e0b76d4b87..0dd87e77ac 100644
--- a/crawl-ref/source/tilepick.cc
+++ b/crawl-ref/source/tilepick.cc
@@ -42,6 +42,7 @@
#include "traps.h"
#include "travel.h"
#include "view.h"
+#include "shout.h"
#include "viewgeom.h"
void TileNewLevel(bool first_time)
diff --git a/crawl-ref/source/tilereg.cc b/crawl-ref/source/tilereg.cc
index d5751cdd30..a88531d66a 100644
--- a/crawl-ref/source/tilereg.cc
+++ b/crawl-ref/source/tilereg.cc
@@ -43,6 +43,7 @@
#include "transfor.h"
#include "travel.h"
#include "view.h"
+#include "shout.h"
#include "viewgeom.h"
#include "tilereg.h"
diff --git a/crawl-ref/source/tilesdl.cc b/crawl-ref/source/tilesdl.cc
index 3f164a7bea..b0bf32d8e1 100644
--- a/crawl-ref/source/tilesdl.cc
+++ b/crawl-ref/source/tilesdl.cc
@@ -24,6 +24,7 @@
#include "tilesdl.h"
#include "travel.h"
#include "view.h"
+#include "shout.h"
#include "viewgeom.h"
#include "tiledef-dngn.h"
diff --git a/crawl-ref/source/traps.cc b/crawl-ref/source/traps.cc
index d34f66b9b1..261a8bfde6 100644
--- a/crawl-ref/source/traps.cc
+++ b/crawl-ref/source/traps.cc
@@ -41,6 +41,7 @@
#include "transfor.h"
#include "tutorial.h"
#include "view.h"
+#include "shout.h"
#include "xom.h"
bool trap_def::active() const
diff --git a/crawl-ref/source/travel.cc b/crawl-ref/source/travel.cc
index df1dbbd627..c0ab8904de 100644
--- a/crawl-ref/source/travel.cc
+++ b/crawl-ref/source/travel.cc
@@ -53,6 +53,7 @@
#include "travel.h"
#include "tutorial.h"
#include "view.h"
+#include "shout.h"
#include <algorithm>
#include <set>
diff --git a/crawl-ref/source/tutorial.cc b/crawl-ref/source/tutorial.cc
index d7ef041d35..ae925a00f3 100644
--- a/crawl-ref/source/tutorial.cc
+++ b/crawl-ref/source/tutorial.cc
@@ -57,6 +57,7 @@
#include "tiles.h"
#endif
#include "view.h"
+#include "shout.h"
#include "viewchar.h"
#include "viewgeom.h"
diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc
index aa08afb7bd..05e43236bc 100644
--- a/crawl-ref/source/view.cc
+++ b/crawl-ref/source/view.cc
@@ -7,6 +7,7 @@
#include "AppHdr.h"
#include "view.h"
+#include "shout.h"
#include <stdint.h>
#include <string.h>
@@ -85,8 +86,6 @@
crawl_view_geometry crawl_view;
-extern int stealth; // defined in acr.cc
-
bool inside_level_bounds(int x, int y)
{
return (x > 0 && x < GXM && y > 0 && y < GYM);
@@ -142,245 +141,6 @@ void flush_comes_into_view()
handle_seen_interrupt(mon);
}
-void handle_monster_shouts(monsters* monster, bool force)
-{
- if (!force && x_chance_in_y(you.skills[SK_STEALTH], 30))
- return;
-
- // Friendly or neutral monsters don't shout.
- if (!force && (monster->friendly() || monster->neutral()))
- return;
-
- // Get it once, since monster might be S_RANDOM, in which case
- // mons_shouts() will return a different value every time.
- // Demon lords will insult you as a greeting, but later we'll
- // choose a random verb and loudness for them.
- shout_type s_type = mons_shouts(monster->type, false);
-
- // Silent monsters can give noiseless "visual shouts" if the
- // player can see them, in which case silence isn't checked for.
- if (s_type == S_SILENT && !monster->visible_to(&you)
- || s_type != S_SILENT && !player_can_hear(monster->pos()))
- {
- return;
- }
-
- mon_acting mact(monster);
-
- std::string default_msg_key = "";
-
- switch (s_type)
- {
- case S_SILENT:
- // No default message.
- break;
- case S_SHOUT:
- default_msg_key = "__SHOUT";
- break;
- case S_BARK:
- default_msg_key = "__BARK";
- break;
- case S_SHOUT2:
- default_msg_key = "__TWO_SHOUTS";
- break;
- case S_ROAR:
- default_msg_key = "__ROAR";
- break;
- case S_SCREAM:
- default_msg_key = "__SCREAM";
- break;
- case S_BELLOW:
- default_msg_key = "__BELLOW";
- break;
- case S_SCREECH:
- default_msg_key = "__SCREECH";
- break;
- case S_BUZZ:
- default_msg_key = "__BUZZ";
- break;
- case S_MOAN:
- default_msg_key = "__MOAN";
- break;
- case S_GURGLE:
- default_msg_key = "__GURGLE";
- break;
- case S_WHINE:
- default_msg_key = "__WHINE";
- break;
- case S_CROAK:
- default_msg_key = "__CROAK";
- break;
- case S_GROWL:
- default_msg_key = "__GROWL";
- break;
- case S_HISS:
- default_msg_key = "__HISS";
- break;
- case S_DEMON_TAUNT:
- default_msg_key = "__DEMON_TAUNT";
- break;
- default:
- default_msg_key = "__BUGGY"; // S_LOUD, S_VERY_SOFT, etc. (loudness)
- }
-
- // Now that we have the message key, get a random verb and noise level
- // for pandemonium lords.
- if (s_type == S_DEMON_TAUNT)
- s_type = mons_shouts(monster->type, true);
-
- std::string msg, suffix;
- std::string key = mons_type_name(monster->type, DESC_PLAIN);
-
- // Pandemonium demons have random names, so use "pandemonium lord"
- if (monster->type == MONS_PANDEMONIUM_DEMON)
- key = "pandemonium lord";
- // Search for player ghost shout by the ghost's class.
- else if (monster->type == MONS_PLAYER_GHOST)
- {
- const ghost_demon &ghost = *(monster->ghost);
- std::string ghost_class = get_class_name(ghost.job);
-
- key = ghost_class + " player ghost";
-
- default_msg_key = "player ghost";
- }
-
- // Tries to find an entry for "name seen" or "name unseen",
- // and if no such entry exists then looks simply for "name".
- // We don't use "you.can_see(monster)" here since that would return
- // false for submerged monsters, but submerged monsters will be forced
- // to surface before they shout, thus removing that source of
- // non-visibility.
- if (mons_near(monster) && (!monster->invisible() || you.can_see_invisible()))
- suffix = " seen";
- else
- suffix = " unseen";
-
- msg = getShoutString(key, suffix);
-
- if (msg == "__DEFAULT" || msg == "__NEXT")
- msg = getShoutString(default_msg_key, suffix);
- else if (msg.empty())
- {
- // NOTE: Use the hardcoded glyph rather than that returned
- // by mons_char(), since the result of mons_char() can be
- // changed by user settings.
- char mchar = get_monster_data(monster->type)->showchar;
-
- // See if there's a shout for all monsters using the
- // same glyph/symbol
- std::string glyph_key = "'";
-
- // Database keys are case-insensitve.
- if (isupper(mchar))
- glyph_key += "cap-";
-
- glyph_key += mchar;
- glyph_key += "'";
- msg = getShoutString(glyph_key, suffix);
-
- if (msg.empty() || msg == "__DEFAULT")
- msg = getShoutString(default_msg_key, suffix);
- }
-
- if (default_msg_key == "__BUGGY")
- {
- msg::streams(MSGCH_SOUND) << "You hear something buggy!"
- << std::endl;
- }
- else if (s_type == S_SILENT && (msg.empty() || msg == "__NONE"))
- {
- ; // No "visual shout" defined for silent monster, do nothing.
- }
- else if (msg.empty()) // Still nothing found?
- {
- msg::streams(MSGCH_DIAGNOSTICS)
- << "No shout entry for default shout type '"
- << default_msg_key << "'" << std::endl;
-
- msg::streams(MSGCH_SOUND) << "You hear something buggy!"
- << std::endl;
- }
- else if (msg == "__NONE")
- {
- msg::streams(MSGCH_DIAGNOSTICS)
- << "__NONE returned as shout for non-silent monster '"
- << default_msg_key << "'" << std::endl;
- msg::streams(MSGCH_SOUND) << "You hear something buggy!"
- << std::endl;
- }
- else
- {
- msg_channel_type channel = MSGCH_TALK;
-
- std::string param = "";
- std::string::size_type pos = msg.find(":");
-
- if (pos != std::string::npos)
- {
- param = msg.substr(0, pos);
- msg = msg.substr(pos + 1);
- }
-
- if (s_type == S_SILENT || param == "VISUAL")
- channel = MSGCH_TALK_VISUAL;
- else if (param == "SOUND")
- channel = MSGCH_SOUND;
-
- // Monster must come up from being submerged if it wants to shout.
- if (monster->submerged())
- {
- if (!monster->del_ench(ENCH_SUBMERGED))
- {
- // Couldn't unsubmerge.
- return;
- }
-
- if (you.can_see(monster))
- {
- if (monster->type == MONS_AIR_ELEMENTAL)
- monster->seen_context = "thin air";
- else if (monster->type == MONS_TRAPDOOR_SPIDER)
- monster->seen_context = "leaps out";
- else if (!monster_habitable_grid(monster, DNGN_FLOOR))
- monster->seen_context = "bursts forth shouting";
- else
- monster->seen_context = "surfaces";
-
- // Give interrupt message before shout message.
- handle_seen_interrupt(monster);
- }
- }
-
- if (channel != MSGCH_TALK_VISUAL || you.can_see(monster))
- {
- msg = do_mon_str_replacements(msg, monster, s_type);
- msg::streams(channel) << msg << std::endl;
-
- // Otherwise it can move away with no feedback.
- if (you.can_see(monster))
- {
- if (!(monster->flags & MF_WAS_IN_VIEW))
- handle_seen_interrupt(monster);
- seen_monster(monster);
- }
- }
- }
-
- const int noise_level = get_shout_noise_level(s_type);
- const bool heard = noisy(noise_level, monster->pos(), monster->mindex());
-
- if (Options.tutorial_left && (heard || you.can_see(monster)))
- learned_something_new(TUT_MONSTER_SHOUT, monster->pos());
-}
-
-#ifdef WIZARD
-void force_monster_shout(monsters* monster)
-{
- handle_monster_shouts(monster, true);
-}
-#endif
-
void monster_grid_updates()
{
for (int s = 0; s < MAX_MONSTERS; ++s)
@@ -501,283 +261,6 @@ void update_monsters_in_view()
}
}
-bool check_awaken(monsters* monster)
-{
- // Monsters put to sleep by ensorcelled hibernation will sleep
- // at least one turn.
- if (monster->has_ench(ENCH_SLEEPY))
- return (false);
-
- // Berserkers aren't really concerned about stealth.
- if (you.berserk())
- return (true);
-
- // I assume that creatures who can sense invisible are very perceptive.
- int mons_perc = 10 + (mons_intel(monster) * 4) + monster->hit_dice
- + mons_sense_invis(monster) * 5;
-
- bool unnatural_stealthy = false; // "stealthy" only because of invisibility?
-
- // Critters that are wandering but still have MHITYOU as their foe are
- // still actively on guard for the player, even if they can't see you.
- // Give them a large bonus -- handle_behaviour() will nuke 'foe' after
- // a while, removing this bonus.
- if (mons_is_wandering(monster) && monster->foe == MHITYOU)
- mons_perc += 15;
-
- if (!you.visible_to(monster))
- {
- mons_perc -= 75;
- unnatural_stealthy = true;
- }
-
- if (monster->asleep())
- {
- if (monster->holiness() == MH_NATURAL)
- {
- // Monster is "hibernating"... reduce chance of waking.
- if (monster->has_ench(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;
- }
- }
-
- // If you've been tagged with Corona or are Glowing, the glow
- // makes you extremely unstealthy.
- if (you.backlit() && you.visible_to(monster))
- mons_perc += 50;
-
- if (mons_perc < 0)
- mons_perc = 0;
-
- if (x_chance_in_y(mons_perc + 1, stealth))
- return (true); // Oops, the monster wakes up!
-
- // You didn't wake the monster!
- if (player_light_armour(true)
- && you.can_see(monster) // to avoid leaking information
- && you.burden_state == BS_UNENCUMBERED
- && !you.attribute[ATTR_SHADOWS]
- && !monster->wont_attack()
- && !mons_class_flag(monster->type, M_NO_EXP_GAIN)
- // If invisible, training happens much more rarely.
- && (!unnatural_stealthy && one_chance_in(25) || one_chance_in(100)))
- {
- exercise(SK_STEALTH, 1);
- }
-
- return (false);
-}
-
-// 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, const coord_def& where, const char *msg, int who,
- bool mermaid)
-{
- bool ret = false;
-
- if (loudness <= 0)
- return (false);
-
- // If the origin is silenced there is no noise.
- if (silenced(where))
- return (false);
-
- const int dist = loudness * loudness;
- const int player_distance = distance( you.pos(), where );
-
- // Message the player.
- if (player_distance <= dist && player_can_hear( where ))
- {
- if (msg)
- mpr( msg, MSGCH_SOUND );
-
- you.check_awaken(dist - player_distance);
-
- if (!mermaid)
- you.beholders_check_noise(loudness);
-
- ret = true;
- }
-
- for (int p = 0; p < MAX_MONSTERS; p++)
- {
- monsters* monster = &menv[p];
-
- if (!monster->alive())
- continue;
-
- // Monsters arent' affected by their own noise. We don't check
- // where == monster->pos() since it might be caused by the
- // Projected Noise spell.
- if (p == who)
- continue;
-
- if (distance(monster->pos(), where) <= dist
- && !silenced(monster->pos()))
- {
- // If the noise came from the character, any nearby monster
- // will be jumping on top of them.
- if (where == you.pos())
- behaviour_event( monster, ME_ALERT, MHITYOU, you.pos() );
- else if (mermaid && mons_primary_habitat(monster) == HT_WATER
- && !monster->friendly())
- {
- // Mermaids/sirens call (hostile) aquatic monsters.
- behaviour_event( monster, ME_ALERT, MHITNOT, where );
- }
- else
- behaviour_event( monster, ME_DISTURB, MHITNOT, where );
- }
- }
-
- return (ret);
-}
-
-bool noisy(int loudness, const coord_def& where, int who,
- bool mermaid)
-{
- return noisy(loudness, where, NULL, who, mermaid);
-}
-
-static const char* _player_vampire_smells_blood(int dist)
-{
- // non-thirsty vampires get no clear indication of how close the
- // smell is
- if (you.hunger_state >= HS_SATIATED)
- return "";
-
- if (dist < 16) // 4*4
- return " near-by";
-
- if (you.hunger_state <= HS_NEAR_STARVING && dist > get_los_radius_sq())
- return " in the distance";
-
- return "";
-}
-
-void blood_smell( int strength, const coord_def& where )
-{
- monsters *monster = NULL;
-
- const int range = strength * strength;
-#ifdef DEBUG_DIAGNOSTICS
- mprf(MSGCH_DIAGNOSTICS,
- "blood stain at (%d, %d), range of smell = %d",
- where.x, where.y, range);
-#endif
-
- // Of the player species, only Vampires can smell blood.
- if (you.species == SP_VAMPIRE)
- {
- // Whether they actually do so, depends on their hunger state.
- int vamp_strength = strength - 2 * (you.hunger_state - 1);
- if (vamp_strength > 0)
- {
- int vamp_range = vamp_strength * vamp_strength;
-
- const int player_distance = distance( you.pos(), where );
-
- if (player_distance <= vamp_range)
- {
-#ifdef DEBUG_DIAGNOSTICS
- mprf(MSGCH_DIAGNOSTICS,
- "Player smells blood, pos: (%d, %d), dist = %d)",
- you.pos().x, you.pos().y, player_distance);
-#endif
- you.check_awaken(range - player_distance);
- // Don't message if you can see the square.
- if (!you.see_cell(where))
- {
- mprf("You smell fresh blood%s.",
- _player_vampire_smells_blood(player_distance));
- }
- }
- }
- }
-
- for (int p = 0; p < MAX_MONSTERS; p++)
- {
- monster = &menv[p];
-
- if (monster->type < 0)
- continue;
-
- if (!mons_class_flag(monster->type, M_BLOOD_SCENT))
- continue;
-
- if (distance(monster->pos(), where) <= range)
- {
- // Let sleeping hounds lie.
- if (monster->asleep()
- && mons_species(monster->type) != MONS_VAMPIRE
- && monster->type != MONS_SHARK)
- {
- // 33% chance of sleeping on
- // 33% of being disturbed (start BEH_WANDER)
- // 33% of being alerted (start BEH_SEEK)
- if (!one_chance_in(3))
- {
- if (coinflip())
- {
-#ifdef DEBUG_DIAGNOSTICS
- mprf(MSGCH_DIAGNOSTICS, "disturbing %s (%d, %d)",
- monster->name(DESC_PLAIN).c_str(),
- monster->pos().x, monster->pos().y);
-#endif
- behaviour_event(monster, ME_DISTURB, MHITNOT, where);
- }
- continue;
- }
- }
-#ifdef DEBUG_DIAGNOSTICS
- mprf(MSGCH_DIAGNOSTICS, "alerting %s (%d, %d)",
- monster->name(DESC_PLAIN).c_str(),
- monster->pos().x, monster->pos().y);
-#endif
- behaviour_event( monster, ME_ALERT, MHITNOT, where );
-
- if (monster->type == MONS_SHARK)
- {
- // Sharks go into a battle frenzy if they smell blood.
- monster_pathfind mp;
- if (mp.init_pathfind(monster, where))
- {
- mon_enchant ench = monster->get_ench(ENCH_BATTLE_FRENZY);
- const int dist = 15 - (monster->pos() - where).rdist();
- const int dur = random_range(dist, dist*2)
- * speed_to_duration(monster->speed);
-
- if (ench.ench != ENCH_NONE)
- {
- int level = ench.degree;
- if (level < 4 && one_chance_in(2*level))
- ench.degree++;
- ench.duration = std::max(ench.duration, dur);
- monster->update_ench(ench);
- }
- else
- {
- monster->add_ench(mon_enchant(ENCH_BATTLE_FRENZY, 1,
- KC_OTHER, dur));
- simple_monster_message(monster, " is consumed with "
- "blood-lust!");
- }
- }
- }
- }
- }
-}
-
-
// We logically associate a difficulty parameter with each tile on each level,
// to make deterministic magic mapping work. This function returns the
// difficulty parameters for each tile on the current level, whose difficulty
diff --git a/crawl-ref/source/view.h b/crawl-ref/source/view.h
index 5a9c9577e7..0ebe7859e2 100644
--- a/crawl-ref/source/view.h
+++ b/crawl-ref/source/view.h
@@ -25,16 +25,8 @@ bool magic_mapping(int map_radius, int proportion, bool suppress_msg,
coord_def origin = coord_def(-1, -1));
void reautomap_level();
-bool noisy(int loudness, const coord_def& where, int who,
- bool mermaid = false);
-bool noisy(int loudness, const coord_def& where, const char *msg = NULL,
- int who = -1, bool mermaid = false);
-void blood_smell( int strength, const coord_def& where);
-void handle_monster_shouts(monsters* monster, bool force = false);
-
class level_pos;
void show_map( level_pos &spec_place, bool travel_mode, bool allow_esc = false );
-bool check_awaken(monsters* monster);
bool is_feature(int feature, const coord_def& where);
bool inside_level_bounds(int x, int y);
bool inside_level_bounds(const coord_def &p);
diff --git a/crawl-ref/source/wiz-dgn.cc b/crawl-ref/source/wiz-dgn.cc
index 5d178d02c1..d5747370e2 100644
--- a/crawl-ref/source/wiz-dgn.cc
+++ b/crawl-ref/source/wiz-dgn.cc
@@ -29,6 +29,7 @@
#include "terrain.h"
#include "traps.h"
#include "view.h"
+#include "shout.h"
#include "wiz-mon.h"
#ifdef WIZARD
diff --git a/crawl-ref/source/wiz-item.cc b/crawl-ref/source/wiz-item.cc
index 9eaacc7c32..23758bef03 100644
--- a/crawl-ref/source/wiz-item.cc
+++ b/crawl-ref/source/wiz-item.cc
@@ -32,6 +32,7 @@
#include "stuff.h"
#include "terrain.h"
#include "view.h"
+#include "shout.h"
#ifdef WIZARD
static void _make_all_books()
diff --git a/crawl-ref/source/wiz-mon.cc b/crawl-ref/source/wiz-mon.cc
index d6c15acbd4..fe17464637 100644
--- a/crawl-ref/source/wiz-mon.cc
+++ b/crawl-ref/source/wiz-mon.cc
@@ -31,6 +31,7 @@
#include "spl-util.h"
#include "stuff.h"
#include "view.h"
+#include "shout.h"
#ifdef WIZARD
// Creates a specific monster by mon type number.
diff --git a/crawl-ref/source/xom.cc b/crawl-ref/source/xom.cc
index 335349b10a..b502715536 100644
--- a/crawl-ref/source/xom.cc
+++ b/crawl-ref/source/xom.cc
@@ -53,6 +53,7 @@
#include "transfor.h"
#include "traps.h"
#include "view.h"
+#include "shout.h"
#include "viewchar.h"
#include "xom.h"