diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 04bbaa928..c7b1ec38e 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -11,6 +11,7 @@ /// \brief custom HUD rendering library for Lua scripting #include "doomdef.h" +#include "fastcmp.h" #ifdef HAVE_BLUA #include "r_defs.h" #include "r_local.h" @@ -346,6 +347,118 @@ static int libd_cachePatch(lua_State *L) return 1; } +// this is structured like getSprite2Patch in vanilla 2.2 +// v.getSpritePatch(skin, sprite, [frame, [angle, [rollangle]]]) +static int libd_getSpritePatch(lua_State *L) +{ + UINT32 i; // sprite prefix + INT32 skn = -1; // skin number + UINT32 frame = 0; // 'A' + UINT8 angle = 0; + spritedef_t *sprdef; + spriteframe_t *sprframe; +#ifdef ROTSPRITE + spriteinfo_t *sprinfo; +#endif + HUDONLY + + // mashing together the stuff from getSprite2Patch: + // get skin first! + if (!lua_isnoneornil(L, 1)) // ONLY do this if we have a skin + { + if (lua_isnumber(L, 1)) // find skin by number + { + skn = lua_tonumber(L, 1); + if (skn < 0 || skn >= MAXSKINS) + return luaL_error(L, "skin number %d out of range (0 - %d)", skn, MAXSKINS-1); + if (skn >= numskins) + return 0; + } + else // find skin by name + { + const char *name = luaL_checkstring(L, 1); + for (skn = 0; skn < numskins; skn++) + if (fastcmp(skins[skn].name, name)) + break; + if (skn >= numskins) + return 0; + } + } + + lua_remove(L, 1); // remove skin now + + if (lua_isnumber(L, 1)) // sprite number given, e.g. SPR_THOK + { + i = lua_tonumber(L, 1); + if (i >= NUMSPRITES) + return 0; + } + else if (lua_isstring(L, 1)) // sprite prefix name given, e.g. "THOK" + { + const char *name = lua_tostring(L, 1); + for (i = 0; i < NUMSPRITES; i++) + if (fastcmp(name, sprnames[i])) + break; + if (i >= NUMSPRITES) + return 0; + } + else + return 0; + + // get outta dodge if we're a playersprite and have no skin + if ((i == SPR_PLAY) && (skn < 0)) + return luaL_error(L, "You must provide a skin for player sprites!"); + + if (skn < 0) // standard sprite + { + sprdef = &sprites[i]; + sprinfo = &spriteinfo[i]; + } + else // player skin + { + sprdef = &skins[skn].spritedef; + sprinfo = &skins[skn].sprinfo; + } + + // set frame number + frame = luaL_optinteger(L, 2, 0); + frame &= FF_FRAMEMASK; // ignore any bits that are not the actual frame, just in case + if (frame >= sprdef->numframes) + return 0; + // set angle number + sprframe = &sprdef->spriteframes[frame]; + angle = luaL_optinteger(L, 3, 1); + + // convert WAD editor angle numbers (1-8) to internal angle numbers (0-7) + // keep 0 the same since we'll make it default to angle 1 (which is internally 0) + // in case somebody didn't know that angle 0 really just maps all 8 angles to the same patch + if (angle != 0) + angle--; + + if (angle >= 8) // out of range? + angle = (angle & 7); // modulus angle by 8 + + // rotsprite????? + if (lua_isnumber(L, 4) && (cv_spriteroll.value)) + { + angle_t rollangle = luaL_checkangle(L, 4); + INT32 rot = R_GetRollAngle(rollangle); + + if (rot) { + patch_t *rotsprite = Patch_GetRotatedSprite(sprframe, frame, angle, sprframe->flip & (1<lumppat[angle], PU_STATIC), META_PATCH); + lua_pushboolean(L, (sprframe->flip & (1<