summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/CREDITS1
-rw-r--r--crawl-ref/source/insult.cc4
-rw-r--r--crawl-ref/source/insult.h4
-rw-r--r--crawl-ref/source/mon-data.h2
-rw-r--r--crawl-ref/source/monspeak.cc118
-rw-r--r--crawl-ref/source/monspeak.h2
-rw-r--r--crawl-ref/source/monstuff.cc2
-rw-r--r--crawl-ref/source/monstuff.h2
8 files changed, 123 insertions, 12 deletions
diff --git a/crawl-ref/CREDITS b/crawl-ref/CREDITS
index b7238a9081..4be4310bf0 100644
--- a/crawl-ref/CREDITS
+++ b/crawl-ref/CREDITS
@@ -34,6 +34,7 @@ Mitsuhiro Itakura
Jarmo Kielosto
Ryan Kusnery
Jukka Kuusisto
+Jordan Lewis
Icy Lich
Arien Malec
Shawn M Moore
diff --git a/crawl-ref/source/insult.cc b/crawl-ref/source/insult.cc
index 4a6359110f..7b94c35a9d 100644
--- a/crawl-ref/source/insult.cc
+++ b/crawl-ref/source/insult.cc
@@ -38,7 +38,7 @@ void init_cap(char * str)
str[0] = toupper( str[0] );
}
-void imp_taunt( struct monsters *mons )
+void imp_taunt( const monsters *mons )
{
char buff[80];
const char *mon_name = ptr_monam( mons, DESC_CAP_THE );
@@ -65,7 +65,7 @@ void imp_taunt( struct monsters *mons )
}
}
-void demon_taunt( struct monsters *mons )
+void demon_taunt( const monsters *mons )
{
static const char * sound_list[] =
{
diff --git a/crawl-ref/source/insult.h b/crawl-ref/source/insult.h
index 143d0ecae3..d29b66acb4 100644
--- a/crawl-ref/source/insult.h
+++ b/crawl-ref/source/insult.h
@@ -3,8 +3,8 @@
#include "externs.h"
-void imp_taunt( struct monsters *mons );
-void demon_taunt( struct monsters *mons );
+void imp_taunt( const monsters *mons );
+void demon_taunt( const monsters *mons );
const char * generic_insult(void);
const char * racial_insult(void);
diff --git a/crawl-ref/source/mon-data.h b/crawl-ref/source/mon-data.h
index 31214f6f44..2b09f34de8 100644
--- a/crawl-ref/source/mon-data.h
+++ b/crawl-ref/source/mon-data.h
@@ -4393,7 +4393,7 @@
{
MONS_MURRAY, 'z', LIGHTRED, "Murray",
- M_SPELLCASTER | M_SEE_INVIS | M_EVIL | M_UNIQUE,
+ M_SPELLCASTER | M_SEE_INVIS | M_EVIL | M_SPEAKS | M_UNIQUE,
MR_RES_ELEC | MR_RES_POISON | MR_RES_HELLFIRE | MR_RES_COLD,
0, 50, MONS_LICH, MONS_CURSE_SKULL, MH_UNDEAD, MAG_IMMUNE,
{ {AT_BITE, AF_PLAIN, 20}, {AT_BITE, AF_PLAIN, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} },
diff --git a/crawl-ref/source/monspeak.cc b/crawl-ref/source/monspeak.cc
index 5b511530ef..877ac1857f 100644
--- a/crawl-ref/source/monspeak.cc
+++ b/crawl-ref/source/monspeak.cc
@@ -38,11 +38,117 @@
#include "stuff.h"
#include "view.h"
+struct mon_dialogue
+{
+ monster_type speaker;
+ const char **silenced;
+ const char **confused;
+ const char **confused_friend;
+ const char **fleeing;
+ const char **fleeing_friend;
+ const char **friendly;
+ const char **hostile; // Most common.
+};
+
+static const char *murray_silenced[] =
+{
+ "%s rolls in a circle.",
+ "%s rolls around.",
+ "%s spins like a top.",
+ "%s grins evilly.",
+ "%s seems to say something.",
+ "%s says something you can't hear. It was probably not a compliment.",
+ NULL
+};
+
+static const char *murray_hostile[] =
+{
+ "%s rolls in a circle.",
+ "%s rolls around.",
+ "%s spins like a top.",
+ "%s grins evilly.",
+ "%s laughs evilly.",
+ "%s cackles, \"I will rule the world!\"",
+ "%s shouts, \"Give me your head, so I can impale it on a pike!\"",
+ "%s's teeth chatter loudly.",
+ "%s yells, \"I'm a mighty demonic power!\"",
+ "%s asks, \"How could you choose the Orb over me, your best friend?\"",
+ "%s shouts, \"Let the forces of evil and voodoo overcome you!\"",
+ "%s screams, \"If I had legs, you would be dead twenty times over!\"",
+ "%s yells, \"My visage is famous all over the dungeon!\"",
+ "%s says, \"You're the second biggest fool I've ever met!\"",
+ NULL
+};
+
+static mon_dialogue vox_populi[] =
+{
+ { MONS_MURRAY, murray_silenced, NULL, NULL, NULL, NULL, NULL,
+ murray_hostile },
+};
+
+static const mon_dialogue *find_dialogue(const monsters *monster)
+{
+ for (unsigned i = 0; i < sizeof(vox_populi) / sizeof(*vox_populi); ++i)
+ if (vox_populi[i].speaker == monster->type)
+ return (&vox_populi[i]);
+ return (NULL);
+}
+
+static bool say_dialogue(const monsters *monster,
+ const char **dialogue)
+{
+ if (!dialogue)
+ return (false);
+
+ int nitems = 0;
+ for (const char **run = dialogue; *run; ++run, ++nitems)
+ ;
+
+ const char *chosen = nitems? dialogue[random2(nitems)] : NULL;
+
+ if (chosen && *chosen)
+ {
+ mprf(MSGCH_TALK, chosen, monster->name(DESC_CAP_THE).c_str());
+ return (true);
+ }
+
+ return (false);
+}
+
+static bool say_specific_dialogue(const monsters *monster,
+ const mon_dialogue *dialogue)
+{
+ if (silenced(monster->x, monster->y))
+ return (say_dialogue(monster, dialogue->silenced));
+
+ if (monster->has_ench(ENCH_CHARM))
+ return (false);
+
+ const bool friendly = (monster->attitude == ATT_FRIENDLY);
+
+ if (mons_is_confused(monster))
+ return (say_dialogue(
+ monster,
+ friendly? dialogue->confused_friend
+ : dialogue->confused));
+
+ if (monster->behaviour == BEH_FLEE)
+ return (say_dialogue(
+ monster,
+ friendly? dialogue->fleeing_friend
+ : dialogue->fleeing));
+
+ if (monster->attitude == ATT_FRIENDLY)
+ return (say_dialogue(monster, dialogue->friendly));
+
+ return (say_dialogue(monster, dialogue->hostile));
+}
+
// returns true if something is said
-bool mons_speaks(struct monsters *monster)
+bool mons_speaks(const 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
@@ -57,6 +163,10 @@ bool mons_speaks(struct monsters *monster)
return false;
// invisible monster tries to remain unnoticed
+ const mon_dialogue *dialogue = find_dialogue(monster);
+ if (dialogue)
+ return (say_specific_dialogue(monster, dialogue));
+
//mv: if it's also invisible, program never gets here
if (silenced(monster->x, monster->y))
{
@@ -82,7 +192,7 @@ bool mons_speaks(struct monsters *monster)
(temp_rand == 4) ? " looks around." :
(temp_rand == 5) ? " appears indecisive." :
(temp_rand == 6) ? " ponders the situation."
- : " seems to says something.");
+ : " seems to say something.");
}
// disregard charmed critters.. they're not too expressive
else if (monster->attitude == ATT_FRIENDLY)
@@ -191,7 +301,7 @@ bool mons_speaks(struct monsters *monster)
switch (random2(23)) // speaks for unfriendly confused monsters
{
case 0:
- strcat(info, " yells, \"Get them off of me!\"");
+ strcat(info, " yells, \"Get them off me!\"");
break;
case 1:
strcat(info, " screams, \"I will kill you anyway!\"");
diff --git a/crawl-ref/source/monspeak.h b/crawl-ref/source/monspeak.h
index 7a6559b04e..328ebd0a67 100644
--- a/crawl-ref/source/monspeak.h
+++ b/crawl-ref/source/monspeak.h
@@ -3,6 +3,6 @@
#include "externs.h"
-bool mons_speaks(struct monsters *monster);
+bool mons_speaks(const monsters *monster);
#endif
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index 4dffb17f14..507f1c1f7b 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -1834,7 +1834,7 @@ std::string str_simple_monster_message(monsters *mons, const char *event)
// 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,
+bool simple_monster_message(const monsters *monster, const char *event,
int channel, int param)
{
char buff[INFO_SIZE];
diff --git a/crawl-ref/source/monstuff.h b/crawl-ref/source/monstuff.h
index 9b70d4020a..e5ea8f2c45 100644
--- a/crawl-ref/source/monstuff.h
+++ b/crawl-ref/source/monstuff.h
@@ -87,7 +87,7 @@ bool random_near_space( int ox, int oy, int &tx, int &ty,
* called from: beam - effects - fight - monstuff - mstuff2 - spells1 -
* spells2 - spells4
* *********************************************************************** */
-bool simple_monster_message(struct monsters *monster, const char *event,
+bool simple_monster_message(const monsters *monster, const char *event,
int channel = MSGCH_PLAIN, int param = 0);
std::string str_simple_monster_message(monsters *mons, const char *event);