diff --git a/polymer/eduke32/source/lunatic/con_lang.lua b/polymer/eduke32/source/lunatic/con_lang.lua index 3942d6ee4..5f76bf9e2 100644 --- a/polymer/eduke32/source/lunatic/con_lang.lua +++ b/polymer/eduke32/source/lunatic/con_lang.lua @@ -430,10 +430,7 @@ for member, code in pairs(ActorLabels) do if (type(code)=="string") then TspriteLabels["tspr"..member] = spr2tspr(code) else - local rwcodetab = { spr2tspr(code[1]), spr2tspr(code[2]) } - if (#rwcodetab > 0) then - TspriteLabels["tspr"..member] = rwcodetab - end + TspriteLabels["tspr"..member] = { spr2tspr(code[1]), spr2tspr(code[2]) } end end @@ -735,6 +732,7 @@ StructAccessCode = } local PROJ = function(memb) return "projectile[%s]"..memb end +local THISPROJ = function(memb) return "actor[%s].proj"..memb end local ProjectileLabels = { workslike = PROJ".workslike", @@ -768,10 +766,30 @@ local ProjectileLabels = { clipdist = PROJ".clipdist", } +-- XXX: kind of CODEDUP form above +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 + -- These structs cannot be accessed by inline array exprs in CON: StructAccessCode2 = { tspr = TspriteLabels, + projectile = ProjectileLabels, + thisprojectile = SpriteProjectileLabels, } -- NOTE: These MUST be in reverse lexicographical order! diff --git a/polymer/eduke32/source/lunatic/control.lua b/polymer/eduke32/source/lunatic/control.lua index 64f1c0a70..0c022ed8f 100644 --- a/polymer/eduke32/source/lunatic/control.lua +++ b/polymer/eduke32/source/lunatic/control.lua @@ -232,6 +232,18 @@ function _spawnmany(ow, tilenum, n) end end +local int16_st = ffi.typeof "struct { int16_t s; }" + +function _shoot(i, tilenum, zvel) + check_sprite_idx(i) + check_sector_idx(sprite[i].sectnum) -- accessed in A_ShootWithZvel + check_tile_idx(tilenum) + + zvel = zvel and int16_st(zvel).s or 0x80000000 -- SHOOT_HARDCODED_ZVEL + + return ffiC.A_ShootWithZvel(i, tilenum, zvel) +end + function isenemytile(tilenum) if (bit.band(ffiC.g_tile[tilenum].flags, 0x00040000)~=0) then return true diff --git a/polymer/eduke32/source/lunatic/defs.ilua b/polymer/eduke32/source/lunatic/defs.ilua index a87c787d1..93881ef76 100644 --- a/polymer/eduke32/source/lunatic/defs.ilua +++ b/polymer/eduke32/source/lunatic/defs.ilua @@ -624,6 +624,12 @@ local con_action_ct = ffi.typeof("con_action_t") local con_move_ct = ffi.typeof("con_move_t") local con_ai_ct = ffi.typeof("con_ai_t") +local function get_actor_idx(a) + local i = ffi.cast(actor_ptr_ct, a)-ffi.cast(actor_ptr_ct, ffiC.actor) + assert(not (i >= ffiC.MAXSPRITES+0ULL)) + return i +end + local actor_mt = { __index = { -- action @@ -694,8 +700,7 @@ local actor_mt = { end a.t_data[0] = 0 - local i = a-ffi.cast(actor_ptr_ct, ffiC.actor[0]) - assert(not (i >= ffiC.MAXSPRITES+0ULL)) + local i = get_actor_idx(a) ffiC.sprite[i].hitag = movflags or 0 -- TODO: random angle moveflag @@ -778,6 +783,15 @@ local actor_mt = { end, }, } + +local function actor_index_index(a, key) + -- actor[].proj gets an actor's projectile ([gs]etthisprojectile in CON) + if (key=="proj") then + return ffiC.SpriteProjectile[get_actor_idx(a)] + end +end + +setmtonce(actor_mt.__index, { __index = actor_index_index }) ffi.metatype("actor_t", actor_mt) @@ -916,6 +930,9 @@ local camera_mt = { gv_access.cam = setmtonce({}, camera_mt) +-- Support for some CON global system gamevars +gv_access._csv = ffi.new "struct { int32_t RETURN; }" + function gv_access._currentFramerate() return ffiC.g_currentFrameRate end diff --git a/polymer/eduke32/source/lunatic/lunacon.lua b/polymer/eduke32/source/lunatic/lunacon.lua index b58951d79..c9f7b104f 100644 --- a/polymer/eduke32/source/lunatic/lunacon.lua +++ b/polymer/eduke32/source/lunatic/lunacon.lua @@ -142,6 +142,8 @@ local function new_initial_codetab() } end +local RETURN_VAR_CODE = "gv._csv.RETURN" + -- Creates the table of predefined game variables. -- KEEPINSYNC gamevars.c: Gv_AddSystemVars() local function new_initial_gvartab() @@ -164,8 +166,7 @@ local function new_initial_gvartab() -- e.g. sector[THISACTOR] is sector[sprite[].sectnum] THISACTOR = RO "_aci", - -- TODO - RETURN = RW "_RETURN_", + RETURN = RW(RETURN_VAR_CODE), xdim = RO "_gv.xdim", ydim = RO "_gv.ydim", @@ -1193,6 +1194,7 @@ local Access = tspr = function(...) return StructAccess("tspr", ...) end, projectile = function(...) return StructAccess("projectile", ...) end, + thisprojectile = function(...) return StructAccess("thisprojectile", ...) end, } local function GetStructCmd(accessfunc) @@ -1292,7 +1294,7 @@ local Cinner = { getinput = getstructcmd / handle.NYI, getprojectile = GetStructCmd(Access.projectile), - getthisprojectile = getstructcmd / handle.NYI, + getthisprojectile = GetStructCmd(Access.thisprojectile), gettspr = GetStructCmd(Access.tspr), -- NOTE: {get,set}userdef is the only struct that can be accessed without -- an "array part", e.g. H266MOD has "setuserdef .weaponswitch 0" (space @@ -1314,7 +1316,7 @@ local Cinner = { setinput = setstructcmd / handle.NYI, setprojectile = SetStructCmd(Access.projectile), - setthisprojectile = setstructcmd / handle.NYI, + setthisprojectile = SetStructCmd(Access.thisprojectile), settspr = SetStructCmd(Access.tspr), setuserdef = (arraypat + sp1)/{} * singlememberpat * sp1 * tok.rvar / handle.NYI, @@ -1490,13 +1492,18 @@ local Cinner = { sleeptime = cmd(D) / ACS".timetosleep=%1", - eshoot = cmd(D), - ezshoot = cmd(R,D), - ezshootvar = cmd(R,R), + eshoot = cmd(D) + / (RETURN_VAR_CODE.."=_con._shoot(_aci,%1)"), + ezshoot = cmd(R,D) + / (RETURN_VAR_CODE.."=_con._shoot(_aci,%2,%1)"), + ezshootvar = cmd(R,R) + / (RETURN_VAR_CODE.."=_con._shoot(_aci,%2,%1)"), shoot = cmd(D) - / "_con._A_Shoot(_aci,%1)", - zshoot = cmd(R,D), - zshootvar = cmd(R,R), + / "_con._shoot(_aci,%1)", + zshoot = cmd(R,D) + / "_con._shoot(_aci,%2,%1)", + zshootvar = cmd(R,R) + / "_con._shoot(_aci,%2,%1)", fall = cmd() / "_con._VM_FallSprite(_aci)", diff --git a/polymer/eduke32/source/lunatic/test.elua b/polymer/eduke32/source/lunatic/test.elua index 8d81e252d..ca3959be4 100644 --- a/polymer/eduke32/source/lunatic/test.elua +++ b/polymer/eduke32/source/lunatic/test.elua @@ -208,6 +208,7 @@ gameevent("JUMP", ps.weapon.PISTOL.shoots = 2605 -- RPG ps.weapon[gv.PISTOL_WEAPON].firesound = 351 -- thunder + -- XXX: provide either named constants or methods? ps.pipebombControl = 2 ps.tripbombControl = 2