LunaCON: real user per-player vars.

The previous behavior was to translate them as global gamevars, since LunaCON
currently has no support for multiplayer. However, then some errors would be
missed where such gamevars are accessed in no-player context
(e.g. EVENT_ENTERLEVEL).
On by default, disabled with -fno-playervar.

git-svn-id: https://svn.eduke32.com/eduke32@3842 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2013-06-01 20:09:41 +00:00
parent 358c7eb28b
commit e0433e66fb
2 changed files with 60 additions and 16 deletions

View file

@ -1845,6 +1845,11 @@ local function serialize_array(ar, strtab, maxnum)
return table.concat(strtab)
end
local function our_get_require()
return OUR_REQUIRE_STRING
end
--- Game arrays ---
local function moddir_filename(cstr_fn)
@ -2006,10 +2011,7 @@ local gamearray_methods = {
--- Serialization ---
_get_require = function(gar)
return OUR_REQUIRE_STRING
end,
_get_require = our_get_require,
_serialize = function(gar)
local strtab = { OUR_NAME.."._gamearray(", tostring(gar._size), ",{" }
@ -2069,7 +2071,7 @@ function killit()
end
-- Per-actor variable.
--== Per-actor variable ==--
local actorvar_methods = {
--- Internal routines ---
@ -2089,10 +2091,7 @@ local actorvar_methods = {
--- Serialization ---
_get_require = function(acv)
return OUR_REQUIRE_STRING
end,
_get_require = our_get_require,
_serialize = function(acv)
local strtab = { OUR_NAME..".actorvar(", tostring(acv._defval), ",{" }
@ -2129,3 +2128,41 @@ function actorvar(initval, values)
g_actorvar[acv] = true
return set_values_from_table(acv, values)
end
--== Per-player variable (kind of CODEDUP) ==--
local playervar_methods = {
--- Serialization ---
_get_require = our_get_require,
_serialize = function(plv)
local strtab = { OUR_NAME..".playervar(", tostring(plv._defval), ",{" }
return serialize_array(plv, strtab, ffiC.MAXSPRITES)
end,
}
-- XXX: How about types other than numbers?
local playervar_mt = {
__index = function(plv, idx)
if (type(idx)=="number") then
check_player_idx(idx)
return plv._defval
else
return playervar_methods[idx]
end
end,
__newindex = function(plv, idx, val)
check_player_idx(idx)
rawset(plv, idx, val)
end,
__metatable = "serializeable",
}
-- <initval>: default value for per-player variable.
-- <values>: optional, a table of <playeridx>=value
function playervar(initval, values)
local plv = setmetatable({ _defval=initval }, playervar_mt)
return set_values_from_table(plv, values)
end

View file

@ -113,7 +113,9 @@ local g_warn = { ["not-redefined"]=true, ["bad-identifier"]=false,
-- Code generation and output options.
local g_cgopt = { ["no"]=false, ["debug-lineinfo"]=false, ["gendir"]=nil,
["cache-sap"]=false, ["error-nostate"]=true, }
["cache-sap"]=false, ["error-nostate"]=true,
["playervar"]=true, }
local function csapp() return g_cgopt["cache-sap"] end
-- Stack with *true* on top if the innermost block is a "whilevar*n".
@ -130,6 +132,8 @@ local GVFLAG = {
NODEFAULT = 0x00000400, -- don't reset on actor spawn
NORESET = 0x00020000, -- don't reset when restoring map state
CON_PERPLAYER = 0x40000000, -- LunaCON internal
}
-- NOTE: This differs from enum GamevarFlags_t's GAMEVAR_USER_MASK
@ -1214,10 +1218,11 @@ function Cmd.gamevar(identifier, initval, flags)
g_gamevar[identifier] = gv
-- TODO: Write gamevar system on the Lunatic side and hook it up.
-- TODO: per-player gamevars. Currently, no error on using per-player var
-- in no-player context!
if (bit.band(flags, GVFLAG.PERX_MASK)==GVFLAG.PERACTOR) then
addcodef("%s=_con.actorvar(%d)", gv.name, initval)
elseif (bit.band(flags, GVFLAG.PERX_MASK)==GVFLAG.PERPLAYER and g_cgopt["playervar"]) then
gv.flags = bit.bor(gv.flags, GVFLAG.CON_PERPLAYER)
addcodef("%s=_con.playervar(%d)", gv.name, initval)
else
addcodef("%s=%d", gv.name, initval)
end
@ -1239,6 +1244,10 @@ function lookup.gamearray(identifier)
return ga.name
end
local function thisactor_to_pli(var)
return (var=="_aci") and "_pli" or var
end
-- <aorpvar>: code for actor or player index
function lookup.gamevar(identifier, aorpvar, writable)
local gv = g_gamevar[identifier]
@ -1255,6 +1264,8 @@ function lookup.gamevar(identifier, aorpvar, writable)
if (bit.band(gv.flags, GVFLAG.PERACTOR)~=0) then
return format("%s[%s]", gv.name, aorpvar)
elseif (bit.band(gv.flags, GVFLAG.CON_PERPLAYER)~=0 and g_cgopt["playervar"]) then
return format("%s[%s]", gv.name, thisactor_to_pli(aorpvar))
else
return gv.name
end
@ -1510,10 +1521,6 @@ local getperxvarcmd = -- get<actor/player>var[<idx>].<varname> <<var>>
local setperxvarcmd = -- set<actor/player>var[<idx>].<<varname>> <var>
arraypat * singlememberpat * sp1 * tok.rvar
local function thisactor_to_pli(var)
return (var=="_aci") and "_pli" or var
end
-- Function generating code for a struct read/write access.
local function StructAccess(Structname, writep, index, membertab)
assert(type(membertab)=="table")