From 402e94a76a9f01bc3b5cebee4d616e4121b4c5ff Mon Sep 17 00:00:00 2001 From: zelgadis Date: Thu, 6 Dec 2007 12:13:42 +0000 Subject: Database entries fetched with getLongDescription() can contain embeded Lua code. The code will be replaced with its return value before being displayed to the user. The Lua code has no access to the thing being described, and so can only rely on global data. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@3011 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/clua.cc | 2 ++ crawl-ref/source/dat/descript/items.txt | 23 +++++++++++++++--- crawl-ref/source/database.cc | 43 ++++++++++++++++++++++++++++++++- crawl-ref/source/describe.cc | 24 +++--------------- 4 files changed, 67 insertions(+), 25 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/clua.cc b/crawl-ref/source/clua.cc index a823f21464..e8bd6449dd 100644 --- a/crawl-ref/source/clua.cc +++ b/crawl-ref/source/clua.cc @@ -757,6 +757,7 @@ LUARET1(you_see_grid, boolean, see_grid(luaL_checkint(ls, 1), luaL_checkint(ls, 2))) LUARET1(you_see_grid_no_trans, boolean, see_grid_no_trans(luaL_checkint(ls, 1), luaL_checkint(ls, 2))) +LUARET1(you_can_smell, boolean, player_can_smell()) // increase by 1 because check happens on old level @@ -842,6 +843,7 @@ static const struct luaL_reg you_lib[] = { "see_grid", you_see_grid }, { "see_grid_no_trans", you_see_grid_no_trans }, + { "can_smell", you_can_smell }, { NULL, NULL }, }; diff --git a/crawl-ref/source/dat/descript/items.txt b/crawl-ref/source/dat/descript/items.txt index 0f8813be44..564fbeef68 100644 --- a/crawl-ref/source/dat/descript/items.txt +++ b/crawl-ref/source/dat/descript/items.txt @@ -1374,7 +1374,17 @@ A small shield. %%%% large shield -Like a normal shield, only larger. +Like a normal shield, only larger. {{ +if string.find(you.race(), "Ogre") + or string.find(you.race(), "Draconian") + or you.race() == "Troll" +then + return "It looks like it would fit you well." +else + return "It is very cumbersome to wear, and slows the rate at " .. + "which you may attack. " +end +}} %%%% dragon hide @@ -1466,10 +1476,17 @@ animal skin The skins of several animals. %%%% +# Produces "The slimy skin" if you can't smell and "The slimy, smelly +# skin" if you can smell. swamp dragon hide -The slimy skin of a swamp-dwelling dragon. I suppose you could wear it -if you really wanted to. +The slimy{{ +if you.can_smell() then + return ", smelly" +else + return "" +end +}} skin of a swamp-dwelling dragon. I suppose you could wear it if you really wanted to. %%%% swamp dragon armour diff --git a/crawl-ref/source/database.cc b/crawl-ref/source/database.cc index fb695332ee..ff1b59bf2c 100644 --- a/crawl-ref/source/database.cc +++ b/crawl-ref/source/database.cc @@ -14,6 +14,8 @@ #include #include #include + +#include "clua.h" #include "database.h" #include "files.h" #include "libutil.h" @@ -211,6 +213,42 @@ std::vector database_find_bodies(DBM *database, /////////////////////////////////////////////////////////////////////////// // Internal DB utility functions +static void execute_embedded_lua(std::string &str) +{ + // Execute any lua code found between "{{" and "}}". The lua code + // is expected to return a string, with which the lua code and braces + // will be replaced. + std::string::size_type pos = str.find("{{"); + while (pos != std::string::npos) + { + std::string::size_type end = str.find("}}", pos + 2); + if (end == std::string::npos) + { + mpr("Unbalanced {{, bailing.", MSGCH_DIAGNOSTICS); + break; + } + + std::string lua_full = str.substr(pos, end - pos + 2); + std::string lua = str.substr(pos + 2, end - pos - 2); + + if (clua.execstring(lua.c_str(), "db_embedded_lua", 1)) + { + std::string err = "{{" + clua.error; + err += "}}"; + str.replace(pos, lua_full.length(), err); + + return; + } + + std::string result; + clua.fnreturns(">s", &result); + + str.replace(pos, lua_full.length(), result); + + pos = str.find("{{", pos + result.length()); + } // while (pos != std::string::npos) +} + static void trim_right(std::string &s) { s.erase(s.find_last_not_of(" \r\t\n") + 1); @@ -457,7 +495,10 @@ std::string getLongDescription(const std::string &key) datum result = database_fetch(descriptionDB, canonical_key); // Cons up a (C++) string to return. The caller must release it. - return std::string((const char *)result.dptr, result.dsize); + std::string str((const char *)result.dptr, result.dsize); + + execute_embedded_lua(str); + return (str); } std::vector getLongDescKeysByRegex(const std::string ®ex, diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc index ba26fc4f6e..14a7244cec 100644 --- a/crawl-ref/source/describe.cc +++ b/crawl-ref/source/describe.cc @@ -1860,14 +1860,11 @@ std::string get_item_description( const item_def &item, bool verbose, description << db_desc; if (item.base_type == OBJ_WANDS - || (item.base_type == OBJ_FOOD && item.sub_type == FOOD_CHUNK) - || (item.base_type == OBJ_ARMOUR && - item.sub_type == ARM_LARGE_SHIELD)) + || (item.base_type == OBJ_FOOD && item.sub_type == FOOD_CHUNK)) { // Get rid of newline at end of description, so that - // either the wand "no charges left", the meat chunk - // "unpleasent", or the large shield "cumbersome" - // description can follow on the same line. + // either the wand "no charges left" or the meat chunk + // "unpleasent" description can follow on the same line. description.seekp(description.tellp() - (std::streamoff)1); description << " "; } @@ -1886,21 +1883,6 @@ std::string get_item_description( const item_def &item, bool verbose, break; case OBJ_ARMOUR: - if (item.sub_type == ARM_LARGE_SHIELD) - { - 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. "; - } - } - description << describe_armour( item, verbose ); break; -- cgit v1.2.3-54-g00ecf