From e0433e66fb8bf74f707802fde8110f0feb65e0ea Mon Sep 17 00:00:00 2001 From: helixhorned Date: Sat, 1 Jun 2013 20:09:41 +0000 Subject: [PATCH] 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 --- polymer/eduke32/source/lunatic/control.lua | 55 ++++++++++++++++++---- polymer/eduke32/source/lunatic/lunacon.lua | 21 ++++++--- 2 files changed, 60 insertions(+), 16 deletions(-) diff --git a/polymer/eduke32/source/lunatic/control.lua b/polymer/eduke32/source/lunatic/control.lua index 4ffe8dcdc..51c190d73 100644 --- a/polymer/eduke32/source/lunatic/control.lua +++ b/polymer/eduke32/source/lunatic/control.lua @@ -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", +} + +-- : default value for per-player variable. +-- : optional, a table of =value +function playervar(initval, values) + local plv = setmetatable({ _defval=initval }, playervar_mt) + return set_values_from_table(plv, values) +end diff --git a/polymer/eduke32/source/lunatic/lunacon.lua b/polymer/eduke32/source/lunatic/lunacon.lua index a7675bf1e..fdc3012e2 100644 --- a/polymer/eduke32/source/lunatic/lunacon.lua +++ b/polymer/eduke32/source/lunatic/lunacon.lua @@ -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 + -- : 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 = -- getvar[]. <> local setperxvarcmd = -- setvar[].<> 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")