Lunatic: [gs]et{player,actor}var, access to protected projectile members.

git-svn-id: https://svn.eduke32.com/eduke32@3469 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2013-02-10 16:23:59 +00:00
parent 90793f6a67
commit 35802d7e41
5 changed files with 89 additions and 36 deletions

View file

@ -740,12 +740,12 @@ local ProjectileLabels = {
hitradius = PROJ".hitradius",
range = PROJ".range",
flashcolor = PROJ".flashcolor",
spawns = { PROJ".spawns" },
spawns = { PROJ".spawns", PROJ":set_spawns(%%s)" },
sound = PROJ".sound",
isound = PROJ".isound",
vel = PROJ".vel",
decal = { PROJ".decal" },
trail = { PROJ".trail" },
decal = { PROJ".decal", PROJ":set_decal(%%s)" },
trail = { PROJ".trail", PROJ":set_trail(%%s)" },
tnum = PROJ".tnum",
drop = PROJ".drop",
offset = PROJ".offset",

View file

@ -254,6 +254,25 @@ __attribute__((packed)) struct {
}
]]
local PROJECTILE_STRUCT = [[
struct {
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];
}
]]
local randgen = require("randgen")
local geom = require("geom")
@ -329,22 +348,9 @@ typedef struct {
int32_t shade;
} hudweapon_t;
typedef struct {
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
]].. PROJECTILE_STRUCT ..[[
projectile_t;
typedef struct {
uint32_t flags;
@ -620,6 +626,7 @@ end
-- An unrestricted actor_t pointer, for internal use:
local actor_ptr_ct = ffi.typeof("$ *", ffi.typeof(strip_const(ACTOR_STRUCT)))
local player_ptr_ct = ffi.typeof("$ *", ffi.typeof(strip_const(DUKEPLAYER_STRUCT)))
local projectile_ptr_ct = ffi.typeof("$ *", ffi.typeof(strip_const(PROJECTILE_STRUCT)))
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")
@ -916,6 +923,24 @@ local player_mt = {
}
ffi.metatype("DukePlayer_t", player_mt)
local function GenProjectileSetFunc(Member)
return function(self, picnum)
if (picnum >= 0) then
check_tile_idx(picnum)
end
ffi.cast(projectile_ptr_ct, self)[Member] = picnum
end
end
local projectile_mt = {
__index = {
set_spawns = GenProjectileSetFunc "spawns",
set_decal = GenProjectileSetFunc "decal",
set_trail = GenProjectileSetFunc "trail",
},
}
ffi.metatype("projectile_t", projectile_mt)
--- CUSTOM "gv" VARIABLES
local camera_mt = {
-- TODO: "set position" method, which also updates the sectnum

View file

@ -890,7 +890,8 @@ function Cmd.gamevar(identifier, initval, flags)
end
end
function lookup.gamevar(identifier, writable)
-- <aorpvar>: code for actor or player index
function lookup.gamevar(identifier, aorpvar, writable)
local gv = g_gamevar[identifier]
if (gv == nil) then
@ -903,8 +904,8 @@ function lookup.gamevar(identifier, writable)
return "_READONLYGV"
end
if (gv.flags==GVFLAG.PERACTOR) then
return format("%s[_aci]", gv.name)
if (bit.band(gv.flags, GVFLAG.PERACTOR)~=0) then
return format("%s[%s]", gv.name, aorpvar)
else
return gv.name
end
@ -912,7 +913,7 @@ end
local function maybe_gamevar_Cmt(subj, pos, identifier)
if (g_gamevar[identifier]) then
return true, lookup.gamevar(identifier)
return true, lookup.gamevar(identifier, "_aci", false)
end
end
@ -1125,10 +1126,10 @@ local getstructcmd = -- get<structname>[<idx>].<member> (<parm2>)? <<var>>
local setstructcmd = -- set<structname>[<idx>].<<member>> (<parm2>)? <var>
arraypat * bothmemberpat * sp1 * tok.rvar
local getperxvarcmd = -- get<actor/player>var[<idx>].<member> <<var>>
local getperxvarcmd = -- get<actor/player>var[<idx>].<varname> <<var>>
arraypat * singlememberpat * sp1 * tok.wvar
local setperxvarcmd = -- set<actor/player>var[<idx>].<<member>> <var>
local setperxvarcmd = -- set<actor/player>var[<idx>].<<varname>> <var>
arraypat * singlememberpat * sp1 * tok.rvar
-- Function generating code for a struct read/write access.
@ -1198,14 +1199,17 @@ local Access =
}
local function GetStructCmd(accessfunc)
local pattern = getstructcmd / function(idx, memb, var)
local pattern = getstructcmd /
function(idx, memb, var)
return format("%s=%s", var, accessfunc(false, idx, memb))
end
end
return pattern
end
local function SetStructCmd(accessfunc)
local pattern = setstructcmd / function(idx, memb, var)
local pattern = setstructcmd
local function capfunc(idx, memb, var)
local membercode, ismethod = accessfunc(true, idx, memb)
if (ismethod) then
-- METHOD_MEMBER syntax
@ -1221,7 +1225,29 @@ local function SetStructCmd(accessfunc)
return format("%s=%s", membercode, var)
end
end
return pattern
return pattern / capfunc
end
-- <Setp>: whether the perxvar is set
local function GetOrSetPerxvarCmd(Setp, Actorp)
local EXPECTED_PERX_BIT = Actorp and GVFLAG.PERACTOR or GVFLAG.PERPLAYER
local pattern = (Setp and setperxvarcmd or getperxvarcmd)
local function capfunc(idx, perxvarname, var)
local gv = g_gamevar[perxvarname]
if (gv and bit.band(gv.flags, GVFLAG.PERX_MASK)~=EXPECTED_PERX_BIT) then
errprintf("variable `%s' is not per-%s", perxvarname, Actorp and "actor" or "player")
end
if (Setp) then
return format("%s=%s", lookup.gamevar(perxvarname, idx, true), var)
else
return format("%s=%s", var, lookup.gamevar(perxvarname, idx, false))
end
end
return pattern / capfunc
end
@ -1306,8 +1332,8 @@ local Cinner = {
-- these.
getuserdef = (arraypat + sp1)/{} * singlememberpat * sp1 * tok.wvar / handle.NYI,
getactorvar = getperxvarcmd / handle.NYI,
getplayervar = getperxvarcmd / handle.NYI,
getplayervar = GetOrSetPerxvarCmd(false, false),
getactorvar = GetOrSetPerxvarCmd(false, true),
setsector = SetStructCmd(Access.sector),
setwall = SetStructCmd(Access.wall),
@ -1320,8 +1346,8 @@ local Cinner = {
settspr = SetStructCmd(Access.tspr),
setuserdef = (arraypat + sp1)/{} * singlememberpat * sp1 * tok.rvar / handle.NYI,
setactorvar = setperxvarcmd,
setplayervar = setperxvarcmd,
setplayervar = GetOrSetPerxvarCmd(true, false),
setactorvar = GetOrSetPerxvarCmd(true, true),
setsprite = cmd(R,R,R,R),
@ -2136,7 +2162,7 @@ local Grammar = Pat{
-- For written-to vars, only (non-parm2) array exprs and writable gamevars
-- are permitted. NOTE: C-CON doesn't support inline array exprs here.
t_wvar = Var("t_singlearrayexp") / function() errprintf("t_wvar: array exprs NYI") return "_NYIVAR" end
+ (tok.identifier / function(id) return lookup.gamevar(id, true) end),
+ (tok.identifier / function(id) return lookup.gamevar(id, "_aci", true) end),
t_move =
POS()*tok.identifier / function(...) return lookup.composite(LABEL.MOVE, ...) end +

View file

@ -264,7 +264,9 @@ gameevent(gv.EVENT_ENTERLEVEL,
-- MORTER2 from test/weaponvars.con
player[0].weapon.SHOTGUN.shoots = 1653
projectile[1653].drop = 0
local proj = projectile[1653]
proj.drop = 0
proj:set_trail(2329) -- SMALLSMOKE
t = gv.gethitickms()
local N=1

View file

@ -18,7 +18,7 @@ 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_TRAIL -1 // overridden in test.elua
defineprojectile MORTER2 PROJ_TNUM 6
onevent EVENT_GAME