summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Cline <zelgadis@sourceforge.net>2009-12-07 03:04:10 -0800
committerMatthew Cline <zelgadis@sourceforge.net>2009-12-07 03:04:10 -0800
commite0d592b0a5e032d7d35551907c4af69014e48b10 (patch)
tree8d8d3f1c0d1e75b05b184a04815b66b2ef709139
parenta2285dbfa468cca31b2d724db38ccb102c487675 (diff)
downloadcrawl-ref-e0d592b0a5e032d7d35551907c4af69014e48b10.tar.gz
crawl-ref-e0d592b0a5e032d7d35551907c4af69014e48b10.zip
New monster props "speech_func" and "shout_func"
MonPropsMarker can be used to set "speech_func" and "shout_func" on a monster, functions which return a string to be used as the monster's speech/shout message.
-rw-r--r--crawl-ref/docs/develop/levels/advanced.txt15
-rw-r--r--crawl-ref/source/mon-speak.cc39
-rw-r--r--crawl-ref/source/mon-stuff.cc6
-rw-r--r--crawl-ref/source/shout.cc34
4 files changed, 92 insertions, 2 deletions
diff --git a/crawl-ref/docs/develop/levels/advanced.txt b/crawl-ref/docs/develop/levels/advanced.txt
index f9cd653809..f5ffffe725 100644
--- a/crawl-ref/docs/develop/levels/advanced.txt
+++ b/crawl-ref/docs/develop/levels/advanced.txt
@@ -779,6 +779,18 @@ the marker is placed upon. The options currently available are:
* monster_dies_lua_key: If this property is set to a function, that function
will be executed upon the monster's death.
+* shout_func: If this property is set to a function, that function will be
+ called if the monster shouts, and the string returned by the function
+ will be used as the text of the message. can return "__NONE" to
+ make the monster not shout, or "__NEXT" to proceed as if there was no
+ speech_func property.
+
+* speech_func: If this property is set to a function, that function will be
+ called if the monster speaks, and the string returned by the function
+ will be used as the text of the message. can return "__NONE" to
+ make the monster not talk, or "__NEXT" to proceed as if there was no
+ speech_func property.
+
* speech_key: This will override the initial key searched for in the speech
database. Setting this to "Edmund", for example, will give the relevant
monster Edmund's speech.
@@ -792,6 +804,9 @@ An example of MonPropsMarker to replace the description and quote of a monster:
MARKER: 8 = lua:MonPropsMarker:new {description="What a horrible sight!\n", \
quote='"They were filled with fear!'\n"}
+Note that all of the speech related properties will be reset if the monster
+polymorphs.
+
Lua API reference
-----------------
a. The Map.
diff --git a/crawl-ref/source/mon-speak.cc b/crawl-ref/source/mon-speak.cc
index a5424f117b..9d2d8ecc85 100644
--- a/crawl-ref/source/mon-speak.cc
+++ b/crawl-ref/source/mon-speak.cc
@@ -15,8 +15,10 @@
#include "externs.h"
#include "beam.h"
+#include "cluautil.h"
#include "database.h"
#include "debug.h"
+#include "dlua.h"
#include "ghost.h"
#include "message.h"
#include "mon-stuff.h"
@@ -558,8 +560,43 @@ bool mons_speaks(monsters *monster)
}
else
{
+ if (monster->props.exists("speech_func"))
+ {
+#ifdef DEBUG_MONSPEAK
+ mpr("Trying Lua function for monster speech", MSGCH_DIAGNOSTICS);
+#endif
+ lua_stack_cleaner clean(dlua);
+
+ dlua_chunk &chunk = monster->props["speech_func"];
+
+ if (!chunk.load(dlua))
+ {
+ push_monster(dlua, monster);
+ dlua.callfn(NULL, 1, 1);
+ dlua.fnreturns(">s", &msg);
+
+ // __NONE means to be silent, and __NEXT means to try the next
+ // method of getting a speech message.
+ if (msg == "__NONE")
+ {
+#ifdef DEBUG_MONSPEAK
+ mpr("result: \"__NONE\"!", MSGCH_DIAGNOSTICS);
+#endif
+ return (false);
+ }
+ if (msg == "__NEXT")
+ msg.clear();
+ }
+ else
+ {
+ mprf(MSGCH_ERROR,
+ "Lua speech function for monster '%s' didn't load: %s",
+ monster->full_name(DESC_PLAIN).c_str(),
+ dlua.error.c_str());
+ }
+ }
- if (monster->props.exists("speech_key"))
+ if (msg.empty() && monster->props.exists("speech_key"))
{
msg = _get_speak_string(prefixes,
monster->props["speech_key"].get_string(),
diff --git a/crawl-ref/source/mon-stuff.cc b/crawl-ref/source/mon-stuff.cc
index 0d4c374ce2..fc109c5aee 100644
--- a/crawl-ref/source/mon-stuff.cc
+++ b/crawl-ref/source/mon-stuff.cc
@@ -2509,6 +2509,12 @@ bool monster_polymorph(monsters *monster, monster_type targetc,
monster->flags = flags;
monster->god = god;
+ // Forget various speech/shout Lua functions.
+ monster->props.erase("speech_key");
+ monster->props.erase("speech_prefix");
+ monster->props.erase("speech_func");
+ monster->props.erase("shout_func");
+
// Keep spells for named monsters, but don't override innate ones
// for dragons and the like. This means that Sigmund polymorphed
// into a goblin will still cast spells, but if he ends up as a
diff --git a/crawl-ref/source/shout.cc b/crawl-ref/source/shout.cc
index e4167278ba..d7d21af7a4 100644
--- a/crawl-ref/source/shout.cc
+++ b/crawl-ref/source/shout.cc
@@ -7,8 +7,10 @@
#include "shout.h"
+#include "cluautil.h"
#include "coord.h"
#include "database.h"
+#include "dlua.h"
#include "env.h"
#include "ghost.h"
#include "jobs.h"
@@ -148,7 +150,37 @@ void handle_monster_shouts(monsters* monster, bool force)
else
suffix = " unseen";
- msg = getShoutString(key, suffix);
+ if (monster->props.exists("shout_func"))
+ {
+ lua_stack_cleaner clean(dlua);
+
+ dlua_chunk &chunk = monster->props["shout_func"];
+
+ if (!chunk.load(dlua))
+ {
+ push_monster(dlua, monster);
+ clua_pushcxxstring(dlua, suffix);
+ dlua.callfn(NULL, 2, 1);
+ dlua.fnreturns(">s", &msg);
+
+ // __NONE means to be silent, and __NEXT or __DEFAULT means to try
+ // the next method of getting a shout message.
+ if (msg == "__NONE")
+ return;
+ if (msg == "__DEFAULT" || msg == "__NEXT")
+ msg.clear();
+ }
+ else
+ {
+ mprf(MSGCH_ERROR,
+ "Lua shout function for monster '%s' didn't load: %s",
+ monster->full_name(DESC_PLAIN).c_str(),
+ dlua.error.c_str());
+ }
+ }
+
+ if (msg.empty())
+ msg = getShoutString(key, suffix);
if (msg == "__DEFAULT" || msg == "__NEXT")
msg = getShoutString(default_msg_key, suffix);