From eda5b220308cef98da95d67ed1e637524d4d2cf4 Mon Sep 17 00:00:00 2001 From: helixhorned Date: Tue, 1 Jan 2013 15:24:28 +0000 Subject: [PATCH] Lunatic: more code... git-svn-id: https://svn.eduke32.com/eduke32@3357 1a8010ca-5511-0410-912e-c29ae57300e0 --- polymer/eduke32/source/gamedef.c | 6 ++ polymer/eduke32/source/lunatic/con_lang.lua | 4 + polymer/eduke32/source/lunatic/control.lua | 105 ++++++++++++++++---- polymer/eduke32/source/lunatic/defs.ilua | 5 + polymer/eduke32/source/lunatic/dynsymlist | 5 + polymer/eduke32/source/lunatic/lunacon.lua | 61 ++++++++++-- 6 files changed, 156 insertions(+), 30 deletions(-) diff --git a/polymer/eduke32/source/gamedef.c b/polymer/eduke32/source/gamedef.c index ce764c7f5..2b132982f 100644 --- a/polymer/eduke32/source/gamedef.c +++ b/polymer/eduke32/source/gamedef.c @@ -2128,6 +2128,12 @@ void C_DefineSound(int32_t sndidx, const char *fn, int32_t args[5]) g_maxSoundPos = sndidx; } } + +void C_DefineQuote(int32_t qnum, const char *qstr) +{ + C_AllocQuote(qnum); + Bstrncpyz(ScriptQuotes[qnum], qstr, MAXQUOTELEN); +} #endif int32_t C_AllocQuote(int32_t qnum) diff --git a/polymer/eduke32/source/lunatic/con_lang.lua b/polymer/eduke32/source/lunatic/con_lang.lua index 753b81aa3..dc0ed1219 100644 --- a/polymer/eduke32/source/lunatic/con_lang.lua +++ b/polymer/eduke32/source/lunatic/con_lang.lua @@ -20,6 +20,10 @@ MAXSKILLS = 7 MAXEVENTS = 95 -- KEEPINSYNC with EVENT_* list MAXSOUNDS = 4096 +-- KEEPINSYNC quotes.h +MAXQUOTES = 16384 +MAXQUOTELEN = 128 + -- KEEPINSYNC with gamedef.c:C_AddDefaultDefinitions() and the respective -- defines. These are exported to the ffi.C namespace and as literal defines diff --git a/polymer/eduke32/source/lunatic/control.lua b/polymer/eduke32/source/lunatic/control.lua index 9ff0bd2b5..41a62dff6 100644 --- a/polymer/eduke32/source/lunatic/control.lua +++ b/polymer/eduke32/source/lunatic/control.lua @@ -6,6 +6,7 @@ local ffiC = ffi.C local bit = require("bit") local math = require("math") local geom = require("geom") +local con_lang = require("con_lang") local setmetatable = setmetatable @@ -286,6 +287,20 @@ end --- expose the functionality in a better fashion than merely giving access to --- the C functions.) +function _quote(pli, qnum) + local MAXQUOTES = con_lang.MAXQUOTES + if (qnum >= MAXQUOTES+0ULL) then + error("invalid quote number "..qnum) + end + + if (ffiC.ScriptQuotes[qnum] == nil) then + error("null quote "..qnum) + end + + local p = player[pli] -- bound-check + ffiC.P_DoQuote(qnum+MAXQUOTES, ffiC.g_player[pli].ps) +end + local D = { -- TODO: dynamic tile remapping ACTIVATOR = 2, @@ -299,6 +314,7 @@ local D = { BOOTS = 61, HOLODUKE = 1348, + ATOMICHEALTH = 100, GLASSPIECES = 1031, COMMANDER = 1920, JIBS2 = 2250, @@ -437,6 +453,7 @@ local ICONS = { [ffiC.GET_BOOTS] = 7, } +-- XXX function _addinventory(ps, inv, amount, pal) if (inv == ffiC.GET_ACCESS) then if (PALBITS[pal]) then @@ -469,6 +486,49 @@ function _getinventory(ps, inv, i) end end +function _addphealth(ps, spr, hlthadd) + if (ps.newowner >= 0) then + ffiC.G_ClearCameraView(ps) + end + + if (ffiC.ud.god ~= 0) then + return + end + + local notatomic = (spr.picnum ~= D.ATOMICHEALTH) + local j = sprite[ps.i].extra + + if (notatomic and j > ps.max_player_health and hlthadd > 0) then + return + end + + if (j > 0) then + j = j + hlthadd + end + + if (notatomic) then + if (hlthadd > 0) then + j = math.min(j, ps.max_player_health) + end + else + j = math.min(j, 2*ps.max_player_health) + end + + j = math.max(j, 0) + + if (hlthadd > 0) then + local qmaxhlth = bit.rshift(ps.max_player_health, 2) + if (j-hlthadd < qmaxhlth and j >= qmaxhlth) then + -- TODO + --A_PlaySound(DUKE_GOTHEALTHATLOW, ps->i) + end + + ps.last_extra = j + end + + sprite[ps.i].extra = j +end + -- The return value is true iff the ammo was at the weapon's max. -- In that case, no action is taken. function _addammo(ps, weap, amount) @@ -603,6 +663,7 @@ local function A_FurthestVisiblePoint(aci, otherspr) until (j >= 2048) end +local MAXSLEEPDIST = 16384 local SLEEPTIME = 1536 function _cansee(aci, ps) @@ -643,6 +704,13 @@ function _cansee(aci, ps) return can end +function _sleepcheck(aci, dist) + local acs = actor[aci] + if (dist > MAXSLEEPDIST and acs.timetosleep == 0) then + acs.timetosleep = SLEEPTIME + end +end + function _canseetarget(spr, ps) -- NOTE: &41 ? return cansee(spr^krandand(41), spr.sectnum, @@ -734,48 +802,47 @@ function _ifp(flags, pli, aci) local ps = player[pli] local vel = sprite[ps.i].xvel local band = bit.band - local j = false if (band(l,8)~=0 and ps.on_ground and _testkey(pli, SK.CROUCH)) then - j = true + return true elseif (band(l,16)~=0 and ps.jumping_counter == 0 and not ps.on_ground and ps.vel.z > 2048) then - j = true + return true elseif (band(l,32)~=0 and ps.jumping_counter > 348) then - j = true + return true elseif (band(l,1)~=0 and vel >= 0 and vel < 8) then - j = true + return true elseif (band(l,2)~=0 and vel >= 8 and not _testkey(pli, SK.RUN)) then - j = true + return true elseif (band(l,4)~=0 and vel >= 8 and _testkey(pli, SK.RUN)) then - j = true + return true elseif (band(l,64)~=0 and ps.pos.z < (sprite[aci].z-(48*256))) then - j = true + return true elseif (band(l,128)~=0 and vel <= -8 and not _testkey(pli, SK.RUN)) then - j = true + return true elseif (band(l,256)~=0 and vel <= -8 and _testkey(pli, SK.RUN)) then - j = true + return true elseif (band(l,512)~=0 and (ps.quick_kick > 0 or (ps.curr_weapon == ffiC.KNEE_WEAPON and ps.kickback_pic > 0))) then - j = true + return true elseif (band(l,1024)~=0 and sprite[ps.i].xrepeat < 32) then - j = true + return true elseif (band(l,2048)~=0 and ps.jetpack_on) then - j = true + return true elseif (band(l,4096)~=0 and ps:get_inv_amount(ffiC.GET_STEROIDS) > 0 and ps:get_inv_amount(ffiC.GET_STEROIDS) < 400) then - j = true + return true elseif (band(l,8192)~=0 and ps.on_ground) then - j = true + return true elseif (band(l,16384)~=0 and sprite[ps.i].xrepeat > 32 and sprite[ps.i].extra > 0 and ps.timebeforeexit == 0) then - j = true + return true elseif (band(l,32768)~=0 and sprite[ps.i].extra <= 0) then - j = true + return true elseif (band(l,65536)~=0) then -- TODO: multiplayer branch if (_angdiffabs(ps.ang, ffiC.getangle(sprite[aci].x-ps.pos.x, sprite[aci].y-ps.pos.y)) < 128) then - j = true + return true end end - return j + return false end function _checkspace(sectnum, floorp) diff --git a/polymer/eduke32/source/lunatic/defs.ilua b/polymer/eduke32/source/lunatic/defs.ilua index 03badcd84..e7bfba988 100644 --- a/polymer/eduke32/source/lunatic/defs.ilua +++ b/polymer/eduke32/source/lunatic/defs.ilua @@ -453,6 +453,8 @@ user_defs ud; playerdata_t g_player[MAXPLAYERS]; tiledata_t g_tile[MAXTILES]; +char *ScriptQuotes[]; + const int32_t playerswhenstarted; int32_t lastvisinc; int16_t g_spriteDeleteQueueSize; @@ -473,6 +475,8 @@ int32_t A_InsertSprite(int32_t whatsect,int32_t s_x,int32_t s_y,int32_t s_z,int3 int32_t s_xr,int32_t s_yr,int32_t s_a,int32_t s_ve,int32_t s_zv,int32_t s_ow,int32_t s_ss); int32_t A_Spawn(int32_t j, int32_t pn); void A_AddToDeleteQueue(int32_t i); +void P_DoQuote(int32_t q, DukePlayer_t *p); +void G_ClearCameraView(DukePlayer_t *ps); ]] -- functions @@ -485,6 +489,7 @@ int32_t kread(int32_t handle, void *buffer, int32_t leng); const char *G_ConFile(void); void G_DoGameStartup(const int32_t *params); int32_t C_DefineSound(int32_t sndidx, const char *fn, int32_t args[5]); +void C_DefineQuote(int32_t qnum, const char *qstr); ]] diff --git a/polymer/eduke32/source/lunatic/dynsymlist b/polymer/eduke32/source/lunatic/dynsymlist index 4ee2bf989..f4c263fa8 100644 --- a/polymer/eduke32/source/lunatic/dynsymlist +++ b/polymer/eduke32/source/lunatic/dynsymlist @@ -66,12 +66,15 @@ kread; G_ConFile; G_DoGameStartup; C_DefineSound; +C_DefineQuote; actor; ud; g_player; g_tile; +ScriptQuotes; + playerswhenstarted; lastvisinc; g_spriteDeleteQueueSize; @@ -103,4 +106,6 @@ A_Dodge; A_InsertSprite; A_Spawn; A_AddToDeleteQueue; +P_DoQuote; +G_ClearCameraView; }; diff --git a/polymer/eduke32/source/lunatic/lunacon.lua b/polymer/eduke32/source/lunatic/lunacon.lua index cd3cddfb3..f57c1afdb 100644 --- a/polymer/eduke32/source/lunatic/lunacon.lua +++ b/polymer/eduke32/source/lunatic/lunacon.lua @@ -4,7 +4,7 @@ local require = require local lpeg = require("lpeg") -local bit = require("bit") +local bit local math = require("math") local string = require("string") local table = require("table") @@ -27,8 +27,12 @@ local read_into_string = read_into_string local ffi, ffiC if (string.dump) then + bit = require("bit") + -- For Rio Lua: + bit = { bor=function() return 0 end } require("strict") else + bit = require("bit") ffi = require("ffi") ffiC = ffi.C end @@ -497,14 +501,30 @@ local function cmd_definevolumename(vol, name) end local function cmd_definequote(qnum, quotestr) +--[[ -- have the INT_MAX limit simply for some sanity - if (qnum < 0 or qnum > 0x7fffffff) then + if (not (qnum >= 0 and <= 0x7fffffff)) then errprintf("quote number is negative or exceeds limit of INT32_MAX.") return end +--]] + if (not (qnum >= 0 and qnum < conl.MAXQUOTES)) then + errprintf("quote number is negative or exceeds limit of %d.", conl.MAXQUOTES-1) + return + end -- strip whitespace from front and back - g_data.quote[qnum] = quotestr:match("^%s*(.*)%s*$") + quotestr = quotestr:match("^%s*(.*)%s*$") + + if (ffi) then + if (#quotestr >= conl.MAXQUOTELEN) then + warnprintf("quote %d truncated to %d characters.", conl.MAXQUOTELEN-1) + end + + ffiC.C_DefineQuote(qnum, quotestr) + end + + g_data.quote[qnum] = quotestr end local function cmd_gamestartup(...) @@ -528,7 +548,7 @@ local function cmd_gamestartup(...) end local function cmd_definesound(sndnum, fn, ...) - if (sndnum >= conl.MAXSOUNDS+0ULL) then + if (not (sndnum >= 0 and sndnum < conl.MAXSOUNDS)) then errprintf("sound number is or exceeds sound limit of %d", conl.MAXSOUNDS) return end @@ -937,7 +957,7 @@ local Ci = { addkills = cmd(D) / (PLS".actors_killed="..PLS".actors_killed+%1;"..ACS".actorstayput=-1"), addphealth = cmd(D) - / "", -- TODO + / format("_con._addphealth(%s,%s,%%1)", PLS"", SPS""), angoff = cmd(D) / "spritext[_aci].angoff=%1", debug = cmd(D) @@ -959,7 +979,7 @@ local Ci = { qspawn = cmd(D) / "_con.spawn(_aci,%1,true)", quote = cmd(D) - / "", -- TODO + / "_con._quote(_pli,%1)", savenn = cmd(D), save = cmd(D), sleeptime = cmd(D) @@ -1156,9 +1176,9 @@ local Cif = { ifrnd = cmd(D) / "_con.rnd(%1)", ifpdistl = cmd(D) - / "_dist<%1", -- TODO: conditionally set actor[].timetosleep afterwards + / function(val) return "_dist<"..val end, --, "_con.sleepcheck(_aci,_dist)" end, ifpdistg = cmd(D) - / "_dist>%1", -- TODO: conditionally set actor[].timetosleep afterwards + / function(val) return "_dist>"..val end, --"_con.sleepcheck(_aci,_dist)" end, ifactioncount = cmd(D) / ACS":get_acount()==%1", ifcount = cmd(D) @@ -1376,8 +1396,9 @@ local function after_if_cmd_Cmt(subj, pos, ...) return nil end - if (type(capts[1])=="string" and capts[2]==nil) then - return true, capts[1] + if (type(capts[1])=="string" and (capts[2]==nil or type(capts[2])=="string") and capts[3]==nil) then + assert(capts[2]==nil or capts[2]=="_con.sleepcheck(_aci,_dist)") + return true, capts[1], capts[2] end return true @@ -1495,16 +1516,34 @@ 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. local t_broken_identifier = BadIdent(-((t_number + t_good_identifier) * (sp1 + Set("[]:"))) * (alphanum + Set("_/\\*?")) * (alphanum + Set("_/\\*-+?"))^0) +local g_ifStack = {} -local function begin_if_fn(condstr) +local function begin_if_fn(condstr, endifstr) g_ifseqlevel = g_ifseqlevel+1 condstr = condstr or "TODO" assert(type(condstr)=="string") + + if (endifstr ~= nil) then + assert(type(endifstr)=="string") + g_ifStack[#g_ifStack+1] = endifstr + end + return format("if (%s) then", condstr) end local function end_if_fn() + local code + if (#g_ifStack > 0) then + code = g_ifStack[#g_ifStack] + 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 + end end local function check_else_Cmt()