-- CON language definitions local lpeg = require("lpeg") local pairs = pairs local print = print local setmetatable = setmetatable local type = type module(...) MAXVOLUMES = 7 MAXLEVELS = 64 MAXGAMETYPES = 16 MAXSKILLS = 7 MAXEVENTS = 95 -- KEEPINSYNC with EVENT_* list MAXSOUNDS = 4096 MAXSESSIONVARS = 8 -- KEEPINSYNC lunatic_game.c -- KEEPINSYNC quotes.h -- For Lunatic, MAXQUOTES is OBITQUOTEINDEX because starting from that index -- are obituary and suicide quotes which are passed as *format strings* to -- sprintf() in C. REALMAXQUOTES = 16384 MAXQUOTES = REALMAXQUOTES-128 MAXQUOTELEN = 128 local STR = { STR_MAPNAME = 0, STR_MAPFILENAME = 1, STR_PLAYERNAME = 2, STR_VERSION = 3, STR_GAMETYPE = 4, STR_VOLUMENAME = 5, } PROJ = { PROJ_WORKSLIKE = 0, PROJ_SPAWNS = 1, PROJ_SXREPEAT = 2, PROJ_SYREPEAT = 3, PROJ_SOUND = 4, PROJ_ISOUND = 5, PROJ_VEL = 6, PROJ_EXTRA = 7, PROJ_DECAL = 8, PROJ_TRAIL = 9, PROJ_TXREPEAT = 10, PROJ_TYREPEAT = 11, PROJ_TOFFSET = 12, PROJ_TNUM = 13, PROJ_DROP = 14, PROJ_CSTAT = 15, PROJ_CLIPDIST = 16, PROJ_SHADE = 17, PROJ_XREPEAT = 18, PROJ_YREPEAT = 19, PROJ_PAL = 20, PROJ_EXTRA_RAND = 21, PROJ_HITRADIUS = 22, PROJ_VEL_MULT = 23, -- NAME (PROJ_MOVECNT) PROJ_OFFSET = 24, PROJ_BOUNCES = 25, PROJ_BSOUND = 26, PROJ_RANGE = 27, PROJ_FLASH_COLOR = 28, PROJ_USERDATA = 29, } -- TODO: EVENT_INIT currently can't run since we init Lunatic state only afterwards EVENT = { EVENT_INIT = 0, EVENT_ENTERLEVEL = 1, EVENT_RESETWEAPONS = 2, EVENT_RESETINVENTORY = 3, EVENT_HOLSTER = 4, EVENT_LOOKLEFT = 5, EVENT_LOOKRIGHT = 6, EVENT_SOARUP = 7, EVENT_SOARDOWN = 8, EVENT_CROUCH = 9, EVENT_JUMP = 10, EVENT_RETURNTOCENTER = 11, EVENT_LOOKUP = 12, EVENT_LOOKDOWN = 13, EVENT_AIMUP = 14, EVENT_FIRE = 15, EVENT_CHANGEWEAPON = 16, EVENT_GETSHOTRANGE = 17, EVENT_GETAUTOAIMANGLE = 18, EVENT_GETLOADTILE = 19, EVENT_CHEATGETSTEROIDS = 20, EVENT_CHEATGETHEAT = 21, EVENT_CHEATGETBOOT = 22, EVENT_CHEATGETSHIELD = 23, EVENT_CHEATGETSCUBA = 24, EVENT_CHEATGETHOLODUKE = 25, EVENT_CHEATGETJETPACK = 26, EVENT_CHEATGETFIRSTAID = 27, EVENT_QUICKKICK = 28, EVENT_INVENTORY = 29, EVENT_USENIGHTVISION = 30, EVENT_USESTEROIDS = 31, EVENT_INVENTORYLEFT = 32, EVENT_INVENTORYRIGHT = 33, EVENT_HOLODUKEON = 34, EVENT_HOLODUKEOFF = 35, EVENT_USEMEDKIT = 36, EVENT_USEJETPACK = 37, EVENT_TURNAROUND = 38, EVENT_DISPLAYWEAPON = 39, EVENT_FIREWEAPON = 40, EVENT_SELECTWEAPON = 41, EVENT_MOVEFORWARD = 42, EVENT_MOVEBACKWARD = 43, EVENT_TURNLEFT = 44, EVENT_TURNRIGHT = 45, EVENT_STRAFELEFT = 46, EVENT_STRAFERIGHT = 47, EVENT_WEAPKEY1 = 48, EVENT_WEAPKEY2 = 49, EVENT_WEAPKEY3 = 50, EVENT_WEAPKEY4 = 51, EVENT_WEAPKEY5 = 52, EVENT_WEAPKEY6 = 53, EVENT_WEAPKEY7 = 54, EVENT_WEAPKEY8 = 55, EVENT_WEAPKEY9 = 56, EVENT_WEAPKEY10 = 57, EVENT_DRAWWEAPON = 58, EVENT_DISPLAYCROSSHAIR = 59, EVENT_DISPLAYREST = 60, EVENT_DISPLAYSBAR = 61, EVENT_RESETPLAYER = 62, EVENT_INCURDAMAGE = 63, EVENT_AIMDOWN = 64, EVENT_GAME = 65, EVENT_PREVIOUSWEAPON = 66, EVENT_NEXTWEAPON = 67, EVENT_SWIMUP = 68, EVENT_SWIMDOWN = 69, EVENT_GETMENUTILE = 70, EVENT_SPAWN = 71, EVENT_LOGO = 72, EVENT_EGS = 73, EVENT_DOFIRE = 74, EVENT_PRESSEDFIRE = 75, EVENT_USE = 76, EVENT_PROCESSINPUT = 77, EVENT_FAKEDOMOVETHINGS = 78, EVENT_DISPLAYROOMS = 79, EVENT_KILLIT = 80, EVENT_LOADACTOR = 81, EVENT_DISPLAYBONUSSCREEN = 82, EVENT_DISPLAYMENU = 83, EVENT_DISPLAYMENUREST = 84, EVENT_DISPLAYLOADINGSCREEN = 85, EVENT_ANIMATESPRITES = 86, EVENT_NEWGAME = 87, EVENT_SOUND = 88, EVENT_CHECKTOUCHDAMAGE = 89, EVENT_CHECKFLOORDAMAGE = 90, EVENT_LOADGAME = 91, EVENT_SAVEGAME = 92, EVENT_PREGAME = 93, EVENT_CHANGEMENU = 94, -- EVENT_ANIMATEALLSPRITES = 95, -- internal } -- NOTE: negated values are not exported to the ffi.C namespace or CON. -- See TWEAK_SFLAG below. SFLAG = { SFLAG_SHADOW = 0x00000001, SFLAG_NVG = 0x00000002, SFLAG_NOSHADE = 0x00000004, SFLAG_PROJECTILE = -0x00000008, SFLAG_DECAL = -0x00000010, SFLAG_BADGUY = 0x00000020, SFLAG_NOPAL = 0x00000040, SFLAG_NOEVENTS = 0x00000080, -- NAME SFLAG_NOLIGHT = 0x00000100, SFLAG_USEACTIVATOR = 0x00000200, SFLAG_NULL = -0x00000400, SFLAG_NOCLIP = 0x00000800, SFLAG_NOFLOORSHADOW = -0x00001000, SFLAG_SMOOTHMOVE = 0x00002000, SFLAG_NOTELEPORT = 0x00004000, SFLAG_BADGUYSTAYPUT = -0x00008000, SFLAG_CACHE = -0x00010000, SFLAG_ROTFIXED = -0x00020000, SFLAG_HARDCODED_BADGUY = -0x00040000, SFLAG_DIDNOSE7WATER = -0x00080000, -- RESERVED for actor.FLAGS.chain_*/replace_*: -- 0x08000000, 0x10000000, 0x20000000, 0x40000000 } STAT = { STAT_DEFAULT = 0, STAT_ACTOR = 1, STAT_ZOMBIEACTOR = 2, STAT_EFFECTOR = 3, STAT_PROJECTILE = 4, STAT_MISC = 5, STAT_STANDABLE = 6, STAT_LOCATOR = 7, STAT_ACTIVATOR = 8, STAT_TRANSPORT = 9, STAT_PLAYER = 10, STAT_FX = 11, STAT_FALLER = 12, STAT_DUMMYPLAYER = 13, STAT_LIGHT = 14, -- STAT_NETALLOC = 1023, -- MAXSTATUS-1 } local GAMEFUNC = { GAMEFUNC_MOVE_FORWARD = 0, GAMEFUNC_MOVE_BACKWARD = 1, GAMEFUNC_TURN_LEFT = 2, GAMEFUNC_TURN_RIGHT = 3, GAMEFUNC_STRAFE = 4, GAMEFUNC_FIRE = 5, GAMEFUNC_OPEN = 6, GAMEFUNC_RUN = 7, GAMEFUNC_AUTORUN = 8, GAMEFUNC_JUMP = 9, GAMEFUNC_CROUCH = 10, GAMEFUNC_LOOK_UP = 11, GAMEFUNC_LOOK_DOWN = 12, GAMEFUNC_LOOK_LEFT = 13, GAMEFUNC_LOOK_RIGHT = 14, GAMEFUNC_STRAFE_LEFT = 15, GAMEFUNC_STRAFE_RIGHT = 16, GAMEFUNC_AIM_UP = 17, GAMEFUNC_AIM_DOWN = 18, GAMEFUNC_WEAPON_1 = 19, GAMEFUNC_WEAPON_2 = 20, GAMEFUNC_WEAPON_3 = 21, GAMEFUNC_WEAPON_4 = 22, GAMEFUNC_WEAPON_5 = 23, GAMEFUNC_WEAPON_6 = 24, GAMEFUNC_WEAPON_7 = 25, GAMEFUNC_WEAPON_8 = 26, GAMEFUNC_WEAPON_9 = 27, GAMEFUNC_WEAPON_10 = 28, GAMEFUNC_INVENTORY = 29, GAMEFUNC_INVENTORY_LEFT = 30, GAMEFUNC_INVENTORY_RIGHT = 31, GAMEFUNC_HOLO_DUKE = 32, GAMEFUNC_JETPACK = 33, GAMEFUNC_NIGHTVISION = 34, GAMEFUNC_MEDKIT = 35, GAMEFUNC_TURNAROUND = 36, GAMEFUNC_SENDMESSAGE = 37, GAMEFUNC_MAP = 38, GAMEFUNC_SHRINK_SCREEN = 39, GAMEFUNC_ENLARGE_SCREEN = 40, GAMEFUNC_CENTER_VIEW = 41, GAMEFUNC_HOLSTER_WEAPON = 42, GAMEFUNC_SHOW_OPPONENTS_WEAPON = 43, GAMEFUNC_MAP_FOLLOW_MODE = 44, GAMEFUNC_SEE_COOP_VIEW = 45, GAMEFUNC_MOUSE_AIMING = 46, GAMEFUNC_TOGGLE_CROSSHAIR = 47, GAMEFUNC_STEROIDS = 48, GAMEFUNC_QUICK_KICK = 49, GAMEFUNC_NEXT_WEAPON = 50, GAMEFUNC_PREVIOUS_WEAPON = 51, -- GAMEFUNC_SHOW_CONSOLE = 52, GAMEFUNC_SHOW_DUKEMATCH_SCORES = 53, GAMEFUNC_DPAD_SELECT = 54, GAMEFUNC_DPAD_AIMING = 55, } local function shallow_copy(tab) local t = {} for k,v in pairs(tab) do t[k] = v end return t end -- KEEPINSYNC with gamedef.c:C_AddDefaultDefinitions() and the respective -- defines. These are exported to the ffi.C namespace (except STAT) and as -- literal defines in lunacon.lua. labels = { STR, PROJ, EVENT, shallow_copy(SFLAG), setmetatable(STAT, { __metatable="noffiC" }), GAMEFUNC, } -- TWEAK_SFLAG for name, flag in pairs(SFLAG) do if (flag < 0) then SFLAG[name] = -flag labels[4][name] = nil end end -- KEEPINSYNC player.h wdata_members = { -- NOTE: they are lowercased for Lunatic -- NOTE: members _*sound*, _spawn and _shoots assume *zero* to mean "none" -- (-1 would be more logical). "const int32_t _workslike", "int32_t clip", "int32_t reload", "int32_t firedelay", "int32_t totaltime", "int32_t holddelay", "int32_t flags", "const int32_t _shoots", "int32_t spawntime", "const int32_t _spawn", "int32_t shotsperburst", "const int32_t _initialsound", "const int32_t _firesound", "int32_t sound2time", -- NOTE: this is a time number, not a sound "const int32_t _sound2sound", "const int32_t _reloadsound1", "const int32_t _reloadsound2", "const int32_t _selectsound", "int32_t flashcolor", } local SP = function(memb) return "sprite[%s]"..memb end local ATSP = function(memb) return "_atsprite[%s]"..memb end local AC = function(memb) return "actor[%s]"..memb end local SX = function(memb) return "spriteext[%s]"..memb end -- Generate code to access a signed member as unsigned. local function s2u(label) return "(_band("..label.."+65536,65535))" end local function S2U(label) return { s2u(label), label } end local ActorLabels = { x = SP".x", y = SP".y", z = SP".z", cstat = SP".cstat", picnum = { SP".picnum", SP":set_picnum(%%s)" }, shade = SP".shade", pal = SP".pal", clipdist = SP".clipdist", -- filler = SP".filler", detail = SP".filler", -- NAME xrepeat = SP".xrepeat", yrepeat = SP".yrepeat", xoffset = SP".xoffset", yoffset = SP".yoffset", sectnum = { SP".sectnum", SP".sectnum" }, -- set: for tsprite statnum = { SP".statnum", SP".statnum" }, -- set: for tsprite ang = SP".ang", owner = { SP".owner", SP":_set_owner(%%s)" }, xvel = SP".xvel", yvel = { SP".yvel", SP":_set_yvel(%%s)" }, -- XXX zvel = SP".zvel", lotag = SP".lotag", hitag = SP".hitag", extra = SP".extra", ulotag = S2U(SP".lotag"), uhitag = S2U(SP".hitag"), -- ActorExtra labels... htcgg = AC".cgg", htpicnum = { AC".picnum", AC":set_picnum(%%s)" }, htang = AC".ang", htextra = AC".extra", htowner = { AC".owner", AC":set_owner(%%s)" }, htmovflag = AC"._movflag", httempang = AC".tempang", htactorstayput = AC".stayputsect", -- NAME htdispicnum = { AC".dispicnum" }, -- NOTE: no access for .shootzvel httimetosleep = AC".timetosleep", htfloorz = AC".floorz", htceilingz = AC".ceilingz", htlastvx = AC".lastvx", htlastvy = AC".lastvy", htbposx = AC".bpos.x", htbposy = AC".bpos.y", htbposz = AC".bpos.z", -- Read access differs from write ({ get, set }): htg_t = { AC":_get_t_data(%s)", AC":_set_t_data(%s,%%s)" }, htflags = AC".flags", -- (mostly) model-related flags angoff = SX".angoff", pitch = SX".pitch", roll = SX".roll", mdxoff = SX".mdoff.x", -- NAME mdyoff = SX".mdoff.y", mdzoff = SX".mdoff.z", mdflags = SX".flags", xpanning = SX".xpanning", ypanning = SX".ypanning", -- Read access differs from write, write not available: alpha = { "_math.floor(spriteext[%s].alpha*255)", "spriteext[%s].alpha=(%%s)/255" }, isvalid = { "_con._isvalid(%s)" }, } local function spr2tspr(code) if (code and code:find(SP"", 1, true)==1) then return ATSP(code:sub(#SP"" + 1)) end -- else return nothing end local TspriteLabels = {} for member, code in pairs(ActorLabels) do if (type(code)=="string") then TspriteLabels["tspr"..member] = spr2tspr(code) else TspriteLabels["tspr"..member] = { spr2tspr(code[1]), spr2tspr(code[2]) } end end -- Sprites set stat- and sectnum via sprite.change{stat,sect} functions. ActorLabels.sectnum[2] = "sprite.changesect(%s,%%s,true)" ActorLabels.statnum[2] = "sprite.changestat(%s,%%s,true)" local PL = function(memb) return "player[%s]"..memb end -- Access to DukePlayer_t's bool members: they must be read as numbers. local PLBOOL = function(memb) return { "("..PL(memb).." and 1 or 0)", PL(memb) } end local PlayerLabels = { posx = PL".pos.x", posy = PL".pos.y", posz = PL".pos.z", oposx = PL".opos.x", oposy = PL".opos.y", oposz = PL".opos.z", posxv = PL".vel.x", -- NAME posyv = PL".vel.y", poszv = PL".vel.z", -- NOTE: no access for .npos bobposx = PL".bobposx", bobposy = PL".bobposy", truefz = PL".truefz", truecz = PL".truecz", player_par = PL".player_par", randomflamex = PL".randomflamex", exitx = PL".exitx", exity = PL".exity", runspeed = PL".runspeed", max_player_health = PL".max_player_health", max_shield_amount = PL".max_shield_amount", autostep = PL".autostep", autostep_sbw = PL".autostep_sbw", interface_toggle_flag = PL".interface_toggle_flag", -- NOTE: *bombControl etc. are accessed by gamevars in CON max_actors_killed = PL".max_actors_killed", actors_killed = PL".actors_killed", -- NOTE the special case; "%%s" is used to mark settable members -- with METHOD_MEMBER syntax, it's the value to be set. gotweapon = { "("..PL":has_weapon(%s) and 1 or 0)", PL":_gt_weapon(%s,%%s)" }, zoom = PL".zoom", loogiex = {}, loogiey = {}, sbs = PL".sbs", sound_pitch = PL".sound_pitch", ang = PL".ang", oang = PL".oang", angvel = PL".angvel", cursectnum = PL".cursectnum", look_ang = PL".look_ang", last_extra = PL".last_extra", subweapon = PL".subweapon", max_ammo_amount = PL".max_ammo_amount[%s]", ammo_amount = PL".ammo_amount[%s]", -- NOTE: no direct access for .inv_amount (but see end) wackedbyactor = PL".wackedbyactor", pyoff = PL".pyoff", opyoff = PL".opyoff", horiz = PL".horiz", horizoff = PL".horizoff", ohoriz = PL".ohoriz", ohorizoff = PL".ohorizoff", newowner = { PL".newowner" }, jumping_counter = PL".jumping_counter", airleft = PL".airleft", fta = PL".fta", ftq = PL".ftq", access_wallnum = { PL".access_wallnum" }, access_spritenum = { PL".access_spritenum" }, got_access = PL".got_access", weapon_ang = PL".weapon_ang", visibility = PL".visibility", somethingonplayer = PL".somethingonplayer", on_crane = PL".on_crane", i = { PL".i" }, one_parallax_sectnum = { PL".one_parallax_sectnum" }, random_club_frame = PL".random_club_frame", one_eighty_count = PL".one_eighty_count", dummyplayersprite = PL".dummyplayersprite", extra_extra8 = PL".extra_extra8", actorsqu = PL".actorsqu", timebeforeexit = PL".timebeforeexit", customexitsound = { PL".customexitsound" }, last_pissed_time = PL".last_pissed_time", weaprecs = PL".weaprecs[%s]", weapon_sway = PL".weapon_sway", crack_time = PL".crack_time", bobcounter = PL".bobcounter", -- NOTE: no access for .orotscrnang rotscrnang = PL".rotscrnang", dead_flag = PL".dead_flag", holoduke_on = PL".holoduke_on", pycount = PL".pycount", transporter_hold = PL".transporter_hold", max_secret_rooms = PL".max_secret_rooms", secret_rooms = PL".secret_rooms", frag = PL".frag", fraggedself = PL".fraggedself", quick_kick = PL".quick_kick", last_quick_kick = PL".last_quick_kick", return_to_center = PL".return_to_center", reloading = PLBOOL".reloading", weapreccnt = { PL".weapreccnt" }, aim_mode = PL".aim_mode", auto_aim = PL".auto_aim", weaponswitch = PL".weaponswitch", movement_lock = PL".movement_lock", team = PL".team", tipincs = PL".tipincs", hbomb_hold_delay = PL".hbomb_hold_delay", frag_ps = PL".frag_ps", kickback_pic = PL".kickback_pic", gm = PL".gm", on_warping_sector = PLBOOL".on_warping_sector", footprintcount = PL".footprintcount", hurt_delay = PL".hurt_delay", hbomb_on = PLBOOL".hbomb_on", jumping_toggle = PLBOOL".jumping_toggle", rapid_fire_hold = PLBOOL".rapid_fire_hold", on_ground = PLBOOL".on_ground", inven_icon = PL".inven_icon", buttonpalette = PL".buttonpalette", over_shoulder_on = PLBOOL".over_shoulder_on", show_empty_weapon = PL".show_empty_weapon", jetpack_on = PLBOOL".jetpack_on", spritebridge = PLBOOL".spritebridge", lastrandomspot = PL".lastrandomspot", scuba_on = PLBOOL".scuba_on", footprintpal = PL".footprintpal", heat_on = PLBOOL".heat_on", invdisptime = PL".invdisptime", holster_weapon = PLBOOL".holster_weapon", falling_counter = PL".falling_counter", footprintshade = PL".footprintshade", refresh_inventory = PL".refresh_inventory", last_full_weapon = PL".last_full_weapon", walking_snd_toggle = PL".walking_snd_toggle", palookup = PL".palookup", hard_landing = PL".hard_landing", fist_incs = PL".fist_incs", toggle_key_flag = PLBOOL".toggle_key_flag", knuckle_incs = PL".knuckle_incs", knee_incs = PL".knee_incs", access_incs = PL".access_incs", numloogs = PL".numloogs", loogcnt = PL".loogcnt", scream_voice = PL".scream_voice", last_weapon = PL".last_weapon", cheat_phase = PL".cheat_phase", weapon_pos = PL".weapon_pos", wantweaponfire = PL".wantweaponfire", curr_weapon = PL".curr_weapon", palette = PL".palette", -- NOTE the special case: pals = PL"._pals[%s]", pals_time = PL"._pals.f", name = {}, -- Access to .inv_amount steroids_amount = PL".inv_amount[0]", shield_amount = PL".inv_amount[1]", scuba_amount = PL".inv_amount[2]", holoduke_amount = PL".inv_amount[3]", jetpack_amount = PL".inv_amount[4]", -- 5: dummy -- 6: no "access_amount" heat_amount = PL".inv_amount[7]", -- 8: dummy firstaid_amount = PL".inv_amount[9]", boot_amount = PL".inv_amount[10]", } local SEC = function(memb) return "sector[%s]"..memb end local SECRO = function(memb) return { "sector[%s]"..memb } end local SectorLabels = { wallptr = SECRO".wallptr", wallnum = SECRO".wallnum", ceilingz = SEC".ceilingz", floorz = SEC".floorz", ceilingstat = SEC".ceilingstat", floorstat = SEC".floorstat", -- CEILING ceilingpicnum = { SEC".ceilingpicnum", SEC":set_ceilingpicnum(%%s)" }, ceilingslope = SEC".ceilingheinum", -- NAME ceilingshade = SEC".ceilingshade", ceilingpal = SEC".ceilingpal", ceilingxpanning = SEC".ceilingxpanning", ceilingypanning = SEC".ceilingypanning", -- FLOOR floorpicnum = { SEC".floorpicnum", SEC":set_floorpicnum(%%s)" }, floorslope = SEC".floorheinum", -- NAME floorshade = SEC".floorshade", floorpal = SEC".floorpal", floorxpanning = SEC".floorxpanning", floorypanning = SEC".floorypanning", visibility = SEC".visibility", filler = SEC".filler", alignto = SEC".filler", -- NAME lotag = SEC".lotag", hitag = SEC".hitag", extra = SEC".extra", ceilingbunch = { SEC".ceilingbunch" }, floorbunch = { SEC".floorbunch" }, ulotag = S2U(SEC".lotag"), uhitag = S2U(SEC".hitag"), } local WAL = function(memb) return "wall[%s]"..memb end local WALRO = function(memb) return { "wall[%s]"..memb } end local WallLabels = { x = WAL".x", y = WAL".y", point2 = WALRO".point2", nextwall = { WAL".nextwall", WAL":_set_nextwall(%%s)" }, nextsector = { WAL".nextsector", WAL":_set_nextsector(%%s)" }, cstat = WAL".cstat", picnum = { WAL".picnum", WAL":set_picnum(%%s)" }, overpicnum = { WAL".overpicnum", WAL":set_overpicnum(%%s)" }, shade = WAL".shade", pal = WAL".pal", xrepeat = WAL".xrepeat", yrepeat = WAL".yrepeat", xpanning = WAL".xpanning", ypanning = WAL".ypanning", lotag = WAL".lotag", hitag = WAL".hitag", extra = WAL".extra", ulotag = S2U(WAL".lotag"), uhitag = S2U(WAL".hitag"), } StructAccessCode = { sector = SectorLabels, wall = WallLabels, sprite = ActorLabels, player = PlayerLabels, } local PROJ = function(memb) return "projectile[%s]"..memb end local THISPROJ = function(memb) return "actor[%s].proj"..memb end local ProjectileLabels = { workslike = PROJ".workslike", cstat = PROJ".cstat", hitradius = PROJ".hitradius", range = PROJ".range", flashcolor = PROJ".flashcolor", spawns = { PROJ".spawns", PROJ":set_spawns(%%s)" }, sound = PROJ".sound", isound = PROJ".isound", vel = PROJ".vel", decal = { PROJ".decal", PROJ":set_decal(%%s)" }, trail = { PROJ".trail", PROJ":set_trail(%%s)" }, tnum = PROJ".tnum", drop = PROJ".drop", offset = PROJ".offset", bounces = PROJ".bounces", bsound = PROJ".bsound", toffset = PROJ".toffset", extra = PROJ".extra", extra_rand = PROJ".extra_rand", sxrepeat = PROJ".sxrepeat", syrepeat = PROJ".syrepeat", txrepeat = PROJ".txrepeat", tyrepeat = PROJ".tyrepeat", shade = PROJ".shade", xrepeat = PROJ".xrepeat", yrepeat = PROJ".yrepeat", pal = PROJ".pal", velmult = PROJ".movecnt", -- NAME clipdist = PROJ".clipdist", userdata = PROJ".userdata", } -- XXX: kind of CODEDUP form spr2tspr local function proj2thisproj(code) if (code and code:find(PROJ"", 1, true)==1) then return THISPROJ(code:sub(#PROJ"" + 1)) end -- else return nothing end local SpriteProjectileLabels = {} for member, code in pairs(ProjectileLabels) do if (type(code)=="string") then SpriteProjectileLabels[member] = proj2thisproj(code) else SpriteProjectileLabels[member] = { proj2thisproj(code[1]), proj2thisproj(code[2]) } end end local UD = function(memb) return "_gv._ud"..memb end local UDRO = function(memb) return { UD(memb) } end -- NOTE: Only members that actually encountered in existing mods are added here. local UserdefLabels = { althud = UD".althud", auto_run = UD".auto_run", camerasprite = UDRO".camerasprite", cashman = UDRO".cashman", clipping = UD".noclip", -- NAME const_visibility = UD".const_visibility", crosshair = UD".crosshair", crosshairscale = UDRO".crosshairscale", detail = { "1" }, display_bonus_screen = UD".display_bonus_screen", drawweapon = UDRO".drawweapon", eog = UD".eog", ffire = UDRO".ffire", fta_on = UD".fta_on", god = UDRO".god", idplayers = UDRO".idplayers", level_number = { UD".level_number", UD":set_level_number(%%s)" }, lockout = UDRO".lockout", m_player_skill = UDRO".m_player_skill", m_volume_number = UDRO".m_volume_number", pause_on = UDRO".pause_on", player_skill = UD".player_skill", mouseflip = UDRO".mouseflip", multimode = { "1" }, noexits = UDRO".noexits", overhead_on = UD".overhead_on", show_level_text = UD".show_level_text", screen_size = { UD".screen_size", UD":set_screen_size(%%s)" }, screen_tilting = UD".screen_tilting", showallmap = UDRO".showallmap", showweapons = UDRO".showweapons", statusbarscale = UDRO".statusbarscale", volume_number = { UD".volume_number", UD":set_volume_number(%%s)" }, weaponscale = UDRO".weaponscale", weaponswitch = UD".weaponswitch", } local INP = function(memb) return PL"._input"..memb end local InputLabels = { avel = INP".avel", horz = INP".horz", fvel = INP".fvel", svel = INP".svel", bits = INP".bits", extbits = INP".extbits", } -- These structs cannot be accessed by inline array exprs in CON: StructAccessCode2 = { tspr = TspriteLabels, projectile = ProjectileLabels, thisprojectile = SpriteProjectileLabels, userdef = UserdefLabels, input = InputLabels, } -- NOTE: These MUST be in reverse lexicographical order! -- Per CON syntax, valid identifiers names are disjunct from keywords, -- so that a rule like -- t_identifier = -con_keyword * (sp1 + "[") * t_identifier_all -- (from the final grammar in lunacon.lua) must match the longest -- possible keyword name, else the negation might wrongly not fail. keyword = lpeg.P(false) + "}" + "{" + "zshootvar" + "zshoot" + "xorvarvar" + "xorvar" + "writearraytofile" + "whilevarvarn" + "whilevarn" + "wackplayer" + "userquote" + "useractor" + "updatesectorz" + "updatesector" + "tossweapon" + "tip" + "time" + "switch" + "subvarvar" + "subvar" + "strength" + "stopsoundvar" + "stopsound" + "stopallsounds" + "stopactorsound" + "state" + "starttrackvar" + "starttrack" + "startlevel" + "ssp" + "sqrt" + "spriteshadow" + "spritepal" + "spritenvg" + "spritenoshade" + "spritenopal" + "spriteflags" + "spgetlotag" + "spgethitag" + "spawn" + "soundvar" + "soundoncevar" + "soundonce" + "sound" + "smaxammo" + "sleeptime" + "sizeto" + "sizeat" + "sin" + "showviewunbiased" + "showview" + "shootvar" + "shoot" + "shiftvarr" + "shiftvarl" + "shadeto" + "setwall" + "setvarvar" + "setvar" + "setuserdef" + "settspr" + "setthisprojectile" + "setsprite" + "setsector" + "setprojectile" + "setplayervar" + "setplayerangle" + "setplayer" + "setinput" + "setgamepalette" + "setgamename" + "setdefname" + "setcfgname" + "setaspect" + "setarray" + "setactorvar" + "setactorsoundpitch" + "setactorangle" + "setactor" + "sectsetinterpolation" + "sectorofwall" + "sectgetlotag" + "sectgethitag" + "sectclearinterpolation" + "scriptsize" + "screentext" + "screensound" + "savenn" + "savemapstate" + "savegamevar" + "save" + "rotatespritea" + "rotatesprite16" + "rotatesprite" + "rotatepoint" + "return" + "respawnhitag" + "resizearray" + "resetplayer" + "resetcount" + "resetactioncount" + "redefinequote" + "readgamevar" + "readarrayfromfile" + "rayintersect" + "randvarvar" + "randvar" + "quote" + "quake" + "qsubstr" + "qstrncat" + "qstrlen" + "qstrdim" + "qstrcpy" + "qstrcat" + "qsprintf" + "qspawnvar" + "qspawn" + "qgetsysstr" + "pstomp" + "prevspritestat" + "prevspritesect" + "precache" + "pkick" + "paper" + "palfrom" + "orvarvar" + "orvar" + "operatesectors" + "operaterespawns" + "operatemasterswitches" + "operateactivators" + "operate" + "onevent" + "nullop" + "nextspritestat" + "nextspritesect" + "neartag" + "myosx" + "myospalx" + "myospal" + "myos" + "music" + "mulvarvar" + "mulvar" + "mulscale" + "movesprite" + "move" + "money" + "modvarvar" + "modvar" + "minitext" + "mikesnd" + "mail" + "lotsofglass" + "lockplayer" + "loadmapstate" + "lineintersect" + "ldist" + "killit" + "jump" + "insertspriteq" + "inittimer" + "includedefault" + "include" + "ifwasweapon" + "ifvarxor" + "ifvarvarxor" + "ifvarvaror" + "ifvarvarn" + "ifvarvarl" + "ifvarvarg" + "ifvarvareither" + "ifvarvare" + "ifvarvarand" + "ifvaror" + "ifvarn" + "ifvarl" + "ifvarg" + "ifvareither" + "ifvare" + "ifvarand" + "ifstrength" + "ifsquished" + "ifspritepal" + "ifspawnedby" + "ifsound" + "ifserver" + "ifrnd" + "ifrespawn" + "ifplayersl" + "ifpinventory" + "ifphealthl" + "ifpdistl" + "ifpdistg" + "ifp" + "ifoutside" + "ifonwater" + "ifnotmoving" + "ifnosounds" + "ifmultiplayer" + "ifmove" + "ifinwater" + "ifinspace" + "ifinouterspace" + "ifhitweapon" + "ifhitspace" + "ifgotweaponce" + "ifgapzl" + "iffloordistl" + "ifdead" + "ifcount" + "ifclient" + "ifceilingdistl" + "ifcanshoottarget" + "ifcanseetarget" + "ifcansee" + "ifbulletnear" + "ifawayfromwall" + "ifangdiffl" + "ifai" + "ifactorsound" + "ifactornotstayput" + "ifactor" + "ifactioncount" + "ifaction" + "hitscan" + "hitradiusvar" + "hitradius" + "headspritestat" + "headspritesect" + "guts" + "guniqhudid" + "gmaxammo" + "globalsoundvar" + "globalsound" + "getzrange" + "getwall" + "getuserdef" + "gettspr" + "gettimedate" + "getticks" + "getthisprojectile" + "gettexturefloor" + "gettextureceiling" + "getsector" + "getprojectile" + "getpname" + "getplayervar" + "getplayerangle" + "getplayer" + "getlastpal" + "getkeyname" + "getinput" + "getincangle" + "getflorzofslope" + "getcurraddress" + "getceilzofslope" + "getarraysize" + "getangletotarget" + "getangle" + "getactorvar" + "getactorangle" + "getactor" + "gamevar" + "gametextz" + "gametext" + "gamestartup" + "gamearray" + "flash" + "findplayer" + "findotherplayer" + "findnearspritezvar" + "findnearspritez" + "findnearspritevar" + "findnearsprite3dvar" + "findnearsprite3d" + "findnearsprite" + "findnearactorzvar" + "findnearactorz" + "findnearactorvar" + "findnearactor3dvar" + "findnearactor3d" + "findnearactor" + "fall" + "ezshootvar" + "ezshoot" + "eventloadactor" + "espawnvar" + "espawn" + "eshootvar" + "eshoot" + "eqspawnvar" + "eqspawn" + "enhanced" + "endswitch" + "ends" + "endoflevel" + "endofgame" + "endevent" + "enda" + "else" + "echo" + "dynamicsoundremap" + "dynamicremap" + "dragpoint" + "divvarvar" + "divvar" + "dist" + "displayrandvarvar" + "displayrandvar" + "displayrand" + "digitalnumberz" + "digitalnumber" + "definevolumename" + "definesound" + "defineskillname" + "definequote" + "defineprojectile" + "definelevelname" + "definegametype" + "definegamefuncname" + "definecheat" + "define" + "default" + "debug" + "debris" + "cstator" + "cstat" + "count" + "cos" + "copy" + "cmenu" + "clipmovenoslide" + "clipmove" + "clipdist" + "clearmapstate" + "checkavailweapon" + "checkavailinven" + "checkactivatormotion" + "cheatkeys" + "changespritestat" + "changespritesect" + "case" + "canseespr" + "cansee" + "calchypotenuse" + "cactor" + "break" + "betaname" + "angoffvar" + "angoff" + "andvarvar" + "andvar" + "ai" + "addweaponvar" + "addweapon" + "addvarvar" + "addvar" + "addstrength" + "addphealth" + "addlogvar" + "addlog" + "addkills" + "addinventory" + "addammo" + "actor" + "activatecheat" + "activatebysector" + "activate" + "action" + lpeg.P(false)