mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-16 21:33:46 +03:00
158 lines
4.0 KiB
Lua
158 lines
4.0 KiB
Lua
--[[
|
|
| This file was obtained through the combined efforts
|
|
| of Madbluntz & Plymouth Antiquarian Society.
|
|
|
|
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
|
| Maloy, DrPepper10 @ RIP, Atle!
|
|
|
|
|
| Visit for more: https://plymouth.thetwilightzone.ru/
|
|
--]]
|
|
|
|
-- Copyright © 2022-2072, Nak, https://steamcommunity.com/id/Nak2/
|
|
-- All Rights Reserved. Not allowed to be reuploaded.
|
|
-- License: https://github.com/Nak2/NikNaks/blob/main/LICENSE
|
|
|
|
local obj_tostring = "BSP %s [ %s ]"
|
|
local format = string.format
|
|
|
|
--- @class BSPObject
|
|
local meta = NikNaks.__metatables["BSP"]
|
|
|
|
--- @class BrushObject
|
|
local meta_brush = {}
|
|
meta_brush.__index = meta_brush
|
|
meta_brush.__tostring = function( self ) return format( obj_tostring, "BSP Brush", self.__id ) end
|
|
meta_brush.MetaName = "BSP Brush"
|
|
NikNaks.__metatables["BSP Brush"] = meta_brush
|
|
|
|
local DIST_EPSILON = 0.03125
|
|
local MAX_MAP_BRUSHES = 8192
|
|
local MAX_MAP_BRUSHSIDES = 65536
|
|
|
|
--- Returns an array of the brush-data with brush-sides.
|
|
--- @return BrushObject[]
|
|
function meta:GetBrushes()
|
|
if self._brushes then return self._brushes end
|
|
|
|
self._brushes = {}
|
|
|
|
local data = self:GetLump( 18 )
|
|
for id = 1, math.min( data:Size() / 96, MAX_MAP_BRUSHES ) do
|
|
--- @class BrushObject
|
|
local t = {}
|
|
local first = data:ReadLong()
|
|
local num = data:ReadLong()
|
|
t.contents = data:ReadLong()
|
|
t.numsides = num
|
|
--- @type BrushSideObject[]
|
|
t.sides = {}
|
|
t.__id = id
|
|
t.__map = self
|
|
|
|
local n = 1
|
|
for i = first, first + num - 1 do
|
|
t.sides[n] = self:GetBrushSides()[i]
|
|
n = n + 1
|
|
end
|
|
|
|
self._brushes[id] = setmetatable( t, meta_brush )
|
|
end
|
|
|
|
self:ClearLump( 18 )
|
|
return self._brushes
|
|
end
|
|
|
|
--- Returns an array of brushside-data.
|
|
--- @return BrushSideObject[]
|
|
function meta:GetBrushSides()
|
|
if self._brushside then return self._brushside end
|
|
|
|
self._brushside = {}
|
|
|
|
local data = self:GetLump( 19 )
|
|
local planes = self:GetPlanes()
|
|
for i = 1, math.min( data:Size() / 64, MAX_MAP_BRUSHSIDES ) do
|
|
--- @class BrushSideObject
|
|
local t = {}
|
|
t.plane = planes[ data:ReadUShort() ]
|
|
t.texinfo = data:ReadShort()
|
|
t.dispinfo = data:ReadShort()
|
|
local q = data:ReadShort()
|
|
t.bevel = bit.band( q, 0x1 ) == 1 -- Seems to be 1 if used for collision detection
|
|
t.thin = bit.rshift( q, 8 ) == 1 -- For Portal 2 / Alien Swarm
|
|
self._brushside[i - 1] = t
|
|
end
|
|
|
|
self:ClearLump( 19 )
|
|
return self._brushside
|
|
end
|
|
|
|
|
|
function meta_brush:GetIndex()
|
|
return self.__id or -1
|
|
end
|
|
|
|
--- Returns the content flag the brush has.
|
|
--- @return number
|
|
function meta_brush:GetContents()
|
|
return self.contents
|
|
end
|
|
|
|
--- Returns true if the brush has said content
|
|
--- @param CONTENTS number
|
|
--- @return boolean
|
|
function meta_brush:HasContents( CONTENTS )
|
|
if CONTENTS == 0 then return self.contents == CONTENTS end
|
|
return bit.band( self.contents, CONTENTS ) ~= 0
|
|
end
|
|
|
|
-- Texture Stuff
|
|
|
|
--- Returns the TexInfo for the brush-side.
|
|
--- @param side number
|
|
--- @return table
|
|
function meta_brush:GetTexInfo( side )
|
|
return self.__map:GetTexInfo()[self.sides[side].texinfo]
|
|
end
|
|
|
|
--- Returns the TexData for the brush-side.
|
|
--- @param side number
|
|
--- @return table
|
|
function meta_brush:GetTexData( side )
|
|
return self.__map:GetTexData()[ self:GetTexInfo( side ).texdata]
|
|
end
|
|
|
|
--- Returns the texture for the brush-side.
|
|
--- @param side number
|
|
--- @return string
|
|
function meta_brush:GetTexture( side )
|
|
local t = self:GetTexData( side ) or {}
|
|
return t.nameStringTableID
|
|
end
|
|
|
|
--- Returns the Material for the brush-side.
|
|
--- @param side number
|
|
--- @return IMaterial
|
|
function meta_brush:GetMaterial( side )
|
|
if self._material and self._material[side] then return self._material[side] end
|
|
if not self._material then self._material = {} end
|
|
|
|
self._material[side] = Material( self:GetTexture( side ) or "__error" )
|
|
return self._material[side]
|
|
end
|
|
|
|
--- Returns true if the point is inside the brush
|
|
--- @param position Vector
|
|
--- @return boolean
|
|
function meta_brush:IsPointInside( position )
|
|
for i = 1, self.numsides do
|
|
local side = self.sides[i]
|
|
local plane = side.plane
|
|
if plane.normal:Dot( position ) - plane.dist > DIST_EPSILON then
|
|
return false
|
|
end
|
|
end
|
|
|
|
return true
|
|
end
|