mirror of
https://github.com/DrBeef/Raze.git
synced 2024-11-16 01:11:28 +00:00
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:
parent
358c7eb28b
commit
e0433e66fb
2 changed files with 60 additions and 16 deletions
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
|
Loading…
Reference in a new issue