summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scripts/lua/libmana.lua44
-rw-r--r--src/game-server/mapcomposite.cpp30
-rw-r--r--src/game-server/mapcomposite.h4
-rw-r--r--src/game-server/state.cpp30
-rw-r--r--src/scripting/lua.cpp17
5 files changed, 81 insertions, 44 deletions
diff --git a/scripts/lua/libmana.lua b/scripts/lua/libmana.lua
index 162da833..777d8e08 100644
--- a/scripts/lua/libmana.lua
+++ b/scripts/lua/libmana.lua
@@ -44,7 +44,8 @@ function debug(...) log(LOG_DEBUG, table.concat({...}, " ")) end
-- Array containing the function registered by atinit.
local init_fun = {}
--- Table of scheduled jobs. A job is an array with 3 elements:
+-- Set of scheduled jobs. The key is the mapid or 0 for no map.
+-- The value is an array with 3 elements:
-- 0: the UNIX timestamp when it is executed
-- 1: the function which is executed
-- 2: nil when it is a one-time job. Repetition interval is seconds when it is
@@ -53,13 +54,18 @@ local scheduler_jobs = {}
-- checks for jobs which have to be executed, executes them and reschedules
-- them when they are repeated jobs.
-local function check_schedule()
+local function check_schedule(mapid)
local current_time = os.time()
+ local jobs
- while #scheduler_jobs~=0 and current_time > scheduler_jobs[#scheduler_jobs][0] do
+ jobs = scheduler_jobs[mapid or 0]
+
+ if not jobs then return end
+
+ while #jobs ~= 0 and current_time >= jobs[#jobs][0] do
-- retreive the job and remove it from the schedule
- job = scheduler_jobs[#scheduler_jobs]
- table.remove(scheduler_jobs)
+ local job = jobs[#jobs]
+ table.remove(jobs)
-- reschedule the job when it is a repeated job
if job[2] then
schedule_every(job[2], job[1])
@@ -70,9 +76,14 @@ local function check_schedule()
end
-- Registered as the function to call every tick.
--- Checks for scheduled function calls and cleans obsolete connections.
local function update()
- check_schedule()
+ check_schedule()
+end
+
+-- Registered as function to call every map tick.
+-- Checks for scheduled function calls
+local function mapupdate(mapid)
+ check_schedule(mapid)
end
-- Registers a function so that is is executed during map initialization.
@@ -114,8 +125,10 @@ function schedule_in(seconds, funct)
job[0] = os.time() + seconds
job[1] = funct
job[2] = nil
- table.insert(scheduler_jobs, job)
- table.sort(scheduler_jobs, job_cmp)
+ local map_id = get_map_id() or 0 -- if no map context
+ scheduler_jobs[map_id] = scheduler_jobs[map_id] or {}
+ table.insert(scheduler_jobs[map_id], job)
+ table.sort(scheduler_jobs[map_id], job_cmp)
end
-- schedules a function call to be executed at regular intervals of n seconds
@@ -124,8 +137,10 @@ function schedule_every(seconds, funct)
job[0] = os.time() + seconds
job[1] = funct
job[2] = seconds
- table.insert(scheduler_jobs, job)
- table.sort(scheduler_jobs, job_cmp)
+ local map_id = get_map_id() or 0 -- if no map context
+ scheduler_jobs[map_id] = scheduler_jobs[map_id] or {}
+ table.insert(scheduler_jobs[map_id], job)
+ table.sort(scheduler_jobs[map_id], job_cmp)
end
-- schedules a function call to be executed at a given date
@@ -135,8 +150,10 @@ function schedule_per_date(my_year, my_month, my_day, my_hour, my_minute, funct)
hour = my_hour, min = my_minute}
job[1] = funct
job[2] = nil
- table.insert(scheduler_jobs, job)
- table.sort(scheduler_jobs, job_cmp)
+ local map_id = get_map_id() or 0 -- if no map context
+ scheduler_jobs[map_id] = scheduler_jobs[map_id] or {}
+ table.insert(scheduler_jobs[map_id], job)
+ table.sort(scheduler_jobs[map_id], job_cmp)
end
-- MAP/WORLD VARIABLES NOTIFICATIONS
@@ -244,6 +261,7 @@ end
-- Register callbacks
on_update(update)
+on_mapupdate(mapupdate)
on_create_npc_delayed(create_npc_delayed)
on_map_initialize(map_initialize)
diff --git a/src/game-server/mapcomposite.cpp b/src/game-server/mapcomposite.cpp
index 6b2b74f9..7d377d18 100644
--- a/src/game-server/mapcomposite.cpp
+++ b/src/game-server/mapcomposite.cpp
@@ -457,6 +457,7 @@ MapZone& MapContent::getZone(const Point &pos) const
*****************************************************************************/
Script::Ref MapComposite::mInitializeCallback;
+Script::Ref MapComposite::mUpdateCallback;
MapComposite::MapComposite(int id, const std::string &name):
mMap(NULL),
@@ -607,6 +608,35 @@ void MapComposite::remove(Thing *ptr)
void MapComposite::update()
{
+ // Update object status
+ const std::vector< Thing * > &things = getEverything();
+ for (std::vector< Thing * >::const_iterator it = things.begin(),
+ it_end = things.end(); it != it_end; ++it)
+ {
+ (*it)->update();
+ }
+
+ if (mUpdateCallback.isValid())
+ {
+ Script *s = ScriptManager::currentState();
+ s->setMap(this);
+ s->prepare(mUpdateCallback);
+ s->push(mID);
+ s->execute();
+ }
+
+ // Perform actions
+ for (BeingIterator it(getWholeMapIterator()); it; ++it)
+ {
+ (*it)->perform();
+ }
+
+ // Move objects around and update zones.
+ for (BeingIterator it(getWholeMapIterator()); it; ++it)
+ {
+ (*it)->move();
+ }
+
for (int i = 0; i < mContent->mapHeight * mContent->mapWidth; ++i)
{
mContent->zones[i].destinations.clear();
diff --git a/src/game-server/mapcomposite.h b/src/game-server/mapcomposite.h
index 15310a97..96939a9c 100644
--- a/src/game-server/mapcomposite.h
+++ b/src/game-server/mapcomposite.h
@@ -356,6 +356,9 @@ class MapComposite
static void setInitializeCallback(Script *script)
{ script->assignCallback(mInitializeCallback); }
+ static void setUpdateCallback(Script *script)
+ { script->assignCallback(mUpdateCallback); }
+
private:
MapComposite(const MapComposite &);
@@ -374,6 +377,7 @@ class MapComposite
std::map<const std::string, Script::Ref> mWorldVariableCallbacks;
static Script::Ref mInitializeCallback;
+ static Script::Ref mUpdateCallback;
};
#endif
diff --git a/src/game-server/state.cpp b/src/game-server/state.cpp
index 34ede681..0e7bea25 100644
--- a/src/game-server/state.cpp
+++ b/src/game-server/state.cpp
@@ -70,34 +70,6 @@ static DelayedEvents delayedEvents;
*/
static std::map< std::string, std::string > mScriptVariables;
-
-/**
- * Updates object states on the map.
- */
-static void updateMap(MapComposite *map)
-{
- // Update object status
- const std::vector< Thing * > &things = map->getEverything();
- for (std::vector< Thing * >::const_iterator it = things.begin(),
- it_end = things.end(); it != it_end; ++it)
- {
- (*it)->update();
- }
-
- // Perform actions
- for (BeingIterator it(map->getWholeMapIterator()); it; ++it)
- {
- (*it)->perform();
- }
-
- // Move objects around and update zones.
- for (BeingIterator it(map->getWholeMapIterator()); it; ++it)
- {
- (*it)->move();
- }
- map->update();
-}
-
/**
* Sets message fields describing character look.
*/
@@ -456,7 +428,7 @@ void GameState::update(int worldTime)
if (!map->isActive())
continue;
- updateMap(map);
+ map->update();
for (CharacterIterator p(map->getWholeMapIterator()); p; ++p)
{
diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp
index c5ab16ff..136350da 100644
--- a/src/scripting/lua.cpp
+++ b/src/scripting/lua.cpp
@@ -168,6 +168,13 @@ static int on_worldvar_changed(lua_State *s)
return 0;
}
+static int on_mapupdate(lua_State *s)
+{
+ luaL_checktype(s, 1, LUA_TFUNCTION);
+ MapComposite::setUpdateCallback(getScript(s));
+ return 0;
+}
+
static int get_item_class(lua_State *s)
{
LuaItemClass::push(s, checkItemClass(s, 1));
@@ -1921,8 +1928,13 @@ static int test_tableget(lua_State *s)
*/
static int get_map_id(lua_State *s)
{
- MapComposite *m = checkCurrentMap(s);
- lua_pushinteger(s, m->getID());
+ Script *script = getScript(s);
+
+ if (MapComposite *mapComposite = script->getMap())
+ lua_pushinteger(s, mapComposite->getID());
+ else
+ lua_pushnil(s);
+
return 1;
}
@@ -2232,6 +2244,7 @@ LuaScript::LuaScript():
{ "on_get_special_recharge_cost", &on_get_special_recharge_cost },
{ "on_mapvar_changed", &on_mapvar_changed },
{ "on_worldvar_changed", &on_worldvar_changed },
+ { "on_mapupdate", &on_mapupdate },
{ "get_item_class", &get_item_class },
{ "get_monster_class", &get_monster_class },
{ "get_status_effect", &get_status_effect },