From ef25eb6329bec3a85e3fc801160a494cce100b40 Mon Sep 17 00:00:00 2001 From: helixhorned Date: Sat, 16 May 2015 14:27:03 +0000 Subject: [PATCH] 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 --- polymer/eduke32/source/lunatic/control.lua | 27 ++++++++++++++-------- polymer/eduke32/source/lunatic/lunacon.lua | 18 +++++++-------- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/polymer/eduke32/source/lunatic/control.lua b/polymer/eduke32/source/lunatic/control.lua index e85a9c650..a39ba03cc 100644 --- a/polymer/eduke32/source/lunatic/control.lua +++ b/polymer/eduke32/source/lunatic/control.lua @@ -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. -- [] = 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 = { -- : default value for per-actor variable. -- : optional, a table of =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 diff --git a/polymer/eduke32/source/lunatic/lunacon.lua b/polymer/eduke32/source/lunatic/lunacon.lua index 05072a2ba..7544fa84f 100644 --- a/polymer/eduke32/source/lunatic/lunacon.lua +++ b/polymer/eduke32/source/lunatic/lunacon.lua @@ -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)