Lunatic: getting closer to the first milestone.

On the C side, zrange, angrange and autoaimang are represented as
DukePlayer_t members then.

git-svn-id: https://svn.eduke32.com/eduke32@3366 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2013-01-02 22:33:37 +00:00
parent 67cdd9d883
commit 0c44056945
7 changed files with 467 additions and 291 deletions

View file

@ -24,22 +24,16 @@ MAXSOUNDS = 4096
MAXQUOTES = 16384 MAXQUOTES = 16384
MAXQUOTELEN = 128 MAXQUOTELEN = 128
local STR = {
-- KEEPINSYNC with gamedef.c:C_AddDefaultDefinitions() and the respective
-- defines. These are exported to the ffi.C namespace and as literal defines
-- in lunacon.lua.
labels =
{
{
STR_MAPNAME = 0, STR_MAPNAME = 0,
STR_MAPFILENAME = 1, STR_MAPFILENAME = 1,
STR_PLAYERNAME = 2, STR_PLAYERNAME = 2,
STR_VERSION = 3, STR_VERSION = 3,
STR_GAMETYPE = 4, STR_GAMETYPE = 4,
STR_VOLUMENAME = 5, STR_VOLUMENAME = 5,
}, }
{ PROJ = {
PROJ_WORKSLIKE = 0, PROJ_WORKSLIKE = 0,
PROJ_SPAWNS = 1, PROJ_SPAWNS = 1,
PROJ_SXREPEAT = 2, PROJ_SXREPEAT = 2,
@ -69,10 +63,11 @@ labels =
PROJ_BSOUND = 26, PROJ_BSOUND = 26,
PROJ_RANGE = 27, PROJ_RANGE = 27,
PROJ_FLASH_COLOR = 28, PROJ_FLASH_COLOR = 28,
}, }
{ -- TODO: EVENT_INIT currently can't run since we init Lunatic state only afterwards
EVENT_INIT = 0, -- TODO: currently can't run since we init Lunatic state only afterwards EVENT = {
EVENT_INIT = 0,
EVENT_ENTERLEVEL = 1, EVENT_ENTERLEVEL = 1,
EVENT_RESETWEAPONS = 2, EVENT_RESETWEAPONS = 2,
EVENT_RESETINVENTORY = 3, EVENT_RESETINVENTORY = 3,
@ -167,9 +162,9 @@ labels =
EVENT_SAVEGAME = 92, EVENT_SAVEGAME = 92,
EVENT_PREGAME = 93, EVENT_PREGAME = 93,
EVENT_CHANGEMENU = 94, EVENT_CHANGEMENU = 94,
}, }
{ local SFLAG = {
SFLAG_SHADOW = 0x00000001, SFLAG_SHADOW = 0x00000001,
SFLAG_NVG = 0x00000002, SFLAG_NVG = 0x00000002,
SFLAG_NOSHADE = 0x00000004, SFLAG_NOSHADE = 0x00000004,
@ -188,9 +183,9 @@ labels =
-- SFLAG_BADGUYSTAYPUT = 0x00008000, -- SFLAG_BADGUYSTAYPUT = 0x00008000,
-- SFLAG_CACHE = 0x00010000, -- SFLAG_CACHE = 0x00010000,
-- SFLAG_ROTFIXED = 0x00020000, -- SFLAG_ROTFIXED = 0x00020000,
}, }
{ STAT = {
STAT_DEFAULT = 0, STAT_DEFAULT = 0,
STAT_ACTOR = 1, STAT_ACTOR = 1,
STAT_ZOMBIEACTOR = 2, STAT_ZOMBIEACTOR = 2,
@ -207,9 +202,9 @@ labels =
STAT_DUMMYPLAYER = 13, STAT_DUMMYPLAYER = 13,
STAT_LIGHT = 14, STAT_LIGHT = 14,
STAT_NETALLOC = 15, STAT_NETALLOC = 15,
}, }
{ local GAMEFUNC = {
GAMEFUNC_MOVE_FORWARD = 0, GAMEFUNC_MOVE_FORWARD = 0,
GAMEFUNC_MOVE_BACKWARD = 1, GAMEFUNC_MOVE_BACKWARD = 1,
GAMEFUNC_TURN_LEFT = 2, GAMEFUNC_TURN_LEFT = 2,
@ -267,6 +262,18 @@ labels =
GAMEFUNC_DPAD_SELECT = 54, GAMEFUNC_DPAD_SELECT = 54,
GAMEFUNC_DPAD_AIMING = 55, GAMEFUNC_DPAD_AIMING = 55,
} }
-- KEEPINSYNC with gamedef.c:C_AddDefaultDefinitions() and the respective
-- defines. These are exported to the ffi.C namespace and as literal defines
-- in lunacon.lua.
labels =
{
STR,
PROJ,
EVENT,
SFLAG,
STAT,
GAMEFUNC,
} }

