This commit is contained in:
lifestorm
2024-08-05 18:40:29 +03:00
parent c4d91bf369
commit 324f19217d
8040 changed files with 1853423 additions and 21 deletions

View File

@@ -0,0 +1,335 @@
--[[
| 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/
--]]
--[[---------------------------------------------------------
Get the real frame time, instead of the
host_timescale linked frametime. This is for things
like GUI effects. NOT FOR REAL IN GAME STUFF(!!!)
-----------------------------------------------------------]]
local FrameTime = 0
local LastQuery = 0
function RealFrameTime() return FrameTime end
local function RealFrameTimeThink()
FrameTime = math.Clamp( SysTime() - LastQuery, 0, 0.1 )
LastQuery = SysTime()
end
hook.Add( "Think", "RealFrameTime", RealFrameTimeThink ) -- Think is called after every frame on the client.
-- Make Portal 2 materials work out of the box
matproxy.Add( {
name = "FizzlerVortex",
init = function( self, mat, values )
end,
bind = function( self, mat, ent )
mat:SetFloat( "$flow_color_intensity", 1 )
-- Less than ideal, but serves as an example
--[[local entities = {}
for k, v in pairs( ents.FindInSphere( ent:GetPos(), ent:BoundingRadius() ) ) do
if ( v == ent || v:GetMoveType() != MOVETYPE_VPHYSICS ) then continue end
table.insert( entities, v )
end
table.sort( entities, function( a, b ) return a:GetPos():Distance( ent:GetPos() ) < b:GetPos():Distance( ent:GetPos() ) end )
if ( entities[ 1 ] ) then
mat:SetFloat( "$FLOW_VORTEX1", 1 )
mat:SetVector( "$FLOW_VORTEX_POS1", entities[ 1 ]:GetPos() )
else
mat:SetFloat( "$FLOW_VORTEX1", 0 )
end
if ( entities[ 2 ] ) then
mat:SetFloat( "$FLOW_VORTEX2", 1 )
mat:SetVector( "$FLOW_VORTEX_POS2", entities[ 2 ]:GetPos() )
else
mat:SetFloat( "$FLOW_VORTEX2", 0 )
end]]
end
} )
local function RenderSpawnIcon_Prop( model, pos, middle, size )
if ( size < 900 ) then
size = size * ( 1 - ( size / 900 ) )
else
size = size * ( 1 - ( size / 4096 ) )
end
size = math.Clamp( size, 5, 1000 )
local ViewAngle = Angle( 25, 220, 0 )
local ViewPos = pos + ViewAngle:Forward() * size * -15
local view = {}
view.fov = 4 + size * 0.04
view.origin = ViewPos + middle
view.znear = 1
view.zfar = ViewPos:Distance( pos ) + size * 2
view.angles = ViewAngle
return view
end
local function RenderSpawnIcon_Ragdoll( model, pos, middle, size )
local at = model:GetAttachment( model:LookupAttachment( "eyes" ) )
if ( !at ) then at = { Pos = model:GetPos(), Ang = model:GetAngles() } end
local ViewAngle = at.Ang + Angle( -10, 160, 0 )
local ViewPos = at.Pos + ViewAngle:Forward() * -60 + ViewAngle:Up() * -2
local view = {}
view.fov = 10
view.origin = ViewPos
view.znear = 0.1
view.zfar = 100
view.angles = ViewAngle
return view
end
--
-- For some TF2 ragdolls which do not have "eye" attachments
--
local function RenderSpawnIcon_Ragdoll_Head( model, pos, middle, size )
local at = model:GetAttachment( model:LookupAttachment( "head" ) )
if ( !at ) then at = { Pos = model:GetPos(), Ang = model:GetAngles() } end
local ViewAngle = at.Ang + Angle( -10, 160, 0 )
local ViewPos = at.Pos + ViewAngle:Forward() * -67 + ViewAngle:Up() * -7 + ViewAngle:Right() * 1.5
local view = {}
view.fov = 10
view.origin = ViewPos
view.znear = 0.1
view.zfar = 100
view.angles = ViewAngle
return view
end
local function RenderSpawnIcon_Ragdoll_Facemask( model, pos, middle, size )
local at = model:GetAttachment( model:LookupAttachment( "facemask" ) )
if ( !at ) then at = { Pos = model:GetPos(), Ang = model:GetAngles() } end
local ViewAngle = at.Ang
ViewAngle:RotateAroundAxis( ViewAngle:Right(), -10 )
ViewAngle:RotateAroundAxis( ViewAngle:Up(), 160 )
local ViewPos = at.Pos + ViewAngle:Forward() * -67 + ViewAngle:Up() * -2 + ViewAngle:Right() * -1
local view = {}
view.fov = 10
view.origin = ViewPos
view.znear = 0.1
view.zfar = 100
view.angles = ViewAngle
return view
end
local function RenderSpawnIcon_Ragdoll_Forward( model, pos, middle, size )
local at = model:GetAttachment( model:LookupAttachment( "forward" ) )
if ( !at ) then at = { Pos = model:GetPos(), Ang = model:GetAngles() } end
local ViewAngle = at.Ang + Angle( 10, -20, 0 )
local ViewPos = at.Pos + ViewAngle:Forward() * -67 + ViewAngle:Up() * -1 + ViewAngle:Right() * 2.5
local view = {}
view.fov = 10
view.origin = ViewPos
view.znear = 0.1
view.zfar = 100
view.angles = ViewAngle
return view
end
local function RenderSpawnIcon_DOD( model, pos, middle, size )
local ViewAngle = Angle( 0, 160, 0 )
local ViewPos = pos + ViewAngle:Forward() * -67 + ViewAngle:Up() * 30 + ViewAngle:Right() * 2.5
local view = {}
view.fov = 10
view.origin = ViewPos + middle
view.znear = 1
view.zfar = ViewPos:Distance( pos ) + size * 2
view.angles = ViewAngle
return view
end
local function RenderSpawnIcon_CS( model, pos, middle, size )
local ViewAngle = Angle( 0, 160, 0 )
local ViewPos = pos + ViewAngle:Forward() * -70 + ViewAngle:Up() * 32.4 + ViewAngle:Right() * 1.5
local view = {}
view.fov = 10
view.origin = ViewPos + middle
view.znear = 1
view.zfar = ViewPos:Distance( pos ) + size * 2
view.angles = ViewAngle
return view
end
local function RenderSpawnIcon_Special( model, pos, middle, size, x, y, z )
local ViewAngle = Angle( 15, 140, 0 )
local ViewPos = pos + ViewAngle:Forward() * x + ViewAngle:Up() * y + ViewAngle:Right() * z
local view = {}
view.fov = 20
view.origin = ViewPos + middle
view.znear = 1
view.zfar = ViewPos:Distance( pos ) + size * 2
view.angles = ViewAngle
return view
end
SpawniconGenFunctions = {}
function PositionSpawnIcon( model, pos, noAngles )
local mn, mx = model:GetRenderBounds()
local middle = ( mn + mx ) * 0.5
local size = 0
size = math.max( size, math.abs( mn.x ) + math.abs( mx.x ) )
size = math.max( size, math.abs( mn.y ) + math.abs( mx.y ) )
size = math.max( size, math.abs( mn.z ) + math.abs( mx.z ) )
model:SetPos( pos )
if ( !noAngles ) then model:SetAngles( angle_zero ) end
local ModelName = model:GetModel()
ModelName = string.Replace( ModelName, "--", "/" )
ModelName = string.Replace( ModelName, "\\", "/" )
ModelName = string.Replace( ModelName, "//", "/" )
ModelName = string.Replace( ModelName, "\\\\", "/" )
local fnc = SpawniconGenFunctions[ ModelName ]
if ( fnc ) then return fnc( model, pos, middle, size ) end
if ( model:LookupAttachment( "eyes" ) > 0 ) then
return RenderSpawnIcon_Ragdoll( model, pos, middle, size )
end
if ( model:LookupAttachment( "head" ) > 0 ) then
return RenderSpawnIcon_Ragdoll_Head( model, pos, middle, size )
end
-- CS:GO Player Models
if ( model:LookupAttachment( "facemask" ) > 0 ) then
return RenderSpawnIcon_Ragdoll_Facemask( model, pos, middle, size )
end
-- CS:GO Hostages
if ( model:LookupAttachment( "forward" ) > 0 ) then
return RenderSpawnIcon_Ragdoll_Forward( model, pos, middle, size )
end
return RenderSpawnIcon_Prop( model, pos, middle, size )
end
-- DOD Player Models
SpawniconGenFunctions[ "models/player/american_assault.mdl" ] = RenderSpawnIcon_DOD
SpawniconGenFunctions[ "models/player/american_mg.mdl" ] = RenderSpawnIcon_DOD
SpawniconGenFunctions[ "models/player/american_rifleman.mdl" ] = RenderSpawnIcon_DOD
SpawniconGenFunctions[ "models/player/american_rocket.mdl" ] = RenderSpawnIcon_DOD
SpawniconGenFunctions[ "models/player/american_sniper.mdl" ] = RenderSpawnIcon_DOD
SpawniconGenFunctions[ "models/player/american_support.mdl" ] = RenderSpawnIcon_DOD
SpawniconGenFunctions[ "models/player/german_assault.mdl" ] = RenderSpawnIcon_DOD
SpawniconGenFunctions[ "models/player/german_mg.mdl" ] = RenderSpawnIcon_DOD
SpawniconGenFunctions[ "models/player/german_rifleman.mdl" ] = RenderSpawnIcon_DOD
SpawniconGenFunctions[ "models/player/german_rocket.mdl" ] = RenderSpawnIcon_DOD
SpawniconGenFunctions[ "models/player/german_sniper.mdl" ] = RenderSpawnIcon_DOD
SpawniconGenFunctions[ "models/player/german_support.mdl" ] = RenderSpawnIcon_DOD
-- CS Player Models
SpawniconGenFunctions[ "models/player/ct_gign.mdl" ] = RenderSpawnIcon_CS
SpawniconGenFunctions[ "models/player/ct_sas.mdl" ] = RenderSpawnIcon_CS
SpawniconGenFunctions[ "models/player/ct_urban.mdl" ] = RenderSpawnIcon_CS
SpawniconGenFunctions[ "models/player/ct_gsg9.mdl" ] = RenderSpawnIcon_CS
SpawniconGenFunctions[ "models/player/t_leet.mdl" ] = RenderSpawnIcon_CS
SpawniconGenFunctions[ "models/player/t_phoenix.mdl" ] = RenderSpawnIcon_CS
SpawniconGenFunctions[ "models/player/t_arctic.mdl" ] = RenderSpawnIcon_CS
SpawniconGenFunctions[ "models/player/t_guerilla.mdl" ] = RenderSpawnIcon_CS
-- L4D Models
SpawniconGenFunctions[ "models/infected/witch.mdl" ] = function( a, b, c, d ) return RenderSpawnIcon_Special( a, b, c, d, -40, 25, 0 ) end
SpawniconGenFunctions[ "models/infected/smoker.mdl" ] = function( a, b, c, d ) return RenderSpawnIcon_Special( a, b, c, d, -60, 33, 10 ) end
SpawniconGenFunctions[ "models/infected/hunter.mdl" ] = function( a, b, c, d ) return RenderSpawnIcon_Special( a, b, c, d, -50, 26, 2 ) end
SpawniconGenFunctions[ "models/infected/hulk.mdl" ] = function( a, b, c, d ) return RenderSpawnIcon_Special( a, b, c, d, -70, 30, 11 ) end
SpawniconGenFunctions[ "models/infected/boomer.mdl" ] = function( a, b, c, d ) return RenderSpawnIcon_Special( a, b, c, d, -50, 27, 0 ) end
SpawniconGenFunctions[ "models/infected/common_female01.mdl" ] = function ( model, pos, middle, size )
local at = model:GetAttachment( model:LookupAttachment( "forward" ) )
if ( !at ) then at = { Pos = model:GetPos(), Ang = model:GetAngles() } end
local ViewAngle = at.Ang + Angle( 180, 180, 0 ) + Angle( 10, -85, -85 )
local ViewPos = at.Pos + ViewAngle:Forward() * -76 + ViewAngle:Up() * -1.5 + ViewAngle:Right() * 0
return { fov = 10, origin = ViewPos, znear = 0.1, zfar = 200, angles = ViewAngle }
end
SpawniconGenFunctions[ "models/infected/common_female_nurse01.mdl" ] = SpawniconGenFunctions[ "models/infected/common_female01.mdl" ]
SpawniconGenFunctions[ "models/infected/common_female_rural01.mdl" ] = SpawniconGenFunctions[ "models/infected/common_female01.mdl" ]
SpawniconGenFunctions[ "models/infected/common_male01.mdl" ] = SpawniconGenFunctions[ "models/infected/common_female01.mdl" ]
SpawniconGenFunctions[ "models/infected/common_test.mdl" ] = SpawniconGenFunctions[ "models/infected/common_female01.mdl" ]
SpawniconGenFunctions[ "models/infected/common_morph_test.mdl" ] = SpawniconGenFunctions[ "models/infected/common_female01.mdl" ] -- Bad start animation
SpawniconGenFunctions[ "models/infected/common_male_fallen_survivor.mdl" ] = SpawniconGenFunctions[ "models/infected/common_female01.mdl" ] -- Bad start animation
SpawniconGenFunctions[ "models/infected/common_male_baggagehandler_01.mdl" ] = SpawniconGenFunctions[ "models/infected/common_male01.mdl" ]
SpawniconGenFunctions[ "models/infected/common_male_pilot.mdl" ] = SpawniconGenFunctions[ "models/infected/common_male01.mdl" ]
SpawniconGenFunctions[ "models/infected/common_male_rural01.mdl" ] = SpawniconGenFunctions[ "models/infected/common_male01.mdl" ]
SpawniconGenFunctions[ "models/infected/common_male_suit.mdl" ] = SpawniconGenFunctions[ "models/infected/common_male01.mdl" ]
SpawniconGenFunctions[ "models/infected/common_military_male01.mdl" ] = SpawniconGenFunctions[ "models/infected/common_male01.mdl" ]
SpawniconGenFunctions[ "models/infected/common_police_male01.mdl" ] = SpawniconGenFunctions[ "models/infected/common_male01.mdl" ]
SpawniconGenFunctions[ "models/infected/common_patient_male01.mdl" ] = SpawniconGenFunctions[ "models/infected/common_male01.mdl" ]
SpawniconGenFunctions[ "models/infected/common_surgeon_male01.mdl" ] = SpawniconGenFunctions[ "models/infected/common_male01.mdl" ] -- Bad start animation
SpawniconGenFunctions[ "models/infected/common_tsaagent_male01.mdl" ] = SpawniconGenFunctions[ "models/infected/common_male01.mdl" ]
SpawniconGenFunctions[ "models/infected/common_worker_male01.mdl" ] = SpawniconGenFunctions[ "models/infected/common_male01.mdl" ]
-- ZPS Zombies
SpawniconGenFunctions[ "models/zombies/zombie0/zombie0.mdl" ] = function( a, b, c, d ) return RenderSpawnIcon_Special( a, b, c, d, -100, 17, 10 ) end
SpawniconGenFunctions[ "models/zombies/zombie1/zombie1.mdl" ] = function( a, b, c, d ) return RenderSpawnIcon_Special( a, b, c, d, -100, 17, 10 ) end
SpawniconGenFunctions[ "models/zombies/zombie2/zombie2.mdl" ] = function( a, b, c, d ) return RenderSpawnIcon_Special( a, b, c, d, -100, 17, 10 ) end
SpawniconGenFunctions[ "models/zombies/zombie3/zombie3.mdl" ] = function( a, b, c, d ) return RenderSpawnIcon_Special( a, b, c, d, -100, 17, 10 ) end
SpawniconGenFunctions[ "models/zombies/zombie4/zombie4.mdl" ] = function( a, b, c, d ) return RenderSpawnIcon_Special( a, b, c, d, -100, 17, 10 ) end
SpawniconGenFunctions[ "models/zombies/zombie5/zombie5.mdl" ] = function( a, b, c, d ) return RenderSpawnIcon_Special( a, b, c, d, -100, 17, 10 ) end
-- L4D2
SpawniconGenFunctions[ "models/infected/boomette.mdl" ] = function( a, b, c, d ) return RenderSpawnIcon_Special( a, b, c, d, -50, 28, 0 ) end
SpawniconGenFunctions[ "models/infected/charger.mdl" ] = function( a, b, c, d ) return RenderSpawnIcon_Special( a, b, c, d, -70, 14, 20 ) end
SpawniconGenFunctions[ "models/infected/jockey.mdl" ] = function( a, b, c, d ) return RenderSpawnIcon_Special( a, b, c, d, -50, 0, 7 ) end
SpawniconGenFunctions[ "models/infected/spitter.mdl" ] = function( a, b, c, d ) return RenderSpawnIcon_Special( a, b, c, d, -1, 0, -70 ) end -- as good as deleted
SpawniconGenFunctions[ "models/infected/hulk_dlc3.mdl" ] = SpawniconGenFunctions[ "models/infected/hulk.mdl" ]

141
lua/includes/util/color.lua Normal file
View File

@@ -0,0 +1,141 @@
--[[
| 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/
--]]
local COLOR = {}
COLOR.__index = COLOR
--[[---------------------------------------------------------
Register our metatable to make it accessible using FindMetaTable
-----------------------------------------------------------]]
debug.getregistry().Color = COLOR
--[[---------------------------------------------------------
To easily create a color table
-----------------------------------------------------------]]
function Color( r, g, b, a )
a = a or 255
return setmetatable( { r = math.min( tonumber(r), 255 ), g = math.min( tonumber(g), 255 ), b = math.min( tonumber(b), 255 ), a = math.min( tonumber(a), 255 ) }, COLOR )
end
--[[---------------------------------------------------------
Change the alpha of a color
-----------------------------------------------------------]]
function ColorAlpha( c, a )
return Color( c.r, c.g, c.b, a )
end
--[[---------------------------------------------------------
Checks if the given varible is a color object
-----------------------------------------------------------]]
function IsColor( obj )
return getmetatable(obj) == COLOR
end
--[[---------------------------------------------------------
Returns color as a string
-----------------------------------------------------------]]
function COLOR:__tostring()
return string.format( "%d %d %d %d", self.r, self.g, self.b, self.a )
end
--[[---------------------------------------------------------
Compares two colors
-----------------------------------------------------------]]
function COLOR:__eq( c )
return self.r == c.r and self.g == c.g and self.b == c.b and self.a == c.a
end
--[[---------------------------------------------------------
Converts a color to HSL color space
-----------------------------------------------------------]]
function COLOR:ToHSL()
return ColorToHSL( self )
end
--[[---------------------------------------------------------
Converts a color to HSV
-----------------------------------------------------------]]
function COLOR:ToHSV()
return ColorToHSV( self )
end
--[[---------------------------------------------------------
Converts color to vector - loss of precision / alpha lost
-----------------------------------------------------------]]
function COLOR:ToVector()
return Vector( self.r / 255, self.g / 255, self.b / 255 )
end
--[[---------------------------------------------------------
Unpacks the color into four variables
-----------------------------------------------------------]]
function COLOR:Unpack()
return self.r, self.g, self.b, self.a
end
function COLOR:Lerp( target_clr, frac )
return Color( Lerp( frac, self.r, target_clr.r ), Lerp( frac, self.g, target_clr.g ), Lerp( frac, self.b, target_clr.b ), Lerp( frac, self.a, target_clr.a ) )
end
function COLOR:SetUnpacked( r, g, b, a )
self.r = r or 255
self.g = g or 255
self.b = b or 255
self.a = a or 255
end
function COLOR:ToTable()
return { self.r, self.g, self.b, self.a }
end
local imat = FindMetaTable( "IMaterial" )
if ( imat.GetColor4Part ) then
function imat:GetColor( ... )
return Color( self:GetColor4Part( ... ) )
end
else
-- For those clients that do not have the above function yet
-- TODO: Delete me
local oldGetColor = imat.GetColor
function imat:GetColor( ... )
local tbl = oldGetColor( self, ... )
return Color( tbl.r, tbl.g, tbl.b, tbl.a )
end
end

View File

@@ -0,0 +1,50 @@
--[[
| 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/
--]]
function JS_Language( html )
html:AddFunction( "language", "Update", function( phrase )
if ( !phrase ) then return end
return language.GetPhrase( phrase )
end )
end
function JS_Utility( html )
html:AddFunction( "util", "MotionSensorAvailable", function()
return motionsensor.IsAvailable()
end )
end
function JS_Workshop( html )
html:AddFunction( "gmod", "OpenWorkshopFile", function( param ) steamworks.ViewFile( param ) end )
html:AddFunction( "gmod", "DeleteLocal", function( param ) file.Delete( param, "MOD" ) end )
html:AddFunction( "gmod", "FetchItems", function( namespace, cat, offset, perpage, extraTags, searchText, filter, sort )
_G[ namespace ]:Fetch( cat, tonumber( offset ), tonumber( perpage ), string.Explode( ",", extraTags ), searchText, filter, sort )
end )
html:AddFunction( "gmod", "Vote", function( id, vote ) steamworks.Vote( id, tobool( vote ) ) end )
html:AddFunction( "gmod", "SetFavorite", function( id, vote ) steamworks.SetFavorite( id, tobool( vote ) ) end )
html:AddFunction( "gmod", "Publish", function( namespace, filePath, background ) _G[ namespace ]:Publish( filePath, background ) end )
// Dupes
html:AddFunction( "gmod", "DownloadDupe", function( param ) ws_dupe:DownloadAndArm( param ) end )
html:AddFunction( "gmod", "ArmDupe", function( param ) ws_dupe:Arm( param ) end )
html:AddFunction( "gmod", "SaveDupe", function( param ) RunConsoleCommand( "dupe_save", "spawnmenu" ) end )
// Saves
html:AddFunction( "gmod", "DownloadSave", function( param ) ws_save:DownloadAndLoad( param ) end )
html:AddFunction( "gmod", "LoadSave", function( param ) ws_save:Load( param ) end )
html:AddFunction( "gmod", "SaveSave", function( param ) RunConsoleCommand( "gm_save", "spawnmenu" ) end )
end

View File

@@ -0,0 +1,103 @@
--[[
| 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/
--]]
--=============================================================================--
-- ___ ___ _ _ _ __ _ ___ ___ __ __
-- |_ _|| __| / \ | \_/ | / _| / \ | o \ o \\ V /
-- | | | _| | o || \_/ | ( |_n| o || / / \ /
-- |_| |___||_n_||_| |_| \__/|_n_||_|\\_|\\ |_| 2007
--
--=============================================================================--
local DatabasedModels = {}
if ( !sql.TableExists( "modelinfo" ) ) then
sql.Query( [[CREATE TABLE IF NOT EXISTS modelinfo ( name TEXT NOT NULL PRIMARY KEY,
poseparams INTEGER,
numsequences INTEGER,
numattachments INTEGER,
numbonecontrollers INTEGER,
numskins INTEGER,
size INTEGER );]] )
end
--[[---------------------------------------------------------
Called from the engine on model load to enable Lua to cache
the model stats in a database, so that rather than building
all in one go, they'll get updated as the player plays.
-----------------------------------------------------------]]
function OnModelLoaded( ModelName, NumPoseParams, NumSeq, NumAttachments, NumBoneControllers, NumSkins, Size )
local ModelName = string.lower( string.gsub( ModelName, "\\", "/" ) )
ModelName = "models/".. ModelName
-- No need to store a model more than once per session
if ( DatabasedModels[ ModelName ] ) then return end
DatabasedModels[ ModelName ] = true
-- Just in case. Don't want errors spewing all over
-- the place every time a model loads.
if ( !sql.TableExists( "modelinfo" ) ) then return end
local safeModelName = SQLStr( ModelName )
--
-- We delete the old entry because this model may have been updated.
-- The chances are very slim, but there's no real harm in it.
--
sql.Query( "DELETE FROM modelinfo WHERE model = "..safeModelName )
sql.Query( Format( [[INSERT INTO modelinfo ( name,
poseparams,
numsequences,
numattachments,
numbonecontrollers,
numskins,
size )
VALUES
( %s, %i, %i, %i, %i, %i, %i ) ]],
safeModelName,
NumPoseParams,
NumSeq,
NumAttachments,
NumBoneControllers,
NumSkins,
Size
) )
--[[
MsgN( ModelName,
"\nNumPoseParams: ", NumPoseParams,
"\nNumSeq: ", NumSeq,
"\nNumAttachments: ", NumAttachments,
"\nNumBoneControllers: ", NumBoneControllers,
"\nNumSkins: ", NumSkins,
"\nSize: ", Size )
--]]
end
--[[---------------------------------------------------------
Returns the number of skins this model has. If we don't
know, it will return 0
-----------------------------------------------------------]]
function NumModelSkins( ModelName )
local ModelName = string.lower( ModelName )
local safeModelName = SQLStr( ModelName )
local num = sql.QueryValue( "SELECT numskins FROM modelinfo WHERE name = " .. safeModelName )
if ( num == nil ) then return 0 end
return tonumber( num ) or 0
end

119
lua/includes/util/sql.lua Normal file
View File

@@ -0,0 +1,119 @@
--[[
| 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/
--]]
-- Return if there's nothing to add on to
if ( !sql ) then return end
--[[----------------------------------------------------------
Attempts to make a string safe to put into the database
------------------------------------------------------------]]
function sql.SQLStr( str_in, bNoQuotes )
local str = tostring( str_in )
str = str:gsub( "'", "''" )
local null_chr = string.find( str, "\0" )
if ( null_chr ) then
str = string.sub( str, 1, null_chr - 1 )
end
if ( bNoQuotes ) then
return str
end
return "'" .. str .. "'"
end
SQLStr = sql.SQLStr
--[[---------------------------------------------------------
Returns true if the table exists. False if it doesn't
-----------------------------------------------------------]]
function sql.TableExists( name )
local r = sql.Query( "SELECT name FROM sqlite_master WHERE name=" .. SQLStr( name ) .. " AND type='table'" )
return r and true or false
end
--[[---------------------------------------------------------
Returns true if the index exists. False if it doesn't
-----------------------------------------------------------]]
function sql.IndexExists( name )
local r = sql.Query( "SELECT name FROM sqlite_master WHERE name=" .. SQLStr( name ) .. " AND type='index'" )
return r and true or false
end
--[[---------------------------------------------------------
Query and get a single row
eg sql.QueryRow( "SELECT * from ratings LIMIT 1" )
-----------------------------------------------------------]]
function sql.QueryRow( query, row )
row = row or 1
local r = sql.Query( query )
if ( r ) then return r[ row ] end
return r
end
--[[---------------------------------------------------------
Query and get a single value
eg sql.QueryValue( "SELECT count(*) from ratings" )
-----------------------------------------------------------]]
function sql.QueryValue( query )
local r = sql.QueryRow( query )
if ( r ) then
-- Is this really the best way to get the first/only value in a table
for k, v in pairs( r ) do return v end
end
return r
end
--[[---------------------------------------------------------
Call before lots of inserts (100+), will hold off writing to disk
until Commit is called, which will increase performance (a lot)
-----------------------------------------------------------]]
function sql.Begin()
sql.Query( "BEGIN;" )
end
--[[---------------------------------------------------------
See Above
-----------------------------------------------------------]]
function sql.Commit()
sql.Query( "COMMIT;" )
end
--[[----------------------------------------------------------
m_strError is set by the dll
------------------------------------------------------------]]
function sql.LastError()
return sql.m_strError
end

View File

@@ -0,0 +1,90 @@
--[[
| 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/
--]]
local Tooltip = nil
local TooltippedPanel = nil
--[[---------------------------------------------------------
Name: ChangeTooltip
Called from engine on hovering over a panel
-----------------------------------------------------------]]
function RemoveTooltip()
if ( !IsValid( Tooltip ) ) then return true end
Tooltip:Close()
Tooltip = nil
return true
end
--[[---------------------------------------------------------
Name: FindTooltip
-----------------------------------------------------------]]
function FindTooltip( panel )
-- Look at the parent panel for tooltips.
while ( IsValid( panel ) ) do
if ( panel.strTooltipText || panel.pnlTooltipPanel || panel.pnlTooltipPanelOverride ) then
return panel.strTooltipText, panel.pnlTooltipPanel, panel, panel.pnlTooltipPanelOverride
end
panel = panel:GetParent()
end
end
--[[---------------------------------------------------------
Name: ChangeTooltip
Called from engine on hovering over a panel
-----------------------------------------------------------]]
function ChangeTooltip( panel )
RemoveTooltip()
local Text, ContentPanel, PositionPanel, PanelOverride = FindTooltip( panel )
if ( !Text && !IsValid( ContentPanel ) && !PanelOverride ) then return end
Tooltip = vgui.Create( PanelOverride or "DTooltip" )
if ( Text ) then
Tooltip:SetText( Text )
elseif ( IsValid( ContentPanel ) ) then
Tooltip:SetContents( ContentPanel, false )
end
Tooltip:OpenForPanel( PositionPanel )
TooltippedPanel = panel
end
--[[---------------------------------------------------------
Name: EndTooltip
Called from engine on exiting from a panel
-----------------------------------------------------------]]
function EndTooltip( panel )
-- Don't do these checks, the engine has a problem with determing
-- which panel is currently being hovered in some very specific and unknown conditions
--if ( !IsValid( TooltippedPanel ) ) then return end
--if ( TooltippedPanel != panel ) then return end
RemoveTooltip()
end

View File

@@ -0,0 +1,51 @@
--[[
| 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/
--]]
local Panels = {}
hook.Add( "DrawOverlay", "VGUIShowLayoutPaint", function()
for panel, data in pairs( Panels ) do
if ( panel:IsValid() ) then
local x, y = panel:LocalToScreen( 0, 0 )
local Alpha = math.Clamp( (data.Time - SysTime()) / 0.3, 0, 1 ) * 100
surface.SetDrawColor( 255, 0, 0, Alpha )
surface.DrawRect( x, y, panel:GetWide(), panel:GetTall() )
surface.SetDrawColor( 0, 255, 0, Alpha )
surface.DrawOutlinedRect( x, y, panel:GetWide(), panel:GetTall() )
-- vgui_visualizelayout 2?
-- draw.SimpleText( panel:GetZPos(), "Default", x + 3, y, color_white )
end
if ( !panel:IsValid() || data.Time < SysTime() ) then
Panels[ panel ] = nil
end
end
end )
-- Called from the engine
function VisualizeLayout( panel )
local tab = {}
tab.Time = SysTime() + 0.3
Panels[ panel ] = tab
end

View File

@@ -0,0 +1,308 @@
--[[
| 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/
--]]
local PreviewCache = {}
local InfoCache = {}
local ListCache = {}
function WorkshopFileBase( namespace, requiredtags )
local ret = {}
ret.HTML = nil
function ret:Fetch( type, offset, perpage, extratags, searchText, filter, sort )
local tags = table.Copy( requiredtags )
for k, v in pairs( extratags ) do
if ( v == "" ) then continue end
table.insert( tags, v )
end
if ( type == "local" ) then
return self:FetchLocal( offset, perpage )
end
if ( type == "subscribed" ) then
return self:FetchSubscribed( offset, perpage, tags, searchText, false, filter, sort )
end
if ( type == "subscribed_ugc" ) then
return self:FetchSubscribed( offset, perpage, tags, searchText, true, filter, sort )
end
local userid = "0"
if ( type == "mine" ) then userid = "1" end
local cachename = type .. "-" .. table.concat( tags, "/" ) .. offset .. "-" .. perpage .. "-" .. userid
if ( type != "favorite" && ListCache[ cachename ] ) then
self:FillFileInfo( ListCache[ cachename ] )
return
end
steamworks.GetList( type, tags, offset, perpage, 0, userid, function( data )
if ( type != "favorite" ) then ListCache[ cachename ] = data end
self:FillFileInfo( data )
end )
end
function ret:FetchSubscribed( offset, perpage, tags, searchText, isUGC, filter, sort )
local subscriptions = {}
if ( isUGC ) then
subscriptions = engine.GetUserContent()
else
subscriptions = engine.GetAddons()
end
for id, e in pairs( subscriptions ) do
if ( e.timeadded == 0 ) then e.timeadded = os.time() end
end
if ( sort == "title" ) then
table.sort( subscriptions, function( a, b )
return a.title:lower() < b.title:lower()
end )
elseif ( sort == "size" ) then
table.sort( subscriptions, function( a, b )
return a.size > b.size
end )
elseif ( sort == "updated" ) then
table.sort( subscriptions, function( a, b )
return a.updated > b.updated
end )
else
table.sort( subscriptions, function( a, b )
return a.timeadded > b.timeadded
end )
end
-- First build a list of items that fit our search terms
local searchedItems = {}
local localFileHack = -1
for id, item in pairs( subscriptions ) do
-- This is a dirty hack for local addons, ideally should be done in engine, or not use solely IDs to identify addons
if ( item.wsid == "0" ) then
item.wsid = tostring( localFileHack ) -- why is this a string?
localFileHack = localFileHack - 1
end
-- Search for tags
local found = true
for _, tag in pairs( tags ) do
if ( !item.tags:lower():find( tag, 1, true ) ) then found = false end
end
if ( !found ) then continue end
-- Search for searchText
if ( searchText:Trim() != "" && !item.title:lower():find( searchText:lower(), 1, true ) ) then
continue
end
if ( filter && filter == "enabledonly" && !steamworks.ShouldMountAddon( item.wsid ) ) then
continue
end
if ( filter && filter == "disabledonly" && steamworks.ShouldMountAddon( item.wsid ) ) then
continue
end
searchedItems[ #searchedItems + 1 ] = item
end
-- Build the page!
local data = {
totalresults = #searchedItems,
extraresults = {}, -- The local info about the addon
otherresults = {}, -- The complete list of IDs that match the search query for the Addons menu UI
results = {}
}
-- Add the list of all items for "select all" in the UI
local i = 0
for id, item in ipairs( searchedItems ) do
data.otherresults[ i ] = item.wsid
i = i + 1
end
-- Add the actual results for the requested range
local p = 0
while ( p < perpage ) do
if ( searchedItems[ offset + p + 1 ] ) then
local res = table.insert( data.results, searchedItems[ offset + p + 1 ].wsid )
data.extraresults[ res ] = searchedItems[ offset + p + 1 ]
end
p = p + 1
end
self:FillFileInfo( data, isUGC )
end
function ret:RetrieveUserName( steamid, func )
steamworks.RequestPlayerInfo( steamid, function( name )
self.HTML:Call( namespace .. ".ReceiveUserName( \"" .. steamid:JavascriptSafe() .. "\", \"" .. name:JavascriptSafe() .. "\" )" )
if ( func ) then func( name ) end
end )
end
function ret:FillFileInfo( results, isUGC )
--
-- File info failed..
--
if ( !results ) then return end
--
-- Send the file index..
--
local json = util.TableToJSON( results, false )
self.HTML:Call( namespace .. ".ReceiveIndex( " .. json .. " )" )
--
-- Request info on each file..
--
for k, v in pairs( results.results ) do
v = v:JavascriptSafe()
--
-- Got it cached?
--
if ( PreviewCache[ v ] ) then
self.HTML:Call( namespace .. ".ReceiveImage( \"" .. v .. "\", \"" .. PreviewCache[ v ] .. "\" )" )
end
--
-- Get the file information
--
if ( tonumber( v ) <= 0 ) then
-- Local addon
local extra = results.extraresults[ k ]
if ( !extra ) then extra = {} end
extra.ownername = "Local"
extra.description = "Non workshop .gma addon. (" .. extra.file .. ")"
extra.floating = true
local jsonExtra = util.TableToJSON( extra, false )
self.HTML:Call( namespace .. ".ReceiveFileInfo( \"" .. v .. "\", " .. jsonExtra .. " )" )
self.HTML:Call( namespace .. ".ReceiveImage( \"" .. v .. "\", \"html/img/localaddon.png\" )" )
-- Do not try to get votes for this one
continue
elseif ( InfoCache[ v ] ) then
self.HTML:Call( namespace .. ".ReceiveFileInfo( \"" .. v .. "\", " .. InfoCache[ v ] .. " )" )
if ( MENU_DLL ) then
-- This could've changed..
steamworks.FileUserInfo( v, function( info )
if ( info.error ) then return end
local localUI = util.TableToJSON( info, false )
self.HTML:Call( namespace .. ".ReceiveFileUserInfo( \"" .. v .. "\", " .. localUI .. " )" )
end )
end
else
steamworks.FileInfo( v, function( result )
if ( !result || result.error != nil ) then
-- Try to get the title from the GetAddons(), this probably could be done more efficiently
local title = "Offline addon"
for id, t in pairs( isUGC && engine.GetUserContent() || engine.GetAddons() ) do
if ( tonumber( v ) == tonumber( t.wsid ) ) then title = t.title break end
end
local jsonErr = util.TableToJSON( { title = title, description = "Failed to get addon info, error code " .. ( result && result.error || "unknown" ) }, false )
self.HTML:Call( namespace .. ".ReceiveFileInfo( \"" .. v .. "\", " .. jsonErr .. " )" )
return
end
if ( result.description ) then
result.description = string.gsub( result.description, "%[img%]([^%]]*)%[/img%]", "" ) -- Gotta remove inner content of img tags
result.description = string.gsub( result.description, "%[([^%]]*)%]", "" )
result.description = string.Trim( result.description )
end
if ( result.owner && ( !result.ownername || result.ownername == "" || result.ownername == "[unknown]" ) ) then
self:RetrieveUserName( result.owner, function( name )
result.ownername = name
local jsonUN = util.TableToJSON( result, false )
InfoCache[ v ] = jsonUN
end )
end
local jsonFI = util.TableToJSON( result, false )
InfoCache[ v ] = jsonFI
self.HTML:Call( namespace .. ".ReceiveFileInfo( \"" .. v .. "\", " .. jsonFI .. " )" )
--
-- Now we have the preview id - get the preview image!
--
if ( !PreviewCache[ v ] && result.previewid ) then
steamworks.Download( result.previewid, false, function( name )
-- Download failed
if ( !name ) then return end
PreviewCache[ v ] = name:JavascriptSafe()
self.HTML:Call( namespace .. ".ReceiveImage( \"" .. v .. "\", \"" .. PreviewCache[ v ] .. "\" )" )
end )
end
if ( MENU_DLL ) then
steamworks.FileUserInfo( v, function( info )
if ( info.error ) then return end
local localUI = util.TableToJSON( info, false )
self.HTML:Call( namespace .. ".ReceiveFileUserInfo( \"" .. v .. "\", " .. localUI .. " )" )
end )
end
end )
end
end
end
function ret:Publish( filename, image )
--MsgN( "PUBLISHING ", filename )
--MsgN( "Image ", image )
local window = vgui.Create( "UGCPublishWindow" )
window:Setup( namespace, filename, image, self )
window:MakePopup()
window:DoModal() -- We want the user to either finish this or quit
end
return ret
end