summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Melquiond <guillaume.melquiond@gmail.com>2007-08-10 14:17:38 +0000
committerGuillaume Melquiond <guillaume.melquiond@gmail.com>2007-08-10 14:17:38 +0000
commitf990980f80ab1523086edba1bed222741d716fa0 (patch)
tree0ce0257ca854ea06949f543227a301a7f553e1a9
parentcb45a65e1020bf129225dd20c57bf64314cef2c8 (diff)
downloadmanaserv-f990980f80ab1523086edba1bed222741d716fa0.tar.gz
manaserv-f990980f80ab1523086edba1bed222741d716fa0.tar.bz2
manaserv-f990980f80ab1523086edba1bed222741d716fa0.tar.xz
manaserv-f990980f80ab1523086edba1bed222741d716fa0.zip
Improved helper functions for Lua scripts. Associated scripts to maps.
-rw-r--r--ChangeLog7
-rw-r--r--data/test.lua79
-rw-r--r--src/game-server/mapcomposite.cpp11
-rw-r--r--src/game-server/mapcomposite.hpp23
-rw-r--r--src/game-server/state.cpp5
-rw-r--r--src/game-server/testing.cpp1
6 files changed, 102 insertions, 24 deletions
diff --git a/ChangeLog b/ChangeLog
index e95d38ad..ee066072 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2007-08-10 Guillaume Melquiond <guillaume.melquiond@gmail.com>
+
+ * data/test.lua: Added Lua helper functions to simplify scripts.
+ * src/game-server/testing.cpp, src/game-server/state.cpp,
+ src/game-server/mapcomposite.cpp, src/game-server/mapcomposite.hpp:
+ Associated scripts to maps.
+
2007-08-09 Guillaume Melquiond <guillaume.melquiond@gmail.com>
* src/game-server/inventory.cpp: Fixed item move toward a not yet
diff --git a/data/test.lua b/data/test.lua
index 3552acc7..5a1327a6 100644
--- a/data/test.lua
+++ b/data/test.lua
@@ -4,6 +4,11 @@
-- NOTE: Could be put into a separate library
+function create_npc(id, x, y, handler)
+ local npc = tmw.obj_create_npc(id, x, y)
+ npcs[npc] = handler
+end
+
function do_message(npc, ch, msg)
tmw.msg_npc_message(npc, ch, msg)
coroutine.yield(1)
@@ -14,37 +19,47 @@ function do_choice(npc, ch, msg)
return coroutine.yield(2)
end
+-- Called whenever a player starts talking to an NPC.
+-- Creates a coroutine based on the register NPC handler.
function npc_start(npc, ch)
- -- TODO: choose the handler depending on the npc type
- local co = coroutine.create(my_npc_handler)
+ local h = npcs[npc]
+ if not h then return end
+ local co = coroutine.create(h)
local b, v = coroutine.resume(co, npc, ch)
if b and v then
- npcs[ch] = {npc, co, v}
+ states[ch] = {npc, co, v, 5}
+ if not timer then
+ timer = 600
+ end
end
end
+-- Called whenever a player keeps talking to an NPC.
+-- Checks that the NPC expects it, and resumes the respective coroutine.
function npc_next(npc, ch)
- local w = npcs[ch]
+ local w = states[ch]
if w and w[1] == npc and w[3] == 1 then
- local co = w[2]
- local b, v = coroutine.resume(co)
+ local b, v = coroutine.resume(w[2])
if b and v then
- npcs[ch] = {npc, co, v}
+ w[3] = v
+ w[4] = 5
else
- npcs[ch] = nil
+ states[ch] = nil
end
end
end
+-- Called whenever a player selects a particular reply.
+-- Checks that the NPC expects it, and resumes the respective coroutine.
function npc_choose(npc, ch, u)
- local w = npcs[ch]
+ local w = states[ch]
if w and w[1] == npc and w[3] == 2 then
- local co = w[2]
- local b, v = coroutine.resume(co, u)
+ local b, v = coroutine.resume(w[2], u)
if b and v then
- npcs[ch] = {npc, co, v}
+ w[3] = v
+ w[4] = 5
else
- npcs[ch] = nil
+ states[ch] = nil
end
end
end
@@ -53,20 +68,41 @@ function npc_update(npc)
end
function update()
- -- TODO: delete obsolete entries of the npcs table
+ -- Run every minute only, in order not to overload the server.
+ if not timer then return end
+ timer = timer - 10
+ if timer ~= 0 then return end
+ -- Free connections that have been inactive for 3-4 minutes.
+ for k, w in pairs(states) do
+ local t = w[4] - 1
+ if t == 0 then
+ states[k] = nil
+ else
+ w[4] = t
+ end
+ end
+ -- Restart timer if there are still some pending states.
+ if next(states) then
+ timer = 600
+ else
+ timer = nil
+ end
end
npcs = {}
+states = {}
--------------
-- Map code --
--------------
function initialize()
- tmw.obj_create_npc(110, 50 * 32 + 16, 19 * 32 + 16)
+ create_npc(110, 50 * 32 + 16, 19 * 32 + 16, my_npc1)
+ create_npc(107, 53 * 32 + 16, 21 * 32 + 16, my_npc2)
+ create_npc(107, 53 * 32 + 16, 23 * 32 + 16, my_npc3)
end
-function my_npc_handler(npc, ch)
+function my_npc1(npc, ch)
do_message(npc, ch, "Hello! I am the testing NPC")
do_message(npc, ch, "This message is just here for testing intertwined connections.")
do_message(npc, ch, "What do you want?")
@@ -76,3 +112,14 @@ function my_npc_handler(npc, ch)
end
end
+npc2_times = 1
+
+function my_npc2(npc, ch)
+ do_message(npc, ch, "You know what?")
+ do_message(npc, ch, string.format("I have already asked this question %d times today.", npc2_times))
+ npc2_times = npc2_times + 1
+end
+
+function my_npc3(npc, ch)
+ do_message(npc, ch, "Don't you think the guy behind me is my evil twin?")
+end
diff --git a/src/game-server/mapcomposite.cpp b/src/game-server/mapcomposite.cpp
index 6fea9488..eeb65a10 100644
--- a/src/game-server/mapcomposite.cpp
+++ b/src/game-server/mapcomposite.cpp
@@ -28,7 +28,7 @@
#include "game-server/map.hpp"
#include "game-server/mapcomposite.hpp"
#include "game-server/character.hpp"
-
+#include "scripting/script.hpp"
#include "utils/logger.h"
/* TODO: Implement overlapping map zones instead of strict partitioning.
@@ -452,10 +452,17 @@ void MapComposite::setMap(Map *m)
mContent = new MapContent(m);
}
+
+MapComposite::MapComposite(int id, std::string const &name):
+ mMap(NULL), mContent(NULL), mScript(NULL), mName(name), mID(id)
+{
+}
+
MapComposite::~MapComposite()
{
delete mMap;
delete mContent;
+ delete mScript;
}
bool MapContent::allocate(MovingObject *obj)
@@ -658,5 +665,3 @@ std::vector< Thing * > const &MapComposite::getEverything() const
{
return mContent->things;
}
-
-
diff --git a/src/game-server/mapcomposite.hpp b/src/game-server/mapcomposite.hpp
index 00d52173..fb86ee85 100644
--- a/src/game-server/mapcomposite.hpp
+++ b/src/game-server/mapcomposite.hpp
@@ -34,6 +34,7 @@ class Object;
class Character;
class Point;
class Rectangle;
+class Script;
class Thing;
struct MapContent;
@@ -129,8 +130,7 @@ class MapComposite
/**
* Constructor.
*/
- MapComposite(int id, std::string const &name)
- : mMap(NULL), mContent(NULL), mName(name), mID(id) {}
+ MapComposite(int id, std::string const &name);
/**
* Destructor.
@@ -150,6 +150,18 @@ class MapComposite
{ return mMap; }
/**
+ * Sets the associated script.
+ */
+ void setScript(Script *s)
+ { mScript = s; }
+
+ /**
+ * Gets the associated script.
+ */
+ Script *getScript() const
+ { return mScript; }
+
+ /**
* Returns whether the map is active on this server or not.
*/
bool isActive() const
@@ -217,10 +229,11 @@ class MapComposite
private:
MapComposite(MapComposite const &);
- Map *mMap; /**< Actual map. */
+ Map *mMap; /**< Actual map. */
MapContent *mContent; /**< Entities on the map. */
- std::string mName; /**< Name of the map. */
- unsigned short mID; /**< ID of the map. */
+ Script *mScript; /**< Script associated to this map. */
+ std::string mName; /**< Name of the map. */
+ unsigned short mID; /**< ID of the map. */
};
#endif
diff --git a/src/game-server/state.cpp b/src/game-server/state.cpp
index 513f7e6e..9262798f 100644
--- a/src/game-server/state.cpp
+++ b/src/game-server/state.cpp
@@ -39,6 +39,7 @@
#include "game-server/npc.hpp"
#include "game-server/trade.hpp"
#include "net/messageout.hpp"
+#include "scripting/script.hpp"
#include "utils/logger.h"
typedef std::map< Object *, DelayedEvent > DelayedEvents;
@@ -88,6 +89,10 @@ static void updateMap(MapComposite *map)
}
// 5. update the map itself.
+ if (Script *s = map->getScript())
+ {
+ s->update();
+ }
map->update();
}
diff --git a/src/game-server/testing.cpp b/src/game-server/testing.cpp
index d08f2ee6..7b34d79a 100644
--- a/src/game-server/testing.cpp
+++ b/src/game-server/testing.cpp
@@ -39,6 +39,7 @@ void testingMap(MapComposite *map)
Script *s = Script::create("lua", "test.lua");
if (s)
{
+ map->setScript(s);
s->setMap(map);
s->prepare("initialize");
s->execute();