mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 05:43:46 +03:00
Upload
This commit is contained in:
346
gamemodes/ixhl2rp/entities/weapons/gmod_tool/shared.lua
Normal file
346
gamemodes/ixhl2rp/entities/weapons/gmod_tool/shared.lua
Normal file
@@ -0,0 +1,346 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
-- Variables that are used on both client and server
|
||||
|
||||
SWEP.PrintName = "Tool Gun"
|
||||
SWEP.Author = ""
|
||||
SWEP.Contact = ""
|
||||
SWEP.Purpose = ""
|
||||
SWEP.Instructions = ""
|
||||
|
||||
SWEP.ViewModel = "models/weapons/c_toolgun.mdl"
|
||||
SWEP.WorldModel = "models/weapons/w_toolgun.mdl"
|
||||
|
||||
SWEP.UseHands = true
|
||||
SWEP.Spawnable = true
|
||||
|
||||
-- Be nice, precache the models
|
||||
util.PrecacheModel( SWEP.ViewModel )
|
||||
util.PrecacheModel( SWEP.WorldModel )
|
||||
|
||||
-- Todo, make/find a better sound.
|
||||
-- SWEP.ShootSound = Sound( "Airboat.FireGunRevDown" )
|
||||
SWEP.ShootSound = Sound( "" )
|
||||
|
||||
SWEP.Tool = {}
|
||||
|
||||
SWEP.Primary.ClipSize = -1
|
||||
SWEP.Primary.DefaultClip = -1
|
||||
SWEP.Primary.Automatic = false
|
||||
SWEP.Primary.Ammo = "none"
|
||||
|
||||
SWEP.Secondary.ClipSize = -1
|
||||
SWEP.Secondary.DefaultClip = -1
|
||||
SWEP.Secondary.Automatic = false
|
||||
SWEP.Secondary.Ammo = "none"
|
||||
|
||||
SWEP.CanHolster = true
|
||||
SWEP.CanDeploy = true
|
||||
|
||||
function SWEP:InitializeTools()
|
||||
|
||||
local temp = {}
|
||||
|
||||
for k,v in pairs( self.Tool ) do
|
||||
|
||||
temp[k] = table.Copy( v )
|
||||
temp[k].SWEP = self
|
||||
temp[k].Owner = self.Owner
|
||||
temp[k].Weapon = self.Weapon
|
||||
temp[k]:Init()
|
||||
|
||||
end
|
||||
|
||||
self.Tool = temp
|
||||
|
||||
end
|
||||
|
||||
function SWEP:SetupDataTables()
|
||||
|
||||
self:NetworkVar( "Entity", 0, "TargetEntity1" )
|
||||
self:NetworkVar( "Entity", 1, "TargetEntity2" )
|
||||
self:NetworkVar( "Entity", 2, "TargetEntity3" )
|
||||
self:NetworkVar( "Entity", 3, "TargetEntity4" )
|
||||
|
||||
end
|
||||
|
||||
-- Convenience function to check object limits
|
||||
function SWEP:CheckLimit( str )
|
||||
return self:GetOwner():CheckLimit( str )
|
||||
end
|
||||
|
||||
function SWEP:Initialize()
|
||||
|
||||
self:SetHoldType( "revolver" )
|
||||
|
||||
self:InitializeTools()
|
||||
|
||||
-- We create these here. The problem is that these are meant to be constant values.
|
||||
-- in the toolmode they're not because some tools can be automatic while some tools aren't.
|
||||
-- Since this is a global table it's shared between all instances of the gun.
|
||||
-- By creating new tables here we're making it so each tool has its own instance of the table
|
||||
-- So changing it won't affect the other tools.
|
||||
|
||||
self.Primary = {
|
||||
ClipSize = -1,
|
||||
DefaultClip = -1,
|
||||
Automatic = false,
|
||||
Ammo = "none"
|
||||
}
|
||||
|
||||
self.Secondary = {
|
||||
ClipSize = -1,
|
||||
DefaultClip = -1,
|
||||
Automatic = false,
|
||||
Ammo = "none"
|
||||
}
|
||||
|
||||
end
|
||||
|
||||
function SWEP:OnRestore()
|
||||
|
||||
self:InitializeTools()
|
||||
|
||||
end
|
||||
|
||||
function SWEP:Precache()
|
||||
|
||||
util.PrecacheSound( self.ShootSound )
|
||||
|
||||
end
|
||||
|
||||
function SWEP:Reload()
|
||||
|
||||
-- This makes the reload a semi-automatic thing rather than a continuous thing
|
||||
if ( !self.Owner:KeyPressed( IN_RELOAD ) ) then return end
|
||||
|
||||
local mode = self:GetMode()
|
||||
local trace = self.Owner:GetEyeTrace()
|
||||
if ( !trace.Hit ) then return end
|
||||
|
||||
local tool = self:GetToolObject()
|
||||
if ( !tool ) then return end
|
||||
|
||||
tool:CheckObjects()
|
||||
|
||||
-- Does the server setting say it's ok?
|
||||
if ( !tool:Allowed() ) then return end
|
||||
|
||||
-- Ask the gamemode if it's ok to do this
|
||||
if ( !gamemode.Call( "CanTool", self.Owner, trace, mode ) ) then return end
|
||||
|
||||
if ( !tool:Reload( trace ) ) then return end
|
||||
|
||||
self:DoShootEffect( trace.HitPos, trace.HitNormal, trace.Entity, trace.PhysicsBone, IsFirstTimePredicted() )
|
||||
|
||||
end
|
||||
|
||||
-- Returns the mode we're in
|
||||
function SWEP:GetMode()
|
||||
|
||||
return self.Mode
|
||||
|
||||
end
|
||||
|
||||
-- Think does stuff every frame
|
||||
function SWEP:Think()
|
||||
|
||||
self.Mode = self.Owner:GetInfo( "gmod_toolmode" )
|
||||
|
||||
local tool = self:GetToolObject()
|
||||
if ( !tool ) then return end
|
||||
|
||||
tool:CheckObjects()
|
||||
|
||||
self.last_mode = self.current_mode
|
||||
self.current_mode = self.Mode
|
||||
|
||||
-- Release ghost entities if we're not allowed to use this new mode?
|
||||
if ( !tool:Allowed() ) then
|
||||
self:GetToolObject( self.last_mode ):ReleaseGhostEntity()
|
||||
return
|
||||
end
|
||||
|
||||
if ( self.last_mode != self.current_mode ) then
|
||||
|
||||
if ( !self:GetToolObject( self.last_mode ) ) then return end
|
||||
|
||||
-- We want to release the ghost entity just in case
|
||||
self:GetToolObject( self.last_mode ):Holster()
|
||||
|
||||
end
|
||||
|
||||
self.Primary.Automatic = tool.LeftClickAutomatic or false
|
||||
self.Secondary.Automatic = tool.RightClickAutomatic or false
|
||||
self.RequiresTraceHit = tool.RequiresTraceHit or true
|
||||
|
||||
tool:Think()
|
||||
|
||||
end
|
||||
|
||||
-- The shoot effect
|
||||
function SWEP:DoShootEffect( hitpos, hitnormal, entity, physbone, bFirstTimePredicted )
|
||||
|
||||
self:EmitSound( self.ShootSound )
|
||||
self:SendWeaponAnim( ACT_VM_PRIMARYATTACK ) -- View model animation
|
||||
|
||||
-- There's a bug with the model that's causing a muzzle to
|
||||
-- appear on everyone's screen when we fire this animation.
|
||||
self.Owner:SetAnimation( PLAYER_ATTACK1 ) -- 3rd Person Animation
|
||||
|
||||
if ( !bFirstTimePredicted ) then return end
|
||||
|
||||
--[[
|
||||
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin( hitpos )
|
||||
effectdata:SetNormal( hitnormal )
|
||||
effectdata:SetEntity( entity )
|
||||
effectdata:SetAttachment( physbone )
|
||||
util.Effect( "selection_indicator", effectdata )
|
||||
|
||||
|
||||
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin( hitpos )
|
||||
effectdata:SetStart( self.Owner:GetShootPos() )
|
||||
effectdata:SetAttachment( 1 )
|
||||
effectdata:SetEntity( self )
|
||||
util.Effect( "ToolTracer", effectdata )
|
||||
|
||||
--]]
|
||||
|
||||
end
|
||||
|
||||
if (SERVER) then
|
||||
ix.log.AddType("toolgunFired", function(client, name)
|
||||
return string.format("%s has fired a toolgun with the name: %s", client:GetName(), name)
|
||||
end)
|
||||
end
|
||||
|
||||
-- Trace a line then send the result to a mode function
|
||||
function SWEP:PrimaryAttack()
|
||||
|
||||
local mode = self:GetMode()
|
||||
local tr = util.GetPlayerTrace( self.Owner )
|
||||
tr.mask = bit.bor( CONTENTS_SOLID, CONTENTS_MOVEABLE, CONTENTS_MONSTER, CONTENTS_WINDOW, CONTENTS_DEBRIS, CONTENTS_GRATE, CONTENTS_AUX )
|
||||
local trace = util.TraceLine( tr )
|
||||
if ( !trace.Hit ) then return end
|
||||
|
||||
local tool = self:GetToolObject()
|
||||
if ( !tool ) then return end
|
||||
|
||||
tool:CheckObjects()
|
||||
|
||||
-- Does the server setting say it's ok?
|
||||
if ( !tool:Allowed() ) then return end
|
||||
|
||||
-- Ask the gamemode if it's ok to do this
|
||||
if ( !gamemode.Call( "CanTool", self.Owner, trace, mode ) ) then return end
|
||||
if (SERVER) then
|
||||
ix.log.Add(self:GetOwner(), "toolgunFired", self:GetMode())
|
||||
end
|
||||
|
||||
if ( !tool:LeftClick( trace ) ) then return end
|
||||
|
||||
self:DoShootEffect( trace.HitPos, trace.HitNormal, trace.Entity, trace.PhysicsBone, IsFirstTimePredicted() )
|
||||
end
|
||||
|
||||
function SWEP:SecondaryAttack()
|
||||
|
||||
local mode = self:GetMode()
|
||||
local tr = util.GetPlayerTrace( self.Owner )
|
||||
tr.mask = bit.bor( CONTENTS_SOLID, CONTENTS_MOVEABLE, CONTENTS_MONSTER, CONTENTS_WINDOW, CONTENTS_DEBRIS, CONTENTS_GRATE, CONTENTS_AUX )
|
||||
local trace = util.TraceLine( tr )
|
||||
if ( !trace.Hit ) then return end
|
||||
|
||||
local tool = self:GetToolObject()
|
||||
if ( !tool ) then return end
|
||||
|
||||
tool:CheckObjects()
|
||||
|
||||
-- Ask the gamemode if it's ok to do this
|
||||
if ( !tool:Allowed() ) then return end
|
||||
if ( !gamemode.Call( "CanTool", self.Owner, trace, mode ) ) then return end
|
||||
|
||||
if ( !tool:RightClick( trace ) ) then return end
|
||||
|
||||
self:DoShootEffect( trace.HitPos, trace.HitNormal, trace.Entity, trace.PhysicsBone, IsFirstTimePredicted() )
|
||||
|
||||
end
|
||||
|
||||
function SWEP:Holster()
|
||||
|
||||
-- Just do what the SWEP wants to do if there's no tool
|
||||
if ( !self:GetToolObject() ) then return self.CanHolster end
|
||||
|
||||
local CanHolster = self:GetToolObject():Holster()
|
||||
if ( CanHolster ~= nil ) then return CanHolster end
|
||||
|
||||
return self.CanHolster
|
||||
|
||||
end
|
||||
|
||||
-- Delete ghosts here in case the weapon gets deleted all of a sudden somehow
|
||||
function SWEP:OnRemove()
|
||||
|
||||
if ( !self:GetToolObject() ) then return end
|
||||
|
||||
self:GetToolObject():ReleaseGhostEntity()
|
||||
|
||||
end
|
||||
|
||||
|
||||
-- This will remove any ghosts when a player dies and drops the weapon
|
||||
function SWEP:OwnerChanged()
|
||||
|
||||
if ( !self:GetToolObject() ) then return end
|
||||
|
||||
self:GetToolObject():ReleaseGhostEntity()
|
||||
|
||||
end
|
||||
|
||||
-- Deploy
|
||||
function SWEP:Deploy()
|
||||
|
||||
-- Just do what the SWEP wants to do if there is no tool
|
||||
if ( !self:GetToolObject() ) then return self.CanDeploy end
|
||||
|
||||
self:GetToolObject():UpdateData()
|
||||
|
||||
local CanDeploy = self:GetToolObject():Deploy()
|
||||
if ( CanDeploy ~= nil ) then return CanDeploy end
|
||||
|
||||
return self.CanDeploy
|
||||
|
||||
end
|
||||
|
||||
function SWEP:GetToolObject( tool )
|
||||
|
||||
local mode = tool or self:GetMode()
|
||||
|
||||
if ( !self.Tool[ mode ] ) then return false end
|
||||
|
||||
return self.Tool[ mode ]
|
||||
|
||||
end
|
||||
|
||||
function SWEP:FireAnimationEvent( pos, ang, event, options )
|
||||
|
||||
-- Disables animation based muzzle event
|
||||
if ( event == 21 ) then return true end
|
||||
-- Disable thirdperson muzzle flash
|
||||
if ( event == 5003 ) then return true end
|
||||
|
||||
end
|
||||
|
||||
include( "stool.lua" )
|
||||
162
gamemodes/ixhl2rp/entities/weapons/gmod_tool/stools/paint.lua
Normal file
162
gamemodes/ixhl2rp/entities/weapons/gmod_tool/stools/paint.lua
Normal file
@@ -0,0 +1,162 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
TOOL.Category = "Render"
|
||||
TOOL.Name = "#tool.paint.name"
|
||||
|
||||
TOOL.LeftClickAutomatic = true
|
||||
TOOL.RightClickAutomatic = true
|
||||
TOOL.RequiresTraceHit = true
|
||||
|
||||
TOOL.ClientConVar[ "decal" ] = "Blood"
|
||||
|
||||
TOOL.Information = {
|
||||
{ name = "left" },
|
||||
{ name = "right" },
|
||||
{ name = "reload" }
|
||||
}
|
||||
|
||||
local function PlaceDecal( ply, ent, data )
|
||||
|
||||
if ( !IsValid( ent ) && !ent:IsWorld() ) then return end
|
||||
|
||||
local bone = ent:GetPhysicsObjectNum( data.bone or 0 )
|
||||
if ( !IsValid( bone ) ) then bone = ent end
|
||||
|
||||
if ( SERVER ) then
|
||||
util.Decal( data.decal, bone:LocalToWorld( data.Pos1 ), bone:LocalToWorld( data.Pos2 ), ply )
|
||||
|
||||
local i = ent.DecalCount or 0
|
||||
i = i + 1
|
||||
duplicator.StoreEntityModifier( ent, "decal" .. i, data )
|
||||
ent.DecalCount = i
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Register decal duplicator
|
||||
--
|
||||
for i = 1, 32 do
|
||||
|
||||
duplicator.RegisterEntityModifier( "decal" .. i, function( ply, ent, data )
|
||||
timer.Simple( i * 0.05, function() PlaceDecal( ply, ent, data ) end )
|
||||
end )
|
||||
|
||||
end
|
||||
|
||||
function TOOL:Reload( trace )
|
||||
if ( !IsValid( trace.Entity ) ) then return false end
|
||||
|
||||
trace.Entity:RemoveAllDecals()
|
||||
|
||||
if ( SERVER ) then
|
||||
for i = 1, 32 do
|
||||
duplicator.ClearEntityModifier( trace.Entity, "decal" .. i )
|
||||
end
|
||||
trace.Entity.DecalCount = nil
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function TOOL:LeftClick( trace )
|
||||
|
||||
return self:RightClick( trace, true )
|
||||
|
||||
end
|
||||
|
||||
function TOOL:RightClick( trace, bNoDelay )
|
||||
|
||||
local decal = self:GetClientInfo( "decal" )
|
||||
|
||||
local Pos1 = trace.HitPos + trace.HitNormal
|
||||
local Pos2 = trace.HitPos - trace.HitNormal
|
||||
|
||||
local Bone = trace.Entity:GetPhysicsObjectNum( trace.PhysicsBone or 0 )
|
||||
if ( !IsValid( Bone ) ) then Bone = trace.Entity end
|
||||
|
||||
Pos1 = Bone:WorldToLocal( Pos1 )
|
||||
Pos2 = Bone:WorldToLocal( Pos2 )
|
||||
|
||||
PlaceDecal( self:GetOwner(), trace.Entity, { Pos1 = Pos1, Pos2 = Pos2, bone = trace.PhysicsBone, decal = decal } )
|
||||
|
||||
if ( bNoDelay ) then
|
||||
self:GetWeapon():SetNextPrimaryFire( CurTime() + 0.05 )
|
||||
self:GetWeapon():SetNextSecondaryFire( CurTime() + 0.05 )
|
||||
else
|
||||
self:GetWeapon():SetNextPrimaryFire( CurTime() + 0.2 )
|
||||
self:GetWeapon():SetNextSecondaryFire( CurTime() + 0.2 )
|
||||
end
|
||||
|
||||
return false
|
||||
|
||||
end
|
||||
|
||||
game.AddDecal( "Eye", "decals/eye" )
|
||||
game.AddDecal( "Dark", "decals/dark" )
|
||||
game.AddDecal( "Smile", "decals/smile" )
|
||||
game.AddDecal( "Light", "decals/light" )
|
||||
game.AddDecal( "Cross", "decals/cross" )
|
||||
game.AddDecal( "Nought", "decals/nought" )
|
||||
game.AddDecal( "Noughtsncrosses", "decals/noughtsncrosses" )
|
||||
|
||||
list.Add( "PaintMaterials", "Eye" )
|
||||
list.Add( "PaintMaterials", "Smile" )
|
||||
list.Add( "PaintMaterials", "Light" )
|
||||
list.Add( "PaintMaterials", "Dark" )
|
||||
list.Add( "PaintMaterials", "Blood" )
|
||||
list.Add( "PaintMaterials", "YellowBlood" )
|
||||
list.Add( "PaintMaterials", "Impact.Metal" )
|
||||
list.Add( "PaintMaterials", "Scorch" )
|
||||
list.Add( "PaintMaterials", "BeerSplash" )
|
||||
list.Add( "PaintMaterials", "ExplosiveGunshot" )
|
||||
list.Add( "PaintMaterials", "BirdPoop" )
|
||||
list.Add( "PaintMaterials", "PaintSplatPink" )
|
||||
list.Add( "PaintMaterials", "PaintSplatGreen" )
|
||||
list.Add( "PaintMaterials", "PaintSplatBlue" )
|
||||
list.Add( "PaintMaterials", "ManhackCut" )
|
||||
list.Add( "PaintMaterials", "FadingScorch" )
|
||||
list.Add( "PaintMaterials", "Antlion.Splat" )
|
||||
list.Add( "PaintMaterials", "Splash.Large" )
|
||||
list.Add( "PaintMaterials", "BulletProof" )
|
||||
list.Add( "PaintMaterials", "GlassBreak" )
|
||||
list.Add( "PaintMaterials", "Impact.Sand" )
|
||||
list.Add( "PaintMaterials", "Impact.BloodyFlesh" )
|
||||
list.Add( "PaintMaterials", "Impact.Antlion" )
|
||||
list.Add( "PaintMaterials", "Impact.Glass" )
|
||||
list.Add( "PaintMaterials", "Impact.Wood" )
|
||||
list.Add( "PaintMaterials", "Impact.Concrete" )
|
||||
list.Add( "PaintMaterials", "Noughtsncrosses" )
|
||||
list.Add( "PaintMaterials", "Nought" )
|
||||
list.Add( "PaintMaterials", "Cross" )
|
||||
|
||||
function TOOL.BuildCPanel( CPanel )
|
||||
|
||||
-- Remove duplicates.
|
||||
local Options = {}
|
||||
for id, str in pairs( list.Get( "PaintMaterials" ) ) do
|
||||
if ( !table.HasValue( Options, str ) ) then
|
||||
table.insert( Options, str )
|
||||
end
|
||||
end
|
||||
|
||||
table.sort( Options )
|
||||
|
||||
local listbox = CPanel:AddControl( "ListBox", { Label = "#tool.paint.texture", Height = 17 + table.Count( Options ) * 17 } )
|
||||
for k, decal in pairs( Options ) do
|
||||
local line = listbox:AddLine( decal )
|
||||
line.data = { paint_decal = decal }
|
||||
|
||||
if ( GetConVarString( "paint_decal" ) == tostring( decal ) ) then line:SetSelected( true ) end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,105 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
TOOL.Category = "HL2RP Staff QoL"
|
||||
TOOL.Name = "NPC Spawner Editor"
|
||||
TOOL.RequiresTraceHit = true
|
||||
|
||||
TOOL.Information = {
|
||||
{ name = "left" },
|
||||
{ name = "right" },
|
||||
{ name = "reload" }
|
||||
}
|
||||
function TOOL:GetPlayerBoundsTrace()
|
||||
local client = self:GetOwner()
|
||||
|
||||
return util.TraceLine({
|
||||
start = client:GetShootPos(),
|
||||
endpos = client:GetShootPos() + client:GetForward() * 96,
|
||||
filter = client
|
||||
})
|
||||
end
|
||||
function TOOL:LeftClick( trace )
|
||||
|
||||
|
||||
if (SERVER) then
|
||||
if !CAMI.PlayerHasAccess(client, "Helix - Basic Admin Commands") then return false end
|
||||
|
||||
local entity = trace.Entity
|
||||
if !entity or entity and !IsValid(entity) then return end
|
||||
if !self.GetOwner then return end
|
||||
if !self:GetOwner() then return end
|
||||
if !IsValid(self:GetOwner()) then return end
|
||||
if entity:GetClass() != "ix_npcspawner" then return end
|
||||
entity:Use(self:GetOwner())
|
||||
end
|
||||
end
|
||||
function TOOL:RightClick( trace )
|
||||
local entity = trace.Entity
|
||||
local client = self:GetOwner()
|
||||
if !entity or entity and !IsValid(entity) then
|
||||
client.npcEditStart = nil
|
||||
client.npcEnt = nil
|
||||
return
|
||||
end
|
||||
if !self.GetOwner then return end
|
||||
if !self:GetOwner() then return end
|
||||
if !IsValid(self:GetOwner()) then return end
|
||||
if entity:GetClass() != "ix_npcspawner" then return end
|
||||
if client.npcEditStart then
|
||||
client.npcEditStart = nil
|
||||
client.npcEnt = nil
|
||||
else
|
||||
client.npcEditStart = entity:GetPos() + (entity:GetForward() * -60 + entity:GetRight()*-40 + entity:GetUp()*128)
|
||||
client.npcEnt = entity
|
||||
end
|
||||
end
|
||||
function TOOL:Reload(trace)
|
||||
local client = self:GetOwner()
|
||||
if !CAMI.PlayerHasAccess(client, "Helix - Basic Admin Commands") then return false end
|
||||
if !self.GetOwner then return end
|
||||
if !self:GetOwner() then return end
|
||||
if !IsValid(self:GetOwner()) then return end
|
||||
if !client.npcEditStart or !client.npcEnt then return end
|
||||
local tr = util.TraceLine({
|
||||
start = client:GetShootPos(),
|
||||
endpos = client:GetShootPos() + client:GetForward() * 96,
|
||||
filter = client
|
||||
})
|
||||
client.npcEnt:SetSpawnPosStart(client.npcEditStart)
|
||||
client.npcEnt:SetSpawnPosEnd(tr.HitPos)
|
||||
|
||||
client.npcEditStart = nil
|
||||
client.npcEnt = nil
|
||||
end
|
||||
if CLIENT then
|
||||
hook.Add("PostDrawTranslucentRenderables", "NPCSpawnEdit", function(bDepth, bSkybox)
|
||||
if ( bSkybox ) then return end
|
||||
if LocalPlayer().npcEditStart then
|
||||
local tr = util.TraceLine({
|
||||
start = LocalPlayer():GetShootPos(),
|
||||
endpos = LocalPlayer():GetShootPos() + LocalPlayer():GetForward() * 96,
|
||||
filter = LocalPlayer()
|
||||
})
|
||||
local center, min, max = LocalPlayer().npcEnt:SpawnAreaPosition(LocalPlayer().npcEditStart, tr.HitPos)
|
||||
local color = Color(255, 255, 255, 255)
|
||||
|
||||
render.DrawWireframeBox(center, angle_zero, min, max, color)
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
language.Add( "Tool.sh_npcspawnedit.name", "NPC Spawner Configurator" )
|
||||
language.Add( "Tool.sh_npcspawnedit.desc", "You can edit NPC spawner entities with it." )
|
||||
language.Add( "Tool.sh_npcspawnedit.left", "Open spawner menu" )
|
||||
language.Add( "Tool.sh_npcspawnedit.right", "Edit spawner area bounds. Click again to stop changing bounds." )
|
||||
language.Add( "Tool.sh_npcspawnedit.reload", "Save your area bound changes." )
|
||||
end
|
||||
@@ -0,0 +1,74 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
TOOL.Category = "HL2RP Staff QoL"
|
||||
TOOL.Name = "Panel Add"
|
||||
TOOL.RequiresTraceHit = true
|
||||
|
||||
TOOL.ClientConVar[ "url" ] = ""
|
||||
TOOL.ClientConVar[ "scale" ] = 1
|
||||
TOOL.ClientConVar[ "brightness" ] = 100
|
||||
|
||||
TOOL.Information = {
|
||||
{ name = "left" },
|
||||
{ name = "right" },
|
||||
{ name = "reload" }
|
||||
}
|
||||
|
||||
function TOOL:LeftClick( trace )
|
||||
if (SERVER) then
|
||||
if !CAMI.PlayerHasAccess(self:GetOwner(), "Helix - Manage Panels") then return false end
|
||||
|
||||
local position = trace.HitPos
|
||||
local angles = trace.HitNormal:Angle()
|
||||
angles:RotateAroundAxis(angles:Up(), 90)
|
||||
angles:RotateAroundAxis(angles:Forward(), 90)
|
||||
|
||||
if !ix.plugin.list then return end
|
||||
if !ix.plugin.list["3dpanel"] then return end
|
||||
if !ix.plugin.list["3dpanel"].AddPanel then return end
|
||||
|
||||
local url = self:GetClientInfo( "url", "" )
|
||||
local scale = self:GetClientNumber( "scale", 0 )
|
||||
local brightness = self:GetClientNumber( "brightness", 0 )
|
||||
|
||||
ix.plugin.list["3dpanel"]:AddPanel(position + angles:Up() * 0.1, angles, url, scale, brightness)
|
||||
|
||||
return "@panelAdded"
|
||||
end
|
||||
end
|
||||
|
||||
function TOOL:RightClick( trace )
|
||||
if !ix.plugin.list then return end
|
||||
if !ix.plugin.list["3dpanel"] then return end
|
||||
if !ix.plugin.list["3dpanel"].RemovePanel then return end
|
||||
|
||||
local position = trace.HitPos
|
||||
-- Remove the panel(s) and get the amount removed.
|
||||
local amount = ix.plugin.list["3dpanel"]:RemovePanel(position, false)
|
||||
|
||||
return "@panelRemoved", amount
|
||||
end
|
||||
|
||||
function TOOL.BuildCPanel( CPanel )
|
||||
CPanel:AddControl( "Header", { Description = "Enter URL!" } )
|
||||
CPanel:AddControl( "textbox", { Label = "URL", Command = "sh_paneladd_url", Help = false } )
|
||||
CPanel:AddControl( "Slider", { Label = "Scale", Command = "sh_paneladd_scale", Type = "Float", Min = 0.001, Max = 5, Help = false } )
|
||||
CPanel:AddControl( "Slider", { Label = "Brightness", Command = "sh_paneladd_brightness", Type = "Float", Min = 0, Max = 255, Help = false } )
|
||||
end
|
||||
|
||||
if CLIENT then
|
||||
language.Add( "Tool.sh_paneladd.name", "Panel Add" )
|
||||
language.Add( "Tool.sh_paneladd.desc", "Same as /paneladd" )
|
||||
language.Add( "Tool.sh_paneladd.left", "Primary: Add Panel" )
|
||||
language.Add( "Tool.sh_paneladd.right", "Right Click: Remove Panel" )
|
||||
language.Add( "Tool.sh_paneladd.reload", "Nothing." )
|
||||
end
|
||||
@@ -0,0 +1,84 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
TOOL.Category = "HL2RP Staff QoL"
|
||||
TOOL.Name = "Persist"
|
||||
TOOL.RequiresTraceHit = true
|
||||
|
||||
TOOL.Information = {
|
||||
{ name = "left" },
|
||||
{ name = "right" },
|
||||
{ name = "reload" }
|
||||
}
|
||||
|
||||
local function GetRealModel(entity)
|
||||
return entity:GetClass() == "prop_effect" and entity.AttachedEntity:GetModel() or entity:GetModel()
|
||||
end
|
||||
|
||||
function TOOL:LeftClick( trace )
|
||||
if (SERVER) then
|
||||
if !CAMI.PlayerHasAccess(client, "Helix - Basic Admin Commands") then return false end
|
||||
|
||||
local entity = trace.Entity
|
||||
if !entity or entity and !IsValid(entity) then return end
|
||||
if entity:IsPlayer() or entity:IsVehicle() or entity.bNoPersist then return end
|
||||
if !self.GetOwner then return end
|
||||
if !self:GetOwner() then return end
|
||||
if !IsValid(self:GetOwner()) then return end
|
||||
if !ix.plugin.list then return end
|
||||
if !ix.plugin.list["persistence"] then return end
|
||||
if !ix.plugin.list["persistence"].stored then return end
|
||||
|
||||
local lampCount = 0
|
||||
|
||||
for _, v in pairs(ix.plugin.list["persistence"].stored) do
|
||||
if IsValid(v) and v:GetClass() == "gmod_lamp" then
|
||||
lampCount = lampCount + 1
|
||||
end
|
||||
end
|
||||
|
||||
if !entity:GetNetVar("Persistent") then
|
||||
if entity:GetClass() == "gmod_lamp" and lampCount >= ix.config.Get("maxLamps", 1) then
|
||||
return self:GetOwner():Notify("Max persisted lamps reached.")
|
||||
end
|
||||
|
||||
ix.plugin.list["persistence"].stored[#ix.plugin.list["persistence"].stored + 1] = entity
|
||||
|
||||
entity:SetNetVar("Persistent", true)
|
||||
ix.saveEnts:SaveEntity(entity)
|
||||
|
||||
ix.log.Add(self:GetOwner(), "persist", GetRealModel(entity), true)
|
||||
self:GetOwner():Notify("You persisted this entity.")
|
||||
else
|
||||
for k, v in ipairs(ix.plugin.list["persistence"].stored) do
|
||||
if (v == entity) then
|
||||
table.remove(ix.plugin.list["persistence"].stored, k)
|
||||
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
entity:SetNetVar("Persistent", false)
|
||||
ix.saveEnts:DeleteEntity(entity)
|
||||
|
||||
ix.log.Add(self:GetOwner(), "persist", GetRealModel(entity), false)
|
||||
self:GetOwner():Notify("You unpersisted this entity.")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if CLIENT then
|
||||
language.Add( "Tool.sh_persist.name", "Persist" )
|
||||
language.Add( "Tool.sh_persist.desc", "Same as persist in context menu" )
|
||||
language.Add( "Tool.sh_persist.left", "Primary: Persist/Unpersist" )
|
||||
language.Add( "Tool.sh_persist.right", "Nothing." )
|
||||
language.Add( "Tool.sh_persist.reload", "Nothing." )
|
||||
end
|
||||
@@ -0,0 +1,79 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
TOOL.Category = "HL2RP Staff QoL"
|
||||
TOOL.Name = "Text Add"
|
||||
TOOL.RequiresTraceHit = true
|
||||
|
||||
TOOL.ClientConVar[ "text" ] = ""
|
||||
TOOL.ClientConVar[ "scale" ] = 1
|
||||
|
||||
TOOL.Information = {
|
||||
{ name = "left" },
|
||||
{ name = "right" },
|
||||
{ name = "reload" }
|
||||
}
|
||||
|
||||
function TOOL:LeftClick( trace )
|
||||
if (SERVER) then
|
||||
if !CAMI.PlayerHasAccess(self:GetOwner(), "Helix - Basic Admin Commands") then return false end
|
||||
|
||||
local position = trace.HitPos
|
||||
local angles = trace.HitNormal:Angle()
|
||||
angles:RotateAroundAxis(angles:Up(), 90)
|
||||
angles:RotateAroundAxis(angles:Forward(), 90)
|
||||
|
||||
if !ix.plugin.list then return end
|
||||
if !ix.plugin.list["3dtext"] then return end
|
||||
if !ix.plugin.list["3dtext"].AddText then return end
|
||||
|
||||
local text = self:GetClientInfo( "text", "" )
|
||||
local scale = self:GetClientNumber( "scale", 0 )
|
||||
|
||||
local index = ix.plugin.list["3dtext"]:AddText(position + angles:Up() * 0.1, angles, text, scale)
|
||||
|
||||
undo.Create("ix3dText")
|
||||
undo.SetPlayer(self:GetOwner())
|
||||
undo.AddFunction(function()
|
||||
if (ix.plugin.list["3dtext"]:RemoveTextByID(index)) then
|
||||
ix.log.Add(self:GetOwner(), "undo3dText")
|
||||
end
|
||||
end)
|
||||
undo.Finish()
|
||||
|
||||
return "@textAdded"
|
||||
end
|
||||
end
|
||||
|
||||
function TOOL:RightClick( trace )
|
||||
if !ix.plugin.list then return end
|
||||
if !ix.plugin.list["3dtext"] then return end
|
||||
if !ix.plugin.list["3dtext"].RemoveText then return end
|
||||
|
||||
local position = trace.HitPos + trace.HitNormal * 2
|
||||
local amount = ix.plugin.list["3dtext"]:RemoveText(position, false)
|
||||
|
||||
return "@textRemoved", amount
|
||||
end
|
||||
|
||||
function TOOL.BuildCPanel( CPanel )
|
||||
CPanel:AddControl( "Header", { Description = "Enter Text!" } )
|
||||
CPanel:AddControl( "textbox", { Label = "Text", Command = "sh_textadd_text", Help = false } )
|
||||
CPanel:AddControl( "Slider", { Label = "Scale", Command = "sh_textadd_scale", Type = "Float", Min = 0.001, Max = 5, Help = false } )
|
||||
end
|
||||
|
||||
if CLIENT then
|
||||
language.Add( "Tool.sh_textadd.name", "Text Add" )
|
||||
language.Add( "Tool.sh_textadd.desc", "Same as /textadd" )
|
||||
language.Add( "Tool.sh_textadd.left", "Primary: Add Text" )
|
||||
language.Add( "Tool.sh_textadd.right", "Right Click: Remove Text." )
|
||||
language.Add( "Tool.sh_textadd.reload", "Nothing." )
|
||||
end
|
||||
492
gamemodes/ixhl2rp/entities/weapons/ix_stunstick.lua
Normal file
492
gamemodes/ixhl2rp/entities/weapons/ix_stunstick.lua
Normal file
@@ -0,0 +1,492 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
if (CLIENT) then
|
||||
SWEP.PrintName = "CV-2000 Stun Baton"
|
||||
SWEP.Slot = 0
|
||||
SWEP.SlotPos = 5
|
||||
SWEP.DrawAmmo = false
|
||||
SWEP.DrawCrosshair = false
|
||||
end
|
||||
|
||||
SWEP.Category = "HL2 RP"
|
||||
SWEP.Author = "Chessnut"
|
||||
SWEP.Instructions = "Primary Fire: Stun.\nALT + Primary Fire: Toggle stun.\nSecondary Fire: Push/Knock."
|
||||
SWEP.Purpose = "Hitting things and knocking on doors."
|
||||
SWEP.Drop = false
|
||||
|
||||
SWEP.HoldType = "melee"
|
||||
|
||||
SWEP.Spawnable = true
|
||||
SWEP.AdminOnly = true
|
||||
|
||||
SWEP.ViewModelFOV = 47
|
||||
SWEP.ViewModelFlip = false
|
||||
SWEP.AnimPrefix = "melee"
|
||||
|
||||
SWEP.ViewTranslation = 4
|
||||
|
||||
SWEP.Primary.ClipSize = -1
|
||||
SWEP.Primary.DefaultClip = -1
|
||||
SWEP.Primary.Automatic = false
|
||||
SWEP.Primary.Ammo = ""
|
||||
SWEP.Primary.Damage = 15
|
||||
SWEP.Primary.Delay = 0.7
|
||||
|
||||
SWEP.Secondary.ClipSize = -1
|
||||
SWEP.Secondary.DefaultClip = 0
|
||||
SWEP.Secondary.Automatic = false
|
||||
SWEP.Secondary.Ammo = ""
|
||||
|
||||
SWEP.ViewModel = Model("models/weapons/c_wn_stunstick.mdl")
|
||||
SWEP.WorldModel = Model("models/weapons/w_wn_stunbaton.mdl")
|
||||
|
||||
SWEP.UseHands = true
|
||||
SWEP.LowerAngles = Angle(15, -10, -20)
|
||||
|
||||
SWEP.FireWhenLowered = true
|
||||
|
||||
function SWEP:SetupDataTables()
|
||||
self:NetworkVar("Bool", 0, "Activated")
|
||||
self:NetworkVarNotify( "Activated", self.OnActiveToggle )
|
||||
end
|
||||
|
||||
function SWEP:Precache()
|
||||
util.PrecacheSound("physics/wood/wood_crate_impact_hard3.wav")
|
||||
end
|
||||
|
||||
function SWEP:StartStunstickSound()
|
||||
if (SERVER) then
|
||||
local client = self:GetOwner()
|
||||
|
||||
self.patch1 = CreateSound(client, "wn_stunstick/stunstick_idle_"..math.random(1, 6)..".wav")
|
||||
self.patch1:SetSoundLevel(40)
|
||||
self.patch1:SetDSP(7)
|
||||
self.patch1:Play()
|
||||
|
||||
self:SoundTimer()
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:StopStunstickSound()
|
||||
if (SERVER) then
|
||||
local patchToStop
|
||||
if (self.patch1 and self.patch1:IsPlaying()) then
|
||||
patchToStop = self.patch1
|
||||
else
|
||||
patchToStop = self.patch2
|
||||
end
|
||||
|
||||
if (!patchToStop) then return end
|
||||
|
||||
patchToStop:FadeOut(1)
|
||||
end
|
||||
end
|
||||
|
||||
-- for when someone primary fires or w/e
|
||||
function SWEP:DuckStunstickSound(vol, delta)
|
||||
if (SERVER) then
|
||||
if (!delta) then
|
||||
delta = 0.5
|
||||
end
|
||||
|
||||
if (!vol) then
|
||||
vol = 0.25
|
||||
end
|
||||
|
||||
local patchToDuck = self.patch1 and self.patch1:IsPlaying() and self.patch1 or self.patch2
|
||||
if (!patchToDuck) then return end
|
||||
|
||||
patchToDuck:ChangeVolume(vol, delta)
|
||||
timer.Simple(delta + 0.1, function()
|
||||
patchToDuck:ChangeVolume(1, delta)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
function SWEP:OnActiveToggle(name, old, new)
|
||||
if (new) then
|
||||
self:StartStunstickSound()
|
||||
else
|
||||
self:StopStunstickSound()
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:SoundTimer()
|
||||
if (SERVER) then
|
||||
local client = self:GetOwner()
|
||||
|
||||
local tName = "stunstick_idle_"..client:SteamID64().."_timer"
|
||||
|
||||
if timer.Exists(tName) then timer.Remove(tName) end
|
||||
|
||||
timer.Create(tName, 7, 0, function()
|
||||
if (!IsValid(client)) then
|
||||
timer.Remove(tName)
|
||||
return
|
||||
end
|
||||
|
||||
if (!IsValid(self) or !self:GetActivated()) then
|
||||
return
|
||||
end
|
||||
|
||||
local patchToStart
|
||||
local patchToStop
|
||||
if (self.patch1 and self.patch1:IsPlaying()) then
|
||||
patchToStart = self.patch2
|
||||
patchToStop = self.patch1
|
||||
else
|
||||
patchToStart = self.patch1
|
||||
patchToStop = self.patch2
|
||||
end
|
||||
|
||||
if (!patchToStop) then
|
||||
timer.Remove(tName)
|
||||
return
|
||||
end
|
||||
|
||||
patchToStop:FadeOut(1)
|
||||
|
||||
patchToStart = CreateSound(client, "wn_stunstick/stunstick_idle_"..math.random(1, 6)..".wav")
|
||||
patchToStart:SetSoundLevel(40) -- maybe make this configurable idk
|
||||
patchToStart:SetDSP(7)
|
||||
patchToStart:Play()
|
||||
patchToStart:ChangeVolume( 0.1, 0 )
|
||||
patchToStart:ChangeVolume(1, 1)
|
||||
|
||||
if (self.patch1 and self.patch1:IsPlaying()) then
|
||||
self.patch2 = patchToStart
|
||||
else
|
||||
self.patch1 = patchToStart
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:CreateWMParticle()
|
||||
if self.particle and self.particle:IsValid() then
|
||||
self.particle:StopEmissionAndDestroyImmediately()
|
||||
end
|
||||
|
||||
self.particle = CreateParticleSystem(self, "wn_stunstick_fx", PATTACH_POINT_FOLLOW, 1, Vector(0, 0, 0))
|
||||
end
|
||||
|
||||
function SWEP:Initialize()
|
||||
self:SetHoldType(self.HoldType)
|
||||
end
|
||||
|
||||
function SWEP:OnRaised()
|
||||
self.lastRaiseTime = CurTime()
|
||||
end
|
||||
|
||||
function SWEP:OnLowered()
|
||||
self:SetActivated(false)
|
||||
|
||||
if (CLIENT) then
|
||||
if (self.particle and IsValid(self.particle)) then
|
||||
self.particle:StopEmissionAndDestroyImmediately()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:Holster(nextWep)
|
||||
if self.patch1 and self.patch1:IsPlaying() or self.patch2 and self.patch2:IsPlaying() then
|
||||
self:StopStunstickSound()
|
||||
end
|
||||
|
||||
self:OnLowered()
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
local STUNSTICK_GLOW_MATERIAL2 = Material("effects/blueflare1")
|
||||
local STUNSTICK_GLOW_MATERIAL_NOZ = Material("sprites/light_glow02_add_noz")
|
||||
|
||||
function SWEP:DrawWorldModel()
|
||||
self:DrawModel()
|
||||
|
||||
if (!self.particle or self.particle and !self.particle:IsValid()) then
|
||||
if self:GetActivated() then
|
||||
self:CreateWMParticle()
|
||||
end
|
||||
elseif (self.particle and self.particle:IsValid()) then
|
||||
if !self:GetActivated() then
|
||||
self.particle:StopEmissionAndDestroyImmediately()
|
||||
end
|
||||
end
|
||||
|
||||
if (self:GetActivated()) then
|
||||
local size = math.Rand(2.0, 6.0)
|
||||
local glow = math.Rand(0.6, 0.8) * 255
|
||||
local color = Color(glow / 2, glow / 1.5, glow / 1.1)
|
||||
local attachment = self:GetAttachment(1)
|
||||
|
||||
if (attachment) then
|
||||
local position = attachment.Pos
|
||||
|
||||
render.SetMaterial(STUNSTICK_GLOW_MATERIAL2)
|
||||
render.DrawSprite(position, size * 2, size * 2, color)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local NUM_BEAM_ATTACHEMENTS = 9
|
||||
local BEAM_ATTACH_CORE_NAME = "sparkrear"
|
||||
|
||||
SWEP.nextSpark = 0
|
||||
|
||||
function SWEP:PostDrawViewModel()
|
||||
if (!self:GetActivated()) then
|
||||
return
|
||||
end
|
||||
|
||||
local viewModel = LocalPlayer():GetViewModel()
|
||||
|
||||
if (!IsValid(viewModel)) then
|
||||
return
|
||||
end
|
||||
|
||||
cam.Start3D(EyePos(), EyeAngles())
|
||||
local size = math.Rand(3.0, 4.0)
|
||||
local color = Color(75, 100, 150, 50 + math.sin(RealTime() * 2)*20)
|
||||
|
||||
STUNSTICK_GLOW_MATERIAL_NOZ:SetFloat("$alpha", color.a / 255)
|
||||
|
||||
render.SetMaterial(STUNSTICK_GLOW_MATERIAL_NOZ)
|
||||
|
||||
local attachment = viewModel:GetAttachment(1)
|
||||
|
||||
if (attachment) then
|
||||
render.DrawSprite(attachment.Pos, size * 10, size * 15, color)
|
||||
end
|
||||
|
||||
for i = 1, NUM_BEAM_ATTACHEMENTS do
|
||||
attachment = viewModel:GetAttachment(viewModel:LookupAttachment("spark"..i.."a"))
|
||||
size = math.Rand(2.5, 5.0)
|
||||
|
||||
if (attachment and attachment.Pos) then
|
||||
render.DrawSprite(attachment.Pos, size, size, color)
|
||||
end
|
||||
|
||||
attachment = viewModel:GetAttachment(viewModel:LookupAttachment("spark"..i.."b"))
|
||||
size = math.Rand(2.5, 5.0)
|
||||
|
||||
if (attachment and attachment.Pos) then
|
||||
render.DrawSprite(attachment.Pos, size, size, color)
|
||||
end
|
||||
end
|
||||
cam.End3D()
|
||||
|
||||
local sparkAttachment = viewModel:GetAttachment(1)
|
||||
|
||||
if self.nextSpark <= CurTime() then
|
||||
self.nextSpark = CurTime() + math.random(1, 10)
|
||||
|
||||
local ef = EffectData()
|
||||
ef:SetOrigin(sparkAttachment.Pos)
|
||||
ef:SetMagnitude(math.random(1, 2))
|
||||
ef:SetScale(0.1)
|
||||
util.Effect("ElectricSpark", ef)
|
||||
|
||||
self:EmitSound("wn_stunstick/spark".. math.random(1, 4) ..".wav", nil, math.random(80, 120))
|
||||
end
|
||||
|
||||
if (self.particle and self.particle:IsValid() and self:GetActivated()) then
|
||||
self.particle:StopEmissionAndDestroyImmediately()
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:PrimaryAttack()
|
||||
self:SetNextPrimaryFire(CurTime() + self.Primary.Delay)
|
||||
|
||||
if (!self:GetOwner():IsWepRaised()) then
|
||||
return
|
||||
end
|
||||
|
||||
if (self:GetOwner():KeyDown(IN_WALK)) then
|
||||
if (SERVER) then
|
||||
self:SetActivated(!self:GetActivated())
|
||||
|
||||
local state = self:GetActivated()
|
||||
|
||||
if (state) then
|
||||
self:GetOwner():EmitSound("Weapon_StunStick.Activate")
|
||||
else
|
||||
self:GetOwner():EmitSound("Weapon_StunStick.Deactivate")
|
||||
end
|
||||
|
||||
local model = string.lower(self:GetOwner():GetModel())
|
||||
|
||||
if (ix.anim.GetModelClass(model) == "metrocop") then
|
||||
self:GetOwner():ForceSequence(state and "activatebaton" or "deactivatebaton", nil, nil, true)
|
||||
end
|
||||
end
|
||||
|
||||
if (CLIENT) then
|
||||
timer.Simple(0, function()
|
||||
if !(IsValid(self)) then return end
|
||||
if (self:GetActivated()) then
|
||||
self:CreateWMParticle()
|
||||
else
|
||||
if (self.particle and self.particle:IsValid()) then
|
||||
self.particle:StopEmissionAndDestroyImmediately()
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
local result = hook.Run("CanDoMeleeAttack", self)
|
||||
if (result == false) then
|
||||
return
|
||||
end
|
||||
|
||||
if (self:GetActivated()) then
|
||||
self:DuckStunstickSound()
|
||||
end
|
||||
|
||||
self:EmitSound("wn_stunstick/stunstick_swing".. math.random(1, 3) ..".wav")
|
||||
self:SendWeaponAnim(ACT_VM_HITCENTER)
|
||||
|
||||
local damage = self.Primary.Damage
|
||||
|
||||
if (self:GetActivated()) then
|
||||
damage = 10
|
||||
end
|
||||
|
||||
self:GetOwner():SetAnimation(PLAYER_ATTACK1)
|
||||
self:GetOwner():ViewPunch(Angle(1, 0, 0.125))
|
||||
|
||||
timer.Simple(0.1, function()
|
||||
if !IsValid(self) then return end
|
||||
self:GetOwner():LagCompensation(true)
|
||||
local data = {}
|
||||
data.start = self:GetOwner():GetShootPos()
|
||||
data.endpos = data.start + self:GetOwner():GetAimVector()*72
|
||||
data.filter = self:GetOwner()
|
||||
local trace = util.TraceLine(data)
|
||||
self:GetOwner():LagCompensation(false)
|
||||
|
||||
if (SERVER and trace.Hit) then
|
||||
if (self:GetActivated()) then
|
||||
local effect = EffectData()
|
||||
effect:SetStart(trace.HitPos)
|
||||
effect:SetNormal(trace.HitNormal)
|
||||
effect:SetOrigin(trace.HitPos)
|
||||
util.Effect("StunstickImpact", effect, true, true)
|
||||
end
|
||||
|
||||
self:GetOwner():EmitSound("wn_stunstick/stunstick_fleshhit".. math.random(1, 3) ..".wav")
|
||||
|
||||
local entity = trace.Entity
|
||||
|
||||
if (IsValid(entity)) then
|
||||
if (entity:IsPlayer()) then
|
||||
if (self:GetActivated()) then
|
||||
entity.ixStuns = (entity.ixStuns or 0) + 1
|
||||
|
||||
timer.Simple(10, function()
|
||||
if (!entity.ixStuns) then return end
|
||||
entity.ixStuns = math.max(entity.ixStuns - 1, 0)
|
||||
end)
|
||||
end
|
||||
|
||||
entity:ViewPunch(Angle(-20, math.random(-15, 15), math.random(-10, 10)))
|
||||
|
||||
if (self:GetActivated() and entity.ixStuns > 2) then
|
||||
entity:SetRagdolled(true, 60)
|
||||
ix.log.Add(entity, "knockedOut", "hit by stunstick owned by "..self:GetOwner():GetName())
|
||||
entity.ixStuns = 0
|
||||
|
||||
return
|
||||
end
|
||||
elseif (entity:IsRagdoll()) then
|
||||
damage = self:GetActivated() and 2 or 10
|
||||
end
|
||||
|
||||
local damageInfo = DamageInfo()
|
||||
damageInfo:SetAttacker(self:GetOwner())
|
||||
damageInfo:SetInflictor(self)
|
||||
damageInfo:SetDamage(damage)
|
||||
damageInfo:SetDamageType(DMG_CLUB)
|
||||
damageInfo:SetDamagePosition(trace.HitPos)
|
||||
damageInfo:SetDamageForce(self:GetOwner():GetAimVector() * 10000)
|
||||
entity:DispatchTraceAttack(damageInfo, data.start, data.endpos)
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function SWEP:SecondaryAttack()
|
||||
self:GetOwner():LagCompensation(true)
|
||||
local data = {}
|
||||
data.start = self:GetOwner():GetShootPos()
|
||||
data.endpos = data.start + self:GetOwner():GetAimVector()*72
|
||||
data.filter = self:GetOwner()
|
||||
data.mins = Vector(-8, -8, -30)
|
||||
data.maxs = Vector(8, 8, 10)
|
||||
local trace = util.TraceHull(data)
|
||||
local entity = trace.Entity
|
||||
self:GetOwner():LagCompensation(false)
|
||||
|
||||
if (SERVER and IsValid(entity)) then
|
||||
local bPushed = false
|
||||
|
||||
if (entity:IsDoor()) then
|
||||
if (hook.Run("PlayerCanKnockOnDoor", self:GetOwner(), entity) == false) then
|
||||
return
|
||||
end
|
||||
|
||||
self:GetOwner():ViewPunch(Angle(-1.3, 1.8, 0))
|
||||
self:GetOwner():EmitSound("physics/wood/wood_crate_impact_hard3.wav")
|
||||
self:GetOwner():SetAnimation(PLAYER_ATTACK1)
|
||||
|
||||
self:SetNextSecondaryFire(CurTime() + 0.4)
|
||||
self:SetNextPrimaryFire(CurTime() + 1)
|
||||
elseif (entity:IsPlayer()) then
|
||||
local direction = self:GetOwner():GetAimVector() * (300 + (self:GetOwner():GetCharacter():GetAttribute("str", 0) * 3))
|
||||
direction.z = 0
|
||||
entity:SetVelocity(direction)
|
||||
|
||||
hook.Run("PlayerPushedPlayer", self:GetOwner(), entity)
|
||||
|
||||
bPushed = true
|
||||
else
|
||||
local physObj = entity:GetPhysicsObject()
|
||||
|
||||
if (IsValid(physObj)) then
|
||||
physObj:SetVelocity(self:GetOwner():GetAimVector() * 180)
|
||||
end
|
||||
|
||||
bPushed = true
|
||||
end
|
||||
|
||||
if (bPushed) then
|
||||
self:SetNextSecondaryFire(CurTime() + 1.5)
|
||||
self:SetNextPrimaryFire(CurTime() + 1.5)
|
||||
self:GetOwner():EmitSound("Weapon_Crossbow.BoltHitBody")
|
||||
|
||||
local model = string.lower(self:GetOwner():GetModel())
|
||||
|
||||
if (ix.anim.GetModelClass(model) == "metrocop") then
|
||||
self:GetOwner():ForceSequence("pushplayer")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user