diff --git a/polymer/eduke32/source/lunatic/control.lua b/polymer/eduke32/source/lunatic/control.lua index 7f3b260f0..2da58a64d 100644 --- a/polymer/eduke32/source/lunatic/control.lua +++ b/polymer/eduke32/source/lunatic/control.lua @@ -271,6 +271,19 @@ function _myos(x, y, zoom, tilenum, shade, orientation, pal) ffiC.G_DrawTileGeneric(x, y, zoom, tilenum, shade, orientation, pal) end +function _inittimer(ticspersec) + if (not (ticspersec >= 1)) then + error("ticspersec must be >= 1", 2) + end + ffiC.G_InitTimer(ticspersec) +end + +function _gettimedate() + v = ffi.new("int32_t [8]") + ffiC.G_GetTimeDate(v) + return v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7] +end + function rnd(x) return (bit.rshift(ffiC.krand(), 8) >= (255-x)) end @@ -295,6 +308,31 @@ function _mod(a,b) return (math.fmod(a,b)) end +-- Sect_ToggleInterpolation() clone +function _togglesectinterp(sectnum, doset) + for w in wallsofsect(sectnum) do + ffiC.G_ToggleWallInterpolation(w, doset) + + local nw = wall[w].nextwall + if (nw >= 0) then + ffiC.G_ToggleWallInterpolation(nw, doset) + ffiC.G_ToggleWallInterpolation(wall[nw].point2, doset) + end + end +end + +--- player/actor/sprite searching functions --- + +local function A_FP_ManhattanDist(ps, spr) + return (ps.pos - spr^(28*256)):blen1() +end + +-- Returns: player index, distance +-- TODO: MP case +function _findplayer(ps, spritenum) + return 0, A_FP_ManhattanDist(ps, sprite[spritenum]) +end + ---=== Weapon stuff ===--- @@ -362,6 +400,7 @@ end local D = { -- TODO: dynamic tile remapping ACTIVATOR = 2, + MASTERSWITCH = 8, RESPAWN = 9, APLAYER = 1405, @@ -675,6 +714,35 @@ function _operate(spritenum) end end +function _operatesectors(sectnum, spritenum) + check_sector_idx(sectnum) + check_sprite_idx(spritenum) -- XXX: -1 permissible under certain circumstances? + ffiC.G_OperateSectors(sectnum, spritenum) +end + +function _operateactivators(tag, playernum) + check_player_idx(playernum) + -- NOTE: passing oob playernum would be safe because G_OperateActivators + -- bound-checks it + ffiC.G_OperateActivators(tag, playernum) +end + +function _activatebysector(sectnum, spritenum) + local didit = false + for i in spriteofsect(sectnum) do + if (sprite[i].picnum==D.ACTIVATOR) then + ffiC.G_OperateActivators(sprite[i].lotag, -1) + end + end + if (didit) then + _operatesectors(sectnum, spritenum) + end +end + +function _checkactivatormotion(tag) + return ffiC.G_CheckActivatorMotion(tag) +end + function _endofgame(pli, timebeforeexit) player[pli].timebeforeexit = timebeforeexit player[pli].customexitsound = -1 @@ -944,7 +1012,7 @@ function _flash(spr, ps) ffiC.lastvisinc = ffiC.totalclock+32 end -local function G_OperateRespawns(tag) +function _G_OperateRespawns(tag) for i in spritesofstat(ffiC.STAT_FX) do local spr = sprite[i] @@ -962,6 +1030,15 @@ local function G_OperateRespawns(tag) end end +function _G_OperateMasterSwitches(tag) + for i in spritesofstat(ffiC.STAT_STANDABLE) do + local spr = sprite[i] + if (spr.picnum==D.MASTERSWITCH and spr.lotag==tag and spr.yvel==0) then + spr:_set_yvel(1) + end + end +end + local RESPAWN_USE_YVEL = { [D.STATUE] = true, @@ -982,10 +1059,10 @@ local RESPAWN_USE_YVEL = function _respawnhitag(spr) if (RESPAWN_USE_YVEL[spr.picnum]) then if (spr.yvel ~= 0) then - G_OperateRespawns(spr.yvel) + _G_OperateRespawns(spr.yvel) end else - G_OperateRespawns(spr.hitag) + _G_OperateRespawns(spr.hitag) end end diff --git a/polymer/eduke32/source/lunatic/defs.ilua b/polymer/eduke32/source/lunatic/defs.ilua index c4fa107e2..3e10a8bae 100644 --- a/polymer/eduke32/source/lunatic/defs.ilua +++ b/polymer/eduke32/source/lunatic/defs.ilua @@ -515,6 +515,8 @@ void VM_FallSprite(int32_t i); int32_t VM_ResetPlayer2(int32_t snum); void A_RadiusDamage(int32_t i, int32_t r, int32_t, int32_t, int32_t, int32_t); void G_OperateSectors(int32_t sn, int32_t ii); +void G_OperateActivators(int32_t low,int32_t snum); +int32_t G_CheckActivatorMotion(int32_t lotag); int32_t A_Dodge(spritetype *s); int32_t A_InsertSprite(int32_t whatsect,int32_t s_x,int32_t s_y,int32_t s_z,int32_t s_pn,int32_t s_s, 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); @@ -524,6 +526,9 @@ void P_DoQuote(int32_t q, DukePlayer_t *p); void G_ClearCameraView(DukePlayer_t *ps); void G_DrawTileGeneric(int32_t x, int32_t y, int32_t zoom, int32_t tilenum, int32_t shade, int32_t orientation, int32_t p); +void G_InitTimer(int32_t ticspersec); +void G_GetTimeDate(int32_t *vals); +int32_t G_ToggleWallInterpolation(int32_t w, int32_t doset); int32_t A_CheckAnySoundPlaying(int32_t i); int32_t A_PlaySound(uint32_t num, int32_t i); diff --git a/polymer/eduke32/source/lunatic/defs_common.lua b/polymer/eduke32/source/lunatic/defs_common.lua index ffca3d062..3a71333c7 100644 --- a/polymer/eduke32/source/lunatic/defs_common.lua +++ b/polymer/eduke32/source/lunatic/defs_common.lua @@ -10,6 +10,7 @@ local ffiC = ffi.C ffi.cdef "enum { _DEBUG_LUNATIC=1 }" local bit = require("bit") +local math = require("math") local string = require("string") local table = require("table") @@ -280,16 +281,29 @@ local check_sector_idx = bcheck.sector_idx local check_sprite_idx = bcheck.sprite_idx local check_tile_idx = bcheck.tile_idx +local band = bit.band +local bor = bit.bor +local bnot = bit.bnot +local lshift = bit.lshift +local rshift = bit.rshift +local xor = bit.bxor + local ivec3_ local ivec3_mt = { -- '^' is the "translate upwards" operator __pow = function(v, zofs) return ivec3_(v.x, v.y, v.z-zofs) end, + + __index = { + -- Manhattan distance with z right-shifted by 4 bits + blen1 = function(v) + return math.abs(v.x) + math.abs(v.y) + math.abs(bit.arshift(v.z,4)) + end, + }, } ivec3_ = ffi.metatype(vec3_ct, ivec3_mt) -local xor = bit.bxor local wallsofsec -- fwd-decl local sectortype_ptr_ct = ffi.typeof("$ *", ffi.typeof(strip_const(SECTOR_STRUCT))) @@ -342,12 +356,6 @@ local sectortype_mt = { } ffi.metatype("sectortype", sectortype_mt) -local band = bit.band -local bor = bit.bor -local bnot = bit.bnot -local lshift = bit.lshift -local rshift = bit.rshift - local walltype_ptr_ct = ffi.typeof("$ *", ffi.typeof(strip_const(WALL_STRUCT))) local walltype_mt = { diff --git a/polymer/eduke32/source/lunatic/dynsymlist b/polymer/eduke32/source/lunatic/dynsymlist index 2bf16a5c9..3fbf2884e 100644 --- a/polymer/eduke32/source/lunatic/dynsymlist +++ b/polymer/eduke32/source/lunatic/dynsymlist @@ -133,6 +133,8 @@ VM_FallSprite; VM_ResetPlayer2; A_RadiusDamage; G_OperateSectors; +G_OperateActivators; +G_CheckActivatorMotion; A_Dodge; A_InsertSprite; A_Spawn; @@ -140,6 +142,9 @@ A_AddToDeleteQueue; P_DoQuote; G_ClearCameraView; G_DrawTileGeneric; +G_InitTimer; +G_GetTimeDate; +G_ToggleWallInterpolation; A_CheckAnySoundPlaying; A_PlaySound; diff --git a/polymer/eduke32/source/lunatic/geom.lua b/polymer/eduke32/source/lunatic/geom.lua index 099469350..2c0769567 100644 --- a/polymer/eduke32/source/lunatic/geom.lua +++ b/polymer/eduke32/source/lunatic/geom.lua @@ -50,6 +50,8 @@ local vec2_mt = { __index = { lensq = function(a) return a.x*a.x + a.y*a.y end, + -- Manhattan distance: + len1 = function(a) return math.abs(a.x)+math.abs(a.y) end, }, } @@ -88,6 +90,8 @@ local vec3_mt = { __index = { lensq = function(a) return a.x*a.x + a.y*a.y + a.z*a.z end, + -- Manhattan distance: + len1 = function(a) return math.abs(a.x)+math.abs(a.y)+math.abs(a.z) end, }, } @@ -98,7 +102,8 @@ vec2_ = ffi.metatype(dvec2_t, vec2_mt) vec2 = vec2_ -- Returns a vec2 from anything indexable with "x" and "y" --- (vec2(t) works if t is such a table, but not if it's a vec2 or other cdata) +-- (vec2(t) works if t is such a table, but not if it's a vec2 or a cdata of +-- different type) function tovec2(t) return vec2(t.x, t.y) end -- Same for vec3 diff --git a/polymer/eduke32/source/lunatic/lunacon.lua b/polymer/eduke32/source/lunatic/lunacon.lua index b6ac68db2..121991a28 100644 --- a/polymer/eduke32/source/lunatic/lunacon.lua +++ b/polymer/eduke32/source/lunatic/lunacon.lua @@ -1353,8 +1353,7 @@ local Cinner = { -- NOTE2: userdef has at least three members with a second parameter: -- user_name, ridecule, savegame. Then there's wchoice. Given that they're -- arrays, I highly doubt that they worked (much less were safe) in CON. - -- We disallow them unless CONs in the wild crop up that actually used - -- these. + -- We disallow them, recent EDuke32 versions didn't expose them either. getuserdef = GetStructCmd(Access.userdef, userdef_common_pat * tok.wvar), getplayervar = GetOrSetPerxvarCmd(false, false), @@ -1448,13 +1447,18 @@ local Cinner = { / "_con._A_RadiusDamage(_aci,%1,%2,%3,%4,%5)", -- some commands taking read vars - operaterespawns = cmd(R), - operatemasterswitches = cmd(R), - checkactivatormotion = cmd(R), + operaterespawns = cmd(R) + / "_con._G_OperateRespawns(%1)", + operatemasterswitches = cmd(R) + / "_con._G_OperateMasterSwitches(%1)", + checkactivatormotion = cmd(R) + / CSV".RETURN=_con._checkactivatormotion(%1)", time = cmd(R) -- no-op / "", - inittimer = cmd(R), - lockplayer = cmd(R), + inittimer = cmd(R) + / "_con._inittimer(%1)", + lockplayer = cmd(R) + / PLS".transporter_hold=%1", quake = cmd(R) / "gv.doQuake(%1,81)", -- EARTHQUAKE jump = cmd(R) @@ -1471,7 +1475,8 @@ local Cinner = { / "_con._echo(%1)", starttrackvar = cmd(R), clearmapstate = cmd(R), - activatecheat = cmd(R), + activatecheat = cmd(R) + / handle.NYI, setgamepalette = cmd(R), -- Sound commands @@ -1605,8 +1610,10 @@ local Cinner = { / PLS":wack()", -- player/sprite searching - findplayer = cmd(W), - findotherplayer = cmd(W), + findplayer = cmd(W) + / CSV".RETURN,%1=_con._findplayer(_pli,_aci)", -- player index, distance + findotherplayer = cmd(W) + / CSV".RETURN,%1=0,0x7fffffff", -- TODO: MP case findnearspritezvar = cmd(D,R,R,W), findnearspritez = cmd(D,D,D,W), findnearsprite3dvar = cmd(D,R,W), @@ -1632,8 +1639,11 @@ local Cinner = { -- array stuff copy = sp1 * tok.identifier * arraypat * sp1 * tok.identifier * arraypat * sp1 * tok.rvar, setarray = sp1 * tok.identifier * arraypat * sp1 * tok.rvar, + resizearray = cmd(I,R), + getarraysize = cmd(I,W), + readarrayfromfile = cmd(I,D), + writearraytofile = cmd(I,D), - activatebysector = cmd(R,R), addlogvar = cmd(R) / handle.addlogvar, addlog = cmd() * #sp1 @@ -1669,11 +1679,18 @@ local Cinner = { savemapstate = cmd(), movesprite = cmd(R,R,R,R,R,W), neartag = cmd(R,R,R,R,R,W,W,W,W,R,R), - operateactivators = cmd(R,R), - operatesectors = cmd(R,R), palfrom = (sp1 * tok.define)^-4 / handle.palfrom, + activatebysector = cmd(R,R) + / "_con._activatebysector(%1,%2)", + operateactivators = cmd(R,R) -- THISACTOR + / function(tag, pli) + return format("_con._operateactivators(%s,%s)", tag, + (pli=="_aci") and "_pli" or pli) + end, + operatesectors = cmd(R,R) + / "_con._operatesectors(%1,%2)", operate = cmd() * #sp1 / "_con._operate(_aci)", @@ -1693,21 +1710,19 @@ local Cinner = { prevspritesect = cmd(W,R), prevspritestat = cmd(W,R), - readarrayfromfile = cmd(I,D), - writearraytofile = cmd(I,D), - redefinequote = sp1 * tok.define * newline_term_string / function(qnum, qstr) return format("_con._definequote(%d,%q)", qnum, stripws(qstr)) end, - resizearray = cmd(I,R), - getarraysize = cmd(I,W), rotatepoint = cmd(R,R,R,R,R,W,W), rotatesprite = cmd(R,R,R,R,R,R,R,R,R,R,R,R) -- 12R / handle.rotatesprite, rotatesprite16 = cmd(R,R,R,R,R,R,R,R,R,R,R,R) -- 12R / handle.rotatesprite16, - sectorofwall = cmd(W,R,R), - sectclearinterpolation = cmd(R), - sectsetinterpolation = cmd(R), + sectorofwall = cmd(W,R,R) + / handle.NYI, + sectclearinterpolation = cmd(R) + / "_con._togglesectinterp(%1,0)", + sectsetinterpolation = cmd(R) + / "_con._togglesectinterp(%1,1)", sectgethitag = cmd() / (CSV".HITAG=sector["..SPS".sectnum].hitag"), @@ -1756,7 +1771,8 @@ local Cinner = { getpname = cmd(R,R), getticks = cmd(W) / "%1=gv.getticks()", - gettimedate = cmd(W,W,W,W,W,W,W,W), + gettimedate = cmd(W,W,W,W,W,W,W,W) + / "%1,%2,%3,%4,%5,%6,%7,%8=_con._gettimedate()", getzrange = cmd(R,R,R,R,W,W,W,W,R,R), setaspect = cmd(R,R),