summaryrefslogtreecommitdiff
path: root/src/game-server
diff options
context:
space:
mode:
authorPhilipp Sehmisch <mana@crushnet.org>2011-04-27 15:24:36 +0200
committerPhilipp Sehmisch <mana@crushnet.org>2011-04-27 15:24:36 +0200
commitc1a6e9947231cc511016378bd326a5d64b0aa18c (patch)
tree03c9b42ae97d61b5568f27ddc3f1be7a8b6648c3 /src/game-server
parentca1dd6fcaf1dfaef0f18df0b6c114f1baa25d2ce (diff)
downloadmanaserv-c1a6e9947231cc511016378bd326a5d64b0aa18c.tar.gz
manaserv-c1a6e9947231cc511016378bd326a5d64b0aa18c.tar.bz2
manaserv-c1a6e9947231cc511016378bd326a5d64b0aa18c.tar.xz
manaserv-c1a6e9947231cc511016378bd326a5d64b0aa18c.zip
Added a simple crafting system
A client can craft something using the @craft command. The command needs a list of item names and amounts. The gameserver checks if the character has these items in the inventory and then passes the list together with the character handle to the lua script function on_craft in the script file scripts/crafting.lua. This function can then be used to evaluate if the list is a valid crafting combination and when this is the case take or give items. Implemented two example crafting scripts there, one which enforces exact item order and amount and one which doesn't. Both are disabled per default and one needs to be enabled by uncommenting a line. Also gave the player group permission to use the @craft command in permissions.xml and added two new items (wood and iron) required for the example crafting combination. Resolves: #333 Reviewed-by: bcs86, Bertram
Diffstat (limited to 'src/game-server')
-rw-r--r--src/game-server/commandhandler.cpp78
-rw-r--r--src/game-server/main-game.cpp2
2 files changed, 80 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