rpgxef/code/game/lua_trace.c
2013-05-09 19:40:15 +02:00

260 lines
5.1 KiB
C

// 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