View file

@ -20,7 +20,7 @@ local cansee, hitscan, neartag = dc.cansee, dc.hitscan, dc.neartag
local inside = dc.inside local inside = dc.inside
local sector, wall, sprite = dc.sector, dc.wall, dc.sprite local sector, wall, sprite = dc.sector, dc.wall, dc.sprite
local spritesofsect = dc.spritesofsect local spritesofsect, spritesofstat = dc.spritesofsect, dc.spritesofstat
module(...) module(...)
@ -304,6 +304,7 @@ end
local D = { local D = {
-- TODO: dynamic tile remapping -- TODO: dynamic tile remapping
ACTIVATOR = 2, ACTIVATOR = 2,
RESPAWN = 9,
APLAYER = 1405, APLAYER = 1405,
FIRSTAID = 53, FIRSTAID = 53,
@ -314,8 +315,23 @@ local D = {
BOOTS = 61, BOOTS = 61,
HOLODUKE = 1348, HOLODUKE = 1348,
STATUE = 753,
NAKED1 = 603,
PODFEM1 = 1294,
FEM1 = 1312,
FEM2 = 1317,
FEM3 = 1321,
FEM5 = 1323,
FEM4 = 1325,
FEM6 = 1334,
FEM8 = 1336,
FEM7 = 1395,
FEM9 = 3450,
FEM10 = 4864,
ATOMICHEALTH = 100, ATOMICHEALTH = 100,
GLASSPIECES = 1031, GLASSPIECES = 1031,
TRANSPORTERSTAR = 1630,
COMMANDER = 1920, COMMANDER = 1920,
JIBS2 = 2250, JIBS2 = 2250,
SCRAP1 = 2400, SCRAP1 = 2400,
@ -713,7 +729,7 @@ end
function _canseetarget(spr, ps) function _canseetarget(spr, ps)
-- NOTE: &41 ? -- NOTE: &41 ?
return cansee(spr^krandand(41), spr.sectnum, return cansee(spr^(256*krandand(41)), spr.sectnum,
ps.pos, sprite[ps.i].sectnum) ps.pos, sprite[ps.i].sectnum)
end end
@ -855,10 +871,55 @@ end
function _flash(spr, ps) function _flash(spr, ps)
spr.shade = -127 spr.shade = -127
ps.visibility = -127 ps.visibility = -127 -- XXX
ffiC.lastvisinc = ffiC.totalclock+32 ffiC.lastvisinc = ffiC.totalclock+32
end end
local function G_OperateRespawns(tag)
for i in spritesofstat(ffiC.STAT_FX) do
local spr = sprite[i]
if (spr.lotag==tag and spr.picnum==D.RESPAWN) then
if (ffiC.ud.monsters_off~=0 and isenemytile(spr.hitag)) then
return
end
local j = spawn(i, D.TRANSPORTERSTAR)
sprite[j].z = sprite[j].z - (32*256)
-- Just a way to killit (see G_MoveFX(): RESPAWN__STATIC)
spr.extra = 66-12
end
end
end
local RESPAWN_USE_YVEL =
{
[D.STATUE] = true,
[D.NAKED1] = true,
[D.PODFEM1] = true,
[D.FEM1] = true,
[D.FEM2] = true,
[D.FEM3] = true,
[D.FEM5] = true,
[D.FEM4] = true,
[D.FEM6] = true,
[D.FEM8] = true,
[D.FEM7] = true,
[D.FEM9] = true,
[D.FEM10] = true,
}
function _respawnhitag(spr)
if (RESPAWN_USE_YVEL[spr.picnum]) then
if (spr.yvel ~= 0) then
G_OperateRespawns(spr.yvel)
end
else
G_OperateRespawns(spr.hitag)
end
end
local INVENTILE = { local INVENTILE = {
[D.FIRSTAID] = true, [D.FIRSTAID] = true,
[D.STEROIDS] = true, [D.STEROIDS] = true,
@ -879,6 +940,48 @@ function _checkrespawn(spr)
return (ffiC.ud.respawn_items~=0) return (ffiC.ud.respawn_items~=0)
end end
-- SOUNDS
local function check_sound_idx(sndidx)
if (sndidx >= con_lang.MAXSOUNDS+0ULL) then
error("invalid sound number "..sndidx, 2)
end
end
function _ianysound(aci)
check_sprite_idx(aci)
return (ffiC.A_CheckAnySoundPlaying(aci)~=0)
end
function _sound(aci, sndidx)
check_sprite_idx(aci)
ffiC.A_PlaySound(sndidx, aci)
end
function _globalsound(pli, sndidx)
-- TODO: conditional on coop, fake multimode
if (pli==ffiC.screenpeek) then
_sound(player[pli].i, sndidx)
end
end
function _stopsound(aci, sndidx)
check_sprite_idx(aci)
check_sound_idx(sndidx)
-- XXX: This is weird: the checking is done wrt a sprite, but the sound not.
-- NOTE: S_StopSound() stops sound <sndidx> that started playing most recently.
if (ffiC.S_CheckSoundPlaying(aci, sndidx) ~= 0) then
S_StopSound(sndidx)
end
end
function _soundonce(aci, sndidx)
check_sound_idx(sndidx)
if (ffiC.S_CheckSoundPlaying(aci, sndidx) == 0) then
_sound(aci, sndidx)
end
end
--- Exported functions --- --- Exported functions ---

View file

@ -164,6 +164,9 @@ local DUKEPLAYER_STRUCT = [[
uint32_t interface_toggle_flag; uint32_t interface_toggle_flag;
int32_t zrange;
int16_t angrange, autoaimang;
uint16_t max_actors_killed, actors_killed; uint16_t max_actors_killed, actors_killed;
uint16_t gotweapon, zoom; uint16_t gotweapon, zoom;
@ -455,6 +458,7 @@ tiledata_t g_tile[MAXTILES];
char *ScriptQuotes[]; char *ScriptQuotes[];
const int32_t playerswhenstarted; const int32_t playerswhenstarted;
const int32_t screenpeek;
int32_t lastvisinc; int32_t lastvisinc;
int16_t g_spriteDeleteQueueSize; int16_t g_spriteDeleteQueueSize;
int16_t BlimpSpawnSprites[15]; int16_t BlimpSpawnSprites[15];
@ -476,6 +480,11 @@ int32_t A_Spawn(int32_t j, int32_t pn);
void A_AddToDeleteQueue(int32_t i); void A_AddToDeleteQueue(int32_t i);
void P_DoQuote(int32_t q, DukePlayer_t *p); void P_DoQuote(int32_t q, DukePlayer_t *p);
void G_ClearCameraView(DukePlayer_t *ps); void G_ClearCameraView(DukePlayer_t *ps);
int32_t A_CheckAnySoundPlaying(int32_t i);
int32_t A_PlaySound(uint32_t num, int32_t i);
int32_t S_CheckSoundPlaying(int32_t i, int32_t num);
void S_StopSound(int32_t num);
]] ]]
-- functions -- functions
@ -792,7 +801,7 @@ local player_mt = {
} }
ffi.metatype("DukePlayer_t", player_mt) ffi.metatype("DukePlayer_t", player_mt)
-- Declare all con_lang.labels constants in the global FFI namespace.
for i=1,#con_lang.labels do for i=1,#con_lang.labels do
local strbuf = {"enum {"} local strbuf = {"enum {"}
@ -1077,7 +1086,7 @@ local function our_gameevent(event, func)
if (event:sub(1,6) ~= "EVENT_") then if (event:sub(1,6) ~= "EVENT_") then
event = "EVENT_"..event event = "EVENT_"..event
end end
local eventidx = con_lang.labels[3][event] -- 3: event list local eventidx = con_lang.labels.EVENT[event]
if (eventidx == nil) then if (eventidx == nil) then
errorf(2, "gameevent: invalid event label %q", event) errorf(2, "gameevent: invalid event label %q", event)
end end

View file

@ -75,6 +75,7 @@ g_tile;
ScriptQuotes; ScriptQuotes;
screenpeek;
playerswhenstarted; playerswhenstarted;
lastvisinc; lastvisinc;
g_spriteDeleteQueueSize; g_spriteDeleteQueueSize;
@ -108,4 +109,9 @@ A_Spawn;
A_AddToDeleteQueue; A_AddToDeleteQueue;
P_DoQuote; P_DoQuote;
G_ClearCameraView; G_ClearCameraView;
A_CheckAnySoundPlaying;
A_PlaySound;
S_CheckSoundPlaying;
S_StopSound;
}; };

View file

@ -29,7 +29,7 @@ local ffi, ffiC
if (string.dump) then if (string.dump) then
bit = require("bit") bit = require("bit")
-- For Rio Lua: -- For Rio Lua:
bit = { bor=function() return 0 end } -- bit = { bor=function() return 0 end }
require("strict") require("strict")
else else
bit = require("bit") bit = require("bit")
@ -91,8 +91,8 @@ local g_warn = { ["not-redefined"]=true, ["bad-identifier"]=true,
-- How many 'if' statements are following immediately each other, -- How many 'if' statements are following immediately each other,
-- needed to cope with CONs dangling-else resolution -- needed to cope with CONs dangling-else resolution
local g_ifseqlevel = 0 local g_iflevel = 0
local g_ifelselevel = 0
---=== Code generation ===--- ---=== Code generation ===---
local g_have_file = {} -- [filename]=true local g_have_file = {} -- [filename]=true
@ -108,7 +108,8 @@ local function getlinecol(pos) end -- fwd-decl
local function new_initial_codetab() local function new_initial_codetab()
return { return {
"local _con, _bit, _math = require'con', require'bit', require'math';", "local _con, _bit, _math = require'con', require'bit', require'math';",
"local sector, sprite, actor, player = sector, sprite, actor, player;" "local sector, sprite, actor, player = sector, sprite, actor, player;",
"local gameactor=gameactor;"
} }
end end
@ -156,7 +157,7 @@ local function on_actor_end(usertype, tsamm, codetab)
end end
local function on_state_end(statename, codetab) local function on_state_end(statename, codetab)
-- TODO: mangle names, make them accessible from other translation units -- TODO: mangle names
addcodef("local function %s(_aci, _pli, _dist)", statename) addcodef("local function %s(_aci, _pli, _dist)", statename)
assert(type(codetab)=="table") assert(type(codetab)=="table")
addcode(codetab) addcode(codetab)
@ -278,7 +279,7 @@ local function do_define_label(identifier, num)
else else
-- conl.labels[...]: don't warn for wrong PROJ_ redefinitions -- conl.labels[...]: don't warn for wrong PROJ_ redefinitions
if (g_warn["not-redefined"]) then if (g_warn["not-redefined"]) then
if (oldval ~= num and conl.labels[2][identifier]==nil) then if (oldval ~= num and conl.labels.PROJ[identifier]==nil) then
warnprintf("label \"%s\" not redefined with new value %d (old: %d)", warnprintf("label \"%s\" not redefined with new value %d (old: %d)",
identifier, num, oldval) identifier, num, oldval)
end end
@ -796,6 +797,10 @@ local function handle_move(mv, ...)
return format(ACS":set_move(%s,%d)", mv, (flags[1] and bit.bor(...)) or 0) return format(ACS":set_move(%s,%d)", mv, (flags[1] and bit.bor(...)) or 0)
end end
local function handle_debug(val)
return format("print('%s:%d: debug %d')", g_filename, getlinecol(g_lastkwpos), val)
end
-- NOTE about prefixes: most is handled by all_alt_pattern(), however commands -- NOTE about prefixes: most is handled by all_alt_pattern(), however commands
-- that have no arguments and that are prefixes of other commands MUST be -- that have no arguments and that are prefixes of other commands MUST be
-- suffixed with a "* #sp1" pattern. -- suffixed with a "* #sp1" pattern.
@ -961,13 +966,13 @@ local Ci = {
angoff = cmd(D) angoff = cmd(D)
/ "spritext[_aci].angoff=%1", / "spritext[_aci].angoff=%1",
debug = cmd(D) debug = cmd(D)
/ "", -- TODO? / handle_debug,
endofgame = cmd(D) endofgame = cmd(D)
/ "_con._endofgame(_pli,%1)", / "_con._endofgame(_pli,%1)",
eqspawn = cmd(D), eqspawn = cmd(D),
espawn = cmd(D), espawn = cmd(D),
globalsound = cmd(D) globalsound = cmd(D)
/ "", / "_con._globalsound(_pli,%1)",
lotsofglass = cmd(D) lotsofglass = cmd(D)
/ "_con._A_SpawnGlass(_aci,%1)", / "_con._A_SpawnGlass(_aci,%1)",
mail = cmd(D) mail = cmd(D)
@ -984,13 +989,14 @@ local Ci = {
save = cmd(D), save = cmd(D),
sleeptime = cmd(D) sleeptime = cmd(D)
/ ACS".timetosleep=%1", / ACS".timetosleep=%1",
soundonce = cmd(D), soundonce = cmd(D)
/ "_con._soundonce(_aci,%1)",
sound = cmd(D) sound = cmd(D)
/ "", -- TODO: all things audio... / "_con._sound(_aci,%1)",
spawn = cmd(D) spawn = cmd(D)
/ "_con.spawn(_aci,%1)", / "_con.spawn(_aci,%1)",
stopsound = cmd(D) stopsound = cmd(D)
/ "", / "_con._stopsound(_aci,%1)",
eshoot = cmd(D), eshoot = cmd(D),
ezshoot = cmd(R,D), ezshoot = cmd(R,D),
@ -1003,7 +1009,7 @@ local Ci = {
fall = cmd() fall = cmd()
/ "_con._VM_FallSprite(_aci)", / "_con._VM_FallSprite(_aci)",
flash = cmd() flash = cmd()
/ format("_con._flash(%s,%s)", ACS"", SPS""), / format("_con._flash(%s,%s)", SPS"", PLS""),
getlastpal = cmd() getlastpal = cmd()
/ "_con._getlastpal(_aci)", / "_con._getlastpal(_aci)",
insertspriteq = cmd() insertspriteq = cmd()
@ -1011,7 +1017,7 @@ local Ci = {
killit = cmd() -- NLCF killit = cmd() -- NLCF
/ "_con.killit()", / "_con.killit()",
mikesnd = cmd() mikesnd = cmd()
/ "", -- TODO / format("_con._soundonce(_aci,%s)", SPS".yvel"),
nullop = cmd() nullop = cmd()
/ "", -- NOTE: really generate no code / "", -- NOTE: really generate no code
pkick = cmd() pkick = cmd()
@ -1025,7 +1031,7 @@ local Ci = {
resetplayer = cmd() -- NLCF resetplayer = cmd() -- NLCF
/ "if (_con._VM_ResetPlayer2(_pli,_aci)) then _con.longjmp() end", / "if (_con._VM_ResetPlayer2(_pli,_aci)) then _con.longjmp() end",
respawnhitag = cmd() respawnhitag = cmd()
/ "", -- TODO / format("_con._respawnhitag(%s)", SPS""),
tip = cmd() tip = cmd()
/ PLS".tipincs=26", / PLS".tipincs=26",
tossweapon = cmd() tossweapon = cmd()
@ -1176,13 +1182,13 @@ local Cif = {
ifrnd = cmd(D) ifrnd = cmd(D)
/ "_con.rnd(%1)", / "_con.rnd(%1)",
ifpdistl = cmd(D) ifpdistl = cmd(D)
/ function(val) return "_dist<"..val end, --, "_con.sleepcheck(_aci,_dist)" end, / function(val) return "_dist<"..val, "", "_con._sleepcheck(_aci,_dist)" end,
ifpdistg = cmd(D) ifpdistg = cmd(D)
/ function(val) return "_dist>"..val end, --"_con.sleepcheck(_aci,_dist)" end, / function(val) return "_dist>"..val, "", "_con._sleepcheck(_aci,_dist)" end,
ifactioncount = cmd(D) ifactioncount = cmd(D)
/ ACS":get_acount()==%1", / ACS":get_acount()>=%1",
ifcount = cmd(D) ifcount = cmd(D)
/ ACS":get_count()==%1", / ACS":get_count()>=%1",
ifactor = cmd(D) ifactor = cmd(D)
/ SPS".picnum==%1", / SPS".picnum==%1",
ifstrength = cmd(D) ifstrength = cmd(D)
@ -1246,7 +1252,7 @@ local Cif = {
ifnotmoving = cmd() ifnotmoving = cmd()
/ "_bit.band(actor[_aci].movflag,49152)>16384", / "_bit.band(actor[_aci].movflag,49152)>16384",
ifnosounds = cmd() ifnosounds = cmd()
/ "false", / "not _con._ianysound()",
ifmultiplayer = cmd() ifmultiplayer = cmd()
/ "false", -- TODO? / "false", -- TODO?
ifinwater = cmd() ifinwater = cmd()
@ -1264,8 +1270,8 @@ local Cif = {
ifclient = cmd(), ifclient = cmd(),
ifcanshoottarget = cmd() ifcanshoottarget = cmd()
/ "_con._canshoottarget(_dist,_aci)", / "_con._canshoottarget(_dist,_aci)",
ifcanseetarget = cmd() -- TODO: conditionally set timetosleep afterwards ifcanseetarget = cmd() -- XXX: 1536 is SLEEPTIME
/ format("_con._canseetarget(%s,%s)", SPS"", PLS""), / function() return format("_con._canseetarget(%s,%s)", SPS"", PLS""), ACS".timetosleep=1536" end,
ifcansee = cmd() * #sp1 ifcansee = cmd() * #sp1
/ format("_con._cansee(_aci,%s)", PLS""), / format("_con._cansee(_aci,%s)", PLS""),
ifbulletnear = cmd() ifbulletnear = cmd()
@ -1396,9 +1402,12 @@ local function after_if_cmd_Cmt(subj, pos, ...)
return nil return nil
end end
if (type(capts[1])=="string" and (capts[2]==nil or type(capts[2])=="string") and capts[3]==nil) then if (capts[1] ~= nil) then
assert(capts[2]==nil or capts[2]=="_con.sleepcheck(_aci,_dist)") assert(#capts <= 3)
return true, capts[1], capts[2] for i=1,#capts do
assert(type(capts[i]=="string"))
end
return true, unpack(capts, 1, #capts)
end end
return true return true
@ -1516,39 +1525,60 @@ local t_good_identifier = Range("AZ", "az", "__") * Range("AZ", "az", "__", "09"
-- This is broken in itself, so we ought to make a compatibility/modern CON switch. -- This is broken in itself, so we ought to make a compatibility/modern CON switch.
local t_broken_identifier = BadIdent(-((t_number + t_good_identifier) * (sp1 + Set("[]:"))) * local t_broken_identifier = BadIdent(-((t_number + t_good_identifier) * (sp1 + Set("[]:"))) *
(alphanum + Set("_/\\*?")) * (alphanum + Set("_/\\*-+?"))^0) (alphanum + Set("_/\\*?")) * (alphanum + Set("_/\\*-+?"))^0)
local g_ifStack = {}
local function begin_if_fn(condstr, endifstr) -- These two tables hold code to be inserted at a later point: either at
g_ifseqlevel = g_ifseqlevel+1 -- the end of the "if" body, or the end of the whole "if [else]" block.
-- For CON interpreter patterns like these:
-- VM_CONDITIONAL(<condition>);
-- <do_something_afterwards>
-- (Still not the same if the body returns or jumps out)
local g_endIfCode = {}
local g_endIfElseCode = {}
local function add_deferred_code(tab, lev, str)
if (str ~= nil) then
assert(type(str)=="string")
tab[lev] = str
end
end
local function get_deferred_code(tab, lev, code)
if (tab[lev]) then
code = code..tab[lev]
tab[lev] = nil
end
return code
end
local function begin_if_fn(condstr, endifstr, endifelsestr)
condstr = condstr or "TODO" condstr = condstr or "TODO"
assert(type(condstr)=="string") assert(type(condstr)=="string")
if (endifstr ~= nil) then add_deferred_code(g_endIfCode, g_iflevel, endifstr)
assert(type(endifstr)=="string") add_deferred_code(g_endIfElseCode, g_ifelselevel, endifelsestr)
g_ifStack[#g_ifStack+1] = endifstr
end g_iflevel = g_iflevel+1
g_ifelselevel = g_ifelselevel+1
return format("if (%s) then", condstr) return format("if (%s) then", condstr)
end end
local function end_if_fn() local function end_if_fn()
local code g_iflevel = g_iflevel-1
if (#g_ifStack > 0) then local code = get_deferred_code(g_endIfCode, g_iflevel, "")
code = g_ifStack[#g_ifStack] if (code ~= "") then
g_ifStack[#g_ifStack] = nil
end
g_ifseqlevel = g_ifseqlevel-1
if (code) then
-- The condition above is significant here.
-- (See lpeg.c: functioncap(), where a lua_call(..., LUA_MULTRET) is done)
return code return code
end end
end end
local function end_if_else_fn()
g_ifelselevel = g_ifelselevel-1
return get_deferred_code(g_endIfElseCode, g_ifelselevel, "end ")
end
local function check_else_Cmt() local function check_else_Cmt()
-- match an 'else' only at the outermost level -- match an 'else' only at the outermost level
local good = (g_ifseqlevel==0) local good = (g_iflevel==0)
if (good) then if (good) then
return true, "else" return true, "else"
end end
@ -1610,7 +1640,7 @@ local Grammar = Pat{
if_stmt = con_if_begs/begin_if_fn * sp1 if_stmt = con_if_begs/begin_if_fn * sp1
* Var("single_stmt") * (Pat("")/end_if_fn) * Var("single_stmt") * (Pat("")/end_if_fn)
* (sp1 * lpeg.Cmt(Pat("else"), check_else_Cmt) * sp1 * Var("single_stmt"))^-1 * (sp1 * lpeg.Cmt(Pat("else"), check_else_Cmt) * sp1 * Var("single_stmt"))^-1
* lpeg.Cc("end"), * (Pat("")/end_if_else_fn),
-- TODO?: SST TC has "state ... else ends" -- TODO?: SST TC has "state ... else ends"
while_stmt = Keyw("whilevarvarn") * sp1 * t_rvar * sp1 * t_rvar * sp1 * Var("single_stmt") while_stmt = Keyw("whilevarvarn") * sp1 * t_rvar * sp1 * t_rvar * sp1 * Var("single_stmt")
@ -1687,7 +1717,8 @@ function parse(contents) -- local
local lastkw, lastkwpos, numerrors = g_lastkw, g_lastkwpos, g_numerrors local lastkw, lastkwpos, numerrors = g_lastkw, g_lastkwpos, g_numerrors
local newlineidxs = g_newlineidxs local newlineidxs = g_newlineidxs
g_ifseqlevel = 0 g_iflevel = 0
g_ifelselevel = 0
g_have_file[g_filename] = true g_have_file[g_filename] = true
-- set up new state -- set up new state

View file

@ -342,13 +342,21 @@ static int32_t GetAutoAimAngle(int32_t i, int32_t p, int32_t atwith,
Bassert((unsigned)p < MAXPLAYERS); Bassert((unsigned)p < MAXPLAYERS);
#ifdef LUNATIC
g_player[p].ps->autoaimang = AUTO_AIM_ANGLE;
#else
Gv_SetVar(g_iAimAngleVarID, AUTO_AIM_ANGLE, i, p); Gv_SetVar(g_iAimAngleVarID, AUTO_AIM_ANGLE, i, p);
#endif
if (G_HaveEvent(EVENT_GETAUTOAIMANGLE)) if (G_HaveEvent(EVENT_GETAUTOAIMANGLE))
VM_OnEvent(EVENT_GETAUTOAIMANGLE, i, p, -1, 0); VM_OnEvent(EVENT_GETAUTOAIMANGLE, i, p, -1, 0);
{ {
#ifdef LUNATIC
int32_t aimang = g_player[p].ps->autoaimang;
#else
int32_t aimang = Gv_GetVar(g_iAimAngleVarID, i, p); int32_t aimang = Gv_GetVar(g_iAimAngleVarID, i, p);
#endif
if (aimang > 0) if (aimang > 0)
j = A_FindTargetSprite(&sprite[i], aimang, atwith); j = A_FindTargetSprite(&sprite[i], aimang, atwith);
} }
@ -445,18 +453,27 @@ static void P_PreFireHitscan(int32_t i, int32_t p, int32_t atwith,
int32_t zRange=256; int32_t zRange=256;
int32_t j = GetAutoAimAngle(i, p, atwith, 5<<8, 0+1, srcvect, 256, zvel, sa); int32_t j = GetAutoAimAngle(i, p, atwith, 5<<8, 0+1, srcvect, 256, zvel, sa);
const DukePlayer_t *const ps = g_player[p].ps; DukePlayer_t *const ps = g_player[p].ps;
#ifdef LUNATIC
ps->angrange = angRange;
ps->zrange = zRange;
#else
Gv_SetVar(g_iAngRangeVarID,angRange, i,p); Gv_SetVar(g_iAngRangeVarID,angRange, i,p);
Gv_SetVar(g_iZRangeVarID,zRange,i,p); Gv_SetVar(g_iZRangeVarID,zRange,i,p);
#endif
if (G_HaveEvent(EVENT_GETSHOTRANGE)) if (G_HaveEvent(EVENT_GETSHOTRANGE))
VM_OnEvent(EVENT_GETSHOTRANGE, i,p, -1, 0); VM_OnEvent(EVENT_GETSHOTRANGE, i,p, -1, 0);
#if !defined LUNATIC_ONLY
// TODO #if defined LUNATIC
angRange = ps->angrange;
zRange = ps->zrange;
#else
angRange=Gv_GetVar(g_iAngRangeVarID,i,p); angRange=Gv_GetVar(g_iAngRangeVarID,i,p);
zRange=Gv_GetVar(g_iZRangeVarID,i,p); zRange=Gv_GetVar(g_iZRangeVarID,i,p);
#endif #endif
if (accurate_autoaim_p) if (accurate_autoaim_p)
{ {
if (!ps->auto_aim) if (!ps->auto_aim)

View file

@ -164,7 +164,10 @@ typedef struct {
int32_t autostep, autostep_sbw; int32_t autostep, autostep_sbw;
uint32_t interface_toggle_flag; uint32_t interface_toggle_flag;
#ifdef LUNATIC
int32_t zrange;
int16_t angrange, autoaimang;
#endif
uint16_t max_actors_killed, actors_killed; uint16_t max_actors_killed, actors_killed;
uint16_t gotweapon, zoom; uint16_t gotweapon, zoom;