diff options
-rw-r--r-- | scripts/lua/libmana.lua | 44 | ||||
-rw-r--r-- | src/game-server/mapcomposite.cpp | 30 | ||||
-rw-r--r-- | src/game-server/mapcomposite.h | 4 | ||||
-rw-r--r-- | src/game-server/state.cpp | 30 | ||||
-rw-r--r-- | src/scripting/lua.cpp | 17 |
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 }, |