2014-03-15 16:59:03 +00:00
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
2016-05-18 00:42:11 +00:00
// Copyright (C) 2012-2016 by John "JTE" Muniz.
2019-12-06 18:49:42 +00:00
// Copyright (C) 2012-2019 by Sonic Team Junior.
2014-03-15 16:59:03 +00:00
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file lua_baselib.c
/// \brief basic functions for Lua scripting
# include "doomdef.h"
# ifdef HAVE_BLUA
2019-12-19 05:13:09 +00:00
# include "fastcmp.h"
2014-03-15 16:59:03 +00:00
# include "p_local.h"
# include "p_setup.h" // So we can have P_SetupLevelSky
2018-10-20 20:08:59 +00:00
# ifdef ESLOPE
# include "p_slopes.h" // P_GetZAt
# endif
2014-03-15 16:59:03 +00:00
# include "z_zone.h"
# include "r_main.h"
2014-04-14 05:14:58 +00:00
# include "r_things.h"
2014-03-15 16:59:03 +00:00
# include "m_random.h"
# include "s_sound.h"
# include "g_game.h"
2019-12-19 05:20:49 +00:00
# include "m_menu.h"
2019-12-19 05:13:09 +00:00
# include "y_inter.h"
2018-07-31 09:10:02 +00:00
# include "hu_stuff.h" // HU_AddChatText
2018-11-07 23:07:34 +00:00
# include "console.h"
# include "d_netcmd.h" // IsPlayerAdmin
2014-03-15 16:59:03 +00:00
# include "lua_script.h"
# include "lua_libs.h"
# include "lua_hud.h" // hud_running errors
2017-01-18 22:02:28 +00:00
# define NOHUD if (hud_running)\
return luaL_error ( L , " HUD rendering code should not call this function! " ) ;
2014-03-15 16:59:03 +00:00
boolean luaL_checkboolean ( lua_State * L , int narg ) {
luaL_checktype ( L , narg , LUA_TBOOLEAN ) ;
return lua_toboolean ( L , narg ) ;
}
// String concatination
static int lib_concat ( lua_State * L )
{
int n = lua_gettop ( L ) ; /* number of arguments */
int i ;
char * r = NULL ;
size_t rl = 0 , sl ;
lua_getglobal ( L , " tostring " ) ;
for ( i = 1 ; i < = n ; i + + ) {
const char * s ;
lua_pushvalue ( L , - 1 ) ; /* function to be called */
lua_pushvalue ( L , i ) ; /* value to print */
lua_call ( L , 1 , 1 ) ;
s = lua_tolstring ( L , - 1 , & sl ) ; /* get result */
if ( s = = NULL )
return luaL_error ( L , LUA_QL ( " tostring " ) " must return a string to "
LUA_QL ( " __add " ) ) ;
r = Z_Realloc ( r , rl + sl , PU_STATIC , NULL ) ;
M_Memcpy ( r + rl , s , sl ) ;
rl + = sl ;
lua_pop ( L , 1 ) ; /* pop result */
}
lua_pushlstring ( L , r , rl ) ;
Z_Free ( r ) ;
return 1 ;
}
// Wrapper for CONS_Printf
// Copied from base Lua code
static int lib_print ( lua_State * L )
{
int n = lua_gettop ( L ) ; /* number of arguments */
int i ;
//HUDSAFE
lua_getglobal ( L , " tostring " ) ;
for ( i = 1 ; i < = n ; i + + ) {
const char * s ;
lua_pushvalue ( L , - 1 ) ; /* function to be called */
lua_pushvalue ( L , i ) ; /* value to print */
lua_call ( L , 1 , 1 ) ;
s = lua_tostring ( L , - 1 ) ; /* get result */
if ( s = = NULL )
return luaL_error ( L , LUA_QL ( " tostring " ) " must return a string to "
LUA_QL ( " print " ) ) ;
if ( i > 1 ) CONS_Printf ( " \n " ) ;
CONS_Printf ( " %s " , s ) ;
lua_pop ( L , 1 ) ; /* pop result */
}
CONS_Printf ( " \n " ) ;
return 0 ;
}
2018-07-31 09:10:02 +00:00
// Print stuff in the chat, or in the console if we can't.
static int lib_chatprint ( lua_State * L )
{
const char * str = luaL_checkstring ( L , 1 ) ; // retrieve string
2018-12-22 11:34:17 +00:00
boolean sound = lua_optboolean ( L , 2 ) ; // retrieve sound boolean
2018-12-18 00:02:22 +00:00
int len = strlen ( str ) ;
2018-07-31 09:10:02 +00:00
if ( str = = NULL ) // error if we don't have a string!
return luaL_error ( L , LUA_QL ( " tostring " ) " must return a string to " LUA_QL ( " chatprint " ) ) ;
2018-12-18 00:02:22 +00:00
2018-07-31 09:10:02 +00:00
if ( len > 255 ) // string is too long!!!
return luaL_error ( L , " String exceeds the 255 characters limit of the chat buffer. " ) ;
2018-12-17 19:43:59 +00:00
HU_AddChatText ( str , sound ) ;
2018-07-31 09:10:02 +00:00
return 0 ;
}
// Same as above, but do it for only one player.
static int lib_chatprintf ( lua_State * L )
{
int n = lua_gettop ( L ) ; /* number of arguments */
2018-12-18 00:02:22 +00:00
const char * str = luaL_checkstring ( L , 2 ) ; // retrieve string
2018-12-22 11:34:17 +00:00
boolean sound = lua_optboolean ( L , 3 ) ; // sound?
2018-12-18 00:02:22 +00:00
int len = strlen ( str ) ;
2018-07-31 09:10:02 +00:00
player_t * plr ;
2018-12-18 00:02:22 +00:00
2018-07-31 09:10:02 +00:00
if ( n < 2 )
return luaL_error ( L , " chatprintf requires at least two arguments: player and text. " ) ;
2018-12-17 19:43:59 +00:00
2018-07-31 09:10:02 +00:00
plr = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ; // retrieve player
if ( ! plr )
return LUA_ErrInvalid ( L , " player_t " ) ;
if ( plr ! = & players [ consoleplayer ] )
return 0 ;
2018-12-17 19:43:59 +00:00
2018-07-31 09:10:02 +00:00
if ( str = = NULL ) // error if we don't have a string!
return luaL_error ( L , LUA_QL ( " tostring " ) " must return a string to " LUA_QL ( " chatprintf " ) ) ;
2018-12-18 00:02:22 +00:00
2018-07-31 09:10:02 +00:00
if ( len > 255 ) // string is too long!!!
return luaL_error ( L , " String exceeds the 255 characters limit of the chat buffer. " ) ;
2018-12-17 19:43:59 +00:00
HU_AddChatText ( str , sound ) ;
2018-07-31 09:10:02 +00:00
return 0 ;
}
2017-01-19 18:30:55 +00:00
static const struct {
const char * meta ;
2017-01-19 21:35:53 +00:00
const char * utype ;
2017-01-19 18:30:55 +00:00
} meta2utype [ ] = {
2017-01-19 21:35:53 +00:00
{ META_STATE , " state_t " } ,
{ META_MOBJINFO , " mobjinfo_t " } ,
{ META_SFXINFO , " sfxinfo_t " } ,
2019-11-07 06:11:16 +00:00
{ META_SPRITEINFO , " spriteinfo_t " } ,
2019-11-08 02:42:14 +00:00
{ META_PIVOTLIST , " spriteframepivot_t[] " } ,
{ META_FRAMEPIVOT , " spriteframepivot_t " } ,
2017-01-19 21:35:53 +00:00
{ META_MOBJ , " mobj_t " } ,
{ META_MAPTHING , " mapthing_t " } ,
{ META_PLAYER , " player_t " } ,
{ META_TICCMD , " ticcmd_t " } ,
{ META_SKIN , " skin_t " } ,
{ META_POWERS , " player_t.powers " } ,
{ META_SOUNDSID , " skin_t.soundsid " } ,
{ META_VERTEX , " vertex_t " } ,
{ META_LINE , " line_t " } ,
{ META_SIDE , " side_t " } ,
{ META_SUBSECTOR , " subsector_t " } ,
{ META_SECTOR , " sector_t " } ,
{ META_FFLOOR , " ffloor_t " } ,
2017-01-19 18:30:55 +00:00
# ifdef HAVE_LUA_SEGS
2017-01-19 21:35:53 +00:00
{ META_SEG , " seg_t " } ,
{ META_NODE , " node_t " } ,
2017-01-19 18:30:55 +00:00
# endif
2017-01-19 21:35:53 +00:00
{ META_MAPHEADER , " mapheader_t " } ,
2017-01-19 18:30:55 +00:00
2017-01-19 21:35:53 +00:00
{ META_CVAR , " consvar_t " } ,
2017-01-19 18:30:55 +00:00
2017-01-19 21:35:53 +00:00
{ META_SECTORLINES , " sector_t.lines " } ,
{ META_SIDENUM , " line_t.sidenum " } ,
2017-01-19 18:30:55 +00:00
# ifdef HAVE_LUA_SEGS
2017-01-19 21:35:53 +00:00
{ META_NODEBBOX , " node_t.bbox " } ,
{ META_NODECHILDREN , " node_t.children " } ,
2017-01-19 18:30:55 +00:00
# endif
2017-01-19 21:35:53 +00:00
{ META_BBOX , " bbox " } ,
2017-01-19 18:30:55 +00:00
2017-01-19 21:35:53 +00:00
{ META_HUDINFO , " hudinfo_t " } ,
{ META_PATCH , " patch_t " } ,
{ META_COLORMAP , " colormap " } ,
{ META_CAMERA , " camera_t " } ,
2017-05-17 19:36:40 +00:00
{ META_ACTION , " action " } ,
2019-08-24 17:25:27 +00:00
{ META_LUABANKS , " luabanks[] " } ,
2017-01-19 21:35:53 +00:00
{ NULL , NULL }
2017-01-19 18:30:55 +00:00
} ;
2017-01-19 21:35:53 +00:00
// goes through the above list and returns the utype string for the userdata type
2017-09-28 15:10:24 +00:00
// returns "unknown" instead if we couldn't find the right userdata type
2017-01-19 21:35:53 +00:00
static const char * GetUserdataUType ( lua_State * L )
2017-01-19 18:30:55 +00:00
{
UINT8 i ;
lua_getmetatable ( L , - 1 ) ;
for ( i = 0 ; meta2utype [ i ] . meta ; i + + )
{
luaL_getmetatable ( L , meta2utype [ i ] . meta ) ;
if ( lua_rawequal ( L , - 1 , - 2 ) )
{
lua_pop ( L , 2 ) ;
return meta2utype [ i ] . utype ;
}
lua_pop ( L , 1 ) ;
}
lua_pop ( L , 1 ) ;
2017-01-19 21:35:53 +00:00
return " unknown " ;
2017-01-19 18:30:55 +00:00
}
2017-01-19 21:35:53 +00:00
// Return a string representing the type of userdata the given var is
// e.g. players[0] -> "player_t"
// or players[0].powers -> "player_t.powers"
2017-01-19 18:30:55 +00:00
static int lib_userdataType ( lua_State * L )
{
lua_settop ( L , 1 ) ; // pop everything except arg 1 (in case somebody decided to add more)
luaL_checktype ( L , 1 , LUA_TUSERDATA ) ;
2017-01-19 21:35:53 +00:00
lua_pushstring ( L , GetUserdataUType ( L ) ) ;
2017-01-19 18:30:55 +00:00
return 1 ;
}
2018-11-07 23:07:34 +00:00
static int lib_isPlayerAdmin ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
//HUDSAFE
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
lua_pushboolean ( L , IsPlayerAdmin ( player - players ) ) ;
return 1 ;
}
2019-08-24 17:25:27 +00:00
static int lib_reserveLuabanks ( lua_State * L )
{
static boolean reserved = false ;
if ( ! lua_lumploading )
return luaL_error ( L , " luabanks[] cannot be reserved from within a hook or coroutine! " ) ;
if ( reserved )
return luaL_error ( L , " luabanks[] has already been reserved! Only one savedata-enabled mod at a time may use this feature. " ) ;
reserved = true ;
LUA_PushUserdata ( L , & luabanks , META_LUABANKS ) ;
return 1 ;
}
2014-03-15 16:59:03 +00:00
// M_RANDOM
//////////////
2016-03-27 14:33:15 +00:00
static int lib_pRandomFixed ( lua_State * L )
2014-03-15 16:59:03 +00:00
{
NOHUD
2016-03-27 14:33:15 +00:00
lua_pushfixed ( L , P_RandomFixed ( ) ) ;
2014-03-15 16:59:03 +00:00
return 1 ;
}
2016-03-27 14:33:15 +00:00
static int lib_pRandomByte ( lua_State * L )
2014-03-15 16:59:03 +00:00
{
NOHUD
2016-03-27 14:33:15 +00:00
lua_pushinteger ( L , P_RandomByte ( ) ) ;
2014-03-15 16:59:03 +00:00
return 1 ;
}
static int lib_pRandomKey ( lua_State * L )
{
INT32 a = ( INT32 ) luaL_checkinteger ( L , 1 ) ;
NOHUD
2016-05-11 21:33:50 +00:00
if ( a > 65536 )
LUA_UsageWarning ( L , " P_RandomKey: range > 65536 is undefined behavior " ) ;
2014-03-15 16:59:03 +00:00
lua_pushinteger ( L , P_RandomKey ( a ) ) ;
return 1 ;
}
static int lib_pRandomRange ( lua_State * L )
{
INT32 a = ( INT32 ) luaL_checkinteger ( L , 1 ) ;
INT32 b = ( INT32 ) luaL_checkinteger ( L , 2 ) ;
NOHUD
if ( b < a ) {
INT32 c = a ;
a = b ;
b = c ;
}
2016-05-11 21:33:50 +00:00
if ( ( b - a + 1 ) > 65536 )
LUA_UsageWarning ( L , " P_RandomRange: range > 65536 is undefined behavior " ) ;
2014-03-15 16:59:03 +00:00
lua_pushinteger ( L , P_RandomRange ( a , b ) ) ;
return 1 ;
}
2018-03-20 15:00:27 +00:00
// Macros.
2016-03-27 14:33:15 +00:00
static int lib_pSignedRandom ( lua_State * L )
{
NOHUD
lua_pushinteger ( L , P_SignedRandom ( ) ) ;
return 1 ;
}
static int lib_pRandomChance ( lua_State * L )
{
fixed_t p = luaL_checkfixed ( L , 1 ) ;
NOHUD
lua_pushboolean ( L , P_RandomChance ( p ) ) ;
return 1 ;
}
2014-03-15 16:59:03 +00:00
// P_MAPUTIL
///////////////
static int lib_pAproxDistance ( lua_State * L )
{
2015-05-21 03:54:04 +00:00
fixed_t dx = luaL_checkfixed ( L , 1 ) ;
fixed_t dy = luaL_checkfixed ( L , 2 ) ;
2014-03-15 16:59:03 +00:00
//HUDSAFE
2015-05-21 03:54:04 +00:00
lua_pushfixed ( L , P_AproxDistance ( dx , dy ) ) ;
2014-03-15 16:59:03 +00:00
return 1 ;
}
static int lib_pClosestPointOnLine ( lua_State * L )
{
2016-03-02 20:31:04 +00:00
int n = lua_gettop ( L ) ;
2015-05-21 03:54:04 +00:00
fixed_t x = luaL_checkfixed ( L , 1 ) ;
fixed_t y = luaL_checkfixed ( L , 2 ) ;
2014-03-15 16:59:03 +00:00
vertex_t result ;
//HUDSAFE
2016-03-02 20:31:04 +00:00
if ( lua_isuserdata ( L , 3 ) ) // use a real linedef to get our points
{
line_t * line = * ( ( line_t * * ) luaL_checkudata ( L , 3 , META_LINE ) ) ;
if ( ! line )
return LUA_ErrInvalid ( L , " line_t " ) ;
P_ClosestPointOnLine ( x , y , line , & result ) ;
}
else // use custom coordinates of our own!
{
vertex_t v1 , v2 ; // fake vertexes
line_t junk ; // fake linedef
if ( n < 6 )
return luaL_error ( L , " arguments 3 to 6 not all given (expected 4 fixed-point integers) " ) ;
v1 . x = luaL_checkfixed ( L , 3 ) ;
v1 . y = luaL_checkfixed ( L , 4 ) ;
v2 . x = luaL_checkfixed ( L , 5 ) ;
v2 . y = luaL_checkfixed ( L , 6 ) ;
junk . v1 = & v1 ;
junk . v2 = & v2 ;
junk . dx = v2 . x - v1 . x ;
junk . dy = v2 . y - v1 . y ;
P_ClosestPointOnLine ( x , y , & junk , & result ) ;
}
2015-05-21 03:54:04 +00:00
lua_pushfixed ( L , result . x ) ;
lua_pushfixed ( L , result . y ) ;
2014-03-15 16:59:03 +00:00
return 2 ;
}
2016-05-25 15:34:09 +00:00
static int lib_pPointOnLineSide ( lua_State * L )
{
2016-11-24 22:01:51 +00:00
int n = lua_gettop ( L ) ;
2016-05-25 15:34:09 +00:00
fixed_t x = luaL_checkfixed ( L , 1 ) ;
fixed_t y = luaL_checkfixed ( L , 2 ) ;
//HUDSAFE
2016-11-24 22:01:51 +00:00
if ( lua_isuserdata ( L , 3 ) ) // use a real linedef to get our points
{
line_t * line = * ( ( line_t * * ) luaL_checkudata ( L , 3 , META_LINE ) ) ;
if ( ! line )
return LUA_ErrInvalid ( L , " line_t " ) ;
lua_pushinteger ( L , P_PointOnLineSide ( x , y , line ) ) ;
}
else // use custom coordinates of our own!
{
vertex_t v1 , v2 ; // fake vertexes
line_t junk ; // fake linedef
if ( n < 6 )
return luaL_error ( L , " arguments 3 to 6 not all given (expected 4 fixed-point integers) " ) ;
v1 . x = luaL_checkfixed ( L , 3 ) ;
v1 . y = luaL_checkfixed ( L , 4 ) ;
v2 . x = luaL_checkfixed ( L , 5 ) ;
v2 . y = luaL_checkfixed ( L , 6 ) ;
junk . v1 = & v1 ;
junk . v2 = & v2 ;
junk . dx = v2 . x - v1 . x ;
junk . dy = v2 . y - v1 . y ;
lua_pushinteger ( L , P_PointOnLineSide ( x , y , & junk ) ) ;
}
2016-05-25 15:34:09 +00:00
return 1 ;
}
2014-03-15 16:59:03 +00:00
// P_ENEMY
/////////////
static int lib_pCheckMeleeRange ( lua_State * L )
{
mobj_t * actor = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! actor )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
lua_pushboolean ( L , P_CheckMeleeRange ( actor ) ) ;
return 1 ;
}
static int lib_pJetbCheckMeleeRange ( lua_State * L )
{
mobj_t * actor = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! actor )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
lua_pushboolean ( L , P_JetbCheckMeleeRange ( actor ) ) ;
return 1 ;
}
static int lib_pFaceStabCheckMeleeRange ( lua_State * L )
{
mobj_t * actor = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! actor )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
lua_pushboolean ( L , P_FaceStabCheckMeleeRange ( actor ) ) ;
return 1 ;
}
static int lib_pSkimCheckMeleeRange ( lua_State * L )
{
mobj_t * actor = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! actor )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
lua_pushboolean ( L , P_SkimCheckMeleeRange ( actor ) ) ;
return 1 ;
}
static int lib_pCheckMissileRange ( lua_State * L )
{
mobj_t * actor = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! actor )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
lua_pushboolean ( L , P_CheckMissileRange ( actor ) ) ;
return 1 ;
}
static int lib_pNewChaseDir ( lua_State * L )
{
mobj_t * actor = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! actor )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
P_NewChaseDir ( actor ) ;
return 0 ;
}
static int lib_pLookForPlayers ( lua_State * L )
{
mobj_t * actor = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
2014-03-18 17:56:54 +00:00
fixed_t dist = ( fixed_t ) luaL_optinteger ( L , 2 , 0 ) ;
2014-03-15 16:59:03 +00:00
boolean allaround = lua_optboolean ( L , 3 ) ;
boolean tracer = lua_optboolean ( L , 4 ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! actor )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
lua_pushboolean ( L , P_LookForPlayers ( actor , allaround , tracer , dist ) ) ;
return 1 ;
}
// P_MOBJ
////////////
static int lib_pSpawnMobj ( lua_State * L )
{
2015-05-21 03:54:04 +00:00
fixed_t x = luaL_checkfixed ( L , 1 ) ;
fixed_t y = luaL_checkfixed ( L , 2 ) ;
fixed_t z = luaL_checkfixed ( L , 3 ) ;
2014-03-15 16:59:03 +00:00
mobjtype_t type = luaL_checkinteger ( L , 4 ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2016-05-01 21:14:42 +00:00
if ( type > = NUMMOBJTYPES )
return luaL_error ( L , " mobj type %d out of range (0 - %d) " , type, NUMMOBJTYPES-1) ;
2014-03-15 16:59:03 +00:00
LUA_PushUserdata ( L , P_SpawnMobj ( x , y , z , type ) , META_MOBJ ) ;
return 1 ;
}
2017-07-08 10:41:20 +00:00
static int lib_pSpawnMobjFromMobj ( lua_State * L )
{
mobj_t * actor = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
fixed_t x = luaL_checkfixed ( L , 2 ) ;
fixed_t y = luaL_checkfixed ( L , 3 ) ;
fixed_t z = luaL_checkfixed ( L , 4 ) ;
mobjtype_t type = luaL_checkinteger ( L , 5 ) ;
NOHUD
INLEVEL
if ( ! actor )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
if ( type > = NUMMOBJTYPES )
return luaL_error ( L , " mobj type %d out of range (0 - %d) " , type, NUMMOBJTYPES-1) ;
LUA_PushUserdata ( L , P_SpawnMobjFromMobj ( actor , x , y , z , type ) , META_MOBJ ) ;
return 1 ;
}
2014-03-15 16:59:03 +00:00
static int lib_pRemoveMobj ( lua_State * L )
{
mobj_t * th = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! th )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
if ( th - > player )
return luaL_error ( L , " Attempt to remove player mobj with P_RemoveMobj. " ) ;
P_RemoveMobj ( th ) ;
return 0 ;
}
2016-11-11 23:23:41 +00:00
// P_IsValidSprite2 technically doesn't exist, and probably never should... but too much would need to be exposed to allow this to be checked by other methods.
static int lib_pIsValidSprite2 ( lua_State * L )
{
mobj_t * mobj = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
UINT8 spr2 = ( UINT8 ) luaL_checkinteger ( L , 2 ) ;
//HUDSAFE
2017-01-18 22:02:28 +00:00
INLEVEL
2016-11-11 23:23:41 +00:00
if ( ! mobj )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
2017-03-11 02:09:01 +00:00
lua_pushboolean ( L , ( mobj - > skin & & ( ( ( skin_t * ) mobj - > skin ) - > sprites [ spr2 ] . numframes ) ) ) ;
2016-11-11 23:23:41 +00:00
return 1 ;
}
2017-03-23 19:11:22 +00:00
// P_SpawnLockOn doesn't exist either, but we want to expose making a local mobj without encouraging hacks.
static int lib_pSpawnLockOn ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
mobj_t * lockon = * ( ( mobj_t * * ) luaL_checkudata ( L , 2 , META_MOBJ ) ) ;
statenum_t state = luaL_checkinteger ( L , 3 ) ;
NOHUD
INLEVEL
if ( ! lockon )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
2017-08-25 17:00:20 +00:00
if ( state > = NUMSTATES )
return luaL_error ( L , " state %d out of range (0 - %d) " , state, NUMSTATES-1) ;
2017-04-29 15:27:52 +00:00
if ( P_IsLocalPlayer ( player ) ) // Only display it on your own view.
2017-03-23 19:11:22 +00:00
{
mobj_t * visual = P_SpawnMobj ( lockon - > x , lockon - > y , lockon - > z , MT_LOCKON ) ; // positioning, flip handled in P_SceneryThinker
2019-07-12 23:42:03 +00:00
P_SetTarget ( & visual - > target , lockon ) ;
2019-06-19 11:09:02 +00:00
visual - > flags2 | = MF2_DONTDRAW ;
2017-03-23 19:11:22 +00:00
P_SetMobjStateNF ( visual , state ) ;
}
return 0 ;
}
2014-03-15 16:59:03 +00:00
static int lib_pSpawnMissile ( 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 ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! source | | ! dest )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
2016-05-01 21:14:42 +00:00
if ( type > = NUMMOBJTYPES )
return luaL_error ( L , " mobj type %d out of range (0 - %d) " , type, NUMMOBJTYPES-1) ;
2014-03-15 16:59:03 +00:00
LUA_PushUserdata ( L , P_SpawnMissile ( source , dest , type ) , META_MOBJ ) ;
return 1 ;
}
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 ) ;
2015-05-21 03:54:04 +00:00
fixed_t x = luaL_checkfixed ( L , 4 ) ;
fixed_t y = luaL_checkfixed ( L , 5 ) ;
fixed_t z = luaL_checkfixed ( L , 6 ) ;
2014-03-15 16:59:03 +00:00
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! source | | ! dest )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
2016-05-01 21:14:42 +00:00
if ( type > = NUMMOBJTYPES )
return luaL_error ( L , " mobj type %d out of range (0 - %d) " , type, NUMMOBJTYPES-1) ;
2014-03-15 16:59:03 +00:00
LUA_PushUserdata ( L , P_SpawnXYZMissile ( source , dest , type , x , y , z ) , META_MOBJ ) ;
return 1 ;
}
static int lib_pSpawnPointMissile ( lua_State * L )
{
mobj_t * source = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
2015-05-21 03:54:04 +00:00
fixed_t xa = luaL_checkfixed ( L , 2 ) ;
fixed_t ya = luaL_checkfixed ( L , 3 ) ;
fixed_t za = luaL_checkfixed ( L , 4 ) ;
2014-03-15 16:59:03 +00:00
mobjtype_t type = luaL_checkinteger ( L , 5 ) ;
2015-05-21 03:54:04 +00:00
fixed_t x = luaL_checkfixed ( L , 6 ) ;
fixed_t y = luaL_checkfixed ( L , 7 ) ;
fixed_t z = luaL_checkfixed ( L , 8 ) ;
2014-03-15 16:59:03 +00:00
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! source )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
2016-05-01 21:14:42 +00:00
if ( type > = NUMMOBJTYPES )
return luaL_error ( L , " mobj type %d out of range (0 - %d) " , type, NUMMOBJTYPES-1) ;
2014-03-15 16:59:03 +00:00
LUA_PushUserdata ( L , P_SpawnPointMissile ( source , xa , ya , za , type , x , y , z ) , META_MOBJ ) ;
return 1 ;
}
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 ) ;
2015-05-21 03:54:04 +00:00
fixed_t x = luaL_checkfixed ( L , 3 ) ;
fixed_t y = luaL_checkfixed ( L , 4 ) ;
fixed_t z = luaL_checkfixed ( L , 5 ) ;
2014-03-15 16:59:03 +00:00
INT32 shiftingAngle = ( INT32 ) luaL_checkinteger ( L , 5 ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! source )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
2016-05-01 21:14:42 +00:00
if ( type > = NUMMOBJTYPES )
return luaL_error ( L , " mobj type %d out of range (0 - %d) " , type, NUMMOBJTYPES-1) ;
2014-03-15 16:59:03 +00:00
LUA_PushUserdata ( L , P_SpawnAlteredDirectionMissile ( source , type , x , y , z , shiftingAngle ) , META_MOBJ ) ;
return 1 ;
}
static int lib_pColorTeamMissile ( lua_State * L )
{
mobj_t * missile = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
player_t * source = * ( ( player_t * * ) luaL_checkudata ( L , 2 , META_PLAYER ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! missile )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
if ( ! source )
return LUA_ErrInvalid ( L , " player_t " ) ;
P_ColorTeamMissile ( missile , source ) ;
return 0 ;
}
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 ) ;
2015-05-21 03:54:04 +00:00
angle_t angle = luaL_checkangle ( L , 3 ) ;
2014-03-18 17:56:54 +00:00
UINT8 allowaim = ( UINT8 ) luaL_optinteger ( L , 4 , 0 ) ;
UINT32 flags2 = ( UINT32 ) luaL_optinteger ( L , 5 , 0 ) ;
2014-03-15 16:59:03 +00:00
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! source )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
2016-05-01 21:14:42 +00:00
if ( type > = NUMMOBJTYPES )
return luaL_error ( L , " mobj type %d out of range (0 - %d) " , type, NUMMOBJTYPES-1) ;
2014-03-15 16:59:03 +00:00
LUA_PushUserdata ( L , P_SPMAngle ( source , type , angle , allowaim , flags2 ) , META_MOBJ ) ;
return 1 ;
}
static int lib_pSpawnPlayerMissile ( lua_State * L )
{
mobj_t * source = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
mobjtype_t type = luaL_checkinteger ( L , 2 ) ;
2014-03-18 17:56:54 +00:00
UINT32 flags2 = ( UINT32 ) luaL_optinteger ( L , 3 , 0 ) ;
2014-03-15 16:59:03 +00:00
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! source )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
2016-05-01 21:14:42 +00:00
if ( type > = NUMMOBJTYPES )
return luaL_error ( L , " mobj type %d out of range (0 - %d) " , type, NUMMOBJTYPES-1) ;
2014-03-15 16:59:03 +00:00
LUA_PushUserdata ( L , P_SpawnPlayerMissile ( source , type , flags2 ) , META_MOBJ ) ;
return 1 ;
}
static int lib_pMobjFlip ( lua_State * L )
{
mobj_t * mobj = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
//HUDSAFE
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! mobj )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
lua_pushinteger ( L , P_MobjFlip ( mobj ) ) ;
return 1 ;
}
2016-06-01 12:19:44 +00:00
static int lib_pGetMobjGravity ( lua_State * L )
{
mobj_t * mobj = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
//HUDSAFE
2017-01-18 22:02:28 +00:00
INLEVEL
2016-06-01 12:19:44 +00:00
if ( ! mobj )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
2016-06-01 13:49:14 +00:00
lua_pushfixed ( L , P_GetMobjGravity ( mobj ) ) ;
2016-06-01 12:19:44 +00:00
return 1 ;
}
2014-03-15 16:59:03 +00:00
static int lib_pWeaponOrPanel ( lua_State * L )
{
mobjtype_t type = luaL_checkinteger ( L , 1 ) ;
//HUDSAFE
2016-05-01 21:14:42 +00:00
if ( type > = NUMMOBJTYPES )
return luaL_error ( L , " mobj type %d out of range (0 - %d) " , type, NUMMOBJTYPES-1) ;
2014-03-15 16:59:03 +00:00
lua_pushboolean ( L , P_WeaponOrPanel ( type ) ) ;
return 1 ;
}
static int lib_pFlashPal ( lua_State * L )
{
player_t * pl = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
UINT16 type = ( UINT16 ) luaL_checkinteger ( L , 2 ) ;
UINT16 duration = ( UINT16 ) luaL_checkinteger ( L , 3 ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! pl )
return LUA_ErrInvalid ( L , " player_t " ) ;
P_FlashPal ( pl , type , duration ) ;
return 0 ;
}
static int lib_pGetClosestAxis ( lua_State * L )
{
mobj_t * source = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
//HUDSAFE
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! source )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
LUA_PushUserdata ( L , P_GetClosestAxis ( source ) , META_MOBJ ) ;
return 1 ;
}
static int lib_pSpawnParaloop ( lua_State * L )
{
2015-05-21 03:54:04 +00:00
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 ) ;
2014-03-15 16:59:03 +00:00
INT32 number = ( INT32 ) luaL_checkinteger ( L , 5 ) ;
mobjtype_t type = luaL_checkinteger ( L , 6 ) ;
2015-05-21 03:54:04 +00:00
angle_t rotangle = luaL_checkangle ( L , 7 ) ;
2014-03-15 16:59:03 +00:00
statenum_t nstate = luaL_optinteger ( L , 8 , S_NULL ) ;
boolean spawncenter = lua_optboolean ( L , 9 ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2016-05-01 21:14:42 +00:00
if ( type > = NUMMOBJTYPES )
return luaL_error ( L , " mobj type %d out of range (0 - %d) " , type, NUMMOBJTYPES-1) ;
if ( nstate > = NUMSTATES )
return luaL_error ( L , " state %d out of range (0 - %d) " , nstate, NUMSTATES-1) ;
2014-03-15 16:59:03 +00:00
P_SpawnParaloop ( x , y , z , radius , number , type , nstate , rotangle , spawncenter ) ;
return 0 ;
}
static int lib_pBossTargetPlayer ( lua_State * L )
{
mobj_t * actor = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
boolean closest = lua_optboolean ( L , 2 ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! actor )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
lua_pushboolean ( L , P_BossTargetPlayer ( actor , closest ) ) ;
return 1 ;
}
static int lib_pSupermanLook4Players ( lua_State * L )
{
mobj_t * actor = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! actor )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
lua_pushboolean ( L , P_SupermanLook4Players ( actor ) ) ;
return 1 ;
}
static int lib_pSetScale ( lua_State * L )
{
mobj_t * mobj = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
2015-05-21 03:54:04 +00:00
fixed_t newscale = luaL_checkfixed ( L , 2 ) ;
2014-03-15 16:59:03 +00:00
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! mobj )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
if ( newscale < FRACUNIT / 100 )
newscale = FRACUNIT / 100 ;
P_SetScale ( mobj , newscale ) ;
return 0 ;
}
2014-08-04 03:49:33 +00:00
static int lib_pInsideANonSolidFFloor ( lua_State * L )
{
mobj_t * mobj = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
ffloor_t * rover = * ( ( ffloor_t * * ) luaL_checkudata ( L , 2 , META_FFLOOR ) ) ;
//HUDSAFE
2017-01-18 22:02:28 +00:00
INLEVEL
2014-08-04 03:49:33 +00:00
if ( ! mobj )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
if ( ! rover )
return LUA_ErrInvalid ( L , " ffloor_t " ) ;
lua_pushboolean ( L , P_InsideANonSolidFFloor ( mobj , rover ) ) ;
return 1 ;
}
2014-03-15 16:59:03 +00:00
static int lib_pCheckDeathPitCollide ( lua_State * L )
{
mobj_t * mo = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
//HUDSAFE
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! mo )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
lua_pushboolean ( L , P_CheckDeathPitCollide ( mo ) ) ;
return 1 ;
}
2014-08-04 03:49:33 +00:00
static int lib_pCheckSolidLava ( lua_State * L )
{
ffloor_t * rover = * ( ( ffloor_t * * ) luaL_checkudata ( L , 2 , META_FFLOOR ) ) ;
//HUDSAFE
2017-01-18 22:02:28 +00:00
INLEVEL
2014-08-04 03:49:33 +00:00
if ( ! rover )
return LUA_ErrInvalid ( L , " ffloor_t " ) ;
2019-10-01 19:58:18 +00:00
lua_pushboolean ( L , P_CheckSolidLava ( rover ) ) ;
2014-08-04 03:49:33 +00:00
return 1 ;
}
static int lib_pCanRunOnWater ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
ffloor_t * rover = * ( ( ffloor_t * * ) luaL_checkudata ( L , 2 , META_FFLOOR ) ) ;
//HUDSAFE
2017-01-18 22:02:28 +00:00
INLEVEL
2014-08-04 03:49:33 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
if ( ! rover )
return LUA_ErrInvalid ( L , " ffloor_t " ) ;
lua_pushboolean ( L , P_CanRunOnWater ( player , rover ) ) ;
return 1 ;
}
2018-04-01 19:54:19 +00:00
static int lib_pMaceRotate ( lua_State * L )
{
mobj_t * center = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
INT32 baserot = luaL_checkinteger ( L , 2 ) ;
INT32 baseprevrot = luaL_checkinteger ( L , 3 ) ;
NOHUD
INLEVEL
if ( ! center )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
P_MaceRotate ( center , baserot , baseprevrot ) ;
return 0 ;
}
2014-03-15 16:59:03 +00:00
// P_USER
////////////
static int lib_pGetPlayerHeight ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
//HUDSAFE
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
2015-05-21 03:54:04 +00:00
lua_pushfixed ( L , P_GetPlayerHeight ( player ) ) ;
2014-03-15 16:59:03 +00:00
return 1 ;
}
static int lib_pGetPlayerSpinHeight ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
//HUDSAFE
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
2015-05-21 03:54:04 +00:00
lua_pushfixed ( L , P_GetPlayerSpinHeight ( player ) ) ;
2014-03-15 16:59:03 +00:00
return 1 ;
}
static int lib_pGetPlayerControlDirection ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
//HUDSAFE
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
lua_pushinteger ( L , P_GetPlayerControlDirection ( player ) ) ;
return 1 ;
}
static int lib_pAddPlayerScore ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
UINT32 amount = ( UINT32 ) luaL_checkinteger ( L , 2 ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
P_AddPlayerScore ( player , amount ) ;
return 0 ;
}
2015-05-27 06:08:18 +00:00
static int lib_pStealPlayerScore ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
UINT32 amount = ( UINT32 ) luaL_checkinteger ( L , 2 ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2015-05-27 06:08:18 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
P_StealPlayerScore ( player , amount ) ;
return 0 ;
}
2017-04-03 17:28:02 +00:00
static int lib_pGetJumpFlags ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
NOHUD
INLEVEL
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
lua_pushinteger ( L , P_GetJumpFlags ( player ) ) ;
return 1 ;
}
2014-03-15 16:59:03 +00:00
static int lib_pPlayerInPain ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
//HUDSAFE
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
lua_pushboolean ( L , P_PlayerInPain ( player ) ) ;
return 1 ;
}
static int lib_pDoPlayerPain ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
mobj_t * source = NULL , * inflictor = NULL ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
2014-08-04 03:49:33 +00:00
if ( ! lua_isnone ( L , 2 ) & & lua_isuserdata ( L , 2 ) )
2014-03-15 16:59:03 +00:00
source = * ( ( mobj_t * * ) luaL_checkudata ( L , 2 , META_MOBJ ) ) ;
2014-08-04 03:49:33 +00:00
if ( ! lua_isnone ( L , 3 ) & & lua_isuserdata ( L , 3 ) )
2014-03-15 16:59:03 +00:00
inflictor = * ( ( mobj_t * * ) luaL_checkudata ( L , 3 , META_MOBJ ) ) ;
P_DoPlayerPain ( player , source , inflictor ) ;
return 0 ;
}
static int lib_pResetPlayer ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
P_ResetPlayer ( player ) ;
return 0 ;
}
2019-06-19 11:09:02 +00:00
static int lib_pPlayerCanDamage ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
mobj_t * thing = * ( ( mobj_t * * ) luaL_checkudata ( L , 2 , META_MOBJ ) ) ;
"PlayerCanDamage" hook!
* Takes function(player, mo) input.
* Return TRUE for stating that yes, the player is in a state that can cause contact damage, do with that what you will.
* Return FALSE for stating that no, the player is weak and vulnerable and cannot cause contact damage, do with that what you will.
* Return NIL for allowing the function to continue regular operation.
Fills a different ideological niche than ShouldDamage - that's for determining whether damage dished between two objects should happen, this is for determining which way around damage should be dished when considering a player-object interaction.
Or, in other words, think of it as "ShouldDamage is whether damage that has been requested should be granted, for object-object interaction, while PlayerCanDamage is for whether global player properties should cause damage to enemies and monitors in the first place, like spinning, hammering or stomping."
2019-06-19 11:55:05 +00:00
NOHUD // was hud safe but then i added a lua hook
2019-06-19 11:09:02 +00:00
INLEVEL
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
if ( ! thing )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
lua_pushboolean ( L , P_PlayerCanDamage ( player , thing ) ) ;
return 1 ;
}
2014-08-04 03:49:33 +00:00
static int lib_pIsObjectInGoop ( lua_State * L )
{
mobj_t * mo = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
//HUDSAFE
2017-01-18 22:02:28 +00:00
INLEVEL
2014-08-04 03:49:33 +00:00
if ( ! mo )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
lua_pushboolean ( L , P_IsObjectInGoop ( mo ) ) ;
return 1 ;
}
2014-03-15 16:59:03 +00:00
static int lib_pIsObjectOnGround ( lua_State * L )
{
mobj_t * mo = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
//HUDSAFE
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! mo )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
lua_pushboolean ( L , P_IsObjectOnGround ( mo ) ) ;
return 1 ;
}
2014-08-04 03:49:33 +00:00
static int lib_pInSpaceSector ( lua_State * L )
{
mobj_t * mo = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
//HUDSAFE
2017-01-18 22:02:28 +00:00
INLEVEL
2014-08-04 03:49:33 +00:00
if ( ! mo )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
lua_pushboolean ( L , P_InSpaceSector ( mo ) ) ;
return 1 ;
}
static int lib_pInQuicksand ( lua_State * L )
{
mobj_t * mo = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
//HUDSAFE
2017-01-18 22:02:28 +00:00
INLEVEL
2014-08-04 03:49:33 +00:00
if ( ! mo )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
lua_pushboolean ( L , P_InQuicksand ( mo ) ) ;
return 1 ;
}
2014-03-15 16:59:03 +00:00
static int lib_pSetObjectMomZ ( lua_State * L )
{
mobj_t * mo = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
2015-05-21 03:54:04 +00:00
fixed_t value = luaL_checkfixed ( L , 2 ) ;
2014-03-15 16:59:03 +00:00
boolean relative = lua_optboolean ( L , 3 ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! mo )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
P_SetObjectMomZ ( mo , value , relative ) ;
return 0 ;
}
static int lib_pRestoreMusic ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
2018-09-18 19:10:42 +00:00
if ( P_IsLocalPlayer ( player ) )
2018-09-18 14:22:17 +00:00
P_RestoreMusic ( player ) ;
2014-03-15 16:59:03 +00:00
return 0 ;
}
2014-08-04 03:49:33 +00:00
static int lib_pSpawnShieldOrb ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-08-04 03:49:33 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
P_SpawnShieldOrb ( player ) ;
return 0 ;
}
2014-03-15 16:59:03 +00:00
static int lib_pSpawnGhostMobj ( lua_State * L )
{
mobj_t * mobj = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! mobj )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
LUA_PushUserdata ( L , P_SpawnGhostMobj ( mobj ) , META_MOBJ ) ;
return 1 ;
}
static int lib_pGivePlayerRings ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
INT32 num_rings = ( INT32 ) luaL_checkinteger ( L , 2 ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
P_GivePlayerRings ( player , num_rings ) ;
return 0 ;
}
static int lib_pGivePlayerLives ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
INT32 numlives = ( INT32 ) luaL_checkinteger ( L , 2 ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
P_GivePlayerLives ( player , numlives ) ;
return 0 ;
}
2017-05-29 21:18:02 +00:00
static int lib_pGiveCoopLives ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
INT32 numlives = ( INT32 ) luaL_checkinteger ( L , 2 ) ;
boolean sound = ( boolean ) lua_opttrueboolean ( L , 3 ) ;
NOHUD
INLEVEL
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
P_GiveCoopLives ( player , numlives , sound ) ;
return 0 ;
}
2014-03-15 16:59:03 +00:00
static int lib_pResetScore ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
P_ResetScore ( player ) ;
return 0 ;
}
2014-08-04 03:49:33 +00:00
static int lib_pDoJumpShield ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-08-04 03:49:33 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
P_DoJumpShield ( player ) ;
return 0 ;
}
2016-10-24 12:33:10 +00:00
static int lib_pDoBubbleBounce ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2016-10-24 12:33:10 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
P_DoBubbleBounce ( player ) ;
return 0 ;
}
2014-03-15 16:59:03 +00:00
static int lib_pBlackOw ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
P_BlackOw ( player ) ;
return 0 ;
}
2016-07-08 21:56:17 +00:00
static int lib_pElementalFire ( lua_State * L )
2014-03-15 16:59:03 +00:00
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
2016-07-08 21:52:49 +00:00
boolean cropcircle = lua_optboolean ( L , 2 ) ;
2014-03-15 16:59:03 +00:00
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
2016-07-08 21:56:17 +00:00
P_ElementalFire ( player , cropcircle ) ;
2014-03-15 16:59:03 +00:00
return 0 ;
}
2019-11-15 14:35:28 +00:00
static int lib_pDoPlayerFinish ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
NOHUD
INLEVEL
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
P_DoPlayerFinish ( player ) ;
return 0 ;
}
2014-03-15 16:59:03 +00:00
static int lib_pDoPlayerExit ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
P_DoPlayerExit ( player ) ;
return 0 ;
}
static int lib_pInstaThrust ( lua_State * L )
{
mobj_t * mo = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
2015-05-21 03:54:04 +00:00
angle_t angle = luaL_checkangle ( L , 2 ) ;
fixed_t move = luaL_checkfixed ( L , 3 ) ;
2014-03-15 16:59:03 +00:00
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! mo )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
P_InstaThrust ( mo , angle , move ) ;
return 0 ;
}
static int lib_pReturnThrustX ( lua_State * L )
{
angle_t angle ;
fixed_t move ;
if ( lua_isnil ( L , 1 ) | | lua_isuserdata ( L , 1 ) )
lua_remove ( L , 1 ) ; // ignore mobj as arg1
2015-05-21 03:54:04 +00:00
angle = luaL_checkangle ( L , 1 ) ;
move = luaL_checkfixed ( L , 2 ) ;
2014-03-15 16:59:03 +00:00
//HUDSAFE
2015-05-21 03:54:04 +00:00
lua_pushfixed ( L , P_ReturnThrustX ( NULL , angle , move ) ) ;
2014-03-15 16:59:03 +00:00
return 1 ;
}
static int lib_pReturnThrustY ( lua_State * L )
{
angle_t angle ;
fixed_t move ;
if ( lua_isnil ( L , 1 ) | | lua_isuserdata ( L , 1 ) )
lua_remove ( L , 1 ) ; // ignore mobj as arg1
2015-05-21 03:54:04 +00:00
angle = luaL_checkangle ( L , 1 ) ;
move = luaL_checkfixed ( L , 2 ) ;
2014-03-15 16:59:03 +00:00
//HUDSAFE
2015-05-21 03:54:04 +00:00
lua_pushfixed ( L , P_ReturnThrustY ( NULL , angle , move ) ) ;
2014-03-15 16:59:03 +00:00
return 1 ;
}
static int lib_pLookForEnemies ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
2015-05-27 09:24:31 +00:00
boolean nonenemies = lua_opttrueboolean ( L , 2 ) ;
2017-03-21 23:24:57 +00:00
boolean bullet = lua_optboolean ( L , 3 ) ;
2014-03-15 16:59:03 +00:00
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
2017-03-22 18:51:30 +00:00
LUA_PushUserdata ( L , P_LookForEnemies ( player , nonenemies , bullet ) , META_MOBJ ) ;
2014-03-15 16:59:03 +00:00
return 1 ;
}
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 ) ) ;
2015-05-21 03:54:04 +00:00
fixed_t radius = luaL_checkfixed ( L , 3 ) ;
2014-03-15 16:59:03 +00:00
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! inflictor | | ! source )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
P_NukeEnemies ( inflictor , source , radius ) ;
return 0 ;
}
static int lib_pHomingAttack ( lua_State * L )
{
mobj_t * source = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
mobj_t * enemy = * ( ( mobj_t * * ) luaL_checkudata ( L , 2 , META_MOBJ ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! source | | ! enemy )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
2019-07-02 23:58:02 +00:00
lua_pushboolean ( L , P_HomingAttack ( source , enemy ) ) ;
return 1 ;
2014-03-15 16:59:03 +00:00
}
2014-04-14 05:14:58 +00:00
static int lib_pSuperReady ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
//HUDSAFE
2017-01-18 22:02:28 +00:00
INLEVEL
2014-04-14 05:14:58 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
lua_pushboolean ( L , P_SuperReady ( player ) ) ;
return 1 ;
}
static int lib_pDoJump ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
boolean soundandstate = ( boolean ) lua_opttrueboolean ( L , 2 ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-04-14 05:14:58 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
P_DoJump ( player , soundandstate ) ;
return 0 ;
}
2014-05-23 20:46:49 +00:00
static int lib_pSpawnThokMobj ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-05-23 20:46:49 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
P_SpawnThokMobj ( player ) ;
return 0 ;
}
2014-05-23 22:08:35 +00:00
static int lib_pSpawnSpinMobj ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
mobjtype_t type = luaL_checkinteger ( L , 2 ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-05-23 22:08:35 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
2016-05-01 21:14:42 +00:00
if ( type > = NUMMOBJTYPES )
return luaL_error ( L , " mobj type %d out of range (0 - %d) " , type, NUMMOBJTYPES-1) ;
2014-05-23 22:08:35 +00:00
P_SpawnSpinMobj ( player , type ) ;
return 0 ;
}
2014-05-26 02:41:05 +00:00
static int lib_pTelekinesis ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
2015-05-21 03:54:04 +00:00
fixed_t thrust = luaL_checkfixed ( L , 2 ) ;
fixed_t range = luaL_checkfixed ( L , 3 ) ;
2014-05-26 02:41:05 +00:00
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-05-26 02:41:05 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
P_Telekinesis ( player , thrust , range ) ;
return 0 ;
}
2017-08-10 12:57:09 +00:00
static int lib_pSwitchShield ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
UINT16 shield = luaL_checkinteger ( L , 2 ) ;
NOHUD
INLEVEL
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
P_SwitchShield ( player , shield ) ;
return 0 ;
}
2014-03-15 16:59:03 +00:00
// P_MAP
///////////
static int lib_pCheckPosition ( lua_State * L )
{
mobj_t * ptmthing = tmthing ;
mobj_t * thing = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
2015-05-21 03:54:04 +00:00
fixed_t x = luaL_checkfixed ( L , 2 ) ;
fixed_t y = luaL_checkfixed ( L , 3 ) ;
2014-03-15 16:59:03 +00:00
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! thing )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
lua_pushboolean ( L , P_CheckPosition ( thing , x , y ) ) ;
LUA_PushUserdata ( L , tmthing , META_MOBJ ) ;
P_SetTarget ( & tmthing , ptmthing ) ;
return 2 ;
}
static int lib_pTryMove ( lua_State * L )
{
mobj_t * ptmthing = tmthing ;
mobj_t * thing = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
2015-05-21 03:54:04 +00:00
fixed_t x = luaL_checkfixed ( L , 2 ) ;
fixed_t y = luaL_checkfixed ( L , 3 ) ;
2014-03-15 16:59:03 +00:00
boolean allowdropoff = lua_optboolean ( L , 4 ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! thing )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
lua_pushboolean ( L , P_TryMove ( thing , x , y , allowdropoff ) ) ;
LUA_PushUserdata ( L , tmthing , META_MOBJ ) ;
P_SetTarget ( & tmthing , ptmthing ) ;
return 2 ;
}
static int lib_pMove ( lua_State * L )
{
mobj_t * ptmthing = tmthing ;
mobj_t * actor = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
2015-05-21 03:54:04 +00:00
fixed_t speed = luaL_checkfixed ( L , 2 ) ;
2014-03-15 16:59:03 +00:00
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! actor )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
lua_pushboolean ( L , P_Move ( actor , speed ) ) ;
LUA_PushUserdata ( L , tmthing , META_MOBJ ) ;
P_SetTarget ( & tmthing , ptmthing ) ;
return 2 ;
}
static int lib_pTeleportMove ( lua_State * L )
{
mobj_t * ptmthing = tmthing ;
mobj_t * thing = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
2015-05-21 03:54:04 +00:00
fixed_t x = luaL_checkfixed ( L , 2 ) ;
fixed_t y = luaL_checkfixed ( L , 3 ) ;
fixed_t z = luaL_checkfixed ( L , 4 ) ;
2014-03-15 16:59:03 +00:00
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! thing )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
lua_pushboolean ( L , P_TeleportMove ( thing , x , y , z ) ) ;
LUA_PushUserdata ( L , tmthing , META_MOBJ ) ;
P_SetTarget ( & tmthing , ptmthing ) ;
return 2 ;
}
static int lib_pSlideMove ( lua_State * L )
{
mobj_t * mo = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! mo )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
P_SlideMove ( mo ) ;
return 0 ;
}
static int lib_pBounceMove ( lua_State * L )
{
mobj_t * mo = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! mo )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
P_BounceMove ( mo ) ;
return 0 ;
}
static int lib_pCheckSight ( lua_State * L )
{
mobj_t * t1 = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
mobj_t * t2 = * ( ( mobj_t * * ) luaL_checkudata ( L , 2 , META_MOBJ ) ) ;
//HUDSAFE?
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! t1 | | ! t2 )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
lua_pushboolean ( L , P_CheckSight ( t1 , t2 ) ) ;
return 1 ;
}
static int lib_pCheckHoopPosition ( lua_State * L )
{
mobj_t * hoopthing = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
2015-05-21 03:54:04 +00:00
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 ) ;
2014-03-15 16:59:03 +00:00
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! hoopthing )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
P_CheckHoopPosition ( hoopthing , x , y , z , radius ) ;
return 0 ;
}
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 ) ) ;
2015-05-21 03:54:04 +00:00
fixed_t damagedist = luaL_checkfixed ( L , 3 ) ;
2018-05-08 22:26:36 +00:00
UINT8 damagetype = luaL_optinteger ( L , 4 , 0 ) ;
2014-03-15 16:59:03 +00:00
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! spot | | ! source )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
2018-05-08 22:26:36 +00:00
P_RadiusAttack ( spot , source , damagedist , damagetype ) ;
2014-03-15 16:59:03 +00:00
return 0 ;
}
static int lib_pFloorzAtPos ( lua_State * L )
{
2015-05-21 03:54:04 +00:00
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 ) ;
2014-03-15 16:59:03 +00:00
//HUDSAFE
2017-01-18 22:02:28 +00:00
INLEVEL
2015-05-21 03:54:04 +00:00
lua_pushfixed ( L , P_FloorzAtPos ( x , y , z , height ) ) ;
2014-03-15 16:59:03 +00:00
return 1 ;
}
2014-05-23 22:55:07 +00:00
static int lib_pDoSpring ( lua_State * L )
{
mobj_t * spring = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
mobj_t * object = * ( ( mobj_t * * ) luaL_checkudata ( L , 2 , META_MOBJ ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-05-23 22:55:07 +00:00
if ( ! spring | | ! object )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
2015-07-28 18:28:51 +00:00
lua_pushboolean ( L , P_DoSpring ( spring , object ) ) ;
return 1 ;
2014-05-23 22:55:07 +00:00
}
2014-03-15 16:59:03 +00:00
// P_INTER
////////////
static int lib_pRemoveShield ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
P_RemoveShield ( player ) ;
return 0 ;
}
static int lib_pDamageMobj ( lua_State * L )
{
mobj_t * target = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) , * inflictor = NULL , * source = NULL ;
INT32 damage ;
2015-02-13 16:15:58 +00:00
UINT8 damagetype ;
2014-03-15 16:59:03 +00:00
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! target )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
2014-08-04 03:49:33 +00:00
if ( ! lua_isnone ( L , 2 ) & & lua_isuserdata ( L , 2 ) )
2014-03-15 16:59:03 +00:00
inflictor = * ( ( mobj_t * * ) luaL_checkudata ( L , 2 , META_MOBJ ) ) ;
2014-08-04 03:49:33 +00:00
if ( ! lua_isnone ( L , 3 ) & & lua_isuserdata ( L , 3 ) )
2014-03-15 16:59:03 +00:00
source = * ( ( mobj_t * * ) luaL_checkudata ( L , 3 , META_MOBJ ) ) ;
damage = ( INT32 ) luaL_optinteger ( L , 4 , 1 ) ;
2015-02-13 16:15:58 +00:00
damagetype = ( UINT8 ) luaL_optinteger ( L , 5 , 0 ) ;
lua_pushboolean ( L , P_DamageMobj ( target , inflictor , source , damage , damagetype ) ) ;
2014-03-15 16:59:03 +00:00
return 1 ;
}
static int lib_pKillMobj ( lua_State * L )
{
mobj_t * target = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) , * inflictor = NULL , * source = NULL ;
2015-02-13 16:15:58 +00:00
UINT8 damagetype ;
2014-03-15 16:59:03 +00:00
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! target )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
2014-08-04 03:49:33 +00:00
if ( ! lua_isnone ( L , 2 ) & & lua_isuserdata ( L , 2 ) )
2014-03-15 16:59:03 +00:00
inflictor = * ( ( mobj_t * * ) luaL_checkudata ( L , 2 , META_MOBJ ) ) ;
2014-08-04 03:49:33 +00:00
if ( ! lua_isnone ( L , 3 ) & & lua_isuserdata ( L , 3 ) )
2014-03-15 16:59:03 +00:00
source = * ( ( mobj_t * * ) luaL_checkudata ( L , 3 , META_MOBJ ) ) ;
2015-02-13 16:15:58 +00:00
damagetype = ( UINT8 ) luaL_optinteger ( L , 4 , 0 ) ;
P_KillMobj ( target , inflictor , source , damagetype ) ;
2014-03-15 16:59:03 +00:00
return 0 ;
}
static int lib_pPlayerRingBurst ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
INT32 num_rings = ( INT32 ) luaL_optinteger ( L , 2 , - 1 ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
if ( num_rings = = - 1 )
2015-08-15 20:07:16 +00:00
num_rings = player - > rings ;
2014-03-15 16:59:03 +00:00
P_PlayerRingBurst ( player , num_rings ) ;
return 0 ;
}
static int lib_pPlayerWeaponPanelBurst ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
P_PlayerWeaponPanelBurst ( player ) ;
return 0 ;
}
static int lib_pPlayerWeaponAmmoBurst ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
P_PlayerWeaponAmmoBurst ( player ) ;
return 0 ;
}
2015-05-27 04:45:34 +00:00
static int lib_pPlayerWeaponPanelOrAmmoBurst ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2015-05-27 04:45:34 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
P_PlayerWeaponPanelOrAmmoBurst ( player ) ;
return 0 ;
}
2014-03-15 16:59:03 +00:00
static int lib_pPlayerEmeraldBurst ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
boolean toss = lua_optboolean ( L , 2 ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
P_PlayerEmeraldBurst ( player , toss ) ;
return 0 ;
}
static int lib_pPlayerFlagBurst ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
boolean toss = lua_optboolean ( L , 2 ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
P_PlayerFlagBurst ( player , toss ) ;
return 0 ;
}
static int lib_pPlayRinglossSound ( lua_State * L )
{
mobj_t * source = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
2014-08-04 03:49:33 +00:00
player_t * player = NULL ;
2014-03-15 16:59:03 +00:00
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! source )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
2014-08-04 03:49:33 +00:00
if ( ! lua_isnone ( L , 2 ) & & lua_isuserdata ( L , 2 ) )
{
player = * ( ( player_t * * ) luaL_checkudata ( L , 2 , META_PLAYER ) ) ;
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
}
if ( ! player | | P_IsLocalPlayer ( player ) )
P_PlayRinglossSound ( source ) ;
2014-03-15 16:59:03 +00:00
return 0 ;
}
static int lib_pPlayDeathSound ( lua_State * L )
{
mobj_t * source = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
2014-08-04 03:49:33 +00:00
player_t * player = NULL ;
2014-03-15 16:59:03 +00:00
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! source )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
2014-08-04 03:49:33 +00:00
if ( ! lua_isnone ( L , 2 ) & & lua_isuserdata ( L , 2 ) )
{
player = * ( ( player_t * * ) luaL_checkudata ( L , 2 , META_PLAYER ) ) ;
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
}
if ( ! player | | P_IsLocalPlayer ( player ) )
P_PlayDeathSound ( source ) ;
2014-03-15 16:59:03 +00:00
return 0 ;
}
static int lib_pPlayVictorySound ( lua_State * L )
{
mobj_t * source = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
2014-08-04 03:49:33 +00:00
player_t * player = NULL ;
2014-03-15 16:59:03 +00:00
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! source )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
2014-08-04 03:49:33 +00:00
if ( ! lua_isnone ( L , 2 ) & & lua_isuserdata ( L , 2 ) )
{
player = * ( ( player_t * * ) luaL_checkudata ( L , 2 , META_PLAYER ) ) ;
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
}
if ( ! player | | P_IsLocalPlayer ( player ) )
P_PlayVictorySound ( source ) ;
2014-03-15 16:59:03 +00:00
return 0 ;
}
static int lib_pPlayLivesJingle ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
P_PlayLivesJingle ( player ) ;
return 0 ;
}
static int lib_pCanPickupItem ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
boolean weapon = lua_optboolean ( L , 2 ) ;
//HUDSAFE
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
lua_pushboolean ( L , P_CanPickupItem ( player , weapon ) ) ;
return 1 ;
}
static int lib_pDoNightsScore ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
P_DoNightsScore ( player ) ;
return 0 ;
}
2015-05-27 06:08:18 +00:00
static int lib_pDoMatchSuper ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2015-05-27 06:08:18 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
P_DoMatchSuper ( player ) ;
return 0 ;
}
2014-03-15 16:59:03 +00:00
// P_SPEC
////////////
static int lib_pThrust ( lua_State * L )
{
mobj_t * mo = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
2015-05-21 03:54:04 +00:00
angle_t angle = luaL_checkangle ( L , 2 ) ;
fixed_t move = luaL_checkfixed ( L , 3 ) ;
2014-03-15 16:59:03 +00:00
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! mo )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
P_Thrust ( mo , angle , move ) ;
return 0 ;
}
static int lib_pSetMobjStateNF ( lua_State * L )
{
mobj_t * mobj = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
statenum_t state = luaL_checkinteger ( L , 2 ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! mobj )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
2016-05-01 21:14:42 +00:00
if ( state > = NUMSTATES )
return luaL_error ( L , " state %d out of range (0 - %d) " , state, NUMSTATES-1) ;
2014-03-15 16:59:03 +00:00
if ( mobj - > player & & state = = S_NULL )
return luaL_error ( L , " Attempt to remove player mobj with S_NULL. " ) ;
lua_pushboolean ( L , P_SetMobjStateNF ( mobj , state ) ) ;
return 1 ;
}
static int lib_pDoSuperTransformation ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
boolean giverings = lua_optboolean ( L , 2 ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
P_DoSuperTransformation ( player , giverings ) ;
return 0 ;
}
static int lib_pExplodeMissile ( lua_State * L )
{
mobj_t * mo = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! mo )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
P_ExplodeMissile ( mo ) ;
return 0 ;
}
static int lib_pPlayerTouchingSectorSpecial ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
INT32 section = ( INT32 ) luaL_checkinteger ( L , 2 ) ;
INT32 number = ( INT32 ) luaL_checkinteger ( L , 3 ) ;
//HUDSAFE
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
LUA_PushUserdata ( L , P_PlayerTouchingSectorSpecial ( player , section , number ) , META_SECTOR ) ;
return 1 ;
}
2017-10-30 20:09:41 +00:00
static int lib_pFindLowestFloorSurrounding ( lua_State * L )
{
sector_t * sector = * ( ( sector_t * * ) luaL_checkudata ( L , 1 , META_SECTOR ) ) ;
//HUDSAFE
INLEVEL
if ( ! sector )
return LUA_ErrInvalid ( L , " sector_t " ) ;
lua_pushfixed ( L , P_FindLowestFloorSurrounding ( sector ) ) ;
return 1 ;
}
static int lib_pFindHighestFloorSurrounding ( lua_State * L )
{
sector_t * sector = * ( ( sector_t * * ) luaL_checkudata ( L , 1 , META_SECTOR ) ) ;
//HUDSAFE
INLEVEL
if ( ! sector )
return LUA_ErrInvalid ( L , " sector_t " ) ;
lua_pushfixed ( L , P_FindHighestFloorSurrounding ( sector ) ) ;
return 1 ;
}
static int lib_pFindNextHighestFloor ( lua_State * L )
{
sector_t * sector = * ( ( sector_t * * ) luaL_checkudata ( L , 1 , META_SECTOR ) ) ;
fixed_t currentheight ;
//HUDSAFE
INLEVEL
if ( ! sector )
return LUA_ErrInvalid ( L , " sector_t " ) ;
// defaults to floorheight of sector arg
currentheight = ( fixed_t ) luaL_optinteger ( L , 2 , sector - > floorheight ) ;
lua_pushfixed ( L , P_FindNextHighestFloor ( sector , currentheight ) ) ;
return 1 ;
}
static int lib_pFindNextLowestFloor ( lua_State * L )
{
sector_t * sector = * ( ( sector_t * * ) luaL_checkudata ( L , 1 , META_SECTOR ) ) ;
fixed_t currentheight ;
//HUDSAFE
INLEVEL
if ( ! sector )
return LUA_ErrInvalid ( L , " sector_t " ) ;
// defaults to floorheight of sector arg
currentheight = ( fixed_t ) luaL_optinteger ( L , 2 , sector - > floorheight ) ;
lua_pushfixed ( L , P_FindNextLowestFloor ( sector , currentheight ) ) ;
return 1 ;
}
static int lib_pFindLowestCeilingSurrounding ( lua_State * L )
{
sector_t * sector = * ( ( sector_t * * ) luaL_checkudata ( L , 1 , META_SECTOR ) ) ;
//HUDSAFE
INLEVEL
if ( ! sector )
return LUA_ErrInvalid ( L , " sector_t " ) ;
lua_pushfixed ( L , P_FindLowestCeilingSurrounding ( sector ) ) ;
return 1 ;
}
static int lib_pFindHighestCeilingSurrounding ( lua_State * L )
{
sector_t * sector = * ( ( sector_t * * ) luaL_checkudata ( L , 1 , META_SECTOR ) ) ;
//HUDSAFE
INLEVEL
if ( ! sector )
return LUA_ErrInvalid ( L , " sector_t " ) ;
lua_pushfixed ( L , P_FindHighestCeilingSurrounding ( sector ) ) ;
return 1 ;
}
2014-03-15 16:59:03 +00:00
static int lib_pFindSpecialLineFromTag ( lua_State * L )
{
INT16 special = ( INT16 ) luaL_checkinteger ( L , 1 ) ;
INT16 line = ( INT16 ) luaL_checkinteger ( L , 2 ) ;
INT32 start = ( INT32 ) luaL_optinteger ( L , 3 , - 1 ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
lua_pushinteger ( L , P_FindSpecialLineFromTag ( special , line , start ) ) ;
return 1 ;
}
static int lib_pSwitchWeather ( lua_State * L )
{
INT32 weathernum = ( INT32 ) luaL_checkinteger ( L , 1 ) ;
2014-08-04 03:49:33 +00:00
player_t * user = NULL ;
2014-03-15 16:59:03 +00:00
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-08-04 03:49:33 +00:00
if ( ! lua_isnone ( L , 2 ) & & lua_isuserdata ( L , 2 ) ) // if a player, setup weather for only the player, otherwise setup weather for all players
user = * ( ( player_t * * ) luaL_checkudata ( L , 2 , META_PLAYER ) ) ;
if ( ! user ) // global
globalweather = weathernum ;
if ( ! user | | P_IsLocalPlayer ( user ) )
P_SwitchWeather ( weathernum ) ;
2014-03-15 16:59:03 +00:00
return 0 ;
}
static int lib_pLinedefExecute ( lua_State * L )
{
INT32 tag = ( INT16 ) luaL_checkinteger ( L , 1 ) ;
mobj_t * actor = NULL ;
sector_t * caller = NULL ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! lua_isnone ( L , 2 ) & & lua_isuserdata ( L , 2 ) )
actor = * ( ( mobj_t * * ) luaL_checkudata ( L , 2 , META_MOBJ ) ) ;
if ( ! lua_isnone ( L , 3 ) & & lua_isuserdata ( L , 3 ) )
caller = * ( ( sector_t * * ) luaL_checkudata ( L , 3 , META_SECTOR ) ) ;
P_LinedefExecute ( tag , actor , caller ) ;
return 0 ;
}
static int lib_pSpawnLightningFlash ( lua_State * L )
{
sector_t * sector = * ( ( sector_t * * ) luaL_checkudata ( L , 1 , META_SECTOR ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! sector )
return LUA_ErrInvalid ( L , " sector_t " ) ;
P_SpawnLightningFlash ( sector ) ;
return 0 ;
}
static int lib_pFadeLight ( lua_State * L )
{
INT16 tag = ( INT16 ) luaL_checkinteger ( L , 1 ) ;
INT32 destvalue = ( INT32 ) luaL_checkinteger ( L , 2 ) ;
INT32 speed = ( INT32 ) luaL_checkinteger ( L , 3 ) ;
2018-09-09 02:10:51 +00:00
boolean ticbased = lua_optboolean ( L , 4 ) ;
2018-09-18 10:27:30 +00:00
boolean force = lua_optboolean ( L , 5 ) ;
2014-03-15 16:59:03 +00:00
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2018-09-18 10:27:30 +00:00
P_FadeLight ( tag , destvalue , speed , ticbased , force ) ;
2014-03-15 16:59:03 +00:00
return 0 ;
}
static int lib_pThingOnSpecial3DFloor ( lua_State * L )
{
mobj_t * mo = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! mo )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
LUA_PushUserdata ( L , P_ThingOnSpecial3DFloor ( mo ) , META_SECTOR ) ;
return 1 ;
}
2014-05-26 02:41:05 +00:00
static int lib_pIsFlagAtBase ( lua_State * L )
{
mobjtype_t flag = luaL_checkinteger ( L , 1 ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2016-05-01 21:14:42 +00:00
if ( flag > = NUMMOBJTYPES )
return luaL_error ( L , " mobj type %d out of range (0 - %d) " , flag, NUMMOBJTYPES-1) ;
2014-05-26 02:41:05 +00:00
lua_pushboolean ( L , P_IsFlagAtBase ( flag ) ) ;
return 1 ;
}
2014-03-15 16:59:03 +00:00
static int lib_pSetupLevelSky ( lua_State * L )
{
INT32 skynum = ( INT32 ) luaL_checkinteger ( L , 1 ) ;
2014-08-04 03:49:33 +00:00
player_t * user = NULL ;
2014-03-15 16:59:03 +00:00
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-08-04 03:49:33 +00:00
if ( ! lua_isnone ( L , 2 ) & & lua_isuserdata ( L , 2 ) ) // if a player, setup sky for only the player, otherwise setup sky for all players
user = * ( ( player_t * * ) luaL_checkudata ( L , 2 , META_PLAYER ) ) ;
if ( ! user ) // global
P_SetupLevelSky ( skynum , true ) ;
else if ( P_IsLocalPlayer ( user ) )
P_SetupLevelSky ( skynum , false ) ;
2014-03-15 16:59:03 +00:00
return 0 ;
}
// Shhh, P_SetSkyboxMobj doesn't actually exist yet.
static int lib_pSetSkyboxMobj ( lua_State * L )
{
int n = lua_gettop ( L ) ;
mobj_t * mo = NULL ;
player_t * user = NULL ;
int w = 0 ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! lua_isnil ( L , 1 ) ) // nil leaves mo as NULL to remove the skybox rendering.
{
mo = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ; // otherwise it is a skybox mobj.
if ( ! mo )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
}
if ( n = = 1 )
;
else if ( lua_isuserdata ( L , 2 ) )
user = * ( ( player_t * * ) luaL_checkudata ( L , 2 , META_PLAYER ) ) ;
else if ( lua_isnil ( L , 2 ) )
w = 0 ;
else if ( lua_isboolean ( L , 2 ) )
{
if ( lua_toboolean ( L , 2 ) )
w = 1 ;
else
w = 0 ;
}
else
w = luaL_optinteger ( L , 2 , 0 ) ;
if ( n > 2 & & lua_isuserdata ( L , 3 ) )
{
user = * ( ( player_t * * ) luaL_checkudata ( L , 3 , META_PLAYER ) ) ;
if ( ! user )
return LUA_ErrInvalid ( L , " player_t " ) ;
}
if ( w > 1 | | w < 0 )
return luaL_error ( L , " skybox mobj index %d is out of range for P_SetSkyboxMobj argument #2 (expected 0 or 1) " , w) ;
if ( ! user | | P_IsLocalPlayer ( user ) )
skyboxmo [ w ] = mo ;
return 0 ;
}
// Shhh, neither does P_StartQuake.
static int lib_pStartQuake ( lua_State * L )
{
fixed_t q_intensity = luaL_checkinteger ( L , 1 ) ;
UINT16 q_time = ( UINT16 ) luaL_checkinteger ( L , 2 ) ;
static mappoint_t q_epicenter = { 0 , 0 , 0 } ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
// While technically we don't support epicenter and radius,
// we get their values anyway if they exist.
// This way when support is added we won't have to change anything.
if ( ! lua_isnoneornil ( L , 3 ) )
{
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 ) )
q_epicenter . x = luaL_checkinteger ( L , - 1 ) ;
else
q_epicenter . 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 ) )
q_epicenter . y = luaL_checkinteger ( L , - 1 ) ;
else
q_epicenter . 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 ) )
q_epicenter . z = luaL_checkinteger ( L , - 1 ) ;
else
q_epicenter . z = 0 ;
lua_pop ( L , 1 ) ;
quake . epicenter = & q_epicenter ;
}
else
quake . epicenter = NULL ;
quake . radius = luaL_optinteger ( L , 4 , 512 * FRACUNIT ) ;
// These things are actually used in 2.1.
quake . intensity = q_intensity ;
quake . time = q_time ;
return 0 ;
}
2014-08-04 03:49:33 +00:00
static int lib_evCrumbleChain ( lua_State * L )
{
2019-07-28 21:45:20 +00:00
sector_t * sec = NULL ;
ffloor_t * rover = NULL ;
2014-08-04 03:49:33 +00:00
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2019-07-28 21:53:27 +00:00
if ( ! lua_isnone ( L , 2 ) )
2019-07-28 21:45:20 +00:00
{
2019-07-28 21:53:27 +00:00
if ( ! lua_isnil ( L , 1 ) )
{
sec = * ( ( sector_t * * ) luaL_checkudata ( L , 1 , META_SECTOR ) ) ;
if ( ! sec )
return LUA_ErrInvalid ( L , " sector_t " ) ;
}
2019-07-28 21:45:20 +00:00
rover = * ( ( ffloor_t * * ) luaL_checkudata ( L , 2 , META_FFLOOR ) ) ;
}
else
rover = * ( ( ffloor_t * * ) luaL_checkudata ( L , 1 , META_FFLOOR ) ) ;
2014-08-04 03:49:33 +00:00
if ( ! rover )
return LUA_ErrInvalid ( L , " ffloor_t " ) ;
EV_CrumbleChain ( sec , rover ) ;
return 0 ;
}
2016-07-01 19:27:09 +00:00
static int lib_evStartCrumble ( lua_State * L )
{
sector_t * sec = * ( ( sector_t * * ) luaL_checkudata ( L , 1 , META_SECTOR ) ) ;
ffloor_t * rover = * ( ( ffloor_t * * ) luaL_checkudata ( L , 2 , META_FFLOOR ) ) ;
boolean floating = lua_optboolean ( L , 3 ) ;
player_t * player = NULL ;
fixed_t origalpha ;
boolean crumblereturn = lua_optboolean ( L , 6 ) ;
NOHUD
if ( ! sec )
return LUA_ErrInvalid ( L , " sector_t " ) ;
if ( ! rover )
return LUA_ErrInvalid ( L , " ffloor_t " ) ;
if ( ! lua_isnone ( L , 4 ) & & lua_isuserdata ( L , 4 ) )
{
player = * ( ( player_t * * ) luaL_checkudata ( L , 4 , META_PLAYER ) ) ;
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
}
if ( ! lua_isnone ( L , 5 ) )
origalpha = luaL_checkfixed ( L , 5 ) ;
else
origalpha = rover - > alpha ;
lua_pushboolean ( L , EV_StartCrumble ( sec , rover , floating , player , origalpha , crumblereturn ) ! = 0 ) ;
return 0 ;
}
2018-10-20 20:08:59 +00:00
# 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
2014-03-15 16:59:03 +00:00
// R_DEFS
////////////
static int lib_rPointToAngle ( lua_State * L )
{
2015-05-21 03:54:04 +00:00
fixed_t x = luaL_checkfixed ( L , 1 ) ;
fixed_t y = luaL_checkfixed ( L , 2 ) ;
2014-03-15 16:59:03 +00:00
//HUDSAFE
2015-05-21 03:54:04 +00:00
lua_pushangle ( L , R_PointToAngle ( x , y ) ) ;
2014-03-15 16:59:03 +00:00
return 1 ;
}
static int lib_rPointToAngle2 ( lua_State * L )
{
2015-05-21 03:54:04 +00:00
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 ) ;
2014-03-15 16:59:03 +00:00
//HUDSAFE
2015-05-21 03:54:04 +00:00
lua_pushangle ( L , R_PointToAngle2 ( px2 , py2 , px1 , py1 ) ) ;
2014-03-15 16:59:03 +00:00
return 1 ;
}
static int lib_rPointToDist ( lua_State * L )
{
2015-05-21 03:54:04 +00:00
fixed_t x = luaL_checkfixed ( L , 1 ) ;
fixed_t y = luaL_checkfixed ( L , 2 ) ;
2014-03-15 16:59:03 +00:00
//HUDSAFE
2015-05-21 03:54:04 +00:00
lua_pushfixed ( L , R_PointToDist ( x , y ) ) ;
2014-03-15 16:59:03 +00:00
return 1 ;
}
static int lib_rPointToDist2 ( lua_State * L )
{
2015-05-21 03:54:04 +00:00
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 ) ;
2014-03-15 16:59:03 +00:00
//HUDSAFE
2015-05-21 03:54:04 +00:00
lua_pushfixed ( L , R_PointToDist2 ( px2 , py2 , px1 , py1 ) ) ;
2014-03-15 16:59:03 +00:00
return 1 ;
}
static int lib_rPointInSubsector ( lua_State * L )
{
2015-05-21 03:54:04 +00:00
fixed_t x = luaL_checkfixed ( L , 1 ) ;
fixed_t y = luaL_checkfixed ( L , 2 ) ;
2014-03-15 16:59:03 +00:00
//HUDSAFE
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
LUA_PushUserdata ( L , R_PointInSubsector ( x , y ) , META_SUBSECTOR ) ;
return 1 ;
}
2020-01-22 15:58:57 +00:00
static int lib_rPointInSubsectorOrNil ( lua_State * L )
2020-01-17 03:49:43 +00:00
{
fixed_t x = luaL_checkfixed ( L , 1 ) ;
fixed_t y = luaL_checkfixed ( L , 2 ) ;
2020-01-22 15:58:57 +00:00
subsector_t * sub = R_PointInSubsectorOrNull ( x , y ) ;
2020-01-17 03:49:43 +00:00
//HUDSAFE
INLEVEL
if ( sub )
LUA_PushUserdata ( L , sub , META_SUBSECTOR ) ;
else
lua_pushnil ( L ) ;
return 1 ;
}
2014-04-14 05:14:58 +00:00
// R_THINGS
////////////
static int lib_rChar2Frame ( lua_State * L )
{
const char * p = luaL_checkstring ( L , 1 ) ;
//HUDSAFE
lua_pushinteger ( L , R_Char2Frame ( * p ) ) ; // first character only
return 1 ;
}
static int lib_rFrame2Char ( lua_State * L )
{
UINT8 ch = ( UINT8 ) luaL_checkinteger ( L , 1 ) ;
char c [ 2 ] = " " ;
//HUDSAFE
c [ 0 ] = R_Frame2Char ( ch ) ;
c [ 1 ] = 0 ;
lua_pushstring ( L , c ) ;
lua_pushinteger ( L , c [ 0 ] ) ;
return 2 ;
}
2014-08-04 03:49:33 +00:00
// R_SetPlayerSkin technically doesn't exist either, although it's basically just SetPlayerSkin and SetPlayerSkinByNum handled in one place for convenience
static int lib_rSetPlayerSkin ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
2019-11-10 16:10:34 +00:00
INT32 i = - 1 , j = - 1 ;
2014-08-04 03:49:33 +00:00
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-08-04 03:49:33 +00:00
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
2019-11-10 16:10:34 +00:00
j = ( player - players ) ;
2014-08-04 03:49:33 +00:00
if ( lua_isnoneornil ( L , 2 ) )
return luaL_error ( L , " argument #2 not given (expected number or string) " ) ;
else if ( lua_type ( L , 2 ) = = LUA_TNUMBER ) // skin number
{
2019-11-10 16:10:34 +00:00
i = luaL_checkinteger ( L , 2 ) ;
if ( i < 0 | | i > = numskins )
return luaL_error ( L , " skin %d (argument #2) out of range ( 0 - % d ) " , i, numskins-1) ;
2014-08-04 03:49:33 +00:00
}
else // skin name
{
const char * skinname = luaL_checkstring ( L , 2 ) ;
2019-11-10 16:10:34 +00:00
i = R_SkinAvailable ( skinname ) ;
if ( i = = - 1 )
return luaL_error ( L , " skin %s (argument 2) is not loaded " , skinname) ;
2014-08-04 03:49:33 +00:00
}
2019-11-10 16:10:34 +00:00
if ( ! R_SkinUsable ( j , i ) )
return luaL_error ( L , " skin %d (argument 2) not usable - check with R_SkinUsable ( player_t , skin ) first . " , i) ;
SetPlayerSkinByNum ( j , i ) ;
2014-08-04 03:49:33 +00:00
return 0 ;
}
2019-11-10 16:10:34 +00:00
static int lib_rSkinUsable ( lua_State * L )
{
player_t * player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
INT32 i = - 1 , j = - 1 ;
if ( player )
j = ( player - players ) ;
else if ( netgame | | multiplayer )
return luaL_error ( L , " player_t (argument #1) must be provided in multiplayer games " ) ;
if ( lua_isnoneornil ( L , 2 ) )
return luaL_error ( L , " argument #2 not given (expected number or string) " ) ;
else if ( lua_type ( L , 2 ) = = LUA_TNUMBER ) // skin number
{
i = luaL_checkinteger ( L , 2 ) ;
if ( i < 0 | | i > = numskins )
return luaL_error ( L , " skin %d (argument #2) out of range ( 0 - % d ) " , i, numskins-1) ;
}
else // skin name
{
const char * skinname = luaL_checkstring ( L , 2 ) ;
i = R_SkinAvailable ( skinname ) ;
if ( i = = - 1 )
return luaL_error ( L , " skin %s (argument 2) is not loaded " , skinname) ;
}
lua_pushboolean ( L , R_SkinUsable ( j , i ) ) ;
return 1 ;
}
2018-12-17 02:36:54 +00:00
// R_DATA
////////////
static int lib_rCheckTextureNumForName ( lua_State * L )
{
const char * name = luaL_checkstring ( L , 1 ) ;
//HUDSAFE
lua_pushinteger ( L , R_CheckTextureNumForName ( name ) ) ;
return 1 ;
}
static int lib_rTextureNumForName ( lua_State * L )
{
const char * name = luaL_checkstring ( L , 1 ) ;
//HUDSAFE
lua_pushinteger ( L , R_TextureNumForName ( name ) ) ;
return 1 ;
}
2014-03-15 16:59:03 +00:00
// S_SOUND
////////////
static int lib_sStartSound ( lua_State * L )
{
const void * origin = NULL ;
sfxenum_t sound_id = luaL_checkinteger ( L , 2 ) ;
2014-08-04 03:49:33 +00:00
player_t * player = NULL ;
2018-07-31 09:10:02 +00:00
//NOHUD // kys @whoever did this.
2016-05-01 21:14:42 +00:00
if ( sound_id > = NUMSFX )
return luaL_error ( L , " sfx %d out of range (0 - %d) " , sound_id, NUMSFX-1) ;
2014-03-15 16:59:03 +00:00
if ( ! lua_isnil ( L , 1 ) )
{
origin = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
if ( ! origin )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
}
2014-08-04 03:49:33 +00:00
if ( ! lua_isnone ( L , 3 ) & & lua_isuserdata ( L , 3 ) )
{
player = * ( ( player_t * * ) luaL_checkudata ( L , 3 , META_PLAYER ) ) ;
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
}
if ( ! player | | P_IsLocalPlayer ( player ) )
2018-07-31 09:10:02 +00:00
{
if ( hud_running )
origin = NULL ; // HUD rendering startsound shouldn't have an origin, just remove it instead of having a retarded error.
2018-12-17 19:43:59 +00:00
2014-08-04 03:49:33 +00:00
S_StartSound ( origin , sound_id ) ;
2018-12-17 19:43:59 +00:00
}
2014-03-15 16:59:03 +00:00
return 0 ;
}
static int lib_sStartSoundAtVolume ( lua_State * L )
{
const void * origin = NULL ;
sfxenum_t sound_id = luaL_checkinteger ( L , 2 ) ;
INT32 volume = ( INT32 ) luaL_checkinteger ( L , 3 ) ;
2014-08-04 03:49:33 +00:00
player_t * player = NULL ;
2014-03-15 16:59:03 +00:00
NOHUD
2016-05-01 21:14:42 +00:00
2014-03-15 16:59:03 +00:00
if ( ! lua_isnil ( L , 1 ) )
{
origin = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
if ( ! origin )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
}
2016-05-01 21:14:42 +00:00
if ( sound_id > = NUMSFX )
return luaL_error ( L , " sfx %d out of range (0 - %d) " , sound_id, NUMSFX-1) ;
2014-08-04 03:49:33 +00:00
if ( ! lua_isnone ( L , 4 ) & & lua_isuserdata ( L , 4 ) )
{
player = * ( ( player_t * * ) luaL_checkudata ( L , 4 , META_PLAYER ) ) ;
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
}
if ( ! player | | P_IsLocalPlayer ( player ) )
2014-03-15 16:59:03 +00:00
S_StartSoundAtVolume ( origin , sound_id , volume ) ;
return 0 ;
}
static int lib_sStopSound ( lua_State * L )
{
void * origin = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
NOHUD
if ( ! origin )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
S_StopSound ( origin ) ;
return 0 ;
}
static int lib_sChangeMusic ( lua_State * L )
{
2016-03-03 10:54:07 +00:00
# ifdef MUSICSLOT_COMPATIBILITY
const char * music_name ;
2018-09-18 14:22:17 +00:00
UINT32 music_num , position , prefadems , fadeinms ;
2016-03-03 10:54:07 +00:00
char music_compat_name [ 7 ] ;
boolean looping ;
player_t * player = NULL ;
UINT16 music_flags = 0 ;
NOHUD
if ( lua_isnumber ( L , 1 ) )
{
music_num = ( UINT32 ) luaL_checkinteger ( L , 1 ) ;
music_flags = ( UINT16 ) ( music_num & 0x0000FFFF ) ;
if ( music_flags & & music_flags < = 1035 )
snprintf ( music_compat_name , 7 , " %sM " , G_BuildMapName ( ( INT32 ) music_flags ) ) ;
else if ( music_flags & & music_flags < = 1050 )
strncpy ( music_compat_name , compat_special_music_slots [ music_flags - 1036 ] , 7 ) ;
else
music_compat_name [ 0 ] = 0 ; // becomes empty string
music_compat_name [ 6 ] = 0 ;
music_name = ( const char * ) & music_compat_name ;
music_flags = 0 ;
}
else
{
music_num = 0 ;
music_name = luaL_checkstring ( L , 1 ) ;
}
looping = ( boolean ) lua_opttrueboolean ( L , 2 ) ;
# else
2016-01-08 03:48:20 +00:00
const char * music_name = luaL_checkstring ( L , 1 ) ;
2014-03-15 16:59:03 +00:00
boolean looping = ( boolean ) lua_opttrueboolean ( L , 2 ) ;
2014-08-04 03:49:33 +00:00
player_t * player = NULL ;
2016-01-08 03:48:20 +00:00
UINT16 music_flags = 0 ;
2014-03-15 16:59:03 +00:00
NOHUD
2016-03-03 10:54:07 +00:00
# endif
2014-08-04 03:49:33 +00:00
if ( ! lua_isnone ( L , 3 ) & & lua_isuserdata ( L , 3 ) )
{
player = * ( ( player_t * * ) luaL_checkudata ( L , 3 , META_PLAYER ) ) ;
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
}
2016-03-03 10:54:07 +00:00
# ifdef MUSICSLOT_COMPATIBILITY
if ( music_num )
music_flags = ( UINT16 ) ( ( music_num & 0x7FFF0000 ) > > 16 ) ;
else
# endif
2016-01-08 03:48:20 +00:00
music_flags = ( UINT16 ) luaL_optinteger ( L , 4 , 0 ) ;
2018-09-18 14:22:17 +00:00
position = ( UINT32 ) luaL_optinteger ( L , 5 , 0 ) ;
prefadems = ( UINT32 ) luaL_optinteger ( L , 6 , 0 ) ;
fadeinms = ( UINT32 ) luaL_optinteger ( L , 7 , 0 ) ;
2014-08-04 03:49:33 +00:00
if ( ! player | | P_IsLocalPlayer ( player ) )
2018-09-18 14:22:17 +00:00
S_ChangeMusicEx ( music_name , music_flags , looping , position , prefadems , fadeinms ) ;
2014-03-15 16:59:03 +00:00
return 0 ;
}
static int lib_sSpeedMusic ( lua_State * L )
{
2015-05-21 03:54:04 +00:00
fixed_t fixedspeed = luaL_checkfixed ( L , 1 ) ;
2014-03-15 16:59:03 +00:00
float speed = FIXED_TO_FLOAT ( fixedspeed ) ;
2014-08-04 03:49:33 +00:00
player_t * player = NULL ;
2014-03-15 16:59:03 +00:00
NOHUD
2014-08-04 03:49:33 +00:00
if ( ! lua_isnone ( L , 2 ) & & lua_isuserdata ( L , 2 ) )
{
player = * ( ( player_t * * ) luaL_checkudata ( L , 2 , META_PLAYER ) ) ;
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
}
if ( ! player | | P_IsLocalPlayer ( player ) )
2018-09-18 14:32:38 +00:00
S_SpeedMusic ( speed ) ;
return 0 ;
2014-03-15 16:59:03 +00:00
}
static int lib_sStopMusic ( lua_State * L )
{
2014-08-04 03:49:33 +00:00
player_t * player = NULL ;
2014-03-15 16:59:03 +00:00
NOHUD
2014-08-04 03:49:33 +00:00
if ( ! lua_isnone ( L , 1 ) & & lua_isuserdata ( L , 1 ) )
{
player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
}
if ( ! player | | P_IsLocalPlayer ( player ) )
S_StopMusic ( ) ;
2014-03-15 16:59:03 +00:00
return 0 ;
}
2019-01-02 09:58:03 +00:00
static int lib_sSetInternalMusicVolume ( lua_State * L )
{
UINT32 volume = ( UINT32 ) luaL_checkinteger ( L , 1 ) ;
player_t * player = NULL ;
NOHUD
if ( ! lua_isnone ( L , 2 ) & & lua_isuserdata ( L , 2 ) )
{
player = * ( ( player_t * * ) luaL_checkudata ( L , 2 , META_PLAYER ) ) ;
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
}
if ( ! player | | P_IsLocalPlayer ( player ) )
{
S_SetInternalMusicVolume ( volume ) ;
lua_pushboolean ( L , true ) ;
}
else
lua_pushnil ( L ) ;
return 1 ;
}
static int lib_sStopFadingMusic ( lua_State * L )
{
player_t * player = NULL ;
NOHUD
if ( ! lua_isnone ( L , 1 ) & & lua_isuserdata ( L , 1 ) )
{
player = * ( ( player_t * * ) luaL_checkudata ( L , 1 , META_PLAYER ) ) ;
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
}
if ( ! player | | P_IsLocalPlayer ( player ) )
{
S_StopFadingMusic ( ) ;
lua_pushboolean ( L , true ) ;
}
else
lua_pushnil ( L ) ;
return 1 ;
}
static int lib_sFadeMusic ( lua_State * L )
{
UINT32 target_volume = ( UINT32 ) luaL_checkinteger ( L , 1 ) ;
UINT32 ms ;
INT32 source_volume ;
player_t * player = NULL ;
NOHUD
if ( ! lua_isnone ( L , 3 ) & & lua_isuserdata ( L , 3 ) )
{
player = * ( ( player_t * * ) luaL_checkudata ( L , 3 , META_PLAYER ) ) ;
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
ms = ( UINT32 ) luaL_checkinteger ( L , 2 ) ;
source_volume = - 1 ;
}
else if ( ! lua_isnone ( L , 4 ) & & lua_isuserdata ( L , 4 ) )
{
player = * ( ( player_t * * ) luaL_checkudata ( L , 4 , META_PLAYER ) ) ;
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
source_volume = ( INT32 ) luaL_checkinteger ( L , 2 ) ;
ms = ( UINT32 ) luaL_checkinteger ( L , 3 ) ;
}
else if ( luaL_optinteger ( L , 3 , INT32_MAX ) = = INT32_MAX )
{
ms = ( UINT32 ) luaL_checkinteger ( L , 2 ) ;
source_volume = - 1 ;
}
else
{
source_volume = ( INT32 ) luaL_checkinteger ( L , 2 ) ;
ms = ( UINT32 ) luaL_checkinteger ( L , 3 ) ;
}
NOHUD
if ( ! player | | P_IsLocalPlayer ( player ) )
lua_pushboolean ( L , S_FadeMusicFromVolume ( target_volume , source_volume , ms ) ) ;
else
lua_pushnil ( L ) ;
return 1 ;
}
static int lib_sFadeOutStopMusic ( lua_State * L )
{
UINT32 ms = ( UINT32 ) luaL_checkinteger ( L , 1 ) ;
player_t * player = NULL ;
NOHUD
if ( ! lua_isnone ( L , 2 ) & & lua_isuserdata ( L , 2 ) )
{
player = * ( ( player_t * * ) luaL_checkudata ( L , 2 , META_PLAYER ) ) ;
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
}
if ( ! player | | P_IsLocalPlayer ( player ) )
{
lua_pushboolean ( L , S_FadeOutStopMusic ( ms ) ) ;
}
else
lua_pushnil ( L ) ;
return 1 ;
}
2014-03-15 16:59:03 +00:00
static int lib_sOriginPlaying ( lua_State * L )
{
void * origin = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! origin )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
lua_pushboolean ( L , S_OriginPlaying ( origin ) ) ;
return 1 ;
}
static int lib_sIdPlaying ( lua_State * L )
{
sfxenum_t id = luaL_checkinteger ( L , 1 ) ;
NOHUD
2016-05-01 21:14:42 +00:00
if ( id > = NUMSFX )
return luaL_error ( L , " sfx %d out of range (0 - %d) " , id, NUMSFX-1) ;
2014-03-15 16:59:03 +00:00
lua_pushboolean ( L , S_IdPlaying ( id ) ) ;
return 1 ;
}
static int lib_sSoundPlaying ( lua_State * L )
{
void * origin = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
sfxenum_t id = luaL_checkinteger ( L , 2 ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( ! origin )
return LUA_ErrInvalid ( L , " mobj_t " ) ;
2016-05-01 21:14:42 +00:00
if ( id > = NUMSFX )
return luaL_error ( L , " sfx %d out of range (0 - %d) " , id, NUMSFX-1) ;
2014-03-15 16:59:03 +00:00
lua_pushboolean ( L , S_SoundPlaying ( origin , id ) ) ;
return 1 ;
}
2017-04-29 15:27:52 +00:00
// This doesn't really exist, but we're providing it as a handy netgame-safe wrapper for stuff that should be locally handled.
static int lib_sStartMusicCaption ( lua_State * L )
{
player_t * player = NULL ;
const char * caption = luaL_checkstring ( L , 1 ) ;
UINT16 lifespan = ( UINT16 ) luaL_checkinteger ( L , 2 ) ;
//HUDSAFE
INLEVEL
if ( ! lua_isnone ( L , 3 ) & & lua_isuserdata ( L , 3 ) )
{
player = * ( ( player_t * * ) luaL_checkudata ( L , 3 , META_PLAYER ) ) ;
if ( ! player )
return LUA_ErrInvalid ( L , " player_t " ) ;
}
if ( lifespan & & ( ! player | | P_IsLocalPlayer ( player ) ) )
{
strlcpy ( S_sfx [ sfx_None ] . caption , caption , sizeof ( S_sfx [ sfx_None ] . caption ) ) ;
S_StartCaption ( sfx_None , - 1 , lifespan ) ;
}
return 0 ;
}
2014-03-15 16:59:03 +00:00
// G_GAME
////////////
2019-12-19 05:13:09 +00:00
// Copypasted from lib_cvRegisterVar :]
static int lib_gAddGametype ( lua_State * L )
{
const char * k ;
lua_Integer i ;
const char * gtname = NULL ;
2019-12-23 21:54:25 +00:00
const char * gtconst = NULL ;
2019-12-19 05:13:09 +00:00
const char * gtdescription = NULL ;
INT16 newgtidx = 0 ;
UINT32 newgtrules = 0 ;
UINT32 newgttol = 0 ;
INT32 newgtpointlimit = 0 ;
INT32 newgttimelimit = 0 ;
UINT8 newgtleftcolor = 0 ;
UINT8 newgtrightcolor = 0 ;
INT16 newgtrankingstype = - 1 ;
int newgtinttype = 0 ;
luaL_checktype ( L , 1 , LUA_TTABLE ) ;
lua_settop ( L , 1 ) ; // Clear out all other possible arguments, leaving only the first one.
if ( ! lua_lumploading )
return luaL_error ( L , " This function cannot be called from within a hook or coroutine! " ) ;
2019-12-23 22:00:46 +00:00
// Ran out of gametype slots
if ( gametypecount = = NUMGAMETYPEFREESLOTS )
return luaL_error ( L , " Ran out of free gametype slots! " ) ;
2019-12-19 05:13:09 +00:00
# define FIELDERROR(f, e) luaL_error(L, "bad value for " LUA_QL(f) " in table passed to " LUA_QL("G_AddGametype") " (%s)", e);
# define TYPEERROR(f, t) FIELDERROR(f, va("%s expected, got %s", lua_typename(L, t), luaL_typename(L, -1)))
lua_pushnil ( L ) ;
while ( lua_next ( L , 1 ) ) {
// stack: gametype table, key/index, value
// 1 2 3
i = 0 ;
k = NULL ;
if ( lua_isnumber ( L , 2 ) )
i = lua_tointeger ( L , 2 ) ;
else if ( lua_isstring ( L , 2 ) )
k = lua_tostring ( L , 2 ) ;
// Sorry, no gametype rules as key names.
if ( i = = 1 | | ( k & & fasticmp ( k , " name " ) ) ) {
if ( ! lua_isstring ( L , 3 ) )
TYPEERROR ( " name " , LUA_TSTRING )
gtname = Z_StrDup ( lua_tostring ( L , 3 ) ) ;
2019-12-23 21:54:25 +00:00
} else if ( i = = 2 | | ( k & & fasticmp ( k , " identifier " ) ) ) {
if ( ! lua_isstring ( L , 3 ) )
TYPEERROR ( " identifier " , LUA_TSTRING )
gtconst = Z_StrDup ( lua_tostring ( L , 3 ) ) ;
} else if ( i = = 3 | | ( k & & fasticmp ( k , " rules " ) ) ) {
2019-12-19 05:13:09 +00:00
if ( ! lua_isnumber ( L , 3 ) )
TYPEERROR ( " rules " , LUA_TNUMBER )
newgtrules = ( UINT32 ) lua_tointeger ( L , 3 ) ;
2019-12-23 21:54:25 +00:00
} else if ( i = = 4 | | ( k & & fasticmp ( k , " typeoflevel " ) ) ) {
2019-12-19 05:13:09 +00:00
if ( ! lua_isnumber ( L , 3 ) )
TYPEERROR ( " typeoflevel " , LUA_TNUMBER )
newgttol = ( UINT32 ) lua_tointeger ( L , 3 ) ;
2019-12-23 21:54:25 +00:00
} else if ( i = = 5 | | ( k & & fasticmp ( k , " rankingtype " ) ) ) {
2019-12-19 05:13:09 +00:00
if ( ! lua_isnumber ( L , 3 ) )
TYPEERROR ( " rankingtype " , LUA_TNUMBER )
newgtrankingstype = ( INT16 ) lua_tointeger ( L , 3 ) ;
2019-12-23 21:54:25 +00:00
} else if ( i = = 6 | | ( k & & fasticmp ( k , " intermissiontype " ) ) ) {
2019-12-19 05:13:09 +00:00
if ( ! lua_isnumber ( L , 3 ) )
TYPEERROR ( " intermissiontype " , LUA_TNUMBER )
newgtinttype = ( int ) lua_tointeger ( L , 3 ) ;
2019-12-23 21:54:25 +00:00
} else if ( i = = 7 | | ( k & & fasticmp ( k , " defaultpointlimit " ) ) ) {
2019-12-19 05:13:09 +00:00
if ( ! lua_isnumber ( L , 3 ) )
TYPEERROR ( " defaultpointlimit " , LUA_TNUMBER )
newgtpointlimit = ( INT32 ) lua_tointeger ( L , 3 ) ;
2019-12-23 21:54:25 +00:00
} else if ( i = = 8 | | ( k & & fasticmp ( k , " defaulttimelimit " ) ) ) {
2019-12-19 05:13:09 +00:00
if ( ! lua_isnumber ( L , 3 ) )
TYPEERROR ( " defaulttimelimit " , LUA_TNUMBER )
newgttimelimit = ( INT32 ) lua_tointeger ( L , 3 ) ;
2019-12-23 21:54:25 +00:00
} else if ( i = = 9 | | ( k & & fasticmp ( k , " description " ) ) ) {
2019-12-19 05:13:09 +00:00
if ( ! lua_isstring ( L , 3 ) )
TYPEERROR ( " description " , LUA_TSTRING )
gtdescription = Z_StrDup ( lua_tostring ( L , 3 ) ) ;
2019-12-23 21:54:25 +00:00
} else if ( i = = 10 | | ( k & & fasticmp ( k , " headerleftcolor " ) ) ) {
2019-12-19 05:13:09 +00:00
if ( ! lua_isnumber ( L , 3 ) )
TYPEERROR ( " headerleftcolor " , LUA_TNUMBER )
newgtleftcolor = ( UINT8 ) lua_tointeger ( L , 3 ) ;
2019-12-23 21:54:25 +00:00
} else if ( i = = 11 | | ( k & & fasticmp ( k , " headerrightcolor " ) ) ) {
2019-12-19 05:13:09 +00:00
if ( ! lua_isnumber ( L , 3 ) )
TYPEERROR ( " headerrightcolor " , LUA_TNUMBER )
newgtrightcolor = ( UINT8 ) lua_tointeger ( L , 3 ) ;
// Key name specified
} else if ( ( ! i ) & & ( k & & fasticmp ( k , " headercolor " ) ) ) {
if ( ! lua_isnumber ( L , 3 ) )
TYPEERROR ( " headercolor " , LUA_TNUMBER )
newgtleftcolor = newgtrightcolor = ( UINT8 ) lua_tointeger ( L , 3 ) ;
}
lua_pop ( L , 1 ) ;
}
# undef FIELDERROR
# undef TYPEERROR
// pop gametype table
lua_pop ( L , 1 ) ;
// Set defaults
if ( gtname = = NULL )
gtname = Z_StrDup ( " Unnamed gametype " ) ;
if ( gtdescription = = NULL )
gtdescription = Z_StrDup ( " ??? " ) ;
// Add the new gametype
newgtidx = G_AddGametype ( newgtrules ) ;
G_AddGametypeTOL ( newgtidx , newgttol ) ;
2019-12-19 05:20:49 +00:00
G_SetGametypeDescription ( newgtidx , NULL , newgtleftcolor , newgtrightcolor ) ;
strncpy ( gametypedesc [ newgtidx ] . notes , gtdescription , 441 ) ;
2019-12-19 05:13:09 +00:00
// Not covered by G_AddGametype alone.
if ( newgtrankingstype = = - 1 )
newgtrankingstype = newgtidx ;
gametyperankings [ newgtidx ] = newgtrankingstype ;
intermissiontypes [ newgtidx ] = newgtinttype ;
pointlimits [ newgtidx ] = newgtpointlimit ;
timelimits [ newgtidx ] = newgttimelimit ;
// Write the new gametype name.
Gametype_Names [ newgtidx ] = gtname ;
// Write the constant name.
2019-12-23 21:54:25 +00:00
if ( gtconst = = NULL )
gtconst = gtname ;
G_AddGametypeConstant ( newgtidx , gtconst ) ;
2019-12-19 05:13:09 +00:00
// Update gametype_cons_t accordingly.
G_UpdateGametypeSelections ( ) ;
// done
CONS_Printf ( " Added gametype %s \n " , Gametype_Names [ newgtidx ] ) ;
return 0 ;
}
2014-03-15 16:59:03 +00:00
static int lib_gBuildMapName ( lua_State * L )
{
2014-04-19 17:41:29 +00:00
INT32 map = luaL_optinteger ( L , 1 , gamemap ) ;
2014-03-15 16:59:03 +00:00
//HUDSAFE
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
lua_pushstring ( L , G_BuildMapName ( map ) ) ;
return 1 ;
}
static int lib_gDoReborn ( lua_State * L )
{
INT32 playernum = luaL_checkinteger ( L , 1 ) ;
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( playernum > = MAXPLAYERS )
2016-05-01 21:14:42 +00:00
return luaL_error ( L , " playernum %d out of range (0 - %d) " , playernum, MAXPLAYERS-1) ;
2014-03-15 16:59:03 +00:00
G_DoReborn ( playernum ) ;
return 0 ;
}
2018-12-18 19:48:04 +00:00
// Another Lua function that doesn't actually exist!
// Sets nextmapoverride & skipstats without instantly ending the level, for instances where other sources should be exiting the level, like normal signposts.
static int lib_gSetCustomExitVars ( lua_State * L )
2014-03-15 16:59:03 +00:00
{
2014-11-12 00:55:07 +00:00
int n = lua_gettop ( L ) ; // Num arguments
2014-03-15 16:59:03 +00:00
NOHUD
2017-01-18 22:02:28 +00:00
INLEVEL
2014-11-12 00:55:07 +00:00
// LUA EXTENSION: Custom exit like support
// Supported:
2018-12-18 19:48:04 +00:00
// G_SetCustomExitVars(); [reset to defaults]
// G_SetCustomExitVars(int) [nextmap override only]
2019-12-13 21:36:33 +00:00
// G_SetCustomExitVars(nil, int) [skipstats only]
// G_SetCustomExitVars(int, int) [both of the above]
nextmapoverride = 0 ;
skipstats = 0 ;
2014-11-12 00:55:07 +00:00
if ( n > = 1 )
{
2019-12-13 21:36:33 +00:00
nextmapoverride = ( INT16 ) luaL_optinteger ( L , 1 , 0 ) ;
skipstats = ( INT16 ) luaL_optinteger ( L , 2 , 0 ) ;
2018-12-18 19:48:04 +00:00
}
2014-11-12 00:55:07 +00:00
2018-12-18 19:48:04 +00:00
return 0 ;
}
2019-11-15 14:35:28 +00:00
static int lib_gEnoughPlayersFinished ( lua_State * L )
{
INLEVEL
lua_pushboolean ( L , G_EnoughPlayersFinished ( ) ) ;
return 1 ;
}
2018-12-18 20:03:54 +00:00
static int lib_gExitLevel ( lua_State * L )
{
int n = lua_gettop ( L ) ; // Num arguments
NOHUD
// Moved this bit to G_SetCustomExitVars
if ( n > = 1 ) // Don't run the reset to defaults option
lib_gSetCustomExitVars ( L ) ;
2014-03-15 16:59:03 +00:00
G_ExitLevel ( ) ;
return 0 ;
}
static int lib_gIsSpecialStage ( lua_State * L )
{
2014-04-19 17:41:29 +00:00
INT32 mapnum = luaL_optinteger ( L , 1 , gamemap ) ;
2014-03-15 16:59:03 +00:00
//HUDSAFE
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
lua_pushboolean ( L , G_IsSpecialStage ( mapnum ) ) ;
return 1 ;
}
static int lib_gGametypeUsesLives ( lua_State * L )
{
//HUDSAFE
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
lua_pushboolean ( L , G_GametypeUsesLives ( ) ) ;
return 1 ;
}
2019-12-27 20:08:20 +00:00
static int lib_gGametypeUsesCoopLives ( lua_State * L )
{
//HUDSAFE
INLEVEL
lua_pushboolean ( L , G_GametypeUsesCoopLives ( ) ) ;
return 1 ;
}
2019-12-27 20:14:56 +00:00
static int lib_gGametypeUsesCoopStarposts ( lua_State * L )
{
//HUDSAFE
INLEVEL
lua_pushboolean ( L , G_GametypeUsesCoopStarposts ( ) ) ;
return 1 ;
}
2014-03-15 16:59:03 +00:00
static int lib_gGametypeHasTeams ( lua_State * L )
{
//HUDSAFE
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
lua_pushboolean ( L , G_GametypeHasTeams ( ) ) ;
return 1 ;
}
static int lib_gGametypeHasSpectators ( lua_State * L )
{
//HUDSAFE
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
lua_pushboolean ( L , G_GametypeHasSpectators ( ) ) ;
return 1 ;
}
static int lib_gRingSlingerGametype ( lua_State * L )
{
//HUDSAFE
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
lua_pushboolean ( L , G_RingSlingerGametype ( ) ) ;
return 1 ;
}
static int lib_gPlatformGametype ( lua_State * L )
{
//HUDSAFE
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
lua_pushboolean ( L , G_PlatformGametype ( ) ) ;
return 1 ;
}
static int lib_gTagGametype ( lua_State * L )
{
//HUDSAFE
2017-01-18 22:02:28 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
lua_pushboolean ( L , G_TagGametype ( ) ) ;
return 1 ;
}
2019-12-27 20:08:20 +00:00
static int lib_gCompetitionGametype ( lua_State * L )
{
//HUDSAFE
INLEVEL
lua_pushboolean ( L , G_CompetitionGametype ( ) ) ;
return 1 ;
}
2014-03-15 16:59:03 +00:00
static int lib_gTicsToHours ( lua_State * L )
{
tic_t rtic = luaL_checkinteger ( L , 1 ) ;
//HUDSAFE
lua_pushinteger ( L , G_TicsToHours ( rtic ) ) ;
return 1 ;
}
static int lib_gTicsToMinutes ( lua_State * L )
{
tic_t rtic = luaL_checkinteger ( L , 1 ) ;
boolean rfull = lua_optboolean ( L , 2 ) ;
//HUDSAFE
lua_pushinteger ( L , G_TicsToMinutes ( rtic , rfull ) ) ;
return 1 ;
}
static int lib_gTicsToSeconds ( lua_State * L )
{
tic_t rtic = luaL_checkinteger ( L , 1 ) ;
//HUDSAFE
lua_pushinteger ( L , G_TicsToSeconds ( rtic ) ) ;
return 1 ;
}
static int lib_gTicsToCentiseconds ( lua_State * L )
{
tic_t rtic = luaL_checkinteger ( L , 1 ) ;
//HUDSAFE
lua_pushinteger ( L , G_TicsToCentiseconds ( rtic ) ) ;
return 1 ;
}
static int lib_gTicsToMilliseconds ( lua_State * L )
{
tic_t rtic = luaL_checkinteger ( L , 1 ) ;
//HUDSAFE
lua_pushinteger ( L , G_TicsToMilliseconds ( rtic ) ) ;
return 1 ;
}
static luaL_Reg lib [ ] = {
{ " print " , lib_print } ,
2018-07-31 09:10:02 +00:00
{ " chatprint " , lib_chatprint } ,
{ " chatprintf " , lib_chatprintf } ,
2017-01-19 18:30:55 +00:00
{ " userdataType " , lib_userdataType } ,
2018-11-07 23:07:34 +00:00
{ " IsPlayerAdmin " , lib_isPlayerAdmin } ,
2019-08-24 17:25:27 +00:00
{ " reserveLuabanks " , lib_reserveLuabanks } ,
2014-03-15 16:59:03 +00:00
// m_random
2016-03-27 14:33:15 +00:00
{ " P_RandomFixed " , lib_pRandomFixed } ,
{ " P_RandomByte " , lib_pRandomByte } ,
2014-03-15 16:59:03 +00:00
{ " P_RandomKey " , lib_pRandomKey } ,
{ " P_RandomRange " , lib_pRandomRange } ,
2016-03-27 14:33:15 +00:00
{ " P_SignedRandom " , lib_pSignedRandom } , // MACRO
{ " P_RandomChance " , lib_pRandomChance } , // MACRO
2014-03-15 16:59:03 +00:00
// p_maputil
{ " P_AproxDistance " , lib_pAproxDistance } ,
{ " P_ClosestPointOnLine " , lib_pClosestPointOnLine } ,
2016-05-25 15:34:09 +00:00
{ " P_PointOnLineSide " , lib_pPointOnLineSide } ,
2014-03-15 16:59:03 +00:00
// p_enemy
{ " P_CheckMeleeRange " , lib_pCheckMeleeRange } ,
{ " P_JetbCheckMeleeRange " , lib_pJetbCheckMeleeRange } ,
{ " P_FaceStabCheckMeleeRange " , lib_pFaceStabCheckMeleeRange } ,
{ " P_SkimCheckMeleeRange " , lib_pSkimCheckMeleeRange } ,
{ " P_CheckMissileRange " , lib_pCheckMissileRange } ,
{ " P_NewChaseDir " , lib_pNewChaseDir } ,
{ " P_LookForPlayers " , lib_pLookForPlayers } ,
// p_mobj
// don't add P_SetMobjState or P_SetPlayerMobjState, use "mobj.state = S_NEWSTATE" instead.
{ " P_SpawnMobj " , lib_pSpawnMobj } ,
2017-07-08 10:41:20 +00:00
{ " P_SpawnMobjFromMobj " , lib_pSpawnMobjFromMobj } ,
2014-03-15 16:59:03 +00:00
{ " P_RemoveMobj " , lib_pRemoveMobj } ,
2016-11-11 23:23:41 +00:00
{ " P_IsValidSprite2 " , lib_pIsValidSprite2 } ,
2017-03-23 19:11:22 +00:00
{ " P_SpawnLockOn " , lib_pSpawnLockOn } ,
2014-03-15 16:59:03 +00:00
{ " P_SpawnMissile " , lib_pSpawnMissile } ,
{ " P_SpawnXYZMissile " , lib_pSpawnXYZMissile } ,
{ " P_SpawnPointMissile " , lib_pSpawnPointMissile } ,
{ " P_SpawnAlteredDirectionMissile " , lib_pSpawnAlteredDirectionMissile } ,
{ " P_ColorTeamMissile " , lib_pColorTeamMissile } ,
{ " P_SPMAngle " , lib_pSPMAngle } ,
{ " P_SpawnPlayerMissile " , lib_pSpawnPlayerMissile } ,
{ " P_MobjFlip " , lib_pMobjFlip } ,
2016-06-01 12:19:44 +00:00
{ " P_GetMobjGravity " , lib_pGetMobjGravity } ,
2014-03-15 16:59:03 +00:00
{ " P_WeaponOrPanel " , lib_pWeaponOrPanel } ,
{ " P_FlashPal " , lib_pFlashPal } ,
{ " P_GetClosestAxis " , lib_pGetClosestAxis } ,
{ " P_SpawnParaloop " , lib_pSpawnParaloop } ,
{ " P_BossTargetPlayer " , lib_pBossTargetPlayer } ,
{ " P_SupermanLook4Players " , lib_pSupermanLook4Players } ,
{ " P_SetScale " , lib_pSetScale } ,
2014-08-04 03:49:33 +00:00
{ " P_InsideANonSolidFFloor " , lib_pInsideANonSolidFFloor } ,
2014-03-15 16:59:03 +00:00
{ " P_CheckDeathPitCollide " , lib_pCheckDeathPitCollide } ,
2014-08-04 03:49:33 +00:00
{ " P_CheckSolidLava " , lib_pCheckSolidLava } ,
{ " P_CanRunOnWater " , lib_pCanRunOnWater } ,
2018-04-01 19:54:19 +00:00
{ " P_MaceRotate " , lib_pMaceRotate } ,
2014-03-15 16:59:03 +00:00
// p_user
{ " P_GetPlayerHeight " , lib_pGetPlayerHeight } ,
{ " P_GetPlayerSpinHeight " , lib_pGetPlayerSpinHeight } ,
{ " P_GetPlayerControlDirection " , lib_pGetPlayerControlDirection } ,
{ " P_AddPlayerScore " , lib_pAddPlayerScore } ,
2015-05-27 06:08:18 +00:00
{ " P_StealPlayerScore " , lib_pStealPlayerScore } ,
2017-04-03 17:28:02 +00:00
{ " P_GetJumpFlags " , lib_pGetJumpFlags } ,
2014-03-15 16:59:03 +00:00
{ " P_PlayerInPain " , lib_pPlayerInPain } ,
{ " P_DoPlayerPain " , lib_pDoPlayerPain } ,
{ " P_ResetPlayer " , lib_pResetPlayer } ,
2019-06-19 11:09:02 +00:00
{ " P_PlayerCanDamage " , lib_pPlayerCanDamage } ,
2014-08-04 03:49:33 +00:00
{ " P_IsObjectInGoop " , lib_pIsObjectInGoop } ,
2014-03-15 16:59:03 +00:00
{ " P_IsObjectOnGround " , lib_pIsObjectOnGround } ,
2014-08-04 03:49:33 +00:00
{ " P_InSpaceSector " , lib_pInSpaceSector } ,
{ " P_InQuicksand " , lib_pInQuicksand } ,
2014-03-15 16:59:03 +00:00
{ " P_SetObjectMomZ " , lib_pSetObjectMomZ } ,
{ " P_RestoreMusic " , lib_pRestoreMusic } ,
2014-08-04 03:49:33 +00:00
{ " P_SpawnShieldOrb " , lib_pSpawnShieldOrb } ,
2014-03-15 16:59:03 +00:00
{ " P_SpawnGhostMobj " , lib_pSpawnGhostMobj } ,
{ " P_GivePlayerRings " , lib_pGivePlayerRings } ,
{ " P_GivePlayerLives " , lib_pGivePlayerLives } ,
2017-05-29 21:18:02 +00:00
{ " P_GiveCoopLives " , lib_pGiveCoopLives } ,
2014-03-15 16:59:03 +00:00
{ " P_ResetScore " , lib_pResetScore } ,
2014-08-04 03:49:33 +00:00
{ " P_DoJumpShield " , lib_pDoJumpShield } ,
2016-10-24 12:33:10 +00:00
{ " P_DoBubbleBounce " , lib_pDoBubbleBounce } ,
2014-03-15 16:59:03 +00:00
{ " P_BlackOw " , lib_pBlackOw } ,
2016-07-08 21:56:17 +00:00
{ " P_ElementalFire " , lib_pElementalFire } ,
2019-11-15 14:35:28 +00:00
{ " P_DoPlayerFinish " , lib_pDoPlayerFinish } ,
2014-03-15 16:59:03 +00:00
{ " P_DoPlayerExit " , lib_pDoPlayerExit } ,
{ " P_InstaThrust " , lib_pInstaThrust } ,
{ " P_ReturnThrustX " , lib_pReturnThrustX } ,
{ " P_ReturnThrustY " , lib_pReturnThrustY } ,
{ " P_LookForEnemies " , lib_pLookForEnemies } ,
{ " P_NukeEnemies " , lib_pNukeEnemies } ,
{ " P_HomingAttack " , lib_pHomingAttack } ,
2014-04-14 05:14:58 +00:00
{ " P_SuperReady " , lib_pSuperReady } ,
{ " P_DoJump " , lib_pDoJump } ,
2014-05-23 20:46:49 +00:00
{ " P_SpawnThokMobj " , lib_pSpawnThokMobj } ,
2014-05-23 22:08:35 +00:00
{ " P_SpawnSpinMobj " , lib_pSpawnSpinMobj } ,
2014-05-26 02:41:05 +00:00
{ " P_Telekinesis " , lib_pTelekinesis } ,
2017-08-10 12:57:09 +00:00
{ " P_SwitchShield " , lib_pSwitchShield } ,
2014-03-15 16:59:03 +00:00
// p_map
{ " P_CheckPosition " , lib_pCheckPosition } ,
{ " P_TryMove " , lib_pTryMove } ,
{ " P_Move " , lib_pMove } ,
{ " P_TeleportMove " , lib_pTeleportMove } ,
{ " P_SlideMove " , lib_pSlideMove } ,
{ " P_BounceMove " , lib_pBounceMove } ,
{ " P_CheckSight " , lib_pCheckSight } ,
{ " P_CheckHoopPosition " , lib_pCheckHoopPosition } ,
{ " P_RadiusAttack " , lib_pRadiusAttack } ,
{ " P_FloorzAtPos " , lib_pFloorzAtPos } ,
2014-05-23 22:55:07 +00:00
{ " P_DoSpring " , lib_pDoSpring } ,
2014-03-15 16:59:03 +00:00
// p_inter
{ " P_RemoveShield " , lib_pRemoveShield } ,
{ " P_DamageMobj " , lib_pDamageMobj } ,
{ " P_KillMobj " , lib_pKillMobj } ,
{ " P_PlayerRingBurst " , lib_pPlayerRingBurst } ,
{ " P_PlayerWeaponPanelBurst " , lib_pPlayerWeaponPanelBurst } ,
{ " P_PlayerWeaponAmmoBurst " , lib_pPlayerWeaponAmmoBurst } ,
2015-05-27 04:45:34 +00:00
{ " P_PlayerWeaponPanelOrAmmoBurst " , lib_pPlayerWeaponPanelOrAmmoBurst } ,
2014-03-15 16:59:03 +00:00
{ " P_PlayerEmeraldBurst " , lib_pPlayerEmeraldBurst } ,
{ " P_PlayerFlagBurst " , lib_pPlayerFlagBurst } ,
{ " P_PlayRinglossSound " , lib_pPlayRinglossSound } ,
{ " P_PlayDeathSound " , lib_pPlayDeathSound } ,
{ " P_PlayVictorySound " , lib_pPlayVictorySound } ,
{ " P_PlayLivesJingle " , lib_pPlayLivesJingle } ,
{ " P_CanPickupItem " , lib_pCanPickupItem } ,
{ " P_DoNightsScore " , lib_pDoNightsScore } ,
2015-05-27 06:08:18 +00:00
{ " P_DoMatchSuper " , lib_pDoMatchSuper } ,
2014-03-15 16:59:03 +00:00
// p_spec
{ " P_Thrust " , lib_pThrust } ,
{ " P_SetMobjStateNF " , lib_pSetMobjStateNF } ,
{ " P_DoSuperTransformation " , lib_pDoSuperTransformation } ,
{ " P_ExplodeMissile " , lib_pExplodeMissile } ,
{ " P_PlayerTouchingSectorSpecial " , lib_pPlayerTouchingSectorSpecial } ,
2017-10-30 20:09:41 +00:00
{ " P_FindLowestFloorSurrounding " , lib_pFindLowestFloorSurrounding } ,
{ " P_FindHighestFloorSurrounding " , lib_pFindHighestFloorSurrounding } ,
{ " P_FindNextHighestFloor " , lib_pFindNextHighestFloor } ,
{ " P_FindNextLowestFloor " , lib_pFindNextLowestFloor } ,
{ " P_FindLowestCeilingSurrounding " , lib_pFindLowestCeilingSurrounding } ,
{ " P_FindHighestCeilingSurrounding " , lib_pFindHighestCeilingSurrounding } ,
2014-03-15 16:59:03 +00:00
{ " P_FindSpecialLineFromTag " , lib_pFindSpecialLineFromTag } ,
{ " P_SwitchWeather " , lib_pSwitchWeather } ,
{ " P_LinedefExecute " , lib_pLinedefExecute } ,
{ " P_SpawnLightningFlash " , lib_pSpawnLightningFlash } ,
{ " P_FadeLight " , lib_pFadeLight } ,
{ " P_ThingOnSpecial3DFloor " , lib_pThingOnSpecial3DFloor } ,
2014-05-26 02:41:05 +00:00
{ " P_IsFlagAtBase " , lib_pIsFlagAtBase } ,
2014-03-15 16:59:03 +00:00
{ " P_SetupLevelSky " , lib_pSetupLevelSky } ,
{ " P_SetSkyboxMobj " , lib_pSetSkyboxMobj } ,
{ " P_StartQuake " , lib_pStartQuake } ,
2014-08-04 03:49:33 +00:00
{ " EV_CrumbleChain " , lib_evCrumbleChain } ,
2016-07-01 19:27:09 +00:00
{ " EV_StartCrumble " , lib_evStartCrumble } ,
2014-03-15 16:59:03 +00:00
2018-10-20 20:08:59 +00:00
# ifdef ESLOPE
// p_slopes
{ " P_GetZAt " , lib_pGetZAt } ,
# endif
2014-03-15 16:59:03 +00:00
// r_defs
{ " R_PointToAngle " , lib_rPointToAngle } ,
{ " R_PointToAngle2 " , lib_rPointToAngle2 } ,
{ " R_PointToDist " , lib_rPointToDist } ,
{ " R_PointToDist2 " , lib_rPointToDist2 } ,
{ " R_PointInSubsector " , lib_rPointInSubsector } ,
2020-01-22 15:58:57 +00:00
{ " R_PointInSubsectorOrNil " , lib_rPointInSubsectorOrNil } ,
2014-03-15 16:59:03 +00:00
2014-04-14 05:14:58 +00:00
// r_things (sprite)
{ " R_Char2Frame " , lib_rChar2Frame } ,
{ " R_Frame2Char " , lib_rFrame2Char } ,
2014-08-04 03:49:33 +00:00
{ " R_SetPlayerSkin " , lib_rSetPlayerSkin } ,
2019-11-10 16:10:34 +00:00
{ " R_SkinUsable " , lib_rSkinUsable } ,
2014-04-14 05:14:58 +00:00
2018-12-16 20:58:47 +00:00
// r_data
2018-12-16 23:19:53 +00:00
{ " R_CheckTextureNumForName " , lib_rCheckTextureNumForName } ,
{ " R_TextureNumForName " , lib_rTextureNumForName } ,
2018-12-16 20:58:47 +00:00
2014-03-15 16:59:03 +00:00
// s_sound
{ " S_StartSound " , lib_sStartSound } ,
{ " S_StartSoundAtVolume " , lib_sStartSoundAtVolume } ,
{ " S_StopSound " , lib_sStopSound } ,
{ " S_ChangeMusic " , lib_sChangeMusic } ,
{ " S_SpeedMusic " , lib_sSpeedMusic } ,
{ " S_StopMusic " , lib_sStopMusic } ,
2019-01-02 09:58:03 +00:00
{ " S_SetInternalMusicVolume " , lib_sSetInternalMusicVolume } ,
{ " S_StopFadingMusic " , lib_sStopFadingMusic } ,
{ " S_FadeMusic " , lib_sFadeMusic } ,
{ " S_FadeOutStopMusic " , lib_sFadeOutStopMusic } ,
2014-03-15 16:59:03 +00:00
{ " S_OriginPlaying " , lib_sOriginPlaying } ,
{ " S_IdPlaying " , lib_sIdPlaying } ,
{ " S_SoundPlaying " , lib_sSoundPlaying } ,
2017-04-29 15:27:52 +00:00
{ " S_StartMusicCaption " , lib_sStartMusicCaption } ,
2014-03-15 16:59:03 +00:00
// g_game
2019-12-19 05:13:09 +00:00
{ " G_AddGametype " , lib_gAddGametype } ,
2014-03-15 16:59:03 +00:00
{ " G_BuildMapName " , lib_gBuildMapName } ,
{ " G_DoReborn " , lib_gDoReborn } ,
2018-12-18 19:48:04 +00:00
{ " G_SetCustomExitVars " , lib_gSetCustomExitVars } ,
2019-11-15 14:35:28 +00:00
{ " G_EnoughPlayersFinished " , lib_gEnoughPlayersFinished } ,
2014-03-15 16:59:03 +00:00
{ " G_ExitLevel " , lib_gExitLevel } ,
{ " G_IsSpecialStage " , lib_gIsSpecialStage } ,
{ " G_GametypeUsesLives " , lib_gGametypeUsesLives } ,
2019-12-27 20:08:20 +00:00
{ " G_GametypeUsesCoopLives " , lib_gGametypeUsesCoopLives } ,
2019-12-27 20:14:56 +00:00
{ " G_GametypeUsesCoopStarposts " , lib_gGametypeUsesCoopStarposts } ,
2014-03-15 16:59:03 +00:00
{ " G_GametypeHasTeams " , lib_gGametypeHasTeams } ,
{ " G_GametypeHasSpectators " , lib_gGametypeHasSpectators } ,
{ " G_RingSlingerGametype " , lib_gRingSlingerGametype } ,
{ " G_PlatformGametype " , lib_gPlatformGametype } ,
{ " G_TagGametype " , lib_gTagGametype } ,
2019-12-27 20:08:20 +00:00
{ " G_CompetitionGametype " , lib_gCompetitionGametype } ,
2014-03-15 16:59:03 +00:00
{ " G_TicsToHours " , lib_gTicsToHours } ,
{ " G_TicsToMinutes " , lib_gTicsToMinutes } ,
{ " G_TicsToSeconds " , lib_gTicsToSeconds } ,
{ " G_TicsToCentiseconds " , lib_gTicsToCentiseconds } ,
{ " G_TicsToMilliseconds " , lib_gTicsToMilliseconds } ,
{ NULL , NULL }
} ;
int LUA_BaseLib ( lua_State * L )
{
// Set metatable for string
lua_pushliteral ( L , " " ) ; // dummy string
lua_getmetatable ( L , - 1 ) ; // get string metatable
lua_pushcfunction ( L , lib_concat ) ; // push concatination function
lua_setfield ( L , - 2 , " __add " ) ; // ... store it as mathematical addition
lua_pop ( L , 2 ) ; // pop metatable and dummy string
lua_newtable ( L ) ;
lua_setfield ( L , LUA_REGISTRYINDEX , LREG_EXTVARS ) ;
// Set global functions
lua_pushvalue ( L , LUA_GLOBALSINDEX ) ;
luaL_register ( L , NULL , lib ) ;
return 0 ;
}
# endif