- I made sure my file(s) follow the Submissions Guidelines
- Yes
CdvCast
CdvCast is a raycasting library for SRB2 2.2 (untested on earlier versions), it allows you to shoot out a ray from any arbitrary position with any arbitrary vector direction and length, and get collision information in response.Usage
CdvCast exposes one function to the user CdvCast.Raycast
.This function takes in a position and direction vector, these should be tables with x, y, and z elements. (
{x = mobj.x, y = mobj.y, z = mobj.z}
)It returns a table that contains information about collisions the ray passed through.
Lua:
{ --Raycast result structure
hit = {sector = sector_t, fof = ffloor_t or nil, line = line_t or nil, side = side_t or nil} or nil, --If nothing solid is hit, this is nil.
hit_position = {x, y, z}, --The position the ray hit at. If nothing solid is hit, it's where the ray ends.
hit_normal = {x, y, z}, --The normal unit vector of the surface the ray hit, nil if nothing solid is hit.
crosses = {table of raycast results} --This contains results of non-solid intersections the ray made, same structure
}
Examples
Spawn dust particles on walls 256 units in front of players
Spawn dust particles on water FOFs 256 units below players
Lua:
addHook("PlayerThink", function(player)
local mobj = player.mo
if mobj ~= nil then
--Test raycast out front of the player
local cast_from = {
x = mobj.x,
y = mobj.y,
z = mobj.z + mobj.height / 2,
}
local cast_dir = {
x = P_ReturnThrustX(mobj, player.drawangle, FRACUNIT * 256),
y = P_ReturnThrustY(mobj, player.drawangle, FRACUNIT * 256),
z = 0
}
local raycast_result = CdvCast.Raycast(cast_from, cast_dir)
if raycast_result.hit ~= nil then
P_SpawnMobj(raycast_result.hit_position.x, raycast_result.hit_position.y, raycast_result.hit_position.z, MT_SPINDUST)
end
end
end)
Spawn dust particles on water FOFs 256 units below players
Lua:
addHook("PlayerThink", function(player)
local mobj = player.mo
if mobj ~= nil then
--Test raycast out front of the player
local cast_from = {
x = mobj.x,
y = mobj.y,
z = mobj.z + mobj.height / 2,
}
local cast_dir = {
x = 0,
y = 0,
z = FRACUNIT * -256
}
local raycast_result = CdvCast.Raycast(cast_from, cast_dir)
for _,v in pairs(raycast_result.crosses) do
if v.hit.fof ~= nil and (v.hit.fof.flags & FF_SWIMMABLE) then
P_SpawnMobj(v.hit_position.x, v.hit_position.y, v.hit_position.z, MT_SPINDUST)
end
end
end
end)
Limitations
Unfortunately, I wasn't able to get PolyObjects working yet. For some reason, SRB2 Lua doesn't expose the BSP and subsectors as I'd want it to, making this a difficult problem to solve. I'll be looking into into implementing this in a later version, however.Additionally, FOF walls don't return sides in the raycast result yet, I'm not entirely sure how these are stored yet.
This library is in an early state, and may be suboptimal in some places or buggy in ways I have not caught. If you find something wrong, please bring it to my attention.