diff --git a/polymer/eduke32/source/lunatic/control.lua b/polymer/eduke32/source/lunatic/control.lua index 0cf557922..7a2699a61 100644 --- a/polymer/eduke32/source/lunatic/control.lua +++ b/polymer/eduke32/source/lunatic/control.lua @@ -512,6 +512,7 @@ end local xmath = require("xmath") local abs = math.abs +local bangvec, kangvec = xmath.bangvec, xmath.kangvec local dist, ldist = xmath.dist, xmath.ldist local vec3, ivec3 = xmath.vec3, xmath.ivec3 local rotate = xmath.rotate @@ -1345,10 +1346,6 @@ function _awayfromwall(spr, d) return true end -local function cossinb(bang) - return xmath.cosb(bang), xmath.sinb(bang) -end - -- TODO: xmath.vec3 'mhlen2' method? local function manhatdist(v1, v2) return abs(v1.x-v2.x) + abs(v1.y-v2.y) @@ -1364,9 +1361,8 @@ local function A_FurthestVisiblePoint(aci, otherspr) local j = 0 repeat - local c, s = cossinb(otherspr.ang + j) - local hit = hitscan(otherspr^(16*256), otherspr.sectnum, - c, s, 16384-krandand(32767), ffiC.CLIPMASK1) + local ray = kangvec(otherspr.ang + j, 16384-krandand(32767)) + local hit = hitscan(otherspr^(16*256), otherspr.sectnum, ray, ffiC.CLIPMASK1) local dother = manhatdist(hit.pos, otherspr) local dactor = manhatdist(hit.pos, sprite[aci]) @@ -1439,7 +1435,8 @@ end -- CON "hitscan" command function _hitscan(x, y, z, sectnum, vx, vy, vz, cliptype) local srcv = ivec3(x, y, z) - local hit = hitscan(srcv, sectnum, vx, vy, vz, cliptype) + local ray = ivec3(vx, vy, vz) + local hit = hitscan(srcv, sectnum, ray, cliptype) return hit.sect, hit.wall, hit.sprite, hit.pos.x, hit.pos.y, hit.pos.z end @@ -1508,15 +1505,12 @@ end local function A_CheckHitSprite(spr, angadd) local zoff = (spr:isenemy() and 42*256) or (ispic(spr.picnum, "APLAYER") and 39*256) or 0 - local c, s = cossinb(spr.ang+angadd) - local hit = hitscan(spr^zoff, spr.sectnum, c, s, 0, ffiC.CLIPMASK1) + local hit = hitscan(spr^zoff, spr.sectnum, kangvec(spr.ang+angadd), ffiC.CLIPMASK1) if (hit.wall >= 0 and wall[hit.wall]:ismasked() and spr:isenemy()) then return -1, nil end - local dx = hit.pos.x-spr.x - local dy = hit.pos.y-spr.y - return hit.sprite, math.sqrt(dx*dx+dy*dy) -- TODO: use "ldist" approximation for authenticity + return hit.sprite, ldist(hit.pos, spr) end function _canshoottarget(dst, aci) diff --git a/polymer/eduke32/source/lunatic/defs_common.lua b/polymer/eduke32/source/lunatic/defs_common.lua index ee81f4331..064435b8f 100644 --- a/polymer/eduke32/source/lunatic/defs_common.lua +++ b/polymer/eduke32/source/lunatic/defs_common.lua @@ -1196,14 +1196,13 @@ end ---=== Engine functions, wrapped for Lua convenience ===--- -- returns a hitdata_ct --- TODO: make v[xyz] be passed as one aggregate, too? -- TODO: make cliptype optional? What should be the default? -function hitscan(pos, sectnum, vx,vy,vz, cliptype) +function hitscan(pos, sectnum, ray, cliptype) check_sector_idx(sectnum) local vec = vec3_ct(pos.x, pos.y, pos.z) local hitdata = hitdata_ct() - ffiC.hitscan(vec, sectnum, vx,vy,vz, hitdata, cliptype) + ffiC.hitscan(vec, sectnum, ray.x, ray.y, ray.z, hitdata, cliptype) return hitdata end diff --git a/polymer/eduke32/source/lunatic/test.lua b/polymer/eduke32/source/lunatic/test.lua index ff48b7ed0..a48d876f2 100644 --- a/polymer/eduke32/source/lunatic/test.lua +++ b/polymer/eduke32/source/lunatic/test.lua @@ -469,6 +469,35 @@ local TROOPSTRENGTH = 30 local AF = actor.FLAGS local CS = sprite.CSTAT +-- Crosshair sprite. +-- NOTE: This ought to be a gamevar -- if a savegame is restored, a new one +-- will be spawned. +local chair + +gameactor{ D.APLAYER, AF.chain_end, + function(aci, pli) + if (chair == nil) then + chair = con.spawn(555, aci) + printf("Spawned our crosshair: sprite %d", chair) + local spr = sprite[chair] + -- Set to STAT_MISC because otherwise interpolation goes crazy (old + -- value never updated; dunno why...) + sprite.changestat(chair, actor.STAT.MISC) + spr.xrepeat, spr.yrepeat = 96, 96 + spr.cstatbits:set(CS.CENTER) + end + + local ps = player[pli] + local ray = xmath.kangvec(ps.ang, -(ps.horiz-100)*2048) + + local hit = hitscan(ps.pos, ps.cursectnum, ray, 0) + if (hit.sect >= 0) then + sprite[chair]:setpos(hit.pos) + sprite.changesect(chair, hit.sect) + end + end +} + -- Also test actor code chaining: strength is doubled. gameactor { @@ -483,7 +512,7 @@ gameactor local spr = sprite[i] local t = gv.gethiticks() - local hit = hitscan(spr, spr.sectnum, 10, 10, 0, gv.CLIPMASK0) + local hit = hitscan(spr, spr.sectnum, {x=10, y=10, z=0}, gv.CLIPMASK0) hs:add(1000*(gv.gethiticks()-t)) @@ -534,7 +563,7 @@ gameactor -- Polymost: only for "ghost" -- Polymer: none local aimv = 256*xmath.bangvec(tspr.ang) - local hit = hitscan(tspr^(16*256), tspr.sectnum, aimv.x, aimv.y, 0, gv.CLIPMASK1) + local hit = hitscan(tspr^(16*256), tspr.sectnum, aimv, gv.CLIPMASK1) if (hit.wall >= 0) then local aimtspr = tspr:dup() diff --git a/polymer/eduke32/source/lunatic/xmath.lua b/polymer/eduke32/source/lunatic/xmath.lua index 8b5ab2cc0..33d423dd6 100644 --- a/polymer/eduke32/source/lunatic/xmath.lua +++ b/polymer/eduke32/source/lunatic/xmath.lua @@ -292,11 +292,16 @@ local vec2, vec3 = vec2, vec3 local intarg = ffi.new("int32_t [1]") function bangvec(bang) intarg[0] = bang -- round towards zero - return vec3(cosb(intarg[0]), sinb(intarg[0])) + return dvec3_t(cosb(intarg[0]), sinb(intarg[0])) +end + +function kangvec(bang, z) + intarg[0] = bang -- round towards zero + return ivec3_t(kcos(intarg[0]), ksin(intarg[0]), z or 0) end function angvec(ang) - return vec3(cos(ang), sin(ang)) + return dvec3_t(cos(ang), sin(ang)) end