diff --git a/polymer/eduke32/source/gamedef.c b/polymer/eduke32/source/gamedef.c index 79171b511..d0ea0c04a 100644 --- a/polymer/eduke32/source/gamedef.c +++ b/polymer/eduke32/source/gamedef.c @@ -2193,6 +2193,73 @@ void C_DefineLevelName(int32_t vol, int32_t lev, const char *fn, } #endif +// NOTE: external linkage for Lunatic +void C_DefineProjectile(int32_t j, int32_t what, int32_t val) +{ + switch (what) + { + case PROJ_WORKSLIKE: + g_tile[j].defproj.workslike = ProjectileData[j].workslike = val; break; + case PROJ_SPAWNS: + g_tile[j].defproj.spawns = ProjectileData[j].spawns = val; break; + case PROJ_SXREPEAT: + g_tile[j].defproj.sxrepeat = ProjectileData[j].sxrepeat = val; break; + case PROJ_SYREPEAT: + g_tile[j].defproj.syrepeat = ProjectileData[j].syrepeat = val; break; + case PROJ_SOUND: + g_tile[j].defproj.sound = ProjectileData[j].sound = val; break; + case PROJ_ISOUND: + g_tile[j].defproj.isound = ProjectileData[j].isound = val; break; + case PROJ_VEL: + g_tile[j].defproj.vel = ProjectileData[j].vel = val; break; + case PROJ_EXTRA: + g_tile[j].defproj.extra = ProjectileData[j].extra = val; break; + case PROJ_DECAL: + g_tile[j].defproj.decal = ProjectileData[j].decal = val; break; + case PROJ_TRAIL: + g_tile[j].defproj.trail = ProjectileData[j].trail = val; break; + case PROJ_TXREPEAT: + g_tile[j].defproj.txrepeat = ProjectileData[j].txrepeat = val; break; + case PROJ_TYREPEAT: + g_tile[j].defproj.tyrepeat = ProjectileData[j].tyrepeat = val; break; + case PROJ_TOFFSET: + g_tile[j].defproj.toffset = ProjectileData[j].toffset = val; break; + case PROJ_TNUM: + g_tile[j].defproj.tnum = ProjectileData[j].tnum = val; break; + case PROJ_DROP: + g_tile[j].defproj.drop = ProjectileData[j].drop = val; break; + case PROJ_CSTAT: + g_tile[j].defproj.cstat = ProjectileData[j].cstat = val; break; + case PROJ_CLIPDIST: + g_tile[j].defproj.clipdist = ProjectileData[j].clipdist = val; break; + case PROJ_SHADE: + g_tile[j].defproj.shade = ProjectileData[j].shade = val; break; + case PROJ_XREPEAT: + g_tile[j].defproj.xrepeat = ProjectileData[j].xrepeat = val; break; + case PROJ_YREPEAT: + g_tile[j].defproj.yrepeat = ProjectileData[j].yrepeat = val; break; + case PROJ_PAL: + g_tile[j].defproj.pal = ProjectileData[j].pal = val; break; + case PROJ_EXTRA_RAND: + g_tile[j].defproj.extra_rand = ProjectileData[j].extra_rand = val; break; + case PROJ_HITRADIUS: + g_tile[j].defproj.hitradius = ProjectileData[j].hitradius = val; break; + case PROJ_MOVECNT: + g_tile[j].defproj.movecnt = ProjectileData[j].movecnt = val; break; + case PROJ_OFFSET: + g_tile[j].defproj.offset = ProjectileData[j].offset = val; break; + case PROJ_BOUNCES: + g_tile[j].defproj.bounces = ProjectileData[j].bounces = val; break; + case PROJ_BSOUND: + g_tile[j].defproj.bsound = ProjectileData[j].bsound = val; break; + case PROJ_RANGE: + g_tile[j].defproj.range = ProjectileData[j].range = val; break; + default: break; + } + + g_tile[j].flags |= SPRITE_PROJECTILE; +} + int32_t C_AllocQuote(int32_t qnum) { if (ScriptQuotes[qnum] == NULL) @@ -4298,68 +4365,7 @@ static int32_t C_ParseCommand(int32_t loop) continue; } - switch (y) - { - case PROJ_WORKSLIKE: - g_tile[j].defproj.workslike = ProjectileData[j].workslike = z; break; - case PROJ_SPAWNS: - g_tile[j].defproj.spawns = ProjectileData[j].spawns = z; break; - case PROJ_SXREPEAT: - g_tile[j].defproj.sxrepeat = ProjectileData[j].sxrepeat = z; break; - case PROJ_SYREPEAT: - g_tile[j].defproj.syrepeat = ProjectileData[j].syrepeat = z; break; - case PROJ_SOUND: - g_tile[j].defproj.sound = ProjectileData[j].sound = z; break; - case PROJ_ISOUND: - g_tile[j].defproj.isound = ProjectileData[j].isound = z; break; - case PROJ_VEL: - g_tile[j].defproj.vel = ProjectileData[j].vel = z; break; - case PROJ_EXTRA: - g_tile[j].defproj.extra = ProjectileData[j].extra = z; break; - case PROJ_DECAL: - g_tile[j].defproj.decal = ProjectileData[j].decal = z; break; - case PROJ_TRAIL: - g_tile[j].defproj.trail = ProjectileData[j].trail = z; break; - case PROJ_TXREPEAT: - g_tile[j].defproj.txrepeat = ProjectileData[j].txrepeat = z; break; - case PROJ_TYREPEAT: - g_tile[j].defproj.tyrepeat = ProjectileData[j].tyrepeat = z; break; - case PROJ_TOFFSET: - g_tile[j].defproj.toffset = ProjectileData[j].toffset = z; break; - case PROJ_TNUM: - g_tile[j].defproj.tnum = ProjectileData[j].tnum = z; break; - case PROJ_DROP: - g_tile[j].defproj.drop = ProjectileData[j].drop = z; break; - case PROJ_CSTAT: - g_tile[j].defproj.cstat = ProjectileData[j].cstat = z; break; - case PROJ_CLIPDIST: - g_tile[j].defproj.clipdist = ProjectileData[j].clipdist = z; break; - case PROJ_SHADE: - g_tile[j].defproj.shade = ProjectileData[j].shade = z; break; - case PROJ_XREPEAT: - g_tile[j].defproj.xrepeat = ProjectileData[j].xrepeat = z; break; - case PROJ_YREPEAT: - g_tile[j].defproj.yrepeat = ProjectileData[j].yrepeat = z; break; - case PROJ_PAL: - g_tile[j].defproj.pal = ProjectileData[j].pal = z; break; - case PROJ_EXTRA_RAND: - g_tile[j].defproj.extra_rand = ProjectileData[j].extra_rand = z; break; - case PROJ_HITRADIUS: - g_tile[j].defproj.hitradius = ProjectileData[j].hitradius = z; break; - case PROJ_MOVECNT: - g_tile[j].defproj.movecnt = ProjectileData[j].movecnt = z; break; - case PROJ_OFFSET: - g_tile[j].defproj.offset = ProjectileData[j].offset = z; break; - case PROJ_BOUNCES: - g_tile[j].defproj.bounces = ProjectileData[j].bounces = z; break; - case PROJ_BSOUND: - g_tile[j].defproj.bsound = ProjectileData[j].bsound = z; break; - case PROJ_RANGE: - g_tile[j].defproj.range = ProjectileData[j].range = z; break; - default: break; - } - - g_tile[j].flags |= SPRITE_PROJECTILE; + C_DefineProjectile(j, y, z); continue; } diff --git a/polymer/eduke32/source/gamedef.h b/polymer/eduke32/source/gamedef.h index 5efa79953..370b7aaf8 100644 --- a/polymer/eduke32/source/gamedef.h +++ b/polymer/eduke32/source/gamedef.h @@ -533,6 +533,7 @@ enum InputLabel_t INPUT_END }; +#endif // KEEPINSYNC lunatic/con_lang.lua enum ProjectileLabel_t { @@ -567,6 +568,7 @@ enum ProjectileLabel_t PROJ_FLASH_COLOR, PROJ_END }; +#if !defined LUNATIC enum ScriptKeywords_t { diff --git a/polymer/eduke32/source/lunatic/con_lang.lua b/polymer/eduke32/source/lunatic/con_lang.lua index c81b74c42..9f59d383b 100644 --- a/polymer/eduke32/source/lunatic/con_lang.lua +++ b/polymer/eduke32/source/lunatic/con_lang.lua @@ -55,7 +55,7 @@ PROJ = { PROJ_PAL = 20, PROJ_EXTRA_RAND = 21, PROJ_HITRADIUS = 22, - PROJ_VEL_MULT = 23, + PROJ_VEL_MULT = 23, -- NAME (PROJ_MOVECNT) PROJ_OFFSET = 24, PROJ_BOUNCES = 25, PROJ_BSOUND = 26, @@ -63,6 +63,39 @@ PROJ = { PROJ_FLASH_COLOR = 28, } +-- PROJ_* define -> projectile_t member name +PROJ_MEMBNAME = { + [PROJ.PROJ_WORKSLIKE] = "workslike", + [PROJ.PROJ_SPAWNS] = "spawns", + [PROJ.PROJ_SXREPEAT] = "sxrepeat", + [PROJ.PROJ_SYREPEAT] = "syrepeat", + [PROJ.PROJ_SOUND] = "sound", + [PROJ.PROJ_ISOUND] = "isound", + [PROJ.PROJ_VEL] = "vel", + [PROJ.PROJ_EXTRA] = "extra", + [PROJ.PROJ_DECAL] = "decal", + [PROJ.PROJ_TRAIL] = "trail", + [PROJ.PROJ_TXREPEAT] = "txrepeat", + [PROJ.PROJ_TYREPEAT] = "tyrepeat", + [PROJ.PROJ_TOFFSET] = "toffset", + [PROJ.PROJ_TNUM] = "tnum", + [PROJ.PROJ_DROP] = "drop", + [PROJ.PROJ_CSTAT] = "cstat", + [PROJ.PROJ_CLIPDIST] = "clipdist", + [PROJ.PROJ_SHADE] = "shade", + [PROJ.PROJ_XREPEAT] = "xrepeat", + [PROJ.PROJ_YREPEAT] = "yrepeat", + [PROJ.PROJ_PAL] = "pal", + [PROJ.PROJ_EXTRA_RAND] = "extra_rand", + [PROJ.PROJ_HITRADIUS] = "hitradius", + [PROJ.PROJ_VEL_MULT] = "movecnt", -- NAME + [PROJ.PROJ_OFFSET] = "offset", + [PROJ.PROJ_BOUNCES] = "bounces", + [PROJ.PROJ_BSOUND] = "bsound", + [PROJ.PROJ_RANGE] = "range", + [PROJ.PROJ_FLASH_COLOR] = "flashcolor", -- NAME +} + -- TODO: EVENT_INIT currently can't run since we init Lunatic state only afterwards EVENT = { EVENT_INIT = 0, @@ -698,6 +731,40 @@ StructAccessCode = player = PlayerLabels, } +local PROJ = function(memb) return "projectile[%s]"..memb end + +local ProjectileLabels = { + workslike = PROJ"workslike", + cstat = PROJ"cstat", + hitradius = PROJ"hitradius", + range = PROJ"range", + flashcolor = PROJ"flashcolor", + spawns = { PROJ"spawns" }, + sound = PROJ"sound", + isound = PROJ"isound", + vel = PROJ"vel", + decal = { PROJ"decal" }, + trail = { PROJ"trail" }, + 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", +} + -- These structs cannot be accessed by inline array exprs in CON: StructAccessCode2 = { diff --git a/polymer/eduke32/source/lunatic/defs.ilua b/polymer/eduke32/source/lunatic/defs.ilua index 90f143619..fcb3d922f 100644 --- a/polymer/eduke32/source/lunatic/defs.ilua +++ b/polymer/eduke32/source/lunatic/defs.ilua @@ -102,7 +102,6 @@ enum { ]] ffi.cdef[[ -#pragma pack(push,1) struct action { int16_t startframe, numframes; int16_t viewtype, incval, delay; @@ -112,8 +111,10 @@ struct move { int16_t hvel, vvel; }; +#pragma pack(push,1) typedef struct { int32_t id; struct move mv; } con_move_t; typedef struct { int32_t id; struct action ac; } con_action_t; +#pragma pack(pop) typedef struct { int32_t id; @@ -121,7 +122,6 @@ typedef struct { con_move_t mov; int32_t movflags; } con_ai_t; -#pragma pack(pop) ]] -- Struct template for actor_t. It already has 'const' fields (TODO: might need @@ -300,7 +300,6 @@ typedef struct { int8_t extbits, filler; // 2b } input_t; -#pragma pack(push, 1) typedef ]].. mangle_arrays(ACTOR_STRUCT) ..[[ actor_t; @@ -309,7 +308,7 @@ typedef ]].. mangle_arrays(DUKEPLAYER_STRUCT) ..[[ DukePlayer_t; -typedef struct { +typedef __attribute__((packed)) struct { DukePlayer_t *ps; input_t *sync; @@ -322,7 +321,6 @@ typedef struct { char user_name[32]; uint32_t revision; } playerdata_t; -#pragma pack(pop) typedef struct { int32_t cur, count; @@ -332,18 +330,20 @@ typedef struct { } hudweapon_t; typedef struct { - int32_t workslike, cstat; // 8b - int32_t hitradius, range, flashcolor; // 12b - int16_t spawns, sound, isound, vel; // 8b - int16_t decal, trail, tnum, drop; // 8b - int16_t offset, bounces, bsound; // 6b - int16_t toffset; // 2b - int16_t extra, extra_rand; // 4b - int8_t sxrepeat, syrepeat, txrepeat, tyrepeat; // 4b - int8_t shade, xrepeat, yrepeat, pal; // 4b - int8_t movecnt; // 1b - uint8_t clipdist; // 1b - int8_t filler[6]; // 6b + int32_t workslike, cstat; + int32_t hitradius, range, flashcolor; + const int16_t spawns; + int16_t sound, isound, vel; + const int16_t decal, trail; + int16_t tnum, drop; + int16_t offset, bounces, bsound; + int16_t toffset; + int16_t extra, extra_rand; + int8_t sxrepeat, syrepeat, txrepeat, tyrepeat; + int8_t shade, xrepeat, yrepeat, pal; + int8_t movecnt; + uint8_t clipdist; + int8_t filler[6]; } projectile_t; typedef struct { @@ -372,7 +372,6 @@ enum NUMGAMEFUNCTIONS = 56, }; -// NOTE: not packed! typedef struct { int32_t const_visibility,uw_framerate; int32_t camera_time,folfvel,folavel,folx,foly,fola; @@ -488,6 +487,8 @@ user_defs ud; playerdata_t g_player[MAXPLAYERS]; weapondata_t g_playerWeapon[MAXPLAYERS][MAX_WEAPONS]; tiledata_t g_tile[MAXTILES]; +projectile_t ProjectileData[MAXTILES]; +projectile_t SpriteProjectile[MAXSPRITES]; char *ScriptQuotes[]; @@ -543,6 +544,7 @@ void C_DefineSkillName(int32_t skill, const char *name); void C_DefineLevelName(int32_t vol, int32_t lev, const char *fn, int32_t partime, int32_t designertime, const char *levelname); +void C_DefineProjectile(int32_t j, int32_t what, int32_t val); ]] @@ -586,6 +588,8 @@ player = setmtonce({}, tmpmt) -- needed by "control" actor = defs_c.creategtab(ffiC.actor, ffiC.MAXSPRITES, "actor[]") +local projectile = defs_c.creategtab(ffiC.ProjectileData, ffiC.MAXTILES, "projectile[]") + --== Custom operations for BUILD data structures ==-- -- Among other things, declares struct action and struct move, and their -- ID-wrapped types con_action_t and con_move_t @@ -780,17 +784,17 @@ ffi.metatype("actor_t", actor_mt) --- PER-PLAYER WEAPON SETTINGS local weapondata_mt = { __newindex = function(wd, member, val) - if (string.match(member, "sound")) then - -- TODO: set to 0 if oob? (e.g. CrackDown) - check_sound_idx(val) - elseif (member=="workslike") then - check_weapon_idx(val) - elseif (member=="shoots" or member=="spawn") then - -- TODO: set to 0 if oob? (e.g. AMC TC) - check_tile_idx(val) - end + if (string.match(member, "sound")) then + -- TODO: set to 0 if oob? (e.g. CrackDown) + check_sound_idx(val) + elseif (member=="workslike") then + check_weapon_idx(val) + elseif (member=="shoots" or member=="spawn") then + -- TODO: set to 0 if oob? (e.g. AMC TC) + check_tile_idx(val) + end - wd[member] = val + wd[member] = val end, } ffi.metatype("weapondata_t", weapondata_mt) @@ -1254,8 +1258,10 @@ end --- non-default data and functions G_.gameevent = our_gameevent G_.gameactor = our_gameactor -G_.player = player -- from above -G_.actor = actor -- from above +-- These come from above: +G_.player = player +G_.actor = actor +G_.projectile = projectile ---=== Lunatic interpreter setup ===--- diff --git a/polymer/eduke32/source/lunatic/dynsymlist b/polymer/eduke32/source/lunatic/dynsymlist index 705fe4bc2..c243d56ac 100644 --- a/polymer/eduke32/source/lunatic/dynsymlist +++ b/polymer/eduke32/source/lunatic/dynsymlist @@ -82,6 +82,7 @@ C_DefineQuote; C_DefineVolumeName; C_DefineSkillName; C_DefineLevelName; +C_DefineProjectile; actor; g_camera; @@ -89,6 +90,8 @@ ud; g_player; g_playerWeapon; g_tile; +ProjectileData; +SpriteProjectile; ScriptQuotes; diff --git a/polymer/eduke32/source/lunatic/lunacon.lua b/polymer/eduke32/source/lunatic/lunacon.lua index fb1dd23e1..b58951d79 100644 --- a/polymer/eduke32/source/lunatic/lunacon.lua +++ b/polymer/eduke32/source/lunatic/lunacon.lua @@ -743,6 +743,18 @@ function Cmd.definequote(qnum, quotestr) g_data.quote[qnum] = quotestr end +function Cmd.defineprojectile(tilenum, what, val) + if (not (tilenum >= 0 and tilenum < (ffiC and ffiC.MAXTILES or 30720))) then + errprintf("invalid tile number %d", tilenum) + return + end + + if (ffi) then + -- TODO: potentially bound-check some members? + ffiC.C_DefineProjectile(tilenum, what, val) + end +end + function Cmd.gamestartup(...) local args = {...} @@ -1026,7 +1038,7 @@ local Couter = { definevolumename = sp1 * tok.define * newline_term_string / Cmd.definevolumename, definequote = sp1 * tok.define * newline_term_string / Cmd.definequote, - defineprojectile = cmd(D,D,D), + defineprojectile = cmd(D,D,D) / Cmd.defineprojectile, definesound = sp1 * tok.define * sp1 * maybe_quoted_filename * n_defines(5) / Cmd.definesound, -- NOTE: gamevar.ogg and the like is OK, too @@ -1180,6 +1192,7 @@ local Access = player = function(...) return StructAccess("player", ...) end, tspr = function(...) return StructAccess("tspr", ...) end, + projectile = function(...) return StructAccess("projectile", ...) end, } local function GetStructCmd(accessfunc) @@ -1278,7 +1291,7 @@ local Cinner = { getplayer = GetStructCmd(Access.player), getinput = getstructcmd / handle.NYI, - getprojectile = getstructcmd / handle.NYI, + getprojectile = GetStructCmd(Access.projectile), getthisprojectile = getstructcmd / handle.NYI, gettspr = GetStructCmd(Access.tspr), -- NOTE: {get,set}userdef is the only struct that can be accessed without @@ -1300,7 +1313,7 @@ local Cinner = { setplayer = SetStructCmd(Access.player), setinput = setstructcmd / handle.NYI, - setprojectile = setstructcmd / handle.NYI, + setprojectile = SetStructCmd(Access.projectile), setthisprojectile = setstructcmd / handle.NYI, settspr = SetStructCmd(Access.tspr), setuserdef = (arraypat + sp1)/{} * singlememberpat * sp1 * tok.rvar / handle.NYI, diff --git a/polymer/eduke32/source/lunatic/test.elua b/polymer/eduke32/source/lunatic/test.elua index b22c5e748..0bc1d1090 100644 --- a/polymer/eduke32/source/lunatic/test.elua +++ b/polymer/eduke32/source/lunatic/test.elua @@ -261,6 +261,10 @@ gameevent(gv.EVENT_ENTERLEVEL, pl:give_weapon(gv.RPG_WEAPON) pl.ammo_amount[gv.RPG_WEAPON] = 54 + -- MORTER2 from test/weaponvars.con + player[0].weapon.SHOTGUN.shoots = 1653 + projectile[1653].drop = -200 + checkfail("gameevent('GAME', function() print('qwe') end)", "must be called from top level") end diff --git a/polymer/eduke32/source/lunatic/test/weaponvars.con b/polymer/eduke32/source/lunatic/test/weaponvars.con index e57089a08..63a163390 100644 --- a/polymer/eduke32/source/lunatic/test/weaponvars.con +++ b/polymer/eduke32/source/lunatic/test/weaponvars.con @@ -3,6 +3,22 @@ gamevar shoots 2605 2 // RPG gamevar WEAPON1_SHOOTS 2605 0 +define MORTER2 1653 +defineprojectile MORTER2 PROJ_WORKSLIKE 6150 +defineprojectile MORTER2 PROJ_SPAWNS EXPLOSION2 +defineprojectile MORTER2 PROJ_SOUND MORTER2_SHOOT +defineprojectile MORTER2 PROJ_VEL 600 +defineprojectile MORTER2 PROJ_EXTRA 165 +defineprojectile MORTER2 PROJ_EXTRA_RAND 10 +defineprojectile MORTER2 PROJ_DROP 0 // tested in test.elua +defineprojectile MORTER2 PROJ_ISOUND PIPEBOMB_EXPLODE +defineprojectile MORTER2 PROJ_HITRADIUS 2800 +defineprojectile MORTER2 PROJ_BOUNCES 4 +defineprojectile MORTER2 PROJ_OFFSET 128 +defineprojectile MORTER2 PROJ_CLIPDIST 24 +defineprojectile MORTER2 PROJ_TRAIL SMALLSMOKE +defineprojectile MORTER2 PROJ_TNUM 6 + onevent EVENT_GAME setvarvar WEAPON1_FIRESOUND snd // setvarvar WEAPON1_SHOOTS shoots