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.
2023-03-31 12:53:31 +00:00
// Copyright (C) 2012-2023 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_maplib.c
/// \brief game map library for Lua scripting
# include "doomdef.h"
# include "r_state.h"
# include "p_local.h"
# include "p_setup.h"
# include "z_zone.h"
2016-03-03 05:47:06 +00:00
# include "p_slopes.h"
2020-09-09 16:31:44 +00:00
# include "p_polyobj.h"
2016-03-03 05:47:06 +00:00
# include "r_main.h"
2014-03-15 16:59:03 +00:00
# include "lua_script.h"
# include "lua_libs.h"
# include "lua_hud.h" // hud_running errors
2020-07-17 05:08:38 +00:00
# include "lua_hook.h" // hook_cmd_running errors
2014-03-15 16:59:03 +00:00
2014-08-04 03:49:33 +00:00
# include "dehacked.h"
# include "fastcmp.h"
# include "doomstat.h"
enum sector_e {
sector_valid = 0 ,
sector_floorheight ,
sector_ceilingheight ,
sector_floorpic ,
2022-11-25 22:27:41 +00:00
sector_floorxoffset ,
sector_flooryoffset ,
2023-11-24 04:52:57 +00:00
sector_floorxscale ,
sector_flooryscale ,
2023-10-27 19:34:53 +00:00
sector_floorangle ,
2014-08-04 03:49:33 +00:00
sector_ceilingpic ,
2022-11-25 22:27:41 +00:00
sector_ceilingxoffset ,
sector_ceilingyoffset ,
2023-11-24 04:52:57 +00:00
sector_ceilingxscale ,
sector_ceilingyscale ,
2022-11-25 22:27:41 +00:00
sector_ceilingangle ,
2014-08-04 03:49:33 +00:00
sector_lightlevel ,
2021-09-19 07:06:39 +00:00
sector_floorlightlevel ,
sector_floorlightabsolute ,
2023-10-27 19:34:53 +00:00
sector_floorlightsec ,
2021-09-19 07:06:39 +00:00
sector_ceilinglightlevel ,
sector_ceilinglightabsolute ,
2022-11-25 23:16:11 +00:00
sector_ceilinglightsec ,
2014-08-04 03:49:33 +00:00
sector_special ,
sector_tag ,
2020-12-04 21:47:22 +00:00
sector_taglist ,
2014-08-04 03:49:33 +00:00
sector_thinglist ,
sector_heightsec ,
sector_camsec ,
2015-06-17 20:00:10 +00:00
sector_lines ,
2016-03-03 05:47:06 +00:00
sector_ffloors ,
sector_fslope ,
2021-12-30 13:16:00 +00:00
sector_cslope ,
2023-11-23 16:39:24 +00:00
sector_colormap ,
2021-12-30 13:16:00 +00:00
sector_flags ,
2021-12-30 23:03:24 +00:00
sector_specialflags ,
2021-12-31 07:53:00 +00:00
sector_damagetype ,
2021-12-31 10:39:34 +00:00
sector_triggertag ,
sector_triggerer ,
2021-12-30 14:32:28 +00:00
sector_friction ,
2021-12-30 17:19:42 +00:00
sector_gravity ,
2014-08-04 03:49:33 +00:00
} ;
2014-03-15 16:59:03 +00:00
static const char * const sector_opt [ ] = {
" valid " ,
" floorheight " ,
" ceilingheight " ,
" floorpic " ,
2022-11-25 22:27:41 +00:00
" floorxoffset " ,
" flooryoffset " ,
2023-11-24 04:52:57 +00:00
" floorxscale " ,
" flooryscale " ,
2022-11-25 22:27:41 +00:00
" floorangle " ,
2014-03-15 16:59:03 +00:00
" ceilingpic " ,
2022-11-25 22:27:41 +00:00
" ceilingxoffset " ,
" ceilingyoffset " ,
2023-11-24 04:52:57 +00:00
" ceilingxscale " ,
" ceilingyscale " ,
2023-10-27 19:34:53 +00:00
" ceilingangle " ,
2014-03-15 16:59:03 +00:00
" lightlevel " ,
2021-09-19 07:06:39 +00:00
" floorlightlevel " ,
" floorlightabsolute " ,
2022-11-25 23:16:11 +00:00
" floorlightsec " ,
2021-09-19 07:06:39 +00:00
" ceilinglightlevel " ,
" ceilinglightabsolute " ,
2023-10-27 19:34:53 +00:00
" ceilinglightsec " ,
2014-03-15 16:59:03 +00:00
" special " ,
" tag " ,
2020-12-04 21:47:22 +00:00
" taglist " ,
2014-08-04 03:49:33 +00:00
" thinglist " ,
" heightsec " ,
" camsec " ,
2015-06-17 20:00:10 +00:00
" lines " ,
2014-08-04 03:49:33 +00:00
" ffloors " ,
2016-03-03 05:47:06 +00:00
" f_slope " ,
" c_slope " ,
2023-11-23 16:39:24 +00:00
" colormap " ,
2021-12-30 13:16:00 +00:00
" flags " ,
2021-12-30 23:03:24 +00:00
" specialflags " ,
2021-12-31 07:53:00 +00:00
" damagetype " ,
2021-12-31 10:39:34 +00:00
" triggertag " ,
" triggerer " ,
2021-12-30 14:32:28 +00:00
" friction " ,
2021-12-30 17:19:42 +00:00
" gravity " ,
2014-03-15 16:59:03 +00:00
NULL } ;
2023-06-18 16:05:16 +00:00
static int sector_fields_ref = LUA_NOREF ;
2014-08-04 03:49:33 +00:00
enum subsector_e {
subsector_valid = 0 ,
subsector_sector ,
subsector_numlines ,
subsector_firstline ,
2020-09-09 16:31:44 +00:00
subsector_polyList
2014-08-04 03:49:33 +00:00
} ;
2014-03-15 16:59:03 +00:00
static const char * const subsector_opt [ ] = {
" valid " ,
" sector " ,
" numlines " ,
" firstline " ,
2020-09-09 16:31:44 +00:00
" polyList " ,
2014-03-15 16:59:03 +00:00
NULL } ;
2023-06-18 16:05:16 +00:00
static int subsector_fields_ref = LUA_NOREF ;
2014-08-04 03:49:33 +00:00
enum line_e {
line_valid = 0 ,
line_v1 ,
line_v2 ,
line_dx ,
line_dy ,
2021-08-24 08:13:18 +00:00
line_angle ,
2014-08-04 03:49:33 +00:00
line_flags ,
line_special ,
line_tag ,
2020-12-04 21:47:22 +00:00
line_taglist ,
2020-01-02 11:23:14 +00:00
line_args ,
2020-01-08 07:42:35 +00:00
line_stringargs ,
2014-08-04 03:49:33 +00:00
line_sidenum ,
line_frontside ,
line_backside ,
2020-01-26 11:24:52 +00:00
line_alpha ,
2020-05-03 18:41:37 +00:00
line_executordelay ,
2014-08-04 03:49:33 +00:00
line_slopetype ,
line_frontsector ,
line_backsector ,
2020-09-09 16:31:44 +00:00
line_polyobj ,
2014-11-12 00:55:07 +00:00
line_text ,
line_callcount
2014-08-04 03:49:33 +00:00
} ;
2014-03-15 16:59:03 +00:00
static const char * const line_opt [ ] = {
" valid " ,
" v1 " ,
" v2 " ,
" dx " ,
" dy " ,
2021-08-24 08:13:18 +00:00
" angle " ,
2014-03-15 16:59:03 +00:00
" flags " ,
" special " ,
" tag " ,
2020-12-04 21:47:22 +00:00
" taglist " ,
2020-01-02 11:23:14 +00:00
" args " ,
2020-01-08 07:42:35 +00:00
" stringargs " ,
2014-03-15 16:59:03 +00:00
" sidenum " ,
" frontside " ,
" backside " ,
2020-01-26 11:24:52 +00:00
" alpha " ,
2020-05-03 18:41:37 +00:00
" executordelay " ,
2014-03-15 16:59:03 +00:00
" slopetype " ,
" frontsector " ,
" backsector " ,
2020-09-09 16:31:44 +00:00
" polyobj " ,
2014-03-15 16:59:03 +00:00
" text " ,
2014-11-12 00:55:07 +00:00
" callcount " ,
2014-03-15 16:59:03 +00:00
NULL } ;
2023-06-18 16:05:16 +00:00
static int line_fields_ref = LUA_NOREF ;
2014-08-04 03:49:33 +00:00
enum side_e {
side_valid = 0 ,
side_textureoffset ,
side_rowoffset ,
2023-06-11 17:55:43 +00:00
side_offsetx_top ,
side_offsety_top ,
side_offsetx_mid ,
side_offsety_mid ,
2023-11-24 16:54:09 +00:00
side_offsetx_bottom ,
2023-06-11 17:55:43 +00:00
side_offsetx_bot ,
2023-11-24 16:54:09 +00:00
side_offsety_bottom ,
2023-06-11 17:55:43 +00:00
side_offsety_bot ,
2023-06-23 21:32:58 +00:00
side_scalex_top ,
side_scaley_top ,
side_scalex_mid ,
side_scaley_mid ,
2023-11-24 16:54:09 +00:00
side_scalex_bottom ,
side_scaley_bottom ,
2014-08-04 03:49:33 +00:00
side_toptexture ,
side_bottomtexture ,
side_midtexture ,
2019-12-29 08:39:50 +00:00
side_line ,
2014-08-04 03:49:33 +00:00
side_sector ,
side_special ,
side_repeatcnt ,
side_text
} ;
2014-03-15 16:59:03 +00:00
static const char * const side_opt [ ] = {
" valid " ,
" textureoffset " ,
" rowoffset " ,
2023-06-11 17:55:43 +00:00
" offsetx_top " ,
" offsety_top " ,
" offsetx_mid " ,
" offsety_mid " ,
2023-11-24 16:54:09 +00:00
" offsetx_bottom " ,
2023-06-11 17:55:43 +00:00
" offsetx_bot " ,
2023-11-24 16:54:09 +00:00
" offsety_bottom " ,
2023-06-11 17:55:43 +00:00
" offsety_bot " ,
2023-06-23 21:32:58 +00:00
" scalex_top " ,
" scaley_top " ,
" scalex_mid " ,
" scaley_mid " ,
2023-11-24 16:54:09 +00:00
" scalex_bottom " ,
" scaley_bottom " ,
2014-03-15 16:59:03 +00:00
" toptexture " ,
" bottomtexture " ,
" midtexture " ,
2020-06-22 19:11:33 +00:00
" line " ,
2014-03-15 16:59:03 +00:00
" sector " ,
" special " ,
" repeatcnt " ,
" text " ,
NULL } ;
2023-06-18 16:05:16 +00:00
static int side_fields_ref = LUA_NOREF ;
2014-08-04 03:49:33 +00:00
enum vertex_e {
vertex_valid = 0 ,
vertex_x ,
vertex_y ,
2020-01-04 10:38:23 +00:00
vertex_floorz ,
vertex_floorzset ,
vertex_ceilingz ,
vertex_ceilingzset
2014-08-04 03:49:33 +00:00
} ;
2014-03-15 16:59:03 +00:00
static const char * const vertex_opt [ ] = {
" valid " ,
" x " ,
" y " ,
2020-01-04 10:38:23 +00:00
" floorz " ,
" floorzset " ,
" ceilingz " ,
" ceilingzset " ,
2014-03-15 16:59:03 +00:00
NULL } ;
2023-06-18 16:05:16 +00:00
static int vertex_fields_ref = LUA_NOREF ;
2014-08-04 03:49:33 +00:00
enum ffloor_e {
ffloor_valid = 0 ,
ffloor_topheight ,
ffloor_toppic ,
ffloor_toplightlevel ,
2023-11-24 11:47:59 +00:00
ffloor_topxoffs ,
ffloor_topyoffs ,
ffloor_topxscale ,
ffloor_topyscale ,
2014-08-04 03:49:33 +00:00
ffloor_bottomheight ,
ffloor_bottompic ,
2023-11-24 11:47:59 +00:00
ffloor_bottomxoffs ,
ffloor_bottomyoffs ,
ffloor_bottomxscale ,
ffloor_bottomyscale ,
2016-03-03 05:47:06 +00:00
ffloor_tslope ,
ffloor_bslope ,
2014-08-04 03:49:33 +00:00
ffloor_sector ,
2022-07-31 10:04:42 +00:00
ffloor_fofflags ,
2014-08-04 03:49:33 +00:00
ffloor_flags ,
ffloor_master ,
ffloor_target ,
ffloor_next ,
ffloor_prev ,
ffloor_alpha ,
2021-11-19 18:01:41 +00:00
ffloor_blend ,
2021-12-03 17:48:16 +00:00
ffloor_bustflags ,
2020-05-02 19:19:55 +00:00
ffloor_busttype ,
ffloor_busttag ,
2020-05-02 20:07:42 +00:00
ffloor_sinkspeed ,
ffloor_friction ,
2020-05-03 10:44:30 +00:00
ffloor_bouncestrength ,
2014-08-04 03:49:33 +00:00
} ;
static const char * const ffloor_opt [ ] = {
" valid " ,
" topheight " ,
" toppic " ,
" toplightlevel " ,
2023-11-24 11:47:59 +00:00
" topxoffs " ,
" topyoffs " ,
" topxscale " ,
" topyscale " ,
2014-08-04 03:49:33 +00:00
" bottomheight " ,
" bottompic " ,
2023-11-24 11:47:59 +00:00
" bottomxoffs " ,
" bottomyoffs " ,
" bottomxscale " ,
" bottomyscale " ,
2016-03-03 05:47:06 +00:00
" t_slope " ,
" b_slope " ,
2014-08-04 03:49:33 +00:00
" sector " , // secnum pushed as control sector userdata
2022-07-31 11:01:45 +00:00
" fofflags " ,
2014-08-04 03:49:33 +00:00
" flags " ,
" master " , // control linedef
" target " , // target sector
" next " ,
" prev " ,
" alpha " ,
2021-11-19 18:01:41 +00:00
" blend " ,
2021-12-03 17:48:16 +00:00
" bustflags " ,
2020-05-02 19:19:55 +00:00
" busttype " ,
" busttag " ,
2020-05-02 20:07:42 +00:00
" sinkspeed " ,
" friction " ,
2020-05-03 10:44:30 +00:00
" bouncestrength " ,
2014-08-04 03:49:33 +00:00
NULL } ;
2023-06-18 16:05:16 +00:00
static int ffloor_fields_ref = LUA_NOREF ;
2016-11-24 21:11:44 +00:00
# ifdef HAVE_LUA_SEGS
2016-05-25 16:15:44 +00:00
enum seg_e {
seg_valid = 0 ,
seg_v1 ,
seg_v2 ,
seg_side ,
seg_offset ,
seg_angle ,
seg_sidedef ,
seg_linedef ,
seg_frontsector ,
seg_backsector ,
2020-09-09 16:31:44 +00:00
seg_polyseg
2016-05-25 16:15:44 +00:00
} ;
static const char * const seg_opt [ ] = {
" valid " ,
" v1 " ,
" v2 " ,
" side " ,
" offset " ,
" angle " ,
" sidedef " ,
" linedef " ,
" frontsector " ,
" backsector " ,
2020-09-09 16:31:44 +00:00
" polyseg " ,
2016-05-25 16:15:44 +00:00
NULL } ;
2023-06-18 16:05:16 +00:00
static int seg_fields_ref = LUA_NOREF ;
2016-07-08 19:05:54 +00:00
enum node_e {
node_valid = 0 ,
node_x ,
node_y ,
node_dx ,
node_dy ,
node_bbox ,
node_children ,
} ;
static const char * const node_opt [ ] = {
" valid " ,
" x " ,
" y " ,
" dx " ,
" dy " ,
" bbox " ,
" children " ,
NULL } ;
2023-06-18 16:05:16 +00:00
static int node_fields_ref = LUA_NOREF ;
2016-08-04 17:54:29 +00:00
enum nodechild_e {
nodechild_valid = 0 ,
nodechild_right ,
nodechild_left ,
} ;
static const char * const nodechild_opt [ ] = {
" valid " ,
" right " ,
" left " ,
NULL } ;
2016-11-24 21:11:44 +00:00
# endif
2016-08-04 17:54:29 +00:00
enum bbox_e {
bbox_valid = 0 ,
bbox_top ,
bbox_bottom ,
bbox_left ,
bbox_right ,
} ;
static const char * const bbox_opt [ ] = {
" valid " ,
" top " ,
" bottom " ,
" left " ,
" right " ,
NULL } ;
2016-03-03 05:47:06 +00:00
enum slope_e {
slope_valid = 0 ,
slope_o ,
slope_d ,
slope_zdelta ,
slope_normal ,
slope_zangle ,
slope_xydirection ,
slope_flags
} ;
static const char * const slope_opt [ ] = {
" valid " ,
" o " ,
" d " ,
" zdelta " ,
" normal " ,
" zangle " ,
" xydirection " ,
" flags " ,
NULL } ;
2023-06-18 16:05:16 +00:00
static int slope_fields_ref = LUA_NOREF ;
2018-10-20 18:00:37 +00:00
// shared by both vector2_t and vector3_t
enum vector_e {
vector_x = 0 ,
vector_y ,
vector_z
} ;
static const char * const vector_opt [ ] = {
" x " ,
" y " ,
" z " ,
NULL } ;
2014-03-15 16:59:03 +00:00
static const char * const array_opt [ ] = { " iterate " , NULL } ;
static const char * const valid_opt [ ] = { " valid " , NULL } ;
2020-09-09 16:31:44 +00:00
/////////////////////////////////////////////
// sector/subsector list iterate functions //
/////////////////////////////////////////////
2017-01-18 22:02:28 +00:00
2014-08-04 03:49:33 +00:00
// iterates through a sector's thinglist!
static int lib_iterateSectorThinglist ( lua_State * L )
{
mobj_t * state = NULL ;
mobj_t * thing = NULL ;
2019-07-30 16:48:13 +00:00
INLEVEL
2017-01-18 22:02:28 +00:00
2014-08-04 03:49:33 +00:00
if ( lua_gettop ( L ) < 2 )
return luaL_error ( L , " Don't call sector.thinglist() directly , use it as ' for rover in sector . thinglist do < block > end ' . " ) ;
if ( ! lua_isnil ( L , 1 ) )
state = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
else
return 0 ; // no thinglist to iterate through sorry!
lua_settop ( L , 2 ) ;
lua_remove ( L , 1 ) ; // remove state now.
if ( ! lua_isnil ( L , 1 ) )
{
thing = * ( ( mobj_t * * ) luaL_checkudata ( L , 1 , META_MOBJ ) ) ;
2024-02-07 17:42:24 +00:00
if ( P_MobjWasRemoved ( thing ) )
2024-02-07 20:30:20 +00:00
return luaL_error ( L , " current entry in thinglist was removed; avoid calling P_RemoveMobj on entries! " ) ;
2014-08-04 03:49:33 +00:00
thing = thing - > snext ;
}
else
thing = state ; // state is used as the "start" of the thinglist
if ( thing )
{
LUA_PushUserdata ( L , thing , META_MOBJ ) ;
return 1 ;
}
return 0 ;
}
// iterates through the ffloors list in a sector!
static int lib_iterateSectorFFloors ( lua_State * L )
{
ffloor_t * state = NULL ;
ffloor_t * ffloor = NULL ;
2019-07-30 16:48:13 +00:00
INLEVEL
2017-01-18 22:02:28 +00:00
2014-08-04 03:49:33 +00:00
if ( lua_gettop ( L ) < 2 )
return luaL_error ( L , " Don't call sector.ffloors() directly , use it as ' for rover in sector . ffloors do < block > end ' . " ) ;
if ( ! lua_isnil ( L , 1 ) )
state = * ( ( ffloor_t * * ) luaL_checkudata ( L , 1 , META_FFLOOR ) ) ;
else
return 0 ; // no ffloors to iterate through sorry!
lua_settop ( L , 2 ) ;
lua_remove ( L , 1 ) ; // remove state now.
if ( ! lua_isnil ( L , 1 ) )
{
ffloor = * ( ( ffloor_t * * ) luaL_checkudata ( L , 1 , META_FFLOOR ) ) ;
ffloor = ffloor - > next ;
}
else
ffloor = state ; // state is used as the "start" of the ffloor list
if ( ffloor )
{
LUA_PushUserdata ( L , ffloor , META_FFLOOR ) ;
return 1 ;
}
return 0 ;
}
2020-09-09 16:31:44 +00:00
// iterates through a subsector's polyList! (for polyobj_t)
static int lib_iterateSubSectorPolylist ( lua_State * L )
{
polyobj_t * state = NULL ;
polyobj_t * po = NULL ;
INLEVEL
if ( lua_gettop ( L ) < 2 )
return luaL_error ( L , " Don't call subsector.polyList() directly , use it as ' for polyobj in subsector . polyList do < block > end ' . " ) ;
if ( ! lua_isnil ( L , 1 ) )
state = * ( ( polyobj_t * * ) luaL_checkudata ( L , 1 , META_POLYOBJ ) ) ;
else
return 0 ; // no polylist to iterate through sorry!
lua_settop ( L , 2 ) ;
lua_remove ( L , 1 ) ; // remove state now.
if ( ! lua_isnil ( L , 1 ) )
{
po = * ( ( polyobj_t * * ) luaL_checkudata ( L , 1 , META_POLYOBJ ) ) ;
po = ( polyobj_t * ) ( po - > link . next ) ;
}
else
po = state ; // state is used as the "start" of the polylist
if ( po )
{
LUA_PushUserdata ( L , po , META_POLYOBJ ) ;
return 1 ;
}
return 0 ;
}
2014-08-04 03:49:33 +00:00
static int sector_iterate ( lua_State * L )
{
lua_pushvalue ( L , lua_upvalueindex ( 1 ) ) ; // iterator function, or the "generator"
lua_pushvalue ( L , lua_upvalueindex ( 2 ) ) ; // state (used as the "start" of the list for our purposes
lua_pushnil ( L ) ; // initial value (unused)
return 3 ;
}
2017-01-18 22:02:28 +00:00
////////////////////
// sector.lines[] //
////////////////////
2015-06-17 20:00:10 +00:00
// sector.lines, i -> sector.lines[i]
// sector.lines.valid, for validity checking
2019-09-25 19:27:41 +00:00
//
// 25/9/19 Monster Iestyn
// Modified this and _num to use triple pointers, to allow for a new hack of mine involving offsetof
// this way we don't need to check frontsector or backsector of line #0 in the array
//
2015-06-17 20:00:10 +00:00
static int sectorlines_get ( lua_State * L )
{
2019-09-25 19:27:41 +00:00
line_t * * * seclines = * ( ( line_t * * * * ) luaL_checkudata ( L , 1 , META_SECTORLINES ) ) ;
2015-06-17 20:00:10 +00:00
size_t i ;
2016-01-20 14:56:52 +00:00
size_t numoflines = 0 ;
2015-06-17 20:00:10 +00:00
lua_settop ( L , 2 ) ;
if ( ! lua_isnumber ( L , 2 ) )
{
int field = luaL_checkoption ( L , 2 , NULL , valid_opt ) ;
2019-09-25 19:27:41 +00:00
if ( ! seclines | | ! ( * seclines ) )
2015-06-17 20:00:10 +00:00
{
if ( field = = 0 ) {
lua_pushboolean ( L , 0 ) ;
return 1 ;
}
2019-09-25 19:27:41 +00:00
return luaL_error ( L , " accessed sector_t.lines doesn't exist anymore. " ) ;
2015-06-17 20:00:10 +00:00
} else if ( field = = 0 ) {
lua_pushboolean ( L , 1 ) ;
return 1 ;
}
}
2019-09-25 19:27:41 +00:00
/* a snip from sector_t struct in r_defs.h, for reference
size_t linecount ;
struct line_s * * lines ; // [linecount] size
*/
// get the "linecount" by shifting our retrieved memory address of "lines" to where "linecount" is in the sector_t, then dereferencing the result
// we need this to determine the array's actual size, and therefore also the maximum value allowed as an index
// this only works if seclines is actually a pointer to a sector's lines member in memory, oh boy
2020-10-10 23:43:09 +00:00
numoflines = * ( size_t * ) FIELDFROM ( sector_t , seclines , lines , /* -> */ linecount ) ;
2019-09-25 19:27:41 +00:00
/* OLD HACK
2016-01-20 14:56:52 +00:00
// check first linedef to figure which of its sectors owns this sector->lines pointer
// then check that sector's linecount to get a maximum index
2019-09-25 19:27:41 +00:00
//if (!(*seclines)[0])
2016-01-20 14:56:52 +00:00
//return luaL_error(L, "no lines found!"); // no first linedef?????
2019-09-25 19:27:41 +00:00
if ( ( * seclines ) [ 0 ] - > frontsector - > lines = = * seclines )
numoflines = ( * seclines ) [ 0 ] - > frontsector - > linecount ;
else if ( ( * seclines ) [ 0 ] - > backsector & & * seclines [ 0 ] - > backsector - > lines = = * seclines ) // check backsector exists first
numoflines = ( * seclines ) [ 0 ] - > backsector - > linecount ;
2016-01-20 14:56:52 +00:00
//if neither sector has it then ???
2019-09-25 19:27:41 +00:00
*/
2015-06-17 20:00:10 +00:00
if ( ! numoflines )
2016-01-20 14:56:52 +00:00
return luaL_error ( L , " no lines found! " ) ;
2015-06-17 20:00:10 +00:00
i = ( size_t ) lua_tointeger ( L , 2 ) ;
2016-01-20 14:56:52 +00:00
if ( i > = numoflines )
return 0 ;
2019-09-25 19:27:41 +00:00
LUA_PushUserdata ( L , ( * seclines ) [ i ] , META_LINE ) ;
2015-06-17 20:00:10 +00:00
return 1 ;
}
2019-09-25 19:27:41 +00:00
// #(sector.lines) -> sector.linecount
2016-01-20 16:03:17 +00:00
static int sectorlines_num ( lua_State * L )
{
2019-09-25 19:27:41 +00:00
line_t * * * seclines = * ( ( line_t * * * * ) luaL_checkudata ( L , 1 , META_SECTORLINES ) ) ;
2016-01-20 16:03:17 +00:00
size_t numoflines = 0 ;
2019-09-25 19:27:41 +00:00
if ( ! seclines | | ! ( * seclines ) )
return luaL_error ( L , " accessed sector_t.lines doesn't exist anymore. " ) ;
// see comments in the _get function above
2020-10-11 00:40:01 +00:00
numoflines = * ( size_t * ) FIELDFROM ( sector_t , seclines , lines , /* -> */ linecount ) ;
2016-01-20 16:03:17 +00:00
lua_pushinteger ( L , numoflines ) ;
return 1 ;
}
2017-01-18 22:02:28 +00:00
//////////////
// sector_t //
//////////////
2014-03-15 16:59:03 +00:00
static int sector_get ( lua_State * L )
{
sector_t * sector = * ( ( sector_t * * ) luaL_checkudata ( L , 1 , META_SECTOR ) ) ;
2023-06-18 16:05:16 +00:00
enum sector_e field = Lua_optoption ( L , 2 , sector_valid , sector_fields_ref ) ;
2018-08-06 21:37:44 +00:00
INT16 i ;
2014-03-15 16:59:03 +00:00
if ( ! sector )
{
2014-08-04 03:49:33 +00:00
if ( field = = sector_valid ) {
2014-03-15 16:59:03 +00:00
lua_pushboolean ( L , 0 ) ;
return 1 ;
}
return luaL_error ( L , " accessed sector_t doesn't exist anymore. " ) ;
}
switch ( field )
{
2014-08-04 03:49:33 +00:00
case sector_valid : // valid
2014-03-15 16:59:03 +00:00
lua_pushboolean ( L , 1 ) ;
return 1 ;
2014-08-04 03:49:33 +00:00
case sector_floorheight :
2015-05-21 03:54:04 +00:00
lua_pushfixed ( L , sector - > floorheight ) ;
2014-03-15 16:59:03 +00:00
return 1 ;
2014-08-04 03:49:33 +00:00
case sector_ceilingheight :
2015-05-21 03:54:04 +00:00
lua_pushfixed ( L , sector - > ceilingheight ) ;
2014-03-15 16:59:03 +00:00
return 1 ;
2016-12-09 21:18:06 +00:00
case sector_floorpic : // floorpic
2018-08-06 21:37:44 +00:00
{
levelflat_t * levelflat = & levelflats [ sector - > floorpic ] ;
for ( i = 0 ; i < 8 ; i + + )
if ( ! levelflat - > name [ i ] )
break ;
lua_pushlstring ( L , levelflat - > name , i ) ;
2014-03-15 16:59:03 +00:00
return 1 ;
2018-08-06 21:37:44 +00:00
}
2022-11-25 22:27:41 +00:00
case sector_floorxoffset :
2022-11-25 23:01:27 +00:00
lua_pushfixed ( L , sector - > floorxoffset ) ;
2022-11-23 17:09:54 +00:00
return 1 ;
2022-11-25 22:27:41 +00:00
case sector_flooryoffset :
2022-11-25 23:01:27 +00:00
lua_pushfixed ( L , sector - > flooryoffset ) ;
2022-11-23 17:09:54 +00:00
return 1 ;
2023-11-24 04:52:57 +00:00
case sector_floorxscale :
lua_pushfixed ( L , sector - > floorxscale ) ;
return 1 ;
case sector_flooryscale :
lua_pushfixed ( L , sector - > flooryscale ) ;
return 1 ;
2023-10-27 19:34:53 +00:00
case sector_floorangle :
2022-11-25 23:01:27 +00:00
lua_pushangle ( L , sector - > floorangle ) ;
2022-11-23 17:09:54 +00:00
return 1 ;
2016-12-09 21:18:06 +00:00
case sector_ceilingpic : // ceilingpic
2018-08-06 21:37:44 +00:00
{
levelflat_t * levelflat = & levelflats [ sector - > ceilingpic ] ;
for ( i = 0 ; i < 8 ; i + + )
if ( ! levelflat - > name [ i ] )
break ;
lua_pushlstring ( L , levelflat - > name , i ) ;
2014-03-15 16:59:03 +00:00
return 1 ;
2018-08-06 21:37:44 +00:00
}
2022-11-25 22:27:41 +00:00
case sector_ceilingxoffset :
2022-11-25 23:01:27 +00:00
lua_pushfixed ( L , sector - > ceilingxoffset ) ;
2022-11-23 17:09:54 +00:00
return 1 ;
2022-11-25 22:27:41 +00:00
case sector_ceilingyoffset :
2022-11-25 23:01:27 +00:00
lua_pushfixed ( L , sector - > ceilingyoffset ) ;
2022-11-23 17:09:54 +00:00
return 1 ;
2023-11-24 04:52:57 +00:00
case sector_ceilingxscale :
lua_pushfixed ( L , sector - > ceilingxscale ) ;
return 1 ;
case sector_ceilingyscale :
lua_pushfixed ( L , sector - > ceilingyscale ) ;
return 1 ;
2022-11-25 22:27:41 +00:00
case sector_ceilingangle :
2022-11-25 23:01:27 +00:00
lua_pushangle ( L , sector - > ceilingangle ) ;
2022-11-23 17:09:54 +00:00
return 1 ;
2014-08-04 03:49:33 +00:00
case sector_lightlevel :
2014-03-15 16:59:03 +00:00
lua_pushinteger ( L , sector - > lightlevel ) ;
return 1 ;
2021-09-19 07:06:39 +00:00
case sector_floorlightlevel :
lua_pushinteger ( L , sector - > floorlightlevel ) ;
return 1 ;
case sector_floorlightabsolute :
lua_pushboolean ( L , sector - > floorlightabsolute ) ;
return 1 ;
2022-11-25 23:16:11 +00:00
case sector_floorlightsec :
lua_pushinteger ( L , sector - > floorlightsec ) ;
2023-10-27 19:34:53 +00:00
return 1 ;
2021-09-19 07:06:39 +00:00
case sector_ceilinglightlevel :
lua_pushinteger ( L , sector - > ceilinglightlevel ) ;
return 1 ;
case sector_ceilinglightabsolute :
lua_pushboolean ( L , sector - > ceilinglightabsolute ) ;
return 1 ;
2022-11-25 23:16:11 +00:00
case sector_ceilinglightsec :
lua_pushinteger ( L , sector - > ceilinglightsec ) ;
2023-10-27 19:34:53 +00:00
return 1 ;
2014-08-04 03:49:33 +00:00
case sector_special :
2014-03-15 16:59:03 +00:00
lua_pushinteger ( L , sector - > special ) ;
return 1 ;
2014-08-04 03:49:33 +00:00
case sector_tag :
2021-02-25 22:41:43 +00:00
lua_pushinteger ( L , ( UINT16 ) Tag_FGet ( & sector - > tags ) ) ;
2014-03-15 16:59:03 +00:00
return 1 ;
2020-12-04 21:47:22 +00:00
case sector_taglist :
LUA_PushUserdata ( L , & sector - > tags , META_SECTORTAGLIST ) ;
2014-03-15 16:59:03 +00:00
return 1 ;
2014-08-04 03:49:33 +00:00
case sector_thinglist : // thinglist
lua_pushcfunction ( L , lib_iterateSectorThinglist ) ;
LUA_PushUserdata ( L , sector - > thinglist , META_MOBJ ) ;
lua_pushcclosure ( L , sector_iterate , 2 ) ; // push lib_iterateSectorThinglist and sector->thinglist as upvalues for the function
return 1 ;
case sector_heightsec : // heightsec - fake floor heights
if ( sector - > heightsec < 0 )
return 0 ;
LUA_PushUserdata ( L , & sectors [ sector - > heightsec ] , META_SECTOR ) ;
return 1 ;
case sector_camsec : // camsec - camera clipping heights
if ( sector - > camsec < 0 )
return 0 ;
LUA_PushUserdata ( L , & sectors [ sector - > camsec ] , META_SECTOR ) ;
return 1 ;
2015-06-17 20:00:10 +00:00
case sector_lines : // lines
2019-09-25 19:27:41 +00:00
LUA_PushUserdata ( L , & sector - > lines , META_SECTORLINES ) ; // push the address of the "lines" member in the struct, to allow our hacks in sectorlines_get/_num to work
2015-06-17 20:00:10 +00:00
return 1 ;
2014-08-04 03:49:33 +00:00
case sector_ffloors : // ffloors
lua_pushcfunction ( L , lib_iterateSectorFFloors ) ;
LUA_PushUserdata ( L , sector - > ffloors , META_FFLOOR ) ;
lua_pushcclosure ( L , sector_iterate , 2 ) ; // push lib_iterateFFloors and sector->ffloors as upvalues for the function
return 1 ;
2016-03-03 05:47:06 +00:00
case sector_fslope : // f_slope
LUA_PushUserdata ( L , sector - > f_slope , META_SLOPE ) ;
return 1 ;
case sector_cslope : // c_slope
LUA_PushUserdata ( L , sector - > c_slope , META_SLOPE ) ;
return 1 ;
2023-11-23 16:39:24 +00:00
case sector_colormap : // extra_colormap
2023-08-04 03:31:51 +00:00
LUA_PushUserdata ( L , sector - > extra_colormap , META_EXTRACOLORMAP ) ;
return 1 ;
2021-12-30 13:16:00 +00:00
case sector_flags : // flags
lua_pushinteger ( L , sector - > flags ) ;
return 1 ;
2021-12-30 23:03:24 +00:00
case sector_specialflags : // specialflags
lua_pushinteger ( L , sector - > specialflags ) ;
return 1 ;
2021-12-31 07:53:00 +00:00
case sector_damagetype : // damagetype
lua_pushinteger ( L , ( UINT8 ) sector - > damagetype ) ;
return 1 ;
2021-12-31 10:39:34 +00:00
case sector_triggertag : // triggertag
lua_pushinteger ( L , ( INT16 ) sector - > triggertag ) ;
return 1 ;
case sector_triggerer : // triggerer
lua_pushinteger ( L , ( UINT8 ) sector - > triggerer ) ;
return 1 ;
2021-12-30 14:32:28 +00:00
case sector_friction : // friction
2022-01-04 20:25:34 +00:00
lua_pushfixed ( L , sector - > friction ) ;
2021-12-30 14:32:28 +00:00
return 1 ;
2021-12-30 17:19:42 +00:00
case sector_gravity : // gravity
lua_pushfixed ( L , sector - > gravity ) ;
return 1 ;
2014-03-15 16:59:03 +00:00
}
return 0 ;
}
static int sector_set ( lua_State * L )
{
sector_t * sector = * ( ( sector_t * * ) luaL_checkudata ( L , 1 , META_SECTOR ) ) ;
2023-06-18 16:05:16 +00:00
enum sector_e field = Lua_optoption ( L , 2 , sector_valid , sector_fields_ref ) ;
2014-03-15 16:59:03 +00:00
if ( ! sector )
return luaL_error ( L , " accessed sector_t doesn't exist anymore. " ) ;
if ( hud_running )
return luaL_error ( L , " Do not alter sector_t in HUD rendering code! " ) ;
2020-07-17 05:08:38 +00:00
if ( hook_cmd_running )
return luaL_error ( L , " Do not alter sector_t in CMD building code! " ) ;
2014-03-15 16:59:03 +00:00
switch ( field )
{
2014-08-04 03:49:33 +00:00
case sector_valid : // valid
case sector_thinglist : // thinglist
case sector_heightsec : // heightsec
case sector_camsec : // camsec
2019-09-25 19:27:41 +00:00
case sector_lines : // lines
2014-08-04 03:49:33 +00:00
case sector_ffloors : // ffloors
2016-03-03 05:47:06 +00:00
case sector_fslope : // f_slope
case sector_cslope : // c_slope
2021-12-30 14:32:28 +00:00
case sector_friction : // friction
2014-03-15 16:59:03 +00:00
return luaL_error ( L , " sector_t field " LUA_QS " cannot be set. " , sector_opt [ field ] ) ;
2023-08-31 18:02:59 +00:00
default :
return luaL_error ( L , " sector_t has no field named " LUA_QS " . " , lua_tostring ( L , 2 ) ) ;
2014-08-04 03:49:33 +00:00
case sector_floorheight : { // floorheight
2014-03-15 16:59:03 +00:00
boolean flag ;
2015-05-22 05:51:40 +00:00
mobj_t * ptmthing = tmthing ;
2014-03-15 16:59:03 +00:00
fixed_t lastpos = sector - > floorheight ;
2015-05-21 03:54:04 +00:00
sector - > floorheight = luaL_checkfixed ( L , 3 ) ;
2014-03-15 16:59:03 +00:00
flag = P_CheckSector ( sector , true ) ;
if ( flag & & sector - > numattached )
{
sector - > floorheight = lastpos ;
P_CheckSector ( sector , true ) ;
}
2015-05-22 05:51:40 +00:00
P_SetTarget ( & tmthing , ptmthing ) ;
2014-03-15 16:59:03 +00:00
break ;
}
2014-08-04 03:49:33 +00:00
case sector_ceilingheight : { // ceilingheight
2014-03-15 16:59:03 +00:00
boolean flag ;
2015-05-22 05:51:40 +00:00
mobj_t * ptmthing = tmthing ;
2014-03-15 16:59:03 +00:00
fixed_t lastpos = sector - > ceilingheight ;
2015-05-21 03:54:04 +00:00
sector - > ceilingheight = luaL_checkfixed ( L , 3 ) ;
2014-03-15 16:59:03 +00:00
flag = P_CheckSector ( sector , true ) ;
if ( flag & & sector - > numattached )
{
sector - > ceilingheight = lastpos ;
P_CheckSector ( sector , true ) ;
}
2015-05-22 05:51:40 +00:00
P_SetTarget ( & tmthing , ptmthing ) ;
2014-03-15 16:59:03 +00:00
break ;
}
2014-08-04 03:49:33 +00:00
case sector_floorpic :
2014-03-15 16:59:03 +00:00
sector - > floorpic = P_AddLevelFlatRuntime ( luaL_checkstring ( L , 3 ) ) ;
break ;
2022-11-25 22:27:41 +00:00
case sector_floorxoffset :
2022-11-25 23:01:27 +00:00
sector - > floorxoffset = luaL_checkfixed ( L , 3 ) ;
2022-11-23 17:09:54 +00:00
break ;
2022-11-25 22:27:41 +00:00
case sector_flooryoffset :
2022-11-25 23:01:27 +00:00
sector - > flooryoffset = luaL_checkfixed ( L , 3 ) ;
2022-11-23 17:09:54 +00:00
break ;
2023-11-24 04:52:57 +00:00
case sector_floorxscale :
sector - > floorxscale = luaL_checkfixed ( L , 3 ) ;
break ;
case sector_flooryscale :
sector - > flooryscale = luaL_checkfixed ( L , 3 ) ;
break ;
2022-11-25 22:27:41 +00:00
case sector_floorangle :
2022-11-25 23:01:27 +00:00
sector - > floorangle = luaL_checkangle ( L , 3 ) ;
2023-10-27 19:34:53 +00:00
break ;
2014-08-04 03:49:33 +00:00
case sector_ceilingpic :
2014-03-15 16:59:03 +00:00
sector - > ceilingpic = P_AddLevelFlatRuntime ( luaL_checkstring ( L , 3 ) ) ;
break ;
2022-11-25 22:27:41 +00:00
case sector_ceilingxoffset :
2022-11-25 23:01:27 +00:00
sector - > ceilingxoffset = luaL_checkfixed ( L , 3 ) ;
2022-11-23 17:09:54 +00:00
break ;
2022-11-25 22:27:41 +00:00
case sector_ceilingyoffset :
2022-11-25 23:01:27 +00:00
sector - > ceilingyoffset = luaL_checkfixed ( L , 3 ) ;
2022-11-23 17:09:54 +00:00
break ;
2023-11-24 04:52:57 +00:00
case sector_ceilingxscale :
sector - > ceilingxscale = luaL_checkfixed ( L , 3 ) ;
break ;
case sector_ceilingyscale :
sector - > ceilingyscale = luaL_checkfixed ( L , 3 ) ;
break ;
2022-11-25 22:27:41 +00:00
case sector_ceilingangle :
2022-11-25 23:01:27 +00:00
sector - > ceilingangle = luaL_checkangle ( L , 3 ) ;
2022-11-23 17:09:54 +00:00
break ;
2014-08-04 03:49:33 +00:00
case sector_lightlevel :
2014-03-15 16:59:03 +00:00
sector - > lightlevel = ( INT16 ) luaL_checkinteger ( L , 3 ) ;
break ;
2021-09-19 07:06:39 +00:00
case sector_floorlightlevel :
sector - > floorlightlevel = ( INT16 ) luaL_checkinteger ( L , 3 ) ;
break ;
case sector_floorlightabsolute :
sector - > floorlightabsolute = luaL_checkboolean ( L , 3 ) ;
break ;
2022-11-25 23:16:11 +00:00
case sector_floorlightsec :
sector - > floorlightsec = ( INT32 ) luaL_checkinteger ( L , 3 ) ;
2023-10-27 19:34:53 +00:00
break ;
2021-09-19 07:06:39 +00:00
case sector_ceilinglightlevel :
sector - > ceilinglightlevel = ( INT16 ) luaL_checkinteger ( L , 3 ) ;
break ;
case sector_ceilinglightabsolute :
sector - > ceilinglightabsolute = luaL_checkboolean ( L , 3 ) ;
break ;
2022-11-25 23:16:11 +00:00
case sector_ceilinglightsec :
sector - > ceilinglightsec = ( INT32 ) luaL_checkinteger ( L , 3 ) ;
2023-10-27 19:34:53 +00:00
break ;
2014-08-04 03:49:33 +00:00
case sector_special :
2014-03-15 16:59:03 +00:00
sector - > special = ( INT16 ) luaL_checkinteger ( L , 3 ) ;
break ;
2014-08-04 03:49:33 +00:00
case sector_tag :
2020-04-17 20:30:16 +00:00
Tag_SectorFSet ( ( UINT32 ) ( sector - sectors ) , ( INT16 ) luaL_checkinteger ( L , 3 ) ) ;
2014-03-15 16:59:03 +00:00
break ;
2020-12-04 21:47:22 +00:00
case sector_taglist :
return LUA_ErrSetDirectly ( L , " sector_t " , " taglist " ) ;
2021-12-30 13:16:00 +00:00
case sector_flags :
sector - > flags = luaL_checkinteger ( L , 3 ) ;
2021-12-30 17:50:02 +00:00
CheckForReverseGravity | = ( sector - > flags & MSF_GRAVITYFLIP ) ;
2021-12-30 13:16:00 +00:00
break ;
2021-12-30 23:03:24 +00:00
case sector_specialflags :
sector - > specialflags = luaL_checkinteger ( L , 3 ) ;
break ;
2021-12-31 07:53:00 +00:00
case sector_damagetype :
sector - > damagetype = ( UINT8 ) luaL_checkinteger ( L , 3 ) ;
break ;
2021-12-31 10:39:34 +00:00
case sector_triggertag :
sector - > triggertag = ( INT16 ) luaL_checkinteger ( L , 3 ) ;
break ;
case sector_triggerer :
sector - > triggerer = ( UINT8 ) luaL_checkinteger ( L , 3 ) ;
break ;
2021-12-30 17:19:42 +00:00
case sector_gravity :
sector - > gravity = luaL_checkfixed ( L , 3 ) ;
break ;
2014-03-15 16:59:03 +00:00
}
return 0 ;
}
static int sector_num ( lua_State * L )
{
sector_t * sector = * ( ( sector_t * * ) luaL_checkudata ( L , 1 , META_SECTOR ) ) ;
lua_pushinteger ( L , sector - sectors ) ;
return 1 ;
}
2017-01-18 22:02:28 +00:00
/////////////////
// subsector_t //
/////////////////
2014-03-15 16:59:03 +00:00
static int subsector_get ( lua_State * L )
{
subsector_t * subsector = * ( ( subsector_t * * ) luaL_checkudata ( L , 1 , META_SUBSECTOR ) ) ;
2023-06-18 16:05:16 +00:00
enum subsector_e field = Lua_optoption ( L , 2 , subsector_valid , subsector_fields_ref ) ;
2014-03-15 16:59:03 +00:00
if ( ! subsector )
{
2014-08-04 03:49:33 +00:00
if ( field = = subsector_valid ) {
2014-03-15 16:59:03 +00:00
lua_pushboolean ( L , 0 ) ;
return 1 ;
}
return luaL_error ( L , " accessed subsector_t doesn't exist anymore. " ) ;
}
switch ( field )
{
2014-08-04 03:49:33 +00:00
case subsector_valid : // valid
2014-03-15 16:59:03 +00:00
lua_pushboolean ( L , 1 ) ;
return 1 ;
2014-08-04 03:49:33 +00:00
case subsector_sector :
2014-03-15 16:59:03 +00:00
LUA_PushUserdata ( L , subsector - > sector , META_SECTOR ) ;
return 1 ;
2014-08-04 03:49:33 +00:00
case subsector_numlines :
2014-03-15 16:59:03 +00:00
lua_pushinteger ( L , subsector - > numlines ) ;
return 1 ;
2014-08-04 03:49:33 +00:00
case subsector_firstline :
2014-03-15 16:59:03 +00:00
lua_pushinteger ( L , subsector - > firstline ) ;
return 1 ;
2020-09-09 16:31:44 +00:00
case subsector_polyList : // polyList
lua_pushcfunction ( L , lib_iterateSubSectorPolylist ) ;
LUA_PushUserdata ( L , subsector - > polyList , META_POLYOBJ ) ;
lua_pushcclosure ( L , sector_iterate , 2 ) ; // push lib_iterateSubSectorPolylist and subsector->polyList as upvalues for the function
return 1 ;
2014-03-15 16:59:03 +00:00
}
return 0 ;
}
static int subsector_num ( lua_State * L )
{
subsector_t * subsector = * ( ( subsector_t * * ) luaL_checkudata ( L , 1 , META_SUBSECTOR ) ) ;
lua_pushinteger ( L , subsector - subsectors ) ;
return 1 ;
}
2017-01-18 22:02:28 +00:00
////////////
// line_t //
////////////
2020-01-02 11:23:14 +00:00
// args, i -> args[i]
static int lineargs_get ( lua_State * L )
{
INT32 * args = * ( ( INT32 * * ) luaL_checkudata ( L , 1 , META_LINEARGS ) ) ;
int i = luaL_checkinteger ( L , 2 ) ;
if ( i < 0 | | i > = NUMLINEARGS )
return luaL_error ( L , LUA_QL ( " line_t.args " ) " index cannot be %d " , i ) ;
lua_pushinteger ( L , args [ i ] ) ;
return 1 ;
}
// #args -> NUMLINEARGS
static int lineargs_len ( lua_State * L )
{
lua_pushinteger ( L , NUMLINEARGS ) ;
return 1 ;
}
2020-01-08 07:42:35 +00:00
// stringargs, i -> stringargs[i]
static int linestringargs_get ( lua_State * L )
{
char * * stringargs = * ( ( char * * * ) luaL_checkudata ( L , 1 , META_LINESTRINGARGS ) ) ;
int i = luaL_checkinteger ( L , 2 ) ;
if ( i < 0 | | i > = NUMLINESTRINGARGS )
return luaL_error ( L , LUA_QL ( " line_t.stringargs " ) " index cannot be %d " , i ) ;
lua_pushstring ( L , stringargs [ i ] ) ;
return 1 ;
}
// #stringargs -> NUMLINESTRINGARGS
static int linestringargs_len ( lua_State * L )
{
lua_pushinteger ( L , NUMLINESTRINGARGS ) ;
return 1 ;
}
2014-03-15 16:59:03 +00:00
static int line_get ( lua_State * L )
{
line_t * line = * ( ( line_t * * ) luaL_checkudata ( L , 1 , META_LINE ) ) ;
2023-06-18 16:05:16 +00:00
enum line_e field = Lua_optoption ( L , 2 , line_valid , line_fields_ref ) ;
2014-03-15 16:59:03 +00:00
if ( ! line )
{
2014-08-04 03:49:33 +00:00
if ( field = = line_valid ) {
2014-03-15 16:59:03 +00:00
lua_pushboolean ( L , 0 ) ;
return 1 ;
}
return luaL_error ( L , " accessed line_t doesn't exist anymore. " ) ;
}
switch ( field )
{
2014-08-04 03:49:33 +00:00
case line_valid : // valid
2014-03-15 16:59:03 +00:00
lua_pushboolean ( L , 1 ) ;
return 1 ;
2014-08-04 03:49:33 +00:00
case line_v1 :
2014-03-15 16:59:03 +00:00
LUA_PushUserdata ( L , line - > v1 , META_VERTEX ) ;
return 1 ;
2014-08-04 03:49:33 +00:00
case line_v2 :
2014-03-15 16:59:03 +00:00
LUA_PushUserdata ( L , line - > v2 , META_VERTEX ) ;
return 1 ;
2014-08-04 03:49:33 +00:00
case line_dx :
2015-05-21 03:54:04 +00:00
lua_pushfixed ( L , line - > dx ) ;
2014-03-15 16:59:03 +00:00
return 1 ;
2014-08-04 03:49:33 +00:00
case line_dy :
2015-05-21 03:54:04 +00:00
lua_pushfixed ( L , line - > dy ) ;
2014-03-15 16:59:03 +00:00
return 1 ;
2021-08-24 08:13:18 +00:00
case line_angle :
lua_pushangle ( L , line - > angle ) ;
return 1 ;
2014-08-04 03:49:33 +00:00
case line_flags :
2014-03-15 16:59:03 +00:00
lua_pushinteger ( L , line - > flags ) ;
return 1 ;
2014-08-04 03:49:33 +00:00
case line_special :
2014-03-15 16:59:03 +00:00
lua_pushinteger ( L , line - > special ) ;
return 1 ;
2014-08-04 03:49:33 +00:00
case line_tag :
2023-10-28 12:46:10 +00:00
// TODO: 2.3: Always return a unsigned value
2020-04-17 20:30:16 +00:00
lua_pushinteger ( L , Tag_FGet ( & line - > tags ) ) ;
2014-03-15 16:59:03 +00:00
return 1 ;
2020-12-04 21:47:22 +00:00
case line_taglist :
2020-12-05 10:02:06 +00:00
LUA_PushUserdata ( L , & line - > tags , META_TAGLIST ) ;
2020-12-04 21:47:22 +00:00
return 1 ;
2020-01-02 11:23:14 +00:00
case line_args :
LUA_PushUserdata ( L , line - > args , META_LINEARGS ) ;
return 1 ;
2020-01-08 07:42:35 +00:00
case line_stringargs :
LUA_PushUserdata ( L , line - > stringargs , META_LINESTRINGARGS ) ;
return 1 ;
2014-08-04 03:49:33 +00:00
case line_sidenum :
2014-03-15 16:59:03 +00:00
LUA_PushUserdata ( L , line - > sidenum , META_SIDENUM ) ;
return 1 ;
2014-08-04 03:49:33 +00:00
case line_frontside : // frontside
2014-03-15 16:59:03 +00:00
LUA_PushUserdata ( L , & sides [ line - > sidenum [ 0 ] ] , META_SIDE ) ;
return 1 ;
2014-08-04 03:49:33 +00:00
case line_backside : // backside
2023-09-21 05:06:06 +00:00
if ( line - > sidenum [ 1 ] = = NO_SIDEDEF )
2014-03-15 16:59:03 +00:00
return 0 ;
LUA_PushUserdata ( L , & sides [ line - > sidenum [ 1 ] ] , META_SIDE ) ;
return 1 ;
2020-01-26 11:24:52 +00:00
case line_alpha :
lua_pushfixed ( L , line - > alpha ) ;
return 1 ;
2020-05-03 18:41:37 +00:00
case line_executordelay :
lua_pushinteger ( L , line - > executordelay ) ;
return 1 ;
2014-08-04 03:49:33 +00:00
case line_slopetype :
switch ( line - > slopetype )
2014-03-15 16:59:03 +00:00
{
case ST_HORIZONTAL :
lua_pushliteral ( L , " horizontal " ) ;
break ;
case ST_VERTICAL :
lua_pushliteral ( L , " vertical " ) ;
break ;
case ST_POSITIVE :
lua_pushliteral ( L , " positive " ) ;
break ;
case ST_NEGATIVE :
lua_pushliteral ( L , " negative " ) ;
break ;
}
return 1 ;
2014-08-04 03:49:33 +00:00
case line_frontsector :
2014-03-15 16:59:03 +00:00
LUA_PushUserdata ( L , line - > frontsector , META_SECTOR ) ;
return 1 ;
2014-08-04 03:49:33 +00:00
case line_backsector :
2014-03-15 16:59:03 +00:00
LUA_PushUserdata ( L , line - > backsector , META_SECTOR ) ;
return 1 ;
2020-09-09 16:31:44 +00:00
case line_polyobj :
LUA_PushUserdata ( L , line - > polyobj , META_POLYOBJ ) ;
return 1 ;
2023-10-28 13:19:35 +00:00
// TODO: 2.3: Delete
2014-08-04 03:49:33 +00:00
case line_text :
Tidier conversion of string properties on linedefs to UDMF
Previously, many concatenated texture field strings were turned to text, then had that string run through get_number, then had it converted back into a string to become a stringarg.
Now, the concatenated string is copied directly to the relevant stringarg, with no intermediary steps.
This fixes an issue where a map with object or state properties would have "context drift" - breaking when the object or state list changed, due to differently ordered freeslots, or new hardcoded objects.
Affected types:
- doomednum 1110/Action 9 (Custom Mace/Chain)
- doomednum 700 and those immediately following (Ambient Sound)
- Action 4 and 414 (dash pad, play sound effect)
- Action 14 (bustable block parameters)
- Action 434 (Award Power)
- doomednum 757/Action 15 (fan particle generator)
- doomednum 1202 (bumpable hazard rock/apple spawner)
- This one has undefined behaviour in the binary map format which was not previously forbidden. This undefined behaviour is EXTREMELY vulnerable to context drift, and so it's simply not worth creating a system to write numerical values into object types - we write an explicit name only for the intended range, and otherwise report the threat of context drift when converting.
In addition, to reduce duplicated zone memory, (sidedef_t).text and (linedef_t).text have been removed from all but the Lua API. In Lua, in binary maps, they point to the host line's stringargs - the line's text and a frontside's text will return stringargs[0], while a backside's text will return stringargs[1]. I've done my best to match the previous API as closely possible, to the point of reporting false nils if the line didn't previously have text available.
However, there are four linedef Actions for which the sidedef text will be different between builds containing and not containing this commit - 331, 332, 333 (the Character-specific linedef executors), and 443 (Call Lua Script), and only if the text is long enough to go over two lines. Given that both halves would be incomplete nonsense in this case, I'm willing to wager this minor point of discrepancy is not a breaking issue.
2023-07-20 18:42:21 +00:00
{
if ( udmf )
{
LUA_Deprecated ( L , " (linedef_t).text " , " (linedef_t).stringargs " ) ;
lua_pushnil ( L ) ;
return 1 ;
}
if ( line - > special = = 331 | | line - > special = = 443 )
{
// See P_ProcessLinedefsAfterSidedefs, P_ConvertBinaryLinedefTypes
lua_pushstring ( L , line - > stringargs [ 0 ] ) ;
}
else
lua_pushnil ( L ) ;
return 1 ;
}
2014-11-12 00:55:07 +00:00
case line_callcount :
lua_pushinteger ( L , line - > callcount ) ;
return 1 ;
2014-03-15 16:59:03 +00:00
}
return 0 ;
}
static int line_num ( lua_State * L )
{
line_t * line = * ( ( line_t * * ) luaL_checkudata ( L , 1 , META_LINE ) ) ;
lua_pushinteger ( L , line - lines ) ;
return 1 ;
}
2017-01-18 22:02:28 +00:00
////////////////////
// line.sidenum[] //
////////////////////
2014-03-15 16:59:03 +00:00
static int sidenum_get ( lua_State * L )
{
2024-01-01 02:44:07 +00:00
UINT32 * sidenum = * ( ( UINT32 * * ) luaL_checkudata ( L , 1 , META_SIDENUM ) ) ;
2014-03-15 16:59:03 +00:00
int i ;
lua_settop ( L , 2 ) ;
if ( ! lua_isnumber ( L , 2 ) )
{
int field = luaL_checkoption ( L , 2 , NULL , valid_opt ) ;
if ( ! sidenum )
{
if ( field = = 0 ) {
lua_pushboolean ( L , 0 ) ;
return 1 ;
}
return luaL_error ( L , " accessed line_t doesn't exist anymore. " ) ;
} else if ( field = = 0 ) {
lua_pushboolean ( L , 1 ) ;
return 1 ;
}
}
i = lua_tointeger ( L , 2 ) ;
if ( i < 0 | | i > 1 )
return 0 ;
lua_pushinteger ( L , sidenum [ i ] ) ;
return 1 ;
}
2017-01-18 22:02:28 +00:00
////////////
// side_t //
////////////
2014-03-15 16:59:03 +00:00
static int side_get ( lua_State * L )
{
side_t * side = * ( ( side_t * * ) luaL_checkudata ( L , 1 , META_SIDE ) ) ;
2023-06-18 16:05:16 +00:00
enum side_e field = Lua_optoption ( L , 2 , side_valid , side_fields_ref ) ;
2014-03-15 16:59:03 +00:00
if ( ! side )
{
2014-08-04 03:49:33 +00:00
if ( field = = side_valid ) {
2014-03-15 16:59:03 +00:00
lua_pushboolean ( L , 0 ) ;
return 1 ;
}
return luaL_error ( L , " accessed side_t doesn't exist anymore. " ) ;
}
switch ( field )
{
2014-08-04 03:49:33 +00:00
case side_valid : // valid
2014-03-15 16:59:03 +00:00
lua_pushboolean ( L , 1 ) ;
return 1 ;
2014-08-04 03:49:33 +00:00
case side_textureoffset :
2015-05-21 03:54:04 +00:00
lua_pushfixed ( L , side - > textureoffset ) ;
2014-03-15 16:59:03 +00:00
return 1 ;
2014-08-04 03:49:33 +00:00
case side_rowoffset :
2015-05-21 03:54:04 +00:00
lua_pushfixed ( L , side - > rowoffset ) ;
2014-03-15 16:59:03 +00:00
return 1 ;
2023-06-11 17:55:43 +00:00
case side_offsetx_top :
lua_pushfixed ( L , side - > offsetx_top ) ;
return 1 ;
case side_offsety_top :
lua_pushfixed ( L , side - > offsety_top ) ;
return 1 ;
case side_offsetx_mid :
lua_pushfixed ( L , side - > offsetx_mid ) ;
return 1 ;
case side_offsety_mid :
lua_pushfixed ( L , side - > offsety_mid ) ;
return 1 ;
2023-11-24 16:54:09 +00:00
case side_offsetx_bottom :
2023-06-11 17:55:43 +00:00
case side_offsetx_bot :
2023-11-24 00:56:18 +00:00
lua_pushfixed ( L , side - > offsetx_bottom ) ;
2023-06-11 17:55:43 +00:00
return 1 ;
2023-11-24 16:54:09 +00:00
case side_offsety_bottom :
2023-06-11 17:55:43 +00:00
case side_offsety_bot :
2023-11-24 00:56:18 +00:00
lua_pushfixed ( L , side - > offsety_bottom ) ;
2023-06-11 17:55:43 +00:00
return 1 ;
2023-06-23 21:32:58 +00:00
case side_scalex_top :
lua_pushfixed ( L , side - > scalex_top ) ;
return 1 ;
case side_scaley_top :
lua_pushfixed ( L , side - > scaley_top ) ;
return 1 ;
case side_scalex_mid :
lua_pushfixed ( L , side - > scalex_mid ) ;
return 1 ;
case side_scaley_mid :
lua_pushfixed ( L , side - > scaley_mid ) ;
return 1 ;
2023-11-24 16:54:09 +00:00
case side_scalex_bottom :
2023-11-24 00:56:18 +00:00
lua_pushfixed ( L , side - > scalex_bottom ) ;
2023-06-23 21:32:58 +00:00
return 1 ;
2023-11-24 16:54:09 +00:00
case side_scaley_bottom :
2023-11-24 00:56:18 +00:00
lua_pushfixed ( L , side - > scaley_bottom ) ;
2023-06-11 17:55:43 +00:00
return 1 ;
2014-08-04 03:49:33 +00:00
case side_toptexture :
2014-03-15 16:59:03 +00:00
lua_pushinteger ( L , side - > toptexture ) ;
return 1 ;
2014-08-04 03:49:33 +00:00
case side_bottomtexture :
2014-03-15 16:59:03 +00:00
lua_pushinteger ( L , side - > bottomtexture ) ;
return 1 ;
2014-08-04 03:49:33 +00:00
case side_midtexture :
2014-03-15 16:59:03 +00:00
lua_pushinteger ( L , side - > midtexture ) ;
return 1 ;
2019-12-29 08:39:50 +00:00
case side_line :
LUA_PushUserdata ( L , side - > line , META_LINE ) ;
return 1 ;
2014-08-04 03:49:33 +00:00
case side_sector :
2014-03-15 16:59:03 +00:00
LUA_PushUserdata ( L , side - > sector , META_SECTOR ) ;
return 1 ;
2014-08-04 03:49:33 +00:00
case side_special :
2014-03-15 16:59:03 +00:00
lua_pushinteger ( L , side - > special ) ;
return 1 ;
2014-08-04 03:49:33 +00:00
case side_repeatcnt :
2014-03-15 16:59:03 +00:00
lua_pushinteger ( L , side - > repeatcnt ) ;
return 1 ;
2023-10-28 13:19:35 +00:00
// TODO: 2.3: Delete
2014-08-04 03:49:33 +00:00
case side_text :
Tidier conversion of string properties on linedefs to UDMF
Previously, many concatenated texture field strings were turned to text, then had that string run through get_number, then had it converted back into a string to become a stringarg.
Now, the concatenated string is copied directly to the relevant stringarg, with no intermediary steps.
This fixes an issue where a map with object or state properties would have "context drift" - breaking when the object or state list changed, due to differently ordered freeslots, or new hardcoded objects.
Affected types:
- doomednum 1110/Action 9 (Custom Mace/Chain)
- doomednum 700 and those immediately following (Ambient Sound)
- Action 4 and 414 (dash pad, play sound effect)
- Action 14 (bustable block parameters)
- Action 434 (Award Power)
- doomednum 757/Action 15 (fan particle generator)
- doomednum 1202 (bumpable hazard rock/apple spawner)
- This one has undefined behaviour in the binary map format which was not previously forbidden. This undefined behaviour is EXTREMELY vulnerable to context drift, and so it's simply not worth creating a system to write numerical values into object types - we write an explicit name only for the intended range, and otherwise report the threat of context drift when converting.
In addition, to reduce duplicated zone memory, (sidedef_t).text and (linedef_t).text have been removed from all but the Lua API. In Lua, in binary maps, they point to the host line's stringargs - the line's text and a frontside's text will return stringargs[0], while a backside's text will return stringargs[1]. I've done my best to match the previous API as closely possible, to the point of reporting false nils if the line didn't previously have text available.
However, there are four linedef Actions for which the sidedef text will be different between builds containing and not containing this commit - 331, 332, 333 (the Character-specific linedef executors), and 443 (Call Lua Script), and only if the text is long enough to go over two lines. Given that both halves would be incomplete nonsense in this case, I'm willing to wager this minor point of discrepancy is not a breaking issue.
2023-07-20 18:42:21 +00:00
{
2023-10-25 11:40:55 +00:00
boolean isfrontside ;
size_t sidei = side - sides ;
Tidier conversion of string properties on linedefs to UDMF
Previously, many concatenated texture field strings were turned to text, then had that string run through get_number, then had it converted back into a string to become a stringarg.
Now, the concatenated string is copied directly to the relevant stringarg, with no intermediary steps.
This fixes an issue where a map with object or state properties would have "context drift" - breaking when the object or state list changed, due to differently ordered freeslots, or new hardcoded objects.
Affected types:
- doomednum 1110/Action 9 (Custom Mace/Chain)
- doomednum 700 and those immediately following (Ambient Sound)
- Action 4 and 414 (dash pad, play sound effect)
- Action 14 (bustable block parameters)
- Action 434 (Award Power)
- doomednum 757/Action 15 (fan particle generator)
- doomednum 1202 (bumpable hazard rock/apple spawner)
- This one has undefined behaviour in the binary map format which was not previously forbidden. This undefined behaviour is EXTREMELY vulnerable to context drift, and so it's simply not worth creating a system to write numerical values into object types - we write an explicit name only for the intended range, and otherwise report the threat of context drift when converting.
In addition, to reduce duplicated zone memory, (sidedef_t).text and (linedef_t).text have been removed from all but the Lua API. In Lua, in binary maps, they point to the host line's stringargs - the line's text and a frontside's text will return stringargs[0], while a backside's text will return stringargs[1]. I've done my best to match the previous API as closely possible, to the point of reporting false nils if the line didn't previously have text available.
However, there are four linedef Actions for which the sidedef text will be different between builds containing and not containing this commit - 331, 332, 333 (the Character-specific linedef executors), and 443 (Call Lua Script), and only if the text is long enough to go over two lines. Given that both halves would be incomplete nonsense in this case, I'm willing to wager this minor point of discrepancy is not a breaking issue.
2023-07-20 18:42:21 +00:00
if ( udmf )
{
LUA_Deprecated ( L , " (sidedef_t).text " , " (sidedef_t).line.stringargs " ) ;
lua_pushnil ( L ) ;
return 1 ;
}
2023-10-25 11:40:55 +00:00
isfrontside = side - > line - > sidenum [ 0 ] = = sidei ;
Tidier conversion of string properties on linedefs to UDMF
Previously, many concatenated texture field strings were turned to text, then had that string run through get_number, then had it converted back into a string to become a stringarg.
Now, the concatenated string is copied directly to the relevant stringarg, with no intermediary steps.
This fixes an issue where a map with object or state properties would have "context drift" - breaking when the object or state list changed, due to differently ordered freeslots, or new hardcoded objects.
Affected types:
- doomednum 1110/Action 9 (Custom Mace/Chain)
- doomednum 700 and those immediately following (Ambient Sound)
- Action 4 and 414 (dash pad, play sound effect)
- Action 14 (bustable block parameters)
- Action 434 (Award Power)
- doomednum 757/Action 15 (fan particle generator)
- doomednum 1202 (bumpable hazard rock/apple spawner)
- This one has undefined behaviour in the binary map format which was not previously forbidden. This undefined behaviour is EXTREMELY vulnerable to context drift, and so it's simply not worth creating a system to write numerical values into object types - we write an explicit name only for the intended range, and otherwise report the threat of context drift when converting.
In addition, to reduce duplicated zone memory, (sidedef_t).text and (linedef_t).text have been removed from all but the Lua API. In Lua, in binary maps, they point to the host line's stringargs - the line's text and a frontside's text will return stringargs[0], while a backside's text will return stringargs[1]. I've done my best to match the previous API as closely possible, to the point of reporting false nils if the line didn't previously have text available.
However, there are four linedef Actions for which the sidedef text will be different between builds containing and not containing this commit - 331, 332, 333 (the Character-specific linedef executors), and 443 (Call Lua Script), and only if the text is long enough to go over two lines. Given that both halves would be incomplete nonsense in this case, I'm willing to wager this minor point of discrepancy is not a breaking issue.
2023-07-20 18:42:21 +00:00
lua_pushstring ( L , side - > line - > stringargs [ isfrontside ? 0 : 1 ] ) ;
return 1 ;
}
2014-03-15 16:59:03 +00:00
}
return 0 ;
}
2015-05-21 23:05:17 +00:00
static int side_set ( lua_State * L )
{
side_t * side = * ( ( side_t * * ) luaL_checkudata ( L , 1 , META_SIDE ) ) ;
2023-06-18 16:05:16 +00:00
enum side_e field = Lua_optoption ( L , 2 , side_valid , side_fields_ref ) ;
2015-05-21 23:05:17 +00:00
if ( ! side )
{
if ( field = = side_valid ) {
lua_pushboolean ( L , 0 ) ;
return 1 ;
}
return luaL_error ( L , " accessed side_t doesn't exist anymore. " ) ;
}
switch ( field )
{
case side_valid : // valid
2019-12-29 08:39:50 +00:00
case side_line :
2015-05-21 23:05:17 +00:00
case side_sector :
case side_special :
case side_text :
return luaL_error ( L , " side_t field " LUA_QS " cannot be set. " , side_opt [ field ] ) ;
2023-08-31 18:02:59 +00:00
default :
return luaL_error ( L , " side_t has no field named " LUA_QS " . " , lua_tostring ( L , 2 ) ) ;
2015-05-21 23:05:17 +00:00
case side_textureoffset :
side - > textureoffset = luaL_checkfixed ( L , 3 ) ;
break ;
case side_rowoffset :
side - > rowoffset = luaL_checkfixed ( L , 3 ) ;
break ;
2023-06-11 17:55:43 +00:00
case side_offsetx_top :
side - > offsetx_top = luaL_checkfixed ( L , 3 ) ;
break ;
case side_offsety_top :
side - > offsety_top = luaL_checkfixed ( L , 3 ) ;
break ;
case side_offsetx_mid :
side - > offsetx_mid = luaL_checkfixed ( L , 3 ) ;
break ;
case side_offsety_mid :
side - > offsety_mid = luaL_checkfixed ( L , 3 ) ;
break ;
case side_offsetx_bot :
2023-11-24 16:56:56 +00:00
case side_offsetx_bottom :
2023-11-24 00:56:18 +00:00
side - > offsetx_bottom = luaL_checkfixed ( L , 3 ) ;
2023-06-11 17:55:43 +00:00
break ;
case side_offsety_bot :
2023-11-24 16:56:56 +00:00
case side_offsety_bottom :
2023-11-24 00:56:18 +00:00
side - > offsety_bottom = luaL_checkfixed ( L , 3 ) ;
2023-06-23 21:32:58 +00:00
break ;
case side_scalex_top :
side - > scalex_top = luaL_checkfixed ( L , 3 ) ;
break ;
case side_scaley_top :
side - > scaley_top = luaL_checkfixed ( L , 3 ) ;
break ;
case side_scalex_mid :
side - > scalex_mid = luaL_checkfixed ( L , 3 ) ;
break ;
case side_scaley_mid :
side - > scaley_mid = luaL_checkfixed ( L , 3 ) ;
break ;
2023-11-24 16:56:56 +00:00
case side_scalex_bottom :
2023-11-24 00:56:18 +00:00
side - > scalex_bottom = luaL_checkfixed ( L , 3 ) ;
2023-06-23 21:32:58 +00:00
break ;
2023-11-24 16:56:56 +00:00
case side_scaley_bottom :
2023-11-24 00:56:18 +00:00
side - > scaley_bottom = luaL_checkfixed ( L , 3 ) ;
2015-05-21 23:05:17 +00:00
break ;
case side_toptexture :
2018-12-17 02:36:54 +00:00
side - > toptexture = luaL_checkinteger ( L , 3 ) ;
2015-05-21 23:05:17 +00:00
break ;
case side_bottomtexture :
2018-12-17 02:36:54 +00:00
side - > bottomtexture = luaL_checkinteger ( L , 3 ) ;
2015-05-21 23:05:17 +00:00
break ;
case side_midtexture :
2018-12-17 02:36:54 +00:00
side - > midtexture = luaL_checkinteger ( L , 3 ) ;
2015-05-21 23:05:17 +00:00
break ;
case side_repeatcnt :
2018-12-17 02:36:54 +00:00
side - > repeatcnt = luaL_checkinteger ( L , 3 ) ;
2015-05-21 23:05:17 +00:00
break ;
}
return 0 ;
}
2014-03-15 16:59:03 +00:00
static int side_num ( lua_State * L )
{
side_t * side = * ( ( side_t * * ) luaL_checkudata ( L , 1 , META_SIDE ) ) ;
lua_pushinteger ( L , side - sides ) ;
return 1 ;
}
2017-01-18 22:02:28 +00:00
//////////////
// vertex_t //
//////////////
2014-03-15 16:59:03 +00:00
static int vertex_get ( lua_State * L )
{
vertex_t * vertex = * ( ( vertex_t * * ) luaL_checkudata ( L , 1 , META_VERTEX ) ) ;
2023-06-18 16:05:16 +00:00
enum vertex_e field = Lua_optoption ( L , 2 , vertex_valid , vertex_fields_ref ) ;
2014-03-15 16:59:03 +00:00
if ( ! vertex )
{
2014-08-04 03:49:33 +00:00
if ( field = = vertex_valid ) {
2014-03-15 16:59:03 +00:00
lua_pushboolean ( L , 0 ) ;
return 1 ;
}
return luaL_error ( L , " accessed vertex_t doesn't exist anymore. " ) ;
}
switch ( field )
{
2014-08-04 03:49:33 +00:00
case vertex_valid : // valid
2014-03-15 16:59:03 +00:00
lua_pushboolean ( L , 1 ) ;
return 1 ;
2014-08-04 03:49:33 +00:00
case vertex_x :
2015-05-21 03:54:04 +00:00
lua_pushfixed ( L , vertex - > x ) ;
2014-03-15 16:59:03 +00:00
return 1 ;
2014-08-04 03:49:33 +00:00
case vertex_y :
2015-05-21 03:54:04 +00:00
lua_pushfixed ( L , vertex - > y ) ;
2014-03-15 16:59:03 +00:00
return 1 ;
2020-01-04 10:38:23 +00:00
case vertex_floorzset :
lua_pushboolean ( L , vertex - > floorzset ) ;
return 1 ;
case vertex_ceilingzset :
lua_pushboolean ( L , vertex - > ceilingzset ) ;
return 1 ;
case vertex_floorz :
lua_pushfixed ( L , vertex - > floorz ) ;
return 1 ;
case vertex_ceilingz :
lua_pushfixed ( L , vertex - > ceilingz ) ;
return 1 ;
2014-03-15 16:59:03 +00:00
}
return 0 ;
}
static int vertex_num ( lua_State * L )
{
vertex_t * vertex = * ( ( vertex_t * * ) luaL_checkudata ( L , 1 , META_VERTEX ) ) ;
lua_pushinteger ( L , vertex - vertexes ) ;
return 1 ;
}
2016-11-24 21:11:44 +00:00
# ifdef HAVE_LUA_SEGS
2017-01-18 22:02:28 +00:00
///////////
// seg_t //
///////////
2016-05-25 16:15:44 +00:00
static int seg_get ( lua_State * L )
{
seg_t * seg = * ( ( seg_t * * ) luaL_checkudata ( L , 1 , META_SEG ) ) ;
2023-06-18 16:05:16 +00:00
enum seg_e field = Lua_optoption ( L , 2 , seg_valid , seg_fields_ref ) ;
2016-05-25 16:15:44 +00:00
if ( ! seg )
{
if ( field = = seg_valid ) {
lua_pushboolean ( L , 0 ) ;
return 1 ;
}
return luaL_error ( L , " accessed seg_t doesn't exist anymore. " ) ;
}
switch ( field )
{
case seg_valid : // valid
lua_pushboolean ( L , 1 ) ;
return 1 ;
case seg_v1 :
LUA_PushUserdata ( L , seg - > v1 , META_VERTEX ) ;
return 1 ;
case seg_v2 :
LUA_PushUserdata ( L , seg - > v2 , META_VERTEX ) ;
return 1 ;
case seg_side :
lua_pushinteger ( L , seg - > side ) ;
return 1 ;
case seg_offset :
lua_pushfixed ( L , seg - > offset ) ;
return 1 ;
case seg_angle :
lua_pushangle ( L , seg - > angle ) ;
return 1 ;
case seg_sidedef :
LUA_PushUserdata ( L , seg - > sidedef , META_SIDE ) ;
return 1 ;
case seg_linedef :
LUA_PushUserdata ( L , seg - > linedef , META_LINE ) ;
return 1 ;
case seg_frontsector :
LUA_PushUserdata ( L , seg - > frontsector , META_SECTOR ) ;
return 1 ;
case seg_backsector :
LUA_PushUserdata ( L , seg - > backsector , META_SECTOR ) ;
return 1 ;
2020-09-09 16:31:44 +00:00
case seg_polyseg :
LUA_PushUserdata ( L , seg - > polyseg , META_POLYOBJ ) ;
return 1 ;
2016-05-25 16:15:44 +00:00
}
return 0 ;
}
static int seg_num ( lua_State * L )
{
seg_t * seg = * ( ( seg_t * * ) luaL_checkudata ( L , 1 , META_SEG ) ) ;
lua_pushinteger ( L , seg - segs ) ;
return 1 ;
}
2017-01-18 22:02:28 +00:00
////////////
// node_t //
////////////
2016-07-08 19:05:54 +00:00
static int node_get ( lua_State * L )
{
node_t * node = * ( ( node_t * * ) luaL_checkudata ( L , 1 , META_NODE ) ) ;
2023-06-18 16:05:16 +00:00
enum node_e field = Lua_optoption ( L , 2 , node_valid , node_fields_ref ) ;
2016-07-08 19:05:54 +00:00
if ( ! node )
{
if ( field = = node_valid ) {
lua_pushboolean ( L , 0 ) ;
return 1 ;
}
return luaL_error ( L , " accessed node_t doesn't exist anymore. " ) ;
}
switch ( field )
{
case node_valid : // valid
lua_pushboolean ( L , 1 ) ;
return 1 ;
case node_x :
lua_pushfixed ( L , node - > x ) ;
return 1 ;
case node_y :
lua_pushfixed ( L , node - > y ) ;
return 1 ;
case node_dx :
lua_pushfixed ( L , node - > x ) ;
return 1 ;
case node_dy :
lua_pushfixed ( L , node - > x ) ;
return 1 ;
case node_bbox :
LUA_PushUserdata ( L , node - > bbox , META_NODEBBOX ) ;
return 1 ;
case node_children :
LUA_PushUserdata ( L , node - > children , META_NODECHILDREN ) ;
return 1 ;
}
return 0 ;
}
static int node_num ( lua_State * L )
{
node_t * node = * ( ( node_t * * ) luaL_checkudata ( L , 1 , META_NODE ) ) ;
lua_pushinteger ( L , node - nodes ) ;
return 1 ;
}
2017-01-18 22:02:28 +00:00
///////////////
// node.bbox //
///////////////
2016-08-04 17:54:29 +00:00
/*
2016-07-08 19:05:54 +00:00
// node.bbox[i][j]: i = 0 or 1, j = 0 1 2 or 3
// NOTE: 2D arrays are NOT double pointers,
// the second bbox will be directly after the first in memory (hence the way the bbox is pushed here)
// this function handles the [i] part, bbox_get handles the [j] part
static int nodebbox_get ( lua_State * L )
{
fixed_t * bbox = * ( ( fixed_t * * ) luaL_checkudata ( L , 1 , META_NODEBBOX ) ) ;
int i ;
lua_settop ( L , 2 ) ;
if ( ! lua_isnumber ( L , 2 ) )
{
int field = luaL_checkoption ( L , 2 , NULL , valid_opt ) ;
if ( ! bbox )
{
if ( field = = 0 ) {
lua_pushboolean ( L , 0 ) ;
return 1 ;
}
return luaL_error ( L , " accessed node_t doesn't exist anymore. " ) ;
} else if ( field = = 0 ) {
lua_pushboolean ( L , 1 ) ;
return 1 ;
}
}
i = lua_tointeger ( L , 2 ) ;
if ( i < 0 | | i > 1 )
return 0 ;
LUA_PushUserdata ( L , bbox + i * 4 * sizeof ( fixed_t ) , META_BBOX ) ;
return 1 ;
}
2016-08-04 17:54:29 +00:00
*/
static int nodebbox_call ( lua_State * L )
{
fixed_t * bbox = * ( ( fixed_t * * ) luaL_checkudata ( L , 1 , META_NODEBBOX ) ) ;
int i , j ;
int n = lua_gettop ( L ) ;
if ( ! bbox )
return luaL_error ( L , " accessed node bbox doesn't exist anymore. " ) ;
if ( n < 3 )
return luaL_error ( L , " arguments 2 and/or 3 not given (expected node.bbox(child, coord) ) " ) ;
// get child
if ( ! lua_isnumber ( L , 2 ) ) {
enum nodechild_e field = luaL_checkoption ( L , 2 , nodechild_opt [ 0 ] , nodechild_opt ) ;
switch ( field ) {
case nodechild_right : i = 0 ; break ;
case nodechild_left : i = 1 ; break ;
default :
return luaL_error ( L , " invalid node child \" %s \" . " , lua_tostring ( L , 2 ) ) ;
}
}
else {
i = lua_tointeger ( L , 2 ) ;
if ( i < 0 | | i > 1 )
return 0 ;
}
// get bbox coord
if ( ! lua_isnumber ( L , 3 ) ) {
enum bbox_e field = luaL_checkoption ( L , 3 , bbox_opt [ 0 ] , bbox_opt ) ;
switch ( field ) {
case bbox_top : j = BOXTOP ; break ;
case bbox_bottom : j = BOXBOTTOM ; break ;
case bbox_left : j = BOXLEFT ; break ;
case bbox_right : j = BOXRIGHT ; break ;
default :
return luaL_error ( L , " invalid bbox coordinate \" %s \" . " , lua_tostring ( L , 3 ) ) ;
}
}
else {
j = lua_tointeger ( L , 3 ) ;
if ( j < 0 | | j > 3 )
return 0 ;
}
lua_pushinteger ( L , bbox [ i * 4 + j ] ) ;
return 1 ;
}
2016-07-08 19:05:54 +00:00
2017-01-18 22:02:28 +00:00
/////////////////////
// node.children[] //
/////////////////////
2016-07-08 19:05:54 +00:00
// node.children[i]: i = 0 or 1
static int nodechildren_get ( lua_State * L )
{
UINT16 * children = * ( ( UINT16 * * ) luaL_checkudata ( L , 1 , META_NODECHILDREN ) ) ;
int i ;
lua_settop ( L , 2 ) ;
if ( ! lua_isnumber ( L , 2 ) )
{
2016-08-04 18:20:34 +00:00
enum nodechild_e field = luaL_checkoption ( L , 2 , nodechild_opt [ 0 ] , nodechild_opt ) ;
2016-07-08 19:05:54 +00:00
if ( ! children )
{
2016-08-04 18:20:34 +00:00
if ( field = = nodechild_valid ) {
2016-07-08 19:05:54 +00:00
lua_pushboolean ( L , 0 ) ;
return 1 ;
}
return luaL_error ( L , " accessed node_t doesn't exist anymore. " ) ;
2016-08-04 18:20:34 +00:00
} else if ( field = = nodechild_valid ) {
2016-07-08 19:05:54 +00:00
lua_pushboolean ( L , 1 ) ;
return 1 ;
2016-08-04 18:20:34 +00:00
} else switch ( field ) {
case nodechild_right : i = 0 ; break ;
case nodechild_left : i = 1 ; break ;
default : return 0 ;
2016-07-08 19:05:54 +00:00
}
}
2016-08-04 18:20:34 +00:00
else {
i = lua_tointeger ( L , 2 ) ;
if ( i < 0 | | i > 1 )
return 0 ;
}
2016-07-08 19:05:54 +00:00
lua_pushinteger ( L , children [ i ] ) ;
return 1 ;
}
2016-11-24 21:11:44 +00:00
# endif
2016-07-08 19:05:54 +00:00
2017-01-18 22:02:28 +00:00
//////////
// bbox //
//////////
2016-07-08 19:05:54 +00:00
// bounding box (aka fixed_t array with four elements)
// NOTE: may be useful for polyobjects or other things later
static int bbox_get ( lua_State * L )
{
fixed_t * bbox = * ( ( fixed_t * * ) luaL_checkudata ( L , 1 , META_BBOX ) ) ;
int i ;
lua_settop ( L , 2 ) ;
if ( ! lua_isnumber ( L , 2 ) )
{
2016-08-04 17:54:29 +00:00
enum bbox_e field = luaL_checkoption ( L , 2 , bbox_opt [ 0 ] , bbox_opt ) ;
2016-07-08 19:05:54 +00:00
if ( ! bbox )
{
2016-08-04 17:54:29 +00:00
if ( field = = bbox_valid ) {
2016-07-08 19:05:54 +00:00
lua_pushboolean ( L , 0 ) ;
return 1 ;
}
2016-08-04 17:54:29 +00:00
return luaL_error ( L , " accessed bbox doesn't exist anymore. " ) ;
} else if ( field = = bbox_valid ) {
2016-07-08 19:05:54 +00:00
lua_pushboolean ( L , 1 ) ;
return 1 ;
2016-08-04 18:20:34 +00:00
} else switch ( field ) {
2016-08-04 17:54:29 +00:00
case bbox_top : i = BOXTOP ; break ;
case bbox_bottom : i = BOXBOTTOM ; break ;
case bbox_left : i = BOXLEFT ; break ;
case bbox_right : i = BOXRIGHT ; break ;
default : return 0 ;
}
}
else {
i = lua_tointeger ( L , 2 ) ;
if ( i < 0 | | i > 3 )
return 0 ;
2016-07-08 19:05:54 +00:00
}
lua_pushinteger ( L , bbox [ i ] ) ;
return 1 ;
}
2017-01-18 22:02:28 +00:00
///////////////
// sectors[] //
///////////////
2014-03-15 16:59:03 +00:00
static int lib_iterateSectors ( lua_State * L )
{
size_t i = 0 ;
2019-07-30 16:48:13 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( lua_gettop ( L ) < 2 )
return luaL_error ( L , " Don't call sectors.iterate() directly , use it as ' for sector in sectors . iterate do < block > end ' . " ) ;
lua_settop ( L , 2 ) ;
lua_remove ( L , 1 ) ; // state is unused.
if ( ! lua_isnil ( L , 1 ) )
i = ( size_t ) ( * ( ( sector_t * * ) luaL_checkudata ( L , 1 , META_SECTOR ) ) - sectors ) + 1 ;
if ( i < numsectors )
{
LUA_PushUserdata ( L , & sectors [ i ] , META_SECTOR ) ;
return 1 ;
}
return 0 ;
}
static int lib_getSector ( lua_State * L )
{
2019-07-30 16:48:13 +00:00
INLEVEL
2020-12-04 08:30:08 +00:00
if ( lua_isnumber ( L , 2 ) )
2014-03-15 16:59:03 +00:00
{
2020-12-04 08:30:08 +00:00
size_t i = lua_tointeger ( L , 2 ) ;
2014-03-15 16:59:03 +00:00
if ( i > = numsectors )
return 0 ;
LUA_PushUserdata ( L , & sectors [ i ] , META_SECTOR ) ;
return 1 ;
}
return 0 ;
}
static int lib_numsectors ( lua_State * L )
{
lua_pushinteger ( L , numsectors ) ;
return 1 ;
}
2017-01-18 22:02:28 +00:00
//////////////////
// subsectors[] //
//////////////////
2014-03-15 16:59:03 +00:00
static int lib_iterateSubsectors ( lua_State * L )
{
size_t i = 0 ;
2019-07-30 16:48:13 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( lua_gettop ( L ) < 2 )
return luaL_error ( L , " Don't call subsectors.iterate() directly , use it as ' for subsector in subsectors . iterate do < block > end ' . " ) ;
lua_settop ( L , 2 ) ;
lua_remove ( L , 1 ) ; // state is unused.
if ( ! lua_isnil ( L , 1 ) )
i = ( size_t ) ( * ( ( subsector_t * * ) luaL_checkudata ( L , 1 , META_SUBSECTOR ) ) - subsectors ) + 1 ;
if ( i < numsubsectors )
{
LUA_PushUserdata ( L , & subsectors [ i ] , META_SUBSECTOR ) ;
return 1 ;
}
return 0 ;
}
static int lib_getSubsector ( lua_State * L )
{
int field ;
2019-07-30 16:48:13 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
lua_settop ( L , 2 ) ;
lua_remove ( L , 1 ) ; // dummy userdata table is unused.
if ( lua_isnumber ( L , 1 ) )
{
size_t i = lua_tointeger ( L , 1 ) ;
if ( i > = numsubsectors )
return 0 ;
LUA_PushUserdata ( L , & subsectors [ i ] , META_SUBSECTOR ) ;
return 1 ;
}
field = luaL_checkoption ( L , 1 , NULL , array_opt ) ;
switch ( field )
{
case 0 : // iterate
lua_pushcfunction ( L , lib_iterateSubsectors ) ;
return 1 ;
}
return 0 ;
}
static int lib_numsubsectors ( lua_State * L )
{
lua_pushinteger ( L , numsubsectors ) ;
return 1 ;
}
2017-01-18 22:02:28 +00:00
/////////////
// lines[] //
/////////////
2014-03-15 16:59:03 +00:00
static int lib_iterateLines ( lua_State * L )
{
size_t i = 0 ;
2019-07-30 16:48:13 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( lua_gettop ( L ) < 2 )
return luaL_error ( L , " Don't call lines.iterate() directly , use it as ' for line in lines . iterate do < block > end ' . " ) ;
lua_settop ( L , 2 ) ;
lua_remove ( L , 1 ) ; // state is unused.
if ( ! lua_isnil ( L , 1 ) )
i = ( size_t ) ( * ( ( line_t * * ) luaL_checkudata ( L , 1 , META_LINE ) ) - lines ) + 1 ;
if ( i < numlines )
{
LUA_PushUserdata ( L , & lines [ i ] , META_LINE ) ;
return 1 ;
}
return 0 ;
}
static int lib_getLine ( lua_State * L )
{
2019-07-30 16:48:13 +00:00
INLEVEL
2020-12-04 08:30:08 +00:00
if ( lua_isnumber ( L , 2 ) )
2014-03-15 16:59:03 +00:00
{
2020-12-04 08:30:08 +00:00
size_t i = lua_tointeger ( L , 2 ) ;
2014-03-15 16:59:03 +00:00
if ( i > = numlines )
return 0 ;
LUA_PushUserdata ( L , & lines [ i ] , META_LINE ) ;
return 1 ;
}
return 0 ;
}
static int lib_numlines ( lua_State * L )
{
lua_pushinteger ( L , numlines ) ;
return 1 ;
}
2017-01-18 22:02:28 +00:00
/////////////
// sides[] //
/////////////
2014-03-15 16:59:03 +00:00
static int lib_iterateSides ( lua_State * L )
{
size_t i = 0 ;
2019-07-30 16:48:13 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( lua_gettop ( L ) < 2 )
return luaL_error ( L , " Don't call sides.iterate() directly , use it as ' for side in sides . iterate do < block > end ' . " ) ;
lua_settop ( L , 2 ) ;
lua_remove ( L , 1 ) ; // state is unused.
if ( ! lua_isnil ( L , 1 ) )
i = ( size_t ) ( * ( ( side_t * * ) luaL_checkudata ( L , 1 , META_SIDE ) ) - sides ) + 1 ;
if ( i < numsides )
{
LUA_PushUserdata ( L , & sides [ i ] , META_SIDE ) ;
return 1 ;
}
return 0 ;
}
static int lib_getSide ( lua_State * L )
{
int field ;
2019-07-30 16:48:13 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
lua_settop ( L , 2 ) ;
lua_remove ( L , 1 ) ; // dummy userdata table is unused.
if ( lua_isnumber ( L , 1 ) )
{
size_t i = lua_tointeger ( L , 1 ) ;
if ( i > = numsides )
return 0 ;
LUA_PushUserdata ( L , & sides [ i ] , META_SIDE ) ;
return 1 ;
}
field = luaL_checkoption ( L , 1 , NULL , array_opt ) ;
switch ( field )
{
case 0 : // iterate
lua_pushcfunction ( L , lib_iterateSides ) ;
return 1 ;
}
return 0 ;
}
static int lib_numsides ( lua_State * L )
{
lua_pushinteger ( L , numsides ) ;
return 1 ;
}
2017-01-18 22:02:28 +00:00
////////////////
// vertexes[] //
////////////////
2014-03-15 16:59:03 +00:00
static int lib_iterateVertexes ( lua_State * L )
{
size_t i = 0 ;
2019-07-30 16:48:13 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
if ( lua_gettop ( L ) < 2 )
return luaL_error ( L , " Don't call vertexes.iterate() directly , use it as ' for vertex in vertexes . iterate do < block > end ' . " ) ;
lua_settop ( L , 2 ) ;
lua_remove ( L , 1 ) ; // state is unused.
if ( ! lua_isnil ( L , 1 ) )
i = ( size_t ) ( * ( ( vertex_t * * ) luaL_checkudata ( L , 1 , META_VERTEX ) ) - vertexes ) + 1 ;
if ( i < numvertexes )
{
LUA_PushUserdata ( L , & vertexes [ i ] , META_VERTEX ) ;
return 1 ;
}
return 0 ;
}
static int lib_getVertex ( lua_State * L )
{
int field ;
2019-07-30 16:48:13 +00:00
INLEVEL
2014-03-15 16:59:03 +00:00
lua_settop ( L , 2 ) ;
lua_remove ( L , 1 ) ; // dummy userdata table is unused.
if ( lua_isnumber ( L , 1 ) )
{
size_t i = lua_tointeger ( L , 1 ) ;
if ( i > = numvertexes )
return 0 ;
LUA_PushUserdata ( L , & vertexes [ i ] , META_VERTEX ) ;
return 1 ;
}
field = luaL_checkoption ( L , 1 , NULL , array_opt ) ;
switch ( field )
{
case 0 : // iterate
lua_pushcfunction ( L , lib_iterateVertexes ) ;
return 1 ;
}
return 0 ;
}
static int lib_numvertexes ( lua_State * L )
{
lua_pushinteger ( L , numvertexes ) ;
return 1 ;
}
2016-11-24 21:11:44 +00:00
# ifdef HAVE_LUA_SEGS
2017-01-18 22:02:28 +00:00
////////////
// segs[] //
////////////
2016-05-25 16:15:44 +00:00
static int lib_iterateSegs ( lua_State * L )
{
size_t i = 0 ;
2019-07-30 16:48:13 +00:00
INLEVEL
2016-05-25 16:15:44 +00:00
if ( lua_gettop ( L ) < 2 )
return luaL_error ( L , " Don't call segs.iterate() directly , use it as ' for seg in segs . iterate do < block > end ' . " ) ;
lua_settop ( L , 2 ) ;
lua_remove ( L , 1 ) ; // state is unused.
if ( ! lua_isnil ( L , 1 ) )
i = ( size_t ) ( * ( ( seg_t * * ) luaL_checkudata ( L , 1 , META_SEG ) ) - segs ) + 1 ;
if ( i < numsegs )
{
LUA_PushUserdata ( L , & segs [ i ] , META_SEG ) ;
return 1 ;
}
return 0 ;
}
static int lib_getSeg ( lua_State * L )
{
int field ;
2019-07-30 16:48:13 +00:00
INLEVEL
2016-05-25 16:15:44 +00:00
lua_settop ( L , 2 ) ;
lua_remove ( L , 1 ) ; // dummy userdata table is unused.
if ( lua_isnumber ( L , 1 ) )
{
size_t i = lua_tointeger ( L , 1 ) ;
if ( i > = numsegs )
return 0 ;
LUA_PushUserdata ( L , & segs [ i ] , META_SEG ) ;
return 1 ;
}
field = luaL_checkoption ( L , 1 , NULL , array_opt ) ;
switch ( field )
{
case 0 : // iterate
lua_pushcfunction ( L , lib_iterateSegs ) ;
return 1 ;
}
return 0 ;
}
static int lib_numsegs ( lua_State * L )
{
lua_pushinteger ( L , numsegs ) ;
return 1 ;
}
2017-01-18 22:02:28 +00:00
/////////////
// nodes[] //
/////////////
2016-07-08 19:05:54 +00:00
static int lib_iterateNodes ( lua_State * L )
{
size_t i = 0 ;
2019-07-30 16:48:13 +00:00
INLEVEL
2016-07-08 19:05:54 +00:00
if ( lua_gettop ( L ) < 2 )
return luaL_error ( L , " Don't call nodes.iterate() directly , use it as ' for node in nodes . iterate do < block > end ' . " ) ;
lua_settop ( L , 2 ) ;
lua_remove ( L , 1 ) ; // state is unused.
if ( ! lua_isnil ( L , 1 ) )
i = ( size_t ) ( * ( ( node_t * * ) luaL_checkudata ( L , 1 , META_NODE ) ) - nodes ) + 1 ;
if ( i < numsegs )
{
LUA_PushUserdata ( L , & nodes [ i ] , META_NODE ) ;
return 1 ;
}
return 0 ;
}
static int lib_getNode ( lua_State * L )
{
int field ;
2019-07-30 16:48:13 +00:00
INLEVEL
2016-07-08 19:05:54 +00:00
lua_settop ( L , 2 ) ;
lua_remove ( L , 1 ) ; // dummy userdata table is unused.
if ( lua_isnumber ( L , 1 ) )
{
size_t i = lua_tointeger ( L , 1 ) ;
if ( i > = numnodes )
return 0 ;
LUA_PushUserdata ( L , & nodes [ i ] , META_NODE ) ;
return 1 ;
}
field = luaL_checkoption ( L , 1 , NULL , array_opt ) ;
switch ( field )
{
case 0 : // iterate
lua_pushcfunction ( L , lib_iterateNodes ) ;
return 1 ;
}
return 0 ;
}
static int lib_numnodes ( lua_State * L )
{
lua_pushinteger ( L , numnodes ) ;
return 1 ;
}
2016-11-24 21:11:44 +00:00
# endif
2016-07-08 19:05:54 +00:00
2017-01-18 22:02:28 +00:00
//////////////
// ffloor_t //
//////////////
2022-07-31 10:04:42 +00:00
static INT32 P_GetOldFOFFlags ( ffloor_t * fflr )
{
INT32 result = 0 ;
if ( fflr - > fofflags & FOF_EXISTS )
result | = FF_OLD_EXISTS ;
if ( fflr - > fofflags & FOF_BLOCKPLAYER )
result | = FF_OLD_BLOCKPLAYER ;
if ( fflr - > fofflags & FOF_BLOCKOTHERS )
result | = FF_OLD_BLOCKOTHERS ;
if ( fflr - > fofflags & FOF_RENDERSIDES )
result | = FF_OLD_RENDERSIDES ;
if ( fflr - > fofflags & FOF_RENDERPLANES )
result | = FF_OLD_RENDERPLANES ;
if ( fflr - > fofflags & FOF_SWIMMABLE )
result | = FF_OLD_SWIMMABLE ;
if ( fflr - > fofflags & FOF_NOSHADE )
result | = FF_OLD_NOSHADE ;
if ( fflr - > fofflags & FOF_CUTSOLIDS )
result | = FF_OLD_CUTSOLIDS ;
if ( fflr - > fofflags & FOF_CUTEXTRA )
result | = FF_OLD_CUTEXTRA ;
if ( fflr - > fofflags & FOF_CUTSPRITES )
result | = FF_OLD_CUTSPRITES ;
if ( fflr - > fofflags & FOF_BOTHPLANES )
result | = FF_OLD_BOTHPLANES ;
if ( fflr - > fofflags & FOF_EXTRA )
result | = FF_OLD_EXTRA ;
if ( fflr - > fofflags & FOF_TRANSLUCENT )
result | = FF_OLD_TRANSLUCENT ;
if ( fflr - > fofflags & FOF_FOG )
result | = FF_OLD_FOG ;
if ( fflr - > fofflags & FOF_INVERTPLANES )
result | = FF_OLD_INVERTPLANES ;
if ( fflr - > fofflags & FOF_ALLSIDES )
result | = FF_OLD_ALLSIDES ;
if ( fflr - > fofflags & FOF_INVERTSIDES )
result | = FF_OLD_INVERTSIDES ;
if ( fflr - > fofflags & FOF_DOUBLESHADOW )
result | = FF_OLD_DOUBLESHADOW ;
if ( fflr - > fofflags & FOF_FLOATBOB )
result | = FF_OLD_FLOATBOB ;
if ( fflr - > fofflags & FOF_NORETURN )
result | = FF_OLD_NORETURN ;
if ( fflr - > fofflags & FOF_CRUMBLE )
result | = FF_OLD_CRUMBLE ;
2022-07-31 11:24:45 +00:00
if ( fflr - > bustflags & FB_ONLYBOTTOM )
2022-07-31 10:04:42 +00:00
result | = FF_OLD_SHATTERBOTTOM ;
if ( fflr - > fofflags & FOF_GOOWATER )
result | = FF_OLD_GOOWATER ;
if ( fflr - > fofflags & FOF_MARIO )
result | = FF_OLD_MARIO ;
if ( fflr - > fofflags & FOF_BUSTUP )
result | = FF_OLD_BUSTUP ;
if ( fflr - > fofflags & FOF_QUICKSAND )
result | = FF_OLD_QUICKSAND ;
if ( fflr - > fofflags & FOF_PLATFORM )
result | = FF_OLD_PLATFORM ;
if ( fflr - > fofflags & FOF_REVERSEPLATFORM )
result | = FF_OLD_REVERSEPLATFORM ;
if ( fflr - > fofflags & FOF_INTANGIBLEFLATS )
result | = FF_OLD_INTANGIBLEFLATS ;
if ( fflr - > busttype = = BT_TOUCH )
result | = FF_OLD_SHATTER ;
if ( fflr - > busttype = = BT_SPINBUST )
result | = FF_OLD_SPINBUST ;
if ( fflr - > busttype = = BT_STRONG )
result | = FF_OLD_STRONGBUST ;
2023-04-10 12:08:53 +00:00
if ( fflr - > fofflags & FOF_RIPPLE )
result | = FF_OLD_RIPPLE ;
if ( fflr - > fofflags & FOF_COLORMAPONLY )
result | = FF_OLD_COLORMAPONLY ;
2022-07-31 10:04:42 +00:00
return result ;
}
2014-08-04 03:49:33 +00:00
static int ffloor_get ( lua_State * L )
{
ffloor_t * ffloor = * ( ( ffloor_t * * ) luaL_checkudata ( L , 1 , META_FFLOOR ) ) ;
2023-06-18 16:05:16 +00:00
enum ffloor_e field = Lua_optoption ( L , 2 , ffloor_valid , ffloor_fields_ref ) ;
2018-12-20 16:47:17 +00:00
INT16 i ;
2014-08-04 03:49:33 +00:00
if ( ! ffloor )
{
if ( field = = ffloor_valid ) {
lua_pushboolean ( L , 0 ) ;
return 1 ;
}
return luaL_error ( L , " accessed ffloor_t doesn't exist anymore. " ) ;
}
switch ( field )
{
case ffloor_valid : // valid
lua_pushboolean ( L , 1 ) ;
return 1 ;
case ffloor_topheight :
2015-05-21 03:54:04 +00:00
lua_pushfixed ( L , * ffloor - > topheight ) ;
2014-08-04 03:49:33 +00:00
return 1 ;
case ffloor_toppic : { // toppic
2018-12-20 16:47:17 +00:00
levelflat_t * levelflat = & levelflats [ * ffloor - > toppic ] ;
for ( i = 0 ; i < 8 ; i + + )
if ( ! levelflat - > name [ i ] )
break ;
lua_pushlstring ( L , levelflat - > name , i ) ;
2014-08-04 03:49:33 +00:00
return 1 ;
}
case ffloor_toplightlevel :
lua_pushinteger ( L , * ffloor - > toplightlevel ) ;
return 1 ;
2023-11-24 11:47:59 +00:00
case ffloor_topxoffs :
lua_pushfixed ( L , * ffloor - > topxoffs ) ;
return 1 ;
case ffloor_topyoffs :
lua_pushfixed ( L , * ffloor - > topyoffs ) ;
return 1 ;
case ffloor_topxscale :
lua_pushfixed ( L , * ffloor - > topxscale ) ;
return 1 ;
case ffloor_topyscale :
lua_pushfixed ( L , * ffloor - > topyscale ) ;
return 1 ;
2014-08-04 03:49:33 +00:00
case ffloor_bottomheight :
2015-05-21 03:54:04 +00:00
lua_pushfixed ( L , * ffloor - > bottomheight ) ;
2014-08-04 03:49:33 +00:00
return 1 ;
case ffloor_bottompic : { // bottompic
2018-12-20 16:47:17 +00:00
levelflat_t * levelflat = & levelflats [ * ffloor - > bottompic ] ;
for ( i = 0 ; i < 8 ; i + + )
if ( ! levelflat - > name [ i ] )
break ;
lua_pushlstring ( L , levelflat - > name , i ) ;
2014-08-04 03:49:33 +00:00
return 1 ;
}
2023-11-24 11:47:59 +00:00
case ffloor_bottomxoffs :
lua_pushfixed ( L , * ffloor - > bottomxoffs ) ;
return 1 ;
case ffloor_bottomyoffs :
lua_pushfixed ( L , * ffloor - > bottomyoffs ) ;
return 1 ;
case ffloor_bottomxscale :
lua_pushfixed ( L , * ffloor - > bottomxscale ) ;
return 1 ;
case ffloor_bottomyscale :
lua_pushfixed ( L , * ffloor - > bottomyscale ) ;
return 1 ;
2016-03-03 05:47:06 +00:00
case ffloor_tslope :
LUA_PushUserdata ( L , * ffloor - > t_slope , META_SLOPE ) ;
return 1 ;
case ffloor_bslope :
LUA_PushUserdata ( L , * ffloor - > b_slope , META_SLOPE ) ;
return 1 ;
2014-08-04 03:49:33 +00:00
case ffloor_sector :
LUA_PushUserdata ( L , & sectors [ ffloor - > secnum ] , META_SECTOR ) ;
return 1 ;
2022-07-31 10:04:42 +00:00
case ffloor_fofflags :
lua_pushinteger ( L , ffloor - > fofflags ) ;
return 1 ;
2014-08-04 03:49:33 +00:00
case ffloor_flags :
2022-07-31 10:04:42 +00:00
lua_pushinteger ( L , P_GetOldFOFFlags ( ffloor ) ) ;
2014-08-04 03:49:33 +00:00
return 1 ;
case ffloor_master :
LUA_PushUserdata ( L , ffloor - > master , META_LINE ) ;
return 1 ;
case ffloor_target :
LUA_PushUserdata ( L , ffloor - > target , META_SECTOR ) ;
return 1 ;
case ffloor_next :
LUA_PushUserdata ( L , ffloor - > next , META_FFLOOR ) ;
return 1 ;
case ffloor_prev :
LUA_PushUserdata ( L , ffloor - > prev , META_FFLOOR ) ;
return 1 ;
case ffloor_alpha :
lua_pushinteger ( L , ffloor - > alpha ) ;
return 1 ;
2022-01-14 20:16:23 +00:00
case ffloor_blend :
lua_pushinteger ( L , ffloor - > blend ) ;
return 1 ;
2021-12-03 17:48:16 +00:00
case ffloor_bustflags :
lua_pushinteger ( L , ffloor - > bustflags ) ;
2020-05-03 10:44:30 +00:00
return 1 ;
2020-05-02 19:19:55 +00:00
case ffloor_busttype :
lua_pushinteger ( L , ffloor - > busttype ) ;
return 1 ;
case ffloor_busttag :
lua_pushinteger ( L , ffloor - > busttag ) ;
return 1 ;
2020-05-02 20:07:42 +00:00
case ffloor_sinkspeed :
lua_pushfixed ( L , ffloor - > sinkspeed ) ;
return 1 ;
case ffloor_friction :
lua_pushfixed ( L , ffloor - > friction ) ;
return 1 ;
2020-05-03 10:44:30 +00:00
case ffloor_bouncestrength :
lua_pushfixed ( L , ffloor - > bouncestrength ) ;
return 1 ;
2014-08-04 03:49:33 +00:00
}
return 0 ;
}
2022-07-31 10:04:42 +00:00
static void P_SetOldFOFFlags ( ffloor_t * fflr , oldffloortype_e oldflags )
{
ffloortype_e originalflags = fflr - > fofflags ;
fflr - > fofflags = 0 ;
if ( oldflags & FF_OLD_EXISTS )
fflr - > fofflags | = FOF_EXISTS ;
if ( oldflags & FF_OLD_BLOCKPLAYER )
fflr - > fofflags | = FOF_BLOCKPLAYER ;
if ( oldflags & FF_OLD_BLOCKOTHERS )
fflr - > fofflags | = FOF_BLOCKOTHERS ;
if ( oldflags & FF_OLD_RENDERSIDES )
fflr - > fofflags | = FOF_RENDERSIDES ;
if ( oldflags & FF_OLD_RENDERPLANES )
fflr - > fofflags | = FOF_RENDERPLANES ;
if ( oldflags & FF_OLD_SWIMMABLE )
fflr - > fofflags | = FOF_SWIMMABLE ;
if ( oldflags & FF_OLD_NOSHADE )
fflr - > fofflags | = FOF_NOSHADE ;
if ( oldflags & FF_OLD_CUTSOLIDS )
fflr - > fofflags | = FOF_CUTSOLIDS ;
if ( oldflags & FF_OLD_CUTEXTRA )
fflr - > fofflags | = FOF_CUTEXTRA ;
if ( oldflags & FF_OLD_CUTSPRITES )
fflr - > fofflags | = FOF_CUTSPRITES ;
if ( oldflags & FF_OLD_BOTHPLANES )
fflr - > fofflags | = FOF_BOTHPLANES ;
if ( oldflags & FF_OLD_EXTRA )
fflr - > fofflags | = FOF_EXTRA ;
if ( oldflags & FF_OLD_TRANSLUCENT )
fflr - > fofflags | = FOF_TRANSLUCENT ;
if ( oldflags & FF_OLD_FOG )
fflr - > fofflags | = FOF_FOG ;
if ( oldflags & FF_OLD_INVERTPLANES )
fflr - > fofflags | = FOF_INVERTPLANES ;
if ( oldflags & FF_OLD_ALLSIDES )
fflr - > fofflags | = FOF_ALLSIDES ;
if ( oldflags & FF_OLD_INVERTSIDES )
fflr - > fofflags | = FOF_INVERTSIDES ;
if ( oldflags & FF_OLD_DOUBLESHADOW )
fflr - > fofflags | = FOF_DOUBLESHADOW ;
if ( oldflags & FF_OLD_FLOATBOB )
fflr - > fofflags | = FOF_FLOATBOB ;
if ( oldflags & FF_OLD_NORETURN )
fflr - > fofflags | = FOF_NORETURN ;
if ( oldflags & FF_OLD_CRUMBLE )
fflr - > fofflags | = FOF_CRUMBLE ;
if ( oldflags & FF_OLD_GOOWATER )
fflr - > fofflags | = FOF_GOOWATER ;
if ( oldflags & FF_OLD_MARIO )
fflr - > fofflags | = FOF_MARIO ;
if ( oldflags & FF_OLD_BUSTUP )
fflr - > fofflags | = FOF_BUSTUP ;
if ( oldflags & FF_OLD_QUICKSAND )
fflr - > fofflags | = FOF_QUICKSAND ;
if ( oldflags & FF_OLD_PLATFORM )
fflr - > fofflags | = FOF_PLATFORM ;
if ( oldflags & FF_OLD_REVERSEPLATFORM )
fflr - > fofflags | = FOF_REVERSEPLATFORM ;
if ( oldflags & FF_OLD_RIPPLE )
fflr - > fofflags | = FOF_RIPPLE ;
if ( oldflags & FF_OLD_COLORMAPONLY )
fflr - > fofflags | = FOF_COLORMAPONLY ;
if ( originalflags & FOF_BOUNCY )
fflr - > fofflags | = FOF_BOUNCY ;
if ( originalflags & FOF_SPLAT )
fflr - > fofflags | = FOF_SPLAT ;
if ( oldflags & FF_OLD_SHATTER )
fflr - > busttype = BT_TOUCH ;
else if ( oldflags & FF_OLD_SPINBUST )
fflr - > busttype = BT_SPINBUST ;
else if ( oldflags & FF_OLD_STRONGBUST )
fflr - > busttype = BT_STRONG ;
else
fflr - > busttype = BT_REGULAR ;
if ( oldflags & FF_OLD_SHATTERBOTTOM )
2022-07-31 11:24:45 +00:00
fflr - > bustflags | = FB_ONLYBOTTOM ;
2022-07-31 10:04:42 +00:00
else
2022-07-31 11:24:45 +00:00
fflr - > bustflags & = ~ FB_ONLYBOTTOM ;
2022-07-31 10:04:42 +00:00
}
2014-08-04 03:49:33 +00:00
static int ffloor_set ( lua_State * L )
{
ffloor_t * ffloor = * ( ( ffloor_t * * ) luaL_checkudata ( L , 1 , META_FFLOOR ) ) ;
2023-06-18 16:05:16 +00:00
enum ffloor_e field = Lua_optoption ( L , 2 , ffloor_valid , ffloor_fields_ref ) ;
2014-08-04 03:49:33 +00:00
if ( ! ffloor )
return luaL_error ( L , " accessed ffloor_t doesn't exist anymore. " ) ;
if ( hud_running )
return luaL_error ( L , " Do not alter ffloor_t in HUD rendering code! " ) ;
2020-07-17 05:08:38 +00:00
if ( hook_cmd_running )
return luaL_error ( L , " Do not alter ffloor_t in CMD building code! " ) ;
2014-08-04 03:49:33 +00:00
switch ( field )
{
case ffloor_valid : // valid
2016-03-03 05:47:06 +00:00
case ffloor_tslope : // t_slope
case ffloor_bslope : // b_slope
2014-08-04 03:49:33 +00:00
case ffloor_sector : // sector
case ffloor_master : // master
case ffloor_target : // target
case ffloor_next : // next
case ffloor_prev : // prev
return luaL_error ( L , " ffloor_t field " LUA_QS " cannot be set. " , ffloor_opt [ field ] ) ;
2023-08-31 18:02:59 +00:00
default :
return luaL_error ( L , " ffloor_t has no field named " LUA_QS " . " , lua_tostring ( L , 2 ) ) ;
2014-08-04 03:49:33 +00:00
case ffloor_topheight : { // topheight
boolean flag ;
fixed_t lastpos = * ffloor - > topheight ;
2015-05-22 05:51:40 +00:00
mobj_t * ptmthing = tmthing ;
2014-08-04 03:49:33 +00:00
sector_t * sector = & sectors [ ffloor - > secnum ] ;
2015-05-21 03:54:04 +00:00
sector - > ceilingheight = luaL_checkfixed ( L , 3 ) ;
2014-08-04 03:49:33 +00:00
flag = P_CheckSector ( sector , true ) ;
if ( flag & & sector - > numattached )
{
* ffloor - > topheight = lastpos ;
P_CheckSector ( sector , true ) ;
}
2015-05-22 05:51:40 +00:00
P_SetTarget ( & tmthing , ptmthing ) ;
2014-08-04 03:49:33 +00:00
break ;
}
case ffloor_toppic :
* ffloor - > toppic = P_AddLevelFlatRuntime ( luaL_checkstring ( L , 3 ) ) ;
break ;
case ffloor_toplightlevel :
* ffloor - > toplightlevel = ( INT16 ) luaL_checkinteger ( L , 3 ) ;
break ;
2023-11-24 11:47:59 +00:00
case ffloor_topxoffs :
* ffloor - > topxoffs = luaL_checkfixed ( L , 3 ) ;
break ;
case ffloor_topyoffs :
* ffloor - > topyoffs = luaL_checkfixed ( L , 3 ) ;
break ;
case ffloor_topxscale :
* ffloor - > topxscale = luaL_checkfixed ( L , 3 ) ;
break ;
case ffloor_topyscale :
* ffloor - > topyscale = luaL_checkfixed ( L , 3 ) ;
break ;
2014-08-04 03:49:33 +00:00
case ffloor_bottomheight : { // bottomheight
boolean flag ;
fixed_t lastpos = * ffloor - > bottomheight ;
2015-05-22 05:51:40 +00:00
mobj_t * ptmthing = tmthing ;
2014-08-04 03:49:33 +00:00
sector_t * sector = & sectors [ ffloor - > secnum ] ;
2015-05-21 03:54:04 +00:00
sector - > floorheight = luaL_checkfixed ( L , 3 ) ;
2014-08-04 03:49:33 +00:00
flag = P_CheckSector ( sector , true ) ;
if ( flag & & sector - > numattached )
{
* ffloor - > bottomheight = lastpos ;
P_CheckSector ( sector , true ) ;
}
2015-05-22 05:51:40 +00:00
P_SetTarget ( & tmthing , ptmthing ) ;
2014-08-04 03:49:33 +00:00
break ;
}
case ffloor_bottompic :
* ffloor - > bottompic = P_AddLevelFlatRuntime ( luaL_checkstring ( L , 3 ) ) ;
break ;
2023-11-24 11:47:59 +00:00
case ffloor_bottomxoffs :
* ffloor - > bottomxoffs = luaL_checkfixed ( L , 3 ) ;
break ;
case ffloor_bottomyoffs :
* ffloor - > bottomyoffs = luaL_checkfixed ( L , 3 ) ;
break ;
case ffloor_bottomxscale :
* ffloor - > bottomxscale = luaL_checkfixed ( L , 3 ) ;
break ;
case ffloor_bottomyscale :
* ffloor - > bottomyscale = luaL_checkfixed ( L , 3 ) ;
break ;
2022-07-31 10:04:42 +00:00
case ffloor_fofflags : {
ffloortype_e oldflags = ffloor - > fofflags ; // store FOF's old flags
ffloor - > fofflags = luaL_checkinteger ( L , 3 ) ;
if ( ffloor - > fofflags ! = oldflags )
ffloor - > target - > moved = true ; // reset target sector's lightlist
break ;
}
2016-02-26 18:11:12 +00:00
case ffloor_flags : {
2022-07-31 10:04:42 +00:00
ffloortype_e oldflags = ffloor - > fofflags ; // store FOF's old flags
busttype_e oldbusttype = ffloor - > busttype ;
ffloorbustflags_e oldbustflags = ffloor - > bustflags ;
oldffloortype_e newflags = luaL_checkinteger ( L , 3 ) ;
P_SetOldFOFFlags ( ffloor , newflags ) ;
if ( ffloor - > fofflags ! = oldflags | | ffloor - > busttype ! = oldbusttype | | ffloor - > bustflags ! = oldbustflags )
2016-02-26 18:11:12 +00:00
ffloor - > target - > moved = true ; // reset target sector's lightlist
2014-08-04 03:49:33 +00:00
break ;
2016-02-26 18:11:12 +00:00
}
2014-08-04 03:49:33 +00:00
case ffloor_alpha :
ffloor - > alpha = ( INT32 ) luaL_checkinteger ( L , 3 ) ;
break ;
2021-11-19 18:01:41 +00:00
case ffloor_blend :
ffloor - > blend = ( INT32 ) luaL_checkinteger ( L , 3 ) ;
break ;
2014-08-04 03:49:33 +00:00
}
return 0 ;
}
2018-11-10 15:47:04 +00:00
//////////////
// pslope_t //
//////////////
2016-03-03 05:47:06 +00:00
static int slope_get ( lua_State * L )
{
pslope_t * slope = * ( ( pslope_t * * ) luaL_checkudata ( L , 1 , META_SLOPE ) ) ;
2023-06-18 16:05:16 +00:00
enum slope_e field = Lua_optoption ( L , 2 , slope_valid , slope_fields_ref ) ;
2016-03-03 05:47:06 +00:00
if ( ! slope )
{
if ( field = = slope_valid ) {
lua_pushboolean ( L , 0 ) ;
return 1 ;
}
return luaL_error ( L , " accessed pslope_t doesn't exist anymore. " ) ;
}
switch ( field )
{
case slope_valid : // valid
lua_pushboolean ( L , 1 ) ;
return 1 ;
case slope_o : // o
2018-10-20 18:00:37 +00:00
LUA_PushUserdata ( L , & slope - > o , META_VECTOR3 ) ;
2016-03-03 05:47:06 +00:00
return 1 ;
case slope_d : // d
2018-10-20 18:00:37 +00:00
LUA_PushUserdata ( L , & slope - > d , META_VECTOR2 ) ;
2016-03-03 05:47:06 +00:00
return 1 ;
case slope_zdelta : // zdelta
lua_pushfixed ( L , slope - > zdelta ) ;
return 1 ;
case slope_normal : // normal
2018-10-20 18:00:37 +00:00
LUA_PushUserdata ( L , & slope - > normal , META_VECTOR3 ) ;
2016-03-03 05:47:06 +00:00
return 1 ;
case slope_zangle : // zangle
lua_pushangle ( L , slope - > zangle ) ;
return 1 ;
case slope_xydirection : // xydirection
lua_pushangle ( L , slope - > xydirection ) ;
return 1 ;
case slope_flags : // flags
lua_pushinteger ( L , slope - > flags ) ;
return 1 ;
}
return 0 ;
}
static int slope_set ( lua_State * L )
{
pslope_t * slope = * ( ( pslope_t * * ) luaL_checkudata ( L , 1 , META_SLOPE ) ) ;
2023-06-18 16:05:16 +00:00
enum slope_e field = Lua_optoption ( L , 2 , slope_valid , slope_fields_ref ) ;
2016-03-03 05:47:06 +00:00
if ( ! slope )
return luaL_error ( L , " accessed pslope_t doesn't exist anymore. " ) ;
if ( hud_running )
return luaL_error ( L , " Do not alter pslope_t in HUD rendering code! " ) ;
2020-07-17 05:08:38 +00:00
if ( hook_cmd_running )
return luaL_error ( L , " Do not alter pslope_t in CMD building code! " ) ;
2016-03-03 05:47:06 +00:00
switch ( field ) // todo: reorganize this shit
{
case slope_valid : // valid
case slope_d : // d
case slope_flags : // flags
case slope_normal : // normal
return luaL_error ( L , " pslope_t field " LUA_QS " cannot be set. " , slope_opt [ field ] ) ;
2023-08-31 18:02:59 +00:00
default :
return luaL_error ( L , " pslope_t has no field named " LUA_QS " . " , lua_tostring ( L , 2 ) ) ;
2016-03-03 05:47:06 +00:00
case slope_o : { // o
luaL_checktype ( L , 3 , LUA_TTABLE ) ;
lua_getfield ( L , 3 , " x " ) ;
if ( lua_isnil ( L , - 1 ) )
{
lua_pop ( L , 1 ) ;
lua_rawgeti ( L , 3 , 1 ) ;
}
if ( ! lua_isnil ( L , - 1 ) )
slope - > o . x = luaL_checkfixed ( L , - 1 ) ;
else
slope - > o . x = 0 ;
lua_pop ( L , 1 ) ;
lua_getfield ( L , 3 , " y " ) ;
if ( lua_isnil ( L , - 1 ) )
{
lua_pop ( L , 1 ) ;
lua_rawgeti ( L , 3 , 2 ) ;
}
if ( ! lua_isnil ( L , - 1 ) )
slope - > o . y = luaL_checkfixed ( L , - 1 ) ;
else
slope - > o . y = 0 ;
lua_pop ( L , 1 ) ;
lua_getfield ( L , 3 , " z " ) ;
if ( lua_isnil ( L , - 1 ) )
{
lua_pop ( L , 1 ) ;
lua_rawgeti ( L , 3 , 3 ) ;
}
if ( ! lua_isnil ( L , - 1 ) )
slope - > o . z = luaL_checkfixed ( L , - 1 ) ;
else
slope - > o . z = 0 ;
2024-01-30 02:55:12 +00:00
DVector3_Load ( & slope - > dorigin ,
FixedToDouble ( slope - > o . x ) ,
FixedToDouble ( slope - > o . y ) ,
FixedToDouble ( slope - > o . z )
) ;
2016-03-03 05:47:06 +00:00
lua_pop ( L , 1 ) ;
break ;
}
2024-01-30 01:08:22 +00:00
case slope_zdelta : { // zdelta
2016-03-03 05:47:06 +00:00
slope - > zdelta = luaL_checkfixed ( L , 3 ) ;
2018-10-21 16:32:53 +00:00
slope - > zangle = R_PointToAngle2 ( 0 , 0 , FRACUNIT , - slope - > zdelta ) ;
2024-01-30 01:08:22 +00:00
slope - > dzdelta = FixedToDouble ( slope - > zdelta ) ;
2016-03-03 05:47:06 +00:00
P_CalculateSlopeNormal ( slope ) ;
break ;
}
2018-10-21 16:32:53 +00:00
case slope_zangle : { // zangle
angle_t zangle = luaL_checkangle ( L , 3 ) ;
if ( zangle = = ANGLE_90 | | zangle = = ANGLE_270 )
return luaL_error ( L , " invalid zangle for slope! " ) ;
slope - > zangle = zangle ;
slope - > zdelta = - FINETANGENT ( ( ( slope - > zangle + ANGLE_90 ) > > ANGLETOFINESHIFT ) & 4095 ) ;
2024-01-30 01:08:22 +00:00
slope - > dzdelta = FixedToDouble ( slope - > zdelta ) ;
2016-03-03 05:47:06 +00:00
P_CalculateSlopeNormal ( slope ) ;
break ;
2018-10-21 16:32:53 +00:00
}
2016-03-03 05:47:06 +00:00
case slope_xydirection : // xydirection
slope - > xydirection = luaL_checkangle ( L , 3 ) ;
2018-10-21 17:25:13 +00:00
slope - > d . x = - FINECOSINE ( ( slope - > xydirection > > ANGLETOFINESHIFT ) & FINEMASK ) ;
slope - > d . y = - FINESINE ( ( slope - > xydirection > > ANGLETOFINESHIFT ) & FINEMASK ) ;
2024-01-30 01:08:22 +00:00
slope - > dnormdir . x = FixedToDouble ( slope - > d . x ) ;
slope - > dnormdir . y = FixedToDouble ( slope - > d . y ) ;
2016-03-03 05:47:06 +00:00
P_CalculateSlopeNormal ( slope ) ;
break ;
}
return 0 ;
}
2018-11-10 15:47:04 +00:00
///////////////
// vector*_t //
///////////////
2018-10-20 18:00:37 +00:00
static int vector2_get ( lua_State * L )
{
vector2_t * vec = * ( ( vector2_t * * ) luaL_checkudata ( L , 1 , META_VECTOR2 ) ) ;
enum vector_e field = luaL_checkoption ( L , 2 , vector_opt [ 0 ] , vector_opt ) ;
if ( ! vec )
return luaL_error ( L , " accessed vector2_t doesn't exist anymore. " ) ;
switch ( field )
{
case vector_x : lua_pushfixed ( L , vec - > x ) ; return 1 ;
case vector_y : lua_pushfixed ( L , vec - > y ) ; return 1 ;
default : break ;
}
return 0 ;
}
static int vector3_get ( lua_State * L )
{
vector3_t * vec = * ( ( vector3_t * * ) luaL_checkudata ( L , 1 , META_VECTOR3 ) ) ;
enum vector_e field = luaL_checkoption ( L , 2 , vector_opt [ 0 ] , vector_opt ) ;
if ( ! vec )
return luaL_error ( L , " accessed vector3_t doesn't exist anymore. " ) ;
switch ( field )
{
case vector_x : lua_pushfixed ( L , vec - > x ) ; return 1 ;
case vector_y : lua_pushfixed ( L , vec - > y ) ; return 1 ;
case vector_z : lua_pushfixed ( L , vec - > z ) ; return 1 ;
default : break ;
}
return 0 ;
}
2017-01-18 22:02:28 +00:00
/////////////////////
// mapheaderinfo[] //
/////////////////////
2014-08-04 03:49:33 +00:00
static int lib_getMapheaderinfo ( lua_State * L )
{
// i -> mapheaderinfo[i-1]
//int field;
lua_settop ( L , 2 ) ;
lua_remove ( L , 1 ) ; // dummy userdata table is unused.
if ( lua_isnumber ( L , 1 ) )
{
size_t i = lua_tointeger ( L , 1 ) - 1 ;
if ( i > = NUMMAPS )
return 0 ;
LUA_PushUserdata ( L , mapheaderinfo [ i ] , META_MAPHEADER ) ;
//CONS_Printf(mapheaderinfo[i]->lvlttl);
return 1 ;
} /*
field = luaL_checkoption ( L , 1 , NULL , array_opt ) ;
switch ( field )
{
case 0 : // iterate
lua_pushcfunction ( L , lib_iterateSubsectors ) ;
return 1 ;
} */
return 0 ;
}
static int lib_nummapheaders ( lua_State * L )
{
lua_pushinteger ( L , NUMMAPS ) ;
return 1 ;
}
2017-01-18 22:02:28 +00:00
/////////////////
// mapheader_t //
/////////////////
2023-06-18 16:05:16 +00:00
enum mapheaderinfo_e
{
mapheaderinfo_lvlttl ,
mapheaderinfo_subttl ,
mapheaderinfo_actnum ,
mapheaderinfo_typeoflevel ,
mapheaderinfo_nextlevel ,
mapheaderinfo_marathonnext ,
mapheaderinfo_keywords ,
mapheaderinfo_musname ,
mapheaderinfo_mustrack ,
mapheaderinfo_muspos ,
mapheaderinfo_musinterfadeout ,
mapheaderinfo_musintername ,
mapheaderinfo_muspostbossname ,
mapheaderinfo_muspostbosstrack ,
mapheaderinfo_muspostbosspos ,
mapheaderinfo_muspostbossfadein ,
mapheaderinfo_musforcereset ,
mapheaderinfo_forcecharacter ,
mapheaderinfo_weather ,
mapheaderinfo_skynum ,
mapheaderinfo_skybox_scalex ,
mapheaderinfo_skybox_scaley ,
mapheaderinfo_skybox_scalez ,
mapheaderinfo_interscreen ,
mapheaderinfo_runsoc ,
mapheaderinfo_scriptname ,
mapheaderinfo_precutscenenum ,
mapheaderinfo_cutscenenum ,
mapheaderinfo_countdown ,
mapheaderinfo_palette ,
mapheaderinfo_numlaps ,
mapheaderinfo_unlockrequired ,
mapheaderinfo_levelselect ,
mapheaderinfo_bonustype ,
mapheaderinfo_ltzzpatch ,
mapheaderinfo_ltzztext ,
mapheaderinfo_ltactdiamond ,
mapheaderinfo_maxbonuslives ,
mapheaderinfo_levelflags ,
mapheaderinfo_menuflags ,
mapheaderinfo_selectheading ,
mapheaderinfo_startrings ,
mapheaderinfo_sstimer ,
mapheaderinfo_ssspheres ,
mapheaderinfo_gravity ,
} ;
static const char * const mapheaderinfo_opt [ ] = {
" lvlttl " ,
" subttl " ,
" actnum " ,
" typeoflevel " ,
" nextlevel " ,
" marathonnext " ,
" keywords " ,
" musname " ,
" mustrack " ,
" muspos " ,
" musinterfadeout " ,
" musintername " ,
" muspostbossname " ,
" muspostbosstrack " ,
" muspostbosspos " ,
" muspostbossfadein " ,
" musforcereset " ,
" forcecharacter " ,
" weather " ,
" skynum " ,
" skybox_scalex " ,
" skybox_scaley " ,
" skybox_scalez " ,
" interscreen " ,
" runsoc " ,
" scriptname " ,
" precutscenenum " ,
" cutscenenum " ,
" countdown " ,
" palette " ,
" numlaps " ,
" unlockrequired " ,
" levelselect " ,
" bonustype " ,
" ltzzpatch " ,
" ltzztext " ,
" ltactdiamond " ,
" maxbonuslives " ,
" levelflags " ,
" menuflags " ,
" selectheading " ,
" startrings " ,
" sstimer " ,
" ssspheres " ,
" gravity " ,
NULL ,
} ;
static int mapheaderinfo_fields_ref = LUA_NOREF ;
2014-08-04 03:49:33 +00:00
static int mapheaderinfo_get ( lua_State * L )
{
mapheader_t * header = * ( ( mapheader_t * * ) luaL_checkudata ( L , 1 , META_MAPHEADER ) ) ;
2023-06-18 16:05:16 +00:00
enum mapheaderinfo_e field = Lua_optoption ( L , 2 , - 1 , mapheaderinfo_fields_ref ) ;
2016-01-20 17:42:35 +00:00
INT16 i ;
2023-06-18 16:05:16 +00:00
switch ( field )
{
case mapheaderinfo_lvlttl :
2016-01-20 17:25:28 +00:00
lua_pushstring ( L , header - > lvlttl ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_subttl :
2016-01-20 17:25:28 +00:00
lua_pushstring ( L , header - > subttl ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_actnum :
2014-08-04 03:49:33 +00:00
lua_pushinteger ( L , header - > actnum ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_typeoflevel :
2014-08-04 03:49:33 +00:00
lua_pushinteger ( L , header - > typeoflevel ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_nextlevel :
2014-08-04 03:49:33 +00:00
lua_pushinteger ( L , header - > nextlevel ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_marathonnext :
Introducing Marathon Run. (I was going to call it Marathon Mode, but NiGHTS Mode being right next to it on the menu looked terrible.)
Basically a dedicated Record Attack-like experience for speedrunning the game as a continuous chunk rather than ILs. Has several quality of life features.
Benefits include:
* An unambiguous real-time bar across the bottom of the screen, always displaying the current time, ticking up until you reach the ending.
* Disable the console (pausing is still allowed, but the timer will still increment).
* Automatically skip intermissions as if you're holding down the spin button.
* Show centiseconds on HUD automatically, like record attack.
* "Live Event Backups" - a category of run fit for major events like GDQ, where recovery from crashes or chokes makes for better entertainment. Essentially a modified SP savefile, down to using the same basic functions, but has its own filename and tweaked internal layout.
* "spmarathon_start" MainCfg block parameter and "marathonnext" mapheader parameter, allowing for a customised flow (makes this fit for purpose for an eventual SUGOI port).
* Disabling inter-level custom cutscenes by default with a menu option to toggle this (won't show up if the mod doesn't *have* any custom cutscenes), although either way ending cutscenes (vanilla or custom) remain intact since is time is called before them.
* Won't show up if you have a mod that consists of only one level (determined by spmarathon_start's nextlevel; this won't trip if you manually set its marathonnext).
* Unconditional gratitude on the evaluation screen, instead of a negging "Try again..." if you didn't get all the emeralds (which you may not have been aiming for).
* Gorgeous new menu (no new assets required, unless you wanna give it a header later).
Changes which were required for the above but affect other areas of the game include:
* "useBlackRock" MainCFG block parameter, which can be used to disable the presence of the Black Rock or Egg Rock in both the Evaluation screen and the Marathon Run menu (for total conversions with different stories).
* Disabling Continues in NiGHTS mode, to match the most common singleplayer experience post 2.2.4's release (is reverted if useContinues is set to true).
* Hiding the exitmove "powerup" outside of multiplayer. (Okay, this isn't really related, I just saw this bug in action a lot while doing test runs and got annoyed enough to fix it here.)
* The ability to use V_DrawPromptBack (in hardcode only at the moment, but) to draw in terms of pixels rather than rows of text, by providing negative instead of positive inputs).
* A refactoring of redundant game saves smattered across the ending, credits, and evaluation - in addition to saving the game slightly earlier.
* Minor m_menu.c touchups and refactorings here and there.
Built using feedback from the official server's #speedruns channel, among other places.
2020-05-14 22:10:00 +00:00
lua_pushinteger ( L , header - > marathonnext ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_keywords :
2020-01-08 22:41:38 +00:00
lua_pushstring ( L , header - > keywords ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_musname :
2016-03-03 11:09:35 +00:00
lua_pushstring ( L , header - > musname ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_mustrack :
2016-01-08 03:48:20 +00:00
lua_pushinteger ( L , header - > mustrack ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_muspos :
2018-09-18 14:22:17 +00:00
lua_pushinteger ( L , header - > muspos ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_musinterfadeout :
2019-03-15 05:00:50 +00:00
lua_pushinteger ( L , header - > musinterfadeout ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_musintername :
2018-10-21 18:51:49 +00:00
lua_pushstring ( L , header - > musintername ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_muspostbossname :
2019-08-04 11:03:57 +00:00
lua_pushstring ( L , header - > muspostbossname ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_muspostbosstrack :
2019-08-04 11:03:57 +00:00
lua_pushinteger ( L , header - > muspostbosstrack ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_muspostbosspos :
2019-08-04 11:03:57 +00:00
lua_pushinteger ( L , header - > muspostbosspos ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_muspostbossfadein :
2019-08-04 11:03:57 +00:00
lua_pushinteger ( L , header - > muspostbossfadein ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_musforcereset :
2019-08-05 00:02:38 +00:00
lua_pushinteger ( L , header - > musforcereset ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_forcecharacter :
2016-01-20 17:25:28 +00:00
lua_pushstring ( L , header - > forcecharacter ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_weather :
2014-08-04 03:49:33 +00:00
lua_pushinteger ( L , header - > weather ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_skynum :
2014-08-04 03:49:33 +00:00
lua_pushinteger ( L , header - > skynum ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_skybox_scalex :
2014-08-04 03:49:33 +00:00
lua_pushinteger ( L , header - > skybox_scalex ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_skybox_scaley :
2014-08-04 03:49:33 +00:00
lua_pushinteger ( L , header - > skybox_scaley ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_skybox_scalez :
2014-08-04 03:49:33 +00:00
lua_pushinteger ( L , header - > skybox_scalez ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_interscreen :
2016-01-20 17:42:35 +00:00
for ( i = 0 ; i < 8 ; i + + )
if ( ! header - > interscreen [ i ] )
break ;
lua_pushlstring ( L , header - > interscreen , i ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_runsoc :
2016-01-20 17:25:28 +00:00
lua_pushstring ( L , header - > runsoc ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_scriptname :
2016-01-20 17:25:28 +00:00
lua_pushstring ( L , header - > scriptname ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_precutscenenum :
2014-08-04 03:49:33 +00:00
lua_pushinteger ( L , header - > precutscenenum ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_cutscenenum :
2014-08-04 03:49:33 +00:00
lua_pushinteger ( L , header - > cutscenenum ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_countdown :
2014-08-04 03:49:33 +00:00
lua_pushinteger ( L , header - > countdown ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_palette :
2014-08-04 03:49:33 +00:00
lua_pushinteger ( L , header - > palette ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_numlaps :
2014-08-04 03:49:33 +00:00
lua_pushinteger ( L , header - > numlaps ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_unlockrequired :
2014-08-04 03:49:33 +00:00
lua_pushinteger ( L , header - > unlockrequired ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_levelselect :
2014-08-04 03:49:33 +00:00
lua_pushinteger ( L , header - > levelselect ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_bonustype :
2014-08-04 03:49:33 +00:00
lua_pushinteger ( L , header - > bonustype ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_ltzzpatch :
2019-12-18 03:28:58 +00:00
lua_pushstring ( L , header - > ltzzpatch ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_ltzztext :
2019-12-18 03:28:58 +00:00
lua_pushstring ( L , header - > ltzztext ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_ltactdiamond :
2019-12-18 03:28:58 +00:00
lua_pushstring ( L , header - > ltactdiamond ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_maxbonuslives :
2018-08-13 18:16:33 +00:00
lua_pushinteger ( L , header - > maxbonuslives ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_levelflags :
2014-08-04 03:49:33 +00:00
lua_pushinteger ( L , header - > levelflags ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_menuflags :
2014-08-04 03:49:33 +00:00
lua_pushinteger ( L , header - > menuflags ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_selectheading :
2020-11-25 02:41:11 +00:00
lua_pushstring ( L , header - > selectheading ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_startrings :
2019-06-23 22:51:42 +00:00
lua_pushinteger ( L , header - > startrings ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_sstimer :
2020-05-03 15:56:49 +00:00
lua_pushinteger ( L , header - > sstimer ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_ssspheres :
2020-05-03 15:56:49 +00:00
lua_pushinteger ( L , header - > ssspheres ) ;
2023-06-18 16:05:16 +00:00
break ;
case mapheaderinfo_gravity :
2020-05-03 16:33:18 +00:00
lua_pushfixed ( L , header - > gravity ) ;
2023-06-18 16:05:16 +00:00
break ;
2014-08-04 03:49:33 +00:00
// TODO add support for reading numGradedMares and grades
2023-06-18 16:05:16 +00:00
default :
2023-07-25 02:44:53 +00:00
{
2014-08-04 03:49:33 +00:00
// Read custom vars now
// (note: don't include the "LUA." in your lua scripts!)
2016-01-21 20:27:35 +00:00
UINT8 j = 0 ;
2023-06-18 16:05:16 +00:00
for ( ; j < header - > numCustomOptions & & ! fastcmp ( lua_tostring ( L , 2 ) , header - > customopts [ j ] . option ) ; + + j ) ;
2014-08-04 03:49:33 +00:00
2016-01-21 20:27:35 +00:00
if ( j < header - > numCustomOptions )
lua_pushstring ( L , header - > customopts [ j ] . value ) ;
2014-08-04 03:49:33 +00:00
else
lua_pushnil ( L ) ;
}
2023-07-25 02:44:53 +00:00
}
2014-08-04 03:49:33 +00:00
return 1 ;
}
2014-03-15 16:59:03 +00:00
int LUA_MapLib ( lua_State * L )
{
2023-10-27 18:17:27 +00:00
LUA_RegisterUserdataMetatable ( L , META_SECTORLINES , sectorlines_get , NULL , sectorlines_num ) ;
LUA_RegisterUserdataMetatable ( L , META_SECTOR , sector_get , sector_set , sector_num ) ;
LUA_RegisterUserdataMetatable ( L , META_SUBSECTOR , subsector_get , NULL , subsector_num ) ;
LUA_RegisterUserdataMetatable ( L , META_LINE , line_get , NULL , line_num ) ;
LUA_RegisterUserdataMetatable ( L , META_LINEARGS , lineargs_get , NULL , lineargs_len ) ;
LUA_RegisterUserdataMetatable ( L , META_LINESTRINGARGS , linestringargs_get , NULL , linestringargs_len ) ;
LUA_RegisterUserdataMetatable ( L , META_SIDENUM , sidenum_get , NULL , NULL ) ;
LUA_RegisterUserdataMetatable ( L , META_SIDE , side_get , side_set , side_num ) ;
LUA_RegisterUserdataMetatable ( L , META_VERTEX , vertex_get , NULL , vertex_num ) ;
LUA_RegisterUserdataMetatable ( L , META_FFLOOR , ffloor_get , ffloor_set , NULL ) ;
LUA_RegisterUserdataMetatable ( L , META_BBOX , bbox_get , NULL , NULL ) ;
LUA_RegisterUserdataMetatable ( L , META_SLOPE , slope_get , slope_set , NULL ) ;
LUA_RegisterUserdataMetatable ( L , META_VECTOR2 , vector2_get , NULL , NULL ) ;
LUA_RegisterUserdataMetatable ( L , META_VECTOR3 , vector3_get , NULL , NULL ) ;
LUA_RegisterUserdataMetatable ( L , META_MAPHEADER , mapheaderinfo_get , NULL , NULL ) ;
2014-03-15 16:59:03 +00:00
2023-06-18 16:05:16 +00:00
sector_fields_ref = Lua_CreateFieldTable ( L , sector_opt ) ;
subsector_fields_ref = Lua_CreateFieldTable ( L , subsector_opt ) ;
line_fields_ref = Lua_CreateFieldTable ( L , line_opt ) ;
side_fields_ref = Lua_CreateFieldTable ( L , side_opt ) ;
vertex_fields_ref = Lua_CreateFieldTable ( L , vertex_opt ) ;
ffloor_fields_ref = Lua_CreateFieldTable ( L , ffloor_opt ) ;
2023-10-27 18:17:27 +00:00
slope_fields_ref = Lua_CreateFieldTable ( L , slope_opt ) ;
mapheaderinfo_fields_ref = Lua_CreateFieldTable ( L , mapheaderinfo_opt ) ;
2023-06-18 16:05:16 +00:00
2023-10-27 22:24:04 +00:00
LUA_RegisterGlobalUserdata ( L , " subsectors " , lib_getSubsector , NULL , lib_numsubsectors ) ;
LUA_RegisterGlobalUserdata ( L , " sides " , lib_getSide , NULL , lib_numsides ) ;
LUA_RegisterGlobalUserdata ( L , " vertexes " , lib_getVertex , NULL , lib_numvertexes ) ;
LUA_RegisterGlobalUserdata ( L , " mapheaderinfo " , lib_getMapheaderinfo , NULL , lib_nummapheaders ) ;
2016-07-08 19:05:54 +00:00
2020-12-04 08:30:08 +00:00
LUA_PushTaggableObjectArray ( L , " sectors " ,
lib_iterateSectors ,
lib_getSector ,
lib_numsectors ,
tags_sectors ,
& numsectors , & sectors ,
sizeof ( sector_t ) , META_SECTOR ) ;
2014-03-15 16:59:03 +00:00
2020-12-04 08:30:08 +00:00
LUA_PushTaggableObjectArray ( L , " lines " ,
lib_iterateLines ,
lib_getLine ,
lib_numlines ,
tags_lines ,
& numlines , & lines ,
sizeof ( line_t ) , META_LINE ) ;
2014-03-15 16:59:03 +00:00
2023-10-27 22:24:04 +00:00
# ifdef HAVE_LUA_SEGS
LUA_RegisterUserdataMetatable ( L , META_SEG , seg_get , NULL , seg_num ) ;
LUA_RegisterUserdataMetatable ( L , META_NODE , node_get , NULL , node_num ) ;
LUA_RegisterUserdataMetatable ( L , META_NODECHILDREN , nodechildren_get , NULL , NULL ) ;
2014-03-15 16:59:03 +00:00
2023-10-27 22:24:04 +00:00
seg_fields_ref = Lua_CreateFieldTable ( L , seg_opt ) ;
node_fields_ref = Lua_CreateFieldTable ( L , node_opt ) ;
2014-03-15 16:59:03 +00:00
2023-10-27 22:24:04 +00:00
luaL_newmetatable ( L , META_NODEBBOX ) ;
2023-10-28 09:06:30 +00:00
//LUA_SetCFunctionField(L, "__index", nodebbox_get);
LUA_SetCFunctionField ( L , " __call " , nodebbox_call ) ;
2023-10-27 22:24:04 +00:00
lua_pop ( L , 1 ) ;
2014-08-04 03:49:33 +00:00
2023-10-27 22:24:04 +00:00
LUA_RegisterGlobalUserdata ( L , " segs " , lib_getSeg , NULL , lib_numsegs ) ;
LUA_RegisterGlobalUserdata ( L , " nodes " , lib_getNode , NULL , lib_numnodes ) ;
2016-11-24 21:11:44 +00:00
# endif
2016-07-08 19:05:54 +00:00
2014-03-15 16:59:03 +00:00
return 0 ;
}