diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/game-server/commandhandler.cpp | 78 | ||||
-rw-r--r-- | src/game-server/main-game.cpp | 2 | ||||
-rw-r--r-- | src/scripting/luascript.cpp | 38 | ||||
-rw-r--r-- | src/scripting/luascript.h | 3 | ||||
-rw-r--r-- | src/scripting/script.cpp | 14 | ||||
-rw-r--r-- | src/scripting/script.h | 8 |
6 files changed, 143 insertions, 0 deletions
diff --git a/src/game-server/commandhandler.cpp b/src/game-server/commandhandler.cpp index d7bd8f44..f0cbcf3b 100644 --- a/src/game-server/commandhandler.cpp +++ b/src/game-server/commandhandler.cpp @@ -33,6 +33,8 @@ #include "game-server/monstermanager.h" #include "game-server/state.h" +#include "scripting/script.h" + #include "common/configuration.h" #include "common/permissionmanager.h" #include "common/transaction.h" @@ -73,6 +75,7 @@ static void handleKick(Character*, std::string&); static void handleLog(Character*, std::string&); static void handleLogsay(Character*, std::string&); static void handleKillMonsters(Character*, std::string&); +static void handleCraft(Character*, std::string&); static CmdRef const cmdRef[] = { @@ -128,6 +131,8 @@ static CmdRef const cmdRef[] = "Says something in public chat while logging it to the transaction log.", &handleLogsay}, {"killmonsters", "", "Kills all monsters on the map.", &handleKillMonsters}, + {"craft", "{ <item> <amount> }", + "Crafts something.", &handleCraft}, {NULL, NULL, NULL, NULL} }; @@ -1291,6 +1296,79 @@ static void handleKillMonsters(Character *player, std::string &args) TRANS_CMD_KILLMONSTERS, msg); } +static void handleCraft(Character *player, std::string &args) +{ + std::stringstream errMsg; + std::list<InventoryItem> recipe; + Inventory playerInventory(player); + std::map<int, int> totalAmountOfItem; + + while (true) + { + // parsing + std::string strItem = getArgument(args); + ItemClass* item = itemManager->getItemByName(strItem); + std::string strAmount = getArgument(args); + int amount = utils::stringToInt(strAmount); + + // syntax error checking + if (strItem.empty()) + { + // the item list has ended + break; + } + if (!item) + { + // item wasn't found in the item database + errMsg << "Unknown item: \"" << strItem << "\"."; + break; + } + + if (strAmount.empty()) + { + // the last item in the list has no amount defined + errMsg << "No amount given for \"" << strItem << "\"."; + break; + } + if (amount < 1) + { + errMsg << "Illegal amount \""<< strAmount << "\" for item \"" << strItem << "\"."; + break; + } + + // inventory checking + int available = playerInventory.count(item->getDatabaseID()); + if (available == 0) + { + errMsg << "You have no "<< strItem << " in your inventory."; + break; + } + if (available < amount) + { + errMsg << "You haven't got that many "<< strItem << "s in your inventory."; + break; + } + + // when there is still no break, add the item; + InventoryItem recipeItem; + recipeItem.itemId = item->getDatabaseID(); + recipeItem.amount = amount; + recipe.push_back(recipeItem); + } + + if (!errMsg.str().empty()) + { + // when an error occured, output the error + say(errMsg.str(), player); + return; + } else { + // pass to script engine. The engine is responsible for all + // further processing of the crafting operation, including + // outputting an error message when the recipe is invalid. + Script::performCraft(player, recipe); + } +} + void CommandHandler::handleCommand(Character *player, const std::string &command) { diff --git a/src/game-server/main-game.cpp b/src/game-server/main-game.cpp index b54e3821..63ea0041 100644 --- a/src/game-server/main-game.cpp +++ b/src/game-server/main-game.cpp @@ -74,6 +74,7 @@ using utils::Logger; #define DEFAULT_PERMISSION_FILE "permissions.xml" #define DEFAULT_GLOBAL_EVENT_SCRIPT_FILE "scripts/global_events.lua" #define DEFAULT_SPECIAL_ACTIONS_SCRIPT_FILE "scripts/special_actions.lua" +#define DEFAULT_CRAFT_SCRIPT_FILE "scripts/crafting.lua" static int const WORLD_TICK_SKIP = 2; /** tolerance for lagging behind in world calculation) **/ @@ -200,6 +201,7 @@ static void initializeServer() LuaScript::loadGlobalEventScript(DEFAULT_GLOBAL_EVENT_SCRIPT_FILE); LuaScript::loadSpecialActionsScript(DEFAULT_SPECIAL_ACTIONS_SCRIPT_FILE); + LuaScript::loadCraftScript(DEFAULT_CRAFT_SCRIPT_FILE); // --- Initialize the global handlers // FIXME: Make the global handlers global vars or part of a bigger diff --git a/src/scripting/luascript.cpp b/src/scripting/luascript.cpp index a9c43b72..dc6230ca 100644 --- a/src/scripting/luascript.cpp +++ b/src/scripting/luascript.cpp @@ -21,6 +21,9 @@ #include "luascript.h" + +#include "scripting/luautil.h" + #include "game-server/being.h" #include "utils/logger.h" @@ -61,6 +64,30 @@ void LuaScript::push(Thing *v) ++nbArgs; } +void LuaScript::push(const std::list<InventoryItem> &itemList) +{ + assert(nbArgs >= 0); + int position = 0; + + lua_createtable(mState, itemList.size(), 0); + int itemTable = lua_gettop(mState); + + for (std::list<InventoryItem>::const_iterator i = itemList.begin(); + i != itemList.end(); + i++) + { + // create the item structure + std::map<std::string, int> item; + item["id"] = i->itemId; + item["amount"] = i->amount; + // add the item structure to the item table under the next index + lua_pushinteger(mState, ++position); + pushSTLContainer<std::string, int>(mState, item); + lua_settable(mState, itemTable); + } + ++nbArgs; +} + int LuaScript::execute() { assert(nbArgs >= 0); @@ -182,3 +209,14 @@ bool LuaScript::loadSpecialActionsScript(const std::string &file) } return true; } + +bool LuaScript::loadCraftScript(const std::string &file) +{ + Script::craftScript = new LuaScript(); + if (!Script::craftScript->loadFile(file)) + { + Script::craftScript = NULL; + return false; + } + return true; +} diff --git a/src/scripting/luascript.h b/src/scripting/luascript.h index af13aa22..b9bde2d8 100644 --- a/src/scripting/luascript.h +++ b/src/scripting/luascript.h @@ -52,6 +52,8 @@ class LuaScript: public Script void push(Thing *); + void push(const std::list<InventoryItem> &itemList); + int execute(); static void getQuestCallback(Character *, const std::string &, @@ -69,6 +71,7 @@ class LuaScript: public Script */ static bool loadGlobalEventScript(const std::string &file); static bool loadSpecialActionsScript(const std::string &file); + static bool loadCraftScript(const std::string &file); private: lua_State *mState; diff --git a/src/scripting/script.cpp b/src/scripting/script.cpp index b222b0f7..490abf09 100644 --- a/src/scripting/script.cpp +++ b/src/scripting/script.cpp @@ -34,6 +34,7 @@ typedef std::map< std::string, Script::Factory > Engines; static Engines *engines = NULL; Script *Script::globalEventScript = NULL; Script *Script::specialActionsScript = NULL; +Script *Script::craftScript = NULL; Script::Script(): mMap(NULL), @@ -158,3 +159,16 @@ bool Script::performSpecialAction(int specialId, Being* caster) } return true; } + +bool Script::performCraft(Being* crafter, std::list<InventoryItem> recipe) +{ + Script *script = Script::craftScript; + if (script) + { + script->prepare("on_craft"); + script->push(crafter); + script->push(recipe); + script->execute(); + } + return true; +} diff --git a/src/scripting/script.h b/src/scripting/script.h index 43eebe10..44a8b7ac 100644 --- a/src/scripting/script.h +++ b/src/scripting/script.h @@ -105,6 +105,12 @@ class Script virtual void push(Thing *) = 0; /** + * Pushes a list of items with amounts to the + * script engine. + */ + virtual void push(const std::list<InventoryItem> &itemList) = 0; + + /** * Executes the function being prepared. * @return the value returned by the script. */ @@ -135,11 +141,13 @@ class Script static bool executeGlobalEventFunction(const std::string &function, Being *obj); static void addDataToSpecial(int specialId, Special *special); static bool performSpecialAction(int specialId, Being *caster); + static bool performCraft(Being* crafter, std::list<InventoryItem> recipe); protected: static Script *globalEventScript; static Script *specialActionsScript; + static Script *craftScript; std::string mScriptFile; private: |