LunaCON: implement NODEFAULT flag (1024) as session variables.

This is in contrast to C-CON, where the implications are not clearly obvious.
See this discussion/monologue:
http://forums.duke4.net/topic/955-eduke32-scripting/page__view__findpost__p__159613

Currently not implemented for session gamevars:
 - per-player, will be made a global one instead
 - per-actor, will be made a plain per-actor one instead

DONT_BUILD.

git-svn-id: https://svn.eduke32.com/eduke32@4112 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2013-10-20 12:35:06 +00:00
parent 937958afef
commit d9b94c772d
6 changed files with 63 additions and 8 deletions

View file

@ -20,6 +20,8 @@ MAXSKILLS = 7
MAXEVENTS = 95 -- KEEPINSYNC with EVENT_* list
MAXSOUNDS = 4096
MAXSESSIONVARS = 8 -- KEEPINSYNC lunatic_game.c
-- KEEPINSYNC quotes.h
-- For Lunatic, MAXQUOTES is OBITQUOTEINDEX because starting from that index

View file

@ -575,6 +575,7 @@ typedef struct {
]])
bcarray.new("weapondata_t", ffiC.MAX_WEAPONS, "weapon", "weapondata_x_MAX_WEAPONS", WEAPON_NAMES)
bcarray.new("int32_t", con_lang.MAXSESSIONVARS, "sessionvar", "int32_x_MAXSESSIONVARS")
-- EXTERNALLY EXPOSED GAME VARIABLES
ffi.cdef[[
@ -604,6 +605,7 @@ int32_t g_elCallDepth;
int32_t block_deletesprite;
const char **g_elModules;
char g_modDir[];
int32_x_MAXSESSIONVARS g_elSessionVar;
actor_t actor[MAXSPRITES];
camera_t g_camera;
user_defs ud;
@ -2344,10 +2346,12 @@ end
local varnameMap = {
gametic = "g_moveThingsCount",
RETURN = "g_RETURN",
_sessionVar = "g_elSessionVar",
}
gv_access.gametic = true
gv_access.RETURN = true
gv_access._sessionVar = true
local tmpmt = {
__index = function(_, key)

View file

@ -107,6 +107,7 @@ block_deletesprite;
g_RETURN;
g_elModules;
g_modDir;
g_elSessionVar;
MapInfo;
EpisodeNames;

View file

@ -254,6 +254,8 @@ local g_funcname = {}
local g_switchCode = nil
-- Global number of switch statements:
local g_switchCount = 0
-- Number of session gamevars:
local g_numSessionVars = 0
-- [identifier] = { name=<mangled name / code>, flags=<gamevar flags> }
local g_gamevar = {}
-- [identifier] = { name=<mangled name / code>, size=<initial size> }
@ -451,6 +453,7 @@ local function reset_codegen()
g_funcname = {}
g_switchCode = nil
g_switchCount = 0
g_numSessionVars = 0
g_gamevar = new_initial_gvartab()
g_gamearray = {
-- SYSTEM_GAMEARRAY
@ -1387,23 +1390,42 @@ function Cmd.gamevar(identifier, initval, flags)
return
end
local GVFLAG_NYI = GVFLAG.NODEFAULT + GVFLAG.NORESET
if (bit.band(flags, GVFLAG_NYI) ~= 0) then
warnprintf("gamevar \"%s\" flag(s) %d: not yet implemented",
identifier, bit.band(flags, GVFLAG_NYI))
if (bit.band(flags, GVFLAG.NORESET) ~= 0) then
warnprintf("gamevar \"%s\" flag NORESET (131072): not yet implemented",
identifier)
end
if (flags==GVFLAG.PERPLAYER+GVFLAG.PERACTOR) then
local perPlayer = (bit.band(flags, GVFLAG.PERPLAYER) ~= 0)
local perActor = (bit.band(flags, GVFLAG.PERACTOR) ~= 0)
if (perPlayer and perActor) then
errprintf("invalid gamevar flags: must be either PERPLAYER or PERACTOR, not both")
return
end
local ogv = g_gamevar[identifier]
local isSessionVar = (bit.band(flags, GVFLAG.NODEFAULT) ~= 0)
if (isSessionVar and (perPlayer or perActor)) then
if (ogv == nil) then -- warn only once per gamevar
warnprintf("per-%s for session gamevars: not yet implemented (made into %s)",
perPlayer and "player" or "actor",
perPlayer and "global" or "plain")
end
if (perActor) then
flags = bit.band(flags, bit.bnot(GVFLAG.NODEFAULT))
isSessionVar = false
elseif (perPlayer) then
flags = bit.band(flags, bit.bnot(GVFLAG.PERPLAYER))
perPlayer = false
end
end
if (ogv ~= nil) then
local oflags = ogv.flags
if (oflags ~= flags) then
if (bit.band(oflags, GVFLAG.SYSTEM) ~= 0) then
if (bit.band(oflags, GVFLAG.SYSTEM) ~= 0 and not isSessionVar) then
-- Attempt to override a system gamevar. See if it's read-only...
if (bit.band(oflags, GVFLAG.READONLY) ~= 0) then
errprintf("attempt to override read-only system gamevar `%s'", identifier)
@ -1450,14 +1472,28 @@ function Cmd.gamevar(identifier, initval, flags)
warnprintf("symbol `%s' already used for a defined %s", identifier, LABEL[ltype])
end
if (isSessionVar) then
if (g_numSessionVars == conl.MAXSESSIONVARS) then
errprintf("Declared too many session gamevars (flag 1024), can have at most %d.",
conl.MAXSESSIONVARS)
return
end
-- Declare new session gamevar.
g_gamevar[identifier] = { name=format("_gv._sessionVar[%d]", g_numSessionVars),
flags=flags }
g_numSessionVars = g_numSessionVars+1
return
end
local gv = { name=mangle_name(identifier, "V"), flags=flags }
g_gamevar[identifier] = gv
addcode("if _S then")
if (bit.band(flags, GVFLAG.PERX_MASK)==GVFLAG.PERACTOR) then
if (perActor) then
addcodef("%s=_con.actorvar(%d)", gv.name, initval)
elseif (bit.band(flags, GVFLAG.PERX_MASK)==GVFLAG.PERPLAYER and g_cgopt["playervar"]) then
elseif (perPlayer and g_cgopt["playervar"]) then
gv.flags = bit.bor(gv.flags, GVFLAG.CON_PERPLAYER)
addcodef("%s=_con.playervar(%d)", gv.name, initval)
else

View file

@ -31,6 +31,9 @@ uint8_t g_elEvents[MAXEVENTS];
// same thing for actors:
el_actor_t g_elActors[MAXTILES];
// Session variable. Never restored except by 'readgamevar'.
int32_t g_elSessionVar[8]; // MAXSESSIONVARS, KEEPINSYNC con_lang.lua
// Set to 1 on error in event.
int32_t g_elEventError;

View file

@ -151,3 +151,12 @@ endevent
onevent EVENT_ENTERLEVEL
loadmapstate
endevent
onevent EVENT_USEJETPACK
savegamevar numwarpsD
endevent
onevent EVENT_USENIGHTVISION
readgamevar numwarpsD
endevent