mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 13:53:45 +03:00
Upload
This commit is contained in:
335
lua/includes/util/client.lua
Normal file
335
lua/includes/util/client.lua
Normal 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
141
lua/includes/util/color.lua
Normal 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
|
||||
50
lua/includes/util/javascript_util.lua
Normal file
50
lua/includes/util/javascript_util.lua
Normal 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
|
||||
103
lua/includes/util/model_database.lua
Normal file
103
lua/includes/util/model_database.lua
Normal 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
119
lua/includes/util/sql.lua
Normal 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
|
||||
90
lua/includes/util/tooltips.lua
Normal file
90
lua/includes/util/tooltips.lua
Normal 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
|
||||
51
lua/includes/util/vgui_showlayout.lua
Normal file
51
lua/includes/util/vgui_showlayout.lua
Normal 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
|
||||
308
lua/includes/util/workshop_files.lua
Normal file
308
lua/includes/util/workshop_files.lua
Normal 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
|
||||
Reference in New Issue
Block a user