Lunatic: merge updatesector and ~breadth, making the former accept a flag.

git-svn-id: https://svn.eduke32.com/eduke32@3910 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2013-06-28 14:07:43 +00:00
parent 885036a6a3
commit 5ea2eee072
3 changed files with 93 additions and 20 deletions

View file

@ -772,6 +772,11 @@ static_members.sector.NEARTAG_FLAGS = conststruct
NOSPRITES = 4, NOSPRITES = 4,
} }
static_members.sector.UPDATE_FLAGS = conststruct
{
BREADTH = 1,
}
static_members.wall.CSTAT = conststruct static_members.wall.CSTAT = conststruct
{ {
BLOCK = 1, BLOCK = 1,
@ -1056,23 +1061,35 @@ function inside(pos, sectnum)
return (ffiC.inside(pos.x, pos.y, sectnum)==1) return (ffiC.inside(pos.x, pos.y, sectnum)==1)
end end
-- TODO: should these rather be one function, and the specific kind of updating
-- controlled by an argument?
local us_retsect = ffi.new("int16_t [1]") local us_retsect = ffi.new("int16_t [1]")
local USF = sector.UPDATE_FLAGS
function updatesector(pos, sectnum, flags)
if (sectnum ~= -1) then
check_sector_idx(sectnum)
end
function updatesector(pos, sectnum)
us_retsect[0] = sectnum us_retsect[0] = sectnum
if (flags==nil or flags==0) then
ffiC.updatesector(pos.x, pos.y, us_retsect) ffiC.updatesector(pos.x, pos.y, us_retsect)
return us_retsect[0] elseif (flags==USF.BREADTH) then
end
function updatesectorbreadth(pos, sectnum)
us_retsect[0] = sectnum
ffiC.updatesectorbreadth(pos.x, pos.y, us_retsect) ffiC.updatesectorbreadth(pos.x, pos.y, us_retsect)
else
error("invalid argument #3 (flags)", 2)
end
return us_retsect[0] return us_retsect[0]
end end
function updatesectorz(pos, sectnum) function updatesectorz(pos, sectnum, flags)
if (sectnum ~= -1) then
check_sector_idx(sectnum)
end
if (flags ~= nil) then
error("invalid argument #3 (flags)", 2)
end
us_retsect[0] = sectnum us_retsect[0] = sectnum
ffiC.updatesectorz(pos.x, pos.y, pos.z, us_retsect) ffiC.updatesectorz(pos.x, pos.y, pos.z, us_retsect)
return us_retsect[0] return us_retsect[0]

View file

@ -522,7 +522,7 @@ from `0` to `255`.
`sec:set_ceilingpicnum(tilenum)`, `sec:set_floorpicnum(tilenum)`:: `sec:set_ceilingpicnum(tilenum)`, `sec:set_floorpicnum(tilenum)`::
Set the tile number of the ceiling or floor. Set the tile number of the ceiling or floor.
`sec:ceilingzat(pos)`, `sec:floorzat(pos)`:: [[sec_cfz_at]] `sec:ceilingzat(pos)`, `sec:floorzat(pos)`::
Return the z coordinate of sector `sec`'s ceiling or floor at position `pos`, Return the z coordinate of sector `sec`'s ceiling or floor at position `pos`,
which can be anything indexable with the strings `x` and `y`. which can be anything indexable with the strings `x` and `y`.
@ -540,6 +540,9 @@ These name single bits:
`TRANS1`, `TRANS2`, `BLOCK`, `HITSCAN`, while the following denote _bit masks_: `TRANS1`, `TRANS2`, `BLOCK`, `HITSCAN`, while the following denote _bit masks_:
`FLIP_BITMASK`, `ORIENT_BITMASK`, `TRANS_BITMASK`. `FLIP_BITMASK`, `ORIENT_BITMASK`, `TRANS_BITMASK`.
[[sector_UPDATE_FLAGS]] `sector.UPDATE_FLAGS`::
Contains a flag `BREADTH` permissible to <<updatesector,`updatesector`>>.
''' '''
[[wall]] [[wall]]
===== `wall` ===== `wall`
@ -556,7 +559,7 @@ permissible as arguments to <<vector_types,`xmath` vector>> operations.
`point2` (read-only):: `point2` (read-only)::
The index of the second wall point. The index of the second wall point.
`nextwall`, `nextsector` (read-only):: [[nextwall]] `nextwall`, `nextsector` (read-only)::
If the wall is ``white'', these members equal `-1`. For ``red'' walls, they If the wall is ``white'', these members equal `-1`. For ``red'' walls, they
contain the wall and sector indices (respectively) of the wall on the other side. contain the wall and sector indices (respectively) of the wall on the other side.
@ -811,10 +814,8 @@ horizontal and vertical texel sizes of each tile.
Lunatic functions Lunatic functions
~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
Engine-side Engine-side iterators
^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^
===== Iterators
+*for* w *in* wallsofsect(sectnum)+:: +*for* w *in* wallsofsect(sectnum)+::
Iterates over the indices of all walls of the sector with index `sectnum`. Iterates over the indices of all walls of the sector with index `sectnum`.
@ -825,14 +826,63 @@ Iterates over the indices of all sprites with status number `statnum`.
+*for* s *in* spritesofsect(sectnum)+:: +*for* s *in* spritesofsect(sectnum)+::
Iterates over the indices of all sprites contained in the sector with index `sectnum`. Iterates over the indices of all sprites contained in the sector with index `sectnum`.
Sector containment functions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
`inside(pos, sectnum)`::
Returns a boolean of whether the position `pos` (which can be anything
indexable with `x` and `y`) is considered inside the sector with number
`sectnum`, which must be valid. The `z` component is not taken into account.
A number of engine functions take a position `pos` and a starting sector number
`sectnum` and try to find a sector that contains `pos`, assuming it started out
in `sectnum`.footnote:[Note that this is different from CON's `updatesector`,
which takes the starting sector to be the one of the _current sprite_.]
If a valid sector numeric is passed for `sectnum`, these functions first check
whether that sector contains `pos` (i.e. the position stays in the same sector)
and then attempt to search neighboring sectors. If the passed `sectnum` is
`-1`, all sectors are searched in an unspecified order. On success, these
functions return the sector number of the ``updated'' sector, otherwise `-1`.
[[updatesector]] `updatesector(pos, sectnum [, flags])`::
Searches for a sector containing `pos`, which can be anything indexable with
`x` and `y`. Thus, the `z` component is not taken into account. If `sectnum` is
a valid sector number, first all its neighboring walls
(<<nextwall,`wall[].nextwall`>>, ``red wall links'') are searched, falling back
to a linear search on failure.
+
However, this strategy can be problematic if the position passes multiple thin
sectors that overlap another, potentially unrelated sector (for example, in a
TROR or sector-over-sector construction). If such a sector is passed without an
`updatesector` call ever made when it contains the position, the next call may
not find the real sector (as it is now two nextwall links away from the initial
one), and wrongly suggest the overlapping one instead.
+
For this reason, the optional argument `flags` accepts
<<sector_UPDATE_FLAGS,`sector.UPDATE_FLAGS.BREADTH`>>, instructing
`updatesector` to look for matching sectors in a _breadth-first_ search
starting from `sectnum`, and following all nextwall links. With this strategy,
there is *no* fallback to a linear search if no matching sector is found.
`updatesectorz(pos, sectnum)`::
Searches for a sector containing `pos`, which can be any value indexable with
`x`, `y` and `z`. Thus, it additionally takes the `z` component into account by
checking against the bounds that would be returned using a sector's
<<sec_cfz_at,ceilingzat/floorzat>> methods.
+
The `updatesectorz` function first checks the initial sector for containment of
`pos`, then it tries any TROR neighbors of `sectnum`. Finally, it proceeds like
`updatesector` as far as the searching order is concerned.
//////////
cansee cansee
hitscan hitscan
inside
neartag neartag
sectorsofbunch sectorsofbunch
updatesector //////////
updatesectorbreadth
updatesectorz
Customizing the game Customizing the game
^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^

View file

@ -11,6 +11,12 @@ local stat = require "stat"
-- set to nil to disable saving positions -- set to nil to disable saving positions
g_posns = {} g_posns = {}
local USF_BREADTH = sector.UPDATE_FLAGS.BREADTH
local function updatesectorbreadth(pos, sectnum)
return updatesector(pos, sectnum, USF_BREADTH)
end
-- [STATS, TIMES] = RANDWALK(N, SPRITENUM, MINLEN, MAXLEN [, RANDOFS [, FUNCI [, LOGFN]]]) -- [STATS, TIMES] = RANDWALK(N, SPRITENUM, MINLEN, MAXLEN [, RANDOFS [, FUNCI [, LOGFN]]])
function randwalk(N, spritenum, minlen, maxlen, randofs, funci, logfn) function randwalk(N, spritenum, minlen, maxlen, randofs, funci, logfn)
-- Set the random seed to an arbitrary but fixed value so that the "random" walk -- Set the random seed to an arbitrary but fixed value so that the "random" walk