diff --git a/src/blua/luaconf.h b/src/blua/luaconf.h index 4fb940799..9e2948f41 100644 --- a/src/blua/luaconf.h +++ b/src/blua/luaconf.h @@ -11,6 +11,13 @@ #include #include +#ifdef _MSC_VER +#define INT32 __int32 +#else +#include +#define INT32 int32_t +#endif + /* ** ================================================================== @@ -140,7 +147,7 @@ ** CHANGE that if ptrdiff_t is not adequate on your machine. (On most ** machines, ptrdiff_t gives a good choice between int or long.) */ -#define LUA_INTEGER ptrdiff_t +#define LUA_INTEGER INT32 /* @@ -502,13 +509,13 @@ */ //#define LUA_NUMBER_DOUBLE -#define LUA_NUMBER ptrdiff_t +#define LUA_NUMBER INT32 /* @@ LUAI_UACNUMBER is the result of an 'usual argument conversion' @* over a number. */ -#define LUAI_UACNUMBER ptrdiff_t +#define LUAI_UACNUMBER INT32 /* @@ -519,14 +526,14 @@ @@ lua_str2number converts a string to a number. */ #ifdef LUA_WIN - #define LUA_NUMBER_SCAN "%Ii" - #define LUA_NUMBER_FMT "%Ii" + #define LUA_NUMBER_SCAN "%d" + #define LUA_NUMBER_FMT "%d" #else - #define LUA_NUMBER_SCAN "%ti" - #define LUA_NUMBER_FMT "%ti" + #define LUA_NUMBER_SCAN "%d" + #define LUA_NUMBER_FMT "%d" #endif #define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) -#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ +#define LUAI_MAXNUMBER2STR 12 /* 10 digits, sign, and \0 */ #define lua_str2number(s,p) strtol((s), (p), 10) diff --git a/src/d_main.c b/src/d_main.c index 61255e272..3918d8118 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -96,6 +96,10 @@ int snprintf(char *str, size_t n, const char *fmt, ...); #include "hardware/hw3sound.h" #endif +#ifdef HAVE_BLUA +#include "lua_script.h" +#endif + // platform independant focus loss UINT8 window_notinfocus = false; @@ -634,6 +638,10 @@ void D_SRB2Loop(void) #ifdef HW3SOUND HW3S_EndFrameUpdate(); #endif + +#ifdef HAVE_BLUA + LUA_Step(); +#endif } } diff --git a/src/dehacked.c b/src/dehacked.c index 72c9b28d0..6b7900f76 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7757,36 +7757,36 @@ struct { {"FF_GOOWATER",FF_GOOWATER}, ///< Used with ::FF_SWIMMABLE. Makes thick bouncey goop. // Angles - {"ANG1",ANG1}, - {"ANG2",ANG2}, - {"ANG10",ANG10}, - {"ANG15",ANG15}, - {"ANG20",ANG20}, - {"ANG30",ANG30}, - {"ANG60",ANG60}, - {"ANG64h",ANG64h}, - {"ANG105",ANG105}, - {"ANG210",ANG210}, - {"ANG255",ANG255}, - {"ANG340",ANG340}, - {"ANG350",ANG350}, - {"ANGLE_11hh",ANGLE_11hh}, - {"ANGLE_22h",ANGLE_22h}, - {"ANGLE_45",ANGLE_45}, - {"ANGLE_67h",ANGLE_67h}, - {"ANGLE_90",ANGLE_90}, - {"ANGLE_112h",ANGLE_112h}, - {"ANGLE_135",ANGLE_135}, - {"ANGLE_157h",ANGLE_157h}, - {"ANGLE_180",ANGLE_180}, - {"ANGLE_202h",ANGLE_202h}, - {"ANGLE_225",ANGLE_225}, - {"ANGLE_247h",ANGLE_247h}, - {"ANGLE_270",ANGLE_270}, - {"ANGLE_292h",ANGLE_292h}, - {"ANGLE_315",ANGLE_315}, - {"ANGLE_337h",ANGLE_337h}, - {"ANGLE_MAX",ANGLE_MAX}, + {"ANG1",ANG1>>16}, + {"ANG2",ANG2>>16}, + {"ANG10",ANG10>>16}, + {"ANG15",ANG15>>16}, + {"ANG20",ANG20>>16}, + {"ANG30",ANG30>>16}, + {"ANG60",ANG60>>16}, + {"ANG64h",ANG64h>>16}, + {"ANG105",ANG105>>16}, + {"ANG210",ANG210>>16}, + {"ANG255",ANG255>>16}, + {"ANG340",ANG340>>16}, + {"ANG350",ANG350>>16}, + {"ANGLE_11hh",ANGLE_11hh>>16}, + {"ANGLE_22h",ANGLE_22h>>16}, + {"ANGLE_45",ANGLE_45>>16}, + {"ANGLE_67h",ANGLE_67h>>16}, + {"ANGLE_90",ANGLE_90>>16}, + {"ANGLE_112h",ANGLE_112h>>16}, + {"ANGLE_135",ANGLE_135>>16}, + {"ANGLE_157h",ANGLE_157h>>16}, + {"ANGLE_180",ANGLE_180>>16}, + {"ANGLE_202h",ANGLE_202h>>16}, + {"ANGLE_225",ANGLE_225>>16}, + {"ANGLE_247h",ANGLE_247h>>16}, + {"ANGLE_270",ANGLE_270>>16}, + {"ANGLE_292h",ANGLE_292h>>16}, + {"ANGLE_315",ANGLE_315>>16}, + {"ANGLE_337h",ANGLE_337h>>16}, + {"ANGLE_MAX",ANGLE_MAX>>16}, // P_Chase directions (dirtype_t) {"DI_NODIR",DI_NODIR}, diff --git a/src/lua_baselib.c b/src/lua_baselib.c index ad5d740f8..d76839e73 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -85,13 +85,6 @@ static int lib_print(lua_State *L) return 0; } -static int lib_evalMath(lua_State *L) -{ - const char *word = luaL_checkstring(L, 1); - lua_pushinteger(L, LUA_EvalMath(word)); - return 1; -} - // M_RANDOM ////////////// @@ -138,25 +131,25 @@ static int lib_pRandomRange(lua_State *L) static int lib_pAproxDistance(lua_State *L) { - fixed_t dx = (fixed_t)luaL_checkinteger(L, 1); - fixed_t dy = (fixed_t)luaL_checkinteger(L, 2); + fixed_t dx = luaL_checkfixed(L, 1); + fixed_t dy = luaL_checkfixed(L, 2); //HUDSAFE - lua_pushinteger(L, P_AproxDistance(dx, dy)); + lua_pushfixed(L, P_AproxDistance(dx, dy)); return 1; } static int lib_pClosestPointOnLine(lua_State *L) { - fixed_t x = (fixed_t)luaL_checkinteger(L, 1); - fixed_t y = (fixed_t)luaL_checkinteger(L, 2); + fixed_t x = luaL_checkfixed(L, 1); + fixed_t y = luaL_checkfixed(L, 2); line_t *line = *((line_t **)luaL_checkudata(L, 3, META_LINE)); vertex_t result; //HUDSAFE if (!line) return LUA_ErrInvalid(L, "line_t"); P_ClosestPointOnLine(x, y, line, &result); - lua_pushinteger(L, result.x); - lua_pushinteger(L, result.y); + lua_pushfixed(L, result.x); + lua_pushfixed(L, result.y); return 2; } @@ -241,9 +234,9 @@ static int lib_pLookForPlayers(lua_State *L) static int lib_pSpawnMobj(lua_State *L) { - fixed_t x = (fixed_t)luaL_checkinteger(L, 1); - fixed_t y = (fixed_t)luaL_checkinteger(L, 2); - fixed_t z = (fixed_t)luaL_checkinteger(L, 3); + fixed_t x = luaL_checkfixed(L, 1); + fixed_t y = luaL_checkfixed(L, 2); + fixed_t z = luaL_checkfixed(L, 3); mobjtype_t type = luaL_checkinteger(L, 4); NOHUD if (type > MT_LASTFREESLOT) @@ -283,9 +276,9 @@ static int lib_pSpawnXYZMissile(lua_State *L) mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *dest = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); mobjtype_t type = luaL_checkinteger(L, 3); - fixed_t x = (fixed_t)luaL_checkinteger(L, 4); - fixed_t y = (fixed_t)luaL_checkinteger(L, 5); - fixed_t z = (fixed_t)luaL_checkinteger(L, 6); + fixed_t x = luaL_checkfixed(L, 4); + fixed_t y = luaL_checkfixed(L, 5); + fixed_t z = luaL_checkfixed(L, 6); NOHUD if (!source || !dest) return LUA_ErrInvalid(L, "mobj_t"); @@ -298,13 +291,13 @@ static int lib_pSpawnXYZMissile(lua_State *L) static int lib_pSpawnPointMissile(lua_State *L) { mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); - fixed_t xa = (fixed_t)luaL_checkinteger(L, 2); - fixed_t ya = (fixed_t)luaL_checkinteger(L, 3); - fixed_t za = (fixed_t)luaL_checkinteger(L, 4); + fixed_t xa = luaL_checkfixed(L, 2); + fixed_t ya = luaL_checkfixed(L, 3); + fixed_t za = luaL_checkfixed(L, 4); mobjtype_t type = luaL_checkinteger(L, 5); - fixed_t x = (fixed_t)luaL_checkinteger(L, 6); - fixed_t y = (fixed_t)luaL_checkinteger(L, 7); - fixed_t z = (fixed_t)luaL_checkinteger(L, 8); + fixed_t x = luaL_checkfixed(L, 6); + fixed_t y = luaL_checkfixed(L, 7); + fixed_t z = luaL_checkfixed(L, 8); NOHUD if (!source) return LUA_ErrInvalid(L, "mobj_t"); @@ -318,9 +311,9 @@ static int lib_pSpawnAlteredDirectionMissile(lua_State *L) { mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobjtype_t type = luaL_checkinteger(L, 2); - fixed_t x = (fixed_t)luaL_checkinteger(L, 3); - fixed_t y = (fixed_t)luaL_checkinteger(L, 4); - fixed_t z = (fixed_t)luaL_checkinteger(L, 5); + fixed_t x = luaL_checkfixed(L, 3); + fixed_t y = luaL_checkfixed(L, 4); + fixed_t z = luaL_checkfixed(L, 5); INT32 shiftingAngle = (INT32)luaL_checkinteger(L, 5); NOHUD if (!source) @@ -348,7 +341,7 @@ static int lib_pSPMAngle(lua_State *L) { mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobjtype_t type = luaL_checkinteger(L, 2); - angle_t angle = (angle_t)luaL_checkinteger(L, 3); + angle_t angle = luaL_checkangle(L, 3); UINT8 allowaim = (UINT8)luaL_optinteger(L, 4, 0); UINT32 flags2 = (UINT32)luaL_optinteger(L, 5, 0); NOHUD @@ -418,13 +411,13 @@ static int lib_pGetClosestAxis(lua_State *L) static int lib_pSpawnParaloop(lua_State *L) { - fixed_t x = (fixed_t)luaL_checkinteger(L, 1); - fixed_t y = (fixed_t)luaL_checkinteger(L, 2); - fixed_t z = (fixed_t)luaL_checkinteger(L, 3); - fixed_t radius = (fixed_t)luaL_checkinteger(L, 4); + fixed_t x = luaL_checkfixed(L, 1); + fixed_t y = luaL_checkfixed(L, 2); + fixed_t z = luaL_checkfixed(L, 3); + fixed_t radius = luaL_checkfixed(L, 4); INT32 number = (INT32)luaL_checkinteger(L, 5); mobjtype_t type = luaL_checkinteger(L, 6); - angle_t rotangle = (angle_t)luaL_checkinteger(L, 7); + angle_t rotangle = luaL_checkangle(L, 7); statenum_t nstate = luaL_optinteger(L, 8, S_NULL); boolean spawncenter = lua_optboolean(L, 9); NOHUD @@ -458,7 +451,7 @@ static int lib_pSupermanLook4Players(lua_State *L) static int lib_pSetScale(lua_State *L) { mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); - fixed_t newscale = (fixed_t)luaL_checkinteger(L, 2); + fixed_t newscale = luaL_checkfixed(L, 2); NOHUD if (!mobj) return LUA_ErrInvalid(L, "mobj_t"); @@ -526,7 +519,7 @@ static int lib_pGetPlayerHeight(lua_State *L) //HUDSAFE if (!player) return LUA_ErrInvalid(L, "player_t"); - lua_pushinteger(L, P_GetPlayerHeight(player)); + lua_pushfixed(L, P_GetPlayerHeight(player)); return 1; } @@ -536,7 +529,7 @@ static int lib_pGetPlayerSpinHeight(lua_State *L) //HUDSAFE if (!player) return LUA_ErrInvalid(L, "player_t"); - lua_pushinteger(L, P_GetPlayerSpinHeight(player)); + lua_pushfixed(L, P_GetPlayerSpinHeight(player)); return 1; } @@ -639,7 +632,7 @@ static int lib_pInQuicksand(lua_State *L) static int lib_pSetObjectMomZ(lua_State *L) { mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); - fixed_t value = (fixed_t)luaL_checkinteger(L, 2); + fixed_t value = luaL_checkfixed(L, 2); boolean relative = lua_optboolean(L, 3); NOHUD if (!mo) @@ -753,8 +746,8 @@ static int lib_pDoPlayerExit(lua_State *L) static int lib_pInstaThrust(lua_State *L) { mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); - angle_t angle = (angle_t)luaL_checkinteger(L, 2); - fixed_t move = (fixed_t)luaL_checkinteger(L, 3); + angle_t angle = luaL_checkangle(L, 2); + fixed_t move = luaL_checkfixed(L, 3); NOHUD if (!mo) return LUA_ErrInvalid(L, "mobj_t"); @@ -768,10 +761,10 @@ static int lib_pReturnThrustX(lua_State *L) fixed_t move; if (lua_isnil(L, 1) || lua_isuserdata(L, 1)) lua_remove(L, 1); // ignore mobj as arg1 - angle = (angle_t)luaL_checkinteger(L, 1); - move = (fixed_t)luaL_checkinteger(L, 2); + angle = luaL_checkangle(L, 1); + move = luaL_checkfixed(L, 2); //HUDSAFE - lua_pushinteger(L, P_ReturnThrustX(NULL, angle, move)); + lua_pushfixed(L, P_ReturnThrustX(NULL, angle, move)); return 1; } @@ -781,10 +774,10 @@ static int lib_pReturnThrustY(lua_State *L) fixed_t move; if (lua_isnil(L, 1) || lua_isuserdata(L, 1)) lua_remove(L, 1); // ignore mobj as arg1 - angle = (angle_t)luaL_checkinteger(L, 1); - move = (fixed_t)luaL_checkinteger(L, 2); + angle = luaL_checkangle(L, 1); + move = luaL_checkfixed(L, 2); //HUDSAFE - lua_pushinteger(L, P_ReturnThrustY(NULL, angle, move)); + lua_pushfixed(L, P_ReturnThrustY(NULL, angle, move)); return 1; } @@ -802,7 +795,7 @@ static int lib_pNukeEnemies(lua_State *L) { mobj_t *inflictor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *source = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); - fixed_t radius = (fixed_t)luaL_checkinteger(L, 3); + fixed_t radius = luaL_checkfixed(L, 3); NOHUD if (!inflictor || !source) return LUA_ErrInvalid(L, "mobj_t"); @@ -868,8 +861,8 @@ static int lib_pSpawnSpinMobj(lua_State *L) static int lib_pTelekinesis(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); - fixed_t thrust = (fixed_t)luaL_checkinteger(L, 2); - fixed_t range = (fixed_t)luaL_checkinteger(L, 3); + fixed_t thrust = luaL_checkfixed(L, 2); + fixed_t range = luaL_checkfixed(L, 3); NOHUD if (!player) return LUA_ErrInvalid(L, "player_t"); @@ -884,8 +877,8 @@ static int lib_pCheckPosition(lua_State *L) { mobj_t *ptmthing = tmthing; mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); - fixed_t x = (fixed_t)luaL_checkinteger(L, 2); - fixed_t y = (fixed_t)luaL_checkinteger(L, 3); + fixed_t x = luaL_checkfixed(L, 2); + fixed_t y = luaL_checkfixed(L, 3); NOHUD if (!thing) return LUA_ErrInvalid(L, "mobj_t"); @@ -899,8 +892,8 @@ static int lib_pTryMove(lua_State *L) { mobj_t *ptmthing = tmthing; mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); - fixed_t x = (fixed_t)luaL_checkinteger(L, 2); - fixed_t y = (fixed_t)luaL_checkinteger(L, 3); + fixed_t x = luaL_checkfixed(L, 2); + fixed_t y = luaL_checkfixed(L, 3); boolean allowdropoff = lua_optboolean(L, 4); NOHUD if (!thing) @@ -915,7 +908,7 @@ static int lib_pMove(lua_State *L) { mobj_t *ptmthing = tmthing; mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); - fixed_t speed = (fixed_t)luaL_checkinteger(L, 2); + fixed_t speed = luaL_checkfixed(L, 2); NOHUD if (!actor) return LUA_ErrInvalid(L, "mobj_t"); @@ -929,9 +922,9 @@ static int lib_pTeleportMove(lua_State *L) { mobj_t *ptmthing = tmthing; mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); - fixed_t x = (fixed_t)luaL_checkinteger(L, 2); - fixed_t y = (fixed_t)luaL_checkinteger(L, 3); - fixed_t z = (fixed_t)luaL_checkinteger(L, 4); + fixed_t x = luaL_checkfixed(L, 2); + fixed_t y = luaL_checkfixed(L, 3); + fixed_t z = luaL_checkfixed(L, 4); NOHUD if (!thing) return LUA_ErrInvalid(L, "mobj_t"); @@ -975,10 +968,10 @@ static int lib_pCheckSight(lua_State *L) static int lib_pCheckHoopPosition(lua_State *L) { mobj_t *hoopthing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); - fixed_t x = (fixed_t)luaL_checkinteger(L, 2); - fixed_t y = (fixed_t)luaL_checkinteger(L, 3); - fixed_t z = (fixed_t)luaL_checkinteger(L, 4); - fixed_t radius = (fixed_t)luaL_checkinteger(L, 5); + fixed_t x = luaL_checkfixed(L, 2); + fixed_t y = luaL_checkfixed(L, 3); + fixed_t z = luaL_checkfixed(L, 4); + fixed_t radius = luaL_checkfixed(L, 5); NOHUD if (!hoopthing) return LUA_ErrInvalid(L, "mobj_t"); @@ -990,7 +983,7 @@ static int lib_pRadiusAttack(lua_State *L) { mobj_t *spot = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *source = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); - fixed_t damagedist = (fixed_t)luaL_checkinteger(L, 3); + fixed_t damagedist = luaL_checkfixed(L, 3); NOHUD if (!spot || !source) return LUA_ErrInvalid(L, "mobj_t"); @@ -1000,12 +993,12 @@ static int lib_pRadiusAttack(lua_State *L) static int lib_pFloorzAtPos(lua_State *L) { - fixed_t x = (fixed_t)luaL_checkinteger(L, 1); - fixed_t y = (fixed_t)luaL_checkinteger(L, 2); - fixed_t z = (fixed_t)luaL_checkinteger(L, 3); - fixed_t height = (fixed_t)luaL_checkinteger(L, 4); + fixed_t x = luaL_checkfixed(L, 1); + fixed_t y = luaL_checkfixed(L, 2); + fixed_t z = luaL_checkfixed(L, 3); + fixed_t height = luaL_checkfixed(L, 4); //HUDSAFE - lua_pushinteger(L, P_FloorzAtPos(x, y, z, height)); + lua_pushfixed(L, P_FloorzAtPos(x, y, z, height)); return 1; } @@ -1209,8 +1202,8 @@ static int lib_pDoNightsScore(lua_State *L) static int lib_pThrust(lua_State *L) { mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); - angle_t angle = (angle_t)luaL_checkinteger(L, 2); - fixed_t move = (fixed_t)luaL_checkinteger(L, 3); + angle_t angle = luaL_checkangle(L, 2); + fixed_t move = luaL_checkfixed(L, 3); NOHUD if (!mo) return LUA_ErrInvalid(L, "mobj_t"); @@ -1485,48 +1478,48 @@ static int lib_evCrumbleChain(lua_State *L) static int lib_rPointToAngle(lua_State *L) { - fixed_t x = (fixed_t)luaL_checkinteger(L, 1); - fixed_t y = (fixed_t)luaL_checkinteger(L, 2); + fixed_t x = luaL_checkfixed(L, 1); + fixed_t y = luaL_checkfixed(L, 2); //HUDSAFE - lua_pushinteger(L, R_PointToAngle(x, y)); + lua_pushangle(L, R_PointToAngle(x, y)); return 1; } static int lib_rPointToAngle2(lua_State *L) { - fixed_t px2 = (fixed_t)luaL_checkinteger(L, 1); - fixed_t py2 = (fixed_t)luaL_checkinteger(L, 2); - fixed_t px1 = (fixed_t)luaL_checkinteger(L, 3); - fixed_t py1 = (fixed_t)luaL_checkinteger(L, 4); + fixed_t px2 = luaL_checkfixed(L, 1); + fixed_t py2 = luaL_checkfixed(L, 2); + fixed_t px1 = luaL_checkfixed(L, 3); + fixed_t py1 = luaL_checkfixed(L, 4); //HUDSAFE - lua_pushinteger(L, R_PointToAngle2(px2, py2, px1, py1)); + lua_pushangle(L, R_PointToAngle2(px2, py2, px1, py1)); return 1; } static int lib_rPointToDist(lua_State *L) { - fixed_t x = (fixed_t)luaL_checkinteger(L, 1); - fixed_t y = (fixed_t)luaL_checkinteger(L, 2); + fixed_t x = luaL_checkfixed(L, 1); + fixed_t y = luaL_checkfixed(L, 2); //HUDSAFE - lua_pushinteger(L, R_PointToDist(x, y)); + lua_pushfixed(L, R_PointToDist(x, y)); return 1; } static int lib_rPointToDist2(lua_State *L) { - fixed_t px2 = (fixed_t)luaL_checkinteger(L, 1); - fixed_t py2 = (fixed_t)luaL_checkinteger(L, 2); - fixed_t px1 = (fixed_t)luaL_checkinteger(L, 3); - fixed_t py1 = (fixed_t)luaL_checkinteger(L, 4); + fixed_t px2 = luaL_checkfixed(L, 1); + fixed_t py2 = luaL_checkfixed(L, 2); + fixed_t px1 = luaL_checkfixed(L, 3); + fixed_t py1 = luaL_checkfixed(L, 4); //HUDSAFE - lua_pushinteger(L, R_PointToDist2(px2, py2, px1, py1)); + lua_pushfixed(L, R_PointToDist2(px2, py2, px1, py1)); return 1; } static int lib_rPointInSubsector(lua_State *L) { - fixed_t x = (fixed_t)luaL_checkinteger(L, 1); - fixed_t y = (fixed_t)luaL_checkinteger(L, 2); + fixed_t x = luaL_checkfixed(L, 1); + fixed_t y = luaL_checkfixed(L, 2); //HUDSAFE LUA_PushUserdata(L, R_PointInSubsector(x, y), META_SUBSECTOR); return 1; @@ -1660,7 +1653,7 @@ static int lib_sChangeMusic(lua_State *L) static int lib_sSpeedMusic(lua_State *L) { - fixed_t fixedspeed = (fixed_t)luaL_checkinteger(L, 1); + fixed_t fixedspeed = luaL_checkfixed(L, 1); float speed = FIXED_TO_FLOAT(fixedspeed); player_t *player = NULL; NOHUD @@ -1861,7 +1854,6 @@ static int lib_gTicsToMilliseconds(lua_State *L) static luaL_Reg lib[] = { {"print", lib_print}, - {"EvalMath", lib_evalMath}, // m_random {"P_Random",lib_pRandom}, diff --git a/src/lua_hook.h b/src/lua_hook.h index fae3bb7e6..da2dcdc38 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -41,7 +41,7 @@ enum hook { hook_BotAI, hook_LinedefExecute, hook_PlayerMsg, - hook_DeathMsg, + hook_HurtMsg, hook_MAX // last hook }; @@ -54,8 +54,9 @@ void LUAh_ThinkFrame(void); // Hook for frame (after mobj and player thinkers) boolean LUAh_MobjHook(mobj_t *mo, enum hook which); boolean LUAh_PlayerHook(player_t *plr, enum hook which); #define LUAh_MobjSpawn(mo) LUAh_MobjHook(mo, hook_MobjSpawn) // Hook for P_SpawnMobj by mobj type -UINT8 LUAh_MobjCollide(mobj_t *thing1, mobj_t *thing2); // Hook for PIT_CheckThing by (thing) mobj type -UINT8 LUAh_MobjMoveCollide(mobj_t *thing1, mobj_t *thing2); // Hook for PIT_CheckThing by (tmthing) mobj type +UINT8 LUAh_MobjCollideHook(mobj_t *thing1, mobj_t *thing2, enum hook which); +#define LUAh_MobjCollide(thing1, thing2) LUAh_MobjCollideHook(thing1, thing2, hook_MobjCollide) // Hook for PIT_CheckThing by (thing) mobj type +#define LUAh_MobjMoveCollide(thing1, thing2) LUAh_MobjCollideHook(thing1, thing2, hook_MobjMoveCollide) // Hook for PIT_CheckThing by (tmthing) mobj type boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher); // Hook for P_TouchSpecialThing by mobj type #define LUAh_MobjFuse(mo) LUAh_MobjHook(mo, hook_MobjFuse) // Hook for mobj->fuse == 0 by mobj type #define LUAh_MobjThinker(mo) LUAh_MobjHook(mo, hook_MobjThinker) // Hook for P_MobjThinker or P_SceneryThinker by mobj type @@ -73,6 +74,6 @@ boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd); // Hook for B_BuildTiccmd boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd); // Hook for B_BuildTailsTiccmd by skin name boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector); // Hook for linedef executors boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg); // Hook for chat messages -boolean LUAh_DeathMsg(player_t *player, mobj_t *inflictor, mobj_t *source); // Hook for hurt messages +boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source); // Hook for hurt messages #endif diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 532726ac2..0415d23e6 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -56,23 +56,40 @@ const char *const hookNames[hook_MAX+1] = { NULL }; +// Hook metadata +struct hook_s +{ + struct hook_s *next; + enum hook type; + UINT16 id; + union { + mobjtype_t mt; + char *skinname; + char *funcname; + } s; + boolean error; +}; +typedef struct hook_s* hook_p; + +#define FMT_HOOKID "hook_%d" + +hook_p roothook; + // Takes hook, function, and additional arguments (mobj type to act on, etc.) static int lib_addHook(lua_State *L) { - UINT16 hook; - boolean notable = false; - boolean subtable = false; - UINT32 subindex = 0; - char *subfield = NULL; - const char *lsubfield = NULL; + static struct hook_s hook = {NULL, 0, 0, {0}, false}; + hook_p hookp, *lastp; - hook = (UINT16)luaL_checkoption(L, 1, NULL, hookNames); - luaL_checktype(L, 2, LUA_TFUNCTION); + hook.type = luaL_checkoption(L, 1, NULL, hookNames); + lua_remove(L, 1); + + luaL_checktype(L, 1, LUA_TFUNCTION); if (hud_running) return luaL_error(L, "HUD rendering code should not call this function!"); - switch(hook) + switch(hook.type) { // Take a mobjtype enum which this hook is specifically for. case hook_MobjSpawn: @@ -87,918 +104,668 @@ static int lib_addHook(lua_State *L) case hook_MobjDeath: case hook_BossDeath: case hook_MobjRemoved: - subtable = true; - if (lua_isnumber(L, 3)) - subindex = (UINT32)luaL_checkinteger(L, 3); - else - lsubfield = "a"; - lua_settop(L, 2); + case hook_HurtMsg: + hook.s.mt = MT_NULL; + if (lua_isnumber(L, 2)) + hook.s.mt = lua_tonumber(L, 2); break; - case hook_BotAI: // Only one AI function per skin, please! - notable = true; - subtable = true; - subfield = ZZ_Alloc(strlen(luaL_checkstring(L, 3))+1); + case hook_BotAI: + hook.s.skinname = NULL; + if (lua_isstring(L, 2)) { // lowercase copy - char *p = subfield; - const char *s = luaL_checkstring(L, 3); + const char *s = lua_tostring(L, 2); + char *p = hook.s.skinname = ZZ_Alloc(strlen(s)+1); do { *p = tolower(*s); ++p; } while(*(++s)); *p = 0; } - lua_settop(L, 3); break; - case hook_LinedefExecute: // Get one linedef executor function by name - notable = true; - subtable = true; - subfield = ZZ_Alloc(strlen(luaL_checkstring(L, 3))+1); + case hook_LinedefExecute: // Linedef executor functions { // uppercase copy - char *p = subfield; - const char *s = luaL_checkstring(L, 3); + const char *s = luaL_checkstring(L, 2); + char *p = hook.s.funcname = ZZ_Alloc(strlen(s)+1); do { *p = toupper(*s); ++p; } while(*(++s)); *p = 0; } - lua_settop(L, 3); break; default: - lua_settop(L, 2); break; } + lua_settop(L, 1); // lua stack contains only the function now. - lua_getfield(L, LUA_REGISTRYINDEX, "hook"); - I_Assert(lua_istable(L, -1)); + hooksAvailable[hook.type/8] |= 1<<(hook.type%8); - // This hook type only allows one entry, not an array of hooks. - // New hooks will overwrite the previous ones, and the stack is one table shorter. - if (notable) + // iterate the hook metadata structs + // set hook.id to the highest id + 1 + // set lastp to the last hook struct's "next" pointer. + lastp = &roothook; + hook.id = 0; + for (hookp = roothook; hookp; hookp = hookp->next) { - if (subtable) - { - lua_rawgeti(L, -1, hook); - lua_remove(L, -2); // pop "hook" - I_Assert(lua_istable(L, -1)); - lua_pushvalue(L, 2); - if (subfield) - lua_setfield(L, -2, subfield); - else if (lsubfield) - lua_setfield(L, -2, lsubfield); - else - lua_rawseti(L, -2, subindex); - } else { - lua_pushvalue(L, 2); - lua_rawseti(L, -2, hook); - } - hooksAvailable[hook/8] |= 1<<(hook%8); - return 0; + if (hookp->id >= hook.id) + hook.id = hookp->id+1; + lastp = &hookp->next; } - // Fetch the hook's table from the registry. - // It should always exist, since LUA_HookLib creates a table for every hook. - lua_rawgeti(L, -1, hook); - lua_remove(L, -2); // pop "hook" - I_Assert(lua_istable(L, -1)); - if (subtable) - { - // Fetch a subtable based on index - if (subfield) - lua_getfield(L, -1, subfield); - else if (lsubfield) - lua_getfield(L, -1, lsubfield); - else - lua_rawgeti(L, -1, subindex); + // allocate a permanent memory struct to stuff hook. + hookp = ZZ_Alloc(sizeof(struct hook_s)); + memcpy(hookp, &hook, sizeof(struct hook_s)); + // tack it onto the end of the linked list. + *lastp = hookp; - // Subtable doesn't exist, make one now. - if (lua_isnil(L, -1)) - { - lua_pop(L, 1); - lua_newtable(L); - - // Store a link to the subtable for later. - lua_pushvalue(L, -1); - if (subfield) - lua_setfield(L, -3, subfield); - else if (lsubfield) - lua_setfield(L, -3, lsubfield); - else - lua_rawseti(L, -3, subindex); - } } - - // Add function to the table. - lua_pushvalue(L, 2); - lua_rawseti(L, -2, (int)(lua_objlen(L, -2) + 1)); - - if (subfield) - Z_Free(subfield); - - hooksAvailable[hook/8] |= 1<<(hook%8); + // set the hook function in the registry. + lua_pushfstring(L, FMT_HOOKID, hook.id); + lua_pushvalue(L, 1); + lua_settable(L, LUA_REGISTRYINDEX); return 0; } int LUA_HookLib(lua_State *L) { - // Create all registry tables - enum hook i; memset(hooksAvailable,0,sizeof(UINT8[(hook_MAX/8)+1])); - - lua_newtable(L); - for (i = 0; i < hook_MAX; i++) - { - lua_newtable(L); - switch(i) - { - default: - break; - case hook_MobjSpawn: - case hook_MobjCollide: - case hook_MobjMoveCollide: - case hook_TouchSpecial: - case hook_MobjFuse: - case hook_MobjThinker: - case hook_BossThinker: - case hook_ShouldDamage: - case hook_MobjDamage: - case hook_MobjDeath: - case hook_BossDeath: - case hook_MobjRemoved: - lua_pushstring(L, "a"); - lua_newtable(L); - lua_rawset(L, -3); - break; - } - lua_rawseti(L, -2, i); - } - lua_setfield(L, LUA_REGISTRYINDEX, "hook"); + roothook = NULL; lua_register(L, "addHook", lib_addHook); return 0; } boolean LUAh_MobjHook(mobj_t *mo, enum hook which) { + hook_p hookp; boolean hooked = false; if (!gL || !(hooksAvailable[which/8] & (1<<(which%8)))) return false; - // clear the stack (just in case) - lua_pop(gL, -1); + lua_settop(gL, 0); - // hook table - lua_getfield(gL, LUA_REGISTRYINDEX, "hook"); - I_Assert(lua_istable(gL, -1)); - lua_rawgeti(gL, -1, which); - lua_remove(gL, -2); - I_Assert(lua_istable(gL, -1)); - - // generic subtable - lua_pushstring(gL, "a"); - lua_rawget(gL, -2); - I_Assert(lua_istable(gL, -1)); - - LUA_PushUserdata(gL, mo, META_MOBJ); - lua_pushnil(gL); - while (lua_next(gL, -3)) { - CONS_Debug(DBG_LUA, "MobjHook: Calling hook_%s for generic mobj types\n", hookNames[which]); - lua_pushvalue(gL, -3); // mo - // stack is: hook_Mobj table, subtable "a", mobj, i, function, mobj - if (lua_pcall(gL, 1, 1, 0)) { - // A run-time error occurred. - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); - lua_pop(gL, 1); - // Remove this function from the hook table to prevent further errors. - lua_pushvalue(gL, -1); // key - lua_pushnil(gL); // value - lua_rawset(gL, -5); // table - CONS_Printf("Hook removed.\n"); - } - else + for (hookp = roothook; hookp; hookp = hookp->next) + if (hookp->type == which + && (hookp->s.mt == MT_NULL || hookp->s.mt == mo->type)) { + if (lua_gettop(gL) == 0) + LUA_PushUserdata(gL, mo, META_MOBJ); + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -2); + if (lua_pcall(gL, 1, 1, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } if (lua_toboolean(gL, -1)) hooked = true; lua_pop(gL, 1); } - } - // stack is: hook_Mobj table, subtable "a", mobj - lua_remove(gL, -2); // pop subtable, leave mobj - // mobjtype subtable - // stack is: hook_Mobj table, mobj - lua_rawgeti(gL, -2, mo->type); - if (lua_isnil(gL, -1)) { - lua_pop(gL, 3); // pop hook_Mobj table, mobj, and nil - // the stack should now be empty. - return false; - } - lua_remove(gL, -3); // remove hook table - // stack is: mobj, mobjtype subtable - lua_insert(gL, lua_gettop(gL)-1); // swap subtable with mobj - // stack is: mobjtype subtable, mobj - - lua_pushnil(gL); - while (lua_next(gL, -3)) { - CONS_Debug(DBG_LUA, "MobjHook: Calling hook_%s for mobj type %d\n", hookNames[which], mo->type); - lua_pushvalue(gL, -3); // mo - // stack is: mobjtype subtable, mobj, i, function, mobj - if (lua_pcall(gL, 1, 1, 0)) { - // A run-time error occurred. - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); - lua_pop(gL, 1); - // Remove this function from the hook table to prevent further errors. - lua_pushvalue(gL, -1); // key - lua_pushnil(gL); // value - lua_rawset(gL, -5); // table - CONS_Printf("Hook removed.\n"); - } - else - { - if (lua_toboolean(gL, -1)) - hooked = true; - lua_pop(gL, 1); - } - } - - lua_pop(gL, 2); // pop mobj and subtable - // the stack should now be empty. - - lua_gc(gL, LUA_GCSTEP, 3); + lua_settop(gL, 0); return hooked; } boolean LUAh_PlayerHook(player_t *plr, enum hook which) { + hook_p hookp; boolean hooked = false; if (!gL || !(hooksAvailable[which/8] & (1<<(which%8)))) return false; - // clear the stack (just in case) - lua_pop(gL, -1); + lua_settop(gL, 0); - // hook table - lua_getfield(gL, LUA_REGISTRYINDEX, "hook"); - I_Assert(lua_istable(gL, -1)); - lua_rawgeti(gL, -1, which); - lua_remove(gL, -2); - I_Assert(lua_istable(gL, -1)); - - LUA_PushUserdata(gL, plr, META_PLAYER); - - lua_pushnil(gL); - while (lua_next(gL, -3) != 0) { - lua_pushvalue(gL, -3); // player - if (lua_pcall(gL, 1, 1, 0)) { // pops hook function, player, pushes 1 return result - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); + for (hookp = roothook; hookp; hookp = hookp->next) + if (hookp->type == which) + { + if (lua_gettop(gL) == 0) + LUA_PushUserdata(gL, plr, META_PLAYER); + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -2); + if (lua_pcall(gL, 1, 1, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (lua_toboolean(gL, -1)) + hooked = true; lua_pop(gL, 1); - continue; } - if (lua_toboolean(gL, -1)) // if return true, - hooked = true; // override vanilla behavior - lua_pop(gL, 1); // pop return value - } - lua_pop(gL, -1); - lua_gc(gL, LUA_GCSTEP, 1); + lua_settop(gL, 0); return hooked; } // Hook for map change (before load) void LUAh_MapChange(void) { + hook_p hookp; if (!gL || !(hooksAvailable[hook_MapChange/8] & (1<<(hook_MapChange%8)))) return; - lua_getfield(gL, LUA_REGISTRYINDEX, "hook"); - I_Assert(lua_istable(gL, -1)); - lua_rawgeti(gL, -1, hook_MapChange); - lua_remove(gL, -2); - I_Assert(lua_istable(gL, -1)); - + lua_settop(gL, 0); lua_pushinteger(gL, gamemap); - lua_pushnil(gL); - while (lua_next(gL, -3) != 0) { - lua_pushvalue(gL, -3); // gamemap - LUA_Call(gL, 1); - } - lua_pop(gL, 1); - lua_gc(gL, LUA_GCSTEP, 1); + + for (hookp = roothook; hookp; hookp = hookp->next) + if (hookp->type == hook_MapChange) + { + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -2); + LUA_Call(gL, 1); + } + + lua_settop(gL, 0); } // Hook for map load void LUAh_MapLoad(void) { + hook_p hookp; if (!gL || !(hooksAvailable[hook_MapLoad/8] & (1<<(hook_MapLoad%8)))) return; - lua_pop(gL, -1); - - lua_getfield(gL, LUA_REGISTRYINDEX, "hook"); - I_Assert(lua_istable(gL, -1)); - lua_rawgeti(gL, -1, hook_MapLoad); - lua_remove(gL, -2); - I_Assert(lua_istable(gL, -1)); - + lua_settop(gL, 0); lua_pushinteger(gL, gamemap); - lua_pushnil(gL); - while (lua_next(gL, -3) != 0) { - lua_pushvalue(gL, -3); // gamemap - LUA_Call(gL, 1); - } - lua_pop(gL, -1); - lua_gc(gL, LUA_GCCOLLECT, 0); + + for (hookp = roothook; hookp; hookp = hookp->next) + if (hookp->type == hook_MapLoad) + { + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -2); + LUA_Call(gL, 1); + } + + lua_settop(gL, 0); } // Hook for Got_AddPlayer void LUAh_PlayerJoin(int playernum) { + hook_p hookp; if (!gL || !(hooksAvailable[hook_PlayerJoin/8] & (1<<(hook_PlayerJoin%8)))) return; - lua_pop(gL, -1); - - lua_getfield(gL, LUA_REGISTRYINDEX, "hook"); - I_Assert(lua_istable(gL, -1)); - lua_rawgeti(gL, -1, hook_PlayerJoin); - lua_remove(gL, -2); - I_Assert(lua_istable(gL, -1)); - + lua_settop(gL, 0); lua_pushinteger(gL, playernum); - lua_pushnil(gL); - while (lua_next(gL, -3) != 0) { - lua_pushvalue(gL, -3); // playernum - LUA_Call(gL, 1); - } - lua_pop(gL, -1); - lua_gc(gL, LUA_GCCOLLECT, 0); + + for (hookp = roothook; hookp; hookp = hookp->next) + if (hookp->type == hook_PlayerJoin) + { + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -2); + LUA_Call(gL, 1); + } + + lua_settop(gL, 0); } // Hook for frame (after mobj and player thinkers) void LUAh_ThinkFrame(void) { + hook_p hookp; if (!gL || !(hooksAvailable[hook_ThinkFrame/8] & (1<<(hook_ThinkFrame%8)))) return; - lua_pop(gL, -1); - - lua_getfield(gL, LUA_REGISTRYINDEX, "hook"); - I_Assert(lua_istable(gL, -1)); - lua_rawgeti(gL, -1, hook_ThinkFrame); - lua_remove(gL, -2); - I_Assert(lua_istable(gL, -1)); - - lua_pushnil(gL); - while (lua_next(gL, -2) != 0) - { - //LUA_Call(gL, 0); - if (lua_pcall(gL, 0, 0, 0)) + for (hookp = roothook; hookp; hookp = hookp->next) + if (hookp->type == hook_ThinkFrame) { - // A run-time error occurred. - CONS_Alert(CONS_WARNING,"%s\n", lua_tostring(gL, -1)); - lua_pop(gL, 1); - // Remove this function from the hook table to prevent further errors. - lua_pushvalue(gL, -1); // key - lua_pushnil(gL); // value - lua_rawset(gL, -4); // table - CONS_Printf("Hook removed.\n"); + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + if (lua_pcall(gL, 0, 0, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + } } - } - lua_pop(gL, -1); - lua_gc(gL, LUA_GCCOLLECT, 0); } -// Hook for PIT_CheckThing by (thing) mobj type (thing1 = thing, thing2 = tmthing) -UINT8 LUAh_MobjCollide(mobj_t *thing1, mobj_t *thing2) +// Hook for mobj collisions +UINT8 LUAh_MobjCollideHook(mobj_t *thing1, mobj_t *thing2, enum hook which) { + hook_p hookp; UINT8 shouldCollide = 0; // 0 = default, 1 = force yes, 2 = force no. - if (!gL || !(hooksAvailable[hook_MobjCollide/8] & (1<<(hook_MobjCollide%8)))) + if (!gL || !(hooksAvailable[which/8] & (1<<(which%8)))) return 0; - // clear the stack - lua_pop(gL, -1); + lua_settop(gL, 0); - // hook table - lua_getfield(gL, LUA_REGISTRYINDEX, "hook"); - I_Assert(lua_istable(gL, -1)); - lua_rawgeti(gL, -1, hook_MobjCollide); - lua_remove(gL, -2); - I_Assert(lua_istable(gL, -1)); - - // mobjtype subtable - lua_rawgeti(gL, -1, thing1->type); - if (lua_isnil(gL, -1)) { - lua_pop(gL, 2); - return 0; - } - lua_remove(gL, -2); // remove hook table - - LUA_PushUserdata(gL, thing1, META_MOBJ); - LUA_PushUserdata(gL, thing2, META_MOBJ); - lua_pushnil(gL); - while (lua_next(gL, -4)) { - lua_pushvalue(gL, -4); // thing1 - lua_pushvalue(gL, -4); // thing2 - if (lua_pcall(gL, 2, 1, 0)) { - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); + for (hookp = roothook; hookp; hookp = hookp->next) + if (hookp->type == which + && (hookp->s.mt == MT_NULL || hookp->s.mt == thing1->type)) + { + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, thing1, META_MOBJ); + LUA_PushUserdata(gL, thing2, META_MOBJ); + } + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -3); + lua_pushvalue(gL, -3); + if (lua_pcall(gL, 2, 1, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (!lua_isnil(gL, -1)) + { // if nil, leave shouldCollide = 0. + if (lua_toboolean(gL, -1)) + shouldCollide = 1; // Force yes + else + shouldCollide = 2; // Force no + } lua_pop(gL, 1); - continue; } - if (!lua_isnil(gL, -1)) - { // if nil, leave shouldCollide = 0. - if (lua_toboolean(gL, -1)) - shouldCollide = 1; // Force yes - else - shouldCollide = 2; // Force no - } - lua_pop(gL, 1); // pop return value - } - lua_pop(gL, 3); // pop arguments and mobjtype table - lua_gc(gL, LUA_GCSTEP, 1); - return shouldCollide; -} - -// Hook for PIT_CheckThing by (tmthing) mobj type (thing1 = tmthing, thing2 = thing) -UINT8 LUAh_MobjMoveCollide(mobj_t *thing1, mobj_t *thing2) -{ - UINT8 shouldCollide = 0; // 0 = default, 1 = force yes, 2 = force no. - if (!gL || !(hooksAvailable[hook_MobjMoveCollide/8] & (1<<(hook_MobjMoveCollide%8)))) - return 0; - - // clear the stack - lua_pop(gL, -1); - - // hook table - lua_getfield(gL, LUA_REGISTRYINDEX, "hook"); - I_Assert(lua_istable(gL, -1)); - lua_rawgeti(gL, -1, hook_MobjMoveCollide); - lua_remove(gL, -2); - I_Assert(lua_istable(gL, -1)); - - // mobjtype subtable - lua_rawgeti(gL, -1, thing1->type); - if (lua_isnil(gL, -1)) { - lua_pop(gL, 2); - return 0; - } - lua_remove(gL, -2); // remove hook table - - LUA_PushUserdata(gL, thing1, META_MOBJ); - LUA_PushUserdata(gL, thing2, META_MOBJ); - lua_pushnil(gL); - while (lua_next(gL, -4)) { - lua_pushvalue(gL, -4); // thing1 - lua_pushvalue(gL, -4); // thing2 - if (lua_pcall(gL, 2, 1, 0)) { - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); - lua_pop(gL, 1); - continue; - } - if (!lua_isnil(gL, -1)) - { // if nil, leave shouldCollide = 0. - if (lua_toboolean(gL, -1)) - shouldCollide = 1; // Force yes - else - shouldCollide = 2; // Force no - } - lua_pop(gL, 1); // pop return value - } - lua_pop(gL, 3); // pop arguments and mobjtype table - - lua_gc(gL, LUA_GCSTEP, 1); + lua_settop(gL, 0); return shouldCollide; } // Hook for P_TouchSpecialThing by mobj type boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher) { + hook_p hookp; boolean hooked = false; if (!gL || !(hooksAvailable[hook_TouchSpecial/8] & (1<<(hook_TouchSpecial%8)))) - return false; + return 0; - // clear the stack - lua_pop(gL, -1); + lua_settop(gL, 0); - // get hook table - lua_getfield(gL, LUA_REGISTRYINDEX, "hook"); - I_Assert(lua_istable(gL, -1)); - lua_rawgeti(gL, -1, hook_TouchSpecial); - lua_remove(gL, -2); - I_Assert(lua_istable(gL, -1)); - - // get mobjtype subtable - lua_pushinteger(gL, special->type); - lua_rawget(gL, 1); - if (lua_isnil(gL, -1)) { - lua_pop(gL, 2); - return false; - } - lua_remove(gL, 1); // pop hook table off the stack - - LUA_PushUserdata(gL, special, META_MOBJ); - LUA_PushUserdata(gL, toucher, META_MOBJ); - - lua_pushnil(gL); - while (lua_next(gL, 1) != 0) { - lua_pushvalue(gL, 2); // special - lua_pushvalue(gL, 3); // toucher - if (lua_pcall(gL, 2, 1, 0)) { // pops hook function, special, toucher, pushes 1 return result - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); + for (hookp = roothook; hookp; hookp = hookp->next) + if (hookp->type == hook_TouchSpecial + && (hookp->s.mt == MT_NULL || hookp->s.mt == special->type)) + { + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, special, META_MOBJ); + LUA_PushUserdata(gL, toucher, META_MOBJ); + } + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -3); + lua_pushvalue(gL, -3); + if (lua_pcall(gL, 2, 1, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (lua_toboolean(gL, -1)) + hooked = true; lua_pop(gL, 1); - continue; } - if (lua_toboolean(gL, -1)) // if return true, - hooked = true; // override vanilla behavior - lua_pop(gL, 1); // pop return value - } - lua_pop(gL, -1); - lua_gc(gL, LUA_GCSTEP, 1); + lua_settop(gL, 0); return hooked; } // Hook for P_DamageMobj by mobj type (Should mobj take damage?) UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage) { + hook_p hookp; UINT8 shouldDamage = 0; // 0 = default, 1 = force yes, 2 = force no. if (!gL || !(hooksAvailable[hook_ShouldDamage/8] & (1<<(hook_ShouldDamage%8)))) return 0; - // clear the stack - lua_pop(gL, -1); + lua_settop(gL, 0); - // hook table - lua_getfield(gL, LUA_REGISTRYINDEX, "hook"); - I_Assert(lua_istable(gL, -1)); - lua_rawgeti(gL, -1, hook_ShouldDamage); - lua_remove(gL, -2); - I_Assert(lua_istable(gL, -1)); - - // mobjtype subtable - lua_rawgeti(gL, -1, target->type); - if (lua_isnil(gL, -1)) { - lua_pop(gL, 2); - return 0; - } - lua_remove(gL, -2); // remove hook table - - LUA_PushUserdata(gL, target, META_MOBJ); - LUA_PushUserdata(gL, inflictor, META_MOBJ); - LUA_PushUserdata(gL, source, META_MOBJ); - lua_pushinteger(gL, damage); - lua_pushnil(gL); - while (lua_next(gL, -6)) { - lua_pushvalue(gL, -6); // target - lua_pushvalue(gL, -6); // inflictor - lua_pushvalue(gL, -6); // source - lua_pushvalue(gL, -6); // damage - if (lua_pcall(gL, 4, 1, 0)) { - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); + for (hookp = roothook; hookp; hookp = hookp->next) + if (hookp->type == hook_ShouldDamage + && (hookp->s.mt == MT_NULL || hookp->s.mt == target->type)) + { + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, target, META_MOBJ); + LUA_PushUserdata(gL, inflictor, META_MOBJ); + LUA_PushUserdata(gL, source, META_MOBJ); + lua_pushinteger(gL, damage); + } + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + if (lua_pcall(gL, 4, 1, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (!lua_isnil(gL, -1)) + { + if (lua_toboolean(gL, -1)) + shouldDamage = 1; // Force yes + else + shouldDamage = 2; // Force no + } lua_pop(gL, 1); - continue; } - if (!lua_isnil(gL, -1)) - { // if nil, leave shouldDamage = 0. - if (lua_toboolean(gL, -1)) - shouldDamage = 1; // Force yes - else - shouldDamage = 2; // Force no - } - lua_pop(gL, 1); // pop return value - } - lua_pop(gL, 5); // pop arguments and mobjtype table - lua_gc(gL, LUA_GCSTEP, 1); + lua_settop(gL, 0); return shouldDamage; } // Hook for P_DamageMobj by mobj type (Mobj actually takes damage!) boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage) { - boolean handled = false; + hook_p hookp; + boolean hooked = false; if (!gL || !(hooksAvailable[hook_MobjDamage/8] & (1<<(hook_MobjDamage%8)))) - return false; + return 0; - // clear the stack - lua_pop(gL, -1); + lua_settop(gL, 0); - // hook table - lua_getfield(gL, LUA_REGISTRYINDEX, "hook"); - I_Assert(lua_istable(gL, -1)); - lua_rawgeti(gL, -1, hook_MobjDamage); - lua_remove(gL, -2); - I_Assert(lua_istable(gL, -1)); - - // mobjtype subtable - lua_rawgeti(gL, -1, target->type); - if (lua_isnil(gL, -1)) { - lua_pop(gL, 2); - return false; - } - lua_remove(gL, -2); // remove hook table - - LUA_PushUserdata(gL, target, META_MOBJ); - LUA_PushUserdata(gL, inflictor, META_MOBJ); - LUA_PushUserdata(gL, source, META_MOBJ); - lua_pushinteger(gL, damage); - lua_pushnil(gL); - while (lua_next(gL, -6)) { - lua_pushvalue(gL, -6); // target - lua_pushvalue(gL, -6); // inflictor - lua_pushvalue(gL, -6); // source - lua_pushvalue(gL, -6); // damage - if (lua_pcall(gL, 4, 1, 0)) { - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); + for (hookp = roothook; hookp; hookp = hookp->next) + if (hookp->type == hook_MobjDamage + && (hookp->s.mt == MT_NULL || hookp->s.mt == target->type)) + { + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, target, META_MOBJ); + LUA_PushUserdata(gL, inflictor, META_MOBJ); + LUA_PushUserdata(gL, source, META_MOBJ); + lua_pushinteger(gL, damage); + } + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + if (lua_pcall(gL, 4, 1, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (lua_toboolean(gL, -1)) + hooked = true; lua_pop(gL, 1); - continue; } - if (lua_toboolean(gL, -1)) - handled = true; - lua_pop(gL, 1); // pop return value - } - lua_pop(gL, 5); // pop arguments and mobjtype table - lua_gc(gL, LUA_GCSTEP, 1); - return handled; + lua_settop(gL, 0); + return hooked; } // Hook for P_KillMobj by mobj type boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source) { - boolean handled = false; + hook_p hookp; + boolean hooked = false; if (!gL || !(hooksAvailable[hook_MobjDeath/8] & (1<<(hook_MobjDeath%8)))) - return false; + return 0; - // clear the stack - lua_pop(gL, -1); + lua_settop(gL, 0); - // hook table - lua_getfield(gL, LUA_REGISTRYINDEX, "hook"); - I_Assert(lua_istable(gL, -1)); - lua_rawgeti(gL, -1, hook_MobjDeath); - lua_remove(gL, -2); - I_Assert(lua_istable(gL, -1)); - - // mobjtype subtable - lua_rawgeti(gL, -1, target->type); - if (lua_isnil(gL, -1)) { - lua_pop(gL, 2); - return false; - } - lua_remove(gL, -2); // remove hook table - - LUA_PushUserdata(gL, target, META_MOBJ); - LUA_PushUserdata(gL, inflictor, META_MOBJ); - LUA_PushUserdata(gL, source, META_MOBJ); - lua_pushnil(gL); - while (lua_next(gL, -5)) { - lua_pushvalue(gL, -5); // target - lua_pushvalue(gL, -5); // inflictor - lua_pushvalue(gL, -5); // source - if (lua_pcall(gL, 3, 1, 0)) { - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); + for (hookp = roothook; hookp; hookp = hookp->next) + if (hookp->type == hook_MobjDeath + && (hookp->s.mt == MT_NULL || hookp->s.mt == target->type)) + { + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, target, META_MOBJ); + LUA_PushUserdata(gL, inflictor, META_MOBJ); + LUA_PushUserdata(gL, source, META_MOBJ); + } + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -4); + lua_pushvalue(gL, -4); + lua_pushvalue(gL, -4); + if (lua_pcall(gL, 3, 1, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (lua_toboolean(gL, -1)) + hooked = true; lua_pop(gL, 1); - continue; } - if (lua_toboolean(gL, -1)) - handled = true; - lua_pop(gL, 1); // pop return value - } - lua_pop(gL, 4); // pop arguments and mobjtype table - lua_gc(gL, LUA_GCSTEP, 1); - return handled; + lua_settop(gL, 0); + return hooked; } // Hook for B_BuildTiccmd boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd) { + hook_p hookp; boolean hooked = false; if (!gL || !(hooksAvailable[hook_BotTiccmd/8] & (1<<(hook_BotTiccmd%8)))) return false; - // clear the stack - lua_pop(gL, -1); + lua_settop(gL, 0); - // hook table - lua_getfield(gL, LUA_REGISTRYINDEX, "hook"); - I_Assert(lua_istable(gL, -1)); - lua_rawgeti(gL, -1, hook_BotTiccmd); - lua_remove(gL, -2); - I_Assert(lua_istable(gL, -1)); - - LUA_PushUserdata(gL, bot, META_PLAYER); - LUA_PushUserdata(gL, cmd, META_TICCMD); - - lua_pushnil(gL); - while (lua_next(gL, 1)) { - lua_pushvalue(gL, 2); // bot - lua_pushvalue(gL, 3); // cmd - if (lua_pcall(gL, 2, 1, 0)) { - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); + for (hookp = roothook; hookp; hookp = hookp->next) + if (hookp->type == hook_BotTiccmd) + { + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, bot, META_PLAYER); + LUA_PushUserdata(gL, cmd, META_TICCMD); + } + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -3); + lua_pushvalue(gL, -3); + if (lua_pcall(gL, 2, 1, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (lua_toboolean(gL, -1)) + hooked = true; lua_pop(gL, 1); - continue; } - if (lua_toboolean(gL, -1)) - hooked = true; - lua_pop(gL, 1); // pop return value - } - lua_pop(gL, -1); - lua_gc(gL, LUA_GCSTEP, 1); + lua_settop(gL, 0); return hooked; } // Hook for B_BuildTailsTiccmd by skin name boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) { - if (!gL || !tails->skin || !(hooksAvailable[hook_BotAI/8] & (1<<(hook_BotAI%8)))) + hook_p hookp; + boolean hooked = false; + if (!gL || !(hooksAvailable[hook_BotAI/8] & (1<<(hook_BotAI%8)))) return false; - // clear the stack - lua_pop(gL, -1); + lua_settop(gL, 0); - // hook table - lua_getfield(gL, LUA_REGISTRYINDEX, "hook"); - I_Assert(lua_istable(gL, -1)); - lua_rawgeti(gL, -1, hook_BotAI); - lua_remove(gL, -2); - I_Assert(lua_istable(gL, -1)); - - // bot skin ai function - lua_getfield(gL, 1, ((skin_t *)tails->skin)->name); - if (lua_isnil(gL, -1)) { - lua_pop(gL, 2); - return false; - } - lua_remove(gL, 1); // pop the hook table - - // Takes sonic, tails - // Returns forward, backward, left, right, jump, spin - LUA_PushUserdata(gL, sonic, META_MOBJ); - LUA_PushUserdata(gL, tails, META_MOBJ); - if (lua_pcall(gL, 2, 8, 0)) { - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); - lua_pop(gL,-1); - return false; - } - - // This turns forward, backward, left, right, jump, and spin into a proper ticcmd for tails. - if (lua_istable(gL, 1)) { - boolean forward=false, backward=false, left=false, right=false, strafeleft=false, straferight=false, jump=false, spin=false; + for (hookp = roothook; hookp; hookp = hookp->next) + if (hookp->type == hook_BotAI + && (hookp->s.skinname == NULL || !strcmp(hookp->s.skinname, ((skin_t*)tails->skin)->name))) + { + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, sonic, META_MOBJ); + LUA_PushUserdata(gL, tails, META_MOBJ); + } + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -3); + lua_pushvalue(gL, -3); + if (lua_pcall(gL, 2, 8, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + // This turns forward, backward, left, right, jump, and spin into a proper ticcmd for tails. + if (lua_istable(gL, 2+1)) { + boolean forward=false, backward=false, left=false, right=false, strafeleft=false, straferight=false, jump=false, spin=false; #define CHECKFIELD(field) \ - lua_getfield(gL, 1, #field);\ - if (lua_toboolean(gL, -1))\ - field = true;\ - lua_pop(gL, 1); - - CHECKFIELD(forward) - CHECKFIELD(backward) - CHECKFIELD(left) - CHECKFIELD(right) - CHECKFIELD(strafeleft) - CHECKFIELD(straferight) - CHECKFIELD(jump) - CHECKFIELD(spin) + lua_getfield(gL, 2+1, #field);\ + if (lua_toboolean(gL, -1))\ + field = true;\ + lua_pop(gL, 1); + CHECKFIELD(forward) + CHECKFIELD(backward) + CHECKFIELD(left) + CHECKFIELD(right) + CHECKFIELD(strafeleft) + CHECKFIELD(straferight) + CHECKFIELD(jump) + CHECKFIELD(spin) #undef CHECKFIELD + B_KeysToTiccmd(tails, cmd, forward, backward, left, right, strafeleft, straferight, jump, spin); + } else + B_KeysToTiccmd(tails, cmd, lua_toboolean(gL, 2+1), lua_toboolean(gL, 2+2), lua_toboolean(gL, 2+3), lua_toboolean(gL, 2+4), lua_toboolean(gL, 2+5), lua_toboolean(gL, 2+6), lua_toboolean(gL, 2+7), lua_toboolean(gL, 2+8)); - B_KeysToTiccmd(tails, cmd, forward, backward, left, right, strafeleft, straferight, jump, spin); - } else - B_KeysToTiccmd(tails, cmd, lua_toboolean(gL, 1), lua_toboolean(gL, 2), lua_toboolean(gL, 3), lua_toboolean(gL, 4), lua_toboolean(gL, 5), lua_toboolean(gL, 6), lua_toboolean(gL, 7), lua_toboolean(gL, 8)); + lua_pop(gL, 8); + hooked = true; + } - lua_pop(gL, -1); - lua_gc(gL, LUA_GCSTEP, 1); - return true; + lua_settop(gL, 0); + return hooked; } // Hook for linedef executors boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector) { + hook_p hookp; + boolean hooked = false; if (!gL || !(hooksAvailable[hook_LinedefExecute/8] & (1<<(hook_LinedefExecute%8)))) - return false; + return 0; - // clear the stack - lua_pop(gL, -1); + lua_settop(gL, 0); - // get hook table - lua_getfield(gL, LUA_REGISTRYINDEX, "hook"); - I_Assert(lua_istable(gL, -1)); - lua_rawgeti(gL, -1, hook_LinedefExecute); - lua_remove(gL, -2); - I_Assert(lua_istable(gL, -1)); + for (hookp = roothook; hookp; hookp = hookp->next) + if (hookp->type == hook_LinedefExecute + && !strcmp(hookp->s.funcname, line->text)) + { + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, line, META_LINE); + LUA_PushUserdata(gL, mo, META_MOBJ); + LUA_PushUserdata(gL, sector, META_SECTOR); + } + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -4); + lua_pushvalue(gL, -4); + lua_pushvalue(gL, -4); + LUA_Call(gL, 3); + hooked = true; + } - // get function by line text - lua_getfield(gL, 1, line->text); - if (lua_isnil(gL, -1)) { - lua_pop(gL, 2); - return false; - } - lua_remove(gL, 1); // pop hook table off the stack - - LUA_PushUserdata(gL, line, META_LINE); - LUA_PushUserdata(gL, mo, META_MOBJ); - LUA_PushUserdata(gL, sector, META_SECTOR); - LUA_Call(gL, 3); // pops hook function, line, mo, sector - - lua_pop(gL, -1); - lua_gc(gL, LUA_GCSTEP, 1); - return true; + lua_settop(gL, 0); + return hooked; } -// Hook for PlayerMsg -Red +// Hook for player chat boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg) { - boolean handled = false; - + hook_p hookp; + boolean hooked = false; if (!gL || !(hooksAvailable[hook_PlayerMsg/8] & (1<<(hook_PlayerMsg%8)))) return false; - lua_getfield(gL, LUA_REGISTRYINDEX, "hook"); - I_Assert(lua_istable(gL, -1)); - lua_rawgeti(gL, -1, hook_PlayerMsg); - lua_remove(gL, -2); - I_Assert(lua_istable(gL, -1)); + lua_settop(gL, 0); - LUA_PushUserdata(gL, &players[source], META_PLAYER); // Source player - - if (flags & 2 /*HU_CSAY*/) { // csay TODO: make HU_CSAY accessible outside hu_stuff.c - lua_pushinteger(gL, 3); // type - lua_pushnil(gL); // target - } else if (target == -1) { // sayteam - lua_pushinteger(gL, 1); // type - lua_pushnil(gL); // target - } else if (target == 0) { // say - lua_pushinteger(gL, 0); // type - lua_pushnil(gL); // target - } else { // sayto - lua_pushinteger(gL, 2); // type - LUA_PushUserdata(gL, &players[target-1], META_PLAYER); // target - } - - lua_pushstring(gL, msg); // msg - - lua_pushnil(gL); - - while (lua_next(gL, -6)) { - lua_pushvalue(gL, -6); // source - lua_pushvalue(gL, -6); // type - lua_pushvalue(gL, -6); // target - lua_pushvalue(gL, -6); // msg - if (lua_pcall(gL, 4, 1, 0)) { - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); + for (hookp = roothook; hookp; hookp = hookp->next) + if (hookp->type == hook_PlayerMsg) + { + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, &players[source], META_PLAYER); // Source player + if (flags & 2 /*HU_CSAY*/) { // csay TODO: make HU_CSAY accessible outside hu_stuff.c + lua_pushinteger(gL, 3); // type + lua_pushnil(gL); // target + } else if (target == -1) { // sayteam + lua_pushinteger(gL, 1); // type + lua_pushnil(gL); // target + } else if (target == 0) { // say + lua_pushinteger(gL, 0); // type + lua_pushnil(gL); // target + } else { // sayto + lua_pushinteger(gL, 2); // type + LUA_PushUserdata(gL, &players[target-1], META_PLAYER); // target + } + lua_pushstring(gL, msg); // msg + } + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + if (lua_pcall(gL, 4, 1, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (lua_toboolean(gL, -1)) + hooked = true; lua_pop(gL, 1); - continue; } - if (lua_toboolean(gL, -1)) - handled = true; - lua_pop(gL, 1); // pop return value - } - lua_pop(gL, 4); // pop arguments and mobjtype table - lua_gc(gL, LUA_GCSTEP, 1); - return handled; + lua_settop(gL, 0); + return hooked; } -// Hook for hurt messages -Red -// The internal name is DeathMsg, but the API name is "HurtMsg". Keep that in mind. (Should this be fixed at some point?) -// @TODO This hook should be fixed to take mobj type at the addHook parameter to compare to inflictor. (I couldn't get this to work without crashing) -boolean LUAh_DeathMsg(player_t *player, mobj_t *inflictor, mobj_t *source) +// Hook for hurt messages +boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source) { - boolean handled = false; - - if (!gL || !(hooksAvailable[hook_DeathMsg/8] & (1<<(hook_DeathMsg%8)))) + hook_p hookp; + boolean hooked = false; + if (!gL || !(hooksAvailable[hook_HurtMsg/8] & (1<<(hook_HurtMsg%8)))) return false; - lua_getfield(gL, LUA_REGISTRYINDEX, "hook"); - I_Assert(lua_istable(gL, -1)); - lua_rawgeti(gL, -1, hook_DeathMsg); - lua_remove(gL, -2); - I_Assert(lua_istable(gL, -1)); + lua_settop(gL, 0); - LUA_PushUserdata(gL, player, META_PLAYER); // Player - LUA_PushUserdata(gL, inflictor, META_MOBJ); // Inflictor - LUA_PushUserdata(gL, source, META_MOBJ); // Source - - lua_pushnil(gL); - - while (lua_next(gL, -5)) { - lua_pushvalue(gL, -5); // player - lua_pushvalue(gL, -5); // inflictor - lua_pushvalue(gL, -5); // source - if (lua_pcall(gL, 3, 1, 0)) { - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); + for (hookp = roothook; hookp; hookp = hookp->next) + if (hookp->type == hook_HurtMsg + && (hookp->s.mt == MT_NULL || (inflictor && hookp->s.mt == inflictor->type))) + { + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, player, META_PLAYER); + LUA_PushUserdata(gL, inflictor, META_MOBJ); + LUA_PushUserdata(gL, source, META_MOBJ); + } + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -4); + lua_pushvalue(gL, -4); + lua_pushvalue(gL, -4); + if (lua_pcall(gL, 3, 1, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (lua_toboolean(gL, -1)) + hooked = true; lua_pop(gL, 1); - continue; } - if (lua_toboolean(gL, -1)) - handled = true; - lua_pop(gL, 1); // pop return value - } - lua_pop(gL, 3); // pop arguments and mobjtype table - lua_gc(gL, LUA_GCSTEP, 1); - return handled; + lua_settop(gL, 0); + return hooked; } #endif diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 86ff11337..5a83d95b5 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -674,8 +674,6 @@ void LUAh_GameHUD(player_t *stplayr) LUA_Call(gL, 3); } lua_pop(gL, -1); - lua_gc(gL, LUA_GCCOLLECT, 0); - hud_running = false; } @@ -701,8 +699,6 @@ void LUAh_ScoresHUD(void) LUA_Call(gL, 1); } lua_pop(gL, -1); - lua_gc(gL, LUA_GCCOLLECT, 0); - hud_running = false; } diff --git a/src/lua_infolib.c b/src/lua_infolib.c index 2c968218c..0fddebaba 100644 --- a/src/lua_infolib.c +++ b/src/lua_infolib.c @@ -137,8 +137,6 @@ static void A_Lua(mobj_t *actor) --superstack; superactions[superstack] = NULL; } - - lua_gc(gL, LUA_GCSTEP, 1); } // Arbitrary states[] table index -> state_t * @@ -510,11 +508,11 @@ static int lib_setMobjInfo(lua_State *L) else if (i == 15 || (str && fastcmp(str,"deathsound"))) info->deathsound = luaL_checkinteger(L, 3); else if (i == 16 || (str && fastcmp(str,"speed"))) - info->speed = (fixed_t)luaL_checkinteger(L, 3); + info->speed = luaL_checkfixed(L, 3); else if (i == 17 || (str && fastcmp(str,"radius"))) - info->radius = (fixed_t)luaL_checkinteger(L, 3); + info->radius = luaL_checkfixed(L, 3); else if (i == 18 || (str && fastcmp(str,"height"))) - info->height = (fixed_t)luaL_checkinteger(L, 3); + info->height = luaL_checkfixed(L, 3); else if (i == 19 || (str && fastcmp(str,"dispoffset"))) info->dispoffset = (INT32)luaL_checkinteger(L, 3); else if (i == 20 || (str && fastcmp(str,"mass"))) @@ -580,11 +578,11 @@ static int mobjinfo_get(lua_State *L) else if (fastcmp(field,"deathsound")) lua_pushinteger(L, info->deathsound); else if (fastcmp(field,"speed")) - lua_pushinteger(L, info->speed); + lua_pushinteger(L, info->speed); // sometimes it's fixed_t, sometimes it's not... else if (fastcmp(field,"radius")) - lua_pushinteger(L, info->radius); + lua_pushfixed(L, info->radius); else if (fastcmp(field,"height")) - lua_pushinteger(L, info->height); + lua_pushfixed(L, info->height); else if (fastcmp(field,"dispoffset")) lua_pushinteger(L, info->dispoffset); else if (fastcmp(field,"mass")) @@ -656,11 +654,11 @@ static int mobjinfo_set(lua_State *L) else if (fastcmp(field,"deathsound")) info->deathsound = luaL_checkinteger(L, 3); else if (fastcmp(field,"speed")) - info->speed = (fixed_t)luaL_checkinteger(L, 3); + info->speed = luaL_checkfixed(L, 3); else if (fastcmp(field,"radius")) - info->radius = (fixed_t)luaL_checkinteger(L, 3); + info->radius = luaL_checkfixed(L, 3); else if (fastcmp(field,"height")) - info->height = (fixed_t)luaL_checkinteger(L, 3); + info->height = luaL_checkfixed(L, 3); else if (fastcmp(field,"dispoffset")) info->dispoffset = (INT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"mass")) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index e5cc30c12..0a12478ca 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -280,10 +280,10 @@ static int sector_get(lua_State *L) lua_pushboolean(L, 1); return 1; case sector_floorheight: - lua_pushinteger(L, sector->floorheight); + lua_pushfixed(L, sector->floorheight); return 1; case sector_ceilingheight: - lua_pushinteger(L, sector->ceilingheight); + lua_pushfixed(L, sector->ceilingheight); return 1; case sector_floorpic: { // floorpic levelflat_t *levelflat; @@ -396,26 +396,30 @@ static int sector_set(lua_State *L) return luaL_error(L, "sector_t field " LUA_QS " cannot be set.", sector_opt[field]); case sector_floorheight: { // floorheight boolean flag; + mobj_t *ptmthing = tmthing; fixed_t lastpos = sector->floorheight; - sector->floorheight = (fixed_t)luaL_checkinteger(L, 3); + sector->floorheight = luaL_checkfixed(L, 3); flag = P_CheckSector(sector, true); if (flag && sector->numattached) { sector->floorheight = lastpos; P_CheckSector(sector, true); } + P_SetTarget(&tmthing, ptmthing); break; } case sector_ceilingheight: { // ceilingheight boolean flag; + mobj_t *ptmthing = tmthing; fixed_t lastpos = sector->ceilingheight; - sector->ceilingheight = (fixed_t)luaL_checkinteger(L, 3); + sector->ceilingheight = luaL_checkfixed(L, 3); flag = P_CheckSector(sector, true); if (flag && sector->numattached) { sector->ceilingheight = lastpos; P_CheckSector(sector, true); } + P_SetTarget(&tmthing, ptmthing); break; } case sector_floorpic: @@ -509,10 +513,10 @@ static int line_get(lua_State *L) LUA_PushUserdata(L, line->v2, META_VERTEX); return 1; case line_dx: - lua_pushinteger(L, line->dx); + lua_pushfixed(L, line->dx); return 1; case line_dy: - lua_pushinteger(L, line->dy); + lua_pushfixed(L, line->dy); return 1; case line_flags: lua_pushinteger(L, line->flags); @@ -628,10 +632,10 @@ static int side_get(lua_State *L) lua_pushboolean(L, 1); return 1; case side_textureoffset: - lua_pushinteger(L, side->textureoffset); + lua_pushfixed(L, side->textureoffset); return 1; case side_rowoffset: - lua_pushinteger(L, side->rowoffset); + lua_pushfixed(L, side->rowoffset); return 1; case side_toptexture: lua_pushinteger(L, side->toptexture); @@ -658,6 +662,50 @@ static int side_get(lua_State *L) return 0; } +static int side_set(lua_State *L) +{ + side_t *side = *((side_t **)luaL_checkudata(L, 1, META_SIDE)); + enum side_e field = luaL_checkoption(L, 2, side_opt[0], side_opt); + + if (!side) + { + if (field == side_valid) { + lua_pushboolean(L, 0); + return 1; + } + return luaL_error(L, "accessed side_t doesn't exist anymore."); + } + + switch(field) + { + case side_valid: // valid + case side_sector: + case side_special: + case side_text: + default: + return luaL_error(L, "side_t field " LUA_QS " cannot be set.", side_opt[field]); + case side_textureoffset: + side->textureoffset = luaL_checkfixed(L, 3); + break; + case side_rowoffset: + side->rowoffset = luaL_checkfixed(L, 3); + break; + case side_toptexture: + side->toptexture = luaL_checkinteger(L, 3); + break; + case side_bottomtexture: + side->bottomtexture = luaL_checkinteger(L, 3); + break; + case side_midtexture: + side->midtexture = luaL_checkinteger(L, 3); + break; + case side_repeatcnt: + side->repeatcnt = luaL_checkinteger(L, 3); + break; + } + return 0; +} + static int side_num(lua_State *L) { side_t *side = *((side_t **)luaL_checkudata(L, 1, META_SIDE)); @@ -685,13 +733,13 @@ static int vertex_get(lua_State *L) lua_pushboolean(L, 1); return 1; case vertex_x: - lua_pushinteger(L, vertex->x); + lua_pushfixed(L, vertex->x); return 1; case vertex_y: - lua_pushinteger(L, vertex->y); + lua_pushfixed(L, vertex->y); return 1; case vertex_z: - lua_pushinteger(L, vertex->z); + lua_pushfixed(L, vertex->z); return 1; } return 0; @@ -954,7 +1002,7 @@ static int ffloor_get(lua_State *L) lua_pushboolean(L, 1); return 1; case ffloor_topheight: - lua_pushinteger(L, *ffloor->topheight); + lua_pushfixed(L, *ffloor->topheight); return 1; case ffloor_toppic: { // toppic levelflat_t *levelflat; @@ -968,7 +1016,7 @@ static int ffloor_get(lua_State *L) lua_pushinteger(L, *ffloor->toplightlevel); return 1; case ffloor_bottomheight: - lua_pushinteger(L, *ffloor->bottomheight); + lua_pushfixed(L, *ffloor->bottomheight); return 1; case ffloor_bottompic: { // bottompic levelflat_t *levelflat; @@ -1027,14 +1075,16 @@ static int ffloor_set(lua_State *L) case ffloor_topheight: { // topheight boolean flag; fixed_t lastpos = *ffloor->topheight; + mobj_t *ptmthing = tmthing; sector_t *sector = §ors[ffloor->secnum]; - sector->ceilingheight = (fixed_t)luaL_checkinteger(L, 3); + sector->ceilingheight = luaL_checkfixed(L, 3); flag = P_CheckSector(sector, true); if (flag && sector->numattached) { *ffloor->topheight = lastpos; P_CheckSector(sector, true); } + P_SetTarget(&tmthing, ptmthing); break; } case ffloor_toppic: @@ -1046,14 +1096,16 @@ static int ffloor_set(lua_State *L) case ffloor_bottomheight: { // bottomheight boolean flag; fixed_t lastpos = *ffloor->bottomheight; + mobj_t *ptmthing = tmthing; sector_t *sector = §ors[ffloor->secnum]; - sector->floorheight = (fixed_t)luaL_checkinteger(L, 3); + sector->floorheight = luaL_checkfixed(L, 3); flag = P_CheckSector(sector, true); if (flag && sector->numattached) { *ffloor->bottomheight = lastpos; P_CheckSector(sector, true); } + P_SetTarget(&tmthing, ptmthing); break; } case ffloor_bottompic: @@ -1214,6 +1266,9 @@ int LUA_MapLib(lua_State *L) lua_pushcfunction(L, side_get); lua_setfield(L, -2, "__index"); + lua_pushcfunction(L, side_set); + lua_setfield(L, -2, "__newindex"); + lua_pushcfunction(L, side_num); lua_setfield(L, -2, "__len"); lua_pop(L, 1); diff --git a/src/lua_mathlib.c b/src/lua_mathlib.c index f8b33ffd2..8ca2e17af 100644 --- a/src/lua_mathlib.c +++ b/src/lua_mathlib.c @@ -47,37 +47,37 @@ static int lib_max(lua_State *L) static int lib_fixedangle(lua_State *L) { - lua_pushinteger(L, FixedAngle((fixed_t)luaL_checkinteger(L, 1))); + lua_pushangle(L, FixedAngle(luaL_checkfixed(L, 1))); return 1; } static int lib_anglefixed(lua_State *L) { - lua_pushinteger(L, AngleFixed((angle_t)luaL_checkinteger(L, 1))); + lua_pushfixed(L, AngleFixed(luaL_checkangle(L, 1))); return 1; } static int lib_invangle(lua_State *L) { - lua_pushinteger(L, InvAngle((angle_t)luaL_checkinteger(L, 1))); + lua_pushangle(L, InvAngle(luaL_checkangle(L, 1))); return 1; } static int lib_finesine(lua_State *L) { - lua_pushinteger(L, FINESINE((luaL_checkinteger(L, 1)>>ANGLETOFINESHIFT) & FINEMASK)); + lua_pushfixed(L, FINESINE((luaL_checkangle(L, 1)>>ANGLETOFINESHIFT) & FINEMASK)); return 1; } static int lib_finecosine(lua_State *L) { - lua_pushinteger(L, FINECOSINE((luaL_checkinteger(L, 1)>>ANGLETOFINESHIFT) & FINEMASK)); + lua_pushfixed(L, FINECOSINE((luaL_checkangle(L, 1)>>ANGLETOFINESHIFT) & FINEMASK)); return 1; } static int lib_finetangent(lua_State *L) { - lua_pushinteger(L, FINETANGENT((luaL_checkinteger(L, 1)>>ANGLETOFINESHIFT) & FINEMASK)); + lua_pushfixed(L, FINETANGENT((luaL_checkangle(L, 1)>>ANGLETOFINESHIFT) & FINEMASK)); return 1; } @@ -86,61 +86,61 @@ static int lib_finetangent(lua_State *L) static int lib_fixedmul(lua_State *L) { - lua_pushinteger(L, FixedMul((fixed_t)luaL_checkinteger(L, 1), (fixed_t)luaL_checkinteger(L, 2))); + lua_pushfixed(L, FixedMul(luaL_checkfixed(L, 1), luaL_checkfixed(L, 2))); return 1; } static int lib_fixedint(lua_State *L) { - lua_pushinteger(L, FixedInt((fixed_t)luaL_checkinteger(L, 1))); + lua_pushinteger(L, FixedInt(luaL_checkfixed(L, 1))); return 1; } static int lib_fixeddiv(lua_State *L) { - lua_pushinteger(L, FixedDiv((fixed_t)luaL_checkinteger(L, 1), (fixed_t)luaL_checkinteger(L, 2))); + lua_pushfixed(L, FixedDiv(luaL_checkfixed(L, 1), luaL_checkfixed(L, 2))); return 1; } static int lib_fixedrem(lua_State *L) { - lua_pushinteger(L, FixedRem((fixed_t)luaL_checkinteger(L, 1), (fixed_t)luaL_checkinteger(L, 2))); + lua_pushfixed(L, FixedRem(luaL_checkfixed(L, 1), luaL_checkfixed(L, 2))); return 1; } static int lib_fixedsqrt(lua_State *L) { - lua_pushinteger(L, FixedSqrt((fixed_t)luaL_checkinteger(L, 1))); + lua_pushfixed(L, FixedSqrt(luaL_checkfixed(L, 1))); return 1; } static int lib_fixedhypot(lua_State *L) { - lua_pushinteger(L, FixedHypot((fixed_t)luaL_checkinteger(L, 1), (fixed_t)luaL_checkinteger(L, 2))); + lua_pushfixed(L, FixedHypot(luaL_checkfixed(L, 1), luaL_checkfixed(L, 2))); return 1; } static int lib_fixedfloor(lua_State *L) { - lua_pushinteger(L, FixedFloor((fixed_t)luaL_checkinteger(L, 1))); + lua_pushfixed(L, FixedFloor(luaL_checkfixed(L, 1))); return 1; } static int lib_fixedtrunc(lua_State *L) { - lua_pushinteger(L, FixedTrunc((fixed_t)luaL_checkinteger(L, 1))); + lua_pushfixed(L, FixedTrunc(luaL_checkfixed(L, 1))); return 1; } static int lib_fixedceil(lua_State *L) { - lua_pushinteger(L, FixedCeil((fixed_t)luaL_checkinteger(L, 1))); + lua_pushfixed(L, FixedCeil(luaL_checkfixed(L, 1))); return 1; } static int lib_fixedround(lua_State *L) { - lua_pushinteger(L, FixedRound((fixed_t)luaL_checkinteger(L, 1))); + lua_pushfixed(L, FixedRound(luaL_checkfixed(L, 1))); return 1; } @@ -156,7 +156,7 @@ static int lib_getsecspecial(lua_State *L) static int lib_all7emeralds(lua_State *L) { - lua_pushinteger(L, ALL7EMERALDS(luaL_checkinteger(L, 1))); + lua_pushboolean(L, ALL7EMERALDS(luaL_checkinteger(L, 1))); return 1; } diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 31496ed9c..83e7039e4 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -162,13 +162,13 @@ static int mobj_get(lua_State *L) lua_pushboolean(L, 1); break; case mobj_x: - lua_pushinteger(L, mo->x); + lua_pushfixed(L, mo->x); break; case mobj_y: - lua_pushinteger(L, mo->y); + lua_pushfixed(L, mo->y); break; case mobj_z: - lua_pushinteger(L, mo->z); + lua_pushfixed(L, mo->z); break; case mobj_snext: LUA_PushUserdata(L, mo->snext, META_MOBJ); @@ -179,7 +179,7 @@ static int mobj_get(lua_State *L) // i.e. it will always ultimately point to THIS mobj -- so that's actually not useful to Lua and won't be included. return UNIMPLEMENTED; case mobj_angle: - lua_pushinteger(L, mo->angle); + lua_pushangle(L, mo->angle); break; case mobj_sprite: lua_pushinteger(L, mo->sprite); @@ -193,28 +193,28 @@ static int mobj_get(lua_State *L) LUA_PushUserdata(L, mo->subsector, META_SUBSECTOR); break; case mobj_floorz: - lua_pushinteger(L, mo->floorz); + lua_pushfixed(L, mo->floorz); break; case mobj_ceilingz: - lua_pushinteger(L, mo->ceilingz); + lua_pushfixed(L, mo->ceilingz); break; case mobj_radius: - lua_pushinteger(L, mo->radius); + lua_pushfixed(L, mo->radius); break; case mobj_height: - lua_pushinteger(L, mo->height); + lua_pushfixed(L, mo->height); break; case mobj_momx: - lua_pushinteger(L, mo->momx); + lua_pushfixed(L, mo->momx); break; case mobj_momy: - lua_pushinteger(L, mo->momy); + lua_pushfixed(L, mo->momy); break; case mobj_momz: - lua_pushinteger(L, mo->momz); + lua_pushfixed(L, mo->momz); break; case mobj_pmomz: - lua_pushinteger(L, mo->pmomz); + lua_pushfixed(L, mo->pmomz); break; case mobj_tics: lua_pushinteger(L, mo->tics); @@ -299,32 +299,32 @@ static int mobj_get(lua_State *L) LUA_PushUserdata(L, mo->tracer, META_MOBJ); break; case mobj_friction: - lua_pushinteger(L, mo->friction); + lua_pushfixed(L, mo->friction); break; case mobj_movefactor: - lua_pushinteger(L, mo->movefactor); + lua_pushfixed(L, mo->movefactor); break; case mobj_fuse: lua_pushinteger(L, mo->fuse); break; case mobj_watertop: - lua_pushinteger(L, mo->watertop); + lua_pushfixed(L, mo->watertop); break; case mobj_waterbottom: - lua_pushinteger(L, mo->waterbottom); + lua_pushfixed(L, mo->waterbottom); break; case mobj_mobjnum: // mobjnum is a networking thing generated for $$$.sav // and therefore shouldn't be used by Lua. return UNIMPLEMENTED; case mobj_scale: - lua_pushinteger(L, mo->scale); + lua_pushfixed(L, mo->scale); break; case mobj_destscale: - lua_pushinteger(L, mo->destscale); + lua_pushfixed(L, mo->destscale); break; case mobj_scalespeed: - lua_pushinteger(L, mo->scalespeed); + lua_pushfixed(L, mo->scalespeed); break; case mobj_extravalue1: lua_pushinteger(L, mo->extravalue1); @@ -382,7 +382,7 @@ static int mobj_set(lua_State *L) { // z doesn't cross sector bounds so it's okay. mobj_t *ptmthing = tmthing; - mo->z = (fixed_t)luaL_checkinteger(L, 3); + mo->z = luaL_checkfixed(L, 3); P_CheckPosition(mo, mo->x, mo->y); mo->floorz = tmfloorz; mo->ceilingz = tmceilingz; @@ -394,7 +394,7 @@ static int mobj_set(lua_State *L) case mobj_sprev: return UNIMPLEMENTED; case mobj_angle: - mo->angle = (angle_t)luaL_checkinteger(L, 3); + mo->angle = luaL_checkangle(L, 3); if (mo->player == &players[consoleplayer]) localangle = mo->angle; else if (mo->player == &players[secondarydisplayplayer]) @@ -417,7 +417,7 @@ static int mobj_set(lua_State *L) case mobj_radius: { mobj_t *ptmthing = tmthing; - mo->radius = (fixed_t)luaL_checkinteger(L, 3); + mo->radius = luaL_checkfixed(L, 3); if (mo->radius < 0) mo->radius = 0; P_CheckPosition(mo, mo->x, mo->y); @@ -429,7 +429,7 @@ static int mobj_set(lua_State *L) case mobj_height: { mobj_t *ptmthing = tmthing; - mo->height = (fixed_t)luaL_checkinteger(L, 3); + mo->height = luaL_checkfixed(L, 3); if (mo->height < 0) mo->height = 0; P_CheckPosition(mo, mo->x, mo->y); @@ -439,16 +439,16 @@ static int mobj_set(lua_State *L) break; } case mobj_momx: - mo->momx = (fixed_t)luaL_checkinteger(L, 3); + mo->momx = luaL_checkfixed(L, 3); break; case mobj_momy: - mo->momy = (fixed_t)luaL_checkinteger(L, 3); + mo->momy = luaL_checkfixed(L, 3); break; case mobj_momz: - mo->momz = (fixed_t)luaL_checkinteger(L, 3); + mo->momz = luaL_checkfixed(L, 3); break; case mobj_pmomz: - mo->pmomz = (fixed_t)luaL_checkinteger(L, 3); + mo->pmomz = luaL_checkfixed(L, 3); mo->eflags |= MFE_APPLYPMOMZ; break; case mobj_tics: @@ -573,25 +573,25 @@ static int mobj_set(lua_State *L) } break; case mobj_friction: - mo->friction = (fixed_t)luaL_checkinteger(L, 3); + mo->friction = luaL_checkfixed(L, 3); break; case mobj_movefactor: - mo->movefactor = (fixed_t)luaL_checkinteger(L, 3); + mo->movefactor = luaL_checkfixed(L, 3); break; case mobj_fuse: mo->fuse = luaL_checkinteger(L, 3); break; case mobj_watertop: - mo->watertop = (fixed_t)luaL_checkinteger(L, 3); + mo->watertop = luaL_checkfixed(L, 3); break; case mobj_waterbottom: - mo->waterbottom = (fixed_t)luaL_checkinteger(L, 3); + mo->waterbottom = luaL_checkfixed(L, 3); break; case mobj_mobjnum: return UNIMPLEMENTED; case mobj_scale: { - fixed_t scale = (fixed_t)luaL_checkinteger(L, 3); + fixed_t scale = luaL_checkfixed(L, 3); if (scale < FRACUNIT/100) scale = FRACUNIT/100; mo->destscale = scale; @@ -600,14 +600,14 @@ static int mobj_set(lua_State *L) } case mobj_destscale: { - fixed_t scale = (fixed_t)luaL_checkinteger(L, 3); + fixed_t scale = luaL_checkfixed(L, 3); if (scale < FRACUNIT/100) scale = FRACUNIT/100; mo->destscale = scale; break; } case mobj_scalespeed: - mo->scalespeed = (fixed_t)luaL_checkinteger(L, 3); + mo->scalespeed = luaL_checkfixed(L, 3); break; case mobj_extravalue1: mo->extravalue1 = luaL_checkinteger(L, 3); diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 7f64fff62..64513ab97 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -109,15 +109,15 @@ static int player_get(lua_State *L) else if (fastcmp(field,"playerstate")) lua_pushinteger(L, plr->playerstate); else if (fastcmp(field,"viewz")) - lua_pushinteger(L, plr->viewz); + lua_pushfixed(L, plr->viewz); else if (fastcmp(field,"viewheight")) - lua_pushinteger(L, plr->viewheight); + lua_pushfixed(L, plr->viewheight); else if (fastcmp(field,"deltaviewheight")) - lua_pushinteger(L, plr->deltaviewheight); + lua_pushfixed(L, plr->deltaviewheight); else if (fastcmp(field,"bob")) - lua_pushinteger(L, plr->bob); + lua_pushfixed(L, plr->bob); else if (fastcmp(field,"aiming")) - lua_pushinteger(L, plr->aiming); + lua_pushangle(L, plr->aiming); else if (fastcmp(field,"health")) lua_pushinteger(L, plr->health); else if (fastcmp(field,"pity")) @@ -141,13 +141,13 @@ static int player_get(lua_State *L) else if (fastcmp(field,"score")) lua_pushinteger(L, plr->score); else if (fastcmp(field,"dashspeed")) - lua_pushinteger(L, plr->dashspeed); + lua_pushfixed(L, plr->dashspeed); else if (fastcmp(field,"dashtime")) lua_pushinteger(L, plr->dashtime); else if (fastcmp(field,"normalspeed")) - lua_pushinteger(L, plr->normalspeed); + lua_pushfixed(L, plr->normalspeed); else if (fastcmp(field,"runspeed")) - lua_pushinteger(L, plr->runspeed); + lua_pushfixed(L, plr->runspeed); else if (fastcmp(field,"thrustfactor")) lua_pushinteger(L, plr->thrustfactor); else if (fastcmp(field,"accelstart")) @@ -167,13 +167,13 @@ static int player_get(lua_State *L) else if (fastcmp(field,"revitem")) lua_pushinteger(L, plr->revitem); else if (fastcmp(field,"actionspd")) - lua_pushinteger(L, plr->actionspd); + lua_pushfixed(L, plr->actionspd); else if (fastcmp(field,"mindash")) - lua_pushinteger(L, plr->mindash); + lua_pushfixed(L, plr->mindash); else if (fastcmp(field,"maxdash")) - lua_pushinteger(L, plr->maxdash); + lua_pushfixed(L, plr->maxdash); else if (fastcmp(field,"jumpfactor")) - lua_pushinteger(L, plr->jumpfactor); + lua_pushfixed(L, plr->jumpfactor); else if (fastcmp(field,"lives")) lua_pushinteger(L, plr->lives); else if (fastcmp(field,"continues")) @@ -183,7 +183,7 @@ static int player_get(lua_State *L) else if (fastcmp(field,"gotcontinue")) lua_pushinteger(L, plr->gotcontinue); else if (fastcmp(field,"speed")) - lua_pushinteger(L, plr->speed); + lua_pushfixed(L, plr->speed); else if (fastcmp(field,"jumping")) lua_pushboolean(L, plr->jumping); else if (fastcmp(field,"secondjump")) @@ -205,13 +205,13 @@ static int player_get(lua_State *L) else if (fastcmp(field,"skidtime")) lua_pushinteger(L, plr->skidtime); else if (fastcmp(field,"cmomx")) - lua_pushinteger(L, plr->cmomx); + lua_pushfixed(L, plr->cmomx); else if (fastcmp(field,"cmomy")) - lua_pushinteger(L, plr->cmomy); + lua_pushfixed(L, plr->cmomy); else if (fastcmp(field,"rmomx")) - lua_pushinteger(L, plr->rmomx); + lua_pushfixed(L, plr->rmomx); else if (fastcmp(field,"rmomy")) - lua_pushinteger(L, plr->rmomy); + lua_pushfixed(L, plr->rmomy); else if (fastcmp(field,"numboxes")) lua_pushinteger(L, plr->numboxes); else if (fastcmp(field,"totalring")) @@ -239,11 +239,11 @@ static int player_get(lua_State *L) else if (fastcmp(field,"starposttime")) lua_pushinteger(L, plr->starposttime); else if (fastcmp(field,"starpostangle")) - lua_pushinteger(L, plr->starpostangle); + lua_pushangle(L, plr->starpostangle); else if (fastcmp(field,"angle_pos")) - lua_pushinteger(L, plr->angle_pos); + lua_pushangle(L, plr->angle_pos); else if (fastcmp(field,"old_angle_pos")) - lua_pushinteger(L, plr->old_angle_pos); + lua_pushangle(L, plr->old_angle_pos); else if (fastcmp(field,"axis1")) LUA_PushUserdata(L, plr->axis1, META_MOBJ); else if (fastcmp(field,"axis2")) @@ -305,16 +305,16 @@ static int player_get(lua_State *L) else if (fastcmp(field,"awayviewtics")) lua_pushinteger(L, plr->awayviewtics); else if (fastcmp(field,"awayviewaiming")) - lua_pushinteger(L, plr->awayviewaiming); + lua_pushangle(L, plr->awayviewaiming); else if (fastcmp(field,"spectator")) - lua_pushinteger(L, plr->spectator); + lua_pushboolean(L, plr->spectator); else if (fastcmp(field,"bot")) lua_pushinteger(L, plr->bot); else if (fastcmp(field,"jointime")) lua_pushinteger(L, plr->jointime); #ifdef HWRENDER else if (fastcmp(field,"fovadd")) - lua_pushinteger(L, plr->fovadd); + lua_pushfixed(L, plr->fovadd); #endif else { lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); @@ -354,15 +354,15 @@ static int player_set(lua_State *L) else if (fastcmp(field,"playerstate")) plr->playerstate = luaL_checkinteger(L, 3); else if (fastcmp(field,"viewz")) - plr->viewz = (fixed_t)luaL_checkinteger(L, 3); + plr->viewz = luaL_checkfixed(L, 3); else if (fastcmp(field,"viewheight")) - plr->viewheight = (fixed_t)luaL_checkinteger(L, 3); + plr->viewheight = luaL_checkfixed(L, 3); else if (fastcmp(field,"deltaviewheight")) - plr->deltaviewheight = (fixed_t)luaL_checkinteger(L, 3); + plr->deltaviewheight = luaL_checkfixed(L, 3); else if (fastcmp(field,"bob")) - plr->bob = (fixed_t)luaL_checkinteger(L, 3); + plr->bob = luaL_checkfixed(L, 3); else if (fastcmp(field,"aiming")) { - plr->aiming = (angle_t)luaL_checkinteger(L, 3); + plr->aiming = luaL_checkangle(L, 3); if (plr == &players[consoleplayer]) localaiming = plr->aiming; else if (plr == &players[secondarydisplayplayer]) @@ -391,13 +391,13 @@ static int player_set(lua_State *L) else if (fastcmp(field,"score")) plr->score = (UINT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"dashspeed")) - plr->dashspeed = (fixed_t)luaL_checkinteger(L, 3); + plr->dashspeed = luaL_checkfixed(L, 3); else if (fastcmp(field,"dashtime")) plr->dashtime = (INT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"normalspeed")) - plr->normalspeed = (fixed_t)luaL_checkinteger(L, 3); + plr->normalspeed = luaL_checkfixed(L, 3); else if (fastcmp(field,"runspeed")) - plr->runspeed = (fixed_t)luaL_checkinteger(L, 3); + plr->runspeed = luaL_checkfixed(L, 3); else if (fastcmp(field,"thrustfactor")) plr->thrustfactor = (UINT8)luaL_checkinteger(L, 3); else if (fastcmp(field,"accelstart")) @@ -433,7 +433,7 @@ static int player_set(lua_State *L) else if (fastcmp(field,"gotcontinue")) plr->gotcontinue = (UINT8)luaL_checkinteger(L, 3); else if (fastcmp(field,"speed")) - plr->speed = (fixed_t)luaL_checkinteger(L, 3); + plr->speed = luaL_checkfixed(L, 3); else if (fastcmp(field,"jumping")) plr->jumping = luaL_checkboolean(L, 3); else if (fastcmp(field,"secondjump")) @@ -455,13 +455,13 @@ static int player_set(lua_State *L) else if (fastcmp(field,"skidtime")) plr->skidtime = (tic_t)luaL_checkinteger(L, 3); else if (fastcmp(field,"cmomx")) - plr->cmomx = (fixed_t)luaL_checkinteger(L, 3); + plr->cmomx = luaL_checkfixed(L, 3); else if (fastcmp(field,"cmomy")) - plr->cmomy = (fixed_t)luaL_checkinteger(L, 3); + plr->cmomy = luaL_checkfixed(L, 3); else if (fastcmp(field,"rmomx")) - plr->rmomx = (fixed_t)luaL_checkinteger(L, 3); + plr->rmomx = luaL_checkfixed(L, 3); else if (fastcmp(field,"rmomy")) - plr->rmomy = (fixed_t)luaL_checkinteger(L, 3); + plr->rmomy = luaL_checkfixed(L, 3); else if (fastcmp(field,"numboxes")) plr->numboxes = (INT16)luaL_checkinteger(L, 3); else if (fastcmp(field,"totalring")) @@ -489,11 +489,11 @@ static int player_set(lua_State *L) else if (fastcmp(field,"starposttime")) plr->starposttime = (tic_t)luaL_checkinteger(L, 3); else if (fastcmp(field,"starpostangle")) - plr->starpostangle = (angle_t)luaL_checkinteger(L, 3); + plr->starpostangle = luaL_checkangle(L, 3); else if (fastcmp(field,"angle_pos")) - plr->angle_pos = (angle_t)luaL_checkinteger(L, 3); + plr->angle_pos = luaL_checkangle(L, 3); else if (fastcmp(field,"old_angle_pos")) - plr->old_angle_pos = (angle_t)luaL_checkinteger(L, 3); + plr->old_angle_pos = luaL_checkangle(L, 3); else if (fastcmp(field,"axis1")) P_SetTarget(&plr->axis1, *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ))); else if (fastcmp(field,"axis2")) @@ -569,7 +569,7 @@ static int player_set(lua_State *L) P_SetTarget(&plr->awayviewmobj, plr->mo); // but since the script might set awayviewmobj immediately AFTER setting awayviewtics, use player mobj as filler for now. } else if (fastcmp(field,"awayviewaiming")) - plr->awayviewaiming = (angle_t)luaL_checkinteger(L, 3); + plr->awayviewaiming = luaL_checkangle(L, 3); else if (fastcmp(field,"spectator")) plr->spectator = lua_toboolean(L, 3); else if (fastcmp(field,"bot")) @@ -578,7 +578,7 @@ static int player_set(lua_State *L) plr->jointime = (tic_t)luaL_checkinteger(L, 3); #ifdef HWRENDER else if (fastcmp(field,"fovadd")) - plr->fovadd = (fixed_t)luaL_checkinteger(L, 3); + plr->fovadd = luaL_checkfixed(L, 3); #endif else { lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); diff --git a/src/lua_script.c b/src/lua_script.c index 8b40d9f00..145104d9a 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -442,7 +442,6 @@ enum ARCH_NULL=0, ARCH_BOOLEAN, ARCH_SIGNED, - ARCH_UNSIGNED, ARCH_STRING, ARCH_TABLE, @@ -522,13 +521,8 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex) case LUA_TNUMBER: { lua_Integer number = lua_tointeger(gL, myindex); - if (number < 0) { - WRITEUINT8(save_p, ARCH_SIGNED); - WRITEFIXED(save_p, number); - } else { - WRITEUINT8(save_p, ARCH_UNSIGNED); - WRITEANGLE(save_p, number); - } + WRITEUINT8(save_p, ARCH_SIGNED); + WRITEFIXED(save_p, number); break; } case LUA_TSTRING: @@ -797,9 +791,6 @@ static UINT8 UnArchiveValue(int TABLESINDEX) case ARCH_SIGNED: lua_pushinteger(gL, READFIXED(save_p)); break; - case ARCH_UNSIGNED: - lua_pushinteger(gL, READANGLE(save_p)); - break; case ARCH_STRING: { char value[1024]; @@ -948,6 +939,14 @@ static void NetArchiveHook(lua_CFunction archFunc) lua_pop(gL, 2); } +void LUA_Step(void) +{ + if (!gL) + return; + lua_settop(gL, 0); + lua_gc(gL, LUA_GCSTEP, 1); +} + void LUA_Archive(void) { INT32 i; diff --git a/src/lua_script.h b/src/lua_script.h index eaef13d1e..292160a0b 100644 --- a/src/lua_script.h +++ b/src/lua_script.h @@ -19,9 +19,21 @@ #include "blua/lua.h" #include "blua/lualib.h" #include "blua/lauxlib.h" + #define lua_optboolean(L, i) (!lua_isnoneornil(L, i) && lua_toboolean(L, i)) #define lua_opttrueboolean(L, i) (lua_isnoneornil(L, i) || lua_toboolean(L, i)) +// fixed_t casting +// TODO add some distinction between fixed numbers and integer numbers +// for at least the purpose of printing and maybe math. +#define luaL_checkfixed(L, i) luaL_checkinteger(L, i) +#define lua_pushfixed(L, f) lua_pushinteger(L, f) + +// angle_t casting +// we reduce the angle to a fixed point between 0.0 and 1.0 +#define luaL_checkangle(L, i) (((angle_t)(luaL_checkfixed(L, i)&0xFFFF))<<16) +#define lua_pushangle(L, a) lua_pushfixed(L, a>>16) + #ifdef _DEBUG void LUA_ClearExtVars(void); #endif @@ -36,6 +48,7 @@ void LUA_InvalidateUserdata(void *data); void LUA_InvalidateLevel(void); void LUA_InvalidateMapthings(void); void LUA_InvalidatePlayer(player_t *player); +void LUA_Step(void); void LUA_Archive(void); void LUA_UnArchive(void); void Got_Luacmd(UINT8 **cp, INT32 playernum); // lua_consolelib.c diff --git a/src/lua_skinlib.c b/src/lua_skinlib.c index f797f30d6..f07b4564c 100644 --- a/src/lua_skinlib.c +++ b/src/lua_skinlib.c @@ -147,19 +147,19 @@ static int skin_get(lua_State *L) lua_pushinteger(L, skin->revitem); break; case skin_actionspd: - lua_pushinteger(L, skin->actionspd); + lua_pushfixed(L, skin->actionspd); break; case skin_mindash: - lua_pushinteger(L, skin->mindash); + lua_pushfixed(L, skin->mindash); break; case skin_maxdash: - lua_pushinteger(L, skin->maxdash); + lua_pushfixed(L, skin->maxdash); break; case skin_normalspeed: - lua_pushinteger(L, skin->normalspeed); + lua_pushfixed(L, skin->normalspeed); break; case skin_runspeed: - lua_pushinteger(L, skin->runspeed); + lua_pushfixed(L, skin->runspeed); break; case skin_thrustfactor: lua_pushinteger(L, skin->thrustfactor); @@ -171,7 +171,7 @@ static int skin_get(lua_State *L) lua_pushinteger(L, skin->acceleration); break; case skin_jumpfactor: - lua_pushinteger(L, skin->jumpfactor); + lua_pushfixed(L, skin->jumpfactor); break; case skin_starttranscolor: lua_pushinteger(L, skin->starttranscolor); diff --git a/src/p_inter.c b/src/p_inter.c index 8eaa4765a..478bd459c 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1478,7 +1478,7 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour return; // Presumably it's obvious what's happening in splitscreen. #ifdef HAVE_BLUA - if (LUAh_DeathMsg(player, inflictor, source)) + if (LUAh_HurtMsg(player, inflictor, source)) return; #endif