summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYohann Ferreira <yohann_dot_ferreira_at_orange_dot_fr>2010-05-28 02:59:45 +0200
committerYohann Ferreira <yohann_dot_ferreira_at_orange_dot_fr>2010-05-28 03:42:16 +0200
commit39b00578c249a3396bb03faa92bc9cccdcb1c68a (patch)
treefb9376dd3229f37c4b8d988c569493178ee130bd /src
parente6ce3d52648aec7139f1c3383a0ef0921411f0d4 (diff)
downloadmanaserv-39b00578c249a3396bb03faa92bc9cccdcb1c68a.tar.gz
manaserv-39b00578c249a3396bb03faa92bc9cccdcb1c68a.tar.xz
manaserv-39b00578c249a3396bb03faa92bc9cccdcb1c68a.zip
Modified the npc_trade() lua function to permit selling the whole player inventory.
It permits to open a sell box with every items in the player inventory as requested by Striker. Also added different return value support to both the buy selling functions, and made fixes where relevant. The test.lua script will be upgraded to show examples in a next commit. What's left to be done is to fix the inventory handling for both selling functions. (Sigh...) Concerns: Manasource mantis: #78, #101. Reviewed-by: Jaxad0127
Diffstat (limited to 'src')
-rw-r--r--src/game-server/buysell.cpp38
-rw-r--r--src/game-server/buysell.hpp12
-rw-r--r--src/scripting/lua.cpp87
-rw-r--r--src/scripting/luautil.cpp13
-rw-r--r--src/scripting/luautil.hpp3
5 files changed, 133 insertions, 20 deletions
diff --git a/src/game-server/buysell.cpp b/src/game-server/buysell.cpp
index 5622514..2ae6461 100644
--- a/src/game-server/buysell.cpp
+++ b/src/game-server/buysell.cpp
@@ -23,6 +23,8 @@
#include "game-server/character.hpp"
#include "game-server/gamehandler.hpp"
#include "game-server/inventory.hpp"
+#include "game-server/itemmanager.hpp"
+#include "game-server/item.hpp"
#include "net/messageout.hpp"
#include <algorithm>
@@ -43,27 +45,54 @@ void BuySell::cancel()
delete this;
}
-void BuySell::registerItem(int id, int amount, int cost)
+bool BuySell::registerItem(int id, int amount, int cost)
{
if (mSell)
{
int nb = Inventory(mChar).count(id);
if (nb == 0)
- return;
+ return false;
if (!amount || nb < amount)
amount = nb;
}
TradedItem it = { id, amount, cost };
mItems.push_back(it);
+ return true;
}
-void BuySell::start(Actor *actor)
+int BuySell::registerPlayerItems()
+{
+ int nbItemsToSell = 0;
+ if (mSell)
+ {
+ for (int i = 0; i < EQUIPMENT_SLOTS; ++i)
+ {
+ int id = Inventory(mChar).getItem(i);
+ int nb = Inventory(mChar).count(id);
+ if (nb > 0)
+ {
+ int cost = -1;
+ if (ItemManager::getItem(id))
+ cost = ItemManager::getItem(id)->getCost();
+ if (cost > 0)
+ {
+ TradedItem it = { id, nb, cost };
+ mItems.push_back(it);
+ nbItemsToSell++;
+ }
+ }
+ }
+ }
+ return nbItemsToSell;
+}
+
+bool BuySell::start(Actor *actor)
{
if (mItems.empty())
{
cancel();
- return;
+ return false;
}
MessageOut msg(mSell ? GPMSG_NPC_SELL : GPMSG_NPC_BUY);
@@ -76,6 +105,7 @@ void BuySell::start(Actor *actor)
msg.writeShort(i->cost);
}
mChar->getClient()->send(msg);
+ return true;
}
void BuySell::perform(int id, int amount)
diff --git a/src/game-server/buysell.hpp b/src/game-server/buysell.hpp
index dc1df16..514200a 100644
--- a/src/game-server/buysell.hpp
+++ b/src/game-server/buysell.hpp
@@ -43,13 +43,21 @@ class BuySell
/**
* Registers an item and indicates how many the NPC is ready to trade
* and how much it will cost.
+ * @return true if at least one item was registered.
*/
- void registerItem(int id, int amount, int cost);
+ bool registerItem(int id, int amount, int cost);
+
+ /**
+ * Registers every player's item at an average cost given by the ItemDB.
+ * @return the number of different soldable items.
+ */
+ int registerPlayerItems();
/**
* Sends the item list to player.
+ * @return true if at least one item was registered before start.
*/
- void start(Actor *actor);
+ bool start(Actor *actor);
/**
* Performs the trade.
diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp
index 790d6d9..da47d93 100644
--- a/src/scripting/lua.cpp
+++ b/src/scripting/lua.cpp
@@ -59,7 +59,6 @@ extern "C" {
* http://doc.manasource.org/scripting
*/
-
/**
* Callback for sending a NPC_MESSAGE.
* mana.npc_message(npc, character, string)
@@ -79,7 +78,7 @@ static int npc_message(lua_State *s)
msg.writeShort(p->getPublicID());
msg.writeString(std::string(m), l);
gameHandler->sendTo(q, msg);
- return 0;
+ return 1;
}
/**
@@ -442,44 +441,106 @@ static int chr_inv_count(lua_State *s)
/**
* Callback for trading between a player and an NPC.
* mana.npc_trade(npc, character, bool sell, table items)
+ * Let the player buy or sell only a subset of predeterminded items.
+ * @param table items: a subset of buyable/sellable items.
+ * When selling, if the 4 parameter is omitted or invalid,
+ * everything in the player inventory can be sold.
+ * @return 0 if something to buy/sell, 1 if no items, 2 in case of errors.
*/
static int npc_trade(lua_State *s)
{
NPC *p = getNPC(s, 1);
Character *q = getCharacter(s, 2);
- if (!p || !q || !lua_isboolean(s, 3) || !lua_istable(s, 4))
+ if (!p || !q || !lua_isboolean(s, 3))
{
- raiseScriptError(s, "npc_trade called with incorrect parameters.");
- return 0;
+ raiseWarning(s, "npc_trade called with incorrect parameters.");
+ lua_pushinteger(s, 2); // return value
+ return 1; // Returns 1 parameter
}
- BuySell *t = new BuySell(q, lua_toboolean(s, 3));
+
+ bool sellMode = lua_toboolean(s, 3);
+ BuySell *t = new BuySell(q, sellMode);
+ if (!lua_istable(s, 4))
+ {
+ if (sellMode)
+ {
+ // Can sell everything
+ if (!t->registerPlayerItems())
+ {
+ // No items to sell in player inventory
+ t->cancel();
+ lua_pushinteger(s, 1);
+ return 1;
+ }
+
+ if (t->start(p))
+ {
+ lua_pushinteger(s, 0);
+ return 1;
+ }
+ else
+ {
+ lua_pushinteger(s, 1);
+ return 1;
+ }
+ }
+ else
+ {
+ raiseWarning(s, "npc_trade[Buy] called with invalid or empty items table parameter.");
+ t->cancel();
+ lua_pushinteger(s, 2);
+ return 1;
+ }
+ }
+
+ int nbItems = 0;
+
lua_pushnil(s);
while (lua_next(s, 4))
{
if (!lua_istable(s, -1))
{
- raiseScriptError(s, "npc_trade called with incorrect parameters.");
+ raiseWarning(s, "npc_trade called with invalid or empty items table parameter.");
t->cancel();
- return 0;
+ lua_pushinteger(s, 2);
+ return 1;
}
+
int v[3];
for (int i = 0; i < 3; ++i)
{
lua_rawgeti(s, -1, i + 1);
if (!lua_isnumber(s, -1))
{
- raiseScriptError(s, "rpc_trade called with incorrect parameters.");
+ raiseWarning(s, "npc_trade called with incorrect parameters in item table.");
t->cancel();
- return 0;
+ lua_pushinteger(s, 2);
+ return 1;
}
v[i] = lua_tointeger(s, -1);
lua_pop(s, 1);
}
- t->registerItem(v[0], v[1], v[2]);
+ if (t->registerItem(v[0], v[1], v[2]))
+ nbItems++;
lua_pop(s, 1);
}
- t->start(p);
- return 0;
+
+ if (nbItems == 0)
+ {
+ t->cancel();
+ lua_pushinteger(s, 1);
+ return 1;
+ }
+ if (t->start(p))
+ {
+ lua_pushinteger(s, 0);
+ return 1;
+ }
+ else
+ {
+ lua_pushinteger(s, 1);
+ return 1;
+ }
}
/**
diff --git a/src/scripting/luautil.cpp b/src/scripting/luautil.cpp
index 02de6ad..a3602d2 100644
--- a/src/scripting/luautil.cpp
+++ b/src/scripting/luautil.cpp
@@ -34,10 +34,21 @@ void raiseScriptError(lua_State *s, const char *format, ...)
vsprintf(message, format, args);
va_end( args );
- LOG_WARN("Lua script error: "<<message);
+ LOG_WARN("Lua script error: "<< message);
luaL_error(s, message);
}
+void raiseWarning(lua_State *s, const char *format, ...)
+{
+ va_list args;
+ va_start(args, format);
+ char message[1024];
+ vsprintf(message, format, args);
+ va_end( args );
+
+ LOG_WARN("Lua script error: "<< message);
+}
+
/* Functions below are unsafe, as they assume the script has passed pointers
to objects which have not yet been destroyed. If the script never keeps
pointers around, there will be no problem. In order to be safe, the engine
diff --git a/src/scripting/luautil.hpp b/src/scripting/luautil.hpp
index de138e2..aec2c5c 100644
--- a/src/scripting/luautil.hpp
+++ b/src/scripting/luautil.hpp
@@ -36,8 +36,11 @@ class NPC;
class Character;
class Thing;
+// Report script errors and interrupt the script.
void raiseScriptError(lua_State *s, const char *format, ...);
+void raiseWarning(lua_State *s, const char *format, ...);
+
NPC *getNPC(lua_State *s, int p);
Character *getCharacter(lua_State *s, int p);
Being *getBeing(lua_State *s, int p);