diff --git a/polymer/eduke32/source/lunatic/bcheck.lua b/polymer/eduke32/source/lunatic/bcheck.lua index 5d6fea4fe..ac9d841e4 100644 --- a/polymer/eduke32/source/lunatic/bcheck.lua +++ b/polymer/eduke32/source/lunatic/bcheck.lua @@ -77,11 +77,11 @@ function bcheck.quote_idx(qnum, onlyidx) error("invalid quote number "..qnum, 3) end + local cstr = ffiC.ScriptQuotes[qnum] if (onlyidx) then - return nil + return cstr end - local cstr = ffiC.ScriptQuotes[qnum] if (cstr == nil) then error("null quote "..qnum, 3) end diff --git a/polymer/eduke32/source/lunatic/control.lua b/polymer/eduke32/source/lunatic/control.lua index e4b7b5189..d14c09abe 100644 --- a/polymer/eduke32/source/lunatic/control.lua +++ b/polymer/eduke32/source/lunatic/control.lua @@ -1211,6 +1211,16 @@ function _neartag(x, y, z, sectnum, ang, range, tagsearch) return near.sector, near.wall, near.sprite, near.dist end +-- CON "getzrange" command +function _getzrange(x, y, z, sectnum, walldist, clipmask) + check_sector_idx(sectnum) + local ipos = geom.ivec3(x, y, z) + local hit = sector[sectnum]:zrangeat(ipos, walldist, clipmask) + -- return: ceilz, ceilhit, florz, florhit + return hit.c.z, hit.c.num + (hit.c.spritep and 49152 or 16384), + hit.f.z, hit.f.num + (hit.f.spritep and 49152 or 16384) +end + function _sleepcheck(aci, dist) local acs = actor[aci] if (dist > MAXSLEEPDIST and acs.timetosleep == 0) then diff --git a/polymer/eduke32/source/lunatic/defs_common.lua b/polymer/eduke32/source/lunatic/defs_common.lua index c988d4b61..cce6c831d 100644 --- a/polymer/eduke32/source/lunatic/defs_common.lua +++ b/polymer/eduke32/source/lunatic/defs_common.lua @@ -260,6 +260,9 @@ int32_t cansee(int32_t x1, int32_t y1, int32_t z1, int16_t sect1, void neartag(int32_t xs, int32_t ys, int32_t zs, int16_t sectnum, int16_t ange, int16_t *neartagsector, int16_t *neartagwall, int16_t *neartagsprite, int32_t *neartaghitdist, int32_t neartagrange, uint8_t tagsearch, int32_t (*blacklist_sprite_func)(int32_t)); +void getzrange(const vec3_t *pos, int16_t sectnum, + int32_t *ceilz, int32_t *ceilhit, int32_t *florz, int32_t *florhit, + int32_t walldist, uint32_t cliptype); int32_t ldist(const spritetype *s1, const spritetype *s2); int32_t dist(const spritetype *s1, const spritetype *s2); @@ -319,6 +322,21 @@ local wallsofsec -- fwd-decl local sectortype_ptr_ct = ffi.typeof("$ *", ffi.typeof(strip_const(SECTOR_STRUCT))) +local function get_sector_idx(sec) + local i = ffi.cast(sectortype_ptr_ct, sec)-ffi.cast(sectortype_ptr_ct, ffiC.sector) + assert(not (i >= ffiC.numsectors+0ULL)) + return i +end + +local zret = ffi.new("int32_t [4]") +local zret_t = ffi.typeof[[const struct { + struct { + bool spritep; + int32_t num; // number of sector or sprite + int32_t z; + } c, f; +}]] + local sectortype_mt = { __index = { --- Setters @@ -341,6 +359,21 @@ local sectortype_mt = { return ffiC.getflorzofslopeptr(s, pos.x, pos.y) end, + -- getzrange() interface + zrangeat = function(s, pos, walldist, cliptype) + local sectnum = get_sector_idx(s) + local ipos = vec3_ct(pos.x, pos.y, pos.z) + walldist = walldist or 128 + cliptype = cliptype or ffiC.CLIPMASK0 + + ffiC.getzrange(ipos, sectnum, zret+0, zret+1, zret+2, zret+3, + walldist, cliptype) + local ceilz, ceilhit, florz, florhit = zret[0], zret[1], zret[2], zret[3] + + return zret_t({ ceilhit>=49152, bit.band(ceilhit,16383), ceilz }, + { florhit>=49152, bit.band(florhit,16383), florz }) + end, + -- inside() port contains = function(s, pos) local x, y = pos.x, pos.y diff --git a/polymer/eduke32/source/lunatic/lunacon.lua b/polymer/eduke32/source/lunatic/lunacon.lua index 0b5fba744..0efb97426 100644 --- a/polymer/eduke32/source/lunatic/lunacon.lua +++ b/polymer/eduke32/source/lunatic/lunacon.lua @@ -1526,6 +1526,14 @@ local handle = return format("print('%s:%d: debug %d')", g_filename, getlinecol(g_lastkwpos), val) end, + getzrange = function(...) + local v = {...} + assert(#v == 10) -- 4R 4W 2R + return format("%s,%s,%s,%s=_con._getzrange(%s,%s,%s,%s,%s,%s)", + v[5], v[6], v[7], v[8], -- outargs + v[1], v[2], v[3], v[4], v[9], v[10]) -- inargs + end, + hitscan = function(...) local v = {...} assert(#v == 14) -- 7R 6W 1R @@ -2009,7 +2017,7 @@ local Cinner = { neartag = cmd(R,R,R,R,R,W,W,W,W,R,R) -- 5R 4W 2R / handle.neartag, getzrange = cmd(R,R,R,R,W,W,W,W,R,R) - / handle.NYI, + / handle.getzrange, -- screen text and numbers display gametext = cmd(R,R,R,R,R,R,R,R,R,R,R) -- 11 R diff --git a/polymer/eduke32/source/lunatic/test.elua b/polymer/eduke32/source/lunatic/test.elua index 966be30ba..cf9dc5a5c 100644 --- a/polymer/eduke32/source/lunatic/test.elua +++ b/polymer/eduke32/source/lunatic/test.elua @@ -393,6 +393,16 @@ gameevent("DISPLAYROOMS", function() local cam = gv.cam cam.pos.z = cam.pos.z + 64*16*math.sin(gv.totalclock/30) + + local ps = player[0] + if (ps.cursectnum >= 0) then + local hit = sector[ps.cursectnum]:zrangeat(cam.pos) + if (gv.totalclock%200==0) then + printf("hit %s %d at z=%d, %s %d at z=%d", + hit.c.spritep and "sprite" or "sector", hit.c.num, hit.c.z, + hit.f.spritep and "sprite" or "sector", hit.f.num, hit.f.z) + end + end end )