diff --git a/game/engine/Map.lua b/game/engine/Map.lua index e54abfd326c7b1fb041d57ae5e145ddcc4b561cb..cbc26706fe63882a5494cb189b9c9e41e908dd53 100644 --- a/game/engine/Map.lua +++ b/game/engine/Map.lua @@ -211,6 +211,8 @@ end --- Serialization function _M:save() return class.save(self, { + _check_entities = true, + _check_entities_store = true, _map = true, _fovcache = true, surface = true, @@ -309,6 +311,9 @@ function _M:loaded() setmetatable(self.remembers, {__call = mapremember}) setmetatable(self.attrs, {__call = mapattrs}) + self._check_entities = {} + self._check_entities_store = {} + self.surface = core.display.newSurface(self.viewport.width, self.viewport.height) self.changed = true self.finished = true @@ -397,6 +402,18 @@ function _M:updateMap(x, y) p:getMapObjects(self.tiles, mos, 13) end + -- Update entities checker for this spot + -- This is to improve speed, we create a function for each spot that checks entities it knows are there + -- This avoid a costly for iteration over a pairs() and this allows luajit to compile only code that is needed + local ce = {} + local fstr = [[p = m[%s]:check(what, x, y, ...) if p then return p end ]] + ce[#ce+1] = [[return function(self, x, y, what, ...) local p local m = self.map[x + y * self.w] ]] + for idx, e in pairs(self.map[x + y * self.w]) do ce[#ce+1] = fstr:format(idx) end + ce[#ce+1] = [[end]] + local ce = table.concat(ce) + self._check_entities[x + y * self.w] = self._check_entities_store[ce] or loadstring(ce)() + self._check_entities_store[ce] = self._check_entities[x + y * self.w] + -- Cache the map objects in the C map self._map:setGrid(x, y, mm, mos) @@ -562,10 +579,7 @@ end function _M:checkAllEntities(x, y, what, ...) if x < 0 or x >= self.w or y < 0 or y >= self.h then return end if self.map[x + y * self.w] then - for _, e in pairs(self.map[x + y * self.w]) do - local p = e:check(what, x, y, ...) - if p then return p end - end + return self._check_entities[x + y * self.w](self, x, y, what, ...) end end diff --git a/game/engine/interface/ActorFOV.lua b/game/engine/interface/ActorFOV.lua index 5ff5f7f1167ef8941c3369a4ac398535b349ac24..d26bf033b005402d083c60a5af9d588bcedca734 100644 --- a/game/engine/interface/ActorFOV.lua +++ b/game/engine/interface/ActorFOV.lua @@ -80,14 +80,16 @@ function _M:computeFOV(radius, block, apply, force, no_store, cache) local t = {x=x,y=y, dx=dx, dy=dy, sqdist=sqdist} fov.actors[a] = t fov.actors_dist[#fov.actors_dist+1] = a + a.__sqdist = sqdist a:check("seen_by", self) a:updateFOV(self, t.sqdist) end end, cache and game.level.map._fovcache[block]) -- Sort actors by distance (squared but we do not care) - table.sort(fov.actors_dist, function(a, b) return fov.actors[a].sqdist < fov.actors[b].sqdist end) - for i = 1, #fov.actors_dist do fov.actors_dist[i].i = i end + table.sort(fov.actors_dist, "__sqdist") +-- table.sort(fov.actors_dist, function(a, b) return a.__sqdist < b.__sqdist end) +-- for i = 1, #fov.actors_dist do fov.actors_dist[i].i = i end -- print("Computed FOV for", self.uid, self.name, ":: seen ", #fov.actors_dist, "actors closeby") self.fov = fov diff --git a/game/modules/tome/class/NPC.lua b/game/modules/tome/class/NPC.lua index c87b1c97f639c41d719802f4c4859f80f961a4af..71a4cdc4dfe1c5e7bd17f24a223c608293473ae7 100644 --- a/game/modules/tome/class/NPC.lua +++ b/game/modules/tome/class/NPC.lua @@ -39,7 +39,12 @@ function _M:act() -- print("lite", self.name, self.lite) -- self:computeFOV(self.lite, "block_sight", function(x, y, dx, dy, sqdist) game.level.map:applyLite(x, y) end, true, true) -- end - self:computeFOV(self.sight or 20) + -- If the actor has no special vision we can use the default cache + if not self.special_vision then + self:computeFOV(self.sight or 20, "block_sight", nil, nil, nil, true) + else + self:computeFOV(self.sight or 20, "block_sight") + end -- Let the AI think .... beware of Shub ! -- If AI did nothing, use energy anyway diff --git a/game/modules/tome/class/Player.lua b/game/modules/tome/class/Player.lua index 4b21b744d486d12741e1abab2302d43209c63276..90daf0455dbb1c4a158a08defd30b840c0c8b0c3 100644 --- a/game/modules/tome/class/Player.lua +++ b/game/modules/tome/class/Player.lua @@ -182,22 +182,28 @@ function _M:act() end end +-- Precompute FOV form +local fovdist = {} +for i = 0, 30 * 30 do + fovdist[i] = math.max((20 - math.sqrt(i)) / 14, 0.6) +end + function _M:playerFOV() -- Clean FOV before computing it game.level.map:cleanFOV() -- Compute ESP FOV, using cache - if not game.zone.wilderness then self:computeFOV(self.esp.range or 10, "block_esp", function(x, y) game.level.map:applyESP(x, y) end, true, true) end + if not game.zone.wilderness then self:computeFOV(self.esp.range or 10, "block_esp", function(x, y) game.level.map:applyESP(x, y) end, true, true, true) end if not self:attr("blind") then -- Compute both the normal and the lite FOV, using cache if game.zone.wilderness_see_radius then self:computeFOV(self.sight or 20, "block_sight", function(x, y, dx, dy, sqdist) - game.level.map:apply(x, y, math.max((20 - math.sqrt(sqdist)) / 14, 0.6)) + game.level.map:apply(x, y, fovdist[sqdist]) end, true, false, true) self:computeFOV(game.zone.wilderness_see_radius, "block_sight", function(x, y, dx, dy, sqdist) game.level.map:applyLite(x, y) end, true, true, true) else self:computeFOV(self.sight or 20, "block_sight", function(x, y, dx, dy, sqdist) - game.level.map:apply(x, y, math.max((20 - math.sqrt(sqdist)) / 14, 0.6)) + game.level.map:apply(x, y, fovdist[sqdist]) end, true, false, true) if self.lite <= 0 then game.level.map:applyLite(self.x, self.y) else self:computeFOV(self.lite, "block_sight", function(x, y, dx, dy, sqdist) game.level.map:applyLite(x, y) end, true, true, true) end diff --git a/src/core_lua.c b/src/core_lua.c index 0fbc691dd1f59debbe103371b7082468200d9cfc..1920d62686d51bfcdc70d94532b5fa8312fe9074 100644 --- a/src/core_lua.c +++ b/src/core_lua.c @@ -170,14 +170,14 @@ static int lua_fov_calc_circle(lua_State *L) } fov.apply_ref = luaL_ref(L, LUA_REGISTRYINDEX); fov.opaque_ref = luaL_ref(L, LUA_REGISTRYINDEX); -// int i= SDL_GetTicks(); + fov_settings_init(&(fov.fov_settings)); fov_settings_set_opacity_test_function(&(fov.fov_settings), map_opaque); fov_settings_set_apply_lighting_function(&(fov.fov_settings), map_seen); fov_circle(&(fov.fov_settings), &fov, NULL, x, y, radius+1); map_seen(&fov, x, y, 0, 0, radius, NULL); fov_settings_free(&(fov.fov_settings)); -// printf("map display ticks %d\n",SDL_GetTicks()-i); + luaL_unref(L, LUA_REGISTRYINDEX, fov.apply_ref); luaL_unref(L, LUA_REGISTRYINDEX, fov.opaque_ref); if (fov.cache_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, fov.cache_ref); diff --git a/src/lua/ltablib.c b/src/lua/ltablib.c index b6d9cb4ac74d7ada27bfa1d429114a16758d257a..61e88922dd04e83d4ee2fc78a97683d5ade2a346 100644 --- a/src/lua/ltablib.c +++ b/src/lua/ltablib.c @@ -169,6 +169,27 @@ static int tconcat (lua_State *L) { ** Addison-Wesley, 1993.) */ +static void stackDump (lua_State *L) { + int i=lua_gettop(L); + printf(" ---------------- Stack Dump ----------------\n" ); + while( i ) { + int t = lua_type(L, i); + switch (t) { + case LUA_TSTRING: + printf("%d:`%s'\n", i, lua_tostring(L, i)); + break; + case LUA_TBOOLEAN: + printf("%d: %s\n",i,lua_toboolean(L, i) ? "true" : "false"); + break; + case LUA_TNUMBER: + printf("%d: %g\n", i, lua_tonumber(L, i)); + break; + default: printf("%d: %s\n", i, lua_typename(L, t)); break; + } + i--; + } + printf("--------------- Stack Dump Finished ---------------\n" ); +} static void set2 (lua_State *L, int i, int j) { lua_rawseti(L, 1, i); @@ -176,7 +197,7 @@ static void set2 (lua_State *L, int i, int j) { } static int sort_comp (lua_State *L, int a, int b) { - if (!lua_isnil(L, 2)) { /* function? */ + if (lua_isfunction(L, 2)) { /* function? */ int res; lua_pushvalue(L, 2); lua_pushvalue(L, a-1); /* -1 to compensate function */ @@ -186,6 +207,17 @@ static int sort_comp (lua_State *L, int a, int b) { lua_pop(L, 1); return res; } + else if (!lua_isnil(L, 2)) { /* index? */ + int res; + lua_pushvalue(L, 2); + lua_gettable(L, a-1); + + lua_pushvalue(L, 2); + lua_gettable(L, b-2); + res = lua_lessthan(L, -2, -1); + lua_pop(L, 2); + return res; + } else /* a < b? */ return lua_lessthan(L, a, b); } @@ -257,7 +289,9 @@ static int sort (lua_State *L) { int n = aux_getn(L, 1); luaL_checkstack(L, 40, ""); /* assume array is smaller than 2^40 */ if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */ - luaL_checktype(L, 2, LUA_TFUNCTION); + { +// if (luaL_checktype(L, 2, LUA_TFUNCTION); + } lua_settop(L, 2); /* make sure there is two arguments */ auxsort(L, 1, n); return 0; diff --git a/src/luajit/ltablib.c b/src/luajit/ltablib.c index b6d9cb4ac74d7ada27bfa1d429114a16758d257a..e6bdb90fa17e5575a157732b0a1a4bd251d16c40 100644 --- a/src/luajit/ltablib.c +++ b/src/luajit/ltablib.c @@ -176,7 +176,7 @@ static void set2 (lua_State *L, int i, int j) { } static int sort_comp (lua_State *L, int a, int b) { - if (!lua_isnil(L, 2)) { /* function? */ + if (lua_isfunction(L, 2)) { /* function? */ int res; lua_pushvalue(L, 2); lua_pushvalue(L, a-1); /* -1 to compensate function */ @@ -186,6 +186,17 @@ static int sort_comp (lua_State *L, int a, int b) { lua_pop(L, 1); return res; } + else if (!lua_isnil(L, 2)) { /* index? */ + int res; + lua_pushvalue(L, 2); + lua_gettable(L, a-1); + + lua_pushvalue(L, 2); + lua_gettable(L, b-2); + res = lua_lessthan(L, -2, -1); + lua_pop(L, 2); + return res; + } else /* a < b? */ return lua_lessthan(L, a, b); } @@ -257,7 +268,9 @@ static int sort (lua_State *L) { int n = aux_getn(L, 1); luaL_checkstack(L, 40, ""); /* assume array is smaller than 2^40 */ if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */ - luaL_checktype(L, 2, LUA_TFUNCTION); + { +// if (luaL_checktype(L, 2, LUA_TFUNCTION); + } lua_settop(L, 2); /* make sure there is two arguments */ auxsort(L, 1, n); return 0; diff --git a/src/luaprofiler/core_profiler.c b/src/luaprofiler/core_profiler.c index 0f70fba106e5ec8380b395fd29896752710e9ae4..0e15072040d58890e8024cc2ef4b70d2a146b631 100644 --- a/src/luaprofiler/core_profiler.c +++ b/src/luaprofiler/core_profiler.c @@ -79,7 +79,7 @@ static void formats(char *s) { /* computes new stack and new timer */ -void lprofP_callhookIN(lprofP_STATE* S, char *func_name, char *file, int linedefined, int currentline) { +void lprofP_callhookIN(lprofP_STATE* S, char *func_name, char *file, int linedefined, int currentline) { S->stack_level++; lprofM_enter_function(S, file, func_name, linedefined, currentline); } @@ -103,8 +103,8 @@ int lprofP_callhookOUT(lprofP_STATE* S) { info->total_time += function_call_time; formats(info->file_defined); formats(info->function_name); - output("%d\t%s\t%s\t%d\t%d\t%f\t%f\n", S->stack_level, info->file_defined, - info->function_name, + output("%d\t%s\t%s:%d:%s\t%d\t%d\t%f\t%f\n", S->stack_level, info->file_defined, + info->function_name, info->line_defined, info->file_defined, info->line_defined, info->current_line, info->local_time, info->total_time); /* ... now it's ok to resume the timer */ @@ -128,7 +128,7 @@ lprofP_STATE* lprofP_init_core_profiler(const char *_out_filename, int isto_prin function_call_time = _function_call_time; out_filename = (_out_filename) ? (_out_filename):(OUT_FILENAME); - + /* the random string to build the logname is extracted */ /* from 'tmpnam()' (the '/tmp/' part is deleted) */ randstr = tmpnam(NULL); @@ -155,7 +155,7 @@ lprofP_STATE* lprofP_init_core_profiler(const char *_out_filename, int isto_prin fclose(outf); return 0; } - + return S; } @@ -174,7 +174,7 @@ lprofP_STATE* lprofP_create_profiler(float _function_call_time) { if(!S) { return 0; } - + return S; } diff --git a/src/luaprofiler/lua50_profiler.c b/src/luaprofiler/lua50_profiler.c index 54533425c3beaf18ccdca27bb7c48f9d2fa42655..0a0a3dde17b33a23e0f8cf7fac54484df9b44df3 100644 --- a/src/luaprofiler/lua50_profiler.c +++ b/src/luaprofiler/lua50_profiler.c @@ -42,7 +42,7 @@ static void callhook(lua_State *L, lua_Debug *ar) { lua_getinfo(L, "l", &previous_ar); currentline = previous_ar.currentline; } - + lua_getinfo(L, "nS", ar); if (!ar->event) { @@ -90,7 +90,7 @@ static int coroutine_create(lua_State *L) { lua_pushlightuserdata(L, S); lua_settable(L, LUA_REGISTRYINDEX); lua_sethook(NL, (lua_Hook)callhook, LUA_MASKCALL | LUA_MASKRET, 0); - return 1; + return 1; } #endif @@ -134,7 +134,7 @@ static int profiler_init(lua_State *L) { lua_pushlightuserdata(L, &profstate_id); lua_pushlightuserdata(L, S); lua_settable(L, LUA_REGISTRYINDEX); - + /* use our own exit function instead */ lua_getglobal(L, "os"); lua_pushlightuserdata(L, &exit_id); @@ -158,7 +158,7 @@ static int profiler_init(lua_State *L) { /* as a library. */ lprofP_callhookIN(S, "profiler_init", "(C)", -1, -1); - + lua_pushboolean(L, 1); return 1; }