LunaCON: implement NODEFAULT per-actor gamevars in the C-CON fashion.

For glocal gamevars, the LunaCON semantics (session gamevar) are kept.
For per-actor ones, this now prevents resetting a gamevar's value to
default on spawn or loadactor. BUILD_LUNATIC.

git-svn-id: https://svn.eduke32.com/eduke32@5194 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2015-05-16 14:27:03 +00:00
parent c3b3b376fa
commit ef25eb6329
2 changed files with 27 additions and 18 deletions

View file

@ -234,7 +234,7 @@ local function check_allnumbers(...)
end
-- Table of all per-actor gamevars active in the system.
-- Table of all non-NODEFAULT per-actor gamevars active in the system.
-- [<actorvar reference>] = true
local g_actorvar = setmetatable({}, { __mode="k" })
@ -2060,12 +2060,12 @@ local function serialize_value(strtab, i, v)
end
-- Common serialization function for gamearray and actorvar.
local function serialize_array(ar, strtab, maxnum)
local function serialize_array(ar, strtab, maxnum, suffix)
for i=0,maxnum-1 do
serialize_value(strtab, i, rawget(ar, i))
end
strtab[#strtab+1] = "})"
strtab[#strtab+1] = "}"..(suffix or "")..")"
return table.concat(strtab)
end
@ -2316,11 +2316,13 @@ end
local actorvar_methods = {
--- Internal routines ---
-- * All values for sprites not in the game world are cleared.
-- * All values for sprites not in the game world are cleared (non-NODEFAULT only).
-- * All values equal to the default one are cleared.
_cleanup = function(acv)
for i=0,ffiC.MAXSPRITES-1 do
if (ffiC.sprite[i].statnum == ffiC.MAXSTATUS or rawget(acv, i)==acv._defval) then
-- NOTE: NODEFAULT per-actor gamevars are used in a non-actor fashion
if ((not acv:_is_nodefault() and ffiC.sprite[i].statnum == ffiC.MAXSTATUS)
or rawget(acv, i)==acv._defval) then
acv:_clear(i)
end
end
@ -2330,6 +2332,10 @@ local actorvar_methods = {
rawset(acv, i, nil)
end,
_is_nodefault = function(acv, i)
return rawget(acv, '_nodefault')
end,
--- Serialization ---
_get_require = our_get_require,
@ -2339,7 +2345,8 @@ local actorvar_methods = {
-- A_ResetVars() and related functions above.)
acv:_cleanup()
local strtab = { "_av(", tostring(acv._defval), ",{" }
return serialize_array(acv, strtab, ffiC.MAXSPRITES)
return serialize_array(acv, strtab, ffiC.MAXSPRITES,
acv:_is_nodefault() and ",true")
end,
}
@ -2364,10 +2371,12 @@ local actorvar_mt = {
-- <initval>: default value for per-actor variable.
-- <values>: optional, a table of <spritenum>=value
function actorvar(initval, values)
function actorvar(initval, values, nodefault)
check_perxval_type(initval)
local acv = setmetatable({ _defval=initval }, actorvar_mt)
g_actorvar[acv] = true
local acv = setmetatable({ _defval=initval, _nodefault=nodefault }, actorvar_mt)
if (not nodefault) then
g_actorvar[acv] = true
end
return set_values_from_table(acv, values)
end

View file

@ -1595,20 +1595,20 @@ function Cmd.gamevar(identifier, initval, flags)
local isSessionVar = (bit.band(flags, GVFLAG.NODEFAULT) ~= 0)
local storeWithSavegames = (bit.band(flags, GVFLAG.NORESET) == 0)
if (isSessionVar and (perPlayer or perActor)) then
if (ogv == nil) then -- warn only once per gamevar
warnprintf("per-%s session gamevar `%s': NYI, made %s",
perPlayer and "player" or "actor",
identifier,
perPlayer and "global" or "non-session")
end
local actorVarSuffix = ""
if (isSessionVar and (perPlayer or perActor)) then
if (perActor) then
flags = bit.band(flags, bit.bnot(GVFLAG.NODEFAULT))
actorVarSuffix = ",nil,true"
-- flags = bit.band(flags, bit.bnot(GVFLAG.NODEFAULT))
isSessionVar = false
elseif (perPlayer) then
flags = bit.band(flags, bit.bnot(GVFLAG.PERPLAYER))
perPlayer = false
if (ogv == nil) then -- warn only once per gamevar
warnprintf("per-player session gamevar `%s': NYI, made global", identifier)
end
end
end
@ -1694,7 +1694,7 @@ function Cmd.gamevar(identifier, initval, flags)
end
if (perActor) then
addcodef("%s=_con.actorvar(%d)", gv.name, initval)
addcodef("%s=_con.actorvar(%d%s)", gv.name, initval, actorVarSuffix)
elseif (perPlayer and g_cgopt["playervar"]) then
gv.flags = bit.bor(gv.flags, GVFLAG.CON_PERPLAYER)
addcodef("%s=_con.playervar(%d)", gv.name, initval)