// lua library for trace_t #include "g_lua.h" #ifdef G_LUA /*** A module allowing to do traces. Documentation under work. @module trace */ static int Trace_GC(lua_State * L) { return 0; } static int Trace_ToString(lua_State * L) { ltrace_t *ltrace; trace_t *trace; char buf[MAX_STRING_CHARS]; ltrace = Lua_GetTrace(L, 1); trace = ltrace->tr; Com_sprintf(buf, sizeof(buf), "trace: entity=%i fraction=%f allsolid=%i contents=%i endpos=\"%s\" startsolid=%i surfaceFlags=%i pointer=%p\n", trace->entityNum, trace->fraction, trace->allsolid, trace->contents, vtos(trace->endpos), trace->startsolid, trace->surfaceFlags, trace); lua_pushstring(L, buf); return 1; } /*** Does a trace. @function DoTrace @param start start-point of the trace. @param mins minimal distance of trace (nil if unused) @param maxs maximal distance of trace (nil if unused) @param end end-point of trace @param passEnt Number of ents to pass @param contents Set content flags. */ static int Trace_DoTrace(lua_State *L) { trace_t *tr; vec_t *start, *end, *mins = NULL, *maxs = NULL; int passEnt, contents; start = Lua_GetVector(L, 1); if(!lua_isnil(L, 2)) mins = Lua_GetVector(L, 2); if(!lua_isnil(L, 3)) maxs = Lua_GetVector(L, 3); end = Lua_GetVector(L, 4); passEnt = (int)luaL_checknumber(L, 5); contents = (int) luaL_checknumber(L, 6); tr = (trace_t *)malloc(sizeof(trace_t)); if(!tr) { LUA_DEBUG("Trace_DoTrace - was unable to allocate a trace_t.\n"); lua_pushnil(L); return 1; } trap_Trace(tr, start, mins, maxs, end, passEnt, contents); Lua_PushTrace(L, tr); return 1; } /*** Frees all memory that was allocated for this trace. @function FreeTrace @param trace The trace. */ static int Trace_FreeTrace(lua_State *L) { ltrace_t *tr; tr = Lua_GetTrace(L, 1); if(tr && tr->tr) free(tr->tr); return 1; } /*** Check whether the trace has gone only trough solid content (e.g. only inside a wall). @function GetAllsolid @return Whether trace was all solid. */ static int Trace_GetAllsolid(lua_State *L) { ltrace_t *tr; tr = Lua_GetTrace(L, 1); lua_pushboolean(L, (int)tr->tr->allsolid); return 1; } /*** Check whether the trace has started in solid contents. @function GetStartsolid @return Whether trace started solid. */ static int Trace_GetStartsolid(lua_State *L) { ltrace_t *tr; tr = Lua_GetTrace(L, 1); lua_pushboolean(L, (int)tr->tr->startsolid); return 1; } /*** Get fraction of trace. @function GetFraction @return Fraction. */ static int Trace_GetFraction(lua_State *L) { ltrace_t *tr; tr = Lua_GetTrace(L, 1); lua_pushnumber(L, tr->tr->fraction); return 1; } /*** Get end position of the trace. @function GetEndpos @return End position of the trace. */ static int Trace_GetEndpos(lua_State *L) { ltrace_t *tr; tr = Lua_GetTrace(L, 1); Lua_PushVector(L, tr->tr->endpos); return 1; } /*** Get the surface flags for the face the trace hit. @function GetSurfaceFlags @return Surface flags. */ static int Trace_GetSurfaceFlags(lua_State *L) { ltrace_t *tr; tr = Lua_GetTrace(L, 1); lua_pushnumber(L, tr->tr->surfaceFlags); return 1; } /*** Get content flags for the trace. @function GetContents @return Content flags. */ static int Trace_GetContents(lua_State *L) { ltrace_t *tr; tr = Lua_GetTrace(L, 1); lua_pushnumber(L, tr->tr->contents); return 1; } /*** Get entity number for entity the trace hit. @function GetEntityNum @return Entity number. */ static int Trace_GetEntityNum(lua_State *L) { ltrace_t *tr; tr = Lua_GetTrace(L, 1); lua_pushnumber(L, tr->tr->entityNum); return 1; } /*** Get entity the trace hit. @function GetEntity @return entity the trace hit. */ static int Trace_GetEntity(lua_State *L) { ltrace_t *tr; gentity_t *ent; tr = Lua_GetTrace(L, 1); ent = &g_entities[tr->tr->entityNum]; Lua_PushEntity(L, ent); return 1; } static const luaL_Reg lib_trace[] = { { "DoTrace", Trace_DoTrace }, { "FreeTrace", Trace_FreeTrace }, { NULL, NULL } }; static const luaL_Reg Trace_meta[] = { { "__gc", Trace_GC }, { "__tostring", Trace_ToString }, { "GetAllsolid", Trace_GetAllsolid }, { "GetStartsolid", Trace_GetStartsolid }, { "GetFraction", Trace_GetFraction }, { "GetEndpos", Trace_GetEndpos }, { "GetSurfaceFlags", Trace_GetSurfaceFlags }, { "GetContents", Trace_GetContents }, { "GetEntityNum", Trace_GetEntityNum }, { "GetEntity", Trace_GetEntity }, { NULL, NULL } }; int Luaopen_Trace(lua_State *L) { luaL_newmetatable(L, "game.trace"); lua_pushstring(L, "__index"); lua_pushvalue(L, -2); lua_settable(L, -3); luaL_register(L, NULL, Trace_meta); luaL_register(L, "trace", lib_trace); return 1; } void Lua_PushTrace(lua_State * L, trace_t * tr) { ltrace_t *trace; trace = (ltrace_t *)lua_newuserdata(L, sizeof(ltrace_t)); luaL_getmetatable(L, "game.trace"); lua_setmetatable(L, -2); trace->tr = tr; } ltrace_t *Lua_GetTrace(lua_State * L, int argNum) { void *ud; ud = luaL_checkudata(L, argNum, "game.trace"); luaL_argcheck(L, ud != NULL, argNum, "\'trace\' expected"); return (ltrace_t *) ud; } #endif