diff --git a/src/dehacked.c b/src/dehacked.c index 212715dd3..1ec601244 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7285,6 +7285,14 @@ struct { {"FF_COLORMAPONLY",FF_COLORMAPONLY}, ///< Only copy the colormap, not the lightlevel {"FF_GOOWATER",FF_GOOWATER}, ///< Used with ::FF_SWIMMABLE. Makes thick bouncey goop. +#ifdef ESLOPE + // Slope flags + {"SL_NOPHYSICS",SL_NOPHYSICS}, // Don't do momentum adjustment with this slope + {"SL_NODYNAMIC",SL_NODYNAMIC}, // Slope will never need to move during the level, so don't fuss with recalculating it + {"SL_ANCHORVERTEX",SL_ANCHORVERTEX},// Slope is using a Slope Vertex Thing to anchor its position + {"SL_VERTEXSLOPE",SL_VERTEXSLOPE}, // Slope is built from three Slope Vertex Things +#endif + // Angles {"ANG1",ANG1}, {"ANG2",ANG2}, diff --git a/src/lua_baselib.c b/src/lua_baselib.c index e8e8fd020..f60756f1c 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -14,6 +14,9 @@ #ifdef HAVE_BLUA #include "p_local.h" #include "p_setup.h" // So we can have P_SetupLevelSky +#ifdef ESLOPE +#include "p_slopes.h" // P_GetZAt +#endif #include "z_zone.h" #include "r_main.h" #include "r_things.h" @@ -1547,6 +1550,24 @@ static int lib_evCrumbleChain(lua_State *L) return 0; } +#ifdef ESLOPE +// P_SLOPES +//////////// + +static int lib_pGetZAt(lua_State *L) +{ + pslope_t *slope = *((pslope_t **)luaL_checkudata(L, 1, META_SLOPE)); + fixed_t x = luaL_checkfixed(L, 2); + fixed_t y = luaL_checkfixed(L, 3); + //HUDSAFE + if (!slope) + return LUA_ErrInvalid(L, "pslope_t"); + + lua_pushfixed(L, P_GetZAt(slope, x, y)); + return 1; +} +#endif + // R_DEFS //////////// @@ -2113,6 +2134,11 @@ static luaL_Reg lib[] = { {"P_StartQuake",lib_pStartQuake}, {"EV_CrumbleChain",lib_evCrumbleChain}, +#ifdef ESLOPE + // p_slopes + {"P_GetZAt",lib_pGetZAt}, +#endif + // r_defs {"R_PointToAngle",lib_rPointToAngle}, {"R_PointToAngle2",lib_rPointToAngle2}, diff --git a/src/lua_libs.h b/src/lua_libs.h index 931cf62d0..15d988ef6 100644 --- a/src/lua_libs.h +++ b/src/lua_libs.h @@ -38,6 +38,11 @@ extern lua_State *gL; #define META_SUBSECTOR "SUBSECTOR_T*" #define META_SECTOR "SECTOR_T*" #define META_FFLOOR "FFLOOR_T*" +#ifdef ESLOPE +#define META_SLOPE "PSLOPE_T*" +#define META_VECTOR2 "VECTOR2_T" +#define META_VECTOR3 "VECTOR3_T" +#endif #define META_MAPHEADER "MAPHEADER_T*" #define META_CVAR "CONSVAR_T*" diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 4e9dbd5af..b59c3c178 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -16,6 +16,10 @@ #include "p_local.h" #include "p_setup.h" #include "z_zone.h" +#ifdef ESLOPE +#include "p_slopes.h" +#endif +#include "r_main.h" #include "lua_script.h" #include "lua_libs.h" @@ -38,7 +42,14 @@ enum sector_e { sector_heightsec, sector_camsec, sector_lines, +#ifdef ESLOPE + sector_ffloors, + sector_fslope, + sector_cslope, + sector_hasslope +#else sector_ffloors +#endif }; static const char *const sector_opt[] = { @@ -55,6 +66,11 @@ static const char *const sector_opt[] = { "camsec", "lines", "ffloors", +#ifdef ESLOPE + "f_slope", + "c_slope", + "hasslope", +#endif NULL}; enum subsector_e { @@ -160,6 +176,10 @@ enum ffloor_e { ffloor_toplightlevel, ffloor_bottomheight, ffloor_bottompic, +#ifdef ESLOPE + ffloor_tslope, + ffloor_bslope, +#endif ffloor_sector, ffloor_flags, ffloor_master, @@ -176,6 +196,10 @@ static const char *const ffloor_opt[] = { "toplightlevel", "bottomheight", "bottompic", +#ifdef ESLOPE + "t_slope", + "b_slope", +#endif "sector", // secnum pushed as control sector userdata "flags", "master", // control linedef @@ -185,6 +209,47 @@ static const char *const ffloor_opt[] = { "alpha", NULL}; +#ifdef ESLOPE +enum slope_e { + slope_valid = 0, + slope_o, + slope_d, + slope_zdelta, + slope_normal, + slope_zangle, + slope_xydirection, + slope_sourceline, + slope_refpos, + slope_flags +}; + +static const char *const slope_opt[] = { + "valid", + "o", + "d", + "zdelta", + "normal", + "zangle", + "xydirection", + "sourceline", + "refpos", + "flags", + NULL}; + +// shared by both vector2_t and vector3_t +enum vector_e { + vector_x = 0, + vector_y, + vector_z +}; + +static const char *const vector_opt[] = { + "x", + "y", + "z", + NULL}; +#endif + static const char *const array_opt[] ={"iterate",NULL}; static const char *const valid_opt[] ={"valid",NULL}; @@ -399,6 +464,17 @@ static int sector_get(lua_State *L) LUA_PushUserdata(L, sector->ffloors, META_FFLOOR); lua_pushcclosure(L, sector_iterate, 2); // push lib_iterateFFloors and sector->ffloors as upvalues for the function return 1; +#ifdef ESLOPE + case sector_fslope: // f_slope + LUA_PushUserdata(L, sector->f_slope, META_SLOPE); + return 1; + case sector_cslope: // c_slope + LUA_PushUserdata(L, sector->c_slope, META_SLOPE); + return 1; + case sector_hasslope: // hasslope + lua_pushboolean(L, sector->hasslope); + return 1; +#endif } return 0; } @@ -421,6 +497,11 @@ static int sector_set(lua_State *L) case sector_heightsec: // heightsec case sector_camsec: // camsec case sector_ffloors: // ffloors +#ifdef ESLOPE + case sector_fslope: // f_slope + case sector_cslope: // c_slope + case sector_hasslope: // hasslope +#endif default: return luaL_error(L, "sector_t field " LUA_QS " cannot be set.", sector_opt[field]); case sector_floorheight: { // floorheight @@ -1055,6 +1136,14 @@ static int ffloor_get(lua_State *L) lua_pushlstring(L, levelflat->name, 8); return 1; } +#ifdef ESLOPE + case ffloor_tslope: + LUA_PushUserdata(L, *ffloor->t_slope, META_SLOPE); + return 1; + case ffloor_bslope: + LUA_PushUserdata(L, *ffloor->b_slope, META_SLOPE); + return 1; +#endif case ffloor_sector: LUA_PushUserdata(L, §ors[ffloor->secnum], META_SECTOR); return 1; @@ -1094,6 +1183,10 @@ static int ffloor_set(lua_State *L) switch(field) { case ffloor_valid: // valid +#ifdef ESLOPE + case ffloor_tslope: // t_slope + case ffloor_bslope: // b_slope +#endif case ffloor_sector: // sector case ffloor_master: // master case ffloor_target: // target @@ -1154,6 +1247,181 @@ static int ffloor_set(lua_State *L) return 0; } +#ifdef ESLOPE +static int slope_get(lua_State *L) +{ + pslope_t *slope = *((pslope_t **)luaL_checkudata(L, 1, META_SLOPE)); + enum slope_e field = luaL_checkoption(L, 2, slope_opt[0], slope_opt); + + if (!slope) + { + if (field == slope_valid) { + lua_pushboolean(L, 0); + return 1; + } + return luaL_error(L, "accessed pslope_t doesn't exist anymore."); + } + + switch(field) + { + case slope_valid: // valid + lua_pushboolean(L, 1); + return 1; + case slope_o: // o + LUA_PushUserdata(L, &slope->o, META_VECTOR3); + return 1; + case slope_d: // d + LUA_PushUserdata(L, &slope->d, META_VECTOR2); + return 1; + case slope_zdelta: // zdelta + lua_pushfixed(L, slope->zdelta); + return 1; + case slope_normal: // normal + LUA_PushUserdata(L, &slope->normal, META_VECTOR3); + return 1; + case slope_zangle: // zangle + lua_pushangle(L, slope->zangle); + return 1; + case slope_xydirection: // xydirection + lua_pushangle(L, slope->xydirection); + return 1; + case slope_sourceline: // source linedef + LUA_PushUserdata(L, slope->sourceline, META_LINE); + return 1; + case slope_refpos: // refpos + lua_pushinteger(L, slope->refpos); + return 1; + case slope_flags: // flags + lua_pushinteger(L, slope->flags); + return 1; + } + return 0; +} + +static int slope_set(lua_State *L) +{ + pslope_t *slope = *((pslope_t **)luaL_checkudata(L, 1, META_SLOPE)); + enum slope_e field = luaL_checkoption(L, 2, slope_opt[0], slope_opt); + + if (!slope) + return luaL_error(L, "accessed pslope_t doesn't exist anymore."); + + if (hud_running) + return luaL_error(L, "Do not alter pslope_t in HUD rendering code!"); + + switch(field) // todo: reorganize this shit + { + case slope_valid: // valid + case slope_sourceline: // sourceline + case slope_d: // d + case slope_flags: // flags + case slope_normal: // normal + case slope_refpos: // refpos + default: + return luaL_error(L, "pslope_t field " LUA_QS " cannot be set.", slope_opt[field]); + case slope_o: { // o + luaL_checktype(L, 3, LUA_TTABLE); + + lua_getfield(L, 3, "x"); + if (lua_isnil(L, -1)) + { + lua_pop(L, 1); + lua_rawgeti(L, 3, 1); + } + if (!lua_isnil(L, -1)) + slope->o.x = luaL_checkfixed(L, -1); + else + slope->o.x = 0; + lua_pop(L, 1); + + lua_getfield(L, 3, "y"); + if (lua_isnil(L, -1)) + { + lua_pop(L, 1); + lua_rawgeti(L, 3, 2); + } + if (!lua_isnil(L, -1)) + slope->o.y = luaL_checkfixed(L, -1); + else + slope->o.y = 0; + lua_pop(L, 1); + + lua_getfield(L, 3, "z"); + if (lua_isnil(L, -1)) + { + lua_pop(L, 1); + lua_rawgeti(L, 3, 3); + } + if (!lua_isnil(L, -1)) + slope->o.z = luaL_checkfixed(L, -1); + else + slope->o.z = 0; + lua_pop(L, 1); + break; + } + case slope_zdelta: { // zdelta, this is temp until i figure out wtf to do + slope->zdelta = luaL_checkfixed(L, 3); + slope->zangle = R_PointToAngle2(0, 0, FRACUNIT, -slope->zdelta); + P_CalculateSlopeNormal(slope); + break; + } + case slope_zangle: { // zangle + angle_t zangle = luaL_checkangle(L, 3); + if (zangle == ANGLE_90 || zangle == ANGLE_270) + return luaL_error(L, "invalid zangle for slope!"); + slope->zangle = zangle; + slope->zdelta = -FINETANGENT(((slope->zangle+ANGLE_90)>>ANGLETOFINESHIFT) & 4095); + P_CalculateSlopeNormal(slope); + break; + } + case slope_xydirection: // xydirection + slope->xydirection = luaL_checkangle(L, 3); + slope->d.x = -FINECOSINE((slope->xydirection>>ANGLETOFINESHIFT) & FINEMASK); + slope->d.y = -FINESINE((slope->xydirection>>ANGLETOFINESHIFT) & FINEMASK); + P_CalculateSlopeNormal(slope); + break; + } + return 0; +} + +static int vector2_get(lua_State *L) +{ + vector2_t *vec = *((vector2_t **)luaL_checkudata(L, 1, META_VECTOR2)); + enum vector_e field = luaL_checkoption(L, 2, vector_opt[0], vector_opt); + + if (!vec) + return luaL_error(L, "accessed vector2_t doesn't exist anymore."); + + switch(field) + { + case vector_x: lua_pushfixed(L, vec->x); return 1; + case vector_y: lua_pushfixed(L, vec->y); return 1; + default: break; + } + + return 0; +} + +static int vector3_get(lua_State *L) +{ + vector3_t *vec = *((vector3_t **)luaL_checkudata(L, 1, META_VECTOR3)); + enum vector_e field = luaL_checkoption(L, 2, vector_opt[0], vector_opt); + + if (!vec) + return luaL_error(L, "accessed vector3_t doesn't exist anymore."); + + switch(field) + { + case vector_x: lua_pushfixed(L, vec->x); return 1; + case vector_y: lua_pushfixed(L, vec->y); return 1; + case vector_z: lua_pushfixed(L, vec->z); return 1; + default: break; + } + + return 0; +} +#endif + static int lib_getMapheaderinfo(lua_State *L) { // i -> mapheaderinfo[i-1] @@ -1330,6 +1598,26 @@ int LUA_MapLib(lua_State *L) lua_setfield(L, -2, "__newindex"); lua_pop(L, 1); +#ifdef ESLOPE + luaL_newmetatable(L, META_SLOPE); + lua_pushcfunction(L, slope_get); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, slope_set); + lua_setfield(L, -2, "__newindex"); + lua_pop(L, 1); + + luaL_newmetatable(L, META_VECTOR2); + lua_pushcfunction(L, vector2_get); + lua_setfield(L, -2, "__index"); + lua_pop(L, 1); + + luaL_newmetatable(L, META_VECTOR3); + lua_pushcfunction(L, vector3_get); + lua_setfield(L, -2, "__index"); + lua_pop(L, 1); +#endif + luaL_newmetatable(L, META_MAPHEADER); lua_pushcfunction(L, mapheaderinfo_get); lua_setfield(L, -2, "__index"); diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 6bb1388fc..05091f126 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -80,7 +80,12 @@ enum mobj_e { mobj_extravalue1, mobj_extravalue2, mobj_cusval, +#ifdef ESLOPE + mobj_cvmem, + mobj_standingslope +#else mobj_cvmem +#endif }; static const char *const mobj_opt[] = { @@ -140,6 +145,9 @@ static const char *const mobj_opt[] = { "extravalue2", "cusval", "cvmem", +#ifdef ESLOPE + "standingslope", +#endif NULL}; #define UNIMPLEMENTED luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", mobj_opt[field]) @@ -343,6 +351,11 @@ static int mobj_get(lua_State *L) case mobj_cvmem: lua_pushinteger(L, mo->cvmem); break; +#ifdef ESLOPE + case mobj_standingslope: + LUA_PushUserdata(L, mo->standingslope, META_SLOPE); + break; +#endif default: // extra custom variables in Lua memory lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); I_Assert(lua_istable(L, -1)); @@ -634,6 +647,10 @@ static int mobj_set(lua_State *L) case mobj_cvmem: mo->cvmem = luaL_checkinteger(L, 3); break; +#ifdef ESLOPE + case mobj_standingslope: + return NOSET; +#endif default: lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); I_Assert(lua_istable(L, -1)); diff --git a/src/lua_script.c b/src/lua_script.c index 3f572f68f..e6b4fc9f4 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -22,6 +22,9 @@ #include "byteptr.h" #include "p_saveg.h" #include "p_local.h" +#ifdef ESLOPE +#include "p_slopes.h" // for P_SlopeById +#endif #ifdef LUA_ALLOW_BYTECODE #include "d_netfil.h" // for LUA_DumpFile #endif @@ -457,6 +460,9 @@ enum ARCH_SIDE, ARCH_SUBSECTOR, ARCH_SECTOR, +#ifdef ESLOPE + ARCH_SLOPE, +#endif ARCH_MAPHEADER, ARCH_TEND=0xFF, @@ -476,6 +482,9 @@ static const struct { {META_SIDE, ARCH_SIDE}, {META_SUBSECTOR,ARCH_SUBSECTOR}, {META_SECTOR, ARCH_SECTOR}, +#ifdef ESLOPE + {META_SLOPE, ARCH_SLOPE}, +#endif {META_MAPHEADER, ARCH_MAPHEADER}, {NULL, ARCH_NULL} }; @@ -680,6 +689,19 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex) } break; } +#ifdef ESLOPE + case ARCH_SLOPE: + { + pslope_t *slope = *((pslope_t **)lua_touserdata(gL, myindex)); + if (!slope) + WRITEUINT8(save_p, ARCH_NULL); + else { + WRITEUINT8(save_p, ARCH_SLOPE); + WRITEUINT16(save_p, slope->id); + } + break; + } +#endif case ARCH_MAPHEADER: { mapheader_t *header = *((mapheader_t **)lua_touserdata(gL, myindex)); @@ -884,6 +906,11 @@ static UINT8 UnArchiveValue(int TABLESINDEX) case ARCH_SECTOR: LUA_PushUserdata(gL, §ors[READUINT16(save_p)], META_SECTOR); break; +#ifdef ESLOPE + case ARCH_SLOPE: + LUA_PushUserdata(gL, P_SlopeById(READUINT16(save_p)), META_SLOPE); + break; +#endif case ARCH_MAPHEADER: LUA_PushUserdata(gL, mapheaderinfo[READUINT16(save_p)], META_MAPHEADER); break; diff --git a/src/p_slopes.c b/src/p_slopes.c index d939fee98..b49cd3e2d 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -29,7 +29,7 @@ static pslope_t *slopelist = NULL; static UINT16 slopecount = 0; // Calculate line normal -static void P_CalculateSlopeNormal(pslope_t *slope) { +void P_CalculateSlopeNormal(pslope_t *slope) { slope->normal.z = FINECOSINE(slope->zangle>>ANGLETOFINESHIFT); slope->normal.x = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.x); slope->normal.y = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.y); diff --git a/src/p_slopes.h b/src/p_slopes.h index de38f1d9e..2ff775051 100644 --- a/src/p_slopes.h +++ b/src/p_slopes.h @@ -14,6 +14,7 @@ #define P_SLOPES_H__ #ifdef ESLOPE +void P_CalculateSlopeNormal(pslope_t *slope); void P_ResetDynamicSlopes(void); void P_RunDynamicSlopes(void); // P_SpawnSlope_Line