mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-16 21:33:46 +03:00
464 lines
13 KiB
Lua
464 lines
13 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.
|
|
|
|
local band = bit.band
|
|
local meta = NikNaks.__metatables["BSP"]
|
|
|
|
--- @class StaticProp
|
|
--- @field Index number
|
|
--- @field version number
|
|
--- @field Origin Vector
|
|
--- @field Angles Angle
|
|
--- @field PropType string
|
|
--- @field First_leaf number
|
|
--- @field LeafCount number
|
|
--- @field Solid number
|
|
--- @field Flags? number
|
|
--- @field Skin number
|
|
--- @field FadeMinDist number
|
|
--- @field FadeMaxDist number
|
|
--- @field LightingOrigin Vector
|
|
--- @field ForcedFadeScale? number
|
|
--- @field MinDXLevel? number
|
|
--- @field MaxDXLevel? number
|
|
--- @field lightmapResolutionX? number
|
|
--- @field lightmapResolutionY? number
|
|
--- @field MinCPULevel? number
|
|
--- @field MaxCPULevel? number
|
|
--- @field MinGPULevel? number
|
|
--- @field MaxGPULevel? number
|
|
--- @field DiffuseModulation? Color
|
|
--- @field DisableX360? boolean
|
|
--- @field FlagsEx? number
|
|
--- @field UniformScale? number
|
|
local meta_staticprop = {}
|
|
meta_staticprop.__index = meta_staticprop
|
|
meta_staticprop.__tostring = function(self) return "Static Prop" .. (self.PropType and " [" .. self.PropType .. "]" or "") end
|
|
meta_staticprop.MetaName = "StaticProp"
|
|
NikNaks.__metatables["StaticProp"] = meta_staticprop
|
|
|
|
local version = {}
|
|
-- Base version from Wiki. Most HL2 maps are version 5.
|
|
version[4] = function( f, obj, m )
|
|
obj.Origin = f:ReadVector() -- Vector (3 float) 12 bytes
|
|
obj.Angles = f:ReadAngle() -- Angle (3 float) 12 bytes
|
|
obj.PropType = m[f:ReadUShort() + 1] -- unsigned short 2 bytes
|
|
obj.First_leaf = f:ReadUShort() -- unsigned short 2 bytes
|
|
obj.LeafCount = f:ReadUShort() -- unsigned short 2 bytes
|
|
obj.Solid = f:ReadByte() -- unsigned char 1 byte
|
|
obj.Flags = f:ReadByte() -- unsigned char 1 byte
|
|
obj.Skin = f:ReadLong() -- int 4 bytes
|
|
obj.FadeMinDist = f:ReadFloat() -- float 4 bytes
|
|
obj.FadeMaxDist = f:ReadFloat() -- float 4 bytes
|
|
obj.LightingOrigin = f:ReadVector() -- Vector (3 float) 12 bytes
|
|
return 448
|
|
end
|
|
|
|
-- Fade scale added.
|
|
version[5] = function( f, obj, m)
|
|
version[4]( f, obj, m )
|
|
obj.ForcedFadeScale = f:ReadFloat() -- float 4 bytes
|
|
return 480
|
|
end
|
|
|
|
-- Minimum and maximum DX-level
|
|
version[6] = function( f, obj, m)
|
|
version[5]( f, obj, m )
|
|
obj.MinDXLevel = f:ReadUShort() -- unsigned short 2 bytes
|
|
obj.MaxDXLevel = f:ReadUShort() -- unsigned short 2 bytes
|
|
return 512
|
|
end
|
|
|
|
-- Color modulation added
|
|
version[7] = function( f, obj, m )
|
|
version[6]( f, obj, m )
|
|
obj.DiffuseModulation = f:ReadColor()
|
|
return 544
|
|
end
|
|
|
|
-- Removal of DX-Level. Possible for Linux and console support.
|
|
version[8] = function( f, obj, m )
|
|
version[5]( f,obj, m )
|
|
obj.MinCPULevel = f:ReadByte() -- unsigned char 1 byte
|
|
obj.MaxCPULevel = f:ReadByte() -- unsigned char 1 byte
|
|
obj.MinGPULevel = f:ReadByte() -- unsigned char 1 byte
|
|
obj.MaxGPULevel = f:ReadByte() -- unsigned char 1 byte
|
|
obj.DiffuseModulation = f:ReadColor()
|
|
return 544
|
|
end
|
|
|
|
-- Added Dissable-flag for X360
|
|
version[9] = function( f, obj, m )
|
|
version[8]( f, obj, m )
|
|
-- The first byte seems to be the indecator.
|
|
-- All maps have the first byte as 0x00, where the L4D2 map; 'c2m4_barns.bsp', tells us it is 0x01 is true.
|
|
obj.DisableX360 = f:ReadByte() == 1 -- The first byte is the indecator
|
|
-- The last 3 bytes seems to be random data, to fill out the 32bit network-limit
|
|
f:Skip( 24 )
|
|
return 576
|
|
end
|
|
|
|
-- This version is for TF2 and some CS:S maps.
|
|
-- Was build on version 6. Guess they where never meant to be released on consoles and only PC ( Since they use DXLevel )
|
|
version[10] = function( f, obj, m )
|
|
version[6]( f, obj, m )
|
|
obj.lightmapResolutionX = f:ReadLong()
|
|
obj.lightmapResolutionY = f:ReadLong()
|
|
return 576
|
|
end
|
|
|
|
-- ( Version 7* ) This version is for some CSGO maps. I guess it was for the console support.
|
|
version["10A"] = function( f, obj, m )
|
|
version[9]( f, obj, m )
|
|
obj.FlagsEx = f:ReadULong()
|
|
return 608
|
|
end
|
|
|
|
-- The newest CSGO maps. Might have left the console's behind with the newest map versions.
|
|
version[11] = function( f, obj, m )
|
|
local q = version[9]( f, obj, m )
|
|
obj.FlagsEx = f:ReadULong()
|
|
obj.UniformScale = f:ReadFloat()
|
|
return q + 64
|
|
end
|
|
|
|
--- @class StaticProp
|
|
|
|
--- @param f BitBuffer
|
|
--- @param ver number
|
|
--- @return StaticProp, number
|
|
local function CreateStaticProp( f, ver, m )
|
|
local obj = {}
|
|
local startTell = f:Tell()
|
|
|
|
version[ver]( f, obj, m )
|
|
obj.version = ver
|
|
|
|
local sizeUsed = f:Tell() - startTell
|
|
return setmetatable( obj, meta_staticprop ), sizeUsed
|
|
end
|
|
|
|
--- Returns a list of staticprops.
|
|
--- @return StaticProp[]
|
|
function meta:GetStaticProps()
|
|
if self._staticprops then return self._staticprops end
|
|
|
|
local gameLump = self:GetGameLump( 1936749168 ) -- 1936749168 == "sprp"
|
|
local b = gameLump.buffer
|
|
local propVersion = gameLump.version
|
|
|
|
if b:Size() < 1 or not NikNaks._Source:find( "niknak" ) then -- This map doesn't have staticprops, or doesn't support them.
|
|
self._staticprops = {}
|
|
self._staticprops_mdl = {}
|
|
return self._staticprops
|
|
end
|
|
|
|
if propVersion > 11 then
|
|
ErrorNoHalt( self._mapfile .. " has an unknown static-prop version!" )
|
|
self._staticprops = {}
|
|
self._staticprops_mdl = {}
|
|
return self._staticprops
|
|
end
|
|
|
|
-- Load the model list. This list is used by the static_props.
|
|
--- @type string[]
|
|
self._staticprops_mdl = {}
|
|
|
|
local n = b:ReadLong()
|
|
if n > 16384 then -- Check if we overread the max static props.
|
|
ErrorNoHalt( self._mapfile .. " has more than 16384 models!" )
|
|
self._staticprops = {}
|
|
return self._staticprops
|
|
end
|
|
|
|
for i = 1, n do
|
|
-- All model-paths are saved as char[128]. Any overflow are nullbytes.
|
|
local model = ""
|
|
|
|
for i2 = 1, 128 do
|
|
local c = string.char( b:ReadByte() )
|
|
if string.match( c,"[%w_%-%.%/]" ) then -- Just in case, we check for "valid" chars instead.
|
|
model = model .. c
|
|
end
|
|
end
|
|
|
|
self._staticprops_mdl[i] = model
|
|
end
|
|
|
|
-- Read the leaf-array. (Unused atm). Prob an index for the static props. However each static-prop already hold said data.
|
|
b:Skip( 16 * b:ReadLong() )
|
|
|
|
-- Read static props
|
|
local count = b:ReadLong()
|
|
if count > 16384 then -- Check if we are above the max staticprop.
|
|
ErrorNoHalt( self._mapfile .. " has more than 16384 staticprops!" )
|
|
self._staticprops = {}
|
|
return self._staticprops
|
|
end
|
|
|
|
-- We calculate the amount of static props within this space. It is more stable.
|
|
local staticStart = b:Tell()
|
|
local endPos = b:Size()
|
|
local staticSize = ( endPos - staticStart ) / count
|
|
local staticUsed
|
|
|
|
--- @type StaticProp[]
|
|
self._staticprops = {}
|
|
|
|
-- Check for the 7* version.
|
|
if staticSize == 608 and propVersion == 10 then
|
|
propVersion = "10A"
|
|
end
|
|
|
|
for i = 0, count - 1 do
|
|
-- This is to try and get as much valid data we can.
|
|
b:Seek( staticStart + staticSize * i )
|
|
local sObj, sizeused = CreateStaticProp( b, propVersion, self._staticprops_mdl, staticSize )
|
|
staticUsed = staticUsed or sizeused
|
|
sObj.Index = i
|
|
self._staticprops[i] = sObj
|
|
end
|
|
|
|
if staticUsed and staticUsed ~= staticSize then
|
|
ErrorNoHalt( "Was unable to parse " .. self._mapfile .. "'s StaticProps correctly!" )
|
|
end
|
|
|
|
return self._staticprops
|
|
end
|
|
|
|
--- Returns the static-prop object from said index.
|
|
--- @param index number
|
|
--- @return StaticProp
|
|
function meta:GetStaticProp( index )
|
|
return self:GetStaticProps()[index]
|
|
end
|
|
|
|
--- Returns a list of all static-prop models used by the map.
|
|
--- @return string[]
|
|
function meta:GetStaticPropModels()
|
|
if self._staticprops_mdl then return self._staticprops_mdl end
|
|
|
|
self:GetStaticProps() -- If no model list, then load the gamelump.
|
|
return self._staticprops_mdl
|
|
end
|
|
|
|
--- Returns a list of all static-props matching the model.
|
|
--- @param model string
|
|
--- @return StaticProp[]
|
|
function meta:FindStaticByModel( model )
|
|
local t = {}
|
|
|
|
for _, v in pairs( self:GetStaticProps() ) do
|
|
if v.PropType == model then
|
|
t[#t + 1] = v
|
|
end
|
|
end
|
|
|
|
return t
|
|
end
|
|
|
|
--- Returns a list of all static-props, within the specified box.
|
|
--- @param boxMins Vector
|
|
--- @param boxMaxs Vector
|
|
--- @return StaticProp[]
|
|
function meta:FindStaticInBox( boxMins, boxMaxs )
|
|
local t = {}
|
|
|
|
for _, v in pairs( self:GetStaticProps() ) do
|
|
local origin = v.Origin
|
|
if origin and v.Origin:WithinAABox( boxMins, boxMaxs ) then
|
|
t[#t + 1] = v
|
|
end
|
|
end
|
|
|
|
return t
|
|
end
|
|
|
|
--- Returns a list of all static-props, within the specified sphere.
|
|
--- @param origin Vector
|
|
--- @param radius number
|
|
--- @return StaticProp[]
|
|
function meta:FindStaticInSphere( origin, radius )
|
|
radius = radius ^ 2
|
|
local t = {}
|
|
|
|
for _, v in pairs( self:GetStaticProps() ) do
|
|
local spOrigin = v.Origin
|
|
if spOrigin and spOrigin:DistToSqr( origin ) <= radius then
|
|
t[#t + 1] = v
|
|
end
|
|
end
|
|
|
|
return t
|
|
end
|
|
|
|
--- Returns the StaticProp index
|
|
function meta_staticprop:GetIndex()
|
|
return self.Index
|
|
end
|
|
|
|
--- Returns the origin
|
|
function meta_staticprop:GetPos()
|
|
return self.Origin
|
|
end
|
|
|
|
--- Returns the angles
|
|
function meta_staticprop:GetAngles()
|
|
return self.Angles
|
|
end
|
|
|
|
--- Returns the model path
|
|
function meta_staticprop:GetModel()
|
|
return self.PropType
|
|
end
|
|
|
|
--- Returns the skin index
|
|
function meta_staticprop:GetSkin()
|
|
return self.Skin or 0
|
|
end
|
|
|
|
--- @return Color
|
|
function meta_staticprop:GetColor()
|
|
return self.DiffuseModulation or color_white
|
|
end
|
|
|
|
function meta_staticprop:GetScale()
|
|
return self.UniformScale or 1
|
|
end
|
|
meta_staticprop.GetModelScale = meta_staticprop.GetScale
|
|
|
|
--- Returns the solid enum. See: https://wiki.facepunch.com/gmod/Enums/SOLID
|
|
function meta_staticprop:GetSolid()
|
|
return self.Solid
|
|
end
|
|
|
|
--- Returns the lighting origin
|
|
function meta_staticprop:GetLightingOrigin()
|
|
return self.LightingOrigin
|
|
end
|
|
|
|
--- Returns the flags
|
|
function meta_staticprop:GetFlags()
|
|
return self.Flags
|
|
end
|
|
|
|
--- Returns true if the staticprop has a flag.
|
|
--- @param flag number
|
|
--- @return boolean
|
|
function meta_staticprop:HasFlag( flag )
|
|
return band( self:GetFlags(), flag ) ~= 0
|
|
end
|
|
|
|
--- Returns true if the static prop is disabled on X360.
|
|
--- @return boolean
|
|
function meta_staticprop:GetDisableX360()
|
|
return self.DisableX360 or false
|
|
end
|
|
|
|
--- Returns the model bounds.
|
|
--- @return Vector
|
|
--- @return Vector
|
|
function meta_staticprop:GetModelBounds()
|
|
local a, b = NikNaks.ModelSize( self:GetModel() )
|
|
local s = self:GetScale()
|
|
return a * s, b * s
|
|
end
|
|
meta_staticprop.GetModelRenderBounds = meta_staticprop.GetModelBounds
|
|
meta_staticprop.GetRenderBounds = meta_staticprop.GetModelBounds
|
|
|
|
-- Fade Functions
|
|
|
|
function meta_staticprop:GetFadeMinDist()
|
|
return self.FadeMinDist
|
|
end
|
|
|
|
function meta_staticprop:GetFadeMaxDist()
|
|
return self.FadeMaxDist
|
|
end
|
|
|
|
function meta_staticprop:GetForceFadeScale()
|
|
return self.ForcedFadeScale or 1
|
|
end
|
|
|
|
-- "Other"
|
|
|
|
--[[ DXLevel
|
|
0 = Ignore
|
|
70 = DirectX 7
|
|
80 = DirectX 8
|
|
81 = DirectX 8.1
|
|
90 = DirectX 9
|
|
95 = DirectX 9+ ( 9.3 )
|
|
98 = DirectX 9Ex
|
|
]]
|
|
function meta_staticprop:GetDXLevel()
|
|
return self.MinDXLevel or 0, self.MaxDXLevel or 0
|
|
end
|
|
|
|
if CLIENT then
|
|
-- Checks to see if the client has the directX level required to render the static prop.
|
|
function meta_staticprop:HasDXLevel()
|
|
local num = render.GetDXLevel()
|
|
if self.MinDXLevel ~= 0 and num < self.MinDXLevel then return false end
|
|
if self.MaxDXLevel ~= 0 and num > self.MaxDXLevel then return false end
|
|
return true
|
|
end
|
|
end
|
|
|
|
--[[ There must be a list of CPU's and what level they are.
|
|
CPU Level
|
|
0 = Ignore
|
|
1 = "Low"
|
|
2 = "Medium"
|
|
3 = "High"
|
|
]]
|
|
function meta_staticprop:GetCPULevel()
|
|
return self.MinCPULevel or 0, self.MaxCPULevel or 0
|
|
end
|
|
|
|
--[[ There must be a list of GPU's and what level they are.
|
|
GPU Level
|
|
0 = Ignore
|
|
1 = "Low"
|
|
2 = "Medium"
|
|
3 = "High"
|
|
]]
|
|
function meta_staticprop:GetGPULevel()
|
|
return self.MinGPULevel or 0, self.MaxGPULevel or 0
|
|
end
|
|
|
|
-- Allows to set the lightmap resolution for said static-prop.
|
|
-- Checkout https://tf2maps.net/threads/guide-lightmap-optimization.33113/ for more info
|
|
function meta_staticprop:GetLightMapResolution()
|
|
return self.lightmapResolutionX, self.lightmapResolutionY
|
|
end
|
|
|
|
--- Returns the "Further" BitFlags. Seems to be only used for the "STATIC_PROP_FLAGS_EX_DISABLE_CSM" flag.
|
|
--- @return number
|
|
function meta_staticprop:GetFlagExs()
|
|
return self.FlagsEx or 0
|
|
end
|
|
|
|
--- Returns true if the staticprop has an exflag.
|
|
--- @param flag number
|
|
--- @return boolean
|
|
function meta_staticprop:HasFlagEx( flag )
|
|
return band( self:GetFlagExs(), flag ) ~= 0
|
|
end
|
|
|
|
--- Returns the version of the static props.
|
|
--- Note: version 7* will be returned as a string: "10A"
|
|
function meta_staticprop:GetVersion()
|
|
return self.version
|
|
end
|