From 60dcfd1021a58cef8a3f5a3fac10c7d5a7b13dd2 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 25 Oct 2016 22:39:27 +0100 Subject: [PATCH] Pop result of P_SearchBlockmap_Objects's function arg Also P_SearchBlockmap_Lines is a thing now too --- src/lua_baselib.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 8c0d3ff19..9eec5bc6e 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -246,6 +246,7 @@ static boolean lib_pSearchBlockmap_Objects_aux(lua_State *L, INT32 x, INT32 y, m if (lua_toboolean(gL, -1)) return false; } + lua_pop(gL, 1); if (P_MobjWasRemoved(thing) // func just popped our thing, cannot continue. || (bnext && P_MobjWasRemoved(bnext))) // func just broke blockmap chain, cannot continue. { @@ -314,6 +315,158 @@ static int lib_pSearchBlockmap_Objects(lua_State *L) lua_pushboolean(L, retval); return 1; } + +// auxillary function for lib_pSearchBlockmap_Objects +static boolean lib_pSearchBlockmap_Lines_aux(lua_State *L, INT32 x, INT32 y, mobj_t *thing, int funcarg) +{ + INT32 offset; + const INT32 *list; // Big blockmap +#ifdef POLYOBJECTS + polymaplink_t *plink; // haleyjd 02/22/06 +#endif + line_t *ld; + + if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight) + return true; + + offset = y*bmapwidth + x; + +#ifdef POLYOBJECTS + // haleyjd 02/22/06: consider polyobject lines + plink = polyblocklinks[offset]; + + while (plink) + { + polyobj_t *po = plink->po; + + if (po->validcount != validcount) // if polyobj hasn't been checked + { + size_t i; + po->validcount = validcount; + + for (i = 0; i < po->numLines; ++i) + { + if (po->lines[i]->validcount == validcount) // line has been checked + continue; + po->lines[i]->validcount = validcount; + + lua_pushvalue(L, funcarg); + LUA_PushUserdata(L, thing, META_MOBJ); + LUA_PushUserdata(L, po->lines[i], META_LINE); + if (lua_pcall(gL, 2, 1, 0)) { + if (!blockfuncerror || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + blockfuncerror = true; + return true; + } + if (!lua_isnil(gL, -1)) + { // if nil, continue + if (lua_toboolean(gL, -1)) + return false; + } + lua_pop(gL, 1); + if (P_MobjWasRemoved(thing)) + return true; + } + } + plink = (polymaplink_t *)(plink->link.next); + } +#endif + + offset = *(blockmap + offset); // offset = blockmap[y*bmapwidth+x]; + + // First index is really empty, so +1 it. + for (list = blockmaplump + offset + 1; *list != -1; list++) + { + ld = &lines[*list]; + + if (ld->validcount == validcount) + continue; // Line has already been checked. + + ld->validcount = validcount; + + lua_pushvalue(L, funcarg); + LUA_PushUserdata(L, thing, META_MOBJ); + LUA_PushUserdata(L, ld, META_LINE); + if (lua_pcall(gL, 2, 1, 0)) { + if (!blockfuncerror || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + blockfuncerror = true; + return true; + } + if (!lua_isnil(gL, -1)) + { // if nil, continue + if (lua_toboolean(gL, -1)) + return false; + } + lua_pop(gL, 1); + if (P_MobjWasRemoved(thing)) + return true; + } + return true; // Everything was checked. +} + +// P_SearchBlockmap_Lines +// same deal as the _Objects version +static int lib_pSearchBlockmap_Lines(lua_State *L) +{ + int n = lua_gettop(L); + mobj_t *mobj; + INT32 xl, xh, yl, yh, bx, by; + fixed_t x1, x2, y1, y2; + int funcarg; + boolean retval = true; + + // the mobj we are searching around + mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + if (!mobj) + return LUA_ErrInvalid(L, "mobj_t"); + + if (n > 2) // specific x/y ranges have been supplied + { + if (n < 6) + return luaL_error(L, "arguments 2 to 5 not all given (expected 4 fixed-point integers)"); + + x1 = luaL_checkfixed(L, 2); + x2 = luaL_checkfixed(L, 3); + y1 = luaL_checkfixed(L, 4); + y2 = luaL_checkfixed(L, 5); + funcarg = 6; + } + else // mobj and function only - search around mobj's radius by default + { + x1 = mobj->x - mobj->radius; + x2 = mobj->x + mobj->radius; + y1 = mobj->y - mobj->radius; + y2 = mobj->y + mobj->radius; + funcarg = 2; + } + luaL_checktype(L, funcarg, LUA_TFUNCTION); + + xl = (unsigned)(x1 - bmaporgx - MAXRADIUS)>>MAPBLOCKSHIFT; + xh = (unsigned)(x2 - bmaporgx + MAXRADIUS)>>MAPBLOCKSHIFT; + yl = (unsigned)(y1 - bmaporgy - MAXRADIUS)>>MAPBLOCKSHIFT; + yh = (unsigned)(y2 - bmaporgy + MAXRADIUS)>>MAPBLOCKSHIFT; + + BMBOUNDFIX(xl, xh, yl, yh); + + blockfuncerror = false; // reset + validcount++; + for (bx = xl; bx <= xh; bx++) + for (by = yl; by <= yh; by++) + { + if (!lib_pSearchBlockmap_Lines_aux(L, bx, by, mobj, funcarg)) + retval = false; + if (P_MobjWasRemoved(mobj)){ + lua_pushboolean(L, false); + return 1; + } + } + lua_pushboolean(L, retval); + return 1; +} #endif // P_ENEMY @@ -2105,6 +2258,7 @@ static luaL_Reg lib[] = { {"P_PointOnLineSide",lib_pPointOnLineSide}, #ifdef LUA_BLOCKMAP {"P_SearchBlockmap_Objects",lib_pSearchBlockmap_Objects}, + {"P_SearchBlockmap_Lines",lib_pSearchBlockmap_Lines}, #endif // p_enemy