add sborka
This commit is contained in:
240
garrysmod/addons/lvs_base/lua/autorun/client/lvs_vehicle_tab.lua
Normal file
240
garrysmod/addons/lvs_base/lua/autorun/client/lvs_vehicle_tab.lua
Normal file
@@ -0,0 +1,240 @@
|
||||
|
||||
hook.Add( "PopulateVehicles", "!!!add_lvs_to_vehicles", function( pnlContent, tree, node )
|
||||
local CategoryNameTranslate = {}
|
||||
local Categorised = {}
|
||||
local SubCategorised = {}
|
||||
|
||||
local SpawnableEntities = table.Copy( list.Get( "SpawnableEntities" ) )
|
||||
local Variants = {
|
||||
[1] = "[LVS] - ",
|
||||
[2] = "[LVS] -",
|
||||
[3] = "[LVS]- ",
|
||||
[4] = "[LVS]-",
|
||||
[5] = "[LVS] ",
|
||||
}
|
||||
|
||||
for _, v in pairs( scripted_ents.GetList() ) do
|
||||
if not v.t or not v.t.ClassName or not v.t.VehicleCategory then continue end
|
||||
|
||||
if not isstring( v.t.ClassName ) or v.t.ClassName == "" or not SpawnableEntities[ v.t.ClassName ] then continue end
|
||||
|
||||
SpawnableEntities[ v.t.ClassName ].Category = "[LVS] - "..v.t.VehicleCategory
|
||||
|
||||
if not v.t.VehicleSubCategory then continue end
|
||||
|
||||
SpawnableEntities[ v.t.ClassName ].SubCategory = v.t.VehicleSubCategory
|
||||
end
|
||||
|
||||
if SpawnableEntities then
|
||||
for k, v in pairs( SpawnableEntities ) do
|
||||
|
||||
local Category = v.Category
|
||||
|
||||
if not isstring( Category ) then continue end
|
||||
|
||||
if not Category:StartWith( "[LVS]" ) and not v.LVS then continue end
|
||||
|
||||
v.SpawnName = k
|
||||
|
||||
for _, start in pairs( Variants ) do
|
||||
if Category:StartWith( start ) then
|
||||
local NewName = string.Replace(Category, start, "")
|
||||
CategoryNameTranslate[ NewName ] = Category
|
||||
Category = NewName
|
||||
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if v.SubCategory then
|
||||
SubCategorised[ Category ] = SubCategorised[ Category ] or {}
|
||||
SubCategorised[ Category ][ v.SubCategory ] = SubCategorised[ Category ][ v.SubCategory ] or {}
|
||||
|
||||
table.insert( SubCategorised[ Category ][ v.SubCategory ], v )
|
||||
end
|
||||
|
||||
Categorised[ Category ] = Categorised[ Category ] or {}
|
||||
|
||||
table.insert( Categorised[ Category ], v )
|
||||
end
|
||||
end
|
||||
|
||||
local lvsNode = tree:AddNode( "[LVS]", "icon16/lvs.png" )
|
||||
|
||||
if Categorised["[LVS]"] then
|
||||
local v = Categorised["[LVS]"]
|
||||
|
||||
lvsNode.DoPopulate = function( self )
|
||||
if self.PropPanel then return end
|
||||
|
||||
self.PropPanel = vgui.Create( "ContentContainer", pnlContent )
|
||||
self.PropPanel:SetVisible( false )
|
||||
self.PropPanel:SetTriggerSpawnlistChange( false )
|
||||
|
||||
for k, ent in SortedPairsByMemberValue( v, "PrintName" ) do
|
||||
spawnmenu.CreateContentIcon( ent.ScriptedEntityType or "entity", self.PropPanel, {
|
||||
nicename = ent.PrintName or ent.ClassName,
|
||||
spawnname = ent.SpawnName,
|
||||
material = ent.IconOverride or "entities/" .. ent.SpawnName .. ".png",
|
||||
admin = ent.AdminOnly
|
||||
} )
|
||||
end
|
||||
end
|
||||
|
||||
lvsNode.DoClick = function( self )
|
||||
self:DoPopulate()
|
||||
pnlContent:SwitchPanel( self.PropPanel )
|
||||
end
|
||||
end
|
||||
|
||||
local IconList = list.Get( "ContentCategoryIcons" )
|
||||
|
||||
for CategoryName, v in SortedPairs( Categorised ) do
|
||||
if CategoryName:StartWith( "[LVS]" ) then continue end
|
||||
|
||||
local Icon = "icon16/lvs_noicon.png"
|
||||
|
||||
if IconList and IconList[ CategoryNameTranslate[ CategoryName ] ] then
|
||||
Icon = IconList[ CategoryNameTranslate[ CategoryName ] ]
|
||||
end
|
||||
|
||||
local node = lvsNode:AddNode( CategoryName, Icon )
|
||||
|
||||
node.DoPopulate = function( self )
|
||||
if self.PropPanel then return end
|
||||
|
||||
self.PropPanel = vgui.Create( "ContentContainer", pnlContent )
|
||||
self.PropPanel:SetVisible( false )
|
||||
self.PropPanel:SetTriggerSpawnlistChange( false )
|
||||
|
||||
for k, ent in SortedPairsByMemberValue( v, "PrintName" ) do
|
||||
if ent.SubCategory then
|
||||
continue
|
||||
end
|
||||
|
||||
spawnmenu.CreateContentIcon( ent.ScriptedEntityType or "entity", self.PropPanel, {
|
||||
nicename = ent.PrintName or ent.ClassName,
|
||||
spawnname = ent.SpawnName,
|
||||
material = ent.IconOverride or "entities/" .. ent.SpawnName .. ".png",
|
||||
admin = ent.AdminOnly
|
||||
} )
|
||||
end
|
||||
end
|
||||
node.DoClick = function( self )
|
||||
self:DoPopulate()
|
||||
pnlContent:SwitchPanel( self.PropPanel )
|
||||
end
|
||||
|
||||
local SubCat = SubCategorised[ CategoryName ]
|
||||
|
||||
if not SubCat then continue end
|
||||
|
||||
for SubName, data in SortedPairs( SubCat ) do
|
||||
|
||||
local SubIcon = "icon16/lvs_noicon.png"
|
||||
|
||||
if IconList then
|
||||
if IconList[ "[LVS] - "..CategoryName.." - "..SubName ] then
|
||||
SubIcon = IconList[ "[LVS] - "..CategoryName.." - "..SubName ]
|
||||
else
|
||||
if IconList[ "[LVS] - "..SubName ] then
|
||||
SubIcon = IconList[ "[LVS] - "..SubName ]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local subnode = node:AddNode( SubName, SubIcon )
|
||||
|
||||
subnode.DoPopulate = function( self )
|
||||
if self.PropPanel then return end
|
||||
|
||||
self.PropPanel = vgui.Create( "ContentContainer", pnlContent )
|
||||
self.PropPanel:SetVisible( false )
|
||||
self.PropPanel:SetTriggerSpawnlistChange( false )
|
||||
|
||||
for k, ent in SortedPairsByMemberValue( data, "PrintName" ) do
|
||||
spawnmenu.CreateContentIcon( ent.ScriptedEntityType or "entity", self.PropPanel, {
|
||||
nicename = ent.PrintName or ent.ClassName,
|
||||
spawnname = ent.SpawnName,
|
||||
material = ent.IconOverride or "entities/" .. ent.SpawnName .. ".png",
|
||||
admin = ent.AdminOnly
|
||||
} )
|
||||
end
|
||||
end
|
||||
subnode.DoClick = function( self )
|
||||
self:DoPopulate()
|
||||
pnlContent:SwitchPanel( self.PropPanel )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- User Stuff
|
||||
hook.Run( "LVS.PopulateVehicles", lvsNode, pnlContent, tree )
|
||||
|
||||
-- CONTROLS
|
||||
local node = lvsNode:AddNode( "Controls", "icon16/keyboard.png" )
|
||||
node.DoClick = function( self )
|
||||
LVS:OpenMenu()
|
||||
LVS:OpenClientControls()
|
||||
end
|
||||
|
||||
-- CLIENT SETTINGS
|
||||
local node = lvsNode:AddNode( "Client Settings", "icon16/wrench.png" )
|
||||
node.DoClick = function( self )
|
||||
LVS:OpenMenu()
|
||||
LVS:OpenClientSettings()
|
||||
end
|
||||
|
||||
-- SERVER SETTINGS
|
||||
local node = lvsNode:AddNode( "Server Settings", "icon16/wrench_orange.png" )
|
||||
node.DoClick = function( self )
|
||||
if LocalPlayer():IsSuperAdmin() then
|
||||
LVS:OpenMenu()
|
||||
LVS:OpenServerMenu()
|
||||
else
|
||||
surface.PlaySound( "buttons/button11.wav" )
|
||||
end
|
||||
end
|
||||
end )
|
||||
|
||||
list.Set( "ContentCategoryIcons", "[LVS]", "icon16/lvs.png" )
|
||||
|
||||
list.Set( "ContentCategoryIcons", "[LVS] - Artillery", "icon16/lvs_artillery.png" )
|
||||
|
||||
list.Set( "ContentCategoryIcons", "[LVS] - Boats", "icon16/lvs_boats.png" )
|
||||
list.Set( "ContentCategoryIcons", "[LVS] - Boats - Civilian", "icon16/lvs_civilian.png" )
|
||||
|
||||
list.Set( "ContentCategoryIcons", "[LVS] - Racers", "icon16/lvs_racers.png" )
|
||||
|
||||
list.Set( "ContentCategoryIcons", "[LVS] - Cars", "icon16/lvs_cars.png" )
|
||||
list.Set( "ContentCategoryIcons", "[LVS] - Cars - Armored", "icon16/lvs_armor.png" )
|
||||
list.Set( "ContentCategoryIcons", "[LVS] - Cars - Civilian", "icon16/lvs_civilian.png" )
|
||||
list.Set( "ContentCategoryIcons", "[LVS] - Cars - Military", "icon16/lvs_military.png" )
|
||||
list.Set( "ContentCategoryIcons", "[LVS] - Cars - Pack", "icon16/lvs_cars_pack.png" )
|
||||
|
||||
list.Set( "ContentCategoryIcons", "[LVS] - Trucks - Pack", "icon16/lvs_trucks.png" )
|
||||
|
||||
list.Set( "ContentCategoryIcons", "[LVS] - Rig", "icon16/lvs_trucks.png" )
|
||||
list.Set( "ContentCategoryIcons", "[LVS] - Rig - Trucks", "icon16/lvs_trucks.png" )
|
||||
list.Set( "ContentCategoryIcons", "[LVS] - Rig - Trailers", "icon16/lvs_trucktrailers.png" )
|
||||
|
||||
list.Set( "ContentCategoryIcons", "[LVS] - Helicopters", "icon16/lvs_helicopters.png" )
|
||||
list.Set( "ContentCategoryIcons", "[LVS] - Helicopters - Combine", "icon16/lvs_combine.png" )
|
||||
list.Set( "ContentCategoryIcons", "[LVS] - Helicopters - Resistance", "icon16/lvs_resistance.png" )
|
||||
|
||||
list.Set( "ContentCategoryIcons", "[LVS] - Planes", "icon16/lvs_planes.png" )
|
||||
list.Set( "ContentCategoryIcons", "[LVS] - Planes - Bombers", "icon16/lvs_bomb.png" )
|
||||
list.Set( "ContentCategoryIcons", "[LVS] - Planes - Fighters", "icon16/lvs_fighter.png" )
|
||||
list.Set( "ContentCategoryIcons", "[LVS] - Planes - Civilian", "icon16/lvs_civilian.png" )
|
||||
|
||||
list.Set( "ContentCategoryIcons", "[LVS] - Tanks", "icon16/lvs_tanks.png" )
|
||||
list.Set( "ContentCategoryIcons", "[LVS] - Tanks - Light", "icon16/lvs_light.png" )
|
||||
list.Set( "ContentCategoryIcons", "[LVS] - Tanks - Medium", "icon16/lvs_medium.png" )
|
||||
list.Set( "ContentCategoryIcons", "[LVS] - Tanks - Heavy", "icon16/lvs_heavy.png" )
|
||||
list.Set( "ContentCategoryIcons", "[LVS] - Tanks - RP", "icon16/lvs_rp.png" )
|
||||
|
||||
list.Set( "ContentCategoryIcons", "[LVS] - Star Wars", "icon16/lvs_starwars.png" )
|
||||
list.Set( "ContentCategoryIcons", "[LVS] - Star Wars - Gunships", "icon16/lvs_sw_gunship.png" )
|
||||
list.Set( "ContentCategoryIcons", "[LVS] - Star Wars - Hover Tanks", "icon16/lvs_sw_hover.png" )
|
||||
list.Set( "ContentCategoryIcons", "[LVS] - Star Wars - Walkers", "icon16/lvs_sw_walker.png" )
|
||||
list.Set( "ContentCategoryIcons", "[LVS] - Star Wars - Starfighters", "icon16/lvs_sw_starfighter.png" )
|
||||
@@ -0,0 +1,3 @@
|
||||
if SERVER then
|
||||
resource.AddWorkshop("2922255744") -- LVS Base
|
||||
end
|
||||
476
garrysmod/addons/lvs_base/lua/autorun/lvs_init.lua
Normal file
476
garrysmod/addons/lvs_base/lua/autorun/lvs_init.lua
Normal file
@@ -0,0 +1,476 @@
|
||||
|
||||
LVS = istable( LVS ) and LVS or {}
|
||||
|
||||
LVS.VERSION = 348
|
||||
LVS.VERSION_GITHUB = 0
|
||||
LVS.VERSION_TYPE = ".WS"
|
||||
LVS.VERSION_ADDONS_OUTDATED = false
|
||||
|
||||
LVS.KEYS_CATEGORIES = {}
|
||||
LVS.KEYS_REGISTERED = {}
|
||||
LVS.pSwitchKeys = {[KEY_1] = 1,[KEY_2] = 2,[KEY_3] = 3,[KEY_4] = 4,[KEY_5] = 5,[KEY_6] = 6,[KEY_7] = 7,[KEY_8] = 8,[KEY_9] = 9,[KEY_0] = 10}
|
||||
LVS.pSwitchKeysInv = {[1] = KEY_1,[2] = KEY_2,[3] = KEY_3,[4] = KEY_4,[5] = KEY_5,[6] = KEY_6,[7] = KEY_7,[8] = KEY_8,[9] = KEY_9,[10] = KEY_0}
|
||||
|
||||
LVS.ThemeColor = Color(127,0,0,255)
|
||||
|
||||
LVS.WHEEL_BRAKE = 1
|
||||
LVS.WHEEL_STEER_NONE = 2
|
||||
LVS.WHEEL_STEER_FRONT = 3
|
||||
LVS.WHEEL_STEER_REAR = 4
|
||||
LVS.WHEEL_STEER_ACKERMANN = 5
|
||||
|
||||
LVS.WHEELTYPE_NONE = 0
|
||||
LVS.WHEELTYPE_LEFT = 1
|
||||
LVS.WHEELTYPE_RIGHT = -1
|
||||
|
||||
LVS.HITCHTYPE_NONE = -1
|
||||
LVS.HITCHTYPE_MALE = 0
|
||||
LVS.HITCHTYPE_FEMALE = 1
|
||||
|
||||
LVS.SOUNDTYPE_NONE = 0
|
||||
LVS.SOUNDTYPE_IDLE_ONLY = 1
|
||||
LVS.SOUNDTYPE_REV_UP = 2
|
||||
LVS.SOUNDTYPE_REV_DOWN = 3
|
||||
LVS.SOUNDTYPE_REV_DN = 3
|
||||
LVS.SOUNDTYPE_ALL = 4
|
||||
|
||||
LVS.FUELTYPE_PETROL = 0
|
||||
LVS.FUELTYPE_DIESEL = 1
|
||||
LVS.FUELTYPE_ELECTRIC = 2
|
||||
LVS.FUELTYPES = {
|
||||
[LVS.FUELTYPE_PETROL] = {
|
||||
name = "Petrol",
|
||||
color = Vector(240,200,0),
|
||||
},
|
||||
[LVS.FUELTYPE_DIESEL] = {
|
||||
name = "Diesel",
|
||||
color = Vector(255,60,0),
|
||||
},
|
||||
[LVS.FUELTYPE_ELECTRIC] = {
|
||||
name = "Electric",
|
||||
color = Vector(0,127,255),
|
||||
},
|
||||
}
|
||||
|
||||
LVS.SPEEDUNITS = {
|
||||
["u/s"] = {
|
||||
name = "u/s",
|
||||
value = 1,
|
||||
},
|
||||
["mph"] = {
|
||||
name = "mph",
|
||||
value = 0.0568182,
|
||||
},
|
||||
["km/h"] = {
|
||||
name = "km/h",
|
||||
value = 0.09144,
|
||||
},
|
||||
}
|
||||
|
||||
LVS.WEAPONS = {
|
||||
["DEFAULT"] = {
|
||||
Icon = Material("lvs/weapons/bullet.png"),
|
||||
Ammo = 9999,
|
||||
Delay = 0,
|
||||
HeatRateUp = 0.2,
|
||||
HeatRateDown = 0.25,
|
||||
Attack = function( ent ) end,
|
||||
StartAttack = function( ent ) end,
|
||||
FinishAttack = function( ent ) end,
|
||||
OnSelect = function( ent, old ) end,
|
||||
OnDeselect = function( ent, new ) end,
|
||||
OnThink = function( ent, active ) end,
|
||||
OnOverheat = function( ent ) end,
|
||||
OnRemove = function( ent ) end,
|
||||
OnReload = function( ent ) end,
|
||||
},
|
||||
["LMG"] = {
|
||||
Icon = Material("lvs/weapons/mg.png"),
|
||||
Ammo = 1000,
|
||||
Delay = 0.1,
|
||||
Attack = function( ent )
|
||||
ent.MirrorPrimary = not ent.MirrorPrimary
|
||||
|
||||
local Mirror = ent.MirrorPrimary and -1 or 1
|
||||
|
||||
local Pos = ent:LocalToWorld( ent.PosLMG and Vector(ent.PosLMG.x,ent.PosLMG.y * Mirror,ent.PosLMG.z) or Vector(0,0,0) )
|
||||
local Dir = ent.DirLMG or 0
|
||||
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin( Pos )
|
||||
effectdata:SetNormal( ent:GetForward() )
|
||||
effectdata:SetEntity( ent )
|
||||
util.Effect( "lvs_muzzle", effectdata )
|
||||
|
||||
local bullet = {}
|
||||
bullet.Src = Pos
|
||||
bullet.Dir = ent:LocalToWorldAngles( Angle(0,-Dir * Mirror,0) ):Forward()
|
||||
bullet.Spread = Vector( 0.015, 0.015, 0.015 )
|
||||
bullet.TracerName = "lvs_tracer_white"
|
||||
bullet.Force = 1000
|
||||
bullet.HullSize = 50
|
||||
bullet.Damage = 35
|
||||
bullet.Velocity = 30000
|
||||
bullet.Attacker = ent:GetDriver()
|
||||
bullet.Callback = function(att, tr, dmginfo) end
|
||||
ent:LVSFireBullet( bullet )
|
||||
|
||||
ent:TakeAmmo()
|
||||
end,
|
||||
StartAttack = function( ent )
|
||||
if not IsValid( ent.SoundEmitter1 ) then
|
||||
ent.SoundEmitter1 = ent:AddSoundEmitter( Vector(109.29,0,92.85), "lvs/weapons/mg_loop.wav", "lvs/weapons/mg_loop_interior.wav" )
|
||||
ent.SoundEmitter1:SetSoundLevel( 95 )
|
||||
end
|
||||
|
||||
ent.SoundEmitter1:Play()
|
||||
end,
|
||||
FinishAttack = function( ent )
|
||||
if IsValid( ent.SoundEmitter1 ) then
|
||||
ent.SoundEmitter1:Stop()
|
||||
ent.SoundEmitter1:EmitSound("lvs/weapons/mg_lastshot.wav")
|
||||
end
|
||||
end,
|
||||
OnSelect = function( ent ) ent:EmitSound("physics/metal/weapon_impact_soft3.wav") end,
|
||||
OnOverheat = function( ent ) ent:EmitSound("lvs/overheat.wav") end,
|
||||
},
|
||||
["TABLE_POINT_MG"] = {
|
||||
Icon = Material("lvs/weapons/mc.png"),
|
||||
Ammo = 2000,
|
||||
Delay = 0.1,
|
||||
Attack = function( ent )
|
||||
if not ent.PosTPMG or not ent.DirTPMG then return end
|
||||
|
||||
for i = 1, 2 do
|
||||
ent._NumTPMG = ent._NumTPMG and ent._NumTPMG + 1 or 1
|
||||
|
||||
if ent._NumTPMG > #ent.PosTPMG then ent._NumTPMG = 1 end
|
||||
|
||||
local Pos = ent:LocalToWorld( ent.PosTPMG[ ent._NumTPMG ] )
|
||||
local Dir = ent.DirTPMG[ ent._NumTPMG ]
|
||||
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin( Pos )
|
||||
effectdata:SetNormal( ent:GetForward() )
|
||||
effectdata:SetEntity( ent )
|
||||
util.Effect( "lvs_muzzle", effectdata )
|
||||
|
||||
local bullet = {}
|
||||
bullet.Src = Pos
|
||||
bullet.Dir = ent:LocalToWorldAngles( Angle(0,-Dir,0) ):Forward()
|
||||
bullet.Spread = Vector( 0.035, 0.035, 0.035 )
|
||||
bullet.TracerName = "lvs_tracer_yellow"
|
||||
bullet.Force = 1000
|
||||
bullet.HullSize = 25
|
||||
bullet.Damage = 35
|
||||
bullet.Velocity = 40000
|
||||
bullet.Attacker = ent:GetDriver()
|
||||
bullet.Callback = function(att, tr, dmginfo) end
|
||||
ent:LVSFireBullet( bullet )
|
||||
end
|
||||
|
||||
ent:TakeAmmo( 2 )
|
||||
end,
|
||||
StartAttack = function( ent )
|
||||
if not IsValid( ent.SoundEmitter1 ) then
|
||||
ent.SoundEmitter1 = ent:AddSoundEmitter( Vector(109.29,0,92.85), "lvs/weapons/mg_light_loop.wav", "lvs/weapons/mg_light_loop_interior.wav" )
|
||||
ent.SoundEmitter1:SetSoundLevel( 95 )
|
||||
end
|
||||
|
||||
ent.SoundEmitter1:Play()
|
||||
end,
|
||||
FinishAttack = function( ent )
|
||||
if IsValid( ent.SoundEmitter1 ) then
|
||||
ent.SoundEmitter1:Stop()
|
||||
ent.SoundEmitter1:EmitSound("lvs/weapons/mg_light_lastshot.wav")
|
||||
end
|
||||
end,
|
||||
OnSelect = function( ent ) ent:EmitSound("physics/metal/weapon_impact_soft3.wav") end,
|
||||
OnOverheat = function( ent ) ent:EmitSound("lvs/overheat.wav") end,
|
||||
},
|
||||
["HMG"] = {
|
||||
Icon = Material("lvs/weapons/hmg.png"),
|
||||
Ammo = 300,
|
||||
Delay = 0.14,
|
||||
Attack = function( ent )
|
||||
ent.MirrorSecondary = not ent.MirrorSecondary
|
||||
|
||||
local Mirror = ent.MirrorSecondary and -1 or 1
|
||||
|
||||
local Pos = ent:LocalToWorld( ent.PosHMG and Vector(ent.PosHMG.x,ent.PosHMG.y * Mirror,ent.PosHMG.z) or Vector(0,0,0) )
|
||||
local Dir = ent.DirHMG or 0.5
|
||||
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin( Pos )
|
||||
effectdata:SetNormal( ent:GetForward() )
|
||||
effectdata:SetEntity( ent )
|
||||
util.Effect( "lvs_muzzle", effectdata )
|
||||
|
||||
local bullet = {}
|
||||
bullet.Src = Pos
|
||||
bullet.Dir = ent:LocalToWorldAngles( Angle(0,-Dir * Mirror,0) ):Forward()
|
||||
bullet.Spread = Vector( 0.02, 0.02, 0.02 )
|
||||
bullet.TracerName = "lvs_tracer_orange"
|
||||
bullet.Force = 4000
|
||||
bullet.HullSize = 15
|
||||
bullet.Damage = 45
|
||||
bullet.SplashDamage = 75
|
||||
bullet.SplashDamageRadius = 200
|
||||
bullet.Velocity = 15000
|
||||
bullet.Attacker = ent:GetDriver()
|
||||
bullet.Callback = function(att, tr, dmginfo)
|
||||
end
|
||||
ent:LVSFireBullet( bullet )
|
||||
|
||||
ent:TakeAmmo()
|
||||
end,
|
||||
StartAttack = function( ent )
|
||||
if not IsValid( ent.SoundEmitter2 ) then
|
||||
ent.SoundEmitter2 = ent:AddSoundEmitter( Vector(109.29,0,92.85), "lvs/weapons/mc_loop.wav", "lvs/weapons/mc_loop_interior.wav" )
|
||||
ent.SoundEmitter2:SetSoundLevel( 95 )
|
||||
end
|
||||
|
||||
ent.SoundEmitter2:Play()
|
||||
end,
|
||||
FinishAttack = function( ent )
|
||||
if IsValid( ent.SoundEmitter2 ) then
|
||||
ent.SoundEmitter2:Stop()
|
||||
ent.SoundEmitter2:EmitSound("lvs/weapons/mc_lastshot.wav")
|
||||
end
|
||||
end,
|
||||
OnSelect = function( ent ) ent:EmitSound("physics/metal/weapon_impact_soft2.wav") end,
|
||||
OnOverheat = function( ent ) ent:EmitSound("lvs/overheat.wav") end,
|
||||
},
|
||||
["TURBO"] = {
|
||||
Icon = Material("lvs/weapons/nos.png"),
|
||||
HeatRateUp = 0.1,
|
||||
HeatRateDown = 0.1,
|
||||
UseableByAI = false,
|
||||
Attack = function( ent )
|
||||
local PhysObj = ent:GetPhysicsObject()
|
||||
if not IsValid( PhysObj ) then return end
|
||||
local THR = ent:GetThrottle()
|
||||
local FT = FrameTime()
|
||||
|
||||
local Vel = ent:GetVelocity():Length()
|
||||
|
||||
PhysObj:ApplyForceCenter( ent:GetForward() * math.Clamp(ent.MaxVelocity + 500 - Vel,0,1) * PhysObj:GetMass() * THR * FT * 150 ) -- increase speed
|
||||
PhysObj:AddAngleVelocity( PhysObj:GetAngleVelocity() * FT * 0.5 * THR ) -- increase turn rate
|
||||
end,
|
||||
StartAttack = function( ent )
|
||||
ent.TargetThrottle = 1.3
|
||||
ent:EmitSound("lvs/vehicles/generic/boost.wav")
|
||||
end,
|
||||
FinishAttack = function( ent )
|
||||
ent.TargetThrottle = 1
|
||||
end,
|
||||
OnSelect = function( ent )
|
||||
ent:EmitSound("buttons/lever5.wav")
|
||||
end,
|
||||
OnThink = function( ent, active )
|
||||
if not ent.TargetThrottle then return end
|
||||
|
||||
local Rate = FrameTime() * 0.5
|
||||
|
||||
ent:SetMaxThrottle( ent:GetMaxThrottle() + math.Clamp(ent.TargetThrottle - ent:GetMaxThrottle(),-Rate,Rate) )
|
||||
|
||||
local MaxThrottle = ent:GetMaxThrottle()
|
||||
|
||||
ent:SetThrottle( MaxThrottle )
|
||||
|
||||
if MaxThrottle == ent.TargetThrottle then
|
||||
ent.TargetThrottle = nil
|
||||
end
|
||||
end,
|
||||
OnOverheat = function( ent ) ent:EmitSound("lvs/overheat_boost.wav") end,
|
||||
},
|
||||
}
|
||||
|
||||
function LVS:GetVersion()
|
||||
return LVS.VERSION
|
||||
end
|
||||
|
||||
function LVS:AddKey(name, category, printname, cmd, default)
|
||||
local data = {
|
||||
printname = printname,
|
||||
id = name,
|
||||
category = category,
|
||||
cmd = cmd,
|
||||
}
|
||||
|
||||
if not LVS.KEYS_CATEGORIES[ category ] then
|
||||
LVS.KEYS_CATEGORIES[ category ] = {}
|
||||
end
|
||||
|
||||
if SERVER then
|
||||
table.insert( LVS.KEYS_REGISTERED, data )
|
||||
else
|
||||
if default then
|
||||
if isstring( default ) then
|
||||
local Key = input.LookupBinding( default )
|
||||
|
||||
if Key then
|
||||
default = input.GetKeyCode( Key )
|
||||
else
|
||||
default = 0
|
||||
end
|
||||
end
|
||||
else
|
||||
default = 0
|
||||
end
|
||||
|
||||
data.default = default
|
||||
|
||||
table.insert( LVS.KEYS_REGISTERED, data )
|
||||
|
||||
CreateClientConVar( cmd, default, true, true )
|
||||
end
|
||||
end
|
||||
|
||||
function LVS:CheckUpdates()
|
||||
http.Fetch("https://raw.githubusercontent.com/SpaxscE/lvs_base/main/lua/autorun/lvs_init.lua", function(contents,size)
|
||||
local Entry = string.match( contents, "LVS.VERSION%s=%s%d+" )
|
||||
|
||||
if Entry then
|
||||
LVS.VERSION_GITHUB = tonumber( string.match( Entry , "%d+" ) ) or 0
|
||||
else
|
||||
LVS.VERSION_GITHUB = 0
|
||||
end
|
||||
|
||||
if LVS.VERSION_GITHUB == 0 then
|
||||
print("[LVS] - Framework: latest version could not be detected, You have Version: "..LVS:GetVersion())
|
||||
else
|
||||
if LVS:GetVersion() >= LVS.VERSION_GITHUB then
|
||||
print("[LVS] - Framework is up to date, Version: "..LVS:GetVersion())
|
||||
else
|
||||
print("[LVS] - Framework: a newer version is available! Version: "..LVS.VERSION_GITHUB..", You have Version: "..LVS:GetVersion())
|
||||
|
||||
if LVS.VERSION_TYPE == ".GIT" then
|
||||
print("[LVS] - Framework: get the latest version at https://github.com/SpaxscE/lvs_base")
|
||||
else
|
||||
print("[LVS] - Framework: restart your game/server to get the latest version!")
|
||||
end
|
||||
|
||||
if CLIENT then
|
||||
timer.Simple(18, function()
|
||||
chat.AddText( Color( 255, 0, 0 ), "[LVS] - Framework: a newer version is available!" )
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local Delay = 0
|
||||
local addons = file.Find( "data_static/lvs/*", "GAME" )
|
||||
|
||||
for _, addonFile in pairs( addons ) do
|
||||
local addonInfo = file.Read( "data_static/lvs/"..addonFile, "GAME" )
|
||||
|
||||
if not addonInfo then continue end
|
||||
|
||||
local data = string.Explode( "\n", addonInfo )
|
||||
|
||||
local wsid = string.Replace( addonFile, ".txt", "" )
|
||||
local addon_name = wsid
|
||||
local addon_url
|
||||
local addon_version
|
||||
|
||||
for _, entry in pairs( data ) do
|
||||
if string.StartsWith( entry, "url=" ) then
|
||||
addon_url = string.Replace( entry, "url=", "" )
|
||||
end
|
||||
|
||||
if string.StartsWith( entry, "version=" ) then
|
||||
addon_version = string.Replace( entry, "version=", "" )
|
||||
end
|
||||
|
||||
if string.StartsWith( entry, "name=" ) then
|
||||
addon_name = string.Replace( entry, "name=", "" )
|
||||
end
|
||||
end
|
||||
|
||||
if not addon_url or not addon_version then continue end
|
||||
|
||||
addon_version = tonumber( addon_version )
|
||||
|
||||
Delay = Delay + 1.5
|
||||
|
||||
timer.Simple( Delay, function()
|
||||
http.Fetch(addon_url, function(con,_)
|
||||
local addon_entry = string.match( con, "version=%d+" )
|
||||
|
||||
local addon_version_git = 0
|
||||
|
||||
if addon_entry then
|
||||
addon_version_git = tonumber( string.match( addon_entry, "%d+" ) ) or 0
|
||||
end
|
||||
|
||||
local wsurl = "https://steamcommunity.com/sharedfiles/filedetails/?id="..wsid
|
||||
|
||||
if addon_version_git == 0 then
|
||||
print("[LVS] latest version of "..addon_name.." ( "..wsurl.." ) could not be detected, You have Version: "..addon_version)
|
||||
else
|
||||
if addon_version_git > addon_version then
|
||||
print("[LVS] - "..addon_name.." ( "..wsurl.." ) is out of date!")
|
||||
|
||||
if CLIENT then
|
||||
timer.Simple(18, function()
|
||||
chat.AddText( Color( 255, 0, 0 ),"[LVS] - "..addon_name.." is out of date!" )
|
||||
end)
|
||||
end
|
||||
|
||||
LVS.VERSION_ADDONS_OUTDATED = true
|
||||
|
||||
else
|
||||
print("[LVS] - "..addon_name.." is up to date, Version: "..addon_version)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end )
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function LVS:GetWeaponPreset( name )
|
||||
if not LVS.WEAPONS[ name ] then return table.Copy( LVS.WEAPONS["DEFAULT"] ) end
|
||||
|
||||
return table.Copy( LVS.WEAPONS[ name ] )
|
||||
end
|
||||
|
||||
function LVS:AddWeaponPreset( name, data )
|
||||
if not isstring( name ) or not istable( data ) then return end
|
||||
|
||||
LVS.WEAPONS[ name ] = data
|
||||
end
|
||||
|
||||
function LVS:GetVehicleTypes()
|
||||
local VehicleTypes = {}
|
||||
|
||||
for s, v in pairs( scripted_ents.GetList() ) do
|
||||
if not v.t or not isfunction( v.t.GetVehicleType ) then continue end
|
||||
|
||||
local vehicletype = v.t:GetVehicleType()
|
||||
|
||||
if not isstring( vehicletype ) or string.StartsWith( vehicletype, "LBase" ) or table.HasValue( VehicleTypes, vehicletype ) then continue end
|
||||
|
||||
table.insert( VehicleTypes, vehicletype )
|
||||
end
|
||||
|
||||
return VehicleTypes
|
||||
end
|
||||
|
||||
if CLIENT then
|
||||
function LVS:GetUnitValue( number )
|
||||
if not LVS.SPEEDUNITS[ LVS.SpeedUnit ] then return number end
|
||||
|
||||
return (number * LVS.SPEEDUNITS[ LVS.SpeedUnit ].value)
|
||||
end
|
||||
|
||||
function LVS:GetUnitName()
|
||||
if not LVS.SPEEDUNITS[ LVS.SpeedUnit ] then return "u/s" end
|
||||
|
||||
return LVS.SPEEDUNITS[ LVS.SpeedUnit ].name
|
||||
end
|
||||
end
|
||||
|
||||
AddCSLuaFile("lvs_framework/init.lua")
|
||||
include("lvs_framework/init.lua")
|
||||
179
garrysmod/addons/lvs_base/lua/effects/lvs_ammorack_fire.lua
Normal file
179
garrysmod/addons/lvs_base/lua/effects/lvs_ammorack_fire.lua
Normal file
@@ -0,0 +1,179 @@
|
||||
|
||||
EFFECT.FireMat = Material( "effects/fire_cloud1" )
|
||||
EFFECT.HeatMat = Material( "sprites/heatwave" )
|
||||
|
||||
EFFECT.Smoke = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local Pos = data:GetOrigin()
|
||||
local Ent = data:GetEntity()
|
||||
|
||||
self.LifeTime = 0.4
|
||||
self.DieTime = CurTime() + self.LifeTime
|
||||
|
||||
if not IsValid( Ent ) then return end
|
||||
|
||||
self.Ent = Ent
|
||||
self.Pos = Ent:WorldToLocal( Pos + VectorRand() * 3 )
|
||||
self.Seed = math.Rand( 0, 10000 )
|
||||
self.Magnitude = data:GetMagnitude()
|
||||
|
||||
local emitter = Ent:GetParticleEmitter( self.Pos )
|
||||
|
||||
if not IsValid( emitter ) then return end
|
||||
|
||||
local VecCol = (render.GetLightColor( Pos ) * 0.8 + Vector(0.2,0.2,0.2)) * 255
|
||||
|
||||
for i = 0, 20 do
|
||||
local particle = emitter:Add( "sprites/rico1", Pos )
|
||||
|
||||
local vel = VectorRand() * 800
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( Vector(0,0,500) + VectorRand() * 500 )
|
||||
particle:SetDieTime( 0.25 * self.Magnitude )
|
||||
particle:SetStartAlpha( 200 )
|
||||
particle:SetEndAlpha( 0 )
|
||||
particle:SetStartSize( 3 )
|
||||
particle:SetEndSize( 0 )
|
||||
particle:SetRoll( math.Rand(-1,1) * math.pi )
|
||||
particle:SetRollDelta( math.Rand(-1,1) * 3 )
|
||||
particle:SetColor( 255, 255, 255 )
|
||||
particle:SetAirResistance( 0 )
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, 8 do
|
||||
local particle = emitter:Add( self.Smoke[ math.random(1, #self.Smoke ) ], Pos )
|
||||
|
||||
local Dir = Angle(0,math.Rand(-180,180),0):Forward()
|
||||
Dir.z = -0.5
|
||||
Dir:Normalize()
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( Dir * 250 )
|
||||
particle:SetDieTime( 0.5 + i * 0.01 )
|
||||
particle:SetAirResistance( 125 )
|
||||
particle:SetStartAlpha( 100 )
|
||||
particle:SetStartSize( 20 )
|
||||
particle:SetEndSize( 40 )
|
||||
particle:SetRoll( math.Rand(-1,1) * math.pi )
|
||||
particle:SetRollDelta( math.Rand(-1,1) * 3 )
|
||||
particle:SetColor( 0, 0, 0 )
|
||||
particle:SetGravity( Vector( 0, 0, 600 ) )
|
||||
particle:SetCollide( true )
|
||||
particle:SetBounce( 0 )
|
||||
end
|
||||
end
|
||||
|
||||
for i = 0,22 do
|
||||
local particle = emitter:Add( "particles/flamelet"..math.random(1,5), Pos )
|
||||
|
||||
local Dir = Angle(0,math.Rand(-180,180),0):Forward()
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( Dir * math.Rand(600,900) * self.Magnitude )
|
||||
particle:SetDieTime( math.Rand(0.2,0.3) * self.Magnitude )
|
||||
particle:SetAirResistance( 400 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( math.Rand(20,25) )
|
||||
particle:SetEndSize( math.Rand(5,10) )
|
||||
particle:SetRoll( math.Rand(-1,1) * 180 )
|
||||
particle:SetRollDelta( math.Rand(-1,1) * 3 )
|
||||
particle:SetColor( 255, 200, 50 )
|
||||
particle:SetGravity( Vector( 0, 0, 1000 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, 4 do
|
||||
local particle = emitter:Add( self.Smoke[ math.random(1, #self.Smoke ) ], Pos )
|
||||
|
||||
local Dir = Angle(0,math.Rand(-180,180),0):Forward()
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( Dir * 500 * self.Magnitude )
|
||||
particle:SetDieTime( 0.5 + i * 0.01 )
|
||||
particle:SetAirResistance( 125 )
|
||||
particle:SetStartAlpha( 150 * self.Magnitude )
|
||||
particle:SetStartSize( 40 * self.Magnitude )
|
||||
particle:SetEndSize( 250 * self.Magnitude )
|
||||
particle:SetRoll( math.Rand(-1,1) * math.pi )
|
||||
particle:SetRollDelta( math.Rand(-1,1) * 3 )
|
||||
particle:SetColor( math.min( VecCol.r, 255 ), math.min( VecCol.g, 255 ), math.min( VecCol.b, 255 ) )
|
||||
particle:SetGravity( Vector( 0, 0, 600 ) )
|
||||
particle:SetCollide( true )
|
||||
particle:SetBounce( 0 )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if not IsValid( self.Ent ) then return false end
|
||||
|
||||
if self.DieTime < CurTime() then return false end
|
||||
|
||||
self:SetPos( self.Ent:LocalToWorld( self.Pos ) )
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
if not IsValid( self.Ent ) or not self.Pos then return end
|
||||
|
||||
self:RenderFire()
|
||||
end
|
||||
|
||||
function EFFECT:RenderFire()
|
||||
local Scale = ((self.DieTime - CurTime()) / self.LifeTime) * (self.Magnitude or 0)
|
||||
|
||||
if Scale < 0 then return end
|
||||
|
||||
local Pos = self.Ent:LocalToWorld( self.Pos )
|
||||
|
||||
local scroll = -CurTime() * 10
|
||||
|
||||
local Up = Vector(0,0,0.92) + VectorRand() * 0.08
|
||||
|
||||
render.SetMaterial( self.FireMat )
|
||||
render.StartBeam( 3 )
|
||||
render.AddBeam( Pos, 64 * Scale, scroll, Color( 100, 100, 100, 100 ) )
|
||||
render.AddBeam( Pos + Up * 120 * Scale, 64 * Scale, scroll + 1, Color( 255, 200, 50, 150 ) )
|
||||
render.AddBeam( Pos + Up * 300 * Scale, 64 * Scale, scroll + 3, Color( 255, 191, 0, 0 ) )
|
||||
render.EndBeam()
|
||||
|
||||
scroll = scroll * 0.5
|
||||
|
||||
render.UpdateRefractTexture()
|
||||
render.SetMaterial( self.HeatMat )
|
||||
render.StartBeam( 3 )
|
||||
render.AddBeam( Pos, 64 * Scale, scroll, Color( 0, 0, 255, 200 ) )
|
||||
render.AddBeam( Pos + Up * 64 * Scale, 64 * Scale, scroll + 2, color_white )
|
||||
render.AddBeam( Pos + Up * 250 * Scale, 120 * Scale, scroll + 5, Color( 0, 0, 0, 0 ) )
|
||||
render.EndBeam()
|
||||
|
||||
scroll = scroll * 1.3
|
||||
render.SetMaterial( self.FireMat )
|
||||
render.StartBeam( 3 )
|
||||
render.AddBeam( Pos, 32 * Scale, scroll, Color( 100, 100, 100, 100 ) )
|
||||
render.AddBeam( Pos + Up * 60 * Scale, 32 * Scale, scroll + 1, Color( 255, 200, 50, 150 ) )
|
||||
render.AddBeam( Pos + Up * 300 * Scale, 32 * Scale, scroll + 3, Color( 255, 191, 0, 0 ) )
|
||||
render.EndBeam()
|
||||
end
|
||||
110
garrysmod/addons/lvs_base/lua/effects/lvs_bullet_impact.lua
Normal file
110
garrysmod/addons/lvs_base/lua/effects/lvs_bullet_impact.lua
Normal file
@@ -0,0 +1,110 @@
|
||||
|
||||
EFFECT.SmokeMat = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
EFFECT.DustMat = {
|
||||
"effects/lvs_base/particle_debris_01",
|
||||
"effects/lvs_base/particle_debris_02",
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local pos = data:GetOrigin()
|
||||
local dir = data:GetNormal()
|
||||
local scale = data:GetMagnitude()
|
||||
|
||||
sound.Play( "physics/flesh/flesh_strider_impact_bullet"..math.random(1,3)..".wav", pos, 85, math.random(180,200) + 55 * math.max(1 - scale,0), 0.75 )
|
||||
sound.Play( "ambient/materials/rock"..math.random(1,5)..".wav", pos, 75, 180, 1 )
|
||||
|
||||
local emitter = ParticleEmitter( pos, false )
|
||||
|
||||
local VecCol = (render.GetLightColor( pos + dir ) * 0.5 + Vector(0.2,0.18,0.15)) * 255
|
||||
|
||||
local DieTime = math.Rand(0.8,1.6)
|
||||
|
||||
if dir.z > 0.85 then
|
||||
for i = 1, 10 do
|
||||
for n = 0,6 do
|
||||
local particle = emitter:Add( self.DustMat[ math.random(1,#self.DustMat) ] , pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( (dir * 50 * i + VectorRand() * 25) * scale )
|
||||
particle:SetDieTime( (i / 8) * DieTime )
|
||||
particle:SetAirResistance( 10 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 10 * scale )
|
||||
particle:SetEndSize( 20 * i * scale )
|
||||
particle:SetRollDelta( math.Rand(-1,1) )
|
||||
particle:SetColor( math.min( VecCol.r, 255 ), math.min( VecCol.g, 255 ), math.min( VecCol.b, 255 ) )
|
||||
particle:SetGravity( Vector(0,0,-600) * scale )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, 10 do
|
||||
local particle = emitter:Add( self.SmokeMat[ math.random(1,#self.SmokeMat) ] , pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( (dir * 50 * i + VectorRand() * 40) * scale )
|
||||
particle:SetDieTime( (i / 8) * DieTime )
|
||||
particle:SetAirResistance( 10 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 10 * scale )
|
||||
particle:SetEndSize( 20 * i * scale )
|
||||
particle:SetRollDelta( math.Rand(-1,1) )
|
||||
particle:SetColor( math.min( VecCol.r, 255 ), math.min( VecCol.g, 255 ), math.min( VecCol.b, 255 ) )
|
||||
particle:SetGravity( Vector(0,0,-600) * scale )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1,12 do
|
||||
local particle = emitter:Add( self.SmokeMat[ math.random(1,#self.SmokeMat) ] , pos )
|
||||
|
||||
if particle then
|
||||
local ang = i * 30
|
||||
local X = math.cos( math.rad(ang) )
|
||||
local Y = math.sin( math.rad(ang) )
|
||||
|
||||
local Vel = Vector(X,Y,0) * math.Rand(200,1600) + Vector(0,0,50)
|
||||
Vel:Rotate( dir:Angle() + Angle(90,0,0) )
|
||||
|
||||
particle:SetVelocity( Vel * scale )
|
||||
particle:SetDieTime( DieTime )
|
||||
particle:SetAirResistance( 500 )
|
||||
particle:SetStartAlpha( 100 )
|
||||
particle:SetStartSize( 40 * scale )
|
||||
particle:SetEndSize( 200 * scale )
|
||||
particle:SetRollDelta( math.Rand(-1,1) )
|
||||
particle:SetColor( math.min( VecCol.r, 255 ), math.min( VecCol.g, 255 ), math.min( VecCol.b, 255 ) )
|
||||
particle:SetGravity( Vector(0,0,60) * scale )
|
||||
particle:SetCollide( true )
|
||||
end
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
end
|
||||
229
garrysmod/addons/lvs_base/lua/effects/lvs_bullet_impact_ap.lua
Normal file
229
garrysmod/addons/lvs_base/lua/effects/lvs_bullet_impact_ap.lua
Normal file
@@ -0,0 +1,229 @@
|
||||
|
||||
EFFECT.DustMat = {
|
||||
"effects/lvs_base/particle_debris_01",
|
||||
"effects/lvs_base/particle_debris_02",
|
||||
}
|
||||
|
||||
EFFECT.SmokeMat = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
EFFECT.SparkSurface = {
|
||||
["chainlink"] = true,
|
||||
["canister"] = true,
|
||||
["metal_barrel"] = true,
|
||||
["metalvehicle"] = true,
|
||||
["metal"] = true,
|
||||
["metalgrate"] = true,
|
||||
["rubbertire"] = true,
|
||||
}
|
||||
|
||||
EFFECT.DustSurface = {
|
||||
["sand"] = true,
|
||||
["dirt"] = true,
|
||||
["grass"] = true,
|
||||
["antlionsand"] = true,
|
||||
}
|
||||
|
||||
EFFECT.SmokeSurface = {
|
||||
["concrete"] = true,
|
||||
["tile"] = true,
|
||||
["plaster"] = true,
|
||||
["boulder"] = true,
|
||||
["plastic"] = true,
|
||||
["default"] = true,
|
||||
["glass"] = true,
|
||||
["brick"] = true,
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local pos = data:GetOrigin()
|
||||
|
||||
local bullet_dir = data:GetStart()
|
||||
local dir = data:GetNormal()
|
||||
local magnitude = data:GetMagnitude()
|
||||
|
||||
local ent = data:GetEntity()
|
||||
local surface = data:GetSurfaceProp()
|
||||
local surfaceName = util.GetSurfacePropName( surface )
|
||||
|
||||
local emitter = ParticleEmitter( pos, false )
|
||||
|
||||
local VecCol = (render.GetLightColor( pos ) * 0.8 + Vector(0.17,0.15,0.1)) * 255
|
||||
|
||||
local DieTime = math.Rand(0.8,1.4)
|
||||
|
||||
for i = 1, 60 * magnitude do
|
||||
local spark = emitter:Add("effects/spark", pos + dir * 8)
|
||||
|
||||
if not spark then continue end
|
||||
|
||||
spark:SetStartAlpha( 255 )
|
||||
spark:SetEndAlpha( 0 )
|
||||
spark:SetCollide( true )
|
||||
spark:SetBounce( math.Rand(0,1) )
|
||||
spark:SetColor( 255, 255, 255 )
|
||||
spark:SetGravity( Vector(0,0,-600) )
|
||||
spark:SetEndLength(0)
|
||||
|
||||
local size = math.Rand(4, 6) * magnitude
|
||||
spark:SetEndSize( size )
|
||||
spark:SetStartSize( size )
|
||||
|
||||
spark:SetStartLength( math.Rand(20,40) * magnitude )
|
||||
spark:SetDieTime( math.Rand(0.4, 1.2) )
|
||||
spark:SetVelocity( (dir * math.Rand(300, 600) + VectorRand() * 300) * magnitude )
|
||||
end
|
||||
|
||||
local flash = emitter:Add( "effects/yellowflare",pos )
|
||||
|
||||
if flash then
|
||||
flash:SetPos( pos + dir * 15 )
|
||||
flash:SetStartAlpha( 200 )
|
||||
flash:SetEndAlpha( 0 )
|
||||
flash:SetColor( 255,255,255 )
|
||||
flash:SetEndSize( 0 )
|
||||
flash:SetDieTime( 0.075 )
|
||||
flash:SetStartSize( 300 * magnitude ^ 2 )
|
||||
end
|
||||
|
||||
if self.SparkSurface[ surfaceName ] then
|
||||
if IsValid( ent ) and ent.LVS then
|
||||
if (90 - math.deg( math.acos( math.Clamp( -dir:Dot( bullet_dir ) ,-1,1) ) )) > 10 then
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin( pos )
|
||||
util.Effect( "cball_explode", effectdata, true, true )
|
||||
|
||||
local Ax = math.acos( math.Clamp( dir:Dot( bullet_dir ) ,-1,1) )
|
||||
local Fx = math.cos( Ax )
|
||||
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin( pos )
|
||||
effectdata:SetNormal( (bullet_dir - dir * Fx * 2):GetNormalized() * 0.75 )
|
||||
util.Effect( "manhacksparks", effectdata, true, true )
|
||||
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin( pos )
|
||||
effectdata:SetNormal( -bullet_dir * 0.75 )
|
||||
util.Effect( "manhacksparks", effectdata, true, true )
|
||||
end
|
||||
else
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin( pos )
|
||||
util.Effect( "cball_explode", effectdata, true, true )
|
||||
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin( pos )
|
||||
effectdata:SetNormal( dir )
|
||||
util.Effect( "manhacksparks", effectdata, true, true )
|
||||
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin( pos )
|
||||
effectdata:SetNormal( -bullet_dir )
|
||||
util.Effect( "manhacksparks", effectdata, true, true )
|
||||
end
|
||||
end
|
||||
|
||||
if self.SmokeSurface[ surfaceName ] then
|
||||
for i = 1, 24 do
|
||||
local particle = emitter:Add( self.SmokeMat[ math.random(1, #self.SmokeMat ) ], pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetStartAlpha( math.Rand(33, 66) )
|
||||
particle:SetEndAlpha( 0 )
|
||||
particle:SetColor( math.min( VecCol.r, 255 ), math.min( VecCol.g, 255 ), math.min( VecCol.b, 255 ) )
|
||||
particle:SetGravity( Vector(0,0,-math.Rand(33, 66)) )
|
||||
particle:SetRollDelta( math.random(0, 0.5 * math.pi) )
|
||||
particle:SetAirResistance( 175 )
|
||||
|
||||
particle:SetStartSize( 15 )
|
||||
particle:SetDieTime( math.Rand(0.5, 1) )
|
||||
particle:SetEndSize( math.Rand(45, 90) )
|
||||
particle:SetVelocity( dir * math.Rand(40, 200) + VectorRand() * 150)
|
||||
end
|
||||
|
||||
for i = 1,15 do
|
||||
local particle = emitter:Add("effects/fleck_cement" .. math.random(1, 2), pos + dir * 8)
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetEndAlpha( 0 )
|
||||
particle:SetCollide( true )
|
||||
particle:SetBounce( math.Rand(0,1) )
|
||||
particle:SetColor( math.min( VecCol.r, 255 ), math.min( VecCol.g, 255 ), math.min( VecCol.b, 255 ) )
|
||||
particle:SetGravity(Vector(0,0,-600))
|
||||
particle:SetRollDelta( math.random(0, 0.5*math.pi) )
|
||||
|
||||
particle:SetEndSize( 2 )
|
||||
particle:SetStartSize( 2 )
|
||||
|
||||
particle:SetDieTime( math.Rand(1, 2) )
|
||||
particle:SetVelocity( dir * math.Rand(40, 200) + VectorRand() * 500 )
|
||||
end
|
||||
end
|
||||
|
||||
if not self.DustSurface[ surfaceName ] then return end
|
||||
|
||||
for i = 1, 10 do
|
||||
for i = 1, 15 do
|
||||
local particle = emitter:Add( self.SmokeMat[ math.random(1, #self.SmokeMat ) ], pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetStartAlpha( math.Rand(40, 80) )
|
||||
particle:SetEndAlpha(0)
|
||||
particle:SetColor( math.min( VecCol.r, 255 ), math.min( VecCol.g, 255 ), math.min( VecCol.b, 255 ) )
|
||||
particle:SetGravity( Vector(0,0,-math.Rand(75, 150)) )
|
||||
particle:SetRollDelta( math.random(0, 0.5*math.pi) )
|
||||
particle:SetAirResistance( 175 )
|
||||
|
||||
particle:SetStartSize( 5 )
|
||||
particle:SetDieTime( math.Rand(0.5, 1) )
|
||||
particle:SetEndSize( math.Rand(15, 30) )
|
||||
particle:SetVelocity( (dir * math.Rand(80, 400) + VectorRand() * 100) * 1.5 )
|
||||
end
|
||||
|
||||
for n = 0,6 do
|
||||
local particle = emitter:Add( self.DustMat[ math.random(1,#self.DustMat) ] , pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( (dir * 50 * i + VectorRand() * 50) )
|
||||
particle:SetDieTime( (i / 8) * DieTime )
|
||||
particle:SetAirResistance( 10 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 5 )
|
||||
particle:SetEndSize( 10 * i )
|
||||
particle:SetRollDelta( math.Rand(-1,1) )
|
||||
particle:SetColor( math.min( VecCol.r, 255 ), math.min( VecCol.g, 255 ), math.min( VecCol.b, 255 ) )
|
||||
particle:SetGravity( Vector(0,0,-600) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
end
|
||||
@@ -0,0 +1,277 @@
|
||||
|
||||
EFFECT.GlowMat = Material( "sprites/light_glow02_add" )
|
||||
EFFECT.SmokeMat = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
EFFECT.DustMat = {
|
||||
"effects/lvs_base/particle_debris_01",
|
||||
"effects/lvs_base/particle_debris_02",
|
||||
}
|
||||
|
||||
EFFECT.DecalMat = Material( util.DecalMaterial( "Scorch" ) )
|
||||
|
||||
function EFFECT:Init( data )
|
||||
self.Dir = data:GetNormal()
|
||||
self.Pos = data:GetOrigin()
|
||||
|
||||
self.LifeTime = 0.35
|
||||
self.DieTime = CurTime() + self.LifeTime
|
||||
|
||||
local scale = data:GetMagnitude() * 0.5
|
||||
|
||||
self.Scale = 3 * scale
|
||||
|
||||
local emitter = ParticleEmitter( self.Pos, false )
|
||||
|
||||
local VecCol = (render.GetLightColor( self.Pos + self.Dir ) * 0.5 + Vector(0.1,0.09,0.075)) * 255
|
||||
|
||||
local DieTime = math.Rand(0.8,1.6)
|
||||
|
||||
local traceSky = util.TraceLine( {
|
||||
start = self.Pos,
|
||||
endpos = self.Pos + Vector(0,0,50000),
|
||||
filter = self,
|
||||
} )
|
||||
|
||||
local traceWater = util.TraceLine( {
|
||||
start = traceSky.HitPos,
|
||||
endpos = self.Pos - Vector(0,0,100),
|
||||
filter = self,
|
||||
mask = MASK_WATER,
|
||||
} )
|
||||
|
||||
if traceWater.Hit then
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin( traceWater.HitPos )
|
||||
effectdata:SetScale( 100 )
|
||||
effectdata:SetFlags( 2 )
|
||||
util.Effect( "WaterSplash", effectdata, true, true )
|
||||
end
|
||||
|
||||
local Pos = self.Pos
|
||||
local Dist = (traceWater.HitPos - Pos):Length()
|
||||
local ply = LocalPlayer():GetViewEntity()
|
||||
|
||||
if not IsValid( ply ) then return end
|
||||
|
||||
local delay = (Pos - ply:GetPos()):Length() / 13503.9
|
||||
|
||||
if traceWater.Hit and Dist > 150 then
|
||||
timer.Simple( delay, function()
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin( Pos )
|
||||
util.Effect( "WaterSurfaceExplosion", effectdata, true, true )
|
||||
end )
|
||||
|
||||
if Dist > 300 then return end
|
||||
else
|
||||
timer.Simple( delay, function()
|
||||
sound.Play( "LVS.BULLET_EXPLOSION", Pos )
|
||||
sound.Play( "LVS.BULLET_EXPLOSION_DYNAMIC", Pos )
|
||||
end )
|
||||
|
||||
local trace = util.TraceLine( {
|
||||
start = self.Pos + Vector(0,0,100),
|
||||
endpos = self.Pos - Vector(0,0,100),
|
||||
mask = MASK_SOLID_BRUSHONLY,
|
||||
} )
|
||||
|
||||
if trace.Hit and not trace.HitNonWorld then
|
||||
util.DecalEx( self.DecalMat, trace.Entity, trace.HitPos + trace.HitNormal, trace.HitNormal, Color(255,255,255,255), self.Scale * 2.5, self.Scale * 2.5 )
|
||||
end
|
||||
end
|
||||
|
||||
if self.Dir.z > 0.8 then
|
||||
for i = 1, 10 do
|
||||
for n = 0,6 do
|
||||
local particle = emitter:Add( self.DustMat[ math.random(1,#self.DustMat) ], self.Pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( (self.Dir * 50 * i + VectorRand() * 25) * self.Scale )
|
||||
particle:SetDieTime( (i / 8) * DieTime )
|
||||
particle:SetAirResistance( 10 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 10 * self.Scale )
|
||||
particle:SetEndSize( 20 * i * self.Scale )
|
||||
particle:SetRollDelta( math.Rand(-1,1) )
|
||||
particle:SetColor( math.min( VecCol.r, 255 ), math.min( VecCol.g, 255 ), math.min( VecCol.b, 255 ) )
|
||||
particle:SetGravity( Vector(0,0,-600) * self.Scale )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, 10 do
|
||||
local particle = emitter:Add( self.SmokeMat[ math.random(1,#self.SmokeMat) ], self.Pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( (self.Dir * 50 * i + VectorRand() * 40) * self.Scale )
|
||||
particle:SetDieTime( (i / 8) * DieTime )
|
||||
particle:SetAirResistance( 10 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 10 * self.Scale )
|
||||
particle:SetEndSize( 20 * i * self.Scale )
|
||||
particle:SetRollDelta( math.Rand(-1,1) )
|
||||
particle:SetColor( math.min( VecCol.r, 255 ), math.min( VecCol.g, 255 ), math.min( VecCol.b, 255 ) )
|
||||
particle:SetGravity( Vector(0,0,-600) * self.Scale )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1,24 do
|
||||
local particle = emitter:Add( self.SmokeMat[ math.random(1,#self.SmokeMat) ] , self.Pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
local ang = i * 15
|
||||
local X = math.cos( math.rad(ang) )
|
||||
local Y = math.sin( math.rad(ang) )
|
||||
|
||||
local Vel = Vector(X,Y,0) * math.Rand(800,1200)
|
||||
Vel:Rotate( self.Dir:Angle() + Angle(90,0,0) )
|
||||
|
||||
particle:SetVelocity( Vel * self.Scale )
|
||||
particle:SetDieTime( math.Rand(1,3) )
|
||||
particle:SetAirResistance( 600 )
|
||||
particle:SetStartAlpha( 100 )
|
||||
particle:SetStartSize( 40 * self.Scale )
|
||||
particle:SetEndSize( 140 * self.Scale )
|
||||
particle:SetRollDelta( math.Rand(-1,1) )
|
||||
particle:SetColor( math.min( VecCol.r, 255 ), math.min( VecCol.g, 255 ), math.min( VecCol.b, 255 ) )
|
||||
particle:SetGravity( Vector(0,0,60) * self.Scale )
|
||||
particle:SetCollide( true )
|
||||
end
|
||||
|
||||
for i = 0, 15 do
|
||||
local particle = emitter:Add( self.SmokeMat[ math.random(1, #self.SmokeMat ) ], self.Pos )
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( VectorRand(-1,1) * 1000 * scale )
|
||||
particle:SetDieTime( math.Rand(2,3) )
|
||||
particle:SetAirResistance( 200 )
|
||||
particle:SetStartAlpha( 100 )
|
||||
particle:SetStartSize( 200 * scale )
|
||||
particle:SetEndSize( 600 * scale )
|
||||
particle:SetRoll( math.Rand(-1,1) )
|
||||
particle:SetRollDelta( math.Rand(-1,1) )
|
||||
particle:SetColor( math.min( VecCol.r, 255 ), math.min( VecCol.g, 255 ), math.min( VecCol.b, 255 ) )
|
||||
particle:SetGravity( Vector( 0, 0, -600 ) * scale )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
for i = 0, 20 do
|
||||
local particle = emitter:Add( "effects/lvs_base/flamelet"..math.random(1,5), self.Pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( VectorRand() * 800 * scale )
|
||||
particle:SetDieTime( math.Rand(0.2,0.4) )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetEndAlpha( 0 )
|
||||
particle:SetStartSize( 120 * scale )
|
||||
particle:SetEndSize( 20 * scale )
|
||||
particle:SetColor( 255, 255, 255 )
|
||||
particle:SetGravity( self.Dir * 2500 )
|
||||
particle:SetRollDelta( math.Rand(-5,5) )
|
||||
particle:SetAirResistance( 300 )
|
||||
end
|
||||
|
||||
for i = 0, 5 do
|
||||
local particle = emitter:Add( "effects/lvs_base/flamelet"..math.random(1,5), self.Pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetEndAlpha( 0 )
|
||||
particle:SetColor( 255, 255, 255 )
|
||||
particle:SetGravity( Vector(0,0,0) )
|
||||
|
||||
local size = math.Rand(8, 24) * scale
|
||||
particle:SetEndSize( size )
|
||||
particle:SetStartSize( size )
|
||||
|
||||
particle:SetStartLength( 400 * scale )
|
||||
particle:SetEndLength( size )
|
||||
|
||||
particle:SetDieTime( math.Rand(0.1,0.2) )
|
||||
particle:SetVelocity( (self.Dir * 4000 + VectorRand() * 2000) * scale )
|
||||
|
||||
particle:SetAirResistance( 0 )
|
||||
end
|
||||
|
||||
for i = 0, 40 do
|
||||
local particle = emitter:Add( "effects/fire_embers"..math.random(1,2), self.Pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( VectorRand() * 800 * scale )
|
||||
particle:SetDieTime( math.Rand(0.4,0.6) )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetEndAlpha( 0 )
|
||||
particle:SetStartSize( 40 * scale )
|
||||
particle:SetEndSize( 0 )
|
||||
particle:SetColor( 255, 255, 255 )
|
||||
particle:SetGravity( Vector(0,0,600) )
|
||||
particle:SetRollDelta( math.Rand(-8,8) )
|
||||
particle:SetAirResistance( 300 )
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
end
|
||||
|
||||
function EFFECT:Explosion( pos , scale )
|
||||
local emitter = ParticleEmitter( pos, false )
|
||||
|
||||
if not IsValid( emitter ) then return end
|
||||
|
||||
for i = 0, 40 do
|
||||
local particle = emitter:Add( "particles/flamelet"..math.random(1,5), pos )
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( VectorRand() * 1500 * scale )
|
||||
particle:SetDieTime( 0.2 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 20 * scale )
|
||||
particle:SetEndSize( math.Rand(180,240) * scale )
|
||||
particle:SetEndAlpha( 100 )
|
||||
particle:SetRoll( math.Rand( -1, 1 ) )
|
||||
particle:SetColor( 200,150,150 )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if self.DieTime < CurTime() then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
if not self.Scale then return end
|
||||
|
||||
local Scale = (self.DieTime - CurTime()) / self.LifeTime
|
||||
local R1 = 800 * self.Scale
|
||||
render.SetMaterial( self.GlowMat )
|
||||
render.DrawSprite( self.Pos, R1 * Scale, R1 * Scale, Color( 255, 200, 150, 255) )
|
||||
end
|
||||
@@ -0,0 +1,57 @@
|
||||
EFFECT.Smoke = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local Pos = data:GetOrigin()
|
||||
local Ent = data:GetEntity()
|
||||
|
||||
if not IsValid( Ent ) then return end
|
||||
|
||||
local emitter = Ent:GetParticleEmitter( Ent:WorldToLocal( Pos ) )
|
||||
|
||||
if not IsValid( emitter ) then return end
|
||||
|
||||
local particle = emitter:Add( self.Smoke[ math.random(1, #self.Smoke ) ], Pos )
|
||||
|
||||
local rCol = math.random(30,60)
|
||||
|
||||
local Scale = math.Rand(1,8)
|
||||
|
||||
if not particle then return end
|
||||
|
||||
particle:SetVelocity( Vector(0,0,80) + VectorRand() * 80 )
|
||||
particle:SetDieTime( Scale )
|
||||
particle:SetAirResistance( 200 )
|
||||
particle:SetStartAlpha( 100 / Scale )
|
||||
particle:SetStartSize( 20 )
|
||||
particle:SetEndSize( math.random(15,30) * Scale )
|
||||
particle:SetRoll( math.pi / Scale )
|
||||
particle:SetRollDelta( math.Rand(-1,1) )
|
||||
particle:SetColor( rCol, rCol, rCol )
|
||||
particle:SetGravity( Vector( 0, 0, math.random(-40,80) ) )
|
||||
particle:SetCollide( true )
|
||||
particle:SetBounce( 0 )
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
end
|
||||
130
garrysmod/addons/lvs_base/lua/effects/lvs_carengine_fire.lua
Normal file
130
garrysmod/addons/lvs_base/lua/effects/lvs_carengine_fire.lua
Normal file
@@ -0,0 +1,130 @@
|
||||
|
||||
EFFECT.GlowMat = Material( "sprites/light_glow02_add" )
|
||||
EFFECT.FireMat = {
|
||||
[1] = Material( "effects/lvs_base/flamelet1" ),
|
||||
[2] = Material( "effects/lvs_base/flamelet2" ),
|
||||
[3] = Material( "effects/lvs_base/flamelet3" ),
|
||||
[4] = Material( "effects/lvs_base/flamelet4" ),
|
||||
[5] = Material( "effects/lvs_base/flamelet5" ),
|
||||
[6] = Material( "effects/lvs_base/fire" ),
|
||||
}
|
||||
|
||||
EFFECT.SmokeMat = {
|
||||
[1] = Material( "particle/smokesprites_0001" ),
|
||||
[2] = Material( "particle/smokesprites_0002" ),
|
||||
[3] = Material( "particle/smokesprites_0003" ),
|
||||
[4] = Material( "particle/smokesprites_0004" ),
|
||||
[5] = Material( "particle/smokesprites_0005" ),
|
||||
[6] = Material( "particle/smokesprites_0006" ),
|
||||
[7] = Material( "particle/smokesprites_0007" ),
|
||||
[8] = Material( "particle/smokesprites_0008" ),
|
||||
[9] = Material( "particle/smokesprites_0009" ),
|
||||
[10] = Material( "particle/smokesprites_0010" ),
|
||||
[11] = Material( "particle/smokesprites_0011" ),
|
||||
[12] = Material( "particle/smokesprites_0012" ),
|
||||
[13] = Material( "particle/smokesprites_0013" ),
|
||||
[14] = Material( "particle/smokesprites_0014" ),
|
||||
[15] = Material( "particle/smokesprites_0015" ),
|
||||
[16] = Material( "particle/smokesprites_0016" ),
|
||||
}
|
||||
|
||||
EFFECT.Smoke = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local Pos = data:GetOrigin()
|
||||
local Ent = data:GetEntity()
|
||||
|
||||
self.LifeTime = 1
|
||||
self.DieTime = CurTime() + self.LifeTime
|
||||
|
||||
if not IsValid( Ent ) then return end
|
||||
|
||||
local randomPos = VectorRand() * 15
|
||||
randomPos.z = 0
|
||||
|
||||
self.Ent = Ent
|
||||
self.Pos = Ent:WorldToLocal( Pos + randomPos )
|
||||
self.RandomSize = math.Rand( 0.8, 1.6 )
|
||||
self.Vel = self.Ent:GetVelocity()
|
||||
|
||||
local emitter = Ent:GetParticleEmitter( self.Pos )
|
||||
|
||||
if not IsValid( emitter ) then return end
|
||||
|
||||
for i = 1, 8 do
|
||||
local particle = emitter:Add( self.Smoke[ math.random(1, #self.Smoke ) ], Pos )
|
||||
|
||||
local Dir = Angle(0,math.Rand(-180,180),0):Forward()
|
||||
Dir.z = -0.5
|
||||
Dir:Normalize()
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( Dir * 250 )
|
||||
particle:SetDieTime( 0.5 + i * 0.01 )
|
||||
particle:SetAirResistance( 125 )
|
||||
particle:SetStartAlpha( 100 )
|
||||
particle:SetStartSize( 20 )
|
||||
particle:SetEndSize( 40 )
|
||||
particle:SetRoll( math.Rand(-1,1) * math.pi )
|
||||
particle:SetRollDelta( math.Rand(-1,1) * 3 )
|
||||
particle:SetColor( 0, 0, 0 )
|
||||
particle:SetGravity( Vector( 0, 0, 600 ) )
|
||||
particle:SetCollide( true )
|
||||
particle:SetBounce( 0 )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if not IsValid( self.Ent ) then return false end
|
||||
|
||||
if self.DieTime < CurTime() then return false end
|
||||
|
||||
self:SetPos( self.Ent:LocalToWorld( self.Pos ) )
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
if not IsValid( self.Ent ) or not self.Pos then return end
|
||||
|
||||
self:RenderFire()
|
||||
end
|
||||
|
||||
function EFFECT:RenderFire()
|
||||
local Scale = (self.DieTime - 0.4 - CurTime()) / 0.6
|
||||
|
||||
if Scale < 0 then return end
|
||||
|
||||
local Pos = self.Ent:LocalToWorld( self.Pos )
|
||||
|
||||
local InvScale = 1 - Scale
|
||||
|
||||
render.SetMaterial( self.GlowMat )
|
||||
render.DrawSprite( Pos + Vector(0,0,InvScale ^ 2 * 10), 100 * InvScale, 100 * InvScale, Color( 255, 150, 75, 255) )
|
||||
|
||||
local Num = #self.FireMat - math.Clamp(math.ceil( Scale * #self.FireMat ) - 1,0, #self.FireMat - 1)
|
||||
|
||||
local Size = (5 + 20 * Scale) * self.RandomSize
|
||||
local Offset = (self.Vel * InvScale ^ 2) * 0.025
|
||||
|
||||
render.SetMaterial( self.FireMat[ Num ] )
|
||||
render.DrawSprite( Pos + Vector(0,0,InvScale ^ 2 * 30) - Offset, Size, Size, Color( 255, 255, 255, 255) )
|
||||
end
|
||||
@@ -0,0 +1,71 @@
|
||||
|
||||
EFFECT.SmokeMat = {
|
||||
[1] = Material( "particle/smokesprites_0001" ),
|
||||
[2] = Material( "particle/smokesprites_0002" ),
|
||||
[3] = Material( "particle/smokesprites_0003" ),
|
||||
[4] = Material( "particle/smokesprites_0004" ),
|
||||
[5] = Material( "particle/smokesprites_0005" ),
|
||||
[6] = Material( "particle/smokesprites_0006" ),
|
||||
[7] = Material( "particle/smokesprites_0007" ),
|
||||
[8] = Material( "particle/smokesprites_0008" ),
|
||||
[9] = Material( "particle/smokesprites_0009" ),
|
||||
[10] = Material( "particle/smokesprites_0010" ),
|
||||
[11] = Material( "particle/smokesprites_0011" ),
|
||||
[12] = Material( "particle/smokesprites_0012" ),
|
||||
[13] = Material( "particle/smokesprites_0013" ),
|
||||
[14] = Material( "particle/smokesprites_0014" ),
|
||||
[15] = Material( "particle/smokesprites_0015" ),
|
||||
[16] = Material( "particle/smokesprites_0016" ),
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local Pos = data:GetOrigin()
|
||||
local Ent = data:GetEntity()
|
||||
local Mag = data:GetMagnitude()
|
||||
|
||||
self.LifeTime = 0.5 + Mag * 0.5
|
||||
self.DieTime = CurTime() + self.LifeTime
|
||||
|
||||
if not IsValid( Ent ) then return end
|
||||
|
||||
self.Mag = Mag
|
||||
self.Ent = Ent
|
||||
self.Pos = Ent:WorldToLocal( Pos + VectorRand() * 15 )
|
||||
self.RandomSize = math.Rand( 0.8, 1.6 )
|
||||
self.Vel = self.Ent:GetVelocity()
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if not IsValid( self.Ent ) then return false end
|
||||
|
||||
if self.DieTime < CurTime() then return false end
|
||||
|
||||
self:SetPos( self.Ent:LocalToWorld( self.Pos ) )
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
if not IsValid( self.Ent ) or not self.Pos then return end
|
||||
|
||||
self:RenderSmoke()
|
||||
end
|
||||
|
||||
function EFFECT:RenderSmoke()
|
||||
local Scale = (self.DieTime - CurTime()) / self.LifeTime
|
||||
|
||||
local Pos = self.Ent:LocalToWorld( self.Pos )
|
||||
|
||||
local InvScale = 1 - Scale
|
||||
|
||||
local Num = #self.SmokeMat - math.Clamp(math.ceil( Scale * #self.SmokeMat ) - 1,0, #self.SmokeMat - 1)
|
||||
|
||||
local A = (50 + 100 * (1 - self.Mag)) * Scale
|
||||
local C = (20 + 30 * self.RandomSize * self.Mag)
|
||||
|
||||
local Size = (25 + 30 * InvScale) * self.RandomSize
|
||||
local Offset = (self.Vel * InvScale ^ 2) * 0.15
|
||||
|
||||
render.SetMaterial( self.SmokeMat[ Num ] )
|
||||
render.DrawSprite( Pos + Vector(0,0,InvScale ^ 2 * (20 + self.Vel:Length() / 25) * self.RandomSize) - Offset, Size, Size, Color( C, C, C, A ) )
|
||||
end
|
||||
@@ -0,0 +1,127 @@
|
||||
|
||||
EFFECT.SmokeMat = {
|
||||
[1] = Material( "particle/smokesprites_0001" ),
|
||||
[2] = Material( "particle/smokesprites_0002" ),
|
||||
[3] = Material( "particle/smokesprites_0003" ),
|
||||
[4] = Material( "particle/smokesprites_0004" ),
|
||||
[5] = Material( "particle/smokesprites_0005" ),
|
||||
[6] = Material( "particle/smokesprites_0006" ),
|
||||
[7] = Material( "particle/smokesprites_0007" ),
|
||||
[8] = Material( "particle/smokesprites_0008" ),
|
||||
[9] = Material( "particle/smokesprites_0009" ),
|
||||
[10] = Material( "particle/smokesprites_0010" ),
|
||||
[11] = Material( "particle/smokesprites_0011" ),
|
||||
[12] = Material( "particle/smokesprites_0012" ),
|
||||
[13] = Material( "particle/smokesprites_0013" ),
|
||||
[14] = Material( "particle/smokesprites_0014" ),
|
||||
[15] = Material( "particle/smokesprites_0015" ),
|
||||
[16] = Material( "particle/smokesprites_0016" ),
|
||||
}
|
||||
|
||||
EFFECT.GlowMat = Material( "sprites/light_glow02_add" )
|
||||
EFFECT.FireMat = Material( "effects/muzzleflash2" )
|
||||
|
||||
function EFFECT:Init( data )
|
||||
self.Pos = data:GetOrigin()
|
||||
self.Ang = data:GetAngles()
|
||||
self.Ent = data:GetEntity()
|
||||
|
||||
self.LifeTime = 0.5
|
||||
self.DieTime = CurTime() + self.LifeTime
|
||||
|
||||
if not IsValid( self.Ent ) then return end
|
||||
|
||||
self.Mat = self.SmokeMat[ math.random(1,#self.SmokeMat) ]
|
||||
|
||||
local Pos = self.Ent:LocalToWorld( self.Pos )
|
||||
|
||||
self:SetPos( Pos )
|
||||
|
||||
local dlight = DynamicLight( self.Ent:EntIndex() * math.random(1,4), true )
|
||||
if dlight then
|
||||
dlight.pos = Pos
|
||||
dlight.r = 255
|
||||
dlight.g = 180
|
||||
dlight.b = 100
|
||||
dlight.brightness = 1
|
||||
dlight.Decay = 2000
|
||||
dlight.Size = 300
|
||||
dlight.DieTime = CurTime() + 0.2
|
||||
end
|
||||
|
||||
sound.Play( "lvs/vehicles/generic/exhaust_backfire"..math.random(1,3)..".ogg", Pos, 75, 100, 1 )
|
||||
|
||||
local vel = self.Ent:GetVelocity()
|
||||
local dir = self.Ent:LocalToWorldAngles( self.Ang ):Forward()
|
||||
local emitter = ParticleEmitter( Pos, false )
|
||||
|
||||
if emitter then
|
||||
for i = 0, 12 do
|
||||
local particle = emitter:Add( "sprites/rico1", Pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( vel + dir * 100 + VectorRand() * 100 )
|
||||
particle:SetDieTime( math.Rand(0.2,0.4) )
|
||||
particle:SetStartAlpha( 0 )
|
||||
particle:SetEndAlpha( 25 )
|
||||
particle:SetStartSize( 1 )
|
||||
particle:SetEndSize( 0 )
|
||||
particle:SetRoll( math.Rand(-100,100) )
|
||||
particle:SetRollDelta( math.Rand(-100,100) )
|
||||
particle:SetCollide( true )
|
||||
particle:SetBounce( 0.5 )
|
||||
particle:SetAirResistance( 0 )
|
||||
particle:SetColor( 255, 225, 150 )
|
||||
particle:SetGravity( Vector(0,0,-600) )
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if not IsValid( self.Ent ) then return false end
|
||||
|
||||
if self.DieTime < CurTime() then return false end
|
||||
|
||||
self:SetPos( self.Ent:LocalToWorld( self.Pos ) )
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
function EFFECT:Render()
|
||||
if not IsValid( self.Ent ) or not self.Pos then return end
|
||||
|
||||
self:RenderSmoke()
|
||||
end
|
||||
|
||||
function EFFECT:RenderSmoke()
|
||||
if not self.Pos or not self.Ang then return end
|
||||
|
||||
local Scale = (self.DieTime - CurTime()) / self.LifeTime
|
||||
local InvScale = 1 - Scale
|
||||
|
||||
local Pos = self.Ent:LocalToWorld( self.Pos )
|
||||
local Ang = self.Ent:LocalToWorldAngles( self.Ang )
|
||||
|
||||
local FlameSize = 40 * Scale ^ 2
|
||||
render.SetMaterial( self.FireMat )
|
||||
for i = 1, 4 do
|
||||
render.DrawSprite( Pos + Ang:Forward() * InvScale * 5 + VectorRand() * 2, FlameSize, FlameSize, Color( 255, 255, 255, 255 * InvScale) )
|
||||
end
|
||||
|
||||
local GlowSize = 80 * Scale ^ 2
|
||||
render.SetMaterial( self.GlowMat )
|
||||
render.DrawSprite( Pos + Ang:Forward() * InvScale * 10, GlowSize, GlowSize, Color(255* InvScale, 150* InvScale,75* InvScale,255* InvScale) )
|
||||
|
||||
if not self.Mat then return end
|
||||
|
||||
local C = 40
|
||||
local Size = (20 + 50 * InvScale)
|
||||
|
||||
render.SetMaterial( self.Mat )
|
||||
render.DrawSprite( Pos + Ang:Forward() * InvScale * 40, Size, Size, Color( C, C, C, 255 * Scale) )
|
||||
end
|
||||
|
||||
105
garrysmod/addons/lvs_base/lua/effects/lvs_carexhaust_pop.lua
Normal file
105
garrysmod/addons/lvs_base/lua/effects/lvs_carexhaust_pop.lua
Normal file
@@ -0,0 +1,105 @@
|
||||
|
||||
EFFECT.GlowMat = Material( "effects/yellowflare" )
|
||||
EFFECT.FireMat = Material( "effects/muzzleflash2" )
|
||||
|
||||
function EFFECT:Init( data )
|
||||
self.Pos = data:GetOrigin()
|
||||
self.Ang = data:GetAngles()
|
||||
self.Ent = data:GetEntity()
|
||||
|
||||
local volume = math.Clamp( data:GetMagnitude(), 0, 1 )
|
||||
|
||||
local T = CurTime()
|
||||
|
||||
self.LifeTime = 0.25
|
||||
self.LifeTimePop = 0.1
|
||||
|
||||
self.DieTime = T + self.LifeTime
|
||||
self.DieTimePop = T + self.LifeTimePop
|
||||
|
||||
self.Scale = math.Rand( 0.25, 1 )
|
||||
|
||||
if not IsValid( self.Ent ) then return end
|
||||
|
||||
local Pos = self.Ent:LocalToWorld( self.Pos )
|
||||
|
||||
self:SetPos( Pos )
|
||||
|
||||
local ply = LocalPlayer()
|
||||
|
||||
if not IsValid( ply ) then return end
|
||||
|
||||
local veh = ply:lvsGetVehicle()
|
||||
|
||||
if IsValid( veh ) and veh == self.Ent then
|
||||
local pod = ply:GetVehicle()
|
||||
|
||||
if IsValid( pod ) and not pod:GetThirdPersonMode() then
|
||||
sound.Play( "lvs/vehicles/generic/exhaust_pop_interior"..math.random(1,12)..".ogg", Pos, 75, math.random(98,105), volume )
|
||||
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local dlight = DynamicLight( self.Ent:EntIndex() * math.random(1,4), true )
|
||||
|
||||
if dlight then
|
||||
dlight.pos = Pos
|
||||
dlight.r = 255
|
||||
dlight.g = 180
|
||||
dlight.b = 100
|
||||
dlight.brightness = 1
|
||||
dlight.Decay = 2000
|
||||
dlight.Size = 400
|
||||
dlight.DieTime = CurTime() + 0.2
|
||||
end
|
||||
|
||||
sound.Play( "lvs/vehicles/generic/exhaust_pop"..math.random(1,16)..".ogg", Pos, 75, math.random(98,105), volume )
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if not IsValid( self.Ent ) then return false end
|
||||
|
||||
if self.DieTime < CurTime() then return false end
|
||||
|
||||
self:SetPos( self.Ent:LocalToWorld( self.Pos ) )
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
function EFFECT:Render()
|
||||
if not IsValid( self.Ent ) or not self.Pos then return end
|
||||
|
||||
self:RenderSmoke()
|
||||
end
|
||||
|
||||
function EFFECT:RenderSmoke()
|
||||
if not self.Pos or not self.Ang or not self.Scale then return end
|
||||
|
||||
local T = CurTime()
|
||||
|
||||
local ScalePop = math.Clamp( (self.DieTimePop - T) / self.LifeTimePop, 0, 1 )
|
||||
local InvScalePop = 1 - ScalePop
|
||||
|
||||
local Scale = (self.DieTime - T) / self.LifeTime
|
||||
local InvScale = 1 - Scale
|
||||
|
||||
local Pos = self.Ent:LocalToWorld( self.Pos )
|
||||
local Ang = self.Ent:LocalToWorldAngles( self.Ang )
|
||||
|
||||
local FlameSize = 5 * Scale ^ 2
|
||||
render.SetMaterial( self.FireMat )
|
||||
for i = 1, 12 do
|
||||
render.DrawSprite( Pos + Ang:Forward() * InvScale * 20 + VectorRand() * 2, FlameSize, FlameSize, color_white )
|
||||
end
|
||||
|
||||
if InvScalePop <= 0 then return end
|
||||
|
||||
local GlowSize = 60 * InvScalePop * self.Scale
|
||||
local A255 = 255 * ScalePop
|
||||
|
||||
render.SetMaterial( self.GlowMat )
|
||||
render.DrawSprite( Pos, GlowSize, GlowSize, Color(A255,A255,A255,A255) )
|
||||
end
|
||||
|
||||
145
garrysmod/addons/lvs_base/lua/effects/lvs_carfueltank_fire.lua
Normal file
145
garrysmod/addons/lvs_base/lua/effects/lvs_carfueltank_fire.lua
Normal file
@@ -0,0 +1,145 @@
|
||||
|
||||
EFFECT.GlowMat = Material( "sprites/light_glow02_add" )
|
||||
EFFECT.FireMat = {
|
||||
[1] = Material( "effects/lvs_base/flamelet1" ),
|
||||
[2] = Material( "effects/lvs_base/flamelet2" ),
|
||||
[3] = Material( "effects/lvs_base/flamelet3" ),
|
||||
[4] = Material( "effects/lvs_base/flamelet4" ),
|
||||
[5] = Material( "effects/lvs_base/flamelet5" ),
|
||||
[6] = Material( "effects/lvs_base/fire" ),
|
||||
}
|
||||
|
||||
EFFECT.SmokeMat = {
|
||||
[1] = Material( "particle/smokesprites_0001" ),
|
||||
[2] = Material( "particle/smokesprites_0002" ),
|
||||
[3] = Material( "particle/smokesprites_0003" ),
|
||||
[4] = Material( "particle/smokesprites_0004" ),
|
||||
[5] = Material( "particle/smokesprites_0005" ),
|
||||
[6] = Material( "particle/smokesprites_0006" ),
|
||||
[7] = Material( "particle/smokesprites_0007" ),
|
||||
[8] = Material( "particle/smokesprites_0008" ),
|
||||
[9] = Material( "particle/smokesprites_0009" ),
|
||||
[10] = Material( "particle/smokesprites_0010" ),
|
||||
[11] = Material( "particle/smokesprites_0011" ),
|
||||
[12] = Material( "particle/smokesprites_0012" ),
|
||||
[13] = Material( "particle/smokesprites_0013" ),
|
||||
[14] = Material( "particle/smokesprites_0014" ),
|
||||
[15] = Material( "particle/smokesprites_0015" ),
|
||||
[16] = Material( "particle/smokesprites_0016" ),
|
||||
}
|
||||
|
||||
EFFECT.Smoke = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local Pos = data:GetOrigin()
|
||||
local Ent = data:GetEntity()
|
||||
|
||||
self.LifeTime = 1
|
||||
self.DieTime = CurTime() + self.LifeTime
|
||||
|
||||
if not IsValid( Ent ) then return end
|
||||
|
||||
self.Ent = Ent
|
||||
self.Pos = Ent:WorldToLocal( Pos + VectorRand() * 20 )
|
||||
self.RandomSize = math.Rand( 1, 2 )
|
||||
self.Vel = self.Ent:GetVelocity()
|
||||
|
||||
local emitter = Ent:GetParticleEmitter( self.Pos )
|
||||
|
||||
if not IsValid( emitter ) then return end
|
||||
|
||||
for i = 1, 8 do
|
||||
local particle = emitter:Add( self.Smoke[ math.random(1, #self.Smoke ) ], Pos )
|
||||
|
||||
local Dir = Angle(0,math.Rand(-180,180),0):Forward()
|
||||
Dir.z = -0.5
|
||||
Dir:Normalize()
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( Dir * 250 )
|
||||
particle:SetDieTime( 0.5 + i * 0.01 )
|
||||
particle:SetAirResistance( 125 )
|
||||
particle:SetStartAlpha( 100 )
|
||||
particle:SetStartSize( 20 )
|
||||
particle:SetEndSize( 40 )
|
||||
particle:SetRoll( math.Rand(-1,1) * math.pi )
|
||||
particle:SetRollDelta( math.Rand(-1,1) * 3 )
|
||||
particle:SetColor( 0, 0, 0 )
|
||||
particle:SetGravity( Vector( 0, 0, 600 ) )
|
||||
particle:SetCollide( true )
|
||||
particle:SetBounce( 0 )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if not IsValid( self.Ent ) then return false end
|
||||
|
||||
if self.DieTime < CurTime() then return false end
|
||||
|
||||
self:SetPos( self.Ent:LocalToWorld( self.Pos ) )
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
if not IsValid( self.Ent ) or not self.Pos then return end
|
||||
|
||||
self:RenderSmoke()
|
||||
self:RenderFire()
|
||||
end
|
||||
|
||||
function EFFECT:RenderSmoke()
|
||||
local Scale = (self.DieTime - CurTime()) / self.LifeTime
|
||||
|
||||
local Pos = self.Ent:LocalToWorld( self.Pos ) + Vector(0,0,25)
|
||||
|
||||
local InvScale = 1 - Scale
|
||||
|
||||
local Num = #self.SmokeMat - math.Clamp(math.ceil( Scale * #self.SmokeMat ) - 1,0, #self.SmokeMat - 1)
|
||||
|
||||
local C = 10 + 10 * self.RandomSize
|
||||
local Size = (25 + 30 * InvScale) * self.RandomSize
|
||||
local Offset = (self.Vel * InvScale ^ 2) * 0.5
|
||||
|
||||
render.SetMaterial( self.SmokeMat[ Num ] )
|
||||
render.DrawSprite( Pos + Vector(0,0,InvScale ^ 2 * 80 * self.RandomSize) - Offset, Size, Size, Color( C, C, C, 200 * Scale) )
|
||||
end
|
||||
|
||||
function EFFECT:RenderFire()
|
||||
local Scale = (self.DieTime - 0.4 - CurTime()) / 0.6
|
||||
|
||||
if Scale < 0 then return end
|
||||
|
||||
local Pos = self.Ent:LocalToWorld( self.Pos )
|
||||
|
||||
local InvScale = 1 - Scale
|
||||
|
||||
render.SetMaterial( self.GlowMat )
|
||||
render.DrawSprite( Pos + Vector(0,0,InvScale ^ 2 * 10), 100 * InvScale, 100 * InvScale, Color( 255, 150, 75, 255) )
|
||||
|
||||
local Num = #self.FireMat - math.Clamp(math.ceil( Scale * #self.FireMat ) - 1,0, #self.FireMat - 1)
|
||||
|
||||
local Size = (10 + 20 * Scale) * self.RandomSize
|
||||
local Offset = (self.Vel * InvScale ^ 2) * 0.025
|
||||
|
||||
render.SetMaterial( self.FireMat[ Num ] )
|
||||
render.DrawSprite( Pos + Vector(0,0,InvScale ^ 2 * 25) - Offset, Size, Size, Color( 255, 255, 255, 255) )
|
||||
end
|
||||
@@ -0,0 +1,119 @@
|
||||
|
||||
local GlowMat = Material( "sprites/light_glow02_add" )
|
||||
local Materials = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
self.Pos = data:GetOrigin()
|
||||
|
||||
self.LifeTime = 0.4
|
||||
self.DieTime = CurTime() + self.LifeTime
|
||||
|
||||
local emitter = ParticleEmitter( self.Pos, false )
|
||||
|
||||
if not IsValid( emitter ) then return end
|
||||
|
||||
for i = 0,30 do
|
||||
local particle = emitter:Add( Materials[ math.random(1, #Materials ) ], self.Pos )
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( VectorRand(-1,1) * 800 )
|
||||
particle:SetDieTime( math.Rand(4,6) )
|
||||
particle:SetAirResistance( math.Rand(200,600) )
|
||||
particle:SetStartAlpha( 100 )
|
||||
particle:SetStartSize( math.Rand(30,60) )
|
||||
particle:SetEndSize( math.Rand(100,150) )
|
||||
particle:SetRoll( math.Rand(-1,1) )
|
||||
particle:SetColor( 50,50,50 )
|
||||
particle:SetGravity( Vector( 0, 0, 100 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
for i = 0, 20 do
|
||||
local particle = emitter:Add( "sprites/light_glow02_add", self.Pos )
|
||||
|
||||
local vel = VectorRand() * 400
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( vel )
|
||||
particle:SetAngles( vel:Angle() + Angle(0,90,0) )
|
||||
particle:SetDieTime( math.Rand(0.4,0.8) )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetEndAlpha( 0 )
|
||||
particle:SetStartSize( math.Rand(24,48) )
|
||||
particle:SetEndSize( 0 )
|
||||
particle:SetRoll( math.Rand(-100,100) )
|
||||
particle:SetRollDelta( math.Rand(-100,100) )
|
||||
particle:SetColor( 255, 40, 100 )
|
||||
particle:SetGravity( Vector(0,0,-600) )
|
||||
|
||||
particle:SetAirResistance( 0 )
|
||||
|
||||
particle:SetCollide( true )
|
||||
particle:SetBounce( 0.5 )
|
||||
end
|
||||
end
|
||||
|
||||
for i = 0, 40 do
|
||||
local particle = emitter:Add( "effects/lvs_base/flamelet"..math.random(1,5), self.Pos )
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( VectorRand(-1,1) * 500 )
|
||||
particle:SetDieTime( 0.14 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 10 )
|
||||
particle:SetEndSize( math.Rand(30,60) )
|
||||
particle:SetEndAlpha( 100 )
|
||||
particle:SetRoll( math.Rand( -1, 1 ) )
|
||||
particle:SetColor( 200,150,150 )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
|
||||
local Pos = self.Pos
|
||||
local ply = LocalPlayer():GetViewEntity()
|
||||
if IsValid( ply ) then
|
||||
local delay = (Pos - ply:GetPos()):Length() / 13503.9
|
||||
if delay <= 0.11 then
|
||||
sound.Play( "ambient/explosions/explode_9.wav", Pos, 85, 100, 1 - delay * 8 )
|
||||
end
|
||||
|
||||
timer.Simple( delay, function()
|
||||
sound.Play( "LVS.MISSILE_EXPLOSION", Pos )
|
||||
end )
|
||||
else
|
||||
sound.Play( "LVS.MISSILE_EXPLOSION", Pos )
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if self.DieTime < CurTime() then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
local Scale = (self.DieTime - CurTime()) / self.LifeTime
|
||||
render.SetMaterial( GlowMat )
|
||||
render.DrawSprite( self.Pos, 400 * Scale, 400 * Scale, Color( 255, 40, 100, 255) )
|
||||
render.DrawSprite( self.Pos, 100 * Scale, 100 * Scale, Color( 255, 255, 255, 255) )
|
||||
end
|
||||
124
garrysmod/addons/lvs_base/lua/effects/lvs_concussion_trail.lua
Normal file
124
garrysmod/addons/lvs_base/lua/effects/lvs_concussion_trail.lua
Normal file
@@ -0,0 +1,124 @@
|
||||
EFFECT.Offset = Vector(-8,0,0)
|
||||
|
||||
local GlowMat = Material( "effects/select_ring" )
|
||||
local Materials = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
self.Entity = data:GetEntity()
|
||||
|
||||
if IsValid( self.Entity ) then
|
||||
self.OldPos = self.Entity:LocalToWorld( self.Offset )
|
||||
|
||||
self.Emitter = ParticleEmitter( self.Entity:LocalToWorld( self.OldPos ), false )
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:doFX( pos )
|
||||
if not IsValid( self.Entity ) then return end
|
||||
|
||||
if IsValid( self.Emitter ) then
|
||||
local emitter = self.Emitter
|
||||
|
||||
local particle = emitter:Add( Materials[ math.random(1, #Materials ) ], pos )
|
||||
if particle then
|
||||
particle:SetGravity( Vector(0,0,100) + VectorRand() * 50 )
|
||||
particle:SetVelocity( -self.Entity:GetForward() * 200 )
|
||||
particle:SetAirResistance( 600 )
|
||||
particle:SetDieTime( math.Rand(2,3) )
|
||||
particle:SetStartAlpha( 100 )
|
||||
particle:SetStartSize( math.Rand(5,6) )
|
||||
particle:SetEndSize( math.Rand(12,30) )
|
||||
particle:SetRoll( math.Rand( -1, 1 ) )
|
||||
particle:SetColor( 50,50,50 )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
local particle = emitter:Add( "effects/lvs_base/flamelet"..math.random(1,5), pos )
|
||||
if particle then
|
||||
particle:SetVelocity( -self.Entity:GetForward() * math.Rand(250,800) + self.Entity:GetVelocity())
|
||||
particle:SetDieTime( math.Rand(0.2,0.4) )
|
||||
particle:SetAirResistance( 0 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( math.Rand(10,15) )
|
||||
particle:SetEndSize( 5 )
|
||||
particle:SetRoll( math.Rand(-1,1) )
|
||||
particle:SetColor( 150,50,100 )
|
||||
particle:SetGravity( Vector( 0, 0, 0 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
local particle = emitter:Add( "effects/lvs_base/flamelet"..math.random(1,5), self.Entity:GetPos() )
|
||||
if particle then
|
||||
particle:SetVelocity( -self.Entity:GetForward() * 200 + VectorRand() * 50 )
|
||||
particle:SetDieTime( 0.25 )
|
||||
particle:SetAirResistance( 600 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( math.Rand(6,10) )
|
||||
particle:SetEndSize( math.Rand(2,3) )
|
||||
particle:SetRoll( math.Rand(-1,1) )
|
||||
particle:SetColor( 255,100,200 )
|
||||
particle:SetGravity( Vector( 0, 0, 0 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if IsValid( self.Entity ) then
|
||||
self.nextDFX = self.nextDFX or 0
|
||||
|
||||
if self.nextDFX < CurTime() then
|
||||
self.nextDFX = CurTime() + 0.02
|
||||
|
||||
local oldpos = self.OldPos
|
||||
local newpos = self.Entity:LocalToWorld( self.Offset )
|
||||
self:SetPos( newpos )
|
||||
|
||||
local Sub = (newpos - oldpos)
|
||||
local Dir = Sub:GetNormalized()
|
||||
local Len = Sub:Length()
|
||||
|
||||
self.OldPos = newpos
|
||||
|
||||
for i = 0, Len, 45 do
|
||||
local pos = oldpos + Dir * i
|
||||
|
||||
self:doFX( pos )
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
if IsValid( self.Emitter ) then
|
||||
self.Emitter:Finish()
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
local ent = self.Entity
|
||||
local pos = ent:LocalToWorld( self.Offset )
|
||||
|
||||
render.SetMaterial( GlowMat )
|
||||
|
||||
render.DrawSprite( pos, 100, 100, Color( 255, 40, 100, 50 ) )
|
||||
end
|
||||
182
garrysmod/addons/lvs_base/lua/effects/lvs_defence_explosion.lua
Normal file
182
garrysmod/addons/lvs_base/lua/effects/lvs_defence_explosion.lua
Normal file
@@ -0,0 +1,182 @@
|
||||
|
||||
EFFECT.GlowMat = Material( "sprites/light_glow02_add" )
|
||||
EFFECT.SmokeMat = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
EFFECT.DustMat = {
|
||||
"effects/lvs_base/particle_debris_01",
|
||||
"effects/lvs_base/particle_debris_02",
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local pos = data:GetOrigin()
|
||||
local dir = data:GetNormal()
|
||||
local scale = data:GetMagnitude()
|
||||
|
||||
self.LifeTime = 0.35
|
||||
self.DieTime = CurTime() + self.LifeTime
|
||||
|
||||
self.Pos = pos
|
||||
self.Scale = scale
|
||||
|
||||
sound.Play( "weapons/shotgun/shotgun_fire6.wav", pos, 75, 150, 1 )
|
||||
|
||||
local VecCol = (render.GetLightColor( pos + dir ) * 0.5 + Vector(0.2,0.18,0.15)) * 255
|
||||
|
||||
local emitter = ParticleEmitter( pos, false )
|
||||
|
||||
for i = 0,20 do
|
||||
local particle = emitter:Add( self.SmokeMat[ math.random(1,#self.SmokeMat) ] , pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( VectorRand() * 500 * scale )
|
||||
particle:SetDieTime( math.Rand(0.4,0.6) )
|
||||
particle:SetAirResistance( 500 )
|
||||
particle:SetStartAlpha( 100 )
|
||||
particle:SetStartSize( 40 * scale )
|
||||
particle:SetEndSize( 200 * scale )
|
||||
particle:SetRollDelta( math.Rand(-1,1) )
|
||||
particle:SetColor( math.min( VecCol.r, 255 ), math.min( VecCol.g, 255 ), math.min( VecCol.b, 255 ) )
|
||||
particle:SetGravity( Vector(0,0,1200) )
|
||||
particle:SetCollide( true )
|
||||
end
|
||||
|
||||
for i = 1,12 do
|
||||
local particle = emitter:Add( self.SmokeMat[ math.random(1,#self.SmokeMat) ] , pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
local ang = i * 30
|
||||
local X = math.cos( math.rad(ang) )
|
||||
local Y = math.sin( math.rad(ang) )
|
||||
|
||||
local Vel = Vector(X,Y,0) * 1000
|
||||
Vel:Rotate( dir:Angle() + Angle(90,0,0) )
|
||||
|
||||
particle:SetVelocity( Vel * scale )
|
||||
particle:SetDieTime( math.Rand(0.6,0.8) )
|
||||
particle:SetAirResistance( 500 )
|
||||
particle:SetStartAlpha( 100 )
|
||||
particle:SetStartSize( 30 * scale )
|
||||
particle:SetEndSize( 60 * scale )
|
||||
particle:SetRollDelta( math.Rand(-1,1) )
|
||||
particle:SetColor( math.min( VecCol.r, 255 ), math.min( VecCol.g, 255 ), math.min( VecCol.b, 255 ) )
|
||||
particle:SetGravity( Vector(0,0,600) )
|
||||
particle:SetCollide( true )
|
||||
end
|
||||
|
||||
for i = 0, 15 do
|
||||
local particle = emitter:Add( "effects/lvs_base/flamelet"..math.random(1,5), pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( VectorRand() * 400 * scale )
|
||||
particle:SetDieTime( math.Rand(0.2,0.3) )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetEndAlpha( 0 )
|
||||
particle:SetStartSize( 60 * scale )
|
||||
particle:SetEndSize( 10 * scale )
|
||||
particle:SetColor( 255, 255, 255 )
|
||||
particle:SetGravity( dir * 2500 )
|
||||
particle:SetRollDelta( math.Rand(-5,5) )
|
||||
particle:SetAirResistance( 300 )
|
||||
end
|
||||
|
||||
for i = 0, 5 do
|
||||
local particle = emitter:Add( "effects/lvs_base/flamelet"..math.random(1,5), pos)
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetEndAlpha( 0 )
|
||||
particle:SetColor( 255, 255, 255 )
|
||||
particle:SetGravity( Vector(0,0,0) )
|
||||
|
||||
local size = math.Rand(2, 12) * scale
|
||||
particle:SetEndSize( size )
|
||||
particle:SetStartSize( size )
|
||||
|
||||
particle:SetStartLength( 100 * scale )
|
||||
particle:SetEndLength( size )
|
||||
|
||||
particle:SetDieTime( math.Rand(0.1,0.2) )
|
||||
particle:SetVelocity( (dir * 2000 + VectorRand() * 1000) * scale )
|
||||
|
||||
particle:SetAirResistance( 0 )
|
||||
end
|
||||
|
||||
for i = 0, 40 do
|
||||
local particle = emitter:Add( "effects/fire_embers"..math.random(1,2), pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( VectorRand() * 400 * scale )
|
||||
particle:SetDieTime( math.Rand(0.4,0.6) )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetEndAlpha( 0 )
|
||||
particle:SetStartSize( 20 * scale )
|
||||
particle:SetEndSize( 0 )
|
||||
particle:SetColor( 255, 255, 255 )
|
||||
particle:SetGravity( Vector(0,0,600) )
|
||||
particle:SetRollDelta( math.Rand(-8,8) )
|
||||
particle:SetAirResistance( 300 )
|
||||
end
|
||||
|
||||
if dir.z > 0.8 then
|
||||
for i = 0,60 do
|
||||
local particle = emitter:Add( "effects/fleck_cement"..math.random(1,2), pos )
|
||||
local vel = dir * math.Rand(600,1000) + VectorRand() * 200
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( vel * scale )
|
||||
particle:SetDieTime( math.Rand(10,15) )
|
||||
particle:SetAirResistance( 10 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
|
||||
local size = math.Rand(2, 4) * scale
|
||||
particle:SetEndSize( size )
|
||||
particle:SetStartSize( size )
|
||||
|
||||
particle:SetRoll( math.Rand(-1,1) )
|
||||
particle:SetColor( math.min( VecCol.r, 255 ), math.min( VecCol.g, 255 ), math.min( VecCol.b, 255 ) )
|
||||
particle:SetGravity( Vector( 0, 0, -600 ) )
|
||||
particle:SetCollide( true )
|
||||
particle:SetBounce( 0.3 )
|
||||
end
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if self.DieTime < CurTime() then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
if not self.Scale then return end
|
||||
|
||||
local Scale = (self.DieTime - CurTime()) / self.LifeTime
|
||||
local R1 = 800 * self.Scale
|
||||
render.SetMaterial( self.GlowMat )
|
||||
render.DrawSprite( self.Pos, R1 * Scale, R1 * Scale, Color( 255, 200, 150, 255) )
|
||||
end
|
||||
56
garrysmod/addons/lvs_base/lua/effects/lvs_defence_smoke.lua
Normal file
56
garrysmod/addons/lvs_base/lua/effects/lvs_defence_smoke.lua
Normal file
@@ -0,0 +1,56 @@
|
||||
|
||||
EFFECT.MatSmoke = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local pos = data:GetOrigin()
|
||||
|
||||
local emitter = ParticleEmitter( pos, false )
|
||||
|
||||
if not emitter then return end
|
||||
|
||||
local VecCol = (render.GetLightColor( pos ) * 0.8 + Vector(0.2,0.2,0.2)) * 255
|
||||
|
||||
for i = 0,2 do
|
||||
local particle = emitter:Add( self.MatSmoke[math.random(1,#self.MatSmoke)], pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( VectorRand() * 200 )
|
||||
particle:SetDieTime( math.Rand(4,6) )
|
||||
particle:SetAirResistance( 250 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 0 )
|
||||
particle:SetEndSize( 650 )
|
||||
particle:SetRollDelta( math.Rand(-1,1) )
|
||||
particle:SetColor( math.min( VecCol.r, 255 ), math.min( VecCol.g, 255 ), math.min( VecCol.b, 255 ) )
|
||||
particle:SetGravity( VectorRand() * 600 )
|
||||
particle:SetCollide( true )
|
||||
particle:SetBounce( 1 )
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
end
|
||||
43
garrysmod/addons/lvs_base/lua/effects/lvs_downgrade.lua
Normal file
43
garrysmod/addons/lvs_base/lua/effects/lvs_downgrade.lua
Normal file
@@ -0,0 +1,43 @@
|
||||
|
||||
function EFFECT:Init( data )
|
||||
self.Ent = data:GetEntity()
|
||||
self.Pos = data:GetOrigin()
|
||||
|
||||
local T = CurTime()
|
||||
|
||||
self.LifeTime = 1
|
||||
self.DieTime = T + self.LifeTime
|
||||
|
||||
if IsValid( self.Ent ) then
|
||||
self.Model = ClientsideModel( self.Ent:GetModel(), RENDERMODE_TRANSCOLOR )
|
||||
self.Model:SetMaterial("models/alyx/emptool_glow")
|
||||
self.Model:SetColor( Color(255,0,0,255) )
|
||||
self.Model:SetParent( self.Ent, 0 )
|
||||
self.Model:SetMoveType( MOVETYPE_NONE )
|
||||
self.Model:SetLocalPos( Vector( 0, 0, 0 ) )
|
||||
self.Model:SetLocalAngles( Angle( 0, 0, 0 ) )
|
||||
self.Model:AddEffects( EF_BONEMERGE )
|
||||
self.Model:SetModelScale( self.Ent:GetModelScale() )
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if not IsValid( self.Ent ) then
|
||||
if IsValid( self.Model ) then
|
||||
self.Model:Remove()
|
||||
end
|
||||
end
|
||||
|
||||
if self.DieTime < CurTime() then
|
||||
if IsValid( self.Model ) then
|
||||
self.Model:Remove()
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
end
|
||||
@@ -0,0 +1,53 @@
|
||||
|
||||
local Materials = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local Pos = data:GetOrigin() + VectorRand() * 25
|
||||
local Ent = data:GetEntity()
|
||||
|
||||
if not IsValid( Ent ) then return end
|
||||
|
||||
local emitter = Ent:GetParticleEmitter( Pos )
|
||||
|
||||
if not IsValid( emitter ) then return end
|
||||
|
||||
local particle = emitter:Add( Materials[ math.random(1, #Materials ) ], Pos )
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( VectorRand() * 100 )
|
||||
particle:SetDieTime( 2 )
|
||||
particle:SetAirResistance( 600 )
|
||||
particle:SetStartAlpha( 50 )
|
||||
particle:SetStartSize( 60 )
|
||||
particle:SetEndSize( 200 )
|
||||
particle:SetRoll( math.Rand(-1,1) * math.pi )
|
||||
particle:SetRollDelta( math.Rand(-1,1) )
|
||||
particle:SetColor( 60, 60, 60 )
|
||||
particle:SetGravity( Vector( 0, 0, 600 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
end
|
||||
59
garrysmod/addons/lvs_base/lua/effects/lvs_exhaust.lua
Normal file
59
garrysmod/addons/lvs_base/lua/effects/lvs_exhaust.lua
Normal file
@@ -0,0 +1,59 @@
|
||||
|
||||
local Materials = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local Pos = data:GetOrigin()
|
||||
local Dir = data:GetNormal()
|
||||
local Ent = data:GetEntity()
|
||||
local Scale = data:GetMagnitude()
|
||||
|
||||
if not IsValid( Ent ) then return end
|
||||
|
||||
local Vel = Ent:GetVelocity()
|
||||
|
||||
local emitter = Ent:GetParticleEmitter( Pos )
|
||||
|
||||
if not IsValid( emitter ) then return end
|
||||
|
||||
local particle = emitter:Add( Materials[ math.random(1, #Materials ) ], Pos )
|
||||
|
||||
if not particle then return end
|
||||
|
||||
local Col = 100 - 60 * Scale
|
||||
|
||||
particle:SetVelocity( Vel + Dir * (100 + 50 * Scale) )
|
||||
particle:SetDieTime( 0.4 - 0.3 * Scale )
|
||||
particle:SetAirResistance( 400 )
|
||||
particle:SetStartAlpha( 80 )
|
||||
particle:SetStartSize( 2 )
|
||||
particle:SetEndSize( 10 + 20 * Scale )
|
||||
particle:SetRoll( math.Rand( -1, 1 ) )
|
||||
particle:SetRollDelta( math.Rand( -1, 1 ) * 2 )
|
||||
particle:SetColor( Col, Col, Col )
|
||||
particle:SetGravity( Vector( 0, 0, 10 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
end
|
||||
52
garrysmod/addons/lvs_base/lua/effects/lvs_exhaust_fire.lua
Normal file
52
garrysmod/addons/lvs_base/lua/effects/lvs_exhaust_fire.lua
Normal file
@@ -0,0 +1,52 @@
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local Pos = data:GetOrigin()
|
||||
local Dir = data:GetNormal()
|
||||
local Ent = data:GetEntity()
|
||||
local Scale = data:GetMagnitude()
|
||||
|
||||
if not IsValid( Ent ) then return end
|
||||
|
||||
local emitter = Ent:GetParticleEmitter( Pos )
|
||||
|
||||
if not IsValid( emitter ) then return end
|
||||
|
||||
local particle = emitter:Add( "effects/lvs_base/fire", Pos )
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( Dir * 70 )
|
||||
particle:SetDieTime( 0.2 )
|
||||
particle:SetAirResistance( 0 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 10 + 18 * Scale )
|
||||
particle:SetEndSize( 0 )
|
||||
particle:SetRoll( math.Rand(-1,1) * 180 )
|
||||
particle:SetColor( 255,255,255 )
|
||||
particle:SetGravity( Vector( 0, 0, 100 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
for i = 1, 3 do
|
||||
local particle = emitter:Add( "effects/lvs_base/flamelet"..math.random(1,5), Pos )
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( Dir * 40 * i )
|
||||
particle:SetDieTime( 0.2 )
|
||||
particle:SetAirResistance( 0 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( (5 + 5 * Scale) - i )
|
||||
particle:SetEndSize( 0 )
|
||||
particle:SetRoll( math.Rand(-1,1) * 180 )
|
||||
particle:SetColor( 255,255,255 )
|
||||
particle:SetGravity( Vector( 0, 0, 100 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
end
|
||||
178
garrysmod/addons/lvs_base/lua/effects/lvs_explosion.lua
Normal file
178
garrysmod/addons/lvs_base/lua/effects/lvs_explosion.lua
Normal file
@@ -0,0 +1,178 @@
|
||||
local Materials = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
EFFECT.DecalMat = Material( util.DecalMaterial( "Scorch" ) )
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local Pos = data:GetOrigin()
|
||||
|
||||
self.DieTime = CurTime() + 1
|
||||
|
||||
self:Explosion( Pos, 2 )
|
||||
|
||||
local ply = LocalPlayer():GetViewEntity()
|
||||
if IsValid( ply ) then
|
||||
local delay = (Pos - ply:GetPos()):Length() / 13503.9
|
||||
timer.Simple( delay, function()
|
||||
sound.Play( "LVS.DYNAMIC_EXPLOSION", Pos )
|
||||
end )
|
||||
else
|
||||
sound.Play( "LVS.DYNAMIC_EXPLOSION", Pos )
|
||||
end
|
||||
|
||||
for i = 1, 20 do
|
||||
timer.Simple(math.Rand(0,0.01) * i, function()
|
||||
if IsValid( self ) then
|
||||
local p = Pos + VectorRand() * 10 * i
|
||||
|
||||
self:Explosion( p, math.Rand(0.5,0.8) )
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
self:Debris( Pos )
|
||||
|
||||
local traceSky = util.TraceLine( {
|
||||
start = Pos,
|
||||
endpos = Pos + Vector(0,0,50000),
|
||||
mask = MASK_SOLID_BRUSHONLY,
|
||||
} )
|
||||
|
||||
local traceWater = util.TraceLine( {
|
||||
start = traceSky.HitPos,
|
||||
endpos = Pos - Vector(0,0,100),
|
||||
mask = MASK_WATER,
|
||||
} )
|
||||
|
||||
if traceWater.Hit then
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin( traceWater.HitPos )
|
||||
effectdata:SetScale( 100 )
|
||||
effectdata:SetFlags( 2 )
|
||||
util.Effect( "WaterSplash", effectdata, true, true )
|
||||
else
|
||||
local trace = util.TraceLine( {
|
||||
start = Pos + Vector(0,0,100),
|
||||
endpos = Pos - Vector(0,0,100),
|
||||
mask = MASK_SOLID_BRUSHONLY,
|
||||
} )
|
||||
|
||||
if trace.Hit and not trace.HitNonWorld then
|
||||
for i = 1, 10 do
|
||||
local StartPos = trace.HitPos + Vector(math.random(-25,25) * i,math.random(-25,25) * i,0)
|
||||
local decalTrace = util.TraceLine( {
|
||||
start = StartPos + Vector(0,0,100),
|
||||
endpos = StartPos - Vector(0,0,100),
|
||||
mask = MASK_SOLID_BRUSHONLY,
|
||||
} )
|
||||
|
||||
util.DecalEx( self.DecalMat, trace.Entity, decalTrace.HitPos + decalTrace.HitNormal, decalTrace.HitNormal, Color(255,255,255,255), math.Rand(2,3), math.Rand(2,3) )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:Debris( pos )
|
||||
local emitter = ParticleEmitter( pos, false )
|
||||
|
||||
if not IsValid( emitter ) then return end
|
||||
|
||||
for i = 0,60 do
|
||||
local particle = emitter:Add( "effects/fleck_tile"..math.random(1,2), pos )
|
||||
local vel = VectorRand() * math.Rand(200,600)
|
||||
vel.z = math.Rand(200,600)
|
||||
if particle then
|
||||
particle:SetVelocity( vel )
|
||||
particle:SetDieTime( math.Rand(10,15) )
|
||||
particle:SetAirResistance( 10 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 5 )
|
||||
particle:SetEndSize( 5 )
|
||||
particle:SetRoll( math.Rand(-1,1) )
|
||||
particle:SetColor( 0,0,0 )
|
||||
particle:SetGravity( Vector( 0, 0, -600 ) )
|
||||
particle:SetCollide( true )
|
||||
particle:SetBounce( 0.3 )
|
||||
end
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
end
|
||||
|
||||
function EFFECT:Explosion( pos , scale )
|
||||
local emitter = ParticleEmitter( pos, false )
|
||||
|
||||
if not IsValid( emitter ) then return end
|
||||
|
||||
for i = 0,10 do
|
||||
local particle = emitter:Add( Materials[ math.random(1, #Materials ) ], pos )
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( VectorRand() * 1500 * scale )
|
||||
particle:SetDieTime( math.Rand(0.75,1.5) * scale )
|
||||
particle:SetAirResistance( math.Rand(200,600) )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( math.Rand(60,120) * scale )
|
||||
particle:SetEndSize( math.Rand(220,320) * scale )
|
||||
particle:SetRoll( math.Rand(-1,1) )
|
||||
particle:SetColor( 40,40,40 )
|
||||
particle:SetGravity( Vector( 0, 0, 100 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
for i = 0, 40 do
|
||||
local particle = emitter:Add( "effects/lvs_base/flamelet"..math.random(1,5), pos )
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( VectorRand() * 1500 * scale )
|
||||
particle:SetDieTime( 0.2 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 20 * scale )
|
||||
particle:SetEndSize( math.Rand(180,240) * scale )
|
||||
particle:SetEndAlpha( 100 )
|
||||
particle:SetRoll( math.Rand( -1, 1 ) )
|
||||
particle:SetColor( 200,150,150 )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
|
||||
local dlight = DynamicLight( math.random(0,9999) )
|
||||
if dlight then
|
||||
dlight.pos = pos
|
||||
dlight.r = 255
|
||||
dlight.g = 180
|
||||
dlight.b = 100
|
||||
dlight.brightness = 8
|
||||
dlight.Decay = 2000
|
||||
dlight.Size = 300
|
||||
dlight.DieTime = CurTime() + 1
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if CurTime() < self.DieTime then return true end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
end
|
||||
297
garrysmod/addons/lvs_base/lua/effects/lvs_explosion_bomb.lua
Normal file
297
garrysmod/addons/lvs_base/lua/effects/lvs_explosion_bomb.lua
Normal file
@@ -0,0 +1,297 @@
|
||||
|
||||
EFFECT.GlowMat = Material( "sprites/light_glow02_add" )
|
||||
EFFECT.SmokeMat = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
EFFECT.DustMat = {
|
||||
"effects/lvs_base/particle_debris_01",
|
||||
"effects/lvs_base/particle_debris_02",
|
||||
}
|
||||
|
||||
EFFECT.DecalMat = Material( util.DecalMaterial( "Scorch" ) )
|
||||
|
||||
function EFFECT:Init( data )
|
||||
self.Dir = Vector(0,0,1)
|
||||
self.Pos = data:GetOrigin()
|
||||
self.LifeTime = 0.35
|
||||
self.DieTime = CurTime() + self.LifeTime
|
||||
|
||||
local scale = 3
|
||||
|
||||
local emitter = ParticleEmitter( self.Pos, false )
|
||||
|
||||
local VecCol = (render.GetLightColor( self.Pos + self.Dir ) * 0.5 + Vector(0.1,0.09,0.075)) * 255
|
||||
|
||||
local DieTime = math.Rand(0.8,1.6)
|
||||
|
||||
local traceSky = util.TraceLine( {
|
||||
start = self.Pos,
|
||||
endpos = self.Pos + Vector(0,0,50000),
|
||||
filter = self,
|
||||
} )
|
||||
|
||||
local traceWater = util.TraceLine( {
|
||||
start = traceSky.HitPos,
|
||||
endpos = self.Pos - Vector(0,0,100),
|
||||
filter = self,
|
||||
mask = MASK_WATER,
|
||||
} )
|
||||
|
||||
if traceWater.Hit then
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin( traceWater.HitPos )
|
||||
effectdata:SetScale( 100 )
|
||||
effectdata:SetFlags( 2 )
|
||||
util.Effect( "WaterSplash", effectdata, true, true )
|
||||
else
|
||||
local trace = util.TraceLine( {
|
||||
start = self.Pos + Vector(0,0,100),
|
||||
endpos = self.Pos - Vector(0,0,100),
|
||||
} )
|
||||
|
||||
if trace.Hit and not trace.HitNonWorld then
|
||||
for i = 1, 3 do
|
||||
local StartPos = trace.HitPos + Vector(math.random(-200,200),math.random(-200,200),0)
|
||||
local decalTrace = util.TraceLine( {
|
||||
start = StartPos + Vector(0,0,100),
|
||||
endpos = StartPos - Vector(0,0,100),
|
||||
} )
|
||||
|
||||
util.DecalEx( self.DecalMat, trace.Entity, decalTrace.HitPos + decalTrace.HitNormal, decalTrace.HitNormal, Color(255,255,255,255), math.Rand(3,6), math.Rand(3,6) )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local Pos = self.Pos
|
||||
local Dist = (traceWater.HitPos - Pos):Length()
|
||||
local ply = LocalPlayer():GetViewEntity()
|
||||
|
||||
if not IsValid( ply ) then return end
|
||||
|
||||
local delay = (Pos - ply:GetPos()):Length() / 13503.9
|
||||
|
||||
if traceWater.Hit and Dist > 150 then
|
||||
timer.Simple( delay, function()
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin( Pos )
|
||||
util.Effect( "WaterSurfaceExplosion", effectdata, true, true )
|
||||
end )
|
||||
|
||||
if Dist > 300 then return end
|
||||
else
|
||||
timer.Simple( delay, function()
|
||||
sound.Play( "LVS.BOMB_EXPLOSION", Pos )
|
||||
sound.Play( "LVS.BOMB_EXPLOSION_DYNAMIC", Pos )
|
||||
end )
|
||||
end
|
||||
|
||||
for i = 1, 10 do
|
||||
for n = 0,6 do
|
||||
local particle = emitter:Add( self.DustMat[ math.random(1,#self.DustMat) ], self.Pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( (self.Dir * 50 * i + VectorRand() * 25) * scale )
|
||||
particle:SetDieTime( (i / 8) * DieTime )
|
||||
particle:SetAirResistance( 10 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 10 * scale )
|
||||
particle:SetEndSize( 20 * i * scale )
|
||||
particle:SetRollDelta( math.Rand(-1,1) )
|
||||
particle:SetColor( VecCol.r, VecCol.g, VecCol.b )
|
||||
particle:SetGravity( Vector(0,0,-600) * scale )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, 10 do
|
||||
local particle = emitter:Add( self.SmokeMat[ math.random(1,#self.SmokeMat) ], self.Pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( (self.Dir * 50 * i + VectorRand() * 40) * scale )
|
||||
particle:SetDieTime( (i / 8) * DieTime )
|
||||
particle:SetAirResistance( 10 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 10 * scale )
|
||||
particle:SetEndSize( 20 * i * scale )
|
||||
particle:SetRollDelta( math.Rand(-1,1) )
|
||||
particle:SetColor( VecCol.r, VecCol.g, VecCol.b )
|
||||
particle:SetGravity( Vector(0,0,-600) * scale )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
for i = 1,24 do
|
||||
local particle = emitter:Add( self.SmokeMat[ math.random(1,#self.SmokeMat) ] , self.Pos )
|
||||
|
||||
if particle then
|
||||
local ang = i * 15
|
||||
local X = math.cos( math.rad(ang) )
|
||||
local Y = math.sin( math.rad(ang) )
|
||||
|
||||
local Vel = Vector(X,Y,0) * math.Rand(1500,2000)
|
||||
|
||||
particle:SetVelocity( Vel * scale )
|
||||
particle:SetDieTime( math.Rand(1,3) )
|
||||
particle:SetAirResistance( 600 )
|
||||
particle:SetStartAlpha( 100 )
|
||||
particle:SetStartSize( 40 * scale )
|
||||
particle:SetEndSize( 200 * scale )
|
||||
particle:SetRollDelta( math.Rand(-1,1) )
|
||||
particle:SetColor( VecCol.r, VecCol.g, VecCol.b )
|
||||
particle:SetGravity( Vector(0,0,60) * scale )
|
||||
particle:SetCollide( true )
|
||||
end
|
||||
end
|
||||
|
||||
for i = 0, 15 do
|
||||
local particle = emitter:Add( self.SmokeMat[ math.random(1, #self.SmokeMat ) ], self.Pos )
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( VectorRand(-1,1) * 1000 )
|
||||
particle:SetDieTime( math.Rand(2,3) )
|
||||
particle:SetAirResistance( 200 )
|
||||
particle:SetStartAlpha( 100 )
|
||||
particle:SetStartSize( 200 )
|
||||
particle:SetEndSize( 600 )
|
||||
particle:SetRoll( math.Rand(-1,1) )
|
||||
particle:SetRollDelta( math.Rand(-1,1) )
|
||||
particle:SetColor( VecCol.r, VecCol.g, VecCol.b )
|
||||
particle:SetGravity( Vector( 0, 0, -600 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
for i = 0, 15 do
|
||||
local particle = emitter:Add( "effects/lvs_base/flamelet"..math.random(1,5), self.Pos )
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( VectorRand(-1,1) * 500 )
|
||||
particle:SetDieTime( math.Rand(0.15,0.3) )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 25 )
|
||||
particle:SetEndSize( math.Rand(70,100) )
|
||||
particle:SetEndAlpha( 100 )
|
||||
particle:SetRoll( math.Rand( -1, 1 ) )
|
||||
particle:SetColor( 200,150,150 )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
for i = 0, 20 do
|
||||
local particle = emitter:Add( "sprites/rico1", self.Pos )
|
||||
|
||||
local vel = VectorRand() * 800
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( vel )
|
||||
particle:SetAngles( vel:Angle() + Angle(0,90,0) )
|
||||
particle:SetDieTime( math.Rand(0.2,0.4) )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetEndAlpha( 0 )
|
||||
particle:SetStartSize( math.Rand(20,40) )
|
||||
particle:SetEndSize( 0 )
|
||||
particle:SetRoll( math.Rand(-100,100) )
|
||||
particle:SetRollDelta( 0 )
|
||||
particle:SetColor( 255, 255, 255 )
|
||||
|
||||
particle:SetAirResistance( 0 )
|
||||
end
|
||||
end
|
||||
|
||||
for i = 0,60 do
|
||||
local particle = emitter:Add( "effects/fleck_tile"..math.random(1,2), self.Pos )
|
||||
local vel = VectorRand() * math.Rand(800,1600)
|
||||
vel.z = math.Rand(1000,4000)
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( vel )
|
||||
particle:SetDieTime( math.random(5,15) )
|
||||
particle:SetAirResistance( 10 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 5 )
|
||||
particle:SetEndSize( 5 )
|
||||
particle:SetRoll( math.Rand(-1,1) )
|
||||
particle:SetColor( 0,0,0 )
|
||||
particle:SetGravity( Vector( 0, 0, -2000 ) )
|
||||
particle:SetCollide( true )
|
||||
particle:SetBounce( 0.3 )
|
||||
end
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
end
|
||||
|
||||
function EFFECT:Explosion( pos , scale )
|
||||
local emitter = ParticleEmitter( pos, false )
|
||||
|
||||
if not IsValid( emitter ) then return end
|
||||
|
||||
for i = 0, 40 do
|
||||
local particle = emitter:Add( "effects/lvs_base/flamelet"..math.random(1,5), pos )
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( VectorRand() * 1500 * scale )
|
||||
particle:SetDieTime( 0.2 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 20 * scale )
|
||||
particle:SetEndSize( math.Rand(180,240) * scale )
|
||||
particle:SetEndAlpha( 100 )
|
||||
particle:SetRoll( math.Rand( -1, 1 ) )
|
||||
particle:SetColor( 200,150,150 )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
|
||||
local dlight = DynamicLight( math.random(0,9999) )
|
||||
if dlight then
|
||||
dlight.pos = pos
|
||||
dlight.r = 255
|
||||
dlight.g = 180
|
||||
dlight.b = 100
|
||||
dlight.brightness = 8
|
||||
dlight.Decay = 2000
|
||||
dlight.Size = 300
|
||||
dlight.DieTime = CurTime() + 1
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if self.DieTime < CurTime() then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
local Scale = (self.DieTime - CurTime()) / self.LifeTime
|
||||
render.SetMaterial( self.GlowMat )
|
||||
render.DrawSprite( self.Pos, 2000 * Scale, 2000 * Scale, Color( 255, 200, 150, 255) )
|
||||
|
||||
local Scale = (self.DieTime - self.LifeTime + 0.25 - CurTime()) / 0.25
|
||||
local InvScale = 1 - Scale
|
||||
if Scale > 0 then
|
||||
render.SetColorMaterial()
|
||||
render.DrawSphere( self.Pos, -450 * InvScale, 30,30, Color( 255, 200, 150, 150 * (Scale ^ 2) ) )
|
||||
render.DrawSphere( self.Pos, -500 * InvScale, 30,30, Color( 255, 200, 150, 100 * (Scale ^ 2) ) )
|
||||
render.DrawSphere( self.Pos, -550 * InvScale, 30,30, Color( 255, 200, 150, 25 * (Scale ^ 2) ) )
|
||||
render.DrawSphere( self.Pos, 600 * InvScale, 30,30, Color( 255, 200, 150, 25 * (Scale ^ 2) ) )
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,92 @@
|
||||
local Materials = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local Pos = data:GetOrigin()
|
||||
|
||||
self:Explosion( Pos, 2 )
|
||||
|
||||
local ply = LocalPlayer():GetViewEntity()
|
||||
if IsValid( ply ) then
|
||||
local delay = (Pos - ply:GetPos()):Length() / 13503.9
|
||||
timer.Simple( delay, function()
|
||||
sound.Play( "LVS.EXPLOSION", Pos )
|
||||
end )
|
||||
else
|
||||
sound.Play( "LVS.EXPLOSION", Pos )
|
||||
end
|
||||
|
||||
for i = 1, 20 do
|
||||
timer.Simple(math.Rand(0,0.01) * i, function()
|
||||
if not IsValid( self ) then return end
|
||||
|
||||
local p = Pos + VectorRand() * 10 * i
|
||||
|
||||
self:Explosion( p, math.Rand(0.5,0.8) )
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:Explosion( pos , scale )
|
||||
local emitter = ParticleEmitter( pos, false )
|
||||
|
||||
if not IsValid( emitter ) then return end
|
||||
|
||||
for i = 0,10 do
|
||||
local particle = emitter:Add( Materials[ math.random(1, #Materials ) ], pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( VectorRand() * 1000 * scale )
|
||||
particle:SetDieTime( math.Rand(0.75,1.5) * scale )
|
||||
particle:SetAirResistance( math.Rand(200,600) )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( math.Rand(60,120) * scale )
|
||||
particle:SetEndSize( math.Rand(160,280) * scale )
|
||||
particle:SetRoll( math.Rand(-1,1) )
|
||||
particle:SetColor( 40,40,40 )
|
||||
particle:SetGravity( Vector( 0, 0, 100 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
for i = 0, 40 do
|
||||
local particle = emitter:Add( "effects/lvs_base/flamelet"..math.random(1,5), pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( VectorRand() * 1000 * scale )
|
||||
particle:SetDieTime( 0.14 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 10 * scale )
|
||||
particle:SetEndSize( math.Rand(60,120) * scale )
|
||||
particle:SetEndAlpha( 100 )
|
||||
particle:SetRoll( math.Rand( -1, 1 ) )
|
||||
particle:SetColor( 200,150,150 )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
end
|
||||
112
garrysmod/addons/lvs_base/lua/effects/lvs_explosion_small.lua
Normal file
112
garrysmod/addons/lvs_base/lua/effects/lvs_explosion_small.lua
Normal file
@@ -0,0 +1,112 @@
|
||||
|
||||
local GlowMat = Material( "sprites/light_glow02_add" )
|
||||
local Materials = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
self.Pos = data:GetOrigin()
|
||||
self.LifeTime = 0.35
|
||||
self.DieTime = CurTime() + self.LifeTime
|
||||
|
||||
local emitter = ParticleEmitter( self.Pos, false )
|
||||
|
||||
for i = 0, 15 do
|
||||
local particle = emitter:Add( Materials[ math.random(1, #Materials ) ], self.Pos )
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( VectorRand(-1,1) * 1000 )
|
||||
particle:SetDieTime( math.Rand(2,3) )
|
||||
particle:SetAirResistance( math.Rand(200,600) )
|
||||
particle:SetStartAlpha( 200 )
|
||||
particle:SetStartSize( 120 )
|
||||
particle:SetEndSize( 300 )
|
||||
particle:SetRoll( math.Rand(-1,1) )
|
||||
particle:SetRollDelta( math.Rand(-1,1) )
|
||||
particle:SetColor( 50,50,50 )
|
||||
particle:SetGravity( Vector( 0, 0, 600 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
for i = 0, 15 do
|
||||
local particle = emitter:Add( "effects/lvs_base/flamelet"..math.random(1,5), self.Pos )
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( VectorRand(-1,1) * 500 )
|
||||
particle:SetDieTime( math.Rand(0.15,0.3) )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 25 )
|
||||
particle:SetEndSize( math.Rand(70,100) )
|
||||
particle:SetEndAlpha( 100 )
|
||||
particle:SetRoll( math.Rand( -1, 1 ) )
|
||||
particle:SetColor( 200,150,150 )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
for i = 0, 20 do
|
||||
local particle = emitter:Add( "sprites/rico1", self.Pos )
|
||||
|
||||
local vel = VectorRand() * 800
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( vel )
|
||||
particle:SetAngles( vel:Angle() + Angle(0,90,0) )
|
||||
particle:SetDieTime( math.Rand(0.2,0.4) )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetEndAlpha( 0 )
|
||||
particle:SetStartSize( math.Rand(20,40) )
|
||||
particle:SetEndSize( 0 )
|
||||
particle:SetRoll( math.Rand(-100,100) )
|
||||
particle:SetRollDelta( 0 )
|
||||
particle:SetColor( 255, 255, 255 )
|
||||
|
||||
particle:SetAirResistance( 0 )
|
||||
end
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
|
||||
local Pos = self.Pos
|
||||
local ply = LocalPlayer():GetViewEntity()
|
||||
if IsValid( ply ) then
|
||||
local delay = (Pos - ply:GetPos()):Length() / 13503.9
|
||||
if delay <= 0.11 then
|
||||
sound.Play( "ambient/explosions/explode_9.wav", Pos, 85, 100, 1 - delay * 8 )
|
||||
end
|
||||
|
||||
timer.Simple( delay, function()
|
||||
sound.Play( "LVS.MISSILE_EXPLOSION", Pos )
|
||||
end )
|
||||
else
|
||||
sound.Play( "LVS.MISSILE_EXPLOSION", Pos )
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if self.DieTime < CurTime() then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
local Scale = (self.DieTime - CurTime()) / self.LifeTime
|
||||
render.SetMaterial( GlowMat )
|
||||
render.DrawSprite( self.Pos, 2000 * Scale, 2000 * Scale, Color( 255, 200, 150, 255) )
|
||||
end
|
||||
111
garrysmod/addons/lvs_base/lua/effects/lvs_firetrail.lua
Normal file
111
garrysmod/addons/lvs_base/lua/effects/lvs_firetrail.lua
Normal file
@@ -0,0 +1,111 @@
|
||||
|
||||
local Materials = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
self.Entity = data:GetEntity()
|
||||
self.Scale = data:GetScale()
|
||||
self.DieTime = CurTime() + data:GetMagnitude()
|
||||
self.Pos = data:GetStart()
|
||||
|
||||
if not IsValid( self.Entity ) then return end
|
||||
|
||||
self.Emitter = ParticleEmitter( self.Entity:LocalToWorld( self.Pos ), false )
|
||||
end
|
||||
|
||||
|
||||
function EFFECT:Think()
|
||||
if IsValid( self.Entity ) then
|
||||
local Pos = self.Entity:LocalToWorld( self.Pos )
|
||||
|
||||
local T = CurTime()
|
||||
|
||||
if (self.nextDFX or 0) < T then
|
||||
self.nextDFX = T + 0.05
|
||||
|
||||
if self.Emitter then
|
||||
local particle = self.Emitter:Add( Materials[ math.random(1, #Materials ) ], Pos )
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( VectorRand() * 100 * self.Scale )
|
||||
particle:SetDieTime( 3 )
|
||||
particle:SetAirResistance( 0 )
|
||||
particle:SetStartAlpha( 150 )
|
||||
particle:SetStartSize( 150 * self.Scale )
|
||||
particle:SetEndSize( math.Rand(200,300) * self.Scale )
|
||||
particle:SetRoll( math.Rand(-1,1) * 100 )
|
||||
particle:SetColor( 40,40,40 )
|
||||
particle:SetGravity( Vector( 0, 0, 0 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
local particle = self.Emitter:Add( "effects/lvs_base/fire", Pos )
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( VectorRand() * 100 * self.Scale )
|
||||
particle:SetDieTime( math.random(40,80) / 100 )
|
||||
particle:SetAirResistance( 0 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 130 * self.Scale )
|
||||
particle:SetEndSize( math.Rand(50,100) * self.Scale )
|
||||
particle:SetRoll( math.Rand(-1,1) * 180 )
|
||||
particle:SetColor( 255,255,255 )
|
||||
particle:SetGravity( Vector( 0, 0, 70 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
for i = 0,3 do
|
||||
local particle = self.Emitter:Add( "effects/lvs_base/flamelet"..math.random(1,5), Pos + VectorRand() * 100 * self.Scale )
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( VectorRand() * 100 * self.Scale )
|
||||
particle:SetDieTime( math.random(30,60) / 100 )
|
||||
particle:SetAirResistance( 0 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 70 * self.Scale )
|
||||
particle:SetEndSize( math.Rand(25,80) * self.Scale )
|
||||
particle:SetRoll( math.Rand(-1,1) * 180 )
|
||||
particle:SetColor( 255,255,255 )
|
||||
particle:SetGravity( Vector( 0, 0, 40 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if self.DieTime < CurTime() then
|
||||
if self.Emitter then
|
||||
self.Emitter:Finish()
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
if self.Emitter then
|
||||
self.Emitter:Finish()
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
end
|
||||
415
garrysmod/addons/lvs_base/lua/effects/lvs_flamestream.lua
Normal file
415
garrysmod/addons/lvs_base/lua/effects/lvs_flamestream.lua
Normal file
@@ -0,0 +1,415 @@
|
||||
|
||||
local GlowMat = Material( "sprites/light_glow02_add" )
|
||||
local FireMat = Material( "effects/fire_cloud1" )
|
||||
local HeatMat = Material( "sprites/heatwave" )
|
||||
local Materials = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
self.Entity = data:GetEntity()
|
||||
|
||||
if not IsValid( self.Entity ) then return end
|
||||
|
||||
local Pos = self:GetPos()
|
||||
|
||||
self._Particles = {}
|
||||
self.Emitter = ParticleEmitter( Pos, false )
|
||||
self.Emitter3D = ParticleEmitter( Pos, true )
|
||||
self._LastParticlePos = vector_origin
|
||||
end
|
||||
|
||||
function EFFECT:AddParticle( particle )
|
||||
table.insert( self._Particles, particle )
|
||||
|
||||
for id, particle in pairs( self._Particles ) do
|
||||
if not particle or particle:GetLifeTime() > particle:GetDieTime() then
|
||||
self._Particles[ id ] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:GetPosition()
|
||||
local ent = self.Entity
|
||||
|
||||
if not IsValid( ent ) then return vector_origin, vector_origin end
|
||||
|
||||
local Pos = ent:GetPos()
|
||||
local Dir = ent:GetForward()
|
||||
|
||||
local Target = ent:GetTarget()
|
||||
local Attachment = ent:GetTargetAttachment()
|
||||
|
||||
if IsValid( Target ) and Attachment ~= "" then
|
||||
local ID = Target:LookupAttachment( Attachment )
|
||||
local Muzzle = Target:GetAttachment( ID )
|
||||
|
||||
if not Muzzle then return vector_origin, vector_origin end
|
||||
|
||||
Pos = Muzzle.Pos
|
||||
Dir = Muzzle.Ang:Forward()
|
||||
end
|
||||
|
||||
return Pos, Dir
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
local ent = self.Entity
|
||||
local emitter = self.Emitter
|
||||
local emitter3D = self.Emitter3D
|
||||
|
||||
if not IsValid( emitter ) or not IsValid( emitter3D ) then return true end
|
||||
|
||||
local T = CurTime()
|
||||
|
||||
if IsValid( ent ) and not self._KillSwitch then
|
||||
if not ent:GetActive() then
|
||||
self._KillSwitch = true
|
||||
self._KillSwitchTime = CurTime() + 2
|
||||
end
|
||||
|
||||
if (self.nextDFX or 0) < T then
|
||||
self.nextDFX = T + 0.01
|
||||
|
||||
local Pos, Dir = self:GetPosition()
|
||||
|
||||
self:MakeFlameStream( emitter, emitter3D, Pos, Dir )
|
||||
self:MakeFlameMuzzle( emitter, emitter3D, Pos, Dir )
|
||||
self:SetRenderBoundsWS( Pos, Pos + Dir * 50000 )
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
if self._KillSwitch and IsValid( emitter ) and IsValid( emitter3D ) then
|
||||
if self._KillSwitchTime > T then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
if emitter then
|
||||
emitter:Finish()
|
||||
end
|
||||
|
||||
if emitter3D then
|
||||
emitter3D:Finish()
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:MakeFlameImpact( Pos, Dir, Size )
|
||||
local emitter3D = self.Emitter3D
|
||||
|
||||
if not IsValid( emitter3D ) then return end
|
||||
|
||||
local hitparticle = emitter3D:Add( "effects/lvs_base/flamelet"..math.random(1,5), Pos + Dir )
|
||||
if hitparticle then
|
||||
hitparticle:SetStartSize( Size * 0.25 )
|
||||
hitparticle:SetEndSize( Size )
|
||||
hitparticle:SetDieTime( math.Rand(0.5,1) )
|
||||
hitparticle:SetStartAlpha( 255 )
|
||||
hitparticle:SetEndAlpha( 0 )
|
||||
hitparticle:SetRollDelta( math.Rand(-2,2) )
|
||||
hitparticle:SetAngles( Dir:Angle() )
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:MakeFlameImpactWater( Pos, Dir, Size )
|
||||
local emitter3D = self.Emitter3D
|
||||
local emitter = self.Emitter
|
||||
|
||||
if not IsValid( emitter ) or not IsValid( emitter3D ) then return end
|
||||
|
||||
local sparticle = emitter:Add( Materials[ math.random(1, #Materials ) ], Pos )
|
||||
if sparticle then
|
||||
sparticle:SetVelocity( Vector(0,0,400) + VectorRand() * 100 )
|
||||
sparticle:SetDieTime( Size * 0.01 )
|
||||
sparticle:SetAirResistance( 500 )
|
||||
sparticle:SetStartAlpha( 40 )
|
||||
sparticle:SetStartSize( 0 )
|
||||
sparticle:SetEndSize( Size * 4 )
|
||||
sparticle:SetRoll( math.Rand(-3,3) )
|
||||
sparticle:SetRollDelta( math.Rand(-1,1) )
|
||||
sparticle:SetColor( 255, 255, 255 )
|
||||
sparticle:SetGravity( Vector( 0, 0, 800 ) )
|
||||
sparticle:SetCollide( false )
|
||||
end
|
||||
|
||||
local hitparticle = emitter3D:Add( "effects/lvs_base/flamelet"..math.random(1,5), Pos + Dir )
|
||||
if hitparticle then
|
||||
hitparticle:SetStartSize( Size * 0.25 )
|
||||
hitparticle:SetEndSize( Size )
|
||||
hitparticle:SetDieTime( math.Rand(0.5,1) )
|
||||
hitparticle:SetStartAlpha( 255 )
|
||||
hitparticle:SetEndAlpha( 0 )
|
||||
hitparticle:SetRollDelta( math.Rand(-2,2) )
|
||||
hitparticle:SetAngles( Dir:Angle() )
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:MakeFlameBurst( Pos, Vel, Size )
|
||||
local emitter = self.Emitter
|
||||
|
||||
if not IsValid( emitter ) then return end
|
||||
|
||||
local fparticle = emitter:Add( "effects/lvs_base/fire", Pos )
|
||||
if fparticle then
|
||||
fparticle:SetVelocity( VectorRand() * 15 + Vector( 0, 0, 200 ) + Vel )
|
||||
fparticle:SetDieTime( math.Rand(0.6,0.8) )
|
||||
fparticle:SetAirResistance( 0 )
|
||||
|
||||
fparticle:SetStartAlpha( 255 )
|
||||
fparticle:SetEndAlpha( 255 )
|
||||
|
||||
fparticle:SetStartSize( 40 )
|
||||
fparticle:SetEndSize( 0 )
|
||||
|
||||
fparticle:SetRollDelta( math.Rand(-2,2) )
|
||||
fparticle:SetColor( 255,255,255 )
|
||||
fparticle:SetGravity( Vector( 0, 0, 0 ) )
|
||||
fparticle:SetCollide( false )
|
||||
|
||||
self:AddParticle( fparticle )
|
||||
end
|
||||
|
||||
local fparticle = emitter:Add( "effects/lvs_base/flamelet"..math.random(1,5), Pos )
|
||||
if fparticle then
|
||||
fparticle:SetVelocity( VectorRand() * 25 + Vel )
|
||||
fparticle:SetDieTime( math.Rand(0.4,0.8) )
|
||||
fparticle:SetStartAlpha( 150 )
|
||||
fparticle:SetEndAlpha( 0 )
|
||||
fparticle:SetStartSize( 0 )
|
||||
fparticle:SetEndSize( math.Rand(60,120) )
|
||||
fparticle:SetColor( 255, 255, 255 )
|
||||
fparticle:SetGravity( Vector(0,0,100) )
|
||||
fparticle:SetRollDelta( math.Rand(-2,2) )
|
||||
fparticle:SetAirResistance( 0 )
|
||||
end
|
||||
|
||||
for i = 0, 6 do
|
||||
local eparticle = emitter:Add( "effects/fire_embers"..math.random(1,2), Pos )
|
||||
|
||||
if not eparticle then continue end
|
||||
|
||||
eparticle:SetVelocity( VectorRand() * 400 + Vel )
|
||||
eparticle:SetDieTime( math.Rand(0.4,0.6) )
|
||||
eparticle:SetStartAlpha( 255 )
|
||||
eparticle:SetEndAlpha( 0 )
|
||||
eparticle:SetStartSize( 20 )
|
||||
eparticle:SetEndSize( 0 )
|
||||
eparticle:SetColor( 255, 255, 255 )
|
||||
eparticle:SetGravity( Vector(0,0,600) )
|
||||
eparticle:SetRollDelta( math.Rand(-8,8) )
|
||||
eparticle:SetAirResistance( 300 )
|
||||
end
|
||||
|
||||
local Dist = (self._LastParticlePos - Pos):Length()
|
||||
self._LastParticlePos = Pos
|
||||
|
||||
if Dist < 250 then
|
||||
if math.random(1,8) ~= 1 then return end
|
||||
end
|
||||
|
||||
local sparticle = emitter:Add( Materials[ math.random(1, #Materials ) ], Pos )
|
||||
if sparticle then
|
||||
sparticle:SetVelocity( Vector(0,0,400) + Vel )
|
||||
sparticle:SetDieTime( math.Rand(2,4) * Size )
|
||||
sparticle:SetAirResistance( 500 )
|
||||
sparticle:SetStartAlpha( 125 )
|
||||
sparticle:SetStartSize( 0 )
|
||||
sparticle:SetEndSize( 200 * Size )
|
||||
sparticle:SetRoll( math.Rand(-3,3) )
|
||||
sparticle:SetRollDelta( math.Rand(-1,1) )
|
||||
sparticle:SetColor( 0, 0, 0 )
|
||||
sparticle:SetGravity( Vector( 0, 0, 800 ) )
|
||||
sparticle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:MakeFlameMuzzle( emitter, emitter3D, pos, dir )
|
||||
local particle = emitter:Add( "effects/lvs_base/flamelet"..math.random(1,5), pos )
|
||||
|
||||
if not particle then return end
|
||||
|
||||
local ent = self.Entity
|
||||
|
||||
if not IsValid( ent ) then return end
|
||||
|
||||
local velDesired = ent:GetFlameVelocity()
|
||||
local vel = dir * velDesired
|
||||
|
||||
local DieTime = 0.075
|
||||
|
||||
particle:SetVelocity( VectorRand() * 30 + vel )
|
||||
particle:SetDieTime( DieTime )
|
||||
particle:SetAirResistance( 0 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetEndLength( velDesired * 0.1 )
|
||||
particle:SetStartLength( velDesired * 0.04 )
|
||||
particle:SetStartSize( 10 )
|
||||
particle:SetEndSize( 0 )
|
||||
particle:SetRollDelta( math.Rand(-5,5) )
|
||||
particle:SetColor( 50, 50, 255 )
|
||||
particle:SetGravity( Vector( 0, 0, -600 ) )
|
||||
particle:SetCollide( true )
|
||||
end
|
||||
|
||||
function EFFECT:MakeFlameStream( emitter, emitter3D, pos, dir )
|
||||
local particle = emitter:Add( "effects/lvs_base/flamelet"..math.random(1,5), pos )
|
||||
|
||||
if not particle then return end
|
||||
|
||||
local ent = self.Entity
|
||||
|
||||
if not IsValid( ent ) then return end
|
||||
|
||||
local velDesired = ent:GetFlameVelocity()
|
||||
local vel = dir * velDesired
|
||||
|
||||
local DieTime = math.Rand( ent:GetFlameLifeTime() * 0.5, ent:GetFlameLifeTime() )
|
||||
|
||||
particle:SetVelocity( VectorRand() * 30 + vel )
|
||||
particle:SetDieTime( DieTime )
|
||||
particle:SetAirResistance( 0 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetEndLength( velDesired * 0.1 )
|
||||
particle:SetStartLength( velDesired * 0.04 )
|
||||
particle:SetStartSize( 2 )
|
||||
particle:SetEndSize( ent:GetFlameSize() )
|
||||
particle:SetRollDelta( math.Rand(-5,5) )
|
||||
particle:SetColor( 255, 255, 255 )
|
||||
particle:SetGravity( Vector( 0, 0, -600 ) )
|
||||
particle:SetCollide( true )
|
||||
local Delay = math.Rand( DieTime * 0.5, DieTime )
|
||||
local Size = (Delay / DieTime) ^ 2
|
||||
timer.Simple( Delay, function()
|
||||
if not IsValid( self ) or not particle or particle.NoSmokeSpawn then return end
|
||||
|
||||
local ParticlePos = particle:GetPos()
|
||||
|
||||
self:MakeFlameBurst( ParticlePos, vel * 0.2, Size )
|
||||
end)
|
||||
particle:SetNextThink( CurTime() )
|
||||
particle:SetThinkFunction( function( p )
|
||||
if not IsValid( self ) then return end
|
||||
|
||||
p:SetNextThink( CurTime() + 0.05 )
|
||||
|
||||
local pos = p:GetPos()
|
||||
local vel = p:GetVelocity()
|
||||
local dir = vel:GetNormalized()
|
||||
local speed = vel:Length() * 0.06
|
||||
|
||||
local traceData = {
|
||||
start = pos,
|
||||
endpos = pos + dir * speed,
|
||||
filter = self.Entity,
|
||||
}
|
||||
local trace = util.TraceLine( traceData )
|
||||
|
||||
traceData.mask = MASK_WATER
|
||||
local traceWater = util.TraceLine( traceData )
|
||||
|
||||
if traceWater.Hit and not trace.Hit then
|
||||
p:SetDieTime( 0 )
|
||||
p.NoSmokeSpawn = true
|
||||
local RandomSize = math.Rand(60,80)
|
||||
self:MakeFlameImpactWater( traceWater.HitPos, traceWater.HitNormal, RandomSize )
|
||||
end
|
||||
|
||||
if trace.HitWorld or not trace.Hit then return end
|
||||
|
||||
p:SetDieTime( 0 )
|
||||
p.NoSmokeSpawn = true
|
||||
local RandomSize = math.Rand(40,60)
|
||||
self:MakeFlameImpact( trace.HitPos, trace.HitNormal, RandomSize )
|
||||
self:MakeFlameBurst( trace.HitPos, vector_origin, RandomSize / 60 )
|
||||
end )
|
||||
particle:SetCollideCallback( function( p, hitpos, hitnormal )
|
||||
if p.NoSmokeSpawn then return end
|
||||
|
||||
p:SetDieTime( 0 )
|
||||
p.NoSmokeSpawn = true
|
||||
|
||||
if not IsValid( emitter3D ) then return end
|
||||
|
||||
local RandomSize = math.Rand(40,60)
|
||||
|
||||
self:MakeFlameImpact( hitpos, hitnormal, RandomSize )
|
||||
self:MakeFlameBurst( hitpos + hitnormal, vector_origin, RandomSize / 60 )
|
||||
end )
|
||||
|
||||
particle.NoFade = true
|
||||
self:AddParticle( particle )
|
||||
|
||||
local particle = emitter:Add( "effects/lvs_base/fire", pos )
|
||||
if particle then
|
||||
particle:SetVelocity( VectorRand() * 4 + dir * math.Rand(velDesired * 0.8,velDesired * 1.6) )
|
||||
particle:SetDieTime( math.Rand(0.75,1.5) )
|
||||
particle:SetAirResistance( 40 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 4 )
|
||||
particle:SetEndSize( 0 )
|
||||
particle:SetRoll( math.Rand(-3,3) )
|
||||
particle:SetRollDelta( math.Rand(-6,6) )
|
||||
particle:SetColor( 255, 255, 255 )
|
||||
particle:SetGravity( VectorRand() * 400 - Vector(0,0,600) )
|
||||
particle:SetCollide( true )
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
local ent = self.Entity
|
||||
|
||||
if not IsValid( ent ) then return end
|
||||
|
||||
if ent:GetActive() and not self._KillSwitch then
|
||||
local Scale = 1
|
||||
local Pos, Dir = self:GetPosition()
|
||||
|
||||
local scroll = -CurTime() * 5
|
||||
|
||||
local Up = Dir + VectorRand() * 0.08
|
||||
|
||||
render.UpdateRefractTexture()
|
||||
render.SetMaterial( HeatMat )
|
||||
render.StartBeam( 3 )
|
||||
render.AddBeam( Pos, 8 * Scale, scroll, Color( 0, 0, 255, 200 ) )
|
||||
render.AddBeam( Pos + Up * 32 * Scale, 32 * Scale, scroll + 2, color_white )
|
||||
render.AddBeam( Pos + Up * 128 * Scale, 32 * Scale, scroll + 5, Color( 0, 0, 0, 0 ) )
|
||||
render.EndBeam()
|
||||
end
|
||||
|
||||
if not istable( self._Particles ) then return end
|
||||
|
||||
for id, particle in pairs( self._Particles ) do
|
||||
if not particle then continue end
|
||||
|
||||
local S = particle:GetLifeTime() / particle:GetDieTime()
|
||||
local A = ((1 - S) ^ 2) * 0.5
|
||||
local Size = particle:GetStartSize() * A * 8
|
||||
|
||||
if particle.NoFade then
|
||||
Size = particle:GetEndSize() * S * 8
|
||||
end
|
||||
|
||||
render.SetMaterial( GlowMat )
|
||||
render.DrawSprite( particle:GetPos(), Size, Size, Color( 255 * A, 150 * A, 75 * A, 255 * A) )
|
||||
end
|
||||
end
|
||||
112
garrysmod/addons/lvs_base/lua/effects/lvs_flamestream_finish.lua
Normal file
112
garrysmod/addons/lvs_base/lua/effects/lvs_flamestream_finish.lua
Normal file
@@ -0,0 +1,112 @@
|
||||
|
||||
local GlowMat = Material( "sprites/light_glow02_add" )
|
||||
local FireMat = Material( "effects/fire_cloud1" )
|
||||
local HeatMat = Material( "sprites/heatwave" )
|
||||
local Materials = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
self.Entity = data:GetEntity()
|
||||
self.LifeTime = data:GetMagnitude() * 4
|
||||
self.DieTime = CurTime() + self.LifeTime
|
||||
|
||||
if not IsValid( self.Entity ) then return end
|
||||
|
||||
local Pos, Dir = self:GetPosition()
|
||||
|
||||
self.Emitter = ParticleEmitter( Pos, false )
|
||||
self:SetRenderBoundsWS( Pos, Pos + Dir * 50000 )
|
||||
end
|
||||
|
||||
function EFFECT:GetPosition()
|
||||
local ent = self.Entity
|
||||
|
||||
if not IsValid( ent ) then return vector_origin, vector_origin end
|
||||
|
||||
local Pos = ent:GetPos()
|
||||
local Dir = ent:GetForward()
|
||||
|
||||
local Target = ent:GetTarget()
|
||||
local Attachment = ent:GetTargetAttachment()
|
||||
|
||||
if IsValid( Target ) and Attachment ~= "" then
|
||||
local ID = Target:LookupAttachment( Attachment )
|
||||
local Muzzle = Target:GetAttachment( ID )
|
||||
|
||||
if not Muzzle then return vector_origin, vector_origin end
|
||||
|
||||
Pos = Muzzle.Pos
|
||||
Dir = Muzzle.Ang:Forward()
|
||||
end
|
||||
|
||||
return Pos, Dir
|
||||
end
|
||||
|
||||
function EFFECT:DoSmoke( emitter, pos, dir )
|
||||
|
||||
local Scale = (self.DieTime - CurTime()) / self.LifeTime
|
||||
|
||||
local particle = emitter:Add( Materials[ math.random(1, #Materials ) ], pos )
|
||||
|
||||
if not particle then return end
|
||||
|
||||
particle:SetVelocity( dir * 20 )
|
||||
particle:SetDieTime( math.Rand(0.8,1.2) )
|
||||
particle:SetAirResistance( 400 )
|
||||
particle:SetStartAlpha( 50 * Scale )
|
||||
particle:SetStartSize( 2 )
|
||||
particle:SetEndSize( 20 )
|
||||
particle:SetRoll( math.Rand( -2, 2 ) )
|
||||
particle:SetRollDelta( math.Rand( -2, 2 ) )
|
||||
particle:SetColor( 0, 0, 0 )
|
||||
particle:SetGravity( Vector( 0, 0, 100 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
local ent = self.Entity
|
||||
local emitter = self.Emitter
|
||||
|
||||
local T = CurTime()
|
||||
|
||||
if IsValid( ent ) and (self.DieTime or 0) > T then
|
||||
if (self.nextDFX or 0) < T then
|
||||
self.nextDFX = T + 0.01
|
||||
|
||||
local Pos, Dir = self:GetPosition()
|
||||
|
||||
if not ent:GetActive() and math.random(1,6) == 1 then
|
||||
self:DoSmoke( emitter, Pos, Dir )
|
||||
end
|
||||
|
||||
self:SetRenderBoundsWS( Pos, Pos + Dir * 50000 )
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
if emitter then
|
||||
emitter:Finish()
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
end
|
||||
186
garrysmod/addons/lvs_base/lua/effects/lvs_flamestream_start.lua
Normal file
186
garrysmod/addons/lvs_base/lua/effects/lvs_flamestream_start.lua
Normal file
@@ -0,0 +1,186 @@
|
||||
|
||||
local GlowMat = Material( "sprites/light_glow02_add" )
|
||||
local FireMat = Material( "effects/fire_cloud1" )
|
||||
local HeatMat = Material( "sprites/heatwave" )
|
||||
local Materials = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
self.Entity = data:GetEntity()
|
||||
self.LifeTime = data:GetMagnitude()
|
||||
self.DieTime = CurTime() + self.LifeTime
|
||||
|
||||
if not IsValid( self.Entity ) then return end
|
||||
|
||||
local Pos, Dir = self:GetPosition()
|
||||
|
||||
self.Emitter = ParticleEmitter( Pos, false )
|
||||
self:SetRenderBoundsWS( Pos, Pos + Dir * 50000 )
|
||||
|
||||
local Pos, Dir = self:GetPosition()
|
||||
|
||||
for i = 1,10 do
|
||||
self:MakeFlameStream( self.Emitter, self.Entity, Pos, Dir )
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:GetPosition()
|
||||
local ent = self.Entity
|
||||
|
||||
if not IsValid( ent ) then return vector_origin, vector_origin end
|
||||
|
||||
local Pos = ent:GetPos()
|
||||
local Dir = ent:GetForward()
|
||||
|
||||
local Target = ent:GetTarget()
|
||||
local Attachment = ent:GetTargetAttachment()
|
||||
|
||||
if IsValid( Target ) and Attachment ~= "" then
|
||||
local ID = Target:LookupAttachment( Attachment )
|
||||
local Muzzle = Target:GetAttachment( ID )
|
||||
|
||||
if not Muzzle then return vector_origin, vector_origin end
|
||||
|
||||
Pos = Muzzle.Pos
|
||||
Dir = Muzzle.Ang:Forward()
|
||||
end
|
||||
|
||||
return Pos, Dir
|
||||
end
|
||||
|
||||
function EFFECT:MakeFlameStream( emitter, ent, pos, dir )
|
||||
local vel = ent:GetTargetVelocity()
|
||||
local Alpha = 100 - vel:Length() / 2
|
||||
|
||||
if Alpha > 1 then
|
||||
local particle = emitter:Add( Materials[ math.random(1, #Materials ) ], pos )
|
||||
if particle then
|
||||
particle:SetVelocity( VectorRand() * 60 + dir * 200 )
|
||||
particle:SetDieTime( math.Rand(0.8,1.2) )
|
||||
particle:SetAirResistance( 400 )
|
||||
particle:SetStartAlpha( Alpha )
|
||||
particle:SetStartSize( 2 )
|
||||
particle:SetEndSize( 20 )
|
||||
particle:SetRoll( math.Rand( -2, 2 ) )
|
||||
particle:SetRollDelta( math.Rand( -2, 2 ) )
|
||||
particle:SetColor( 0, 0, 0 )
|
||||
particle:SetGravity( Vector( 0, 0, 100 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
local particle = emitter:Add( "effects/lvs_base/fire", pos )
|
||||
if particle then
|
||||
particle:SetVelocity( VectorRand() * 60 + dir * math.Rand(100,200) + vel )
|
||||
particle:SetDieTime( math.Rand(0.75,1.5) )
|
||||
particle:SetAirResistance( 40 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 1 )
|
||||
particle:SetEndSize( 0 )
|
||||
particle:SetRoll( math.Rand(-3,3) )
|
||||
particle:SetRollDelta( math.Rand(-6,6) )
|
||||
particle:SetColor( 255, 255, 255 )
|
||||
particle:SetGravity( Vector(0,0,-600) )
|
||||
particle:SetCollide( true )
|
||||
end
|
||||
|
||||
local particle = emitter:Add( "effects/lvs_base/fire", pos )
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( dir * 70 + vel )
|
||||
particle:SetDieTime( 0.2 )
|
||||
particle:SetAirResistance( 0 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 5 )
|
||||
particle:SetEndSize( 0 )
|
||||
particle:SetRoll( math.Rand(-1,1) * 180 )
|
||||
particle:SetColor( 255,255,255 )
|
||||
particle:SetGravity( Vector( 0, 0, 100 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
local particle = emitter:Add( "effects/lvs_base/flamelet"..math.random(1,5), pos )
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( dir * 40 + vel )
|
||||
particle:SetDieTime( 0.2 )
|
||||
particle:SetAirResistance( 0 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 2 )
|
||||
particle:SetEndSize( 0 )
|
||||
particle:SetRoll( math.Rand(-1,1) * 180 )
|
||||
particle:SetColor( 255,255,255 )
|
||||
particle:SetGravity( Vector( 0, 0, 100 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
local ent = self.Entity
|
||||
local emitter = self.Emitter
|
||||
|
||||
local T = CurTime()
|
||||
|
||||
if IsValid( ent ) and (self.DieTime or 0) > T then
|
||||
if (self.nextDFX or 0) < T then
|
||||
self.nextDFX = T + 0.01
|
||||
|
||||
local Pos, Dir = self:GetPosition()
|
||||
|
||||
self:SetRenderBoundsWS( Pos, Pos + Dir * 50000 )
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
if emitter then
|
||||
emitter:Finish()
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
local ent = self.Entity
|
||||
|
||||
if not IsValid( ent ) then return end
|
||||
|
||||
local Scale = (self.DieTime - CurTime()) / self.LifeTime
|
||||
local invScaleExp = (1 - Scale) ^ 2
|
||||
|
||||
local Pos, Dir = self:GetPosition()
|
||||
|
||||
local scroll = -CurTime() * 5
|
||||
|
||||
local Up = Dir + VectorRand() * 0.08
|
||||
|
||||
render.UpdateRefractTexture()
|
||||
render.SetMaterial( HeatMat )
|
||||
render.StartBeam( 3 )
|
||||
render.AddBeam( Pos, 8 * invScaleExp, scroll, Color( 0, 0, 255, 200 ) )
|
||||
render.AddBeam( Pos + Up * 32 * invScaleExp, 32 * invScaleExp, scroll + 2, color_white )
|
||||
render.AddBeam( Pos + Up * 128 * invScaleExp, 32 * invScaleExp, scroll + 5, Color( 0, 0, 0, 0 ) )
|
||||
render.EndBeam()
|
||||
|
||||
local A = Scale ^ 2
|
||||
local Size = Scale * 64
|
||||
|
||||
render.SetMaterial( GlowMat )
|
||||
render.DrawSprite( Pos, Size, Size, Color( 255 * A, 150 * A, 75 * A, 255 * A) )
|
||||
end
|
||||
123
garrysmod/addons/lvs_base/lua/effects/lvs_haubitze_muzzle.lua
Normal file
123
garrysmod/addons/lvs_base/lua/effects/lvs_haubitze_muzzle.lua
Normal file
@@ -0,0 +1,123 @@
|
||||
EFFECT.MatBeam = Material( "effects/lvs_base/spark" )
|
||||
EFFECT.MatSprite = Material( "sprites/light_glow02_add" )
|
||||
EFFECT.MatSmoke = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local Pos = data:GetOrigin()
|
||||
local Dir = data:GetNormal()
|
||||
local Ent = data:GetEntity()
|
||||
local Vel = Dir * 10
|
||||
|
||||
if IsValid( Ent ) then
|
||||
Vel = Ent:GetVelocity()
|
||||
end
|
||||
|
||||
local emitter = ParticleEmitter( Pos, false )
|
||||
|
||||
if not IsValid( emitter ) then return end
|
||||
|
||||
for i = 0, 12 do
|
||||
local particle = emitter:Add( "effects/muzzleflash2", Pos + Dir * i * 0.7 * math.random(1,2) * 0.5 )
|
||||
local Size = 1
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( Dir * 800 + Vel )
|
||||
particle:SetDieTime( 0.05 )
|
||||
particle:SetStartAlpha( 255 * Size )
|
||||
particle:SetStartSize( math.max( math.random(10,24) - i * 0.5,0.1 ) * Size )
|
||||
particle:SetEndSize( 0 )
|
||||
particle:SetRoll( math.Rand( -1, 1 ) )
|
||||
particle:SetColor( 255, 255, 255 )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
local VecCol = (render.GetLightColor( Pos ) * 0.8 + Vector(0.2,0.2,0.2)) * 255
|
||||
for i = 0,10 do
|
||||
local particle = emitter:Add( self.MatSmoke[math.random(1,#self.MatSmoke)], Pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( Dir * 700 + VectorRand() * 200 )
|
||||
particle:SetDieTime( math.Rand(2,3) )
|
||||
particle:SetAirResistance( 250 )
|
||||
particle:SetStartAlpha( 50 )
|
||||
particle:SetStartSize( 5 )
|
||||
particle:SetEndSize( 120 )
|
||||
particle:SetRollDelta( math.Rand(-1,1) )
|
||||
particle:SetColor( math.min( VecCol.r, 255 ), math.min( VecCol.g, 255 ), math.min( VecCol.b, 255 ) )
|
||||
particle:SetGravity( Vector(0,0,100) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
local trace = util.TraceLine( {
|
||||
start = Pos,
|
||||
endpos = Pos - Vector(0,0,500),
|
||||
mask = MASK_SOLID_BRUSHONLY,
|
||||
} )
|
||||
|
||||
if not trace.Hit then return end
|
||||
|
||||
local VecCol = (render.GetLightColor( trace.HitPos + trace.HitNormal ) * 0.8 + Vector(0.17,0.15,0.1)) * 255
|
||||
for i = 1,24 do
|
||||
local particle = emitter:Add( self.MatSmoke[math.random(1,#self.MatSmoke)], trace.HitPos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
local ang = i * 15
|
||||
local X = math.cos( math.rad(ang) )
|
||||
local Y = math.sin( math.rad(ang) )
|
||||
|
||||
particle:SetVelocity( Vector(X,Y,0) * 3000 )
|
||||
particle:SetDieTime( math.Rand(0.5,1) )
|
||||
particle:SetAirResistance( 500 )
|
||||
particle:SetStartAlpha( 100 )
|
||||
particle:SetStartSize( 50 )
|
||||
particle:SetEndSize( 240 )
|
||||
particle:SetRollDelta( math.Rand(-1,1) )
|
||||
particle:SetColor( math.min( VecCol.r, 255 ), math.min( VecCol.g, 255 ), math.min( VecCol.b, 255 ) )
|
||||
particle:SetGravity( Vector(0,0,150) + Dir * 2000 )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
|
||||
local ply = LocalPlayer()
|
||||
|
||||
if not IsValid( ply ) then return end
|
||||
|
||||
local ViewEnt = ply:GetViewEntity()
|
||||
|
||||
if not IsValid( ViewEnt ) then return end
|
||||
|
||||
local Intensity = 16
|
||||
local Ratio = math.min( 250 / (ViewEnt:GetPos() - trace.HitPos):Length(), 1 )
|
||||
|
||||
if Ratio < 0 then return end
|
||||
|
||||
util.ScreenShake( trace.HitPos, Intensity * Ratio, 0.1, 0.5, 250 )
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
end
|
||||
108
garrysmod/addons/lvs_base/lua/effects/lvs_haubitze_trail.lua
Normal file
108
garrysmod/addons/lvs_base/lua/effects/lvs_haubitze_trail.lua
Normal file
@@ -0,0 +1,108 @@
|
||||
local MatBeam = Material( "effects/lvs_base/spark" )
|
||||
local GlowMat = Material( "sprites/light_glow02_add" )
|
||||
local Materials = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
self.Entity = data:GetEntity()
|
||||
|
||||
if IsValid( self.Entity ) then
|
||||
self.OldPos = self.Entity:GetPos()
|
||||
|
||||
self.Emitter = ParticleEmitter( self.Entity:LocalToWorld( self.OldPos ), false )
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:doFX( pos )
|
||||
if not IsValid( self.Entity ) then return end
|
||||
|
||||
if IsValid( self.Emitter ) then
|
||||
local emitter = self.Emitter
|
||||
|
||||
local VecCol = (render.GetLightColor( pos ) * 0.8 + Vector(0.2,0.2,0.2)) * 255
|
||||
|
||||
local particle = emitter:Add( Materials[ math.random(1, #Materials ) ], pos )
|
||||
if particle then
|
||||
particle:SetVelocity( -self.Entity:GetForward() * 1500 + VectorRand() * 10 )
|
||||
particle:SetDieTime( math.Rand(0.05,1) )
|
||||
particle:SetAirResistance( 250 )
|
||||
particle:SetStartAlpha( 100 )
|
||||
particle:SetEndAlpha( 0 )
|
||||
|
||||
particle:SetStartSize( 0 )
|
||||
particle:SetEndSize( 30 )
|
||||
|
||||
particle:SetRollDelta( 1 )
|
||||
particle:SetColor( math.min( VecCol.r, 255 ), math.min( VecCol.g, 255 ), math.min( VecCol.b, 255 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if IsValid( self.Entity ) then
|
||||
self.nextDFX = self.nextDFX or 0
|
||||
|
||||
if self.nextDFX < CurTime() then
|
||||
self.nextDFX = CurTime() + 0.02
|
||||
|
||||
local oldpos = self.OldPos
|
||||
local newpos = self.Entity:GetPos()
|
||||
self:SetPos( newpos )
|
||||
|
||||
local Sub = (newpos - oldpos)
|
||||
local Dir = Sub:GetNormalized()
|
||||
local Len = Sub:Length()
|
||||
|
||||
self.OldPos = newpos
|
||||
|
||||
for i = 0, Len, 45 do
|
||||
local pos = oldpos + Dir * i
|
||||
|
||||
self:doFX( pos )
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
if IsValid( self.Emitter ) then
|
||||
self.Emitter:Finish()
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
local ent = self.Entity
|
||||
|
||||
if not IsValid( ent ) then return end
|
||||
|
||||
local pos = ent:GetPos()
|
||||
local dir = ent:GetForward()
|
||||
|
||||
local len = 250
|
||||
|
||||
render.SetMaterial( MatBeam )
|
||||
render.DrawBeam( pos - dir * len, pos + dir * len * 0.1, 32, 1, 0, Color( 100, 100, 100, 100 ) )
|
||||
render.DrawBeam( pos - dir * len * 0.5, pos + dir * len * 0.1, 16, 1, 0, Color( 255, 255, 255, 255 ) )
|
||||
|
||||
render.SetMaterial( GlowMat )
|
||||
render.DrawSprite( pos, 250, 250, Color( 100, 100, 100, 255 ) )
|
||||
end
|
||||
67
garrysmod/addons/lvs_base/lua/effects/lvs_hover_water.lua
Normal file
67
garrysmod/addons/lvs_base/lua/effects/lvs_hover_water.lua
Normal file
@@ -0,0 +1,67 @@
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local Pos = data:GetOrigin()
|
||||
local Ent = data:GetEntity()
|
||||
self.Size = data:GetMagnitude()
|
||||
|
||||
if not IsValid( Ent ) then return end
|
||||
|
||||
self.LifeTime = math.Rand(1.5,3)
|
||||
self.DieTime = CurTime() + self.LifeTime
|
||||
|
||||
local LightColor = render.GetLightColor( Pos )
|
||||
local VecCol = Vector(1,1.2,1.4) * (0.06 + (0.2126 * LightColor.r) + (0.7152 * LightColor.g) + (0.0722 * LightColor.b)) * 1000
|
||||
VecCol.x = math.min( VecCol.x, 255 )
|
||||
VecCol.y = math.min( VecCol.y, 255 )
|
||||
VecCol.z = math.min( VecCol.z, 255 )
|
||||
|
||||
self.Splash = {
|
||||
Pos = Pos,
|
||||
Mat = Material("effects/splashwake1"),
|
||||
RandomAng = math.random(0,360),
|
||||
Color = VecCol,
|
||||
}
|
||||
|
||||
local emitter = Ent:GetParticleEmitter( Ent:GetPos() )
|
||||
|
||||
if emitter and emitter.Add then
|
||||
local particle = emitter:Add( "effects/splash4", Pos )
|
||||
if not particle then return end
|
||||
|
||||
local Vel = Ent:GetVelocity():Length()
|
||||
|
||||
particle:SetVelocity( Vector(0,0,math.Clamp(Vel / 2,100,250)) )
|
||||
particle:SetDieTime( 0.25 + math.min(Vel / 200,0.35) )
|
||||
particle:SetAirResistance( 60 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetEndAlpha( 0 )
|
||||
particle:SetStartSize( self.Size * 0.2 )
|
||||
particle:SetEndSize( self.Size * 2 )
|
||||
particle:SetRoll( math.Rand(-1,1) * 100 )
|
||||
particle:SetColor( VecCol.r, VecCol.g, VecCol.b )
|
||||
particle:SetGravity( Vector( 0, 0, -600 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function EFFECT:Think()
|
||||
if CurTime() > self.DieTime then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
if self.Splash and self.LifeTime then
|
||||
local Scale = ((self.DieTime - self.LifeTime - CurTime()) / self.LifeTime)
|
||||
local S = self.Size * 5 + (self.Size * 5) * Scale
|
||||
local Alpha = 100 + 100 * Scale
|
||||
|
||||
cam.Start3D2D( self.Splash.Pos + Vector(0,0,1), Angle(0,0,0), 1 )
|
||||
surface.SetMaterial( self.Splash.Mat )
|
||||
surface.SetDrawColor( self.Splash.Color.r, self.Splash.Color.g, self.Splash.Color.b, Alpha )
|
||||
surface.DrawTexturedRectRotated( 0, 0, S , S, self.Splash.RandomAng )
|
||||
cam.End3D2D()
|
||||
end
|
||||
end
|
||||
121
garrysmod/addons/lvs_base/lua/effects/lvs_hsd_dish_projector.lua
Normal file
121
garrysmod/addons/lvs_base/lua/effects/lvs_hsd_dish_projector.lua
Normal file
@@ -0,0 +1,121 @@
|
||||
EFFECT.Mat = Material( "effects/lvs/ballturret_projectorbeam" )
|
||||
EFFECT.HitMat = Material( "sprites/light_glow02_add" )
|
||||
|
||||
function EFFECT:Init( data )
|
||||
self.Entity = data:GetEntity()
|
||||
|
||||
if IsValid( self.Entity ) then
|
||||
self.ID = self.Entity:LookupAttachment( "muzzle_primary" )
|
||||
|
||||
if self.ID then
|
||||
local Muzzle = self.Entity:GetAttachment( self.ID )
|
||||
|
||||
self:SetRenderBoundsWS( self.Entity:GetPos(), -Muzzle.Ang:Right() * 50000 )
|
||||
end
|
||||
end
|
||||
|
||||
self.SpawnTime = CurTime()
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if not IsValid( self.Entity ) or not self.ID or not self.Entity:GetProjectorBeam() then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
if not self.ID or not IsValid( self.Entity ) then return end
|
||||
|
||||
local T = CurTime()
|
||||
|
||||
local Mul = math.min( math.max( 1.5 - (T - self.SpawnTime), 0 ) ^ 2, 1 )
|
||||
|
||||
local Muzzle = self.Entity:GetAttachment( self.ID )
|
||||
|
||||
local Dir = -Muzzle.Ang:Right()
|
||||
local StartPos = Muzzle.Pos
|
||||
local Trace = util.TraceLine( { start = StartPos, endpos = StartPos + Dir * 50000, filter = self } )
|
||||
local EndPos = Trace.HitPos
|
||||
|
||||
self:SetRenderBoundsWS( StartPos, EndPos )
|
||||
|
||||
render.SetMaterial( self.Mat )
|
||||
render.DrawBeam( StartPos, EndPos, (16 + math.random(0,3)) * Mul, 1, 0, Color(255,0,0,255) )
|
||||
render.DrawBeam( StartPos, EndPos, (4 + math.random(0,2)) * Mul, 1, 0, Color(255,255,255,255) )
|
||||
|
||||
render.SetMaterial( self.HitMat )
|
||||
local A = 150 + math.random(0,20)
|
||||
local B = 70 + math.random(0,20)
|
||||
render.DrawSprite( StartPos, A * Mul, A * Mul, Color(255,0,0,255) )
|
||||
render.DrawSprite( StartPos, B * Mul, B * Mul, Color(255,255,255,255) )
|
||||
|
||||
render.DrawSprite( EndPos, A, A, Color(255,0,0,255) )
|
||||
render.DrawSprite( EndPos + VectorRand() * 10, B, B, Color(255,255,255,255) )
|
||||
|
||||
if (self._Next or 0) > T then return end
|
||||
|
||||
self._Next = T + 0.02
|
||||
|
||||
local emitter = ParticleEmitter( EndPos, false )
|
||||
|
||||
if not emitter or not IsValid( emitter ) then return end
|
||||
|
||||
local dir = (self.Entity:GetPos() - EndPos):GetNormalized()
|
||||
|
||||
for i = 0, 3 do
|
||||
local particle = emitter:Add( "sprites/light_glow02_add", EndPos )
|
||||
|
||||
local vel = VectorRand() * 250 + Trace.HitNormal
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( vel )
|
||||
particle:SetAngles( vel:Angle() + Angle(0,90,0) )
|
||||
particle:SetDieTime( math.Rand(0.2,0.4) )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetEndAlpha( 0 )
|
||||
particle:SetStartSize( math.Rand(12,24) )
|
||||
particle:SetEndSize( 0 )
|
||||
particle:SetRoll( math.Rand(-100,100) )
|
||||
particle:SetRollDelta( math.Rand(-100,100) )
|
||||
particle:SetColor( 255, 0, 0 )
|
||||
particle:SetGravity( Vector(0,0,-600) )
|
||||
|
||||
particle:SetAirResistance( 0 )
|
||||
|
||||
particle:SetCollide( true )
|
||||
particle:SetBounce( 1 )
|
||||
end
|
||||
|
||||
local Dist = (StartPos - EndPos):Length()
|
||||
|
||||
local invMul = (1 - Mul)
|
||||
|
||||
for i = 0, Dist, 25 do
|
||||
local Pos = StartPos + Dir * i
|
||||
|
||||
local particle = emitter:Add( "sprites/rico1", Pos )
|
||||
|
||||
local vel = VectorRand() * 150
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( vel + vel * invMul )
|
||||
particle:SetDieTime( 0.1 + 0.15 * invMul )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetEndAlpha( 0 )
|
||||
particle:SetStartSize( math.Rand( 1, 5 ) + invMul * 2 )
|
||||
particle:SetEndSize( 0 )
|
||||
particle:SetColor( 50 + 205 * Mul, 0, 0 )
|
||||
particle:SetAirResistance( 0 )
|
||||
particle:SetRoll( math.Rand(-10,10) )
|
||||
particle:SetRollDelta( math.Rand(-10,10) )
|
||||
particle:SetGravity( Vector(0,0,-600 * invMul) )
|
||||
|
||||
particle:SetAirResistance( 0 )
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
end
|
||||
@@ -0,0 +1,78 @@
|
||||
EFFECT.Mat = Material( "effects/lvs/ballturret_projectorbeam" )
|
||||
EFFECT.HitMat = Material( "sprites/light_glow02_add" )
|
||||
|
||||
function EFFECT:Init( data )
|
||||
self.Entity = data:GetEntity()
|
||||
|
||||
if IsValid( self.Entity ) then
|
||||
self.ID = self.Entity:LookupAttachment( "muzzle_ballturret_left" )
|
||||
|
||||
if self.ID then
|
||||
local Muzzle = self.Entity:GetAttachment( self.ID )
|
||||
|
||||
self:SetRenderBoundsWS( self.Entity:GetPos(), Muzzle.Ang:Up() * 50000 )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if not IsValid( self.Entity ) or not self.ID or not self.Entity:GetBTLFire() then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
function EFFECT:Render()
|
||||
if not self.ID or not IsValid( self.Entity ) then return end
|
||||
|
||||
local Muzzle = self.Entity:GetAttachment( self.ID )
|
||||
|
||||
local Dir = Muzzle.Ang:Up()
|
||||
local StartPos = Muzzle.Pos + Dir * 14
|
||||
local Trace = util.TraceLine( { start = StartPos, endpos = StartPos + Dir * 50000, filter = self } )
|
||||
local EndPos = Trace.HitPos
|
||||
|
||||
self:SetRenderBoundsWS( StartPos, EndPos )
|
||||
|
||||
render.SetMaterial( self.Mat )
|
||||
render.DrawBeam( StartPos, EndPos, 14 + math.random(0,4), 1, 0, Color(0,255,0,255) )
|
||||
render.DrawBeam( StartPos, EndPos, 3 + math.random(0,4), 1, 0, Color(255,255,255,255) )
|
||||
|
||||
render.SetMaterial( self.HitMat )
|
||||
local A = 150 + math.random(0,20)
|
||||
local B = 70 + math.random(0,20)
|
||||
render.DrawSprite( StartPos, A, A, Color(0,255,0,255) )
|
||||
render.DrawSprite( StartPos, B, B, Color(255,255,255,255) )
|
||||
|
||||
render.DrawSprite( EndPos, A, A, Color(0,255,0,255) )
|
||||
render.DrawSprite( EndPos + VectorRand() * 10, B, B, Color(255,255,255,255) )
|
||||
|
||||
if math.random(0,5) == 1 then
|
||||
local emitter = ParticleEmitter( EndPos, false )
|
||||
local dir = (self.Entity:GetPos() - EndPos):GetNormalized()
|
||||
|
||||
for i = 0, 10 do
|
||||
local particle = emitter:Add( "sprites/rico1", EndPos )
|
||||
|
||||
local vel = VectorRand() * 100 + dir * 40
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( vel )
|
||||
particle:SetAngles( vel:Angle() + Angle(0,90,0) )
|
||||
particle:SetDieTime( math.Rand(0.1,0.3) * 0.5 )
|
||||
particle:SetStartAlpha( math.Rand( 200, 255 ) )
|
||||
particle:SetEndAlpha( 0 )
|
||||
particle:SetStartSize( math.Rand(1,30) )
|
||||
particle:SetEndSize( 0 )
|
||||
particle:SetRoll( math.Rand(-100,100) )
|
||||
particle:SetRollDelta( math.Rand(-100,100) )
|
||||
|
||||
particle:SetAirResistance( 0 )
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,78 @@
|
||||
EFFECT.Mat = Material( "effects/lvs/ballturret_projectorbeam" )
|
||||
EFFECT.HitMat = Material( "sprites/light_glow02_add" )
|
||||
|
||||
function EFFECT:Init( data )
|
||||
self.Entity = data:GetEntity()
|
||||
|
||||
if IsValid( self.Entity ) then
|
||||
self.ID = self.Entity:LookupAttachment( "muzzle_ballturret_right" )
|
||||
|
||||
if self.ID then
|
||||
local Muzzle = self.Entity:GetAttachment( self.ID )
|
||||
|
||||
self:SetRenderBoundsWS( self.Entity:GetPos(), Muzzle.Ang:Up() * 50000 )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if not IsValid( self.Entity ) or not self.ID or not self.Entity:GetBTRFire() then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
function EFFECT:Render()
|
||||
if not self.ID or not IsValid( self.Entity ) then return end
|
||||
|
||||
local Muzzle = self.Entity:GetAttachment( self.ID )
|
||||
|
||||
local Dir = Muzzle.Ang:Up()
|
||||
local StartPos = Muzzle.Pos + Dir * 14
|
||||
local Trace = util.TraceLine( { start = StartPos, endpos = StartPos + Dir * 50000, filter = self } )
|
||||
local EndPos = Trace.HitPos
|
||||
|
||||
self:SetRenderBoundsWS( StartPos, EndPos )
|
||||
|
||||
render.SetMaterial( self.Mat )
|
||||
render.DrawBeam( StartPos, EndPos, 14 + math.random(0,4), 1, 0, Color(0,255,0,255) )
|
||||
render.DrawBeam( StartPos, EndPos, 3 + math.random(0,4), 1, 0, Color(255,255,255,255) )
|
||||
|
||||
render.SetMaterial( self.HitMat )
|
||||
local A = 150 + math.random(0,20)
|
||||
local B = 70 + math.random(0,20)
|
||||
render.DrawSprite( StartPos, A, A, Color(0,255,0,255) )
|
||||
render.DrawSprite( StartPos, B, B, Color(255,255,255,255) )
|
||||
|
||||
render.DrawSprite( EndPos, A, A, Color(0,255,0,255) )
|
||||
render.DrawSprite( EndPos + VectorRand() * 10, B, B, Color(255,255,255,255) )
|
||||
|
||||
if math.random(0,5) == 1 then
|
||||
local emitter = ParticleEmitter( EndPos, false )
|
||||
local dir = (self.Entity:GetPos() - EndPos):GetNormalized()
|
||||
|
||||
for i = 0, 10 do
|
||||
local particle = emitter:Add( "sprites/rico1", EndPos )
|
||||
|
||||
local vel = VectorRand() * 100 + dir * 40
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( vel )
|
||||
particle:SetAngles( vel:Angle() + Angle(0,90,0) )
|
||||
particle:SetDieTime( math.Rand(0.1,0.3) * 0.5 )
|
||||
particle:SetStartAlpha( math.Rand( 200, 255 ) )
|
||||
particle:SetEndAlpha( 0 )
|
||||
particle:SetStartSize( math.Rand(1,30) )
|
||||
particle:SetEndSize( 0 )
|
||||
particle:SetRoll( math.Rand(-100,100) )
|
||||
particle:SetRollDelta( math.Rand(-100,100) )
|
||||
|
||||
particle:SetAirResistance( 0 )
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,82 @@
|
||||
EFFECT.Mat = Material( "effects/lvs/ballturret_projectorbeam" )
|
||||
EFFECT.HitMat = Material( "sprites/light_glow02_add" )
|
||||
|
||||
function EFFECT:Init( data )
|
||||
self.Entity = data:GetEntity()
|
||||
|
||||
self.StartPos = Vector(-172.97,334.04,93.25)
|
||||
self.EndPos = self.Entity:GetWingTurretTarget()
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if not IsValid( self.Entity ) or not self.Entity:GetWingTurretFire() then
|
||||
return false
|
||||
end
|
||||
|
||||
self.EndPosDesired = self.Entity:GetWingTurretTarget()
|
||||
self:SetRenderBoundsWS( self.Entity:GetPos(), self.EndPosDesired )
|
||||
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
if not self.EndPosDesired then return end
|
||||
|
||||
self.EndPos = self.EndPos + (self.EndPosDesired - self.EndPos) * FrameTime() * 10
|
||||
|
||||
for i = -1,1,2 do
|
||||
local StartPos = self.Entity:LocalToWorld( self.StartPos * Vector(1,i,1) )
|
||||
|
||||
local Trace = util.TraceLine( { start = StartPos, endpos = self.EndPos} )
|
||||
local EndPos = Trace.HitPos
|
||||
|
||||
if self.Entity:WorldToLocal( EndPos ).z < 0 then
|
||||
self.StartPos = Vector(-172.97,334.04,93.25)
|
||||
else
|
||||
self.StartPos = Vector(-174.79,350.05,125.98)
|
||||
end
|
||||
|
||||
if Trace.Entity == self.Entity then continue end
|
||||
|
||||
render.SetMaterial( self.Mat )
|
||||
render.DrawBeam( StartPos, EndPos, 14 + math.random(0,4), 1, 0, Color(0,255,0,255) )
|
||||
render.DrawBeam( StartPos, EndPos, 3 + math.random(0,4), 1, 0, Color(255,255,255,255) )
|
||||
|
||||
render.SetMaterial( self.HitMat )
|
||||
local A = 150 + math.random(0,20)
|
||||
local B = 70 + math.random(0,20)
|
||||
render.DrawSprite( StartPos, A, A, Color(0,255,0,255) )
|
||||
render.DrawSprite( StartPos, B, B, Color(255,255,255,255) )
|
||||
|
||||
render.DrawSprite( EndPos, A, A, Color(0,255,0,255) )
|
||||
render.DrawSprite( EndPos + VectorRand() * 10, B, B, Color(255,255,255,255) )
|
||||
|
||||
if math.random(0,5) == 1 then
|
||||
local emitter = ParticleEmitter( EndPos, false )
|
||||
local dir = (self.Entity:GetPos() - EndPos):GetNormalized()
|
||||
|
||||
for i = 0, 10 do
|
||||
local particle = emitter:Add( "sprites/rico1", EndPos )
|
||||
|
||||
local vel = VectorRand() * 100 + dir * 40
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( vel )
|
||||
particle:SetAngles( vel:Angle() + Angle(0,90,0) )
|
||||
particle:SetDieTime( math.Rand(0.1,0.3) * 0.5 )
|
||||
particle:SetStartAlpha( math.Rand( 200, 255 ) )
|
||||
particle:SetEndAlpha( 0 )
|
||||
particle:SetStartSize( math.Rand(1,30) )
|
||||
particle:SetEndSize( 0 )
|
||||
particle:SetRoll( math.Rand(-100,100) )
|
||||
particle:SetRollDelta( math.Rand(-100,100) )
|
||||
|
||||
particle:SetAirResistance( 0 )
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
end
|
||||
end
|
||||
end
|
||||
34
garrysmod/addons/lvs_base/lua/effects/lvs_laser_blue.lua
Normal file
34
garrysmod/addons/lvs_base/lua/effects/lvs_laser_blue.lua
Normal file
@@ -0,0 +1,34 @@
|
||||
|
||||
EFFECT.MatBeam = Material( "effects/spark" )
|
||||
EFFECT.MatSprite = Material( "sprites/light_glow02_add" )
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local pos = data:GetOrigin()
|
||||
local dir = data:GetNormal()
|
||||
|
||||
self.ID = data:GetMaterialIndex()
|
||||
|
||||
self:SetRenderBoundsWS( pos, pos + dir * 50000 )
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if not LVS:GetBullet( self.ID ) then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
local bullet = LVS:GetBullet( self.ID )
|
||||
|
||||
local endpos = bullet:GetPos()
|
||||
local dir = bullet:GetDir()
|
||||
|
||||
local len = 1000 * bullet:GetLength()
|
||||
|
||||
render.SetMaterial( self.MatSprite )
|
||||
render.DrawBeam( endpos - dir * len * 4, endpos + dir * len * 4, 200, 1, 0, Color( 0, 0, 255, 255 ) )
|
||||
|
||||
render.SetMaterial( self.MatBeam )
|
||||
render.DrawBeam( endpos - dir * len, endpos + dir * len, 45, 1, 0, Color( 0, 0, 255, 255 ) )
|
||||
render.DrawBeam( endpos - dir * len, endpos + dir * len, 15, 1, 0, Color( 255, 255, 255, 255 ) )
|
||||
end
|
||||
@@ -0,0 +1,75 @@
|
||||
EFFECT.MatBeam = Material( "effects/lvs/ballturret_projectorbeam" )
|
||||
|
||||
-- variables
|
||||
local LifeTime = 1.4
|
||||
|
||||
local StartSizeOuter = 16
|
||||
local StartSizeInner = 6
|
||||
|
||||
local EndSizeOuter = 3
|
||||
local EndSizeInner = 1
|
||||
local DissipateExponentScale = 16
|
||||
local DissipateExponentAlpha = 16
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local pos = data:GetOrigin()
|
||||
local dir = data:GetNormal()
|
||||
|
||||
self.StartPos = pos
|
||||
self.Dir = dir
|
||||
|
||||
self.ID = data:GetMaterialIndex()
|
||||
|
||||
self.LifeTime = LifeTime
|
||||
self.DieTime = CurTime() + self.LifeTime
|
||||
|
||||
self:SetRenderBoundsWS( pos, pos + dir * 50000 )
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if self.DieTime < CurTime() then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
|
||||
local bullet = LVS:GetBullet( self.ID )
|
||||
|
||||
if bullet then
|
||||
self.StartPos = bullet.Entity:LocalToWorld( bullet.SrcEntity )
|
||||
self.EndPos = bullet:GetPos()
|
||||
self.BulletAlive = true
|
||||
self.BulletFilter = bullet.Filter
|
||||
else
|
||||
-- fix problem in lvs bullet code not updating the target destination
|
||||
if self.BulletAlive and self.BulletFilter then
|
||||
self.BulletAlive = nil
|
||||
|
||||
local trace = util.TraceLine( {
|
||||
start = self.StartPos,
|
||||
endpos = self.StartPos + self.Dir * 50000,
|
||||
mask = MASK_SHOT_HULL,
|
||||
filter = self.BulletFilter,
|
||||
} )
|
||||
|
||||
self.EndPos = trace.HitPos
|
||||
end
|
||||
end
|
||||
|
||||
if not self.StartPos or not self.EndPos then return end
|
||||
|
||||
if bullet and bullet:GetLength() <= 0 then return end
|
||||
|
||||
-- math, dont change
|
||||
local S = (self.DieTime - CurTime()) / self.LifeTime
|
||||
local invS = 1 - S
|
||||
|
||||
local Alpha = 255 * (S ^ DissipateExponentAlpha)
|
||||
local Scale = S ^ DissipateExponentScale
|
||||
local invScale = invS ^ DissipateExponentScale
|
||||
|
||||
render.SetMaterial( self.MatBeam )
|
||||
render.DrawBeam( self.StartPos, self.EndPos, StartSizeOuter * Scale + EndSizeOuter * invScale, 1, 0, Color( 0, 0, 255, Alpha ) )
|
||||
render.DrawBeam( self.StartPos, self.EndPos, StartSizeInner * Scale + EndSizeInner * invScale, 1, 0, Color( 255, 255, 255, Alpha ) )
|
||||
end
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
EFFECT.MatBeam = Material( "effects/spark" )
|
||||
EFFECT.MatSprite = Material( "sprites/light_glow02_add" )
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local pos = data:GetOrigin()
|
||||
local dir = data:GetNormal()
|
||||
|
||||
self.ID = data:GetMaterialIndex()
|
||||
|
||||
self:SetRenderBoundsWS( pos, pos + dir * 50000 )
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if not LVS:GetBullet( self.ID ) then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
local bullet = LVS:GetBullet( self.ID )
|
||||
|
||||
local endpos = bullet:GetPos()
|
||||
local dir = bullet:GetDir()
|
||||
|
||||
local len = 2500 * bullet:GetLength()
|
||||
|
||||
render.SetMaterial( self.MatSprite )
|
||||
render.DrawBeam( endpos - dir * len * 2, endpos + dir * len * 2, 200, 1, 0, Color( 0, 0, 255, 255 ) )
|
||||
|
||||
render.SetMaterial( self.MatBeam )
|
||||
render.DrawBeam( endpos - dir * len, endpos + dir * len, 45, 1, 0, Color( 0, 0, 255, 255 ) )
|
||||
render.DrawBeam( endpos - dir * len, endpos + dir * len, 15, 1, 0, Color( 255, 255, 255, 255 ) )
|
||||
end
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
EFFECT.MatBeam = Material( "effects/spark" )
|
||||
EFFECT.MatSprite = Material( "sprites/light_glow02_add" )
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local pos = data:GetOrigin()
|
||||
local dir = data:GetNormal()
|
||||
|
||||
self.ID = data:GetMaterialIndex()
|
||||
|
||||
self:SetRenderBoundsWS( pos, pos + dir * 50000 )
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if not LVS:GetBullet( self.ID ) then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
local bullet = LVS:GetBullet( self.ID )
|
||||
|
||||
local endpos = bullet:GetPos()
|
||||
local dir = bullet:GetDir()
|
||||
|
||||
local len = 300 * bullet:GetLength()
|
||||
|
||||
render.SetMaterial( self.MatSprite )
|
||||
render.DrawBeam( endpos - dir * len * 2, endpos + dir * len * 2, 200, 1, 0, Color( 0, 0, 255, 255 ) )
|
||||
|
||||
render.SetMaterial( self.MatBeam )
|
||||
render.DrawBeam( endpos - dir * len, endpos + dir * len, 45, 1, 0, Color( 0, 0, 255, 255 ) )
|
||||
render.DrawBeam( endpos - dir * len, endpos + dir * len, 15, 1, 0, Color( 255, 255, 255, 255 ) )
|
||||
end
|
||||
103
garrysmod/addons/lvs_base/lua/effects/lvs_laser_charge.lua
Normal file
103
garrysmod/addons/lvs_base/lua/effects/lvs_laser_charge.lua
Normal file
@@ -0,0 +1,103 @@
|
||||
|
||||
EFFECT.HeatWaveMat = Material( "particle/warp1_warp" )
|
||||
EFFECT.GlowMat = Material( "sprites/light_glow02_add" )
|
||||
|
||||
function EFFECT:Init( data )
|
||||
self.Ent = data:GetEntity()
|
||||
self.ID = data:GetAttachment()
|
||||
|
||||
if not IsValid( self.Ent ) then return end
|
||||
|
||||
|
||||
local att = self.Ent:GetAttachment( self.ID )
|
||||
|
||||
if not att then return end
|
||||
|
||||
local Pos = att.Pos
|
||||
|
||||
self.LifeTime = 0.35
|
||||
self.DieTime = CurTime() + self.LifeTime
|
||||
|
||||
self.Emitter = ParticleEmitter( Pos, false )
|
||||
self.Particles = {}
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if (self.DieTime or 0) < CurTime() or not IsValid( self.Ent ) then
|
||||
if IsValid( self.Emitter ) then
|
||||
self.Emitter:Finish()
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
self:DoSpark()
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:DoSpark()
|
||||
local T = CurTime()
|
||||
|
||||
if (self._Next or 0) > T then return end
|
||||
|
||||
self._Next = T + 0.01
|
||||
|
||||
if not IsValid( self.Emitter ) then return end
|
||||
|
||||
if not IsValid( self.Ent ) or not self.ID then return end
|
||||
|
||||
local att = self.Ent:GetAttachment( self.ID )
|
||||
|
||||
if not att then return end
|
||||
|
||||
local Pos = att.Pos
|
||||
local Dir = VectorRand() * 25
|
||||
|
||||
for id, particle in pairs( self.Particles ) do
|
||||
if not particle then
|
||||
self.Particles[ id ] = nil
|
||||
|
||||
continue
|
||||
end
|
||||
|
||||
particle:SetGravity( (Pos - particle:GetPos()) * 50 )
|
||||
end
|
||||
|
||||
local particle = self.Emitter:Add( "sprites/rico1", Pos + Dir )
|
||||
|
||||
if not particle then return end
|
||||
|
||||
particle:SetDieTime( 0.25 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetEndAlpha( 0 )
|
||||
particle:SetStartSize( math.Rand( 1, 5 ) )
|
||||
particle:SetEndSize( 0 )
|
||||
particle:SetColor( 255, 0, 0 )
|
||||
particle:SetAirResistance( 0 )
|
||||
particle:SetRoll( math.Rand(-10,10) )
|
||||
particle:SetRollDelta( math.Rand(-10,10) )
|
||||
|
||||
table.insert( self.Particles, particle )
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
if not IsValid( self.Ent ) or not self.ID then return end
|
||||
|
||||
local att = self.Ent:GetAttachment( self.ID )
|
||||
|
||||
if not att then return end
|
||||
|
||||
local Scale = (self.DieTime - CurTime()) / self.LifeTime
|
||||
|
||||
if Scale <= 0 then return end
|
||||
|
||||
local rnd = VectorRand() * math.Rand(0,0.5)
|
||||
|
||||
render.SetMaterial( self.HeatWaveMat )
|
||||
render.DrawSprite( att.Pos, 30 *(1 - Scale), 30 * (1 - Scale), Color( 255, 255, 255, 255) )
|
||||
|
||||
render.SetMaterial( self.GlowMat )
|
||||
render.DrawSprite( att.Pos + rnd, 120 * (1 - Scale), 120 * (1 - Scale), Color(255,0,0,255) )
|
||||
end
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
|
||||
local GlowMat = Material( "sprites/light_glow02_add" )
|
||||
|
||||
function EFFECT:Init( data )
|
||||
self.Pos = data:GetOrigin()
|
||||
self.Col = data:GetStart() or Vector(255,100,0)
|
||||
|
||||
self.LifeTime = 0.4
|
||||
self.DieTime = CurTime() + self.LifeTime
|
||||
|
||||
local emitter = ParticleEmitter( self.Pos, false )
|
||||
|
||||
if not IsValid( emitter ) then return end
|
||||
|
||||
for i = 0, 20 do
|
||||
local particle = emitter:Add( "sprites/light_glow02_add", self.Pos )
|
||||
|
||||
local vel = VectorRand() * 400
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( vel )
|
||||
particle:SetAngles( vel:Angle() + Angle(0,90,0) )
|
||||
particle:SetDieTime( math.Rand(0.4,0.8) )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetEndAlpha( 0 )
|
||||
particle:SetStartSize( math.Rand(24,48) )
|
||||
particle:SetEndSize( 0 )
|
||||
particle:SetRoll( math.Rand(-100,100) )
|
||||
particle:SetRollDelta( math.Rand(-100,100) )
|
||||
particle:SetColor( self.Col.x,self.Col.y,self.Col.z )
|
||||
particle:SetGravity( Vector(0,0,-600) )
|
||||
|
||||
particle:SetAirResistance( 0 )
|
||||
|
||||
particle:SetCollide( true )
|
||||
particle:SetBounce( 0.5 )
|
||||
end
|
||||
end
|
||||
|
||||
for i = 0, 20 do
|
||||
local particle = emitter:Add( "effects/lvs_base/flamelet"..math.random(1,5), self.Pos )
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( VectorRand(-1,1) * 500 )
|
||||
particle:SetDieTime( 0.15 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 10 )
|
||||
particle:SetEndSize( 32 )
|
||||
particle:SetEndAlpha( 100 )
|
||||
particle:SetRoll( math.Rand( -1, 1 ) )
|
||||
particle:SetRollDelta( math.Rand( -1, 1 ) * 100 )
|
||||
particle:SetColor( self.Col.x,self.Col.y,self.Col.z )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if self.DieTime < CurTime() then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
if not self.Col then return end
|
||||
|
||||
local Scale = (self.DieTime - CurTime()) / self.LifeTime
|
||||
render.SetMaterial( GlowMat )
|
||||
render.DrawSprite( self.Pos, 400 * Scale, 400 * Scale, Color( self.Col.x,self.Col.y,self.Col.z, 255) )
|
||||
render.DrawSprite( self.Pos, 100 * Scale, 100 * Scale, Color( 255, 255, 255, 255) )
|
||||
end
|
||||
@@ -0,0 +1,121 @@
|
||||
|
||||
|
||||
EFFECT.HeatWaveMat = Material( "particle/warp1_warp" )
|
||||
EFFECT.GlowMat = Material( "sprites/light_glow02_add" )
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local Pos = data:GetOrigin()
|
||||
self.Pos = Pos
|
||||
|
||||
self.LifeTime = 0.4
|
||||
self.DieTime = CurTime() + self.LifeTime
|
||||
self.DieTimeGlow = CurTime() + 0.2
|
||||
|
||||
sound.Play( "LVS.AAT.LASER_EXPLOSION", Pos )
|
||||
self:Explosion( Pos )
|
||||
end
|
||||
|
||||
function EFFECT:Explosion( pos )
|
||||
local emitter = ParticleEmitter( pos, false )
|
||||
|
||||
if not emitter then return end
|
||||
|
||||
for i = 0, 15 do
|
||||
local particle = emitter:Add( "sprites/light_glow02_add", pos )
|
||||
|
||||
local vel = VectorRand() * 450
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( vel )
|
||||
particle:SetAngles( vel:Angle() + Angle(0,90,0) )
|
||||
particle:SetDieTime( math.Rand(1,1.6) )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetEndAlpha( 0 )
|
||||
particle:SetStartSize( math.Rand(12,15) )
|
||||
particle:SetEndSize( 0 )
|
||||
particle:SetRoll( math.Rand(-100,100) )
|
||||
particle:SetRollDelta( math.Rand(-100,100) )
|
||||
particle:SetColor( 255,0,0 )
|
||||
particle:SetGravity( Vector(0,0,-600) )
|
||||
|
||||
particle:SetAirResistance( 0 )
|
||||
|
||||
particle:SetCollide( true )
|
||||
particle:SetBounce( 0.5 )
|
||||
end
|
||||
|
||||
for i = 0, 5 do
|
||||
local particle = emitter:Add( "sprites/rico1", pos )
|
||||
|
||||
local vel = VectorRand() * 1000
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( vel )
|
||||
particle:SetAngles( vel:Angle() + Angle(0,90,0) )
|
||||
particle:SetDieTime( math.Rand(0.5,0.8) )
|
||||
particle:SetStartAlpha( math.Rand( 200, 255 ) )
|
||||
particle:SetEndAlpha( 0 )
|
||||
particle:SetStartSize( math.Rand(10,20) )
|
||||
particle:SetEndSize( 0 )
|
||||
particle:SetRoll( math.Rand(-100,100) )
|
||||
particle:SetRollDelta( math.Rand(-100,100) )
|
||||
particle:SetColor( 255, 0, 0 )
|
||||
particle:SetGravity( -vel:GetNormalized() * math.random(1250,1750) )
|
||||
particle:SetCollide( true )
|
||||
particle:SetBounce( 0.5 )
|
||||
|
||||
particle:SetAirResistance( 200 )
|
||||
end
|
||||
|
||||
for i = 0, 20 do
|
||||
local particle = emitter:Add( "effects/lvs_base/flamelet"..math.random(1,5), pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( VectorRand(-1,1) * 500 )
|
||||
particle:SetDieTime( 0.14 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 10 )
|
||||
particle:SetEndSize( math.Rand(30,60) )
|
||||
particle:SetEndAlpha( 100 )
|
||||
particle:SetRoll( math.Rand( -1, 1 ) )
|
||||
particle:SetColor( 200,150,150 )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if self.DieTime < CurTime() then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
local Scale = math.max((self.DieTime - self.LifeTime + 0.3 - CurTime()) / 0.3,0)
|
||||
render.SetMaterial( self.HeatWaveMat )
|
||||
render.DrawSprite( self.Pos, 300 * Scale, 300 * Scale, Color( 255, 255, 255, 255) )
|
||||
|
||||
render.SetMaterial( self.GlowMat )
|
||||
render.DrawSprite( self.Pos, 1000 * Scale, 1000 * Scale, Color( 255, 100, 50, 255) )
|
||||
|
||||
local Scale = (self.DieTimeGlow - CurTime()) / 0.2
|
||||
if Scale > 0 then
|
||||
render.SetMaterial( self.GlowMat )
|
||||
render.DrawSprite( self.Pos, 100 * Scale, 100 * Scale, Color( 250, 0, 0, 255) )
|
||||
render.DrawSprite( self.Pos, 25 * Scale, 25 * Scale, Color( 255, 255, 255, 255) )
|
||||
end
|
||||
|
||||
local Scale = (self.DieTime - self.LifeTime + 0.25 - CurTime()) / 0.25
|
||||
local InvScale = 1 - Scale
|
||||
if Scale > 0 then
|
||||
render.SetColorMaterial()
|
||||
render.DrawSphere( self.Pos, -180 * InvScale, 30,30, Color( 255, 0, 0, 255 * (Scale ^ 2) ) )
|
||||
render.DrawSphere( self.Pos, -190 * InvScale, 30,30, Color( 255, 0, 0, 150 * (Scale ^ 2) ) )
|
||||
render.DrawSphere( self.Pos, -200 * InvScale, 30,30, Color( 255, 0, 0, 50 * (Scale ^ 2) ) )
|
||||
render.DrawSphere( self.Pos, 210 * InvScale, 30,30, Color( 255, 0, 0, 50 * (Scale ^ 2) ) )
|
||||
end
|
||||
end
|
||||
34
garrysmod/addons/lvs_base/lua/effects/lvs_laser_green.lua
Normal file
34
garrysmod/addons/lvs_base/lua/effects/lvs_laser_green.lua
Normal file
@@ -0,0 +1,34 @@
|
||||
|
||||
EFFECT.MatBeam = Material( "effects/spark" )
|
||||
EFFECT.MatSprite = Material( "sprites/light_glow02_add" )
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local pos = data:GetOrigin()
|
||||
local dir = data:GetNormal()
|
||||
|
||||
self.ID = data:GetMaterialIndex()
|
||||
|
||||
self:SetRenderBoundsWS( pos, pos + dir * 50000 )
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if not LVS:GetBullet( self.ID ) then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
local bullet = LVS:GetBullet( self.ID )
|
||||
|
||||
local endpos = bullet:GetPos()
|
||||
local dir = bullet:GetDir()
|
||||
|
||||
local len = 1000 * bullet:GetLength()
|
||||
|
||||
render.SetMaterial( self.MatSprite )
|
||||
render.DrawBeam( endpos - dir * len * 4, endpos + dir * len * 4, 200, 1, 0, Color( 0, 255, 0, 255 ) )
|
||||
|
||||
render.SetMaterial( self.MatBeam )
|
||||
render.DrawBeam( endpos - dir * len, endpos + dir * len, 45, 1, 0, Color( 0, 255, 0, 255 ) )
|
||||
render.DrawBeam( endpos - dir * len, endpos + dir * len, 15, 1, 0, Color( 255, 255, 255, 255 ) )
|
||||
end
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
EFFECT.MatBeam = Material( "effects/spark" )
|
||||
EFFECT.MatSprite = Material( "sprites/light_glow02_add" )
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local pos = data:GetOrigin()
|
||||
local dir = data:GetNormal()
|
||||
|
||||
self.ID = data:GetMaterialIndex()
|
||||
|
||||
self:SetRenderBoundsWS( pos, pos + dir * 50000 )
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if not LVS:GetBullet( self.ID ) then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
local bullet = LVS:GetBullet( self.ID )
|
||||
|
||||
local endpos = bullet:GetPos()
|
||||
local dir = bullet:GetDir()
|
||||
|
||||
local len = 300 * bullet:GetLength()
|
||||
|
||||
render.SetMaterial( self.MatSprite )
|
||||
render.DrawBeam( endpos - dir * len * 2, endpos + dir * len * 2, 100, 1, 0, Color( 0, 255, 0, 255 ) )
|
||||
|
||||
render.SetMaterial( self.MatBeam )
|
||||
render.DrawBeam( endpos - dir * len, endpos + dir * len, 60, 1, 0, Color( 0, 255, 0, 255 ) )
|
||||
render.DrawBeam( endpos - dir * len, endpos + dir * len, 15, 1, 0, Color( 255, 255, 255, 255 ) )
|
||||
end
|
||||
78
garrysmod/addons/lvs_base/lua/effects/lvs_laser_impact.lua
Normal file
78
garrysmod/addons/lvs_base/lua/effects/lvs_laser_impact.lua
Normal file
@@ -0,0 +1,78 @@
|
||||
EFFECT.GlowMat = Material( "sprites/light_glow02_add" )
|
||||
|
||||
function EFFECT:Init( data )
|
||||
self.Pos = data:GetOrigin()
|
||||
self.Dir = data:GetNormal()
|
||||
self.Col = data:GetStart() or Vector(255,100,0)
|
||||
|
||||
self.LifeTime = 0.2
|
||||
self.DieTime = CurTime() + self.LifeTime
|
||||
|
||||
local trace = util.TraceLine( {
|
||||
start = self.Pos - self.Dir,
|
||||
endpos = self.Pos + self.Dir,
|
||||
mask = MASK_SOLID_BRUSHONLY,
|
||||
} )
|
||||
|
||||
self.Flat = trace.Hit and not trace.HitSky
|
||||
|
||||
local Col = self.Col
|
||||
local Pos = self.Pos
|
||||
|
||||
local emitter = ParticleEmitter( Pos, false )
|
||||
|
||||
for i = 0, 10 do
|
||||
local particle = emitter:Add( "sprites/light_glow02_add", Pos )
|
||||
|
||||
local vel = VectorRand() * 200 + self.Dir * 80
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( vel )
|
||||
particle:SetAngles( vel:Angle() + Angle(0,90,0) )
|
||||
particle:SetDieTime( math.Rand(0.2,0.4) )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetEndAlpha( 0 )
|
||||
particle:SetStartSize( math.Rand(12,24) )
|
||||
particle:SetEndSize( 0 )
|
||||
particle:SetRoll( math.Rand(-100,100) )
|
||||
particle:SetRollDelta( math.Rand(-100,100) )
|
||||
particle:SetColor( Col.x,Col.y,Col.z )
|
||||
particle:SetGravity( Vector(0,0,-600) )
|
||||
|
||||
particle:SetAirResistance( 0 )
|
||||
|
||||
particle:SetCollide( true )
|
||||
particle:SetBounce( 0.5 )
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if self.DieTime < CurTime() then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
local Scale = (self.DieTime - CurTime()) / self.LifeTime
|
||||
|
||||
local S1 = 200 * Scale
|
||||
local S2 = 50 * Scale
|
||||
|
||||
if self.Flat then
|
||||
cam.Start3D2D( self.Pos + self.Dir, self.Dir:Angle() + Angle(90,0,0), 1 )
|
||||
surface.SetMaterial( self.GlowMat )
|
||||
surface.SetDrawColor( self.Col.x, self.Col.y, self.Col.z, 255 )
|
||||
surface.DrawTexturedRectRotated( 0, 0, S1 , S1 , 0 )
|
||||
|
||||
surface.SetDrawColor( 255, 255, 255, 255 )
|
||||
surface.DrawTexturedRectRotated( 0, 0, S2 , S2 , 0 )
|
||||
cam.End3D2D()
|
||||
end
|
||||
|
||||
render.SetMaterial( self.GlowMat )
|
||||
render.DrawSprite( self.Pos + self.Dir, S1, S1, Color( self.Col.x, self.Col.y, self.Col.z, 255 ) )
|
||||
render.DrawSprite( self.Pos + self.Dir, S2, S2, Color( 255, 255, 255, 255) )
|
||||
end
|
||||
34
garrysmod/addons/lvs_base/lua/effects/lvs_laser_red.lua
Normal file
34
garrysmod/addons/lvs_base/lua/effects/lvs_laser_red.lua
Normal file
@@ -0,0 +1,34 @@
|
||||
|
||||
EFFECT.MatBeam = Material( "effects/spark" )
|
||||
EFFECT.MatSprite = Material( "sprites/light_glow02_add" )
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local pos = data:GetOrigin()
|
||||
local dir = data:GetNormal()
|
||||
|
||||
self.ID = data:GetMaterialIndex()
|
||||
|
||||
self:SetRenderBoundsWS( pos, pos + dir * 50000 )
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if not LVS:GetBullet( self.ID ) then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
local bullet = LVS:GetBullet( self.ID )
|
||||
|
||||
local endpos = bullet:GetPos()
|
||||
local dir = bullet:GetDir()
|
||||
|
||||
local len = 1000 * bullet:GetLength()
|
||||
|
||||
render.SetMaterial( self.MatSprite )
|
||||
render.DrawBeam( endpos - dir * len * 4, endpos + dir * len * 4, 200, 1, 0, Color( 255, 0, 0, 255 ) )
|
||||
|
||||
render.SetMaterial( self.MatBeam )
|
||||
render.DrawBeam( endpos - dir * len, endpos + dir * len, 45, 1, 0, Color( 255, 0, 0, 255 ) )
|
||||
render.DrawBeam( endpos - dir * len, endpos + dir * len, 15, 1, 0, Color( 255, 255, 255, 255 ) )
|
||||
end
|
||||
103
garrysmod/addons/lvs_base/lua/effects/lvs_laser_red_aat.lua
Normal file
103
garrysmod/addons/lvs_base/lua/effects/lvs_laser_red_aat.lua
Normal file
@@ -0,0 +1,103 @@
|
||||
|
||||
EFFECT.MatBeam = Material( "effects/spark" )
|
||||
EFFECT.MatSprite = Material( "sprites/light_glow02_add" )
|
||||
EFFECT.MatSmoke = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local pos = data:GetOrigin()
|
||||
local dir = data:GetNormal()
|
||||
|
||||
self.ID = data:GetMaterialIndex()
|
||||
|
||||
self:SetRenderBoundsWS( pos, pos + dir * 50000 )
|
||||
|
||||
local emitter = ParticleEmitter( pos, false )
|
||||
|
||||
if not IsValid( emitter ) then return end
|
||||
|
||||
local trace = util.TraceLine( {
|
||||
start = pos,
|
||||
endpos = pos - Vector(0,0,500),
|
||||
mask = MASK_SOLID_BRUSHONLY,
|
||||
} )
|
||||
|
||||
if not trace.Hit then return end
|
||||
|
||||
local VecCol = (render.GetLightColor( trace.HitPos + trace.HitNormal ) * 0.8 + Vector(0.17,0.15,0.1)) * 255
|
||||
for i = 1,24 do
|
||||
local particle = emitter:Add( self.MatSmoke[math.random(1,#self.MatSmoke)], trace.HitPos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
local ang = i * 15
|
||||
local X = math.cos( math.rad(ang) )
|
||||
local Y = math.sin( math.rad(ang) )
|
||||
|
||||
particle:SetVelocity( Vector(X,Y,0) * 3000 )
|
||||
particle:SetDieTime( math.Rand(0.5,1) )
|
||||
particle:SetAirResistance( 500 )
|
||||
particle:SetStartAlpha( 100 )
|
||||
particle:SetStartSize( 50 )
|
||||
particle:SetEndSize( 240 )
|
||||
particle:SetRollDelta( math.Rand(-1,1) )
|
||||
particle:SetColor( math.min( VecCol.r, 255 ), math.min( VecCol.g, 255 ), math.min( VecCol.b, 255 ) )
|
||||
particle:SetGravity( Vector(0,0,150) + dir * 2000 )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
|
||||
local ply = LocalPlayer()
|
||||
|
||||
if not IsValid( ply ) then return end
|
||||
|
||||
local ViewEnt = ply:GetViewEntity()
|
||||
|
||||
if not IsValid( ViewEnt ) then return end
|
||||
|
||||
local Intensity = 8
|
||||
local Ratio = math.min( 250 / (ViewEnt:GetPos() - trace.HitPos):Length(), 1 )
|
||||
|
||||
if Ratio < 0 then return end
|
||||
|
||||
util.ScreenShake( trace.HitPos, Intensity * Ratio, 0.1, 0.5, 250 )
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if not LVS:GetBullet( self.ID ) then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
local bullet = LVS:GetBullet( self.ID )
|
||||
|
||||
local endpos = bullet:GetPos()
|
||||
local dir = bullet:GetDir()
|
||||
|
||||
local len = 100 * bullet:GetLength()
|
||||
|
||||
render.SetMaterial( self.MatSprite )
|
||||
render.DrawBeam( endpos - dir * len * 8, endpos + dir * len * 8, 200, 1, 0, Color( 255, 0, 0, 255 ) )
|
||||
|
||||
render.SetMaterial( self.MatBeam )
|
||||
render.DrawBeam( endpos - dir * len, endpos + dir * len, 60, 1, 0, Color( 255, 0, 0, 255 ) )
|
||||
render.DrawBeam( endpos - dir * len, endpos + dir * len, 30, 1, 0, Color( 255, 255, 255, 255 ) )
|
||||
end
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
EFFECT.MatBeam = Material( "effects/spark" )
|
||||
EFFECT.MatSprite = Material( "sprites/light_glow02_add" )
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local pos = data:GetOrigin()
|
||||
local dir = data:GetNormal()
|
||||
|
||||
self.ID = data:GetMaterialIndex()
|
||||
|
||||
self:SetRenderBoundsWS( pos, pos + dir * 50000 )
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if not LVS:GetBullet( self.ID ) then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
local bullet = LVS:GetBullet( self.ID )
|
||||
|
||||
local endpos = bullet:GetPos()
|
||||
local dir = bullet:GetDir()
|
||||
|
||||
local len = 300 * bullet:GetLength()
|
||||
|
||||
render.SetMaterial( self.MatSprite )
|
||||
render.DrawBeam( endpos - dir * len * 2, endpos + dir * len * 2, 200, 1, 0, Color( 255, 0, 0, 255 ) )
|
||||
|
||||
render.SetMaterial( self.MatBeam )
|
||||
render.DrawBeam( endpos - dir * len, endpos + dir * len, 45, 1, 0, Color( 255, 0, 0, 255 ) )
|
||||
render.DrawBeam( endpos - dir * len, endpos + dir * len, 15, 1, 0, Color( 255, 255, 255, 255 ) )
|
||||
end
|
||||
127
garrysmod/addons/lvs_base/lua/effects/lvs_missiletrail.lua
Normal file
127
garrysmod/addons/lvs_base/lua/effects/lvs_missiletrail.lua
Normal file
@@ -0,0 +1,127 @@
|
||||
EFFECT.Offset = Vector(-8,0,0)
|
||||
|
||||
local GlowMat = Material( "sprites/light_glow02_add" )
|
||||
local Materials = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
self.Entity = data:GetEntity()
|
||||
|
||||
if IsValid( self.Entity ) then
|
||||
self.OldPos = self.Entity:LocalToWorld( self.Offset )
|
||||
|
||||
self.Emitter = ParticleEmitter( self.Entity:LocalToWorld( self.OldPos ), false )
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:doFX( pos )
|
||||
if not IsValid( self.Entity ) then return end
|
||||
|
||||
if IsValid( self.Emitter ) then
|
||||
local emitter = self.Emitter
|
||||
|
||||
local particle = emitter:Add( Materials[ math.random(1, #Materials ) ], pos )
|
||||
if particle then
|
||||
particle:SetGravity( Vector(0,0,100) + VectorRand() * 50 )
|
||||
particle:SetVelocity( -self.Entity:GetForward() * 200 )
|
||||
particle:SetAirResistance( 600 )
|
||||
particle:SetDieTime( math.Rand(1.5,2) )
|
||||
particle:SetStartAlpha( 50 )
|
||||
particle:SetStartSize( 20 )
|
||||
particle:SetEndSize( 60 )
|
||||
particle:SetRoll( math.Rand( -1, 1 ) )
|
||||
particle:SetRollDelta( math.Rand( -1, 1 ) )
|
||||
particle:SetColor(40,40,40)
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
local particle = emitter:Add( "particles/flamelet"..math.random(1,5), pos )
|
||||
if particle then
|
||||
particle:SetVelocity( -self.Entity:GetForward() * math.Rand(250,800) + self.Entity:GetVelocity())
|
||||
particle:SetDieTime( math.Rand(0.2,0.4) )
|
||||
particle:SetAirResistance( 0 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 8 )
|
||||
particle:SetEndSize( 1 )
|
||||
particle:SetRoll( math.Rand(-1,1) )
|
||||
particle:SetColor( 255,255,255 )
|
||||
particle:SetGravity( Vector( 0, 0, 0 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
local particle = emitter:Add( "particles/flamelet"..math.random(1,5), self.Entity:GetPos() )
|
||||
if particle then
|
||||
particle:SetVelocity( -self.Entity:GetForward() * 200 + VectorRand() * 50 )
|
||||
particle:SetDieTime( 0.25 )
|
||||
particle:SetAirResistance( 600 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 6 )
|
||||
particle:SetEndSize( 2 )
|
||||
particle:SetRoll( math.Rand(-1,1) )
|
||||
particle:SetColor( 255,255,255 )
|
||||
particle:SetGravity( Vector( 0, 0, 0 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if IsValid( self.Entity ) then
|
||||
self.nextDFX = self.nextDFX or 0
|
||||
|
||||
if self.nextDFX < CurTime() then
|
||||
self.nextDFX = CurTime() + 0.02
|
||||
|
||||
local oldpos = self.OldPos
|
||||
local newpos = self.Entity:LocalToWorld( self.Offset )
|
||||
self:SetPos( newpos )
|
||||
|
||||
local Sub = (newpos - oldpos)
|
||||
local Dir = Sub:GetNormalized()
|
||||
local Len = Sub:Length()
|
||||
|
||||
self.OldPos = newpos
|
||||
|
||||
for i = 0, Len, 45 do
|
||||
local pos = oldpos + Dir * i
|
||||
|
||||
self:doFX( pos )
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
if IsValid( self.Emitter ) then
|
||||
self.Emitter:Finish()
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
local ent = self.Entity
|
||||
|
||||
if not IsValid( ent ) then return end
|
||||
|
||||
local pos = ent:LocalToWorld( self.Offset )
|
||||
|
||||
render.SetMaterial( GlowMat )
|
||||
render.DrawSprite( pos, 100, 100, Color( 255, 200, 150, 255 ) )
|
||||
end
|
||||
40
garrysmod/addons/lvs_base/lua/effects/lvs_muzzle.lua
Normal file
40
garrysmod/addons/lvs_base/lua/effects/lvs_muzzle.lua
Normal file
@@ -0,0 +1,40 @@
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local Pos = data:GetOrigin()
|
||||
local Dir = data:GetNormal()
|
||||
local Ent = data:GetEntity()
|
||||
local Vel = Dir * 10
|
||||
|
||||
if IsValid( Ent ) then
|
||||
Vel = Ent:GetVelocity()
|
||||
end
|
||||
|
||||
local emitter = ParticleEmitter( Pos, false )
|
||||
|
||||
if not IsValid( emitter ) then return end
|
||||
|
||||
for i = 0, 12 do
|
||||
local particle = emitter:Add( "effects/muzzleflash2", Pos + Dir * i * 0.7 * math.random(1,2) * 0.5 )
|
||||
local Size = 1
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( Dir * 800 + Vel )
|
||||
particle:SetDieTime( 0.05 )
|
||||
particle:SetStartAlpha( 255 * Size )
|
||||
particle:SetStartSize( math.max( math.random(10,24) - i * 0.5,0.1 ) * Size )
|
||||
particle:SetEndSize( 0 )
|
||||
particle:SetRoll( math.Rand( -1, 1 ) )
|
||||
particle:SetColor( 255, 255, 255 )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
end
|
||||
@@ -0,0 +1,41 @@
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local Pos = data:GetOrigin()
|
||||
local Dir = data:GetNormal()
|
||||
local Ent = data:GetEntity()
|
||||
local Col = data:GetStart() or Vector(255,255,255)
|
||||
local Vel = Dir * 10
|
||||
|
||||
if IsValid( Ent ) then
|
||||
Vel = Ent:GetVelocity()
|
||||
end
|
||||
|
||||
local emitter = ParticleEmitter( Pos, false )
|
||||
|
||||
if not IsValid( emitter ) then return end
|
||||
|
||||
for i = 0, 12 do
|
||||
local particle = emitter:Add( "effects/muzzleflash2", Pos + Dir * i * 0.7 * math.random(1,2) * 0.5 )
|
||||
local Size = 1
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( Dir * 800 + Vel )
|
||||
particle:SetDieTime( 0.05 )
|
||||
particle:SetStartAlpha( 255 * Size )
|
||||
particle:SetStartSize( math.max( math.random(10,24) - i * 0.5,0.1 ) * Size )
|
||||
particle:SetEndSize( 0 )
|
||||
particle:SetRoll( math.Rand( -1, 1 ) )
|
||||
particle:SetColor( Col.x, Col.y, Col.z )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
end
|
||||
82
garrysmod/addons/lvs_base/lua/effects/lvs_physics_dust.lua
Normal file
82
garrysmod/addons/lvs_base/lua/effects/lvs_physics_dust.lua
Normal file
@@ -0,0 +1,82 @@
|
||||
local Materials = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
local MatDebris = {
|
||||
"effects/lvs_base/particle_debris_01",
|
||||
"effects/lvs_base/particle_debris_02",
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local Pos = data:GetOrigin()
|
||||
local Ent = data:GetEntity()
|
||||
|
||||
if not IsValid( Ent ) then return end
|
||||
|
||||
local Dir = Ent:GetForward()
|
||||
|
||||
local emitter = Ent:GetParticleEmitter( Ent:GetPos() )
|
||||
|
||||
local VecCol = render.GetLightColor( Pos + Vector(0,0,10) ) * 0.5 + Vector(0.3,0.25,0.15)
|
||||
|
||||
if emitter and emitter.Add then
|
||||
for i = 1, 3 do
|
||||
local particle = emitter:Add( MatDebris[math.random(1,#MatDebris)], Pos + VectorRand(-10,10) )
|
||||
if particle then
|
||||
particle:SetVelocity( Vector(0,0,150) - Dir * 150 )
|
||||
particle:SetDieTime( 0.2 )
|
||||
particle:SetAirResistance( 60 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetEndAlpha( 255 )
|
||||
particle:SetStartSize( 15 )
|
||||
particle:SetEndSize( 50 )
|
||||
particle:SetRoll( math.Rand(-1,1) * 100 )
|
||||
particle:SetColor( VecCol.x * 130,VecCol.y * 100,VecCol.z * 60 )
|
||||
particle:SetGravity( Vector( 0, 0, -600 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
local Right = Ent:GetRight()
|
||||
Right.z = 0
|
||||
Right:Normalize()
|
||||
|
||||
for i = -1,1,2 do
|
||||
local particle = emitter:Add( Materials[math.random(1,#Materials)], Pos + Vector(0,0,10) )
|
||||
if particle then
|
||||
particle:SetVelocity( -Dir * 400 + Right * 150 * i )
|
||||
particle:SetDieTime( math.Rand(0.5,1) )
|
||||
particle:SetAirResistance( 150 )
|
||||
particle:SetStartAlpha( 50 )
|
||||
particle:SetStartSize( -80 )
|
||||
particle:SetEndSize( 400 )
|
||||
particle:SetColor( VecCol.x * 255,VecCol.y * 255,VecCol.z * 255 )
|
||||
particle:SetGravity( Vector( 0, 0, 100 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function EFFECT:Think()
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
end
|
||||
89
garrysmod/addons/lvs_base/lua/effects/lvs_physics_impact.lua
Normal file
89
garrysmod/addons/lvs_base/lua/effects/lvs_physics_impact.lua
Normal file
@@ -0,0 +1,89 @@
|
||||
|
||||
local Materials = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
if not LVS.ShowPhysicsEffects then return end
|
||||
|
||||
local dir = data:GetNormal()
|
||||
local pos = data:GetOrigin() + dir
|
||||
|
||||
local emitter = ParticleEmitter( pos, false )
|
||||
|
||||
for i = 0, 10 do
|
||||
local particle = emitter:Add( "effects/spark", pos )
|
||||
|
||||
local vel = VectorRand() * 75 + dir * 75 + Vector(0,0,100)
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( vel )
|
||||
particle:SetDieTime( math.Rand(2.5,5) )
|
||||
particle:SetAirResistance( 10 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
|
||||
particle:SetStartLength( 6 )
|
||||
particle:SetEndLength(0)
|
||||
|
||||
particle:SetStartSize( 3 )
|
||||
particle:SetEndSize( 0 )
|
||||
|
||||
particle:SetRoll( math.Rand(-5,5) )
|
||||
particle:SetColor( 255, 200, 50 )
|
||||
particle:SetGravity( Vector(0,0,-600) )
|
||||
particle:SetCollide( true )
|
||||
end
|
||||
|
||||
local smoke = emitter:Add( Materials[ math.random(1, #Materials ) ], pos )
|
||||
|
||||
if smoke then
|
||||
smoke:SetVelocity( dir * 30 + VectorRand() * 15 )
|
||||
smoke:SetDieTime( math.Rand(1.5,3) )
|
||||
smoke:SetAirResistance( 100 )
|
||||
smoke:SetStartAlpha( 100 )
|
||||
smoke:SetEndAlpha( 0 )
|
||||
smoke:SetStartSize( 15 )
|
||||
smoke:SetEndSize( 30 )
|
||||
smoke:SetColor(30,30,30)
|
||||
smoke:SetGravity(Vector(0,0,40))
|
||||
smoke:SetCollide( false )
|
||||
smoke:SetRollDelta( math.Rand(-1,1) )
|
||||
end
|
||||
|
||||
local flash = emitter:Add( "effects/yellowflare",pos )
|
||||
|
||||
if flash then
|
||||
flash:SetPos( pos )
|
||||
flash:SetStartAlpha( 200 )
|
||||
flash:SetEndAlpha( 0 )
|
||||
flash:SetColor( 255, 200, 0 )
|
||||
flash:SetEndSize( 100 )
|
||||
flash:SetDieTime( 0.1 )
|
||||
flash:SetStartSize( 0 )
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
end
|
||||
109
garrysmod/addons/lvs_base/lua/effects/lvs_physics_scrape.lua
Normal file
109
garrysmod/addons/lvs_base/lua/effects/lvs_physics_scrape.lua
Normal file
@@ -0,0 +1,109 @@
|
||||
|
||||
local Materials = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
if not LVS.ShowPhysicsEffects then
|
||||
self.LifeTime = 0
|
||||
self.DieTime = 0
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
self.Pos = data:GetOrigin()
|
||||
|
||||
self.mat = Material( "sprites/light_glow02_add" )
|
||||
|
||||
self.LifeTime = 0.2
|
||||
self.DieTime = CurTime() + self.LifeTime
|
||||
|
||||
local Col = self.Col
|
||||
local Pos = self.Pos
|
||||
local Dir = data:GetNormal()
|
||||
local Strength = data:GetMagnitude()
|
||||
|
||||
local emitter = ParticleEmitter( Pos, false )
|
||||
|
||||
for i = 0,1 do
|
||||
local particle = emitter:Add( Materials[ math.random(1, #Materials ) ], Pos )
|
||||
|
||||
local vel = VectorRand() * 100 + Dir * 40
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( vel )
|
||||
particle:SetDieTime( 1 )
|
||||
particle:SetAirResistance( 1000 )
|
||||
particle:SetStartAlpha( 10 )
|
||||
particle:SetStartSize( 2 )
|
||||
particle:SetEndSize( 12 )
|
||||
particle:SetRoll( math.Rand(-1,1) )
|
||||
particle:SetColor( 40, 30, 20 )
|
||||
particle:SetGravity( Dir * 50 )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
for i = 0, 3 do
|
||||
local particle = emitter:Add( "effects/spark", Pos )
|
||||
|
||||
local vel = VectorRand() * 25 * (1 - Strength) + (VectorRand() * 100 + Dir * 150) * Strength
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( vel )
|
||||
particle:SetAngles( vel:Angle() + Angle(0,90,0) )
|
||||
particle:SetDieTime( 2 )
|
||||
particle:SetStartAlpha( math.Rand( 200, 255 ) )
|
||||
particle:SetEndAlpha( 0 )
|
||||
|
||||
particle:SetStartLength( 4 )
|
||||
particle:SetEndLength(0)
|
||||
|
||||
particle:SetStartSize( 2 )
|
||||
particle:SetEndSize( 0 )
|
||||
|
||||
particle:SetRoll( math.Rand(-100,100) )
|
||||
particle:SetRollDelta( math.Rand(-100,100) )
|
||||
particle:SetCollide( true )
|
||||
particle:SetBounce( 0.5 )
|
||||
particle:SetAirResistance( 0 )
|
||||
particle:SetColor( 255, 200, 50 )
|
||||
particle:SetGravity( Vector(0,0,-600) )
|
||||
end
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if self.DieTime < CurTime() then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
local mat = Material( "sprites/light_glow02_add" )
|
||||
function EFFECT:Render()
|
||||
if not LVS.ShowPhysicsEffects then return end
|
||||
|
||||
local Scale = (self.DieTime - CurTime()) / self.LifeTime
|
||||
render.SetMaterial( mat )
|
||||
render.DrawSprite( self.Pos, 32, 32, Color( 255 * Scale, 175 * Scale, 80 * Scale, 255) )
|
||||
end
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
|
||||
EFFECT.DustMat = {
|
||||
"effects/lvs/track_debris_01",
|
||||
"effects/lvs/track_debris_02",
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local pos = data:GetOrigin()
|
||||
local ent = data:GetEntity()
|
||||
local size = data:GetMagnitude()
|
||||
|
||||
if not IsValid( ent ) then return end
|
||||
|
||||
local dir = data:GetNormal()
|
||||
|
||||
local emitter = ent:GetParticleEmitter( ent:GetPos() )
|
||||
|
||||
local VecCol = (render.GetLightColor( pos + dir ) * 0.5 + Vector(0.5,0.4,0.3)) * 255
|
||||
|
||||
local scale = math.Clamp( size / 23, 0.5, 1.25 )
|
||||
|
||||
local particle = emitter:Add( self.DustMat[ math.random(1,#self.DustMat) ] , pos + dir * 5 * scale + VectorRand() * 5 * scale )
|
||||
|
||||
if not particle then return end
|
||||
|
||||
particle:SetVelocity( (dir * 100 * scale + VectorRand() * 20 * scale) )
|
||||
particle:SetDieTime( math.Rand(0.4,0.6) )
|
||||
particle:SetAirResistance( 10 )
|
||||
particle:SetStartAlpha( math.random(100,255) )
|
||||
particle:SetStartSize( 6 * scale )
|
||||
particle:SetEndSize( math.random(20,25) * scale )
|
||||
particle:SetRollDelta( math.Rand(-1,1) )
|
||||
particle:SetColor( math.min( VecCol.r, 255 ), math.min( VecCol.g, 255 ), math.min( VecCol.b, 255 ) )
|
||||
particle:SetGravity( Vector(0,0,-600) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
end
|
||||
@@ -0,0 +1,48 @@
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local pos = data:GetOrigin()
|
||||
local dir = data:GetNormal()
|
||||
|
||||
local emitter = ParticleEmitter( pos, false )
|
||||
|
||||
for i = 1, 360 do
|
||||
if math.random(1,30) ~= 10 then continue end
|
||||
|
||||
local ang = i
|
||||
|
||||
local X = math.cos( math.rad(ang) )
|
||||
local Y = math.sin( math.rad(ang) )
|
||||
|
||||
local forward = Vector(X,Y,0)
|
||||
forward:Rotate( dir:Angle() + Angle(90,0,0) )
|
||||
|
||||
local spark = emitter:Add("effects/spark", pos + VectorRand() * 10 )
|
||||
|
||||
if not spark then continue end
|
||||
|
||||
spark:SetStartAlpha( 255 )
|
||||
spark:SetEndAlpha( 0 )
|
||||
spark:SetCollide( true )
|
||||
spark:SetBounce( math.Rand(0,1) )
|
||||
spark:SetColor( 255, 255, 255 )
|
||||
spark:SetGravity( Vector(0,0,-600) )
|
||||
spark:SetEndLength(0)
|
||||
|
||||
local size = math.Rand(2, 4)
|
||||
spark:SetEndSize( size )
|
||||
spark:SetStartSize( size )
|
||||
|
||||
spark:SetStartLength( math.Rand(5,7) )
|
||||
spark:SetDieTime( math.Rand(0.1, 0.3) )
|
||||
spark:SetVelocity( forward * math.random(75,100) + VectorRand() * 50 )
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
end
|
||||
@@ -0,0 +1,48 @@
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local pos = data:GetOrigin()
|
||||
local dir = data:GetNormal()
|
||||
|
||||
local emitter = ParticleEmitter( pos, false )
|
||||
|
||||
for i = 1, 360 do
|
||||
if math.random(1,30) ~= 15 then continue end
|
||||
|
||||
local ang = i
|
||||
|
||||
local X = math.cos( math.rad(ang) )
|
||||
local Y = math.sin( math.rad(ang) )
|
||||
|
||||
local forward = Vector(X,Y,0)
|
||||
forward:Rotate( dir:Angle() + Angle(90,0,0) )
|
||||
|
||||
local spark = emitter:Add("effects/spark", pos + forward * 25 )
|
||||
|
||||
if not spark then continue end
|
||||
|
||||
spark:SetStartAlpha( 255 )
|
||||
spark:SetEndAlpha( 0 )
|
||||
spark:SetCollide( true )
|
||||
spark:SetBounce( math.Rand(0,1) )
|
||||
spark:SetColor( 255, 255, 255 )
|
||||
spark:SetGravity( Vector(0,0,-600) )
|
||||
spark:SetEndLength(0)
|
||||
|
||||
local size = math.Rand(4, 6)
|
||||
spark:SetEndSize( size )
|
||||
spark:SetStartSize( size )
|
||||
|
||||
spark:SetStartLength( math.Rand(10,20) )
|
||||
spark:SetDieTime( math.Rand(0.01, 0.2) )
|
||||
spark:SetVelocity( forward * math.random(250,400) + dir * 150 + VectorRand() * 50 )
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
end
|
||||
63
garrysmod/addons/lvs_base/lua/effects/lvs_physics_water.lua
Normal file
63
garrysmod/addons/lvs_base/lua/effects/lvs_physics_water.lua
Normal file
@@ -0,0 +1,63 @@
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local Pos = data:GetOrigin()
|
||||
local Ent = data:GetEntity()
|
||||
|
||||
if not IsValid( Ent ) then return end
|
||||
|
||||
self.LifeTime = math.Rand(1.5,3)
|
||||
self.DieTime = CurTime() + self.LifeTime
|
||||
|
||||
local LightColor = render.GetLightColor( Pos )
|
||||
self.VecCol = Vector(1,1.2,1.4) * (0.06 + (0.2126 * LightColor.r) + (0.7152 * LightColor.g) + (0.0722 * LightColor.b)) * 1000
|
||||
self.VecCol.x = math.min( self.VecCol.x, 255 )
|
||||
self.VecCol.y = math.min( self.VecCol.y, 255 )
|
||||
self.VecCol.z = math.min( self.VecCol.z, 255 )
|
||||
|
||||
self.Splash = {
|
||||
Pos = Pos,
|
||||
Mat = Material("effects/splashwake1"),
|
||||
RandomAng = math.random(0,360),
|
||||
}
|
||||
|
||||
local emitter = Ent:GetParticleEmitter( Ent:GetPos() )
|
||||
|
||||
if emitter and emitter.Add then
|
||||
local particle = emitter:Add( "effects/splash4", Pos + VectorRand(-10,10) - Vector(0,0,20) )
|
||||
if particle then
|
||||
particle:SetVelocity( Vector(0,0,250) )
|
||||
particle:SetDieTime( 0.8 )
|
||||
particle:SetAirResistance( 60 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetEndAlpha( 0 )
|
||||
particle:SetStartSize( 50 )
|
||||
particle:SetEndSize( 100 )
|
||||
particle:SetRoll( math.Rand(-1,1) * 100 )
|
||||
particle:SetColor(self.VecCol.r,self.VecCol.g,self.VecCol.b)
|
||||
particle:SetGravity( Vector( 0, 0, -600 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function EFFECT:Think()
|
||||
if CurTime() > self.DieTime then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
if self.Splash and self.LifeTime then
|
||||
local Scale = (self.DieTime - self.LifeTime - CurTime()) / self.LifeTime
|
||||
local S = 200 - Scale * 600
|
||||
local Alpha = 100 + 100 * Scale
|
||||
|
||||
cam.Start3D2D( self.Splash.Pos + Vector(0,0,1), Angle(0,0,0), 1 )
|
||||
surface.SetMaterial( self.Splash.Mat )
|
||||
surface.SetDrawColor( self.VecCol.r, self.VecCol.g, self.VecCol.b, Alpha )
|
||||
surface.DrawTexturedRectRotated( 0, 0, S , S, self.Splash.RandomAng )
|
||||
cam.End3D2D()
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,175 @@
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local Pos = data:GetOrigin()
|
||||
local Ent = data:GetEntity()
|
||||
|
||||
if not IsValid( Ent ) then return end
|
||||
|
||||
local emitter = Ent:GetParticleEmitter( Ent:GetPos() )
|
||||
|
||||
if not IsValid( emitter ) then return end
|
||||
|
||||
local Vel = Ent:GetVelocity()
|
||||
Vel.z = 0
|
||||
|
||||
local Speed = Vel:Length()
|
||||
|
||||
if Speed < 50 then return end
|
||||
|
||||
local Steer = math.abs( Ent:GetSteer() )
|
||||
|
||||
local ShouldPlaySound = false
|
||||
|
||||
local T = CurTime()
|
||||
|
||||
local LightColor = render.GetLightColor( Pos )
|
||||
local VecCol = Vector(1,1.2,1.4) * (0.06 + (0.2126 * LightColor.r) + (0.7152 * LightColor.g) + (0.0722 * LightColor.b)) * 1000
|
||||
VecCol.x = math.min( VecCol.x, 255 )
|
||||
VecCol.y = math.min( VecCol.y, 255 )
|
||||
VecCol.z = math.min( VecCol.z, 255 )
|
||||
|
||||
local mul = math.min(Speed * 0.005,1)
|
||||
local invmul = 1 - mul
|
||||
|
||||
local EntPos = Ent:GetPos()
|
||||
local Len = Ent:BoundingRadius() * 1.5
|
||||
local MoveDir = Vel:GetNormalized()
|
||||
local MoveAng = MoveDir:Angle()
|
||||
|
||||
local Target = LocalPlayer()
|
||||
|
||||
if IsValid( Target ) then
|
||||
ShouldPlaySound = Target:lvsGetVehicle() == Ent
|
||||
|
||||
local ViewEnt = Target:GetViewEntity()
|
||||
|
||||
if IsValid( ViewEnt ) then
|
||||
Target = ViewEnt
|
||||
end
|
||||
end
|
||||
|
||||
local SwapSides = math.abs( Ent:GetSteer() ) > 0.9
|
||||
local Res = math.max( math.Round( (Target:GetPos() - Pos):LengthSqr() / 2500000, 0 ), 5 )
|
||||
|
||||
for i = -135, 135, Res do
|
||||
local Dir = Angle(0,MoveAng.y+i,0):Forward()
|
||||
|
||||
local StartPos = Pos + Dir * Len
|
||||
local EndPos = Pos
|
||||
|
||||
local trace = util.TraceLine( {
|
||||
start = StartPos,
|
||||
endpos = EndPos,
|
||||
filter = Ent,
|
||||
ignoreworld = true,
|
||||
whitelist = true,
|
||||
} )
|
||||
|
||||
if not trace.Hit then continue end
|
||||
|
||||
local fxPos = Ent:WorldToLocal( trace.HitPos + trace.HitNormal * 2 )
|
||||
if SwapSides then fxPos.y = -fxPos.y end
|
||||
fxPos = Ent:LocalToWorld( fxPos )
|
||||
|
||||
local particle = emitter:Add( "effects/splash4", fxPos + Vector(0,0,math.Rand(-5,5) * mul) )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
local pfxVel = Ent:WorldToLocal( EntPos + Dir * Speed * 0.5 + trace.HitNormal * Speed * 0.25 )
|
||||
if SwapSides then pfxVel.y = -pfxVel.y end
|
||||
pfxVel = Ent:LocalToWorld( pfxVel ) - EntPos
|
||||
|
||||
local pfxMul = math.Clamp( pfxVel.z / 250, 1, 2 )
|
||||
|
||||
particle:SetVelocity( pfxVel )
|
||||
particle:SetDieTime( (math.Rand(0.8,0.8) + math.Rand(0.2,0.4) * invmul) * pfxMul )
|
||||
particle:SetAirResistance( 60 )
|
||||
particle:SetStartAlpha( ((pfxMul / 2) ^ 2) * 255 )
|
||||
particle:SetEndAlpha( 0 )
|
||||
particle:SetStartSize( 5 + math.Rand(5,10) * mul )
|
||||
particle:SetEndSize( 15 + math.Rand(10,20) * mul * pfxMul )
|
||||
particle:SetRoll( math.Rand(-1,1) * math.Rand(50,150) )
|
||||
particle:SetRollDelta( math.Rand(-1,1) * pfxMul * mul * 0.5 )
|
||||
particle:SetColor(VecCol.r,VecCol.g,VecCol.b)
|
||||
particle:SetGravity( Vector( 0, 0, -600 * math.Rand(1,1 + Steer * 3) ) - Vel * math.abs( i * 0.15 ) / 65 )
|
||||
particle:SetCollide( false )
|
||||
particle:SetNextThink( T )
|
||||
particle:SetThinkFunction( function( p )
|
||||
local fxpos = p:GetPos()
|
||||
|
||||
p:SetNextThink( CurTime() )
|
||||
|
||||
if fxpos.z > Pos.z then return end
|
||||
|
||||
p:SetDieTime( 0 )
|
||||
|
||||
if not IsValid( Ent ) or math.random(1,6) ~= 2 then return end
|
||||
|
||||
local startpos = Vector(fxpos.x,fxpos.y,Pos.z + 1)
|
||||
|
||||
local volume = math.min( math.abs( p:GetVelocity().z ) / 100, 1 )
|
||||
|
||||
if ShouldPlaySound and volume > 0.2 and p:GetStartSize() > 13 and math.random(1,10) == 1 then
|
||||
local pitch = math.Rand(95,105) * math.Clamp( 1.5 - volume * 0.9,0.5,1)
|
||||
|
||||
if pitch < 58 then
|
||||
sound.Play( "vehicles/airboat/pontoon_splash"..math.random(1,2)..".wav", startpos, 75, math.Rand(95,105), volume * 0.1, 0 )
|
||||
else
|
||||
if Speed < 600 then
|
||||
sound.Play( "ambient/water/water_splash"..math.random(1,3)..".wav", startpos, 75, pitch, volume * 0.1, 0 )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not ShouldPlaySound then return end
|
||||
|
||||
local emitter3D = Ent:GetParticleEmitter3D( Ent:GetPos() )
|
||||
|
||||
if not IsValid( emitter3D ) then return end
|
||||
|
||||
local particle = emitter3D:Add("effects/splashwake1", startpos )
|
||||
|
||||
if not particle then return end
|
||||
|
||||
local scale = math.Rand(0.5,2)
|
||||
local size = p:GetEndSize()
|
||||
local vsize = Vector(size,size,size)
|
||||
|
||||
particle:SetStartSize( size * scale * 0.5 )
|
||||
particle:SetEndSize( size * scale )
|
||||
particle:SetDieTime( math.Rand(0.5,1) )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetEndAlpha( 0 )
|
||||
particle:SetPos( startpos )
|
||||
particle:SetAngles( Angle(-90,math.Rand(-180,180),0) )
|
||||
particle:SetColor(VecCol.r,VecCol.g,VecCol.b)
|
||||
particle:SetNextThink( CurTime() )
|
||||
particle:SetThinkFunction( function( pfx )
|
||||
|
||||
local startpos = pfx:GetPos()
|
||||
local endpos = startpos - Vector(0,0,100)
|
||||
|
||||
local trace = util.TraceHull( {
|
||||
start = startpos,
|
||||
endpos = endpos,
|
||||
filter = Ent,
|
||||
whitelist = true,
|
||||
mins = -vsize,
|
||||
maxs = vsize,
|
||||
} )
|
||||
|
||||
if trace.Hit then pfx:SetDieTime( 0 ) return end
|
||||
|
||||
pfx:SetNextThink( CurTime() )
|
||||
end )
|
||||
end )
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function EFFECT:Think()
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
end
|
||||
183
garrysmod/addons/lvs_base/lua/effects/lvs_physics_wheeldust.lua
Normal file
183
garrysmod/addons/lvs_base/lua/effects/lvs_physics_wheeldust.lua
Normal file
@@ -0,0 +1,183 @@
|
||||
|
||||
EFFECT.SmokeMat = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
EFFECT.DustMat = {
|
||||
"effects/lvs_base/particle_debris_01",
|
||||
"effects/lvs_base/particle_debris_02",
|
||||
}
|
||||
|
||||
local SmokeMat = EFFECT.SmokeMat
|
||||
local function MakeDustParticle( emitter, emitter3D, pos, vel, r, g, b )
|
||||
local particle = emitter:Add( SmokeMat[ math.random(1,#SmokeMat) ], pos )
|
||||
|
||||
if not particle then return end
|
||||
|
||||
particle:SetVelocity( vel )
|
||||
particle:SetDieTime( 0.4 )
|
||||
particle:SetAirResistance( 0 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 20 )
|
||||
particle:SetEndSize( 30 )
|
||||
particle:SetRollDelta( math.Rand(-6,6) )
|
||||
particle:SetColor( r, g, b )
|
||||
particle:SetGravity( Vector(0,0,-600) )
|
||||
particle:SetCollide( false )
|
||||
particle:SetNextThink( CurTime() )
|
||||
particle:SetThinkFunction( function( p )
|
||||
if not IsValid( emitter3D ) then return end
|
||||
|
||||
p:SetNextThink( CurTime() + 0.05 )
|
||||
|
||||
local pos = p:GetPos()
|
||||
local vel = p:GetVelocity()
|
||||
|
||||
local traceData = {
|
||||
start = pos,
|
||||
endpos = pos + Vector(0,0,vel.z) * 0.06,
|
||||
mask = MASK_SOLID_BRUSHONLY,
|
||||
}
|
||||
|
||||
local trace = util.TraceLine( traceData )
|
||||
|
||||
if not trace.Hit then return end
|
||||
|
||||
p:SetEndSize( 0 )
|
||||
p:SetDieTime( 0 )
|
||||
|
||||
local pHit = emitter3D:Add( SmokeMat[ math.random(1,#SmokeMat) ], trace.HitPos + trace.HitNormal )
|
||||
pHit:SetStartSize( 15 )
|
||||
pHit:SetEndSize( 15 )
|
||||
pHit:SetDieTime( math.Rand(5,6) )
|
||||
pHit:SetStartAlpha( 50 )
|
||||
pHit:SetEndAlpha( 0 )
|
||||
pHit:SetColor( p:GetColor() )
|
||||
|
||||
local Ang = trace.HitNormal:Angle()
|
||||
Ang:RotateAroundAxis( trace.HitNormal, math.Rand(-180,180) )
|
||||
|
||||
pHit:SetAngles( Ang )
|
||||
end )
|
||||
end
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local pos = data:GetOrigin()
|
||||
local ent = data:GetEntity()
|
||||
|
||||
if not IsValid( ent ) then return end
|
||||
|
||||
local dir = data:GetNormal()
|
||||
local scale = data:GetMagnitude()
|
||||
local speed = ent:GetVelocity():LengthSqr()
|
||||
local tooSlow = speed < 30000
|
||||
local tooFast = speed > 400000
|
||||
local underwater = data:GetFlags() == 1
|
||||
|
||||
local start = ent:GetPos()
|
||||
local emitter = ent:GetParticleEmitter( start )
|
||||
local emitter3D = ent:GetParticleEmitter3D( start )
|
||||
|
||||
local VecCol
|
||||
local LightColor = render.GetLightColor( pos + dir )
|
||||
|
||||
if underwater then
|
||||
VecCol = Vector(1,1.2,1.4) * (0.06 + (0.2126 * LightColor.r) + (0.7152 * LightColor.g) + (0.0722 * LightColor.b)) * 1000
|
||||
else
|
||||
VecCol = Vector(0.3,0.25,0.15) * (0.1 + (0.2126 * LightColor.r) + (0.7152 * LightColor.g) + (0.0722 * LightColor.b)) * 1000
|
||||
end
|
||||
VecCol.x = math.min( VecCol.x, 255 )
|
||||
VecCol.y = math.min( VecCol.y, 255 )
|
||||
VecCol.z = math.min( VecCol.z, 255 )
|
||||
|
||||
local DieTime = math.Rand(0.8,1.6)
|
||||
|
||||
if not tooSlow then
|
||||
for i = 1, 5 do
|
||||
local particle = emitter:Add( self.DustMat[ math.random(1,#self.DustMat) ] , pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( (dir * 50 * i + VectorRand() * 25) * scale )
|
||||
particle:SetDieTime( (i / 8) * DieTime )
|
||||
particle:SetAirResistance( 10 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 10 * scale )
|
||||
particle:SetEndSize( 20 * i * scale )
|
||||
particle:SetRollDelta( math.Rand(-1,1) )
|
||||
particle:SetColor( VecCol.r, VecCol.g, VecCol.b )
|
||||
particle:SetGravity( Vector(0,0,-600) * scale )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, 5 do
|
||||
local particle = emitter:Add( underwater and "effects/splash4" or self.SmokeMat[ math.random(1,#self.SmokeMat) ] , pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( (dir * 50 * i + VectorRand() * 40) * scale )
|
||||
particle:SetDieTime( (i / 8) * DieTime )
|
||||
particle:SetAirResistance( 10 )
|
||||
particle:SetStartAlpha( underwarter and 150 or 255 )
|
||||
particle:SetStartSize( 10 * scale )
|
||||
particle:SetEndSize( 20 * i * scale )
|
||||
particle:SetRollDelta( math.Rand(-1,1) )
|
||||
particle:SetColor( VecCol.r, VecCol.g, VecCol.b )
|
||||
particle:SetGravity( Vector(0,0,-600) * scale )
|
||||
particle:SetCollide( false )
|
||||
|
||||
if underwater or tooFast then continue end
|
||||
|
||||
particle:SetNextThink( CurTime() )
|
||||
particle:SetThinkFunction( function( p )
|
||||
if not IsValid( ent ) or not IsValid( emitter ) or not IsValid( emitter3D ) then return end
|
||||
|
||||
p:SetNextThink( CurTime() + 0.05 )
|
||||
|
||||
local pos = p:GetPos()
|
||||
local vel = p:GetVelocity()
|
||||
local dir = vel:GetNormalized()
|
||||
local speed = vel:Length()
|
||||
|
||||
local traceData = {
|
||||
start = pos,
|
||||
endpos = pos + dir * speed * 0.06,
|
||||
whitelist = true,
|
||||
filter = ent,
|
||||
}
|
||||
local trace = util.TraceLine( traceData )
|
||||
|
||||
if not trace.Hit then return end
|
||||
|
||||
if tooSlow then
|
||||
p:SetEndSize( 0 )
|
||||
p:SetDieTime( 0 )
|
||||
end
|
||||
|
||||
MakeDustParticle( emitter, emitter3D, trace.HitPos - trace.HitNormal * 10, trace.HitNormal * 20 + VectorRand() * 40, p:GetColor() )
|
||||
end )
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
end
|
||||
@@ -0,0 +1,56 @@
|
||||
|
||||
EFFECT.SmokeMat = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local pos = data:GetOrigin()
|
||||
local ent = data:GetEntity()
|
||||
|
||||
if not IsValid( ent ) then return end
|
||||
|
||||
local dir = data:GetNormal()
|
||||
|
||||
local emitter = ent:GetParticleEmitter( ent:GetPos() )
|
||||
|
||||
local VecCol = (render.GetLightColor( pos + dir ) * 0.5 + Vector(0.3,0.3,0.3)) * 255
|
||||
|
||||
for i = 1, 2 do
|
||||
local particle = emitter:Add( self.SmokeMat[ math.random(1,#self.SmokeMat) ] , pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( VectorRand() * 50 )
|
||||
particle:SetDieTime( math.Rand(0.5,1.5) )
|
||||
particle:SetAirResistance( 10 )
|
||||
particle:SetStartAlpha( 50 )
|
||||
particle:SetStartSize( 20 )
|
||||
particle:SetEndSize( 60 )
|
||||
particle:SetRollDelta( math.Rand(-1,1) )
|
||||
particle:SetColor( math.min( VecCol.r, 255 ), math.min( VecCol.g, 255 ), math.min( VecCol.b, 255 ) )
|
||||
particle:SetGravity( Vector(0,0,5) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
end
|
||||
@@ -0,0 +1,80 @@
|
||||
|
||||
EFFECT.WaterWake = Material("effects/splashwake1")
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local Pos = data:GetOrigin() + Vector(0,0,1)
|
||||
local Ent = data:GetEntity()
|
||||
self.Size = data:GetMagnitude()
|
||||
|
||||
if not IsValid( Ent ) then return end
|
||||
|
||||
self.LifeTime = 1
|
||||
self.DieTime = CurTime() + self.LifeTime
|
||||
|
||||
local RainFX = data:GetFlags() == 1
|
||||
|
||||
if RainFX then
|
||||
self.Size = self.Size * 2
|
||||
|
||||
else
|
||||
self.Splash = {
|
||||
Pos = Pos,
|
||||
Mat = self.WaterWake,
|
||||
RandomAng = math.random(0,360),
|
||||
}
|
||||
end
|
||||
|
||||
local LightColor = render.GetLightColor( Pos )
|
||||
self.VecCol = Vector(1,1.2,1.4) * (0.06 + (0.2126 * LightColor.r) + (0.7152 * LightColor.g) + (0.0722 * LightColor.b)) * 1000
|
||||
self.VecCol.x = math.min( self.VecCol.x, 255 )
|
||||
self.VecCol.y = math.min( self.VecCol.y, 255 )
|
||||
self.VecCol.z = math.min( self.VecCol.z, 255 )
|
||||
|
||||
local emitter = Ent:GetParticleEmitter( Ent:GetPos() )
|
||||
local Vel = Ent:GetVelocity():Length()
|
||||
|
||||
for i = 1, 3 do
|
||||
if emitter and emitter.Add then
|
||||
local particle = emitter:Add( "effects/splash4", Pos + VectorRand() * self.Size * 0.1 )
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( Vector(0,0,math.Clamp(Vel / 100,100,250)) )
|
||||
particle:SetDieTime( 0.25 + math.min(Vel / 500,0.2) )
|
||||
particle:SetAirResistance( 60 )
|
||||
particle:SetStartAlpha( RainFX and 5 or 150 )
|
||||
particle:SetEndAlpha( 0 )
|
||||
particle:SetStartSize( self.Size * 0.2 )
|
||||
particle:SetEndSize( self.Size )
|
||||
particle:SetRollDelta( math.Rand(-1,1) * 5 )
|
||||
particle:SetColor( math.min( self.VecCol.r, 255 ), math.min( self.VecCol.g, 255 ), math.min( self.VecCol.b, 255 ) )
|
||||
particle:SetGravity( Vector( 0, 0, -600 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function EFFECT:Think()
|
||||
if CurTime() > self.DieTime then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
if not self.Splash or not self.LifeTime or not self.VecCol then return end
|
||||
|
||||
local Scale = 1 - (self.DieTime - CurTime()) / self.LifeTime
|
||||
|
||||
local Alpha = math.max( 100 - 150 * Scale ^ 2, 0 )
|
||||
|
||||
if Alpha <= 0 then return end
|
||||
|
||||
local Size = (self.Size + self.Size * Scale) * 1.5
|
||||
|
||||
cam.Start3D2D( self.Splash.Pos, Angle(0,0,0), 1 )
|
||||
surface.SetMaterial( self.Splash.Mat )
|
||||
surface.SetDrawColor( math.min( self.VecCol.r, 255 ), math.min( self.VecCol.g, 255 ), math.min( self.VecCol.b, 255 ), Alpha )
|
||||
surface.DrawTexturedRectRotated( 0, 0, Size, Size, self.Splash.RandomAng )
|
||||
cam.End3D2D()
|
||||
end
|
||||
119
garrysmod/addons/lvs_base/lua/effects/lvs_proton_explosion.lua
Normal file
119
garrysmod/addons/lvs_base/lua/effects/lvs_proton_explosion.lua
Normal file
@@ -0,0 +1,119 @@
|
||||
|
||||
local GlowMat = Material( "sprites/light_glow02_add" )
|
||||
local Materials = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
self.Pos = data:GetOrigin()
|
||||
|
||||
self.LifeTime = 0.4
|
||||
self.DieTime = CurTime() + self.LifeTime
|
||||
|
||||
local emitter = ParticleEmitter( self.Pos, false )
|
||||
|
||||
if not IsValid( emitter ) then return end
|
||||
|
||||
for i = 0,30 do
|
||||
local particle = emitter:Add( Materials[ math.random(1, #Materials ) ], self.Pos )
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( VectorRand(-1,1) * 800 )
|
||||
particle:SetDieTime( math.Rand(4,6) )
|
||||
particle:SetAirResistance( math.Rand(200,600) )
|
||||
particle:SetStartAlpha( 100 )
|
||||
particle:SetStartSize( math.Rand(30,60) )
|
||||
particle:SetEndSize( math.Rand(100,150) )
|
||||
particle:SetRoll( math.Rand(-1,1) )
|
||||
particle:SetColor( 50,50,50 )
|
||||
particle:SetGravity( Vector( 0, 0, 100 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
for i = 0, 20 do
|
||||
local particle = emitter:Add( "sprites/light_glow02_add", self.Pos )
|
||||
|
||||
local vel = VectorRand() * 400
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( vel )
|
||||
particle:SetAngles( vel:Angle() + Angle(0,90,0) )
|
||||
particle:SetDieTime( math.Rand(0.4,0.8) )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetEndAlpha( 0 )
|
||||
particle:SetStartSize( math.Rand(24,48) )
|
||||
particle:SetEndSize( 0 )
|
||||
particle:SetRoll( math.Rand(-100,100) )
|
||||
particle:SetRollDelta( math.Rand(-100,100) )
|
||||
particle:SetColor( 0,127,255 )
|
||||
particle:SetGravity( Vector(0,0,-600) )
|
||||
|
||||
particle:SetAirResistance( 0 )
|
||||
|
||||
particle:SetCollide( true )
|
||||
particle:SetBounce( 0.5 )
|
||||
end
|
||||
end
|
||||
|
||||
for i = 0, 40 do
|
||||
local particle = emitter:Add( "effects/lvs_base/flamelet"..math.random(1,5), self.Pos )
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( VectorRand(-1,1) * 500 )
|
||||
particle:SetDieTime( 0.14 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 10 )
|
||||
particle:SetEndSize( math.Rand(30,60) )
|
||||
particle:SetEndAlpha( 100 )
|
||||
particle:SetRoll( math.Rand( -1, 1 ) )
|
||||
particle:SetColor( 200,150,150 )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
|
||||
local Pos = self.Pos
|
||||
local ply = LocalPlayer():GetViewEntity()
|
||||
if IsValid( ply ) then
|
||||
local delay = (Pos - ply:GetPos()):Length() / 13503.9
|
||||
if delay <= 0.11 then
|
||||
sound.Play( "ambient/explosions/explode_9.wav", Pos, 85, 100, 1 - delay * 8 )
|
||||
end
|
||||
|
||||
timer.Simple( delay, function()
|
||||
sound.Play( "LVS.MISSILE_EXPLOSION", Pos )
|
||||
end )
|
||||
else
|
||||
sound.Play( "LVS.MISSILE_EXPLOSION", Pos )
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if self.DieTime < CurTime() then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
local Scale = (self.DieTime - CurTime()) / self.LifeTime
|
||||
render.SetMaterial( GlowMat )
|
||||
render.DrawSprite( self.Pos, 400 * Scale, 400 * Scale, Color( 0, 127, 255, 255) )
|
||||
render.DrawSprite( self.Pos, 100 * Scale, 100 * Scale, Color( 255, 255, 255, 255) )
|
||||
end
|
||||
92
garrysmod/addons/lvs_base/lua/effects/lvs_proton_trail.lua
Normal file
92
garrysmod/addons/lvs_base/lua/effects/lvs_proton_trail.lua
Normal file
@@ -0,0 +1,92 @@
|
||||
EFFECT.Offset = Vector(-8,0,0)
|
||||
|
||||
local GlowMat = Material( "effects/select_ring" )
|
||||
|
||||
function EFFECT:Init( data )
|
||||
self.Entity = data:GetEntity()
|
||||
|
||||
if IsValid( self.Entity ) then
|
||||
self.OldPos = self.Entity:LocalToWorld( self.Offset )
|
||||
|
||||
self.Emitter = ParticleEmitter( self.Entity:LocalToWorld( self.OldPos ), false )
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:doFX( pos )
|
||||
if not IsValid( self.Entity ) then return end
|
||||
|
||||
if IsValid( self.Emitter ) then
|
||||
local emitter = self.Emitter
|
||||
|
||||
local particle = emitter:Add( "effects/lvs_base/flamelet"..math.random(1,5), pos )
|
||||
if particle then
|
||||
particle:SetVelocity( -self.Entity:GetForward() * math.Rand(250,800) + self.Entity:GetVelocity())
|
||||
particle:SetDieTime( 1 )
|
||||
particle:SetAirResistance( 0 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 8 )
|
||||
particle:SetEndSize( 1 )
|
||||
particle:SetRoll( math.Rand(-1,1) )
|
||||
particle:SetColor( 0,0,255 )
|
||||
particle:SetGravity( Vector( 0, 0, 600 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
local particle = emitter:Add( "effects/lvs_base/flamelet"..math.random(1,5), self.Entity:GetPos() )
|
||||
if particle then
|
||||
particle:SetVelocity( -self.Entity:GetForward() * 200 + VectorRand() * 50 )
|
||||
particle:SetDieTime( 1 )
|
||||
particle:SetAirResistance( 600 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 6 )
|
||||
particle:SetEndSize( 2 )
|
||||
particle:SetRoll( math.Rand(-1,1) )
|
||||
particle:SetColor( 0,0,255 )
|
||||
particle:SetGravity( Vector( 0, 0, 600 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if IsValid( self.Entity ) then
|
||||
self.nextDFX = self.nextDFX or 0
|
||||
|
||||
if self.nextDFX < CurTime() then
|
||||
self.nextDFX = CurTime() + 0.02
|
||||
|
||||
local oldpos = self.OldPos
|
||||
local newpos = self.Entity:LocalToWorld( self.Offset )
|
||||
self:SetPos( newpos )
|
||||
|
||||
local Sub = (newpos - oldpos)
|
||||
local Dir = Sub:GetNormalized()
|
||||
local Len = Sub:Length()
|
||||
|
||||
self.OldPos = newpos
|
||||
|
||||
for i = 0, Len, 45 do
|
||||
local pos = oldpos + Dir * i
|
||||
|
||||
self:doFX( pos )
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
if IsValid( self.Emitter ) then
|
||||
self.Emitter:Finish()
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
local ent = self.Entity
|
||||
local pos = ent:LocalToWorld( self.Offset )
|
||||
|
||||
render.SetMaterial( GlowMat )
|
||||
|
||||
render.DrawSprite( pos, 100, 100, Color( 0, 127, 255, 50 ) )
|
||||
end
|
||||
@@ -0,0 +1,40 @@
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local Pos = data:GetOrigin()
|
||||
local Dir = data:GetNormal()
|
||||
local Ent = data:GetEntity()
|
||||
local Vel = Dir * 10
|
||||
|
||||
if IsValid( Ent ) then
|
||||
Vel = Ent:GetVelocity()
|
||||
end
|
||||
|
||||
local emitter = ParticleEmitter( Pos, false )
|
||||
|
||||
if not IsValid( emitter ) then return end
|
||||
|
||||
for i = 0, 12 do
|
||||
local particle = emitter:Add( "effects/gunshipmuzzle", Pos + Dir * i * 0.7 * math.random(1,2) * 0.5 )
|
||||
local Size = 1
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( Dir * 800 + Vel )
|
||||
particle:SetDieTime( 0.05 )
|
||||
particle:SetStartAlpha( 255 * Size )
|
||||
particle:SetStartSize( math.max( math.random(10,24) - i * 0.5,0.1 ) * Size )
|
||||
particle:SetEndSize( 0 )
|
||||
particle:SetRoll( math.Rand( -1, 1 ) )
|
||||
particle:SetColor( 255, 255, 255 )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
end
|
||||
@@ -0,0 +1,29 @@
|
||||
|
||||
EFFECT.MatBeam = Material( "effects/gunshiptracer" )
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local pos = data:GetOrigin()
|
||||
local dir = data:GetNormal()
|
||||
|
||||
self.ID = data:GetMaterialIndex()
|
||||
|
||||
self:SetRenderBoundsWS( pos, pos + dir * 50000 )
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if not LVS:GetBullet( self.ID ) then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
local bullet = LVS:GetBullet( self.ID )
|
||||
|
||||
local endpos = bullet:GetPos()
|
||||
local dir = bullet:GetDir()
|
||||
|
||||
local len = 500 * bullet:GetLength()
|
||||
|
||||
render.SetMaterial( self.MatBeam )
|
||||
render.DrawBeam( endpos + dir * len, endpos - dir * len, 12, 1, 0, Color( 255, 255, 255, 255 ) )
|
||||
end
|
||||
@@ -0,0 +1,29 @@
|
||||
|
||||
EFFECT.MatBeam = Material( "effects/gunshiptracer" )
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local pos = data:GetOrigin()
|
||||
local dir = data:GetNormal()
|
||||
|
||||
self.ID = data:GetMaterialIndex()
|
||||
|
||||
self:SetRenderBoundsWS( pos, pos + dir * 50000 )
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if not LVS:GetBullet( self.ID ) then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
local bullet = LVS:GetBullet( self.ID )
|
||||
|
||||
local endpos = bullet:GetPos()
|
||||
local dir = bullet:GetDir()
|
||||
|
||||
local len = 700 * bullet:GetLength()
|
||||
|
||||
render.SetMaterial( self.MatBeam )
|
||||
render.DrawBeam( endpos + dir * len, endpos - dir * len, 24, 1, 0, Color( 255, 255, 255, 255 ) )
|
||||
end
|
||||
141
garrysmod/addons/lvs_base/lua/effects/lvs_rotor_destruction.lua
Normal file
141
garrysmod/addons/lvs_base/lua/effects/lvs_rotor_destruction.lua
Normal file
@@ -0,0 +1,141 @@
|
||||
|
||||
EFFECT.BeamMaterial = Material( "particle/smokesprites_0003" )
|
||||
EFFECT.SmokeMaterials = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
self.Pos = data:GetOrigin()
|
||||
self.Radius = data:GetMagnitude()
|
||||
self.SpawnTime = CurTime()
|
||||
|
||||
self:SetAngles( data:GetNormal():Angle() )
|
||||
|
||||
self:Debris()
|
||||
self:Explosion()
|
||||
end
|
||||
|
||||
|
||||
function EFFECT:Debris()
|
||||
local emitter = ParticleEmitter( self.Pos, false )
|
||||
|
||||
if not IsValid( emitter ) then return end
|
||||
|
||||
for i = 0,30 do
|
||||
local particle = emitter:Add( "effects/fleck_tile"..math.random(1,2), self.Pos )
|
||||
|
||||
local vel = (self:GetRight() * math.Rand(-1,1) + self:GetForward() * math.Rand(-1,1) + self:GetUp() * math.Rand(-0.25,0.25)):GetNormalized() * self.Radius * 5
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( vel )
|
||||
particle:SetDieTime( 0.6 )
|
||||
particle:SetAirResistance( 25 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 5 )
|
||||
particle:SetEndSize( 5 )
|
||||
particle:SetRoll( math.Rand(-1,1) )
|
||||
particle:SetRollDelta( math.Rand(-1,1) * 10 )
|
||||
particle:SetColor( 0,0,0 )
|
||||
particle:SetGravity( Vector( 0, 0, -600 ) )
|
||||
particle:SetCollide( true )
|
||||
particle:SetBounce( 0.3 )
|
||||
end
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
end
|
||||
|
||||
|
||||
function EFFECT:Explosion()
|
||||
local emitter = ParticleEmitter( self.Pos, false )
|
||||
|
||||
if not IsValid( emitter ) then return end
|
||||
|
||||
local scale = 0.1 + self.Radius / 1000
|
||||
|
||||
for i = 0,10 do
|
||||
local particle = emitter:Add( self.SmokeMaterials[ math.random(1, #self.SmokeMaterials ) ], self.Pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( VectorRand() * 1500 * scale )
|
||||
particle:SetDieTime( math.Rand(0.75,1.5) * scale )
|
||||
particle:SetAirResistance( math.Rand(200,600) )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( math.Rand(60,120) * scale )
|
||||
particle:SetEndSize( math.Rand(220,320) * scale )
|
||||
particle:SetRoll( math.Rand(-1,1) )
|
||||
particle:SetColor( 40,40,40 )
|
||||
particle:SetGravity( Vector( 0, 0, 100 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if (self.SpawnTime + 0.15) < CurTime() then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
if not self.SpawnTime then return end
|
||||
|
||||
local pos = self:GetPos()
|
||||
|
||||
render.SetMaterial( self.BeamMaterial )
|
||||
|
||||
local segmentdist = 360 / 30
|
||||
local overlap = 10
|
||||
local Mul = math.Clamp(self.SpawnTime + 0.15 - CurTime(),0,0.15) / 0.15
|
||||
|
||||
do
|
||||
local Width = self.Radius / 2
|
||||
local Alpha = Mul * 255
|
||||
local radius = self.Radius * 0.5 * ((1 - Mul) ^ 5)
|
||||
local AngOffset = Mul * 360
|
||||
|
||||
if Alpha > 0 then
|
||||
for a = segmentdist, 360, segmentdist do
|
||||
local Ang = a + AngOffset
|
||||
local StartPos = self:LocalToWorld( Vector( math.cos( math.rad( -Ang - overlap ) ) * radius, -math.sin( math.rad( -Ang - overlap ) ) * radius, 0 ) )
|
||||
local EndPos = self:LocalToWorld( Vector( math.cos( math.rad( -Ang + overlap + segmentdist ) ) * radius, -math.sin( math.rad( -Ang + overlap + segmentdist ) ) * radius, 0 ) )
|
||||
|
||||
render.DrawBeam( StartPos, EndPos, Width, 0, 1, Color( 255, 255, 255, Alpha ) )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local Width = self.Radius / 2
|
||||
local Alpha = Mul * 255
|
||||
local radius = self.Radius * ((1 - Mul) ^ 5)
|
||||
local AngOffset = Mul * 360
|
||||
|
||||
if Alpha > 0 then
|
||||
for a = segmentdist, 360, segmentdist do
|
||||
local Ang = a + AngOffset
|
||||
local StartPos = self:LocalToWorld( Vector( math.cos( math.rad( -Ang - overlap ) ) * radius, -math.sin( math.rad( -Ang - overlap ) ) * radius, 0 ) )
|
||||
local EndPos = self:LocalToWorld( Vector( math.cos( math.rad( -Ang + overlap + segmentdist ) ) * radius, -math.sin( math.rad( -Ang + overlap + segmentdist ) ) * radius, 0 ) )
|
||||
|
||||
render.DrawBeam( StartPos, EndPos, Width, 0, 1, Color( 255, 255, 255, Alpha ) )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
85
garrysmod/addons/lvs_base/lua/effects/lvs_shield_impact.lua
Normal file
85
garrysmod/addons/lvs_base/lua/effects/lvs_shield_impact.lua
Normal file
@@ -0,0 +1,85 @@
|
||||
|
||||
local LastImpact = 0
|
||||
|
||||
function EFFECT:Init( data )
|
||||
self.Ent = data:GetEntity()
|
||||
self.Pos = data:GetOrigin()
|
||||
|
||||
self.mat = Material( "sprites/light_glow02_add" )
|
||||
|
||||
local T = CurTime()
|
||||
|
||||
self.LifeTime = 0.2
|
||||
self.DieTime = T + self.LifeTime
|
||||
|
||||
local DontHurtEars = math.Clamp( T - LastImpact, 0.4, 1 ) ^ 2
|
||||
|
||||
LastImpact = T
|
||||
|
||||
sound.Play( "lvs/shield_deflect.ogg", self.Pos, 120, 100, DontHurtEars )
|
||||
|
||||
self:Spark( self.Pos )
|
||||
|
||||
if IsValid( self.Ent ) then
|
||||
self.Model = ClientsideModel( self.Ent:GetModel(), RENDERMODE_TRANSCOLOR )
|
||||
self.Model:SetMaterial("models/alyx/emptool_glow")
|
||||
self.Model:SetColor( Color(200,220,255,255) )
|
||||
self.Model:SetParent( self.Ent, 0 )
|
||||
self.Model:SetMoveType( MOVETYPE_NONE )
|
||||
self.Model:SetLocalPos( Vector( 0, 0, 0 ) )
|
||||
self.Model:SetLocalAngles( Angle( 0, 0, 0 ) )
|
||||
self.Model:AddEffects( EF_BONEMERGE )
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:Spark( pos )
|
||||
local emitter = ParticleEmitter( pos, false )
|
||||
|
||||
for i = 0, 20 do
|
||||
local particle = emitter:Add( "sprites/rico1", pos )
|
||||
|
||||
local vel = VectorRand() * 500
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( vel )
|
||||
particle:SetAngles( vel:Angle() + Angle(0,90,0) )
|
||||
particle:SetDieTime( math.Rand(0.2,0.4) )
|
||||
particle:SetStartAlpha( math.Rand( 200, 255 ) )
|
||||
particle:SetEndAlpha( 0 )
|
||||
particle:SetStartSize( math.Rand(10,20) )
|
||||
particle:SetEndSize( 0 )
|
||||
particle:SetRoll( math.Rand(-100,100) )
|
||||
particle:SetRollDelta( math.Rand(-100,100) )
|
||||
particle:SetColor( 0, 127, 255 )
|
||||
|
||||
particle:SetAirResistance( 0 )
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if not IsValid( self.Ent ) then
|
||||
if IsValid( self.Model ) then
|
||||
self.Model:Remove()
|
||||
end
|
||||
end
|
||||
|
||||
if self.DieTime < CurTime() then
|
||||
if IsValid( self.Model ) then
|
||||
self.Model:Remove()
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
local Scale = (self.DieTime - CurTime()) / self.LifeTime
|
||||
render.SetMaterial( self.mat )
|
||||
render.DrawSprite( self.Pos, 800 * Scale, 800 * Scale, Color( 0, 127, 255, 255) )
|
||||
render.DrawSprite( self.Pos, 200 * Scale, 200 * Scale, Color( 255, 255, 255, 255) )
|
||||
end
|
||||
90
garrysmod/addons/lvs_base/lua/effects/lvs_tire_blow.lua
Normal file
90
garrysmod/addons/lvs_base/lua/effects/lvs_tire_blow.lua
Normal file
@@ -0,0 +1,90 @@
|
||||
|
||||
EFFECT.SmokeMat = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local Ent = data:GetEntity()
|
||||
|
||||
if not IsValid( Ent ) then return end
|
||||
|
||||
local Offset = Ent:GetPos()
|
||||
local Low, High = Ent:WorldSpaceAABB()
|
||||
local Vel = Ent:GetVelocity()
|
||||
|
||||
local Radius = Ent:BoundingRadius()
|
||||
|
||||
local NumParticles = Radius
|
||||
NumParticles = NumParticles * 4
|
||||
|
||||
NumParticles = math.Clamp( NumParticles, 32, 256 )
|
||||
|
||||
local emitter = ParticleEmitter( Offset )
|
||||
|
||||
for i = 0, NumParticles do
|
||||
local Pos = Vector( math.Rand( Low.x, High.x ), math.Rand( Low.y, High.y ), math.Rand( Low.z, High.z ) )
|
||||
local particle = emitter:Add( "effects/fleck_tile"..math.random(1,2), Pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( ( Pos - Offset ) * 5 + Vel * 0.5 )
|
||||
particle:SetLifeTime( 0 )
|
||||
particle:SetDieTime( math.Rand( 0.5, 1 ) )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetEndAlpha( 0 )
|
||||
particle:SetStartSize( math.Rand(3,6) * Radius * 0.025 )
|
||||
particle:SetEndSize( 1 )
|
||||
particle:SetRoll( math.Rand( 0, 360 ) )
|
||||
particle:SetRollDelta( math.Rand(-10,10) )
|
||||
|
||||
particle:SetAirResistance( 25 )
|
||||
particle:SetGravity( Vector( 0, 0, -600 ) )
|
||||
particle:SetCollide( true )
|
||||
particle:SetColor( 50, 50, 50 )
|
||||
particle:SetBounce( 0.3 )
|
||||
particle:SetLighting( true )
|
||||
end
|
||||
|
||||
for i = 1, 2 do
|
||||
local particle = emitter:Add( self.SmokeMat[ math.random(1,#self.SmokeMat) ] , Offset )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( VectorRand() * 100 * Radius + Vel * 0.5 )
|
||||
particle:SetDieTime( math.Rand(0.2,0.6) )
|
||||
particle:SetAirResistance( 200 * Radius )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 0.5 * Radius )
|
||||
particle:SetEndSize( 2 * Radius )
|
||||
particle:SetRollDelta( math.Rand(-1,1) )
|
||||
particle:SetColor( 255, 255, 255 )
|
||||
particle:SetGravity( Vector(0,0,600) )
|
||||
particle:SetCollide( false )
|
||||
particle:SetLighting( true )
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
end
|
||||
202
garrysmod/addons/lvs_base/lua/effects/lvs_tracer_autocannon.lua
Normal file
202
garrysmod/addons/lvs_base/lua/effects/lvs_tracer_autocannon.lua
Normal file
@@ -0,0 +1,202 @@
|
||||
|
||||
EFFECT.MatBeam = Material( "effects/lvs_base/spark" )
|
||||
EFFECT.MatSprite = Material( "sprites/light_glow02_add" )
|
||||
|
||||
EFFECT.MatSmoke = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local pos = data:GetOrigin()
|
||||
local dir = data:GetNormal()
|
||||
|
||||
self.ID = data:GetMaterialIndex()
|
||||
|
||||
self:SetRenderBoundsWS( pos, pos + dir * 50000 )
|
||||
|
||||
self.emitter = ParticleEmitter( pos, false )
|
||||
|
||||
self.OldPos = pos
|
||||
self.Dir = dir
|
||||
|
||||
if not self.emitter then return end
|
||||
|
||||
local VecCol = (render.GetLightColor( pos ) * 0.8 + Vector(0.2,0.2,0.2)) * 255
|
||||
for i = 0, 2 do
|
||||
local particle = self.emitter:Add( self.MatSmoke[math.random(1,#self.MatSmoke)], pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( dir * 700 + VectorRand() * 200 )
|
||||
particle:SetDieTime( math.Rand(0.5,1) )
|
||||
particle:SetAirResistance( 250 )
|
||||
particle:SetStartAlpha( 50 )
|
||||
particle:SetStartSize( 5 )
|
||||
particle:SetEndSize( 80 )
|
||||
particle:SetRollDelta( math.Rand(-1,1) )
|
||||
particle:SetColor( math.min( VecCol.r, 255 ), math.min( VecCol.g, 255 ), math.min( VecCol.b, 255 ) )
|
||||
particle:SetGravity( Vector(0,0,100) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
for i = 0, math.random(1,12) do
|
||||
local particle = self.emitter:Add( "sprites/rico1", pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( dir * 2000 + VectorRand() * 50 )
|
||||
particle:SetDieTime( math.Rand(0.1,0.2) )
|
||||
particle:SetStartAlpha( 0 )
|
||||
particle:SetEndAlpha( 5 )
|
||||
particle:SetStartSize( math.Rand(0,0.5) )
|
||||
particle:SetEndSize( math.Rand(0,0.5) )
|
||||
particle:SetRollDelta( 100 )
|
||||
particle:SetAirResistance( 0 )
|
||||
particle:SetColor( 255, 200, 120 )
|
||||
end
|
||||
|
||||
local trace = util.TraceLine( {
|
||||
start = pos,
|
||||
endpos = pos - Vector(0,0,500),
|
||||
mask = MASK_SOLID_BRUSHONLY,
|
||||
} )
|
||||
|
||||
if not trace or not trace.Hit then return end
|
||||
|
||||
local VecCol = (render.GetLightColor( trace.HitPos + trace.HitNormal ) * 0.8 + Vector(0.17,0.15,0.1)) * 255
|
||||
for i = 1, 12 do
|
||||
local particle = self.emitter:Add( self.MatSmoke[math.random(1,#self.MatSmoke)], trace.HitPos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
local ang = i * 30
|
||||
local X = math.cos( math.rad(ang) )
|
||||
local Y = math.sin( math.rad(ang) )
|
||||
|
||||
particle:SetVelocity( Vector(X,Y,0) * 1000 )
|
||||
particle:SetDieTime( math.Rand(0.5,1) )
|
||||
particle:SetAirResistance( 500 )
|
||||
particle:SetStartAlpha( 100 )
|
||||
particle:SetStartSize( 25 )
|
||||
particle:SetEndSize( 80 )
|
||||
particle:SetRollDelta( math.Rand(-1,1) )
|
||||
particle:SetColor( math.min( VecCol.r, 255 ), math.min( VecCol.g, 255 ), math.min( VecCol.b, 255 ) )
|
||||
particle:SetGravity( Vector(0,0,150) + self.Dir * 1000 )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
local ply = LocalPlayer()
|
||||
|
||||
if not IsValid( ply ) then return end
|
||||
|
||||
local ViewEnt = ply:GetViewEntity()
|
||||
|
||||
if not IsValid( ViewEnt ) then return end
|
||||
|
||||
local Intensity = 2
|
||||
local Ratio = math.min( 250 / (ViewEnt:GetPos() - trace.HitPos):Length(), 1 )
|
||||
|
||||
if Ratio < 0 then return end
|
||||
|
||||
util.ScreenShake( trace.HitPos, Intensity * Ratio, 0.1, 0.5, 250 )
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
local bullet = LVS:GetBullet( self.ID )
|
||||
|
||||
if not bullet then
|
||||
if self.emitter then
|
||||
self.emitter:Finish()
|
||||
end
|
||||
|
||||
local StartPos = self.OldPos
|
||||
local EndPos = StartPos + self.Dir * 1000
|
||||
|
||||
local trace = util.TraceLine( {
|
||||
start = StartPos,
|
||||
endpos = EndPos,
|
||||
} )
|
||||
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin( trace.HitPos )
|
||||
effectdata:SetStart( self.Dir )
|
||||
effectdata:SetEntity( trace.Entity )
|
||||
effectdata:SetNormal( trace.HitNormal )
|
||||
effectdata:SetSurfaceProp( trace.SurfaceProps )
|
||||
effectdata:SetMagnitude( 0.5 )
|
||||
util.Effect( "lvs_bullet_impact_ap", effectdata )
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
if not self.emitter then return true end
|
||||
|
||||
local Pos = bullet:GetPos()
|
||||
|
||||
self.Dir = bullet:GetDir()
|
||||
|
||||
local Sub = self.OldPos - Pos
|
||||
local Dist = Sub:Length()
|
||||
local Dir = Sub:GetNormalized()
|
||||
|
||||
local Vel = bullet.Velocity / 10
|
||||
|
||||
for i = 0, Dist, 100 do
|
||||
local cur_pos = self.OldPos + Dir * i
|
||||
|
||||
local VecCol = (render.GetLightColor( cur_pos ) * 0.8 + Vector(0.2,0.2,0.2)) * 255
|
||||
|
||||
local particle = self.emitter:Add( self.MatSmoke[math.random(1,#self.MatSmoke)], cur_pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( -Dir * Vel + VectorRand() * 10 )
|
||||
particle:SetDieTime( math.Rand(0.05,1) )
|
||||
particle:SetAirResistance( 250 )
|
||||
particle:SetStartAlpha( 100 )
|
||||
particle:SetEndAlpha( 0 )
|
||||
|
||||
particle:SetStartSize( 0 )
|
||||
particle:SetEndSize( 15 )
|
||||
|
||||
particle:SetRollDelta( 1 )
|
||||
particle:SetColor( math.min( VecCol.r, 255 ), math.min( VecCol.g, 255 ), math.min( VecCol.b, 255 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
self.OldPos = Pos
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
local bullet = LVS:GetBullet( self.ID )
|
||||
|
||||
local endpos = bullet:GetPos()
|
||||
local dir = bullet:GetDir()
|
||||
|
||||
local len = 2000 * bullet:GetLength()
|
||||
|
||||
render.SetMaterial( self.MatBeam )
|
||||
|
||||
render.DrawBeam( endpos - dir * len, endpos + dir * len * 0.1, 10, 1, 0, Color( 100, 100, 100, 100 ) )
|
||||
render.DrawBeam( endpos - dir * len * 0.5, endpos + dir * len * 0.1, 5, 1, 0, Color( 255, 255, 255, 255 ) )
|
||||
|
||||
render.SetMaterial( self.MatSprite )
|
||||
render.DrawSprite( endpos, 400, 400, Color( 100, 100, 100, 255 ) )
|
||||
end
|
||||
187
garrysmod/addons/lvs_base/lua/effects/lvs_tracer_cannon.lua
Normal file
187
garrysmod/addons/lvs_base/lua/effects/lvs_tracer_cannon.lua
Normal file
@@ -0,0 +1,187 @@
|
||||
|
||||
EFFECT.MatBeam = Material( "effects/lvs_base/spark" )
|
||||
EFFECT.MatSprite = Material( "sprites/light_glow02_add" )
|
||||
|
||||
EFFECT.MatSmoke = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local pos = data:GetOrigin()
|
||||
local dir = data:GetNormal()
|
||||
|
||||
self.ID = data:GetMaterialIndex()
|
||||
|
||||
self:SetRenderBoundsWS( pos, pos + dir * 50000 )
|
||||
|
||||
self.emitter = ParticleEmitter( pos, false )
|
||||
|
||||
self.OldPos = pos
|
||||
self.Dir = dir
|
||||
|
||||
if not self.emitter then return end
|
||||
|
||||
local VecCol = (render.GetLightColor( pos ) * 0.8 + Vector(0.2,0.2,0.2)) * 255
|
||||
for i = 0,10 do
|
||||
local particle = self.emitter:Add( self.MatSmoke[math.random(1,#self.MatSmoke)], pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( dir * 700 + VectorRand() * 200 )
|
||||
particle:SetDieTime( math.Rand(2,3) )
|
||||
particle:SetAirResistance( 250 )
|
||||
particle:SetStartAlpha( 50 )
|
||||
particle:SetStartSize( 5 )
|
||||
particle:SetEndSize( 120 )
|
||||
particle:SetRollDelta( math.Rand(-1,1) )
|
||||
particle:SetColor( math.min( VecCol.r, 255 ), math.min( VecCol.g, 255 ), math.min( VecCol.b, 255 ) )
|
||||
particle:SetGravity( Vector(0,0,100) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
local trace = util.TraceLine( {
|
||||
start = pos,
|
||||
endpos = pos - Vector(0,0,500),
|
||||
mask = MASK_SOLID_BRUSHONLY,
|
||||
} )
|
||||
|
||||
if not trace or not trace.Hit then return end
|
||||
|
||||
local VecCol = (render.GetLightColor( trace.HitPos + trace.HitNormal ) * 0.8 + Vector(0.17,0.15,0.1)) * 255
|
||||
for i = 1,24 do
|
||||
local particle = self.emitter:Add( self.MatSmoke[math.random(1,#self.MatSmoke)], trace.HitPos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
local ang = i * 15
|
||||
local X = math.cos( math.rad(ang) )
|
||||
local Y = math.sin( math.rad(ang) )
|
||||
|
||||
particle:SetVelocity( Vector(X,Y,0) * 2000 )
|
||||
particle:SetDieTime( math.Rand(0.5,1) )
|
||||
particle:SetAirResistance( 500 )
|
||||
particle:SetStartAlpha( 100 )
|
||||
particle:SetStartSize( 25 )
|
||||
particle:SetEndSize( 120 )
|
||||
particle:SetRollDelta( math.Rand(-1,1) )
|
||||
particle:SetColor( math.min( VecCol.r, 255 ), math.min( VecCol.g, 255 ), math.min( VecCol.b, 255 ) )
|
||||
particle:SetGravity( Vector(0,0,150) + self.Dir * 2000 )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
local ply = LocalPlayer()
|
||||
|
||||
if not IsValid( ply ) then return end
|
||||
|
||||
local ViewEnt = ply:GetViewEntity()
|
||||
|
||||
if not IsValid( ViewEnt ) then return end
|
||||
|
||||
local Intensity = 8
|
||||
local Ratio = math.min( 250 / (ViewEnt:GetPos() - trace.HitPos):Length(), 1 )
|
||||
|
||||
if Ratio < 0 then return end
|
||||
|
||||
util.ScreenShake( trace.HitPos, Intensity * Ratio, 0.1, 0.5, 250 )
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
local bullet = LVS:GetBullet( self.ID )
|
||||
|
||||
if not bullet then
|
||||
if self.emitter then
|
||||
self.emitter:Finish()
|
||||
end
|
||||
|
||||
local StartPos = self.OldPos
|
||||
local EndPos = StartPos + self.Dir * 1000
|
||||
|
||||
local trace = util.TraceLine( {
|
||||
start = StartPos,
|
||||
endpos = EndPos,
|
||||
} )
|
||||
|
||||
if not trace.Hit then return false end
|
||||
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin( trace.HitPos )
|
||||
effectdata:SetStart( self.Dir )
|
||||
effectdata:SetEntity( trace.Entity )
|
||||
effectdata:SetNormal( trace.HitNormal )
|
||||
effectdata:SetSurfaceProp( trace.SurfaceProps )
|
||||
effectdata:SetMagnitude( 1 )
|
||||
util.Effect( "lvs_bullet_impact_ap", effectdata )
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
if not self.emitter then return true end
|
||||
|
||||
local Pos = bullet:GetPos()
|
||||
|
||||
self.Dir = bullet:GetDir()
|
||||
|
||||
local Sub = self.OldPos - Pos
|
||||
local Dist = Sub:Length()
|
||||
local Dir = Sub:GetNormalized()
|
||||
|
||||
local Vel = bullet.Velocity / 10
|
||||
|
||||
for i = 0, Dist, 25 do
|
||||
local cur_pos = self.OldPos + Dir * i
|
||||
|
||||
local VecCol = (render.GetLightColor( cur_pos ) * 0.8 + Vector(0.2,0.2,0.2)) * 255
|
||||
|
||||
local particle = self.emitter:Add( self.MatSmoke[math.random(1,#self.MatSmoke)], cur_pos )
|
||||
|
||||
if not particle then continue end
|
||||
particle:SetVelocity( -Dir * Vel + VectorRand() * 10 )
|
||||
particle:SetDieTime( math.Rand(0.05,1) )
|
||||
particle:SetAirResistance( 250 )
|
||||
particle:SetStartAlpha( 100 )
|
||||
particle:SetEndAlpha( 0 )
|
||||
|
||||
particle:SetStartSize( 0 )
|
||||
particle:SetEndSize( 30 )
|
||||
|
||||
particle:SetRollDelta( 1 )
|
||||
particle:SetColor( math.min( VecCol.r, 255 ), math.min( VecCol.g, 255 ), math.min( VecCol.b, 255 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
self.OldPos = Pos
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
local bullet = LVS:GetBullet( self.ID )
|
||||
|
||||
local endpos = bullet:GetPos()
|
||||
local dir = bullet:GetDir()
|
||||
|
||||
local len = 3000 * bullet:GetLength()
|
||||
|
||||
render.SetMaterial( self.MatBeam )
|
||||
|
||||
render.DrawBeam( endpos - dir * len, endpos + dir * len * 0.1, 32, 1, 0, Color( 100, 100, 100, 100 ) )
|
||||
render.DrawBeam( endpos - dir * len * 0.5, endpos + dir * len * 0.1, 16, 1, 0, Color( 255, 255, 255, 255 ) )
|
||||
|
||||
render.SetMaterial( self.MatSprite )
|
||||
render.DrawSprite( endpos, 250, 250, Color( 100, 100, 100, 255 ) )
|
||||
end
|
||||
30
garrysmod/addons/lvs_base/lua/effects/lvs_tracer_green.lua
Normal file
30
garrysmod/addons/lvs_base/lua/effects/lvs_tracer_green.lua
Normal file
@@ -0,0 +1,30 @@
|
||||
|
||||
EFFECT.MatBeam = Material( "effects/lvs_base/spark" )
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local pos = data:GetOrigin()
|
||||
local dir = data:GetNormal()
|
||||
|
||||
self.ID = data:GetMaterialIndex()
|
||||
|
||||
self:SetRenderBoundsWS( pos, pos + dir * 50000 )
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if not LVS:GetBullet( self.ID ) then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
local bullet = LVS:GetBullet( self.ID )
|
||||
|
||||
local endpos = bullet:GetPos()
|
||||
local dir = bullet:GetDir()
|
||||
|
||||
local len = 1600 * bullet:GetLength()
|
||||
|
||||
render.SetMaterial( self.MatBeam )
|
||||
render.DrawBeam( endpos - dir * len, endpos + dir * len, 3, 1, 0, Color( 225, 255, 225, 255 ) )
|
||||
render.DrawBeam( endpos - dir * len, endpos + dir * len, 10, 1, 0, Color( 150, 200, 150, 255 ) )
|
||||
end
|
||||
128
garrysmod/addons/lvs_base/lua/effects/lvs_tracer_missile.lua
Normal file
128
garrysmod/addons/lvs_base/lua/effects/lvs_tracer_missile.lua
Normal file
@@ -0,0 +1,128 @@
|
||||
|
||||
EFFECT.MatBeam = Material( "effects/lvs_base/spark" )
|
||||
EFFECT.MatSprite = Material( "sprites/light_glow02_add" )
|
||||
|
||||
EFFECT.MatSmoke = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local pos = data:GetOrigin()
|
||||
local dir = data:GetNormal()
|
||||
|
||||
self.ID = data:GetMaterialIndex()
|
||||
|
||||
self:SetRenderBoundsWS( pos, pos + dir * 50000 )
|
||||
|
||||
self.emitter = ParticleEmitter( pos, false )
|
||||
|
||||
self.OldPos = pos
|
||||
self.Dir = dir
|
||||
end
|
||||
|
||||
function EFFECT:doFX( pos, curpos )
|
||||
if not IsValid( self.emitter ) then return end
|
||||
|
||||
local particle = self.emitter:Add( self.MatSmoke[ math.random(1, #self.MatSmoke ) ], pos )
|
||||
if particle then
|
||||
particle:SetGravity( Vector(0,0,100) + VectorRand() * 50 )
|
||||
particle:SetVelocity( -self.Dir * 200 )
|
||||
particle:SetAirResistance( 600 )
|
||||
particle:SetDieTime( math.Rand(1.5,2) )
|
||||
particle:SetStartAlpha( 50 )
|
||||
particle:SetStartSize( 20 )
|
||||
particle:SetEndSize( 60 )
|
||||
particle:SetRoll( math.Rand( -1, 1 ) )
|
||||
particle:SetRollDelta( math.Rand( -1, 1 ) )
|
||||
particle:SetColor(40,40,40)
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
local particle = self.emitter:Add( "particles/flamelet"..math.random(1,5), pos )
|
||||
if particle then
|
||||
particle:SetVelocity( -self.Dir * math.Rand(250,800) + self.Dir * 1500 )
|
||||
particle:SetDieTime( math.Rand(0.2,0.4) )
|
||||
particle:SetAirResistance( 0 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 8 )
|
||||
particle:SetEndSize( 1 )
|
||||
particle:SetRoll( math.Rand(-1,1) )
|
||||
particle:SetColor( 255,255,255 )
|
||||
particle:SetGravity( Vector( 0, 0, 0 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
local particle = self.emitter:Add( "particles/flamelet"..math.random(1,5), curpos )
|
||||
if particle then
|
||||
particle:SetVelocity( -self.Dir * 200 + VectorRand() * 50 )
|
||||
particle:SetDieTime( 0.25 )
|
||||
particle:SetAirResistance( 600 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 6 )
|
||||
particle:SetEndSize( 2 )
|
||||
particle:SetRoll( math.Rand(-1,1) )
|
||||
particle:SetColor( 255,255,255 )
|
||||
particle:SetGravity( Vector( 0, 0, 0 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if not LVS:GetBullet( self.ID ) then
|
||||
if self.emitter then
|
||||
self.emitter:Finish()
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
if not self.emitter then return true end
|
||||
|
||||
local T = CurTime()
|
||||
|
||||
if (self.nextDFX or 0) <= T then
|
||||
self.nextDFX = T + 0.02
|
||||
|
||||
local bullet = LVS:GetBullet( self.ID )
|
||||
|
||||
local Pos = bullet:GetPos()
|
||||
|
||||
local Sub = self.OldPos - Pos
|
||||
local Dist = Sub:Length()
|
||||
local Dir = Sub:GetNormalized()
|
||||
|
||||
for i = 0, Dist, 45 do
|
||||
local cur_pos = self.OldPos + Dir * i
|
||||
|
||||
self:doFX( cur_pos, Pos )
|
||||
end
|
||||
|
||||
self.OldPos = Pos
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
local bullet = LVS:GetBullet( self.ID )
|
||||
|
||||
local pos = bullet:GetPos()
|
||||
|
||||
render.SetMaterial( self.MatSprite )
|
||||
render.DrawSprite( pos, 100, 100, Color( 255, 200, 150, 255 ) )
|
||||
end
|
||||
30
garrysmod/addons/lvs_base/lua/effects/lvs_tracer_orange.lua
Normal file
30
garrysmod/addons/lvs_base/lua/effects/lvs_tracer_orange.lua
Normal file
@@ -0,0 +1,30 @@
|
||||
|
||||
EFFECT.MatBeam = Material( "effects/lvs_base/spark" )
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local pos = data:GetOrigin()
|
||||
local dir = data:GetNormal()
|
||||
|
||||
self.ID = data:GetMaterialIndex()
|
||||
|
||||
self:SetRenderBoundsWS( pos, pos + dir * 50000 )
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if not LVS:GetBullet( self.ID ) then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
local bullet = LVS:GetBullet( self.ID )
|
||||
|
||||
local endpos = bullet:GetPos()
|
||||
local dir = bullet:GetDir()
|
||||
|
||||
local len = 1600 * bullet:GetLength()
|
||||
|
||||
render.SetMaterial( self.MatBeam )
|
||||
render.DrawBeam( endpos - dir * len, endpos + dir * len, 3, 1, 0, Color( 255, 255, 0, 255 ) )
|
||||
render.DrawBeam( endpos - dir * len, endpos + dir * len, 10, 1, 0, Color( 125, 50, 0, 255 ) )
|
||||
end
|
||||
104
garrysmod/addons/lvs_base/lua/effects/lvs_tracer_proton.lua
Normal file
104
garrysmod/addons/lvs_base/lua/effects/lvs_tracer_proton.lua
Normal file
@@ -0,0 +1,104 @@
|
||||
|
||||
EFFECT.GlowColor = Color( 0, 127, 255, 255 )
|
||||
EFFECT.GlowMat = Material( "sprites/light_glow02_add" )
|
||||
|
||||
EFFECT.MatSprite = Material( "effects/select_ring" )
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local pos = data:GetOrigin()
|
||||
local dir = data:GetNormal()
|
||||
|
||||
self.ID = data:GetMaterialIndex()
|
||||
|
||||
self:SetRenderBoundsWS( pos, pos + dir * 50000 )
|
||||
|
||||
self.emitter = ParticleEmitter( pos, false )
|
||||
|
||||
self.OldPos = pos
|
||||
self.Dir = dir
|
||||
end
|
||||
|
||||
function EFFECT:doFX( pos, curpos )
|
||||
if not IsValid( self.emitter ) then return end
|
||||
|
||||
local particle = self.emitter:Add( "particles/flamelet"..math.random(1,5), pos )
|
||||
if particle then
|
||||
particle:SetVelocity( -self.Dir * math.Rand(250,800) + self.Dir * 5000 )
|
||||
particle:SetDieTime( math.Rand(0.2,0.4) )
|
||||
particle:SetAirResistance( 0 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 8 )
|
||||
particle:SetEndSize( 1 )
|
||||
particle:SetRoll( math.Rand(-1,1) )
|
||||
particle:SetColor( 0,0,255 )
|
||||
particle:SetGravity( Vector( 0, 0, 600 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
local particle = self.emitter:Add( "particles/flamelet"..math.random(1,5), curpos )
|
||||
if particle then
|
||||
particle:SetVelocity( self.Dir * 5000 + VectorRand() * 50 )
|
||||
particle:SetDieTime( 1 )
|
||||
particle:SetAirResistance( 600 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 6 )
|
||||
particle:SetEndSize( 2 )
|
||||
particle:SetRoll( math.Rand(-1,1) )
|
||||
particle:SetColor( 0,0,255 )
|
||||
particle:SetGravity( Vector( 0, 0, 600 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if not LVS:GetBullet( self.ID ) then
|
||||
if self.emitter then
|
||||
self.emitter:Finish()
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
if not self.emitter then return true end
|
||||
|
||||
local T = CurTime()
|
||||
|
||||
if (self.nextDFX or 0) <= T then
|
||||
self.nextDFX = T + 0.02
|
||||
|
||||
local bullet = LVS:GetBullet( self.ID )
|
||||
|
||||
local Pos = bullet:GetPos()
|
||||
|
||||
local Sub = self.OldPos - Pos
|
||||
local Dist = Sub:Length()
|
||||
local Dir = Sub:GetNormalized()
|
||||
|
||||
for i = 0, Dist, 45 do
|
||||
local cur_pos = self.OldPos + Dir * i
|
||||
|
||||
self:doFX( cur_pos, Pos )
|
||||
end
|
||||
|
||||
self.OldPos = Pos
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
local bullet = LVS:GetBullet( self.ID )
|
||||
|
||||
local pos = bullet:GetPos()
|
||||
|
||||
render.SetMaterial( self.MatSprite )
|
||||
render.DrawSprite( pos, 100, 100, Color( 0, 127, 255, 50 ) )
|
||||
|
||||
render.SetMaterial( self.GlowMat )
|
||||
|
||||
for i = 0, 30 do
|
||||
local Size = ((30 - i) / 30) ^ 2 * 128
|
||||
|
||||
render.DrawSprite( pos - self.Dir * i * 7, Size, Size, self.GlowColor )
|
||||
end
|
||||
end
|
||||
30
garrysmod/addons/lvs_base/lua/effects/lvs_tracer_white.lua
Normal file
30
garrysmod/addons/lvs_base/lua/effects/lvs_tracer_white.lua
Normal file
@@ -0,0 +1,30 @@
|
||||
|
||||
EFFECT.MatBeam = Material( "effects/lvs_base/spark" )
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local pos = data:GetOrigin()
|
||||
local dir = data:GetNormal()
|
||||
|
||||
self.ID = data:GetMaterialIndex()
|
||||
|
||||
self:SetRenderBoundsWS( pos, pos + dir * 50000 )
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if not LVS:GetBullet( self.ID ) then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
local bullet = LVS:GetBullet( self.ID )
|
||||
|
||||
local endpos = bullet:GetPos()
|
||||
local dir = bullet:GetDir()
|
||||
|
||||
local len = 1600 * bullet:GetLength()
|
||||
|
||||
render.SetMaterial( self.MatBeam )
|
||||
render.DrawBeam( endpos - dir * len, endpos + dir * len, 3, 1, 0, Color( 255, 255, 255, 255 ) )
|
||||
render.DrawBeam( endpos - dir * len, endpos + dir * len, 10, 1, 0, Color( 150, 150, 150, 255 ) )
|
||||
end
|
||||
30
garrysmod/addons/lvs_base/lua/effects/lvs_tracer_yellow.lua
Normal file
30
garrysmod/addons/lvs_base/lua/effects/lvs_tracer_yellow.lua
Normal file
@@ -0,0 +1,30 @@
|
||||
|
||||
EFFECT.MatBeam = Material( "effects/lvs_base/spark" )
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local pos = data:GetOrigin()
|
||||
local dir = data:GetNormal()
|
||||
|
||||
self.ID = data:GetMaterialIndex()
|
||||
|
||||
self:SetRenderBoundsWS( pos, pos + dir * 50000 )
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if not LVS:GetBullet( self.ID ) then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
local bullet = LVS:GetBullet( self.ID )
|
||||
|
||||
local endpos = bullet:GetPos()
|
||||
local dir = bullet:GetDir()
|
||||
|
||||
local len = 1600 * bullet:GetLength()
|
||||
|
||||
render.SetMaterial( self.MatBeam )
|
||||
render.DrawBeam( endpos - dir * len, endpos + dir * len, 3, 1, 0, Color( 255, 255, 125, 255 ) )
|
||||
render.DrawBeam( endpos - dir * len, endpos + dir * len, 10, 1, 0, Color( 125, 80, 0, 255 ) )
|
||||
end
|
||||
@@ -0,0 +1,30 @@
|
||||
|
||||
EFFECT.MatBeam = Material( "effects/lvs_base/spark" )
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local pos = data:GetOrigin()
|
||||
local dir = data:GetNormal()
|
||||
|
||||
self.ID = data:GetMaterialIndex()
|
||||
|
||||
self:SetRenderBoundsWS( pos, pos + dir * 50000 )
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if not LVS:GetBullet( self.ID ) then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
local bullet = LVS:GetBullet( self.ID )
|
||||
|
||||
local endpos = bullet:GetPos()
|
||||
local dir = bullet:GetDir()
|
||||
|
||||
local len = 500 * bullet:GetLength()
|
||||
|
||||
render.SetMaterial( self.MatBeam )
|
||||
render.DrawBeam( endpos - dir * len, endpos + dir * len, 4, 1, 0, Color( 255, 255, 125, 255 ) )
|
||||
render.DrawBeam( endpos - dir * len, endpos + dir * len, 8, 1, 0, Color( 125, 80, 0, 255 ) )
|
||||
end
|
||||
@@ -0,0 +1,81 @@
|
||||
|
||||
local Materials = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local pos = data:GetOrigin()
|
||||
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin( pos )
|
||||
util.Effect( "cball_explode", effectdata, true, true )
|
||||
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin( pos )
|
||||
effectdata:SetNormal( Vector(0,0,1) )
|
||||
util.Effect( "manhacksparks", effectdata, true, true )
|
||||
|
||||
local emitter = ParticleEmitter( pos, false )
|
||||
|
||||
for i = 0,30 do
|
||||
local particle = emitter:Add( "effects/fleck_tile"..math.random(1,2), pos )
|
||||
local vel = VectorRand() * math.Rand(150,200)
|
||||
vel.z = math.Rand(200,250)
|
||||
if not particle then continue end
|
||||
|
||||
particle:SetVelocity( vel )
|
||||
particle:SetDieTime( math.Rand(2,6) )
|
||||
particle:SetAirResistance( 10 )
|
||||
particle:SetStartAlpha( 255 )
|
||||
particle:SetStartSize( 2 )
|
||||
particle:SetEndSize( 2 )
|
||||
particle:SetRoll( math.Rand(-1,1) * math.pi )
|
||||
particle:SetColor( 0,0,0 )
|
||||
particle:SetGravity( Vector( 0, 0, -600 ) )
|
||||
particle:SetCollide( true )
|
||||
particle:SetBounce( 0.3 )
|
||||
end
|
||||
|
||||
for i = 0,4 do
|
||||
local particle = emitter:Add( Materials[ math.random(1, #Materials ) ], pos )
|
||||
|
||||
local vel = VectorRand() * 200
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( vel )
|
||||
particle:SetDieTime( math.Rand(2.5,5) )
|
||||
particle:SetAirResistance( 100 )
|
||||
particle:SetStartAlpha( 200 )
|
||||
particle:SetStartSize( 50 )
|
||||
particle:SetEndSize( 200 )
|
||||
particle:SetRoll( math.Rand(-5,5) )
|
||||
particle:SetColor( 10,10,10 )
|
||||
particle:SetGravity( Vector(0,0,20) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
end
|
||||
84
garrysmod/addons/lvs_base/lua/effects/lvs_truck_exhaust.lua
Normal file
84
garrysmod/addons/lvs_base/lua/effects/lvs_truck_exhaust.lua
Normal file
@@ -0,0 +1,84 @@
|
||||
|
||||
local Materials = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local Pos = data:GetOrigin()
|
||||
local Dir = data:GetNormal()
|
||||
local Ent = data:GetEntity()
|
||||
|
||||
if not IsValid( Ent ) or not isfunction( Ent.GetThrottle ) then return end
|
||||
|
||||
local Engine = Ent:GetEngine()
|
||||
|
||||
if not IsValid( Engine ) or not isfunction( Engine.GetRPM ) then return end
|
||||
|
||||
local Vel = Ent:GetVelocity()
|
||||
|
||||
local emitter = Ent:GetParticleEmitter( Pos )
|
||||
|
||||
if not IsValid( emitter ) then return end
|
||||
|
||||
local throttle = math.min( Ent:GetThrottle() / 0.5, 1 )
|
||||
local clutch = Ent:GetQuickVar( "clutch" )
|
||||
local hasClutch = Ent:HasQuickVar( "clutch" )
|
||||
local ClutchActive = Engine:GetClutch()
|
||||
if not clutch then
|
||||
clutch = ClutchActive and 1 or 0
|
||||
end
|
||||
if ClutchActive then
|
||||
throttle = math.max( throttle - clutch, 0 )
|
||||
end
|
||||
|
||||
local Scale = math.min( (math.max( Engine:GetRPM() - Ent.EngineIdleRPM, 0 ) / (Ent.EngineMaxRPM - Ent.EngineIdleRPM)) * (throttle ^ 2), 1 )
|
||||
|
||||
local temp = 0
|
||||
if Ent:HasQuickVar("temp") then
|
||||
temp = math.Clamp( 1 - Ent:GetQuickVar( "temp" ) / 0.5, 0, 1 )
|
||||
end
|
||||
|
||||
local Col = 50 + 205 * temp
|
||||
|
||||
Col = Col - (Scale * Col)
|
||||
|
||||
local particle = emitter:Add( Materials[ math.random(1, #Materials ) ], Pos )
|
||||
|
||||
if not particle then return end
|
||||
|
||||
local invert = (1 - Dir.z) / 2
|
||||
|
||||
particle:SetVelocity( Vel + Dir * (100 + math.min( 800 * Scale, 300)) + VectorRand() * 50 * Scale + (Ent:GetVelocity() * 0.5 + Vector(0,0,Scale * 100)) * invert )
|
||||
particle:SetDieTime( math.max((1.4 - temp) - Ent:GetVelocity():LengthSqr() * 0.0001,0.2) + Scale * math.Rand(0.8,1.2) )
|
||||
particle:SetAirResistance( 400 )
|
||||
particle:SetStartAlpha( 100 - 50 * temp + Scale * 150 )
|
||||
particle:SetStartSize( 2 + (throttle + Scale) * 4 )
|
||||
particle:SetEndSize( 10 + 35 * (throttle + Scale) )
|
||||
particle:SetRoll( math.Rand( -1, 1 ) )
|
||||
particle:SetRollDelta( math.Rand( -1, 1 ) * (2 - Scale * 1.75) )
|
||||
particle:SetColor( Col, Col, Col )
|
||||
particle:SetGravity( Vector( 0, 0, 10 + Scale * 300 ) + Ent:GetVelocity() * 4 )
|
||||
particle:SetCollide( true )
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
end
|
||||
43
garrysmod/addons/lvs_base/lua/effects/lvs_update.lua
Normal file
43
garrysmod/addons/lvs_base/lua/effects/lvs_update.lua
Normal file
@@ -0,0 +1,43 @@
|
||||
|
||||
function EFFECT:Init( data )
|
||||
self.Ent = data:GetEntity()
|
||||
self.Pos = data:GetOrigin()
|
||||
|
||||
local T = CurTime()
|
||||
|
||||
self.LifeTime = 1
|
||||
self.DieTime = T + self.LifeTime
|
||||
|
||||
if IsValid( self.Ent ) then
|
||||
self.Model = ClientsideModel( self.Ent:GetModel(), RENDERMODE_TRANSCOLOR )
|
||||
self.Model:SetMaterial("models/alyx/emptool_glow")
|
||||
self.Model:SetColor( Color(0,127,255,255) )
|
||||
self.Model:SetParent( self.Ent, 0 )
|
||||
self.Model:SetMoveType( MOVETYPE_NONE )
|
||||
self.Model:SetLocalPos( Vector( 0, 0, 0 ) )
|
||||
self.Model:SetLocalAngles( Angle( 0, 0, 0 ) )
|
||||
self.Model:AddEffects( EF_BONEMERGE )
|
||||
self.Model:SetModelScale( self.Ent:GetModelScale() )
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if not IsValid( self.Ent ) then
|
||||
if IsValid( self.Model ) then
|
||||
self.Model:Remove()
|
||||
end
|
||||
end
|
||||
|
||||
if self.DieTime < CurTime() then
|
||||
if IsValid( self.Model ) then
|
||||
self.Model:Remove()
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
end
|
||||
43
garrysmod/addons/lvs_base/lua/effects/lvs_upgrade.lua
Normal file
43
garrysmod/addons/lvs_base/lua/effects/lvs_upgrade.lua
Normal file
@@ -0,0 +1,43 @@
|
||||
|
||||
function EFFECT:Init( data )
|
||||
self.Ent = data:GetEntity()
|
||||
self.Pos = data:GetOrigin()
|
||||
|
||||
local T = CurTime()
|
||||
|
||||
self.LifeTime = 1
|
||||
self.DieTime = T + self.LifeTime
|
||||
|
||||
if IsValid( self.Ent ) then
|
||||
self.Model = ClientsideModel( self.Ent:GetModel(), RENDERMODE_TRANSCOLOR )
|
||||
self.Model:SetMaterial("models/alyx/emptool_glow")
|
||||
self.Model:SetColor( Color(255,200,50,255) )
|
||||
self.Model:SetParent( self.Ent, 0 )
|
||||
self.Model:SetMoveType( MOVETYPE_NONE )
|
||||
self.Model:SetLocalPos( Vector( 0, 0, 0 ) )
|
||||
self.Model:SetLocalAngles( Angle( 0, 0, 0 ) )
|
||||
self.Model:AddEffects( EF_BONEMERGE )
|
||||
self.Model:SetModelScale( self.Ent:GetModelScale() )
|
||||
end
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if not IsValid( self.Ent ) then
|
||||
if IsValid( self.Model ) then
|
||||
self.Model:Remove()
|
||||
end
|
||||
end
|
||||
|
||||
if self.DieTime < CurTime() then
|
||||
if IsValid( self.Model ) then
|
||||
self.Model:Remove()
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
end
|
||||
54
garrysmod/addons/lvs_base/lua/effects/lvs_walker_stomp.lua
Normal file
54
garrysmod/addons/lvs_base/lua/effects/lvs_walker_stomp.lua
Normal file
@@ -0,0 +1,54 @@
|
||||
local Materials = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
function EFFECT:Init( data )
|
||||
local pos = data:GetOrigin()
|
||||
|
||||
local emitter = ParticleEmitter( pos, false )
|
||||
|
||||
for i = 1,12 do
|
||||
local particle = emitter:Add( Materials[ math.random(1, #Materials ) ],pos )
|
||||
|
||||
if not particle then continue end
|
||||
|
||||
local ang = i * 30
|
||||
local X = math.cos( math.rad(ang) )
|
||||
local Y = math.sin( math.rad(ang) )
|
||||
|
||||
particle:SetVelocity( Vector(X,Y,0) * math.Rand(3000,4000) )
|
||||
particle:SetDieTime( math.Rand(0.5,1) )
|
||||
particle:SetAirResistance( math.Rand(3000,5000) )
|
||||
particle:SetStartAlpha( 100 )
|
||||
particle:SetStartSize( 20 )
|
||||
particle:SetEndSize( math.Rand(30,40) )
|
||||
particle:SetRoll( math.Rand(-1,1) )
|
||||
particle:SetColor( 60,60,60 )
|
||||
particle:SetGravity( VectorRand() * 200 + Vector(0,0,1000) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
|
||||
emitter:Finish()
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
return false
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
end
|
||||
@@ -0,0 +1,63 @@
|
||||
|
||||
local MuzzleFX = Material("sprites/strider_blackball")
|
||||
local BeamFX = Material("sprites/bluelaser1")
|
||||
local WarpFX = Material("particle/warp5_warp")
|
||||
|
||||
function EFFECT:Init( data )
|
||||
self.Ent = data:GetEntity()
|
||||
|
||||
if not IsValid( self.Ent ) then return end
|
||||
|
||||
self.LifeTime = 2
|
||||
self.DieTime = CurTime() + self.LifeTime
|
||||
|
||||
self.Ent:EmitSound( "NPC_Strider.Charge" )
|
||||
|
||||
self:SetRenderBoundsWS( self.Ent:GetPos(), self.Ent:GetPos() - self.Ent:GetUp() * 50000 )
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if (self.DieTime or 0) < CurTime() then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
if not IsValid( self.Ent ) then return end
|
||||
|
||||
local Muzzle = self.Ent:GetAttachment( self.Ent:LookupAttachment( "bellygun" ) )
|
||||
|
||||
if not Muzzle then return end
|
||||
|
||||
local T = CurTime()
|
||||
local Delta = ((T + self.LifeTime) - self.DieTime) / self.LifeTime
|
||||
|
||||
local trace = util.TraceLine( {
|
||||
start = Muzzle.Pos,
|
||||
endpos = Muzzle.Pos + self.Ent:GetAimVector() * 50000,
|
||||
mask = MASK_SOLID_BRUSHONLY
|
||||
} )
|
||||
|
||||
self:SetRenderBoundsWS( Muzzle.Pos, trace.HitPos )
|
||||
|
||||
render.SetMaterial( MuzzleFX )
|
||||
render.DrawSprite( Muzzle.Pos, Delta * 32, Delta * 32, Color( 255, 255, 255, Delta * 255) )
|
||||
|
||||
render.SetMaterial( BeamFX )
|
||||
render.DrawBeam( Muzzle.Pos, trace.HitPos, (Delta ^ 2) * 64, 0, 1, Color( 255, 255, 255 ) )
|
||||
|
||||
render.SetMaterial( WarpFX )
|
||||
render.DrawSprite( Muzzle.Pos, (Delta ^ 2) * 256, (Delta ^ 2) * 256, Color( 255, 255, 255, 100) )
|
||||
|
||||
local dlight = DynamicLight( self:EntIndex() * 1337 )
|
||||
if dlight then
|
||||
dlight.pos = Muzzle.Pos
|
||||
dlight.r = 0
|
||||
dlight.g = 255
|
||||
dlight.b = 255
|
||||
dlight.brightness = Delta * 10
|
||||
dlight.Decay = 100
|
||||
dlight.Size = 128
|
||||
dlight.DieTime = CurTime() + 0.2
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,76 @@
|
||||
|
||||
local MuzzleFX = Material("sprites/strider_blackball")
|
||||
local BeamFX = Material("sprites/bluelaser1")
|
||||
local WarpFX = Material("particle/warp5_warp")
|
||||
|
||||
function EFFECT:Init( data )
|
||||
self.Ent = data:GetEntity()
|
||||
|
||||
if not IsValid( self.Ent ) then return end
|
||||
|
||||
self.LifeTime = 0.2
|
||||
self.DieTime = CurTime() + self.LifeTime
|
||||
|
||||
self.Ent:EmitSound( "NPC_Strider.Shoot" )
|
||||
|
||||
self:SetRenderBoundsWS( self.Ent:GetPos(), self.Ent:GetPos() - self.Ent:GetUp() * 50000 )
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
if (self.DieTime or 0) < CurTime() then
|
||||
self:DoImpactEffect()
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function EFFECT:DoImpactEffect()
|
||||
if not IsValid( self.Ent ) then return end
|
||||
|
||||
local Muzzle = self.Ent:GetAttachment( self.Ent:LookupAttachment( "bellygun" ) )
|
||||
|
||||
if not Muzzle then return end
|
||||
|
||||
local trace = util.TraceLine( {
|
||||
start = Muzzle.Pos,
|
||||
endpos = Muzzle.Pos + self.Ent:GetAimVector() * 50000,
|
||||
mask = MASK_SOLID_BRUSHONLY
|
||||
} )
|
||||
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin( trace.HitPos + trace.HitNormal )
|
||||
effectdata:SetRadius( 256 )
|
||||
effectdata:SetNormal( trace.HitNormal )
|
||||
util.Effect( "AR2Explosion", effectdata, true, true )
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
if not IsValid( self.Ent ) then return end
|
||||
|
||||
local Muzzle = self.Ent:GetAttachment( self.Ent:LookupAttachment( "bellygun" ) )
|
||||
|
||||
if not Muzzle then return end
|
||||
|
||||
local T = CurTime()
|
||||
local Delta = ((T + self.LifeTime) - self.DieTime) / self.LifeTime
|
||||
|
||||
local trace = util.TraceLine( {
|
||||
start = Muzzle.Pos,
|
||||
endpos = Muzzle.Pos + self.Ent:GetAimVector() * 50000,
|
||||
mask = MASK_SOLID_BRUSHONLY
|
||||
} )
|
||||
|
||||
self:SetRenderBoundsWS( Muzzle.Pos, trace.HitPos )
|
||||
|
||||
render.SetMaterial( BeamFX )
|
||||
render.DrawBeam( Muzzle.Pos, trace.HitPos, (Delta ^ 2) * 64, 0, 1, Color( 255, 255, 255 ) )
|
||||
|
||||
local Sub = trace.HitPos - Muzzle.Pos
|
||||
local Dir = Sub:GetNormalized()
|
||||
local Dist = Sub:Length()
|
||||
|
||||
local Scale = 512 - Delta * 512
|
||||
render.SetMaterial( WarpFX )
|
||||
render.DrawSprite( Muzzle.Pos + Dir * Dist * Delta, Scale, Scale, Color( 255, 255, 255, 255) )
|
||||
end
|
||||
258
garrysmod/addons/lvs_base/lua/entities/lvs_armor.lua
Normal file
258
garrysmod/addons/lvs_base/lua/entities/lvs_armor.lua
Normal file
@@ -0,0 +1,258 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
ENT.Type = "anim"
|
||||
ENT.DoNotDuplicate = true
|
||||
|
||||
ENT.RenderGroup = RENDERGROUP_BOTH
|
||||
|
||||
function ENT:SetupDataTables()
|
||||
self:NetworkVar( "Entity",0, "Base" )
|
||||
|
||||
self:NetworkVar( "Float",0, "HP" )
|
||||
self:NetworkVar( "Float",1, "MaxHP" )
|
||||
self:NetworkVar( "Float",2, "IgnoreForce" )
|
||||
|
||||
self:NetworkVar( "Vector",0, "Mins" )
|
||||
self:NetworkVar( "Vector",1, "Maxs" )
|
||||
|
||||
self:NetworkVar( "Bool",0, "Destroyed" )
|
||||
|
||||
self:NetworkVar( "String",0, "Label" )
|
||||
|
||||
if SERVER then
|
||||
self:SetMaxHP( 100 )
|
||||
self:SetHP( 100 )
|
||||
self:SetLabel( "Armor Plate" )
|
||||
end
|
||||
end
|
||||
|
||||
if SERVER then
|
||||
function ENT:Initialize()
|
||||
self:SetMoveType( MOVETYPE_NONE )
|
||||
self:SetSolid( SOLID_NONE )
|
||||
self:DrawShadow( false )
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
return false
|
||||
end
|
||||
|
||||
function ENT:OnHealthChanged( dmginfo, old, new )
|
||||
if old == new then return end
|
||||
end
|
||||
|
||||
function ENT:OnRepaired()
|
||||
end
|
||||
|
||||
function ENT:OnDestroyed( dmginfo )
|
||||
end
|
||||
|
||||
function ENT:OnTakeDamage( dmginfo )
|
||||
end
|
||||
|
||||
function ENT:TakeTransmittedDamage( dmginfo )
|
||||
local Force = dmginfo:GetDamageForce()
|
||||
|
||||
local Damage = dmginfo:GetDamage()
|
||||
local DamageForce = Force:Length()
|
||||
local IsBlastDamage = dmginfo:IsDamageType( DMG_BLAST )
|
||||
|
||||
local CurHealth = self:GetHP()
|
||||
|
||||
local pos = dmginfo:GetDamagePosition()
|
||||
local dir = Force:GetNormalized()
|
||||
|
||||
local base = self:GetBase()
|
||||
|
||||
-- translate force value to armor penetration value is Force * 0.1
|
||||
-- mm to inch is * 0.0393701
|
||||
-- so correct value is * 0.00393701
|
||||
local pLength = DamageForce * 0.00393701
|
||||
|
||||
local TraceData = {
|
||||
start = pos - dir * pLength,
|
||||
endpos = pos + dir * pLength,
|
||||
}
|
||||
|
||||
local trace = util.TraceLine( TraceData )
|
||||
|
||||
-- parent stays the same
|
||||
local parent = trace.Entity
|
||||
local parentPos = trace.HitPos
|
||||
local parentDir = trace.HitNormal
|
||||
|
||||
-- only one extra iteration should be enough ...
|
||||
if IsValid( trace.Entity ) and isfunction( trace.Entity.GetBase ) and trace.Entity:GetBase() == base then
|
||||
|
||||
TraceData.filter = trace.Entity
|
||||
|
||||
local FilteredTrace = util.TraceLine( TraceData )
|
||||
|
||||
if FilteredTrace.Hit then
|
||||
trace = FilteredTrace
|
||||
end
|
||||
|
||||
trace.Entity = base
|
||||
end
|
||||
|
||||
local DotHitNormal = math.Clamp( trace.HitNormal:Dot( dir ) ,-1,1)
|
||||
|
||||
local Armor = self:GetIgnoreForce()
|
||||
local ArmorEffective = Armor / math.abs( DotHitNormal )
|
||||
|
||||
if math.abs( DotHitNormal ) > 0.9 then
|
||||
ArmorEffective = Armor
|
||||
end
|
||||
|
||||
local DisableBounce = false
|
||||
|
||||
local Inflictor = dmginfo:GetInflictor()
|
||||
|
||||
if IsValid( Inflictor ) then
|
||||
if Inflictor.DisableBallistics or Inflictor:IsNPC() or Inflictor:IsNextBot() then
|
||||
DisableBounce = true
|
||||
end
|
||||
end
|
||||
|
||||
if DamageForce <= ArmorEffective and not IsBlastDamage then
|
||||
local T = CurTime()
|
||||
|
||||
if trace.Entity ~= base then
|
||||
self._NextBounce = T + 1
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
local Ax = math.acos( DotHitNormal )
|
||||
local HitAngle = 90 - (180 - math.deg( Ax ))
|
||||
|
||||
if HitAngle > 30 then
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin( trace.HitPos )
|
||||
effectdata:SetNormal( -dir )
|
||||
util.Effect( "manhacksparks", effectdata, true, true )
|
||||
|
||||
self._NextBounce = T + 1
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
local NewDir = dir - trace.HitNormal * math.cos( Ax ) * 2
|
||||
|
||||
if (self._NextBounce or 0) > T or DisableBounce then
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin( trace.HitPos )
|
||||
effectdata:SetNormal( NewDir:GetNormalized() * 0.25 )
|
||||
util.Effect( "manhacksparks", effectdata, true, true )
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
self._NextBounce = T + 1
|
||||
|
||||
local hit_decal = ents.Create( "lvs_armor_bounce" )
|
||||
hit_decal:SetPos( trace.HitPos )
|
||||
hit_decal:SetAngles( NewDir:Angle() )
|
||||
hit_decal:Spawn()
|
||||
hit_decal:Activate()
|
||||
hit_decal:EmitSound("lvs/armor_rico"..math.random(1,6)..".wav", 95, 100, math.min( dmginfo:GetDamage() / 1000, 1 ) )
|
||||
|
||||
local PhysObj = hit_decal:GetPhysicsObject()
|
||||
if not IsValid( PhysObj ) then return false end
|
||||
|
||||
PhysObj:EnableDrag( false )
|
||||
PhysObj:SetVelocityInstantaneous( NewDir * 2000 + Vector(0,0,250) )
|
||||
PhysObj:SetAngleVelocityInstantaneous( VectorRand() * 250 )
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
local NewHealth = math.Clamp( CurHealth - Damage, 0, self:GetMaxHP() )
|
||||
|
||||
self:OnHealthChanged( dmginfo, CurHealth, NewHealth )
|
||||
self:SetHP( NewHealth )
|
||||
|
||||
if NewHealth <= 0 and not self:GetDestroyed() then
|
||||
self:SetDestroyed( true )
|
||||
self:OnDestroyed( dmginfo )
|
||||
end
|
||||
|
||||
local hit_decal = ents.Create( "lvs_armor_penetrate" )
|
||||
hit_decal:SetPos( parentPos + parentDir * 0.2 )
|
||||
hit_decal:SetAngles( parentDir:Angle() + Angle(90,0,0) )
|
||||
hit_decal:Spawn()
|
||||
hit_decal:Activate()
|
||||
hit_decal:SetParent( parent )
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
function ENT:Initialize()
|
||||
end
|
||||
|
||||
function ENT:OnRemove()
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
end
|
||||
|
||||
|
||||
function ENT:Draw()
|
||||
end
|
||||
|
||||
local function DrawText( pos, text, col )
|
||||
cam.Start2D()
|
||||
local data2D = pos:ToScreen()
|
||||
|
||||
if not data2D.visible then cam.End2D() return end
|
||||
|
||||
local font = "TargetIDSmall"
|
||||
|
||||
local x = data2D.x
|
||||
local y = data2D.y
|
||||
|
||||
draw.DrawText( text, font, x + 1, y + 1, Color( 0, 0, 0, 120 ), TEXT_ALIGN_CENTER )
|
||||
draw.DrawText( text, font, x + 2, y + 2, Color( 0, 0, 0, 50 ), TEXT_ALIGN_CENTER )
|
||||
draw.DrawText( text, font, x, y, col or color_white, TEXT_ALIGN_CENTER )
|
||||
cam.End2D()
|
||||
end
|
||||
|
||||
local LVS = LVS
|
||||
local BoxMat = Material("models/wireframe")
|
||||
local ColorSelect = Color(0,127,255,150)
|
||||
local ColorNormal = Color(50,50,50,150)
|
||||
local ColorTransBlack = Color(0,0,0,150)
|
||||
local OutlineThickness = Vector(0.5,0.5,0.5)
|
||||
local ColorText = Color(255,0,0,255)
|
||||
|
||||
function ENT:DrawTranslucent()
|
||||
if not LVS.DeveloperEnabled then return end
|
||||
|
||||
local ply = LocalPlayer()
|
||||
|
||||
if not IsValid( ply ) or ply:InVehicle() or not ply:KeyDown( IN_SPEED ) then return end
|
||||
|
||||
local boxOrigin = self:GetPos()
|
||||
local boxAngles = self:GetAngles()
|
||||
local boxMins = self:GetMins()
|
||||
local boxMaxs = self:GetMaxs()
|
||||
|
||||
local HitPos, _, _ = util.IntersectRayWithOBB( ply:GetShootPos(), ply:GetAimVector() * 1000, boxOrigin, boxAngles, boxMins, boxMaxs )
|
||||
|
||||
local InRange = isvector( HitPos )
|
||||
|
||||
local Col = InRange and ColorSelect or ColorNormal
|
||||
|
||||
render.SetColorMaterial()
|
||||
render.DrawBox( boxOrigin, boxAngles, boxMins, boxMaxs, Col )
|
||||
render.DrawBox( boxOrigin, boxAngles, boxMaxs + OutlineThickness, boxMins - OutlineThickness, ColorTransBlack )
|
||||
|
||||
local boxCenter = (self:LocalToWorld( boxMins ) + self:LocalToWorld( boxMaxs )) * 0.5
|
||||
|
||||
if not InRange then return end
|
||||
|
||||
DrawText( boxCenter, "Armor: "..(self:GetIgnoreForce() / 100).."mm\nHealth:"..self:GetHP().."/"..self:GetMaxHP(), ColorText )
|
||||
end
|
||||
124
garrysmod/addons/lvs_base/lua/entities/lvs_armor_bounce.lua
Normal file
124
garrysmod/addons/lvs_base/lua/entities/lvs_armor_bounce.lua
Normal file
@@ -0,0 +1,124 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
ENT.Type = "anim"
|
||||
|
||||
ENT.PrintName = "88mm Round"
|
||||
ENT.Author = "Luna"
|
||||
ENT.Information = "Luna's Vehicle Script"
|
||||
ENT.Category = "[LVS] - Cars - Items"
|
||||
|
||||
ENT.Spawnable = false
|
||||
ENT.AdminOnly = false
|
||||
|
||||
ENT.LifeTime = 10
|
||||
|
||||
if SERVER then
|
||||
function ENT:Initialize()
|
||||
self:SetModel( "models/misc/88mm_projectile.mdl" )
|
||||
self:SetMoveType( MOVETYPE_VPHYSICS )
|
||||
self:PhysicsInit( SOLID_VPHYSICS)
|
||||
|
||||
self.DieTime = CurTime() + self.LifeTime
|
||||
|
||||
self:SetCollisionGroup( COLLISION_GROUP_WORLD )
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
if self.MarkForRemove then self:Remove() return false end
|
||||
|
||||
self:NextThink( CurTime() + 0.1 )
|
||||
|
||||
if (self.DieTime or 0) > CurTime() then return true end
|
||||
|
||||
self:Remove()
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
function ENT:PhysicsCollide( data, physobj )
|
||||
self.MarkForRemove = true
|
||||
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin( data.HitPos )
|
||||
effectdata:SetNormal( -data.HitNormal )
|
||||
effectdata:SetMagnitude( 0.5 )
|
||||
util.Effect( "lvs_bullet_impact", effectdata )
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
ENT.MatSmoke = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
function ENT:Initialize()
|
||||
self.DieTime = CurTime() + self.LifeTime
|
||||
|
||||
self.emitter = ParticleEmitter( self:GetPos(), false )
|
||||
end
|
||||
|
||||
function ENT:Smoke()
|
||||
local T = CurTime()
|
||||
|
||||
if (self.DieTime or 0) < T then return end
|
||||
|
||||
if not IsValid( self.emitter ) then return end
|
||||
|
||||
if (self.NextFX or 0) < T then
|
||||
self.NextFX = T + 0.02
|
||||
|
||||
local Timed = 1 - (self.DieTime - T) / self.LifeTime
|
||||
local Scale = math.max(math.min(2 - Timed * 2,1),0)
|
||||
|
||||
local Pos = self:GetPos()
|
||||
|
||||
local particle = self.emitter:Add( self.MatSmoke[math.random(1,#self.MatSmoke)], Pos )
|
||||
|
||||
local VecCol = (render.GetLightColor( Pos ) * 0.8 + Vector(0.2,0.2,0.2)) * 255
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( VectorRand() * 10 )
|
||||
particle:SetDieTime( math.Rand(0.5,1) )
|
||||
particle:SetAirResistance( 100 )
|
||||
particle:SetStartAlpha( 100 * Scale )
|
||||
particle:SetEndAlpha( 0 )
|
||||
particle:SetStartSize( 10 )
|
||||
particle:SetEndSize( 20 )
|
||||
particle:SetRollDelta( 1 )
|
||||
particle:SetColor( VecCol.r, VecCol.g, VecCol.b )
|
||||
particle:SetGravity( Vector( 0, 0, 200 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
self:Smoke()
|
||||
end
|
||||
|
||||
function ENT:OnRemove()
|
||||
if not self.emitter then return end
|
||||
|
||||
self.emitter:Finish()
|
||||
end
|
||||
|
||||
function ENT:Draw()
|
||||
self:DrawModel()
|
||||
end
|
||||
149
garrysmod/addons/lvs_base/lua/entities/lvs_armor_penetrate.lua
Normal file
149
garrysmod/addons/lvs_base/lua/entities/lvs_armor_penetrate.lua
Normal file
@@ -0,0 +1,149 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
ENT.Type = "anim"
|
||||
|
||||
ENT.RenderGroup = RENDERGROUP_BOTH
|
||||
|
||||
ENT.LifeTime = 15
|
||||
|
||||
if SERVER then
|
||||
local CountTotal = {}
|
||||
|
||||
function ENT:Initialize()
|
||||
CountTotal[ self:EntIndex() ] = true
|
||||
|
||||
local Num = table.Count( CountTotal )
|
||||
|
||||
if (Num > 30 and math.random(1,2) == 1) or Num > 60 then
|
||||
self:Remove()
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
self:SetMoveType( MOVETYPE_NONE )
|
||||
self:SetSolid( SOLID_NONE )
|
||||
self:DrawShadow( false )
|
||||
self.DieTime = CurTime() + self.LifeTime
|
||||
end
|
||||
|
||||
function ENT:OnRemove()
|
||||
CountTotal[ self:EntIndex() ] = nil
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
self:NextThink( CurTime() + 0.1 )
|
||||
|
||||
if not IsValid( self:GetParent() ) then self:Remove() return end
|
||||
|
||||
if (self.DieTime or 0) > CurTime() then return true end
|
||||
|
||||
self:Remove()
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
ENT.GlowMat1 = Material( "particle/particle_ring_wave_8" )
|
||||
ENT.GlowMat2 = Material( "sprites/light_glow02_add" )
|
||||
ENT.DecalMat = Material( "particle/particle_noisesphere" )
|
||||
ENT.MatSmoke = {
|
||||
"particle/smokesprites_0001",
|
||||
"particle/smokesprites_0002",
|
||||
"particle/smokesprites_0003",
|
||||
"particle/smokesprites_0004",
|
||||
"particle/smokesprites_0005",
|
||||
"particle/smokesprites_0006",
|
||||
"particle/smokesprites_0007",
|
||||
"particle/smokesprites_0008",
|
||||
"particle/smokesprites_0009",
|
||||
"particle/smokesprites_0010",
|
||||
"particle/smokesprites_0011",
|
||||
"particle/smokesprites_0012",
|
||||
"particle/smokesprites_0013",
|
||||
"particle/smokesprites_0014",
|
||||
"particle/smokesprites_0015",
|
||||
"particle/smokesprites_0016"
|
||||
}
|
||||
|
||||
local CountTotal = {}
|
||||
|
||||
function ENT:Initialize()
|
||||
CountTotal[ self:EntIndex() ] = true
|
||||
|
||||
self.RandomAng = math.random(0,360)
|
||||
self.DieTime = CurTime() + self.LifeTime
|
||||
|
||||
local Pos = self:GetPos()
|
||||
local Dir = self:GetUp()
|
||||
|
||||
self.emitter = ParticleEmitter( Pos, false )
|
||||
|
||||
self:EmitSound( "lvs/armor_pen_"..math.random(1,3)..".wav", 95 )
|
||||
end
|
||||
|
||||
function ENT:Smoke()
|
||||
local T = CurTime()
|
||||
|
||||
if (self.DieTime or 0) < T then return end
|
||||
|
||||
if not IsValid( self.emitter ) then return end
|
||||
|
||||
if (self.NextFX or 0) < T then
|
||||
self.NextFX = T + 0.2 + table.Count( CountTotal ) / 50
|
||||
|
||||
local particle = self.emitter:Add( self.MatSmoke[math.random(1,#self.MatSmoke)], self:GetPos() )
|
||||
|
||||
if particle then
|
||||
particle:SetVelocity( self:GetUp() * 60 + VectorRand() * 30 )
|
||||
particle:SetDieTime( math.Rand(1.5,2) )
|
||||
particle:SetAirResistance( 100 )
|
||||
particle:SetStartAlpha( 30 )
|
||||
particle:SetEndAlpha( 0 )
|
||||
particle:SetStartSize( 0 )
|
||||
particle:SetEndSize( 60 )
|
||||
particle:SetRollDelta( math.Rand( -1, 1 ) )
|
||||
particle:SetColor( 50,50,50 )
|
||||
particle:SetGravity( Vector( 0, 0, 200 ) )
|
||||
particle:SetCollide( false )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
self:Smoke()
|
||||
end
|
||||
|
||||
function ENT:OnRemove()
|
||||
CountTotal[ self:EntIndex() ] = nil
|
||||
|
||||
if not IsValid(self.emitter) then return end
|
||||
|
||||
self.emitter:Finish()
|
||||
end
|
||||
|
||||
function ENT:Draw()
|
||||
local Timed = 1 - (self.DieTime - CurTime()) / self.LifeTime
|
||||
local Scale = math.max(math.min(2 - Timed * 2,1),0)
|
||||
|
||||
local Scale02 = math.max(Scale - 0.8,0) / 0.2
|
||||
|
||||
cam.Start3D2D( self:GetPos() + self:GetAngles():Up(), self:GetAngles(), 1 )
|
||||
surface.SetDrawColor( 255 * Scale02, (93 + 50 * Scale) * Scale02, (50 * Scale) * Scale02, (200 * Scale) * Scale02 )
|
||||
|
||||
surface.SetMaterial( self.GlowMat1 )
|
||||
surface.DrawTexturedRectRotated( 0, 0, 8 , 8 , self.RandomAng )
|
||||
|
||||
surface.SetMaterial( self.GlowMat2 )
|
||||
surface.DrawTexturedRectRotated( 0, 0, 16 , 16 , self.RandomAng )
|
||||
|
||||
surface.SetDrawColor( 0, 0, 0, 255 )
|
||||
surface.SetMaterial( self.DecalMat )
|
||||
surface.DrawTexturedRectRotated( 0, 0, 16 , 16 , self.RandomAng )
|
||||
cam.End3D2D()
|
||||
end
|
||||
|
||||
function ENT:DrawTranslucent()
|
||||
self:Draw()
|
||||
end
|
||||
@@ -0,0 +1,30 @@
|
||||
|
||||
function ENT:CreateBonePoseParameter( name, bone, ang_min, ang_max, pos_min, pos_max )
|
||||
if not istable( self._BonePoseParameters ) then self._BonePoseParameters = {} end
|
||||
|
||||
self._BonePoseParameters[ name ] = {
|
||||
bone = (bone or -1),
|
||||
ang_min = ang_min or angle_zero,
|
||||
ang_max = ang_max or angle_zero,
|
||||
pos_min = pos_min or vector_origin,
|
||||
pos_max = pos_max or vector_origin,
|
||||
}
|
||||
end
|
||||
|
||||
function ENT:SetBonePoseParameter( name, value )
|
||||
if name and string.StartsWith( name, "!" ) then
|
||||
name = string.Replace( name, "!", "" )
|
||||
end
|
||||
|
||||
local EntTable = self:GetTable()
|
||||
|
||||
if not istable( EntTable._BonePoseParameters ) or not EntTable._BonePoseParameters[ name ] then return end
|
||||
|
||||
local data = EntTable._BonePoseParameters[ name ]
|
||||
|
||||
local ang = LerpAngle( value, data.ang_min, data.ang_max )
|
||||
local pos = LerpVector( value, data.pos_min, data.pos_max )
|
||||
|
||||
self:ManipulateBoneAngles( data.bone, ang )
|
||||
self:ManipulateBonePosition( data.bone, pos )
|
||||
end
|
||||
142
garrysmod/addons/lvs_base/lua/entities/lvs_base/cl_effects.lua
Normal file
142
garrysmod/addons/lvs_base/lua/entities/lvs_base/cl_effects.lua
Normal file
@@ -0,0 +1,142 @@
|
||||
|
||||
function ENT:StartWindSounds()
|
||||
if not LVS.ShowEffects then return end
|
||||
|
||||
self:StopWindSounds()
|
||||
|
||||
if LocalPlayer():lvsGetVehicle() ~= self then return end
|
||||
|
||||
local EntTable = self:GetTable()
|
||||
|
||||
EntTable._WindSFX = CreateSound( self, "LVS.Physics.Wind" )
|
||||
EntTable._WindSFX:PlayEx(0,100)
|
||||
|
||||
EntTable._WaterSFX = CreateSound( self, "LVS.Physics.Water" )
|
||||
EntTable._WaterSFX:PlayEx(0,100)
|
||||
end
|
||||
|
||||
function ENT:StopWindSounds()
|
||||
local EntTable = self:GetTable()
|
||||
|
||||
if EntTable._WindSFX then
|
||||
EntTable._WindSFX:Stop()
|
||||
EntTable._WindSFX = nil
|
||||
end
|
||||
|
||||
if EntTable._WaterSFX then
|
||||
EntTable._WaterSFX:Stop()
|
||||
EntTable._WaterSFX = nil
|
||||
end
|
||||
end
|
||||
|
||||
ENT.DustEffectSurfaces = {
|
||||
["sand"] = true,
|
||||
["dirt"] = true,
|
||||
["grass"] = true,
|
||||
}
|
||||
|
||||
ENT.GroundEffectsMultiplier = 1
|
||||
|
||||
function ENT:DoVehicleFX()
|
||||
local EntTable = self:GetTable()
|
||||
|
||||
if EntTable.GroundEffectsMultiplier <= 0 or not LVS.ShowEffects then self:StopWindSounds() return end
|
||||
|
||||
local Vel = self:GetVelocity():Length() * EntTable.GroundEffectsMultiplier
|
||||
|
||||
if EntTable._WindSFX then EntTable._WindSFX:ChangeVolume( math.Clamp( (Vel - 1200) / 2800,0,1 ), 0.25 ) end
|
||||
|
||||
if Vel < 1500 then
|
||||
if EntTable._WaterSFX then EntTable._WaterSFX:ChangeVolume( 0, 0.25 ) end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
if (EntTable.nextFX or 0) < CurTime() then
|
||||
EntTable.nextFX = CurTime() + 0.05
|
||||
|
||||
local LCenter = self:OBBCenter()
|
||||
LCenter.z = self:OBBMins().z
|
||||
|
||||
local CenterPos = self:LocalToWorld( LCenter )
|
||||
|
||||
local trace = util.TraceLine( {
|
||||
start = CenterPos + Vector(0,0,25),
|
||||
endpos = CenterPos - Vector(0,0,450),
|
||||
filter = self:GetCrosshairFilterEnts(),
|
||||
} )
|
||||
|
||||
local traceWater = util.TraceLine( {
|
||||
start = CenterPos + Vector(0,0,25),
|
||||
endpos = CenterPos - Vector(0,0,450),
|
||||
filter = self:GetCrosshairFilterEnts(),
|
||||
mask = MASK_WATER,
|
||||
} )
|
||||
|
||||
if EntTable._WaterSFX then EntTable._WaterSFX:ChangePitch( math.Clamp((Vel / 1000) * 50,80,150), 0.5 ) end
|
||||
|
||||
if traceWater.Hit and trace.HitPos.z < traceWater.HitPos.z then
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin( traceWater.HitPos )
|
||||
effectdata:SetEntity( self )
|
||||
util.Effect( "lvs_physics_water", effectdata )
|
||||
|
||||
if EntTable._WaterSFX then EntTable._WaterSFX:ChangeVolume( 1 - math.Clamp(traceWater.Fraction,0,1), 0.5 ) end
|
||||
else
|
||||
if EntTable._WaterSFX then EntTable._WaterSFX:ChangeVolume( 0, 0.25 ) end
|
||||
end
|
||||
|
||||
if trace.Hit and EntTable.DustEffectSurfaces[ util.GetSurfacePropName( trace.SurfaceProps ) ] then
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin( trace.HitPos )
|
||||
effectdata:SetEntity( self )
|
||||
util.Effect( "lvs_physics_dust", effectdata )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:GetParticleEmitter( Pos )
|
||||
local EntTable = self:GetTable()
|
||||
|
||||
local T = CurTime()
|
||||
|
||||
if IsValid( EntTable.Emitter ) and (EntTable.EmitterTime or 0) > T then
|
||||
return EntTable.Emitter
|
||||
end
|
||||
|
||||
self:StopEmitter()
|
||||
|
||||
EntTable.Emitter = ParticleEmitter( Pos, false )
|
||||
EntTable.EmitterTime = T + 2
|
||||
|
||||
return EntTable.Emitter
|
||||
end
|
||||
|
||||
function ENT:StopEmitter()
|
||||
if IsValid( self.Emitter ) then
|
||||
self.Emitter:Finish()
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:GetParticleEmitter3D( Pos )
|
||||
local EntTable = self:GetTable()
|
||||
|
||||
local T = CurTime()
|
||||
|
||||
if IsValid( EntTable.Emitter3D ) and (EntTable.EmitterTime3D or 0) > T then
|
||||
return EntTable.Emitter3D
|
||||
end
|
||||
|
||||
self:StopEmitter3D()
|
||||
|
||||
EntTable.Emitter3D = ParticleEmitter( Pos, true )
|
||||
EntTable.EmitterTime3D = T + 2
|
||||
|
||||
return EntTable.Emitter3D
|
||||
end
|
||||
|
||||
function ENT:StopEmitter3D()
|
||||
if IsValid( self.Emitter3D ) then
|
||||
self.Emitter3D:Finish()
|
||||
end
|
||||
end
|
||||
253
garrysmod/addons/lvs_base/lua/entities/lvs_base/cl_hud.lua
Normal file
253
garrysmod/addons/lvs_base/lua/entities/lvs_base/cl_hud.lua
Normal file
@@ -0,0 +1,253 @@
|
||||
|
||||
LVS:AddHudEditor( "VehicleHealth", 10, ScrH() - 85, 220, 75, 220, 75, "VEHICLE HEALTH",
|
||||
function( self, vehicle, X, Y, W, H, ScrX, ScrY, ply )
|
||||
if not vehicle.LVSHudPaintVehicleHealth then return end
|
||||
|
||||
vehicle:LVSHudPaintVehicleHealth( X, Y, W, H, ScrX, ScrY, ply )
|
||||
end
|
||||
)
|
||||
|
||||
LVS:AddHudEditor( "VehicleInfo", ScrW() - 460, ScrH() - 85, 220, 75, 220, 75, "VEHICLE INFORMATION",
|
||||
function( self, vehicle, X, Y, W, H, ScrX, ScrY, ply )
|
||||
if not vehicle.LVSHudPaintInfoText then return end
|
||||
|
||||
vehicle:LVSHudPaintInfoText( X, Y, W, H, ScrX, ScrY, ply )
|
||||
end
|
||||
)
|
||||
|
||||
function ENT:LVSHudPaintVehicleHealth( X, Y, W, H, ScrX, ScrY, ply )
|
||||
draw.DrawText( "HEALTH ", "LVS_FONT", X + 102, Y + 35, color_white, TEXT_ALIGN_RIGHT )
|
||||
draw.DrawText( math.Round( self:GetHP(), 0 ), "LVS_FONT_HUD_LARGE", X + 102, Y + 20, color_white, TEXT_ALIGN_LEFT )
|
||||
end
|
||||
|
||||
ENT.VehicleIdentifierRange = 10000
|
||||
|
||||
function ENT:LVSHudPaintVehicleIdentifier( X, Y, In_Col )
|
||||
local HP = self:GetHP()
|
||||
|
||||
surface.SetDrawColor( In_Col.r, In_Col.g, In_Col.b, In_Col.a )
|
||||
LVS:DrawDiamond( X + 1, Y + 1, 20, HP / self:GetMaxHP() )
|
||||
|
||||
if self:GetMaxShield() > 0 and HP > 0 then
|
||||
surface.SetDrawColor( 200, 200, 255, In_Col.a )
|
||||
LVS:DrawDiamond( X + 1, Y + 1, 24, self:GetShield() / self:GetMaxShield() )
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:LVSPreHudPaint( X, Y, ply )
|
||||
return true
|
||||
end
|
||||
|
||||
local zoom = 0
|
||||
local zoom_mat = Material( "vgui/zoom" )
|
||||
local zoom_switch = 0
|
||||
local zoom_blinder = 0
|
||||
local TargetZoom = 0
|
||||
|
||||
ENT.ZoomInSound = "weapons/sniper/sniper_zoomin.wav"
|
||||
ENT.ZoomOutSound = "weapons/sniper/sniper_zoomout.wav"
|
||||
|
||||
function ENT:GetZoom()
|
||||
return TargetZoom
|
||||
end
|
||||
|
||||
function ENT:PaintZoom( X, Y, ply )
|
||||
TargetZoom = ply:lvsKeyDown( "ZOOM" ) and 1 or 0
|
||||
|
||||
zoom = zoom + (TargetZoom - zoom) * RealFrameTime() * 10
|
||||
|
||||
if self.OpticsEnable then
|
||||
if self:GetOpticsEnabled() then
|
||||
if zoom_switch ~= TargetZoom then
|
||||
zoom_switch = TargetZoom
|
||||
|
||||
zoom_blinder = 1
|
||||
|
||||
if TargetZoom == 1 then
|
||||
surface.PlaySound( self.ZoomInSound )
|
||||
else
|
||||
surface.PlaySound( self.ZoomOutSound )
|
||||
end
|
||||
end
|
||||
|
||||
zoom_blinder = zoom_blinder - zoom_blinder * RealFrameTime() * 5
|
||||
|
||||
surface.SetDrawColor( Color(0,0,0,255 * zoom_blinder) )
|
||||
surface.DrawRect( 0, 0, X, Y )
|
||||
|
||||
self.ZoomFov = self.OpticsFov
|
||||
else
|
||||
self.ZoomFov = nil
|
||||
end
|
||||
end
|
||||
|
||||
X = X * 0.5
|
||||
Y = Y * 0.5
|
||||
|
||||
surface.SetDrawColor( Color(255,255,255,255 * zoom) )
|
||||
surface.SetMaterial(zoom_mat )
|
||||
surface.DrawTexturedRectRotated( X + X * 0.5, Y * 0.5, X, Y, 0 )
|
||||
surface.DrawTexturedRectRotated( X + X * 0.5, Y + Y * 0.5, Y, X, 270 )
|
||||
surface.DrawTexturedRectRotated( X * 0.5, Y * 0.5, Y, X, 90 )
|
||||
surface.DrawTexturedRectRotated( X * 0.5, Y + Y * 0.5, X, Y, 180 )
|
||||
end
|
||||
|
||||
function ENT:LVSHudPaint( X, Y, ply )
|
||||
if not self:LVSPreHudPaint( X, Y, ply ) then return end
|
||||
|
||||
self:PaintZoom( X, Y, ply )
|
||||
end
|
||||
|
||||
function ENT:HurtMarker( intensity )
|
||||
LocalPlayer():EmitSound( "lvs/hit_receive"..math.random(1,2)..".wav", 75, math.random(95,105), 0.25 + intensity * 0.75, CHAN_STATIC )
|
||||
util.ScreenShake( Vector(0, 0, 0), 25 * intensity, 25 * intensity, 0.5, 1 )
|
||||
end
|
||||
|
||||
function ENT:KillMarker()
|
||||
self.LastKillMarker = CurTime() + 0.5
|
||||
|
||||
LocalPlayer():EmitSound( "lvs/hit_kill.wav", 85, 100, 0.4, CHAN_VOICE )
|
||||
end
|
||||
|
||||
local LastMarker = 0
|
||||
function ENT:ArmorMarker( IsDamage )
|
||||
local T = CurTime()
|
||||
|
||||
local DontHurtEars = math.Clamp( T - LastMarker, 0, 1 ) ^ 2
|
||||
|
||||
LastMarker = T
|
||||
|
||||
local ArmorFailed = IsDamage and "takedamage" or "pen"
|
||||
local Volume = IsDamage and (0.3 * DontHurtEars) or 1
|
||||
|
||||
LocalPlayer():EmitSound( "lvs/armor_"..ArmorFailed.."_"..math.random(1,3)..".wav", 85, math.random(95,105), Volume, CHAN_ITEM2 )
|
||||
end
|
||||
|
||||
function ENT:HitMarker()
|
||||
self.LastHitMarker = CurTime() + 0.15
|
||||
|
||||
LocalPlayer():EmitSound( "lvs/hit.wav", 85, math.random(95,105), 0.4, CHAN_ITEM )
|
||||
end
|
||||
|
||||
function ENT:CritMarker()
|
||||
self.LastCritMarker = CurTime() + 0.15
|
||||
|
||||
LocalPlayer():EmitSound( "lvs/hit_crit.wav", 85, math.random(95,105), 0.4, CHAN_ITEM2 )
|
||||
end
|
||||
|
||||
function ENT:GetHitMarker()
|
||||
return self.LastHitMarker or 0
|
||||
end
|
||||
|
||||
function ENT:GetCritMarker()
|
||||
return self.LastCritMarker or 0
|
||||
end
|
||||
|
||||
function ENT:GetKillMarker()
|
||||
return self.LastKillMarker or 0
|
||||
end
|
||||
|
||||
function ENT:LVSPaintHitMarker( scr )
|
||||
local T = CurTime()
|
||||
|
||||
local aV = math.cos( math.rad( math.max(((self:GetHitMarker() - T) / 0.15) * 360,0) ) )
|
||||
if aV ~= 1 then
|
||||
local Start = 12 + (1 - aV) * 8
|
||||
local dst = 10
|
||||
|
||||
surface.SetDrawColor( 255, 255, 0, 255 )
|
||||
|
||||
surface.DrawLine( scr.x + Start, scr.y + Start, scr.x + Start, scr.y + Start - dst )
|
||||
surface.DrawLine( scr.x + Start, scr.y + Start, scr.x + Start - dst, scr.y + Start )
|
||||
|
||||
surface.DrawLine( scr.x + Start, scr.y - Start, scr.x + Start, scr.y - Start + dst )
|
||||
surface.DrawLine( scr.x + Start, scr.y - Start, scr.x + Start - dst, scr.y - Start )
|
||||
|
||||
surface.DrawLine( scr.x - Start, scr.y + Start, scr.x - Start, scr.y + Start - dst )
|
||||
surface.DrawLine( scr.x - Start, scr.y + Start, scr.x - Start + dst, scr.y + Start )
|
||||
|
||||
surface.DrawLine( scr.x - Start, scr.y - Start, scr.x - Start, scr.y - Start + dst )
|
||||
surface.DrawLine( scr.x - Start, scr.y - Start, scr.x - Start + dst, scr.y - Start )
|
||||
|
||||
scr.x = scr.x + 1
|
||||
scr.y = scr.y + 1
|
||||
|
||||
surface.SetDrawColor( 0, 0, 0, 80 )
|
||||
|
||||
surface.DrawLine( scr.x + Start, scr.y + Start, scr.x + Start, scr.y + Start - dst )
|
||||
surface.DrawLine( scr.x + Start, scr.y + Start, scr.x + Start - dst, scr.y + Start )
|
||||
|
||||
surface.DrawLine( scr.x + Start, scr.y - Start, scr.x + Start, scr.y - Start + dst )
|
||||
surface.DrawLine( scr.x + Start, scr.y - Start, scr.x + Start - dst, scr.y - Start )
|
||||
|
||||
surface.DrawLine( scr.x - Start, scr.y + Start, scr.x - Start, scr.y + Start - dst )
|
||||
surface.DrawLine( scr.x - Start, scr.y + Start, scr.x - Start + dst, scr.y + Start )
|
||||
|
||||
surface.DrawLine( scr.x - Start, scr.y - Start, scr.x - Start, scr.y - Start + dst )
|
||||
surface.DrawLine( scr.x - Start, scr.y - Start, scr.x - Start + dst, scr.y - Start )
|
||||
end
|
||||
|
||||
local aV = math.sin( math.rad( math.max(((self:GetCritMarker() - T) / 0.15) * 180,0) ) )
|
||||
if aV > 0.01 then
|
||||
local Start = 10 + aV * 40
|
||||
local End = 20 + aV * 45
|
||||
|
||||
surface.SetDrawColor( 255, 100, 0, 255 )
|
||||
surface.DrawLine( scr.x + Start, scr.y + Start, scr.x + End, scr.y + End )
|
||||
surface.DrawLine( scr.x - Start, scr.y + Start, scr.x - End, scr.y + End )
|
||||
surface.DrawLine( scr.x + Start, scr.y - Start, scr.x + End, scr.y - End )
|
||||
surface.DrawLine( scr.x - Start, scr.y - Start, scr.x - End, scr.y - End )
|
||||
|
||||
draw.NoTexture()
|
||||
surface.DrawTexturedRectRotated( scr.x + Start, scr.y + Start, 3, 20, 45 )
|
||||
surface.DrawTexturedRectRotated( scr.x - Start, scr.y + Start, 20, 3, 45 )
|
||||
surface.DrawTexturedRectRotated( scr.x + Start, scr.y - Start, 20, 3, 45 )
|
||||
surface.DrawTexturedRectRotated( scr.x - Start, scr.y - Start, 3, 20, 45 )
|
||||
end
|
||||
|
||||
local aV = math.sin( math.rad( math.sin( math.rad( math.max(((self:GetKillMarker() - T) / 0.2) * 90,0) ) ) * 90 ) )
|
||||
if aV > 0.01 then
|
||||
surface.SetDrawColor( 255, 255, 255, 15 * (aV ^ 4) )
|
||||
surface.DrawRect( 0, 0, ScrW(), ScrH() )
|
||||
|
||||
local Start = 10 + aV * 40
|
||||
local End = 20 + aV * 45
|
||||
surface.SetDrawColor( 255, 0, 0, 255 )
|
||||
surface.DrawLine( scr.x + Start, scr.y + Start, scr.x + End, scr.y + End )
|
||||
surface.DrawLine( scr.x - Start, scr.y + Start, scr.x - End, scr.y + End )
|
||||
surface.DrawLine( scr.x + Start, scr.y - Start, scr.x + End, scr.y - End )
|
||||
surface.DrawLine( scr.x - Start, scr.y - Start, scr.x - End, scr.y - End )
|
||||
|
||||
draw.NoTexture()
|
||||
surface.DrawTexturedRectRotated( scr.x + Start, scr.y + Start, 5, 20, 45 )
|
||||
surface.DrawTexturedRectRotated( scr.x - Start, scr.y + Start, 20, 5, 45 )
|
||||
surface.DrawTexturedRectRotated( scr.x + Start, scr.y - Start, 20, 5, 45 )
|
||||
surface.DrawTexturedRectRotated( scr.x - Start, scr.y - Start, 5, 20, 45 )
|
||||
end
|
||||
end
|
||||
|
||||
local Circles = {
|
||||
[1] = {r = -1, col = Color(0,0,0,200)},
|
||||
[2] = {r = 0, col = Color(255,255,255,200)},
|
||||
[3] = {r = 1, col = Color(255,255,255,255)},
|
||||
[4] = {r = 2, col = Color(255,255,255,200)},
|
||||
[5] = {r = 3, col = Color(0,0,0,200)},
|
||||
}
|
||||
|
||||
function ENT:LVSDrawCircle( X, Y, target_radius, value )
|
||||
local endang = 360 * value
|
||||
|
||||
if endang == 0 then return end
|
||||
|
||||
for i = 1, #Circles do
|
||||
local data = Circles[ i ]
|
||||
local radius = target_radius + data.r
|
||||
local segmentdist = endang / ( math.pi * radius / 2 )
|
||||
|
||||
for a = 0, endang, segmentdist do
|
||||
surface.SetDrawColor( data.col )
|
||||
|
||||
surface.DrawLine( X - math.sin( math.rad( a ) ) * radius, Y + math.cos( math.rad( a ) ) * radius, X - math.sin( math.rad( a + segmentdist ) ) * radius, Y + math.cos( math.rad( a + segmentdist ) ) * radius )
|
||||
end
|
||||
end
|
||||
end
|
||||
224
garrysmod/addons/lvs_base/lua/entities/lvs_base/cl_init.lua
Normal file
224
garrysmod/addons/lvs_base/lua/entities/lvs_base/cl_init.lua
Normal file
@@ -0,0 +1,224 @@
|
||||
include("shared.lua")
|
||||
include("sh_weapons.lua")
|
||||
include("sh_velocity_changer.lua")
|
||||
include("sh_variables.lua")
|
||||
include("cl_effects.lua")
|
||||
include("cl_hud.lua")
|
||||
include("cl_optics.lua")
|
||||
include("cl_seatswitcher.lua")
|
||||
include("cl_trailsystem.lua")
|
||||
include("cl_boneposeparemeter.lua")
|
||||
|
||||
local Zoom = 0
|
||||
|
||||
function ENT:LVSCalcFov( fov, ply )
|
||||
|
||||
local TargetZoom = ply:lvsKeyDown( "ZOOM" ) and 0 or 1
|
||||
|
||||
Zoom = Zoom + (TargetZoom - Zoom) * RealFrameTime() * 10
|
||||
|
||||
local newfov = fov * Zoom + (self.ZoomFov or 40) * (1 - Zoom)
|
||||
|
||||
return newfov
|
||||
end
|
||||
|
||||
function ENT:LVSCalcView( ply, pos, angles, fov, pod )
|
||||
return LVS:CalcView( self, ply, pos, angles, fov, pod )
|
||||
end
|
||||
|
||||
function ENT:PreDraw( flags )
|
||||
return true
|
||||
end
|
||||
|
||||
function ENT:PreDrawTranslucent( flags )
|
||||
return true
|
||||
end
|
||||
|
||||
function ENT:PostDraw( flags )
|
||||
end
|
||||
|
||||
function ENT:PostDrawTranslucent( flags )
|
||||
end
|
||||
|
||||
function ENT:Draw( flags )
|
||||
if self:PreDraw( flags ) then
|
||||
if self.lvsLegacyDraw then
|
||||
self:DrawModel() -- ugly, but required in order to fix old addons. Refract wont work on these.
|
||||
else
|
||||
self:DrawModel( flags )
|
||||
end
|
||||
end
|
||||
|
||||
self:PostDraw( flags )
|
||||
end
|
||||
|
||||
function ENT:DrawTranslucent( flags )
|
||||
self:DrawTrail()
|
||||
|
||||
if self:PreDrawTranslucent( flags ) then
|
||||
self:DrawModel( flags )
|
||||
else
|
||||
self.lvsLegacyDraw = true -- insert puke simley
|
||||
end
|
||||
|
||||
self:PostDrawTranslucent( flags )
|
||||
end
|
||||
|
||||
function ENT:Initialize()
|
||||
self:OnSpawn()
|
||||
|
||||
if not istable( self.GibModels ) then return end
|
||||
|
||||
for _, modelName in ipairs( self.GibModels ) do
|
||||
util.PrecacheModel( modelName )
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:OnSpawn()
|
||||
end
|
||||
|
||||
function ENT:OnFrameActive()
|
||||
end
|
||||
|
||||
function ENT:OnFrame()
|
||||
end
|
||||
|
||||
function ENT:OnEngineActiveChanged( Active )
|
||||
end
|
||||
|
||||
function ENT:OnActiveChanged( Active )
|
||||
end
|
||||
|
||||
ENT._oldActive = false
|
||||
ENT._oldEnActive = false
|
||||
|
||||
function ENT:HandleActive()
|
||||
local EntTable = self:GetTable()
|
||||
|
||||
local Active = self:GetActive()
|
||||
local EngineActive = self:GetEngineActive()
|
||||
local ActiveChanged = false
|
||||
|
||||
if EntTable._oldActive ~= Active then
|
||||
EntTable._oldActive = Active
|
||||
EntTable:OnActiveChanged( Active )
|
||||
ActiveChanged = true
|
||||
end
|
||||
|
||||
if EntTable._oldEnActive ~= EngineActive then
|
||||
EntTable._oldEnActive = EngineActive
|
||||
self:OnEngineActiveChanged( EngineActive )
|
||||
ActiveChanged = true
|
||||
end
|
||||
|
||||
if ActiveChanged then
|
||||
if Active or EngineActive then
|
||||
self:StartWindSounds()
|
||||
else
|
||||
self:StopWindSounds()
|
||||
end
|
||||
end
|
||||
|
||||
if Active or EngineActive then
|
||||
self:DoVehicleFX()
|
||||
end
|
||||
|
||||
self:FlyByThink()
|
||||
|
||||
return EngineActive
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
if not self:IsInitialized() then return end
|
||||
|
||||
if self:HandleActive() then
|
||||
self:OnFrameActive()
|
||||
end
|
||||
|
||||
self:HandleTrail()
|
||||
self:OnFrame()
|
||||
end
|
||||
|
||||
function ENT:OnRemove()
|
||||
self:StopEmitter()
|
||||
self:StopEmitter3D()
|
||||
self:StopWindSounds()
|
||||
self:StopFlyBy()
|
||||
self:StopDeathSound()
|
||||
|
||||
self:OnRemoved()
|
||||
end
|
||||
|
||||
function ENT:OnRemoved()
|
||||
end
|
||||
|
||||
function ENT:CalcDoppler( Ent )
|
||||
if not IsValid( Ent ) then return 1 end
|
||||
|
||||
if Ent:IsPlayer() then
|
||||
local ViewEnt = Ent:GetViewEntity()
|
||||
local Vehicle = Ent:lvsGetVehicle()
|
||||
|
||||
if IsValid( Vehicle ) then
|
||||
if Ent == ViewEnt then
|
||||
Ent = Vehicle
|
||||
end
|
||||
else
|
||||
if IsValid( ViewEnt ) then
|
||||
Ent = ViewEnt
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local sVel = self:GetVelocity()
|
||||
local oVel = Ent:GetVelocity()
|
||||
|
||||
local SubVel = oVel - sVel
|
||||
local SubPos = self:GetPos() - Ent:GetPos()
|
||||
|
||||
local DirPos = SubPos:GetNormalized()
|
||||
local DirVel = SubVel:GetNormalized()
|
||||
|
||||
local A = math.acos( math.Clamp( DirVel:Dot( DirPos ) ,-1,1) )
|
||||
|
||||
return (1 + math.cos( A ) * SubVel:Length() / 13503.9)
|
||||
end
|
||||
|
||||
function ENT:GetCrosshairFilterEnts()
|
||||
if not self:IsInitialized() or not LVS.MapDoneLoading then return { self } end -- wait for the server to be ready
|
||||
|
||||
if not istable( self.CrosshairFilterEnts ) then
|
||||
self.CrosshairFilterEnts = {self}
|
||||
|
||||
timer.Simple(1, function()
|
||||
if not IsValid( self ) then return end
|
||||
|
||||
-- lets ask the server to build the filter for us because it has access to constraint.GetAllConstrainedEntities()
|
||||
net.Start( "lvs_player_request_filter" )
|
||||
net.WriteEntity( self )
|
||||
net.SendToServer()
|
||||
end)
|
||||
end
|
||||
|
||||
return self.CrosshairFilterEnts
|
||||
end
|
||||
|
||||
function ENT:FlyByThink()
|
||||
end
|
||||
|
||||
function ENT:StopFlyBy()
|
||||
end
|
||||
|
||||
function ENT:StopDeathSound()
|
||||
end
|
||||
|
||||
function ENT:OnDestroyed()
|
||||
end
|
||||
|
||||
net.Receive( "lvs_vehicle_destroy", function( len )
|
||||
local ent = net.ReadEntity()
|
||||
|
||||
if not IsValid( ent ) or not isfunction( ent.OnDestroyed ) then return end
|
||||
|
||||
ent:OnDestroyed()
|
||||
end )
|
||||
208
garrysmod/addons/lvs_base/lua/entities/lvs_base/cl_optics.lua
Normal file
208
garrysmod/addons/lvs_base/lua/entities/lvs_base/cl_optics.lua
Normal file
@@ -0,0 +1,208 @@
|
||||
|
||||
ENT.OpticsFov = 30
|
||||
ENT.OpticsEnable = false
|
||||
ENT.OpticsZoomOnly = true
|
||||
ENT.OpticsFirstPerson = true
|
||||
ENT.OpticsThirdPerson = true
|
||||
ENT.OpticsPodIndex = {
|
||||
[1] = true,
|
||||
}
|
||||
|
||||
ENT.OpticsCrosshairMaterial = Material( "vgui/circle" )
|
||||
ENT.OpticsCrosshairColor = Color(0,0,0,255)
|
||||
ENT.OpticsCrosshairSize = 5
|
||||
|
||||
function ENT:PaintOpticsCrosshair( Pos2D )
|
||||
if not Pos2D.visible then return end
|
||||
|
||||
local size = self.OpticsCrosshairSize
|
||||
|
||||
surface.SetMaterial( self.OpticsCrosshairMaterial )
|
||||
surface.SetDrawColor( self.OpticsCrosshairColor )
|
||||
surface.DrawTexturedRect( Pos2D.x - size * 0.5, Pos2D.y - size * 0.5, size, size )
|
||||
end
|
||||
|
||||
function ENT:CalcOpticsCrosshairDot( Pos2D )
|
||||
self:PaintOpticsCrosshair( Pos2D )
|
||||
end
|
||||
|
||||
function ENT:GetOpticsEnabled()
|
||||
local EntTable = self:GetTable()
|
||||
|
||||
if not EntTable.OpticsEnable then return false end
|
||||
|
||||
local ply = LocalPlayer()
|
||||
|
||||
if not IsValid( ply ) then return false end
|
||||
|
||||
local pod = ply:GetVehicle()
|
||||
local PodIndex = pod:lvsGetPodIndex()
|
||||
if pod == self:GetDriverSeat() then
|
||||
PodIndex = 1
|
||||
end
|
||||
|
||||
if EntTable.OpticsPodIndex[ PodIndex ] then
|
||||
if pod:GetThirdPersonMode() then
|
||||
return EntTable.OpticsThirdPerson
|
||||
else
|
||||
return EntTable.OpticsFirstPerson
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function ENT:UseOptics()
|
||||
if self.OpticsZoomOnly and self:GetZoom() ~= 1 then return false end
|
||||
|
||||
return self:GetOpticsEnabled()
|
||||
end
|
||||
|
||||
function ENT:PaintCrosshairCenter( Pos2D, Col )
|
||||
if self:UseOptics() then
|
||||
if self.OpticsScreenCentered then
|
||||
self:CalcOpticsCrosshairDot( Pos2D )
|
||||
|
||||
local ScreenCenter2D = {
|
||||
x = ScrW() * 0.5,
|
||||
y = ScrH() * 0.5,
|
||||
visible = true,
|
||||
}
|
||||
|
||||
self:PaintOptics( ScreenCenter2D, Col, LocalPlayer():GetVehicle():GetNWInt( "pPodIndex", -1 ), 1 )
|
||||
else
|
||||
self:PaintOptics( Pos2D, Col, LocalPlayer():GetVehicle():GetNWInt( "pPodIndex", -1 ), 1 )
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
if not Col then
|
||||
Col = Color( 255, 255, 255, 255 )
|
||||
end
|
||||
|
||||
local Alpha = Col.a / 255
|
||||
local Shadow = Color( 0, 0, 0, 80 * Alpha )
|
||||
|
||||
surface.DrawCircle( Pos2D.x, Pos2D.y, 4, Shadow )
|
||||
surface.DrawCircle( Pos2D.x, Pos2D.y, 5, Col )
|
||||
surface.DrawCircle( Pos2D.x, Pos2D.y, 6, Shadow )
|
||||
end
|
||||
|
||||
function ENT:PaintCrosshairOuter( Pos2D, Col )
|
||||
if self:UseOptics() then
|
||||
if self.OpticsScreenCentered then
|
||||
self:CalcOpticsCrosshairDot( Pos2D )
|
||||
|
||||
local ScreenCenter2D = {
|
||||
x = ScrW() * 0.5,
|
||||
y = ScrH() * 0.5,
|
||||
visible = true,
|
||||
}
|
||||
|
||||
self:PaintOptics( ScreenCenter2D, Col, LocalPlayer():GetVehicle():GetNWInt( "pPodIndex", -1 ), 2 )
|
||||
else
|
||||
self:PaintOptics( Pos2D, Col, LocalPlayer():GetVehicle():GetNWInt( "pPodIndex", -1 ), 2 )
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
if not Col then
|
||||
Col = Color( 255, 255, 255, 255 )
|
||||
end
|
||||
|
||||
local Alpha = Col.a / 255
|
||||
local Shadow = Color( 0, 0, 0, 80 * Alpha )
|
||||
|
||||
surface.DrawCircle( Pos2D.x,Pos2D.y, 17, Shadow )
|
||||
surface.DrawCircle( Pos2D.x, Pos2D.y, 18, Col )
|
||||
|
||||
if LVS.AntiAliasingEnabled then
|
||||
surface.DrawCircle( Pos2D.x, Pos2D.y, 19, Color( Col.r, Col.g, Col.b, 150 * Alpha ) )
|
||||
surface.DrawCircle( Pos2D.x, Pos2D.y, 20, Shadow )
|
||||
else
|
||||
surface.DrawCircle( Pos2D.x, Pos2D.y, 19, Shadow )
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:PaintCrosshairSquare( Pos2D, Col )
|
||||
if self:UseOptics() then
|
||||
if self.OpticsScreenCentered then
|
||||
self:CalcOpticsCrosshairDot( Pos2D )
|
||||
|
||||
local ScreenCenter2D = {
|
||||
x = ScrW() * 0.5,
|
||||
y = ScrH() * 0.5,
|
||||
visible = true,
|
||||
}
|
||||
|
||||
self:PaintOptics( ScreenCenter2D, Col, LocalPlayer():GetVehicle():GetNWInt( "pPodIndex", -1 ), 3 )
|
||||
else
|
||||
self:PaintOptics( Pos2D, Col, LocalPlayer():GetVehicle():GetNWInt( "pPodIndex", -1 ), 3 )
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
if not Col then
|
||||
Col = Color( 255, 255, 255, 255 )
|
||||
end
|
||||
|
||||
local X = Pos2D.x + 1
|
||||
local Y = Pos2D.y + 1
|
||||
|
||||
local Size = 20
|
||||
|
||||
surface.SetDrawColor( 0, 0, 0, 80 )
|
||||
surface.DrawLine( X - Size, Y + Size, X - Size * 0.5, Y + Size )
|
||||
surface.DrawLine( X + Size, Y + Size, X + Size * 0.5, Y + Size )
|
||||
surface.DrawLine( X - Size, Y + Size, X - Size, Y + Size * 0.5 )
|
||||
surface.DrawLine( X - Size, Y - Size, X - Size, Y - Size * 0.5 )
|
||||
surface.DrawLine( X + Size, Y + Size, X + Size, Y + Size * 0.5 )
|
||||
surface.DrawLine( X + Size, Y - Size, X + Size, Y - Size * 0.5 )
|
||||
surface.DrawLine( X - Size, Y - Size, X - Size * 0.5, Y - Size )
|
||||
surface.DrawLine( X + Size, Y - Size, X + Size * 0.5, Y - Size )
|
||||
|
||||
if Col then
|
||||
surface.SetDrawColor( Col.r, Col.g, Col.b, Col.a )
|
||||
else
|
||||
surface.SetDrawColor( 255, 255, 255, 255 )
|
||||
end
|
||||
|
||||
X = Pos2D.x
|
||||
Y = Pos2D.y
|
||||
|
||||
surface.DrawLine( X - Size, Y + Size, X - Size * 0.5, Y + Size )
|
||||
surface.DrawLine( X + Size, Y + Size, X + Size * 0.5, Y + Size )
|
||||
surface.DrawLine( X - Size, Y + Size, X - Size, Y + Size * 0.5 )
|
||||
surface.DrawLine( X - Size, Y - Size, X - Size, Y - Size * 0.5 )
|
||||
surface.DrawLine( X + Size, Y + Size, X + Size, Y + Size * 0.5 )
|
||||
surface.DrawLine( X + Size, Y - Size, X + Size, Y - Size * 0.5 )
|
||||
surface.DrawLine( X - Size, Y - Size, X - Size * 0.5, Y - Size )
|
||||
surface.DrawLine( X + Size, Y - Size, X + Size * 0.5, Y - Size )
|
||||
end
|
||||
|
||||
function ENT:DrawRotatedText( text, x, y, font, color, ang)
|
||||
render.PushFilterMag( TEXFILTER.ANISOTROPIC )
|
||||
render.PushFilterMin( TEXFILTER.ANISOTROPIC )
|
||||
|
||||
local m = Matrix()
|
||||
m:Translate( Vector( x, y, 0 ) )
|
||||
m:Rotate( Angle( 0, ang, 0 ) )
|
||||
|
||||
surface.SetFont( font )
|
||||
local w, h = surface.GetTextSize( text )
|
||||
|
||||
m:Translate( -Vector( w / 2, h / 2, 0 ) )
|
||||
|
||||
cam.PushModelMatrix( m )
|
||||
draw.DrawText( text, font, 0, 0, color )
|
||||
cam.PopModelMatrix()
|
||||
|
||||
render.PopFilterMag()
|
||||
render.PopFilterMin()
|
||||
end
|
||||
|
||||
function ENT:PaintOptics( Pos2D, Col, PodIndex, Type )
|
||||
end
|
||||
@@ -0,0 +1,147 @@
|
||||
|
||||
ENT.IconVehicleLocked = Material( "lvs/locked.png" )
|
||||
|
||||
LVS:AddHudEditor( "SeatSwitcher", ScrW() - 360, 10, 350, 60, 350, 60, "SEAT SWITCHER",
|
||||
function( self, vehicle, X, Y, W, H, ScrX, ScrY, ply )
|
||||
if not vehicle.LVSHudPaintSeatSwitcher then return end
|
||||
|
||||
vehicle:LVSHudPaintSeatSwitcher( X, Y, W, 30, ScrX, ScrY, ply )
|
||||
end
|
||||
)
|
||||
|
||||
function ENT:LVSHudPaintSeatSwitcher( X, Y, w, h, ScrX, ScrY, ply )
|
||||
local pSeats = table.Copy( self:GetPassengerSeats() )
|
||||
local SeatCount = table.Count( pSeats )
|
||||
|
||||
if SeatCount <= 0 then return end
|
||||
|
||||
pSeats[0] = self:GetDriverSeat()
|
||||
|
||||
draw.NoTexture()
|
||||
|
||||
local HasAI = self:GetAI()
|
||||
local HasAIGunners = self:GetAIGunners()
|
||||
|
||||
local MySeat = ply:GetVehicle():lvsGetPodIndex()
|
||||
|
||||
local Passengers = {}
|
||||
for _, player in pairs( player.GetAll() ) do
|
||||
if player:lvsGetVehicle() == self then
|
||||
local Pod = player:GetVehicle()
|
||||
Passengers[ Pod:lvsGetPodIndex() ] = player:GetName()
|
||||
end
|
||||
end
|
||||
|
||||
if HasAI then
|
||||
Passengers[1] = "[AI] "..self.PrintName
|
||||
end
|
||||
|
||||
if HasAIGunners then
|
||||
for _, Pod in pairs( self:GetPassengerSeats() ) do
|
||||
if IsValid( Pod:GetDriver() ) then continue end
|
||||
|
||||
local weapon = Pod:lvsGetWeapon()
|
||||
|
||||
if not IsValid( weapon ) then continue end
|
||||
|
||||
Passengers[ weapon:GetPodIndex() ] = "[AI] Gunner"
|
||||
end
|
||||
end
|
||||
|
||||
ply.SwitcherTime = ply.SwitcherTime or 0
|
||||
ply._lvsoldPassengers = ply._lvsoldPassengers or {}
|
||||
|
||||
local Time = CurTime()
|
||||
for k, v in pairs( Passengers ) do
|
||||
if ply._lvsoldPassengers[k] ~= v then
|
||||
ply._lvsoldPassengers[k] = v
|
||||
ply.SwitcherTime = Time + 2
|
||||
end
|
||||
end
|
||||
for k, v in pairs( ply._lvsoldPassengers ) do
|
||||
if not Passengers[k] then
|
||||
ply._lvsoldPassengers[k] = nil
|
||||
ply.SwitcherTime = Time + 2
|
||||
end
|
||||
end
|
||||
for _, v in pairs( LVS.pSwitchKeysInv ) do
|
||||
if input.IsKeyDown(v) then
|
||||
ply.SwitcherTime = Time + 2
|
||||
end
|
||||
end
|
||||
|
||||
local Hide = ply.SwitcherTime > Time
|
||||
|
||||
ply.smHider = ply.smHider and (ply.smHider + ((Hide and 1 or 0) - ply.smHider) * RealFrameTime() * 15) or 0
|
||||
|
||||
local Alpha1 = 135 + 110 * ply.smHider
|
||||
local HiderOffset = 270 * ply.smHider
|
||||
local xPos = w - 35
|
||||
local yPos = Y - (SeatCount + 1) * 30 + h + 5
|
||||
|
||||
local SwapY = false
|
||||
local SwapX = false
|
||||
|
||||
local xHider = HiderOffset
|
||||
|
||||
if X < (ScrX * 0.5 - w * 0.5) then
|
||||
SwapX = true
|
||||
xPos = 0
|
||||
xHider = 0
|
||||
end
|
||||
|
||||
if Y < (ScrY * 0.5 - h * 0.5) then
|
||||
SwapY = true
|
||||
yPos = Y - h
|
||||
end
|
||||
|
||||
for _, Pod in pairs( pSeats ) do
|
||||
if not IsValid( Pod ) then continue end
|
||||
|
||||
local I = Pod:lvsGetPodIndex()
|
||||
|
||||
if I <= 0 then continue end
|
||||
|
||||
if not Hide and I > 10 then continue end
|
||||
|
||||
if I == MySeat then
|
||||
draw.RoundedBox(5, X + xPos - xHider, yPos + I * 30, 35 + HiderOffset, 25, Color(LVS.ThemeColor.r, LVS.ThemeColor.g, LVS.ThemeColor.b,100 + 50 * ply.smHider) )
|
||||
else
|
||||
draw.RoundedBox(5, X + xPos - xHider, yPos + I * 30, 35 + HiderOffset, 25, Color(0,0,0,100 + 50 * ply.smHider) )
|
||||
end
|
||||
|
||||
if Hide then
|
||||
if Passengers[I] then
|
||||
draw.DrawText( Passengers[I], "LVS_FONT_SWITCHER", X + 40 + xPos - xHider, yPos + I * 30 + 2.5, Color( 255, 255, 255, Alpha1 ), TEXT_ALIGN_LEFT )
|
||||
else
|
||||
draw.DrawText( "-", "LVS_FONT_SWITCHER", X + 40 + xPos - xHider, yPos + I * 30 + 2.5, Color( 255, 255, 255, Alpha1 ), TEXT_ALIGN_LEFT )
|
||||
end
|
||||
|
||||
draw.DrawText( "["..I.."]", "LVS_FONT_SWITCHER", X + 17 + xPos - xHider, yPos + I * 30 + 2.5, Color( 255, 255, 255, Alpha1 ), TEXT_ALIGN_CENTER )
|
||||
else
|
||||
if Passengers[I] then
|
||||
draw.DrawText( "[^"..I.."]", "LVS_FONT_SWITCHER", X + 17 + xPos - xHider, yPos + I * 30 + 2.5, Color( 255, 255, 255, Alpha1 ), TEXT_ALIGN_CENTER )
|
||||
else
|
||||
draw.DrawText( "["..I.."]", "LVS_FONT_SWITCHER", X + 17 + xPos - xHider, yPos + I * 30 + 2.5, Color( 255, 255, 255, Alpha1 ), TEXT_ALIGN_CENTER )
|
||||
end
|
||||
end
|
||||
|
||||
if not self:GetlvsLockedStatus() then continue end
|
||||
|
||||
local xLocker = SwapX and 35 + HiderOffset or -25 - HiderOffset
|
||||
|
||||
if SwapY then
|
||||
if I == 1 then
|
||||
surface.SetDrawColor( 255, 255, 255, 255 )
|
||||
surface.SetMaterial( self.IconVehicleLocked )
|
||||
surface.DrawTexturedRect( X + xPos + xLocker, yPos + I * 30, 25, 25 )
|
||||
end
|
||||
else
|
||||
if I == SeatCount then
|
||||
surface.SetDrawColor( 255, 255, 255, 255 )
|
||||
surface.SetMaterial( self.IconVehicleLocked )
|
||||
surface.DrawTexturedRect( X + xPos + xLocker, yPos + I * 30, 25, 25 )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,147 @@
|
||||
|
||||
ENT.TrailMaterial = Material( "trails/smoke" )
|
||||
ENT.TrailRed = 255
|
||||
ENT.TrailGreen = 255
|
||||
ENT.TrailBlue = 255
|
||||
ENT.TrailAlpha = 100
|
||||
|
||||
function ENT:OnTrail( active, id )
|
||||
end
|
||||
|
||||
function ENT:HandleTrail()
|
||||
if not self.RegisteredTrailPositions then return end
|
||||
|
||||
local FT = RealFrameTime()
|
||||
|
||||
local pos = self:GetPos()
|
||||
local vel = self:GetVelocity()
|
||||
local vel_length = vel:Length()
|
||||
|
||||
for id, data in pairs( self.RegisteredTrailPositions ) do
|
||||
local cur_pos = self:LocalToWorld( data.pos )
|
||||
local cur_vel = (cur_pos - data.oldpos) / FT
|
||||
|
||||
local cur_velL = math.abs( self:WorldToLocal( pos + cur_vel ).z )
|
||||
|
||||
if cur_velL > data.activation_speed and vel_length > data.min_flight_speed then
|
||||
if not data.id then
|
||||
data.id = self:StartTrail( data.pos, data.startsize, data.endsize, data.lifetime )
|
||||
self:OnTrail( true, data.id )
|
||||
end
|
||||
else
|
||||
if data.id then
|
||||
self:OnTrail( false, data.id )
|
||||
self:FinishTrail( data.id )
|
||||
data.id = nil
|
||||
end
|
||||
end
|
||||
|
||||
data.oldpos = cur_pos
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:RegisterTrail( Pos, StartSize, EndSize, LifeTime, min_flight_speed, activation_speed )
|
||||
if not istable( self.RegisteredTrailPositions ) then
|
||||
self.RegisteredTrailPositions = {}
|
||||
end
|
||||
|
||||
local data = {
|
||||
pos = Pos,
|
||||
oldpos = self:LocalToWorld( Pos ),
|
||||
startsize = StartSize,
|
||||
endsize = EndSize,
|
||||
lifetime = LifeTime,
|
||||
min_flight_speed = min_flight_speed,
|
||||
activation_speed = activation_speed,
|
||||
}
|
||||
|
||||
table.insert( self.RegisteredTrailPositions, data )
|
||||
end
|
||||
|
||||
function ENT:StartTrail( Pos, StartSize, EndSize, LifeTime )
|
||||
if not LVS.ShowTraileffects then return end
|
||||
|
||||
if not istable( self.TrailActive ) then
|
||||
self.TrailActive = {}
|
||||
end
|
||||
|
||||
local ID = 1
|
||||
for _,_ in ipairs( self.TrailActive ) do
|
||||
ID = ID + 1
|
||||
end
|
||||
|
||||
self.TrailActive[ ID ] = {
|
||||
lifetime = LifeTime,
|
||||
start_size = StartSize,
|
||||
end_size = EndSize,
|
||||
pos = Pos,
|
||||
active = true,
|
||||
positions = {},
|
||||
}
|
||||
|
||||
return ID
|
||||
end
|
||||
|
||||
function ENT:FinishTrail( ID )
|
||||
self.TrailActive[ ID ].active = false
|
||||
end
|
||||
|
||||
function ENT:DrawTrail()
|
||||
local EntTable = self:GetTable()
|
||||
|
||||
if not EntTable.TrailActive then return end
|
||||
|
||||
local Time = CurTime()
|
||||
|
||||
EntTable._NextTrail = EntTable._NextTrail or 0
|
||||
|
||||
local Set = EntTable._NextTrail < Time
|
||||
|
||||
render.SetMaterial( EntTable.TrailMaterial )
|
||||
|
||||
for ID, data in pairs( EntTable.TrailActive ) do
|
||||
|
||||
for pos_id, pos_data in pairs( data.positions ) do
|
||||
if Time - pos_data.time > data.lifetime then
|
||||
data.positions[ pos_id ] = nil
|
||||
end
|
||||
end
|
||||
|
||||
if Set then
|
||||
if data.active then
|
||||
local cur_pos = {
|
||||
time = Time,
|
||||
pos = self:LocalToWorld( data.pos ),
|
||||
}
|
||||
|
||||
table.insert( data.positions, cur_pos )
|
||||
table.sort( data.positions, function( a, b ) return a.time > b.time end )
|
||||
end
|
||||
end
|
||||
|
||||
local num = #data.positions
|
||||
|
||||
if num == 0 then
|
||||
if not data.active then
|
||||
EntTable.TrailActive[ ID ] = nil
|
||||
end
|
||||
|
||||
continue
|
||||
end
|
||||
|
||||
render.StartBeam( num )
|
||||
|
||||
for _, pos_data in ipairs( data.positions ) do
|
||||
local Scale = (pos_data.time + data.lifetime - Time) / data.lifetime
|
||||
local InvScale = 1 - Scale
|
||||
|
||||
render.AddBeam( pos_data.pos, data.start_size * Scale + data.end_size * InvScale, pos_data.time * 50, Color( EntTable.TrailRed, EntTable.TrailGreen, EntTable.TrailBlue, EntTable.TrailAlpha * Scale ^ 2 ) )
|
||||
end
|
||||
|
||||
render.EndBeam()
|
||||
end
|
||||
|
||||
if Set then
|
||||
EntTable._NextTrail = Time + 0.025
|
||||
end
|
||||
end
|
||||
509
garrysmod/addons/lvs_base/lua/entities/lvs_base/init.lua
Normal file
509
garrysmod/addons/lvs_base/lua/entities/lvs_base/init.lua
Normal file
@@ -0,0 +1,509 @@
|
||||
AddCSLuaFile( "shared.lua" )
|
||||
AddCSLuaFile( "sh_weapons.lua" )
|
||||
AddCSLuaFile( "sh_velocity_changer.lua" )
|
||||
AddCSLuaFile( "sh_variables.lua" )
|
||||
AddCSLuaFile( "cl_init.lua" )
|
||||
AddCSLuaFile( "cl_effects.lua" )
|
||||
AddCSLuaFile( "cl_hud.lua" )
|
||||
AddCSLuaFile( "cl_optics.lua" )
|
||||
AddCSLuaFile( "cl_trailsystem.lua" )
|
||||
AddCSLuaFile( "cl_seatswitcher.lua" )
|
||||
AddCSLuaFile( "cl_boneposeparemeter.lua" )
|
||||
include("shared.lua")
|
||||
include("sh_weapons.lua")
|
||||
include("sh_velocity_changer.lua")
|
||||
include("sh_variables.lua")
|
||||
include("sv_ai.lua")
|
||||
include("sv_cppi.lua")
|
||||
include("sv_duping.lua")
|
||||
include("sv_pod.lua")
|
||||
include("sv_engine.lua")
|
||||
include("sv_physics.lua")
|
||||
include("sv_physics_damagesystem.lua")
|
||||
include("sv_damagesystem.lua")
|
||||
include("sv_shieldsystem.lua")
|
||||
include("sv_doorsystem.lua")
|
||||
|
||||
ENT.WaterLevelPreventStart = 1
|
||||
ENT.WaterLevelAutoStop = 2
|
||||
ENT.WaterLevelDestroyAI = 2
|
||||
|
||||
function ENT:SpawnFunction( ply, tr, ClassName )
|
||||
|
||||
if ply:InVehicle() then
|
||||
local ent = ents.Create( ClassName )
|
||||
ent:StoreCPPI( ply )
|
||||
ent:SetPos( ply:GetPos() + Vector(0,0,100 + ent.SpawnNormalOffset) )
|
||||
ent:SetAngles( Angle(0, ply:EyeAngles().y + ent.SpawnAngleOffset, 0 ) )
|
||||
ent:Spawn()
|
||||
ent:Activate()
|
||||
|
||||
return ent
|
||||
else
|
||||
if not tr.Hit then return end
|
||||
|
||||
local ent = ents.Create( ClassName )
|
||||
ent:StoreCPPI( ply )
|
||||
ent:SetPos( tr.HitPos + tr.HitNormal * ent.SpawnNormalOffset )
|
||||
ent:SetAngles( Angle(0, ply:EyeAngles().y + ent.SpawnAngleOffset, 0 ) )
|
||||
ent:Spawn()
|
||||
ent:Activate()
|
||||
|
||||
return ent
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Initialize()
|
||||
self:SetModel( self.MDL )
|
||||
|
||||
self:PhysicsInit( SOLID_VPHYSICS, self.MassCenterOverride )
|
||||
self:SetMoveType( MOVETYPE_VPHYSICS )
|
||||
self:SetSolid( SOLID_VPHYSICS )
|
||||
self:SetUseType( SIMPLE_USE )
|
||||
self:SetRenderMode( RENDERMODE_NORMAL )
|
||||
|
||||
-- this is so vj npcs can still see us
|
||||
self:AddEFlags( EFL_DONTBLOCKLOS )
|
||||
|
||||
-- this is for our npc relationship system to work
|
||||
self:AddFlags( FL_OBJECT )
|
||||
|
||||
local PObj = self:GetPhysicsObject()
|
||||
|
||||
if not IsValid( PObj ) then
|
||||
self:Remove()
|
||||
|
||||
print("LVS: missing model. Vehicle terminated.")
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
PObj:SetMaterial( "default_silent" )
|
||||
PObj:EnableMotion( false )
|
||||
PObj:EnableDrag( false )
|
||||
|
||||
timer.Simple(0, function()
|
||||
if not IsValid( self ) or not IsValid( PObj ) then print("LVS: ERROR couldn't initialize vehicle.") return end
|
||||
|
||||
self:PostInitialize( PObj )
|
||||
end)
|
||||
|
||||
if not istable( self.GibModels ) then return end
|
||||
|
||||
for _, modelName in ipairs( self.GibModels ) do
|
||||
util.PrecacheModel( modelName )
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:PostInitialize( PObj )
|
||||
local SpawnSuccess, ErrorMsg = pcall( function() self:OnSpawn( PObj ) end )
|
||||
|
||||
if not SpawnSuccess then
|
||||
ErrorNoHalt( "\n[ERROR] "..ErrorMsg.."\n\n" )
|
||||
end
|
||||
|
||||
self:StartMotionController()
|
||||
|
||||
self:AutoAI()
|
||||
|
||||
self:CallOnRemove( "finish_weapons_on_delete", function( ent )
|
||||
ent:WeaponsFinish()
|
||||
|
||||
for _, pod in pairs( ent:GetPassengerSeats() ) do
|
||||
if not IsValid( pod ) then continue end
|
||||
|
||||
local weapon = pod:lvsGetWeapon()
|
||||
|
||||
if not IsValid( weapon ) or not weapon._activeWeapon then continue end
|
||||
|
||||
local CurWeapon = self.WEAPONS[ weapon:GetPodIndex() ][ weapon._activeWeapon ]
|
||||
|
||||
if not CurWeapon then continue end
|
||||
|
||||
if CurWeapon.FinishAttack then
|
||||
CurWeapon.FinishAttack( weapon )
|
||||
end
|
||||
end
|
||||
|
||||
ent:WeaponsOnRemove()
|
||||
end)
|
||||
|
||||
self:SetlvsReady( true )
|
||||
self:GetCrosshairFilterEnts()
|
||||
|
||||
self:OnSpawnFinish( PObj )
|
||||
end
|
||||
|
||||
function ENT:OnSpawnFinish( PObj )
|
||||
if GetConVar( "developer" ):GetInt() ~= 1 then
|
||||
PObj:EnableMotion( true )
|
||||
end
|
||||
|
||||
self:PhysWake()
|
||||
end
|
||||
|
||||
function ENT:OnSpawn( PObj )
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
self:NextThink( CurTime() )
|
||||
|
||||
if not self:IsInitialized() then return true end
|
||||
|
||||
self:HandleActive()
|
||||
self:HandleStart()
|
||||
self:PhysicsThink()
|
||||
self:DamageThink()
|
||||
self:WeaponsThink()
|
||||
self:ShieldThink()
|
||||
|
||||
if self:GetAI() then self:RunAI() end
|
||||
|
||||
self:OnTick()
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function ENT:OnDriverChanged( Old, New, VehicleIsActive )
|
||||
self:OnPassengerChanged( Old, New, 1 )
|
||||
end
|
||||
|
||||
function ENT:OnPassengerChanged( Old, New, PodIndex )
|
||||
end
|
||||
|
||||
function ENT:OnSwitchSeat( ply, oldpod, newpod )
|
||||
end
|
||||
|
||||
function ENT:OnTick()
|
||||
end
|
||||
|
||||
function ENT:OnRemoved()
|
||||
end
|
||||
|
||||
function ENT:OnRemove()
|
||||
self:OnRemoved()
|
||||
end
|
||||
|
||||
function ENT:Lock()
|
||||
for _, Handler in pairs( self:GetDoorHandlers() ) do
|
||||
if not IsValid( Handler ) then continue end
|
||||
|
||||
Handler:Close( ply )
|
||||
end
|
||||
|
||||
if self:GetlvsLockedStatus() then return end
|
||||
|
||||
self:SetlvsLockedStatus( true )
|
||||
self:EmitSound( "doors/latchlocked2.wav" )
|
||||
end
|
||||
|
||||
function ENT:UnLock()
|
||||
if not self:GetlvsLockedStatus() then return end
|
||||
|
||||
self:SetlvsLockedStatus( false )
|
||||
self:EmitSound( "doors/latchunlocked1.wav" )
|
||||
end
|
||||
|
||||
function ENT:IsUseAllowed( ply )
|
||||
if not IsValid( ply ) then return false end
|
||||
|
||||
if (ply._lvsNextUse or 0) > CurTime() then return false end
|
||||
|
||||
if self:GetlvsLockedStatus() or (LVS.TeamPassenger and ((self:GetAITEAM() ~= ply:lvsGetAITeam()) and ply:lvsGetAITeam() ~= 0 and self:GetAITEAM() ~= 0)) then
|
||||
self:EmitSound( "doors/default_locked.wav" )
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function ENT:Use( ply )
|
||||
if not self:IsUseAllowed( ply ) then return end
|
||||
|
||||
if not istable( self._DoorHandlers ) then
|
||||
self:SetPassenger( ply )
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
if ply:GetMoveType() == MOVETYPE_NOCLIP then
|
||||
ply._lvsNextExit = CurTime() + 0.5
|
||||
|
||||
self:SetPassenger( ply )
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
if ply:KeyDown( IN_SPEED ) then return end
|
||||
|
||||
local Handler = self:GetDoorHandler( ply )
|
||||
|
||||
if not IsValid( Handler ) then
|
||||
if self:HasDoorSystem() and ply:GetMoveType() == MOVETYPE_WALK then
|
||||
return
|
||||
end
|
||||
|
||||
self:SetPassenger( ply )
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
local Pod = Handler:GetLinkedSeat()
|
||||
|
||||
if not IsValid( Pod ) then Handler:Use( ply ) return end
|
||||
|
||||
if not Handler:IsOpen() then Handler:Open( ply ) return end
|
||||
|
||||
if Handler:IsOpen() then
|
||||
Handler:Close( ply )
|
||||
else
|
||||
Handler:OpenAndClose( ply )
|
||||
end
|
||||
|
||||
if ply:KeyDown( IN_WALK ) then
|
||||
|
||||
self:SetPassenger( ply )
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
local DriverSeat = self:GetDriverSeat()
|
||||
|
||||
if Pod ~= self:GetDriverSeat() then
|
||||
if IsValid( Pod:GetDriver() ) then
|
||||
self:SetPassenger( ply )
|
||||
else
|
||||
ply:EnterVehicle( Pod )
|
||||
self:AlignView( ply )
|
||||
|
||||
hook.Run( "LVS.UpdateRelationship", self )
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
if self:GetAI() then
|
||||
self:SetPassenger( ply )
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
if IsValid( Pod:GetDriver() ) then
|
||||
self:SetPassenger( ply )
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
if hook.Run( "LVS.CanPlayerDrive", ply, self ) ~= false then
|
||||
ply:EnterVehicle( Pod )
|
||||
self:AlignView( ply )
|
||||
|
||||
hook.Run( "LVS.UpdateRelationship", self )
|
||||
else
|
||||
hook.Run( "LVS.OnPlayerCannotDrive", ply, self )
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:OnTakeDamage( dmginfo )
|
||||
self:CalcShieldDamage( dmginfo )
|
||||
self:CalcDamage( dmginfo )
|
||||
self:TakePhysicsDamage( dmginfo )
|
||||
self:OnAITakeDamage( dmginfo )
|
||||
self:RemoveAllDecals()
|
||||
end
|
||||
|
||||
function ENT:OnMaintenance()
|
||||
end
|
||||
|
||||
function ENT:UpdateTransmitState()
|
||||
return TRANSMIT_ALWAYS
|
||||
end
|
||||
|
||||
function ENT:GetMissileOffset()
|
||||
return self:OBBCenter()
|
||||
end
|
||||
|
||||
function ENT:RebuildCrosshairFilterEnts()
|
||||
self.CrosshairFilterEnts = nil
|
||||
|
||||
local CrosshairFilterEnts = table.Copy( self:GetCrosshairFilterEnts() )
|
||||
|
||||
for id, entity in pairs( CrosshairFilterEnts ) do
|
||||
if not IsValid( entity ) or entity:GetNoDraw() then
|
||||
CrosshairFilterEnts[ id ] = nil
|
||||
end
|
||||
end
|
||||
|
||||
net.Start( "lvs_player_request_filter" )
|
||||
net.WriteEntity( self )
|
||||
net.WriteTable( CrosshairFilterEnts )
|
||||
net.Broadcast()
|
||||
end
|
||||
|
||||
function ENT:GetCrosshairFilterEnts()
|
||||
if not self:IsInitialized() then return { self } end
|
||||
|
||||
if not istable( self.CrosshairFilterEnts ) then
|
||||
self.CrosshairFilterEnts = {}
|
||||
|
||||
for _, Entity in pairs( constraint.GetAllConstrainedEntities( self ) ) do
|
||||
if not IsValid( Entity ) then continue end
|
||||
|
||||
table.insert( self.CrosshairFilterEnts , Entity )
|
||||
end
|
||||
|
||||
for _, Parent in pairs( self.CrosshairFilterEnts ) do
|
||||
for _, Child in pairs( Parent:GetChildren() ) do
|
||||
if not IsValid( Child ) then continue end
|
||||
|
||||
table.insert( self.CrosshairFilterEnts , Child )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return self.CrosshairFilterEnts
|
||||
end
|
||||
|
||||
function ENT:LVSFireBullet( data )
|
||||
data.Entity = self
|
||||
data.Velocity = data.Velocity + self:GetVelocity():Length()
|
||||
data.SrcEntity = self:WorldToLocal( data.Src )
|
||||
|
||||
LVS:FireBullet( data )
|
||||
end
|
||||
|
||||
function ENT:AddSoundEmitter( pos, snd, snd_interior )
|
||||
local Emitter = ents.Create( "lvs_soundemitter" )
|
||||
|
||||
if not IsValid( Emitter ) then
|
||||
self:Remove()
|
||||
|
||||
print("LVS: Failed to create sound emitter entity. Vehicle terminated.")
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
Emitter:SetPos( self:LocalToWorld( pos ) )
|
||||
Emitter:SetAngles( self:GetAngles() )
|
||||
Emitter:Spawn()
|
||||
Emitter:Activate()
|
||||
Emitter:SetParent( self )
|
||||
Emitter:SetBase( self )
|
||||
|
||||
if snd and not snd_interior then
|
||||
Emitter:SetSound( snd )
|
||||
Emitter:SetSoundInterior( snd )
|
||||
else
|
||||
Emitter:SetSound( snd or "" )
|
||||
Emitter:SetSoundInterior( snd_interior )
|
||||
end
|
||||
|
||||
self:DeleteOnRemove( Emitter )
|
||||
|
||||
self:TransferCPPI( Emitter )
|
||||
|
||||
return Emitter
|
||||
end
|
||||
|
||||
function ENT:AddFlameEmitter( target, attachment )
|
||||
if not IsValid( target ) then return end
|
||||
|
||||
local FlameEmitter = ents.Create( "lvs_firestreamemitter" )
|
||||
FlameEmitter:AttachTo( target, attachment )
|
||||
FlameEmitter:Spawn()
|
||||
FlameEmitter:Activate()
|
||||
|
||||
return FlameEmitter
|
||||
end
|
||||
|
||||
function ENT:AddAmmoRack( pos, fxpos, ang, mins, maxs, target )
|
||||
local AmmoRack = ents.Create( "lvs_wheeldrive_ammorack" )
|
||||
|
||||
if not IsValid( AmmoRack ) then
|
||||
self:Remove()
|
||||
|
||||
print("LVS: Failed to create fueltank entity. Vehicle terminated.")
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
if not target then target = self end
|
||||
|
||||
AmmoRack:SetPos( target:LocalToWorld( pos ) )
|
||||
AmmoRack:SetAngles( target:GetAngles() )
|
||||
AmmoRack:Spawn()
|
||||
AmmoRack:Activate()
|
||||
AmmoRack:SetParent( target )
|
||||
AmmoRack:SetBase( self )
|
||||
AmmoRack:SetEffectPosition( fxpos )
|
||||
|
||||
self:DeleteOnRemove( AmmoRack )
|
||||
|
||||
self:TransferCPPI( AmmoRack )
|
||||
|
||||
mins = mins or Vector(-30,-30,-30)
|
||||
maxs = maxs or Vector(30,30,30)
|
||||
|
||||
debugoverlay.BoxAngles( target:LocalToWorld( pos ), mins, maxs, target:LocalToWorldAngles( ang ), 15, Color( 255, 0, 0, 255 ) )
|
||||
|
||||
self:AddDS( {
|
||||
pos = pos,
|
||||
ang = ang,
|
||||
mins = mins,
|
||||
maxs = maxs,
|
||||
entity = target,
|
||||
Callback = function( tbl, ent, dmginfo )
|
||||
if not IsValid( AmmoRack ) then return end
|
||||
|
||||
AmmoRack:TakeTransmittedDamage( dmginfo )
|
||||
|
||||
if AmmoRack:GetDestroyed() then return end
|
||||
|
||||
local OriginalDamage = dmginfo:GetDamage()
|
||||
|
||||
dmginfo:SetDamage( math.min( 2, OriginalDamage ) )
|
||||
end
|
||||
} )
|
||||
|
||||
return AmmoRack
|
||||
end
|
||||
|
||||
function ENT:AddTrailerHitch( pos, hitchtype )
|
||||
if not hitchtype then
|
||||
|
||||
hitchtype = LVS.HITCHTYPE_MALE
|
||||
|
||||
end
|
||||
|
||||
local TrailerHitch = ents.Create( "lvs_wheeldrive_trailerhitch" )
|
||||
|
||||
if not IsValid( TrailerHitch ) then
|
||||
self:Remove()
|
||||
|
||||
print("LVS: Failed to create trailerhitch entity. Vehicle terminated.")
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
TrailerHitch:SetPos( self:LocalToWorld( pos ) )
|
||||
TrailerHitch:SetAngles( self:GetAngles() )
|
||||
TrailerHitch:Spawn()
|
||||
TrailerHitch:Activate()
|
||||
TrailerHitch:SetParent( self )
|
||||
TrailerHitch:SetBase( self )
|
||||
TrailerHitch:SetHitchType( hitchtype )
|
||||
|
||||
self:TransferCPPI( TrailerHitch )
|
||||
|
||||
return TrailerHitch
|
||||
end
|
||||
|
||||
function ENT:OnCoupleChanged( targetVehicle, targetHitch, active )
|
||||
end
|
||||
|
||||
function ENT:OnStartDrag( caller, activator )
|
||||
end
|
||||
|
||||
function ENT:OnStopDrag( caller, activator )
|
||||
end
|
||||
@@ -0,0 +1,40 @@
|
||||
|
||||
function ENT:HasQuickVar( name )
|
||||
name = "_smValue"..name
|
||||
|
||||
return self[ name ] ~= nil
|
||||
end
|
||||
|
||||
function ENT:GetQuickVar( name )
|
||||
name = "_smValue"..name
|
||||
|
||||
if not self[ name ] then return 0 end
|
||||
|
||||
return self[ name ]
|
||||
end
|
||||
|
||||
if CLIENT then
|
||||
function ENT:QuickLerp( name, target, rate )
|
||||
name = "_smValue"..name
|
||||
|
||||
local EntTable = self:GetTable()
|
||||
|
||||
if not EntTable[ name ] then EntTable[ name ] = 0 end
|
||||
|
||||
EntTable[ name ] = EntTable[ name ] + (target - EntTable[ name ]) * math.min( RealFrameTime() * (rate or 10), 1 )
|
||||
|
||||
return EntTable[ name ]
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
function ENT:QuickLerp( name, target, rate )
|
||||
name = "_smValue"..name
|
||||
|
||||
if not self[ name ] then self[ name ] = 0 end
|
||||
|
||||
self[ name ] = self[ name ] + (target - self[ name ]) * math.min( FrameTime() * (rate or 10), 1 )
|
||||
|
||||
return self[ name ]
|
||||
end
|
||||
@@ -0,0 +1,69 @@
|
||||
|
||||
if CLIENT then
|
||||
hook.Add( "InitPostEntity", "!!!lvsUpdateMaxVelocity", function()
|
||||
net.Start( "lvs_maxvelocity_updater" )
|
||||
net.SendToServer()
|
||||
|
||||
hook.Remove( "InitPostEntity", "!!!lvsUpdateMaxVelocity" )
|
||||
end )
|
||||
|
||||
net.Receive( "lvs_maxvelocity_updater", function( len, ply )
|
||||
for _, data in pairs( net.ReadTable() ) do
|
||||
local entity = data.ent
|
||||
|
||||
if not IsValid( entity ) or not entity.LVS or not entity.MaxVelocity then continue end
|
||||
|
||||
entity.MaxVelocity = data.vel
|
||||
end
|
||||
end )
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
util.AddNetworkString( "lvs_maxvelocity_updater" )
|
||||
|
||||
local UpdatedVehicles = {}
|
||||
|
||||
net.Receive( "lvs_maxvelocity_updater", function( len, ply )
|
||||
if ply._lvsAlreadyAskedForVelocityUpdate then return end
|
||||
|
||||
ply._lvsAlreadyAskedForVelocityUpdate = true
|
||||
|
||||
local TableSend = {}
|
||||
|
||||
for id, data in pairs( UpdatedVehicles ) do
|
||||
local entity = data.ent
|
||||
|
||||
if IsValid( entity ) and entity.LVS and isfunction( entity.ChangeVelocity ) then
|
||||
table.insert( TableSend, data )
|
||||
|
||||
continue
|
||||
end
|
||||
|
||||
UpdatedVehicles[ id ] = nil
|
||||
end
|
||||
|
||||
if #TableSend == 0 then return end
|
||||
|
||||
net.Start( "lvs_maxvelocity_updater" )
|
||||
net.WriteTable( TableSend )
|
||||
net.Send( ply )
|
||||
end )
|
||||
|
||||
function ENT:ChangeVelocity( new )
|
||||
new = math.Clamp( new, 1, physenv.GetPerformanceSettings().MaxVelocity )
|
||||
|
||||
self.MaxVelocity = new
|
||||
|
||||
timer.Simple(0, function()
|
||||
if not IsValid( self ) then return end
|
||||
|
||||
local data = { ent = self, vel = new }
|
||||
|
||||
table.insert( UpdatedVehicles, data )
|
||||
|
||||
net.Start( "lvs_maxvelocity_updater" )
|
||||
net.WriteTable( {data} )
|
||||
net.Broadcast()
|
||||
end)
|
||||
end
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user