Залив
This commit is contained in:
7
gamemodes/cod_custom/cod_custom.txt
Normal file
7
gamemodes/cod_custom/cod_custom.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
"Call Of Duty"
|
||||
{
|
||||
"base" "base"
|
||||
"title" "Call Of Duty"
|
||||
"category" "pvp"
|
||||
"menusystem" "1"
|
||||
}
|
||||
39
gamemodes/cod_custom/entities/effects/base.lua
Normal file
39
gamemodes/cod_custom/entities/effects/base.lua
Normal file
@@ -0,0 +1,39 @@
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Returns the right shoot start position for a tracer - based on 'data'.
|
||||
-----------------------------------------------------------]]
|
||||
function EFFECT:GetTracerShootPos( Position, Ent, Attachment )
|
||||
|
||||
self.ViewModelTracer = false
|
||||
|
||||
if ( !IsValid( Ent ) ) then return Position end
|
||||
if ( !Ent:IsWeapon() ) then return Position end
|
||||
|
||||
-- Shoot from the viewmodel
|
||||
if ( Ent:IsCarriedByLocalPlayer() && !LocalPlayer():ShouldDrawLocalPlayer() ) then
|
||||
|
||||
local ViewModel = LocalPlayer():GetViewModel()
|
||||
|
||||
if ( ViewModel:IsValid() ) then
|
||||
|
||||
local att = ViewModel:GetAttachment( Attachment )
|
||||
if ( att ) then
|
||||
Position = att.Pos
|
||||
self.ViewModelTracer = true
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- Shoot from the world model
|
||||
else
|
||||
|
||||
local att = Ent:GetAttachment( Attachment )
|
||||
if ( att ) then
|
||||
Position = att.Pos
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return Position
|
||||
|
||||
end
|
||||
55
gamemodes/cod_custom/entities/effects/dof_node.lua
Normal file
55
gamemodes/cod_custom/entities/effects/dof_node.lua
Normal file
@@ -0,0 +1,55 @@
|
||||
|
||||
EFFECT.Mat = Material( "pp/dof" )
|
||||
|
||||
function EFFECT:Init( data )
|
||||
|
||||
table.insert( DOF_Ents, self.Entity )
|
||||
self.Scale = data:GetScale()
|
||||
|
||||
local size = 32
|
||||
self:SetCollisionBounds( Vector( -size, -size, -size ), Vector( size, size, size ) )
|
||||
|
||||
end
|
||||
|
||||
function EFFECT:Think( )
|
||||
|
||||
-- If the spacing or offset has changed we need to reconfigure our positions
|
||||
local ply = LocalPlayer()
|
||||
|
||||
self.spacing = DOF_SPACING * self.Scale
|
||||
self.offset = DOF_OFFSET
|
||||
|
||||
-- Just return if it hasn't
|
||||
--if ( spacing == self.spacing && offset == self.offset ) then return true end
|
||||
|
||||
local pos = ply:EyePos()
|
||||
local fwd = ply:EyeAngles():Forward()
|
||||
|
||||
if ( ply:GetViewEntity() != ply ) then
|
||||
pos = ply:GetViewEntity():GetPos()
|
||||
fwd = ply:GetViewEntity():GetForward()
|
||||
end
|
||||
|
||||
pos = pos + ( fwd * self.spacing ) + ( fwd * self.offset )
|
||||
|
||||
self:SetParent( nil )
|
||||
self:SetPos( pos )
|
||||
self:SetParent( ply )
|
||||
|
||||
-- We don't kill this, the pp effect should
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
|
||||
-- Note: UpdateScreenEffectTexture fucks up the water, RefractTexture is lower quality
|
||||
render.UpdateRefractTexture()
|
||||
//render.UpdateScreenEffectTexture()
|
||||
|
||||
local SpriteSize = ( self.spacing + self.offset ) * 8
|
||||
|
||||
render.SetMaterial( self.Mat )
|
||||
render.DrawSprite( self:GetPos(), SpriteSize, SpriteSize, color_white )
|
||||
|
||||
end
|
||||
58
gamemodes/cod_custom/entities/effects/tooltracer.lua
Normal file
58
gamemodes/cod_custom/entities/effects/tooltracer.lua
Normal file
@@ -0,0 +1,58 @@
|
||||
|
||||
EFFECT.Mat = Material( "effects/tool_tracer" )
|
||||
|
||||
function EFFECT:Init( data )
|
||||
|
||||
self.Position = data:GetStart()
|
||||
self.WeaponEnt = data:GetEntity()
|
||||
self.Attachment = data:GetAttachment()
|
||||
|
||||
-- Keep the start and end pos - we're going to interpolate between them
|
||||
self.StartPos = self:GetTracerShootPos( self.Position, self.WeaponEnt, self.Attachment )
|
||||
self.EndPos = data:GetOrigin()
|
||||
|
||||
self.Alpha = 255
|
||||
self.Life = 0
|
||||
|
||||
self:SetRenderBoundsWS( self.StartPos, self.EndPos )
|
||||
|
||||
end
|
||||
|
||||
function EFFECT:Think()
|
||||
|
||||
self.Life = self.Life + FrameTime() * 4
|
||||
self.Alpha = 255 * ( 1 - self.Life )
|
||||
|
||||
return ( self.Life < 1 )
|
||||
|
||||
end
|
||||
|
||||
function EFFECT:Render()
|
||||
|
||||
if ( self.Alpha < 1 ) then return end
|
||||
|
||||
render.SetMaterial( self.Mat )
|
||||
local texcoord = math.Rand( 0, 1 )
|
||||
|
||||
local norm = (self.StartPos - self.EndPos) * self.Life
|
||||
|
||||
self.Length = norm:Length()
|
||||
|
||||
for i = 1, 3 do
|
||||
|
||||
render.DrawBeam( self.StartPos - norm, -- Start
|
||||
self.EndPos, -- End
|
||||
8, -- Width
|
||||
texcoord, -- Start tex coord
|
||||
texcoord + self.Length / 128, -- End tex coord
|
||||
color_white ) -- Color (optional)
|
||||
end
|
||||
|
||||
render.DrawBeam( self.StartPos,
|
||||
self.EndPos,
|
||||
8,
|
||||
texcoord,
|
||||
texcoord + ( ( self.StartPos - self.EndPos ):Length() / 128 ),
|
||||
Color( 255, 255, 255, 128 * ( 1 - self.Life ) ) )
|
||||
|
||||
end
|
||||
10
gamemodes/cod_custom/entities/entities/aoc_spawnpoint.lua
Normal file
10
gamemodes/cod_custom/entities/entities/aoc_spawnpoint.lua
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
-- This is just a simple point entity.
|
||||
|
||||
-- We only use it to represent the position and angle of a spawn point
|
||||
-- So we don't have to do anything here because the baseclass will
|
||||
-- take care of the basics
|
||||
|
||||
-- This file only exists so that the entity is created
|
||||
|
||||
ENT.Type = "point"
|
||||
25
gamemodes/cod_custom/entities/entities/base_ai/cl_init.lua
Normal file
25
gamemodes/cod_custom/entities/entities/base_ai/cl_init.lua
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
include( "shared.lua" )
|
||||
|
||||
ENT.RenderGroup = RENDERGROUP_OPAQUE
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: Draw
|
||||
Desc: Draw it!
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:Draw()
|
||||
self:DrawModel()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: DrawTranslucent
|
||||
Desc: Draw translucent
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:DrawTranslucent()
|
||||
|
||||
-- This is here just to make it backwards compatible.
|
||||
-- You shouldn't really be drawing your model here unless it's translucent
|
||||
|
||||
self:Draw()
|
||||
|
||||
end
|
||||
131
gamemodes/cod_custom/entities/entities/base_ai/init.lua
Normal file
131
gamemodes/cod_custom/entities/entities/base_ai/init.lua
Normal file
@@ -0,0 +1,131 @@
|
||||
|
||||
AddCSLuaFile( "cl_init.lua" )
|
||||
AddCSLuaFile( "shared.lua" )
|
||||
|
||||
include( "shared.lua" )
|
||||
include( "schedules.lua" )
|
||||
include( "tasks.lua" )
|
||||
|
||||
-- Variables
|
||||
|
||||
ENT.m_fMaxYawSpeed = 200 -- Max turning speed
|
||||
ENT.m_iClass = CLASS_CITIZEN_REBEL -- NPC Class
|
||||
|
||||
AccessorFunc( ENT, "m_iClass", "NPCClass" )
|
||||
AccessorFunc( ENT, "m_fMaxYawSpeed", "MaxYawSpeed" )
|
||||
|
||||
function ENT:Initialize()
|
||||
|
||||
-- Some default calls to make the NPC function
|
||||
self:SetModel( "models/alyx.mdl" )
|
||||
self:SetHullType( HULL_HUMAN )
|
||||
self:SetHullSizeNormal()
|
||||
self:SetSolid( SOLID_BBOX )
|
||||
self:SetMoveType( MOVETYPE_STEP )
|
||||
self:CapabilitiesAdd( bit.bor( CAP_MOVE_GROUND, CAP_OPEN_DOORS, CAP_ANIMATEDFACE, CAP_SQUAD, CAP_USE_WEAPONS, CAP_DUCK, CAP_MOVE_SHOOT, CAP_TURN_HEAD, CAP_USE_SHOT_REGULATOR, CAP_AIM_GUN ) )
|
||||
|
||||
self:SetHealth( 100 )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: OnTakeDamage
|
||||
Desc: Called when the NPC takes damage
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:OnTakeDamage( dmginfo )
|
||||
|
||||
--[[
|
||||
Msg( tostring(dmginfo) .. "\n" )
|
||||
Msg( "Inflictor:\t" .. tostring(dmginfo:GetInflictor()) .. "\n" )
|
||||
Msg( "Attacker:\t" .. tostring(dmginfo:GetAttacker()) .. "\n" )
|
||||
Msg( "Damage:\t" .. tostring(dmginfo:GetDamage()) .. "\n" )
|
||||
Msg( "Base Damage:\t" .. tostring(dmginfo:GetBaseDamage()) .. "\n" )
|
||||
Msg( "Force:\t" .. tostring(dmginfo:GetDamageForce()) .. "\n" )
|
||||
Msg( "Position:\t" .. tostring(dmginfo:GetDamagePosition()) .. "\n" )
|
||||
Msg( "Reported Pos:\t" .. tostring(dmginfo:GetReportedPosition()) .. "\n" ) -- ??
|
||||
--]]
|
||||
|
||||
-- return 1
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: Use
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:Use( activator, caller, type, value )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: StartTouch
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:StartTouch( entity )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: EndTouch
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:EndTouch( entity )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: Touch
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:Touch( entity )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: GetRelationship
|
||||
Return the relationship between this NPC and the
|
||||
passed entity. If you don't return anything then
|
||||
the default disposition will be used.
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:GetRelationship( entity )
|
||||
|
||||
--return D_NU;
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: ExpressionFinished
|
||||
Called when an expression has finished. Duh.
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:ExpressionFinished( strExp )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: OnChangeActivity
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:OnChangeActivity( act )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: Think
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:Think()
|
||||
|
||||
end
|
||||
|
||||
-- Called when NPC's movement fails
|
||||
function ENT:OnMovementFailed()
|
||||
end
|
||||
|
||||
-- Called when NPC's movement succeeds
|
||||
function ENT:OnMovementComplete()
|
||||
end
|
||||
|
||||
-- Called when the NPC's active weapon changes
|
||||
function ENT:OnActiveWeaponChanged( old, new )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: GetAttackSpread
|
||||
How good is the NPC with this weapon? Return the number
|
||||
of degrees of inaccuracy for the NPC to use.
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:GetAttackSpread( Weapon, Target )
|
||||
return 0.1
|
||||
end
|
||||
199
gamemodes/cod_custom/entities/entities/base_ai/schedules.lua
Normal file
199
gamemodes/cod_custom/entities/entities/base_ai/schedules.lua
Normal file
@@ -0,0 +1,199 @@
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: RunAI - Called from the engine every 0.1 seconds
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:RunAI( strExp )
|
||||
|
||||
-- If we're running an Engine Side behaviour
|
||||
-- then return true and let it get on with it.
|
||||
if ( self:IsRunningBehavior() ) then
|
||||
return true
|
||||
end
|
||||
|
||||
-- If we're doing an engine schedule then return true
|
||||
-- This makes it do the normal AI stuff.
|
||||
if ( self:DoingEngineSchedule() ) then
|
||||
return true
|
||||
end
|
||||
|
||||
-- If we're currently running a schedule then run it.
|
||||
if ( self.CurrentSchedule ) then
|
||||
self:DoSchedule( self.CurrentSchedule )
|
||||
end
|
||||
|
||||
-- If we have no schedule (schedule is finished etc)
|
||||
-- Then get the derived NPC to select what we should be doing
|
||||
if ( !self.CurrentSchedule ) then
|
||||
self:SelectSchedule()
|
||||
end
|
||||
|
||||
-- Do animation system
|
||||
self:MaintainActivity()
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: SelectSchedule - Set the schedule we should be
|
||||
playing right now.
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:SelectSchedule( iNPCState )
|
||||
|
||||
self:SetSchedule( SCHED_IDLE_WANDER )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: StartSchedule - Start a Lua schedule. Not to be
|
||||
confused with SetSchedule which starts an Engine based
|
||||
schedule.
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:StartSchedule( schedule )
|
||||
|
||||
self.CurrentSchedule = schedule
|
||||
self.CurrentTaskID = 1
|
||||
self:SetTask( schedule:GetTask( 1 ) )
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: DoSchedule - Runs a Lua schedule.
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:DoSchedule( schedule )
|
||||
|
||||
if ( self.CurrentTask ) then
|
||||
self:RunTask( self.CurrentTask )
|
||||
end
|
||||
|
||||
if ( self:TaskFinished() ) then
|
||||
self:NextTask( schedule )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: ScheduleFinished
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:ScheduleFinished()
|
||||
|
||||
self.CurrentSchedule = nil
|
||||
self.CurrentTask = nil
|
||||
self.CurrentTaskID = nil
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: DoSchedule - Set the current task.
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:SetTask( task )
|
||||
|
||||
self.CurrentTask = task
|
||||
self.bTaskComplete = false
|
||||
self.TaskStartTime = CurTime()
|
||||
|
||||
self:StartTask( self.CurrentTask )
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: NextTask - Start the next task in specific schedule.
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:NextTask( schedule )
|
||||
|
||||
-- Increment task id
|
||||
self.CurrentTaskID = self.CurrentTaskID + 1
|
||||
|
||||
-- If this was the last task then finish up.
|
||||
if ( self.CurrentTaskID > schedule:NumTasks() ) then
|
||||
|
||||
self:ScheduleFinished( schedule )
|
||||
return
|
||||
|
||||
end
|
||||
|
||||
-- Switch to next task
|
||||
self:SetTask( schedule:GetTask( self.CurrentTaskID ) )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: StartTask - called once on starting task
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:StartTask( task )
|
||||
task:Start( self.Entity )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: RunTask - called every think on running task.
|
||||
The actual task function should tell us when
|
||||
the task is finished.
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:RunTask( task )
|
||||
task:Run( self.Entity )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: TaskTime - Returns how many seconds we've been
|
||||
doing this current task
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:TaskTime()
|
||||
return CurTime() - self.TaskStartTime
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: OnTaskComplete - Called from the engine when
|
||||
TaskComplete is called. This allows us to move
|
||||
onto the next task - even when TaskComplete was
|
||||
called from an engine side task.
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:OnTaskComplete()
|
||||
|
||||
self.bTaskComplete = true
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: TaskFinished - Returns true if the current
|
||||
running Task is finished.
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:TaskFinished()
|
||||
return self.bTaskComplete
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: StartTask
|
||||
Start the task. You can use this to override engine
|
||||
side tasks. Return true to not run default stuff.
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:StartEngineTask( iTaskID, TaskData )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: RunTask
|
||||
Run the task. You can use this to override engine
|
||||
side tasks. Return true to not run default stuff.
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:RunEngineTask( iTaskID, TaskData )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
These functions handle the engine schedules
|
||||
When an engine schedule is set the engine calls StartEngineSchedule
|
||||
Then when it's finished it calls EngineScheduleFinishHelp me decide
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:StartEngineSchedule( scheduleID ) self:ScheduleFinished() self.bDoingEngineSchedule = true end
|
||||
function ENT:EngineScheduleFinish() self.bDoingEngineSchedule = nil end
|
||||
function ENT:DoingEngineSchedule() return self.bDoingEngineSchedule end
|
||||
|
||||
function ENT:OnCondition( iCondition )
|
||||
|
||||
--Msg( self, " Condition: ", iCondition, " - ", self:ConditionName(iCondition), "\n" )
|
||||
|
||||
end
|
||||
44
gamemodes/cod_custom/entities/entities/base_ai/shared.lua
Normal file
44
gamemodes/cod_custom/entities/entities/base_ai/shared.lua
Normal file
@@ -0,0 +1,44 @@
|
||||
|
||||
ENT.Base = "base_entity"
|
||||
ENT.Type = "ai"
|
||||
|
||||
ENT.PrintName = "Base SNPC"
|
||||
ENT.Author = ""
|
||||
ENT.Contact = ""
|
||||
ENT.Purpose = ""
|
||||
ENT.Instructions = ""
|
||||
|
||||
ENT.AutomaticFrameAdvance = false
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: OnRemove
|
||||
Desc: Called just before entity is deleted
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:OnRemove()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: PhysicsCollide
|
||||
Desc: Called when physics collides. The table contains
|
||||
data on the collision
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:PhysicsCollide( data, physobj )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: PhysicsUpdate
|
||||
Desc: Called to update the physics .. or something.
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:PhysicsUpdate( physobj )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: SetAutomaticFrameAdvance
|
||||
Desc: If you're not using animation you should turn this
|
||||
off - it will save lots of bandwidth.
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:SetAutomaticFrameAdvance( bUsingAnim )
|
||||
|
||||
self.AutomaticFrameAdvance = bUsingAnim
|
||||
|
||||
end
|
||||
81
gamemodes/cod_custom/entities/entities/base_ai/tasks.lua
Normal file
81
gamemodes/cod_custom/entities/entities/base_ai/tasks.lua
Normal file
@@ -0,0 +1,81 @@
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Task: PlaySequence
|
||||
|
||||
Accepts:
|
||||
|
||||
data.ID - sequence id
|
||||
data.Name - sequence name (Must provide either id or name)
|
||||
data.Wait - Optional. Should we wait for sequence to finish
|
||||
data.Speed - Optional. Playback speed of sequence
|
||||
data.Loop - Optional. Should the sequence be looped
|
||||
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:TaskStart_PlaySequence( data )
|
||||
|
||||
local SequenceID = data.ID
|
||||
|
||||
if ( data.Name ) then SequenceID = self:LookupSequence( data.Name ) end
|
||||
|
||||
self:ResetSequence( SequenceID )
|
||||
self:SetNPCState( NPC_STATE_SCRIPT )
|
||||
|
||||
local Duration = self:SequenceDuration()
|
||||
|
||||
if ( data.Speed && data.Speed > 0 ) then
|
||||
|
||||
SequenceID = self:SetPlaybackRate( data.Speed )
|
||||
Duration = Duration / data.Speed
|
||||
|
||||
end
|
||||
|
||||
self.TaskSequenceEnd = CurTime() + Duration
|
||||
self.Loop = data.Loop or false
|
||||
|
||||
end
|
||||
|
||||
function ENT:Task_PlaySequence( data )
|
||||
|
||||
-- Wait until sequence is finished
|
||||
if ( CurTime() < self.TaskSequenceEnd or self.Loop ) then return end
|
||||
|
||||
self:TaskComplete()
|
||||
self:SetNPCState( NPC_STATE_NONE )
|
||||
|
||||
-- Clean up
|
||||
self.TaskSequenceEnd = nil
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Task: FindEnemy
|
||||
|
||||
Accepts:
|
||||
|
||||
data.ID - sequence id
|
||||
data.Name - sequence name (Must provide either id or name)
|
||||
data.Wait - Optional. Should we wait for sequence to finish
|
||||
data.Speed - Optional. Playback speed of sequence
|
||||
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:TaskStart_FindEnemy( data )
|
||||
|
||||
local et = ents.FindInSphere( self:GetPos(), data.Radius or 512 )
|
||||
for k, v in ipairs( et ) do
|
||||
|
||||
if ( v:IsValid() && v != self && v:GetClass() == data.Class ) then
|
||||
|
||||
self:SetEnemy( v, true )
|
||||
self:UpdateEnemyMemory( v, v:GetPos() )
|
||||
self:TaskComplete()
|
||||
return
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
self:SetEnemy( NULL )
|
||||
|
||||
end
|
||||
|
||||
function ENT:Task_FindEnemy( data )
|
||||
end
|
||||
104
gamemodes/cod_custom/entities/entities/base_anim.lua
Normal file
104
gamemodes/cod_custom/entities/entities/base_anim.lua
Normal file
@@ -0,0 +1,104 @@
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
ENT.Base = "base_entity"
|
||||
ENT.Type = "anim"
|
||||
|
||||
ENT.PrintName = ""
|
||||
ENT.Author = ""
|
||||
ENT.Contact = ""
|
||||
ENT.Purpose = ""
|
||||
ENT.Instructions = ""
|
||||
|
||||
-- Defaulting this to OFF. This will automatically save bandwidth
|
||||
-- on stuff that is already out there, but might break a few things
|
||||
-- that are out there. I'm choosing to break those things because
|
||||
-- there are a lot less of them that are actually using the animtime
|
||||
|
||||
ENT.AutomaticFrameAdvance = false
|
||||
|
||||
function ENT:SetAutomaticFrameAdvance( bUsingAnim )
|
||||
self.AutomaticFrameAdvance = bUsingAnim
|
||||
end
|
||||
|
||||
|
||||
function ENT:OnRemove()
|
||||
end
|
||||
|
||||
|
||||
function ENT:PhysicsCollide( data, physobj )
|
||||
end
|
||||
|
||||
|
||||
function ENT:PhysicsUpdate( physobj )
|
||||
end
|
||||
|
||||
if ( CLIENT ) then
|
||||
|
||||
function ENT:Draw( flags )
|
||||
|
||||
self:DrawModel( flags )
|
||||
|
||||
end
|
||||
|
||||
function ENT:DrawTranslucent( flags )
|
||||
|
||||
-- This is here just to make it backwards compatible.
|
||||
-- You shouldn't really be drawing your model here unless it's translucent
|
||||
|
||||
self:Draw( flags )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if ( SERVER ) then
|
||||
|
||||
function ENT:OnTakeDamage( dmginfo )
|
||||
|
||||
--[[
|
||||
Msg( tostring(dmginfo) .. "\n" )
|
||||
Msg( "Inflictor:\t" .. tostring(dmginfo:GetInflictor()) .. "\n" )
|
||||
Msg( "Attacker:\t" .. tostring(dmginfo:GetAttacker()) .. "\n" )
|
||||
Msg( "Damage:\t" .. tostring(dmginfo:GetDamage()) .. "\n" )
|
||||
Msg( "Base Damage:\t" .. tostring(dmginfo:GetBaseDamage()) .. "\n" )
|
||||
Msg( "Force:\t" .. tostring(dmginfo:GetDamageForce()) .. "\n" )
|
||||
Msg( "Position:\t" .. tostring(dmginfo:GetDamagePosition()) .. "\n" )
|
||||
Msg( "Reported Pos:\t" .. tostring(dmginfo:GetReportedPosition()) .. "\n" ) -- ??
|
||||
--]]
|
||||
|
||||
end
|
||||
|
||||
|
||||
function ENT:Use( activator, caller, type, value )
|
||||
end
|
||||
|
||||
|
||||
function ENT:StartTouch( entity )
|
||||
end
|
||||
|
||||
|
||||
function ENT:EndTouch( entity )
|
||||
end
|
||||
|
||||
|
||||
function ENT:Touch( entity )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: Simulate
|
||||
Desc: Controls/simulates the physics on the entity.
|
||||
Officially the most complicated callback in the whole mod.
|
||||
Returns 3 variables..
|
||||
1. A SIM_ enum
|
||||
2. A vector representing the linear acceleration/force
|
||||
3. A vector represending the angular acceleration/force
|
||||
If you're doing nothing you can return SIM_NOTHING
|
||||
Note that you need to call ent:StartMotionController to tell the entity
|
||||
to start calling this function..
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:PhysicsSimulate( phys, deltatime )
|
||||
return SIM_NOTHING
|
||||
end
|
||||
|
||||
end
|
||||
56
gamemodes/cod_custom/entities/entities/base_brush.lua
Normal file
56
gamemodes/cod_custom/entities/entities/base_brush.lua
Normal file
@@ -0,0 +1,56 @@
|
||||
|
||||
ENT.Base = "base_entity"
|
||||
ENT.Type = "brush"
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: Initialize
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:Initialize()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: StartTouch
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:StartTouch( entity )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: EndTouch
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:EndTouch( entity )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: Touch
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:Touch( entity )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: PassesTriggerFilters
|
||||
Desc: Return true if this object should trigger us
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:PassesTriggerFilters( entity )
|
||||
return true
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: KeyValue
|
||||
Desc: Called when a keyvalue is added to us
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:KeyValue( key, value )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: Think
|
||||
Desc: Entity's think function.
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:Think()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: OnRemove
|
||||
Desc: Called just before entity is deleted
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:OnRemove()
|
||||
end
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
include( "shared.lua" )
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: Initialize
|
||||
Desc: First function called. Use to set up your entity
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:Initialize()
|
||||
end
|
||||
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: Think
|
||||
Desc: Client Think - called every frame
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:Think()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: OnRestore
|
||||
Desc: Called immediately after a "load"
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:OnRestore()
|
||||
end
|
||||
77
gamemodes/cod_custom/entities/entities/base_entity/init.lua
Normal file
77
gamemodes/cod_custom/entities/entities/base_entity/init.lua
Normal file
@@ -0,0 +1,77 @@
|
||||
|
||||
AddCSLuaFile( "cl_init.lua" )
|
||||
AddCSLuaFile( "shared.lua" )
|
||||
|
||||
include( "shared.lua" )
|
||||
include( "outputs.lua" )
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: Initialize
|
||||
Desc: First function called. Use to set up your entity
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:Initialize()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: KeyValue
|
||||
Desc: Called when a keyvalue is added to us
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:KeyValue( key, value )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: OnRestore
|
||||
Desc: The game has just been reloaded. This is usually the right place
|
||||
to call the GetNW* functions to restore the script's values.
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:OnRestore()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: AcceptInput
|
||||
Desc: Accepts input, return true to override/accept input
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:AcceptInput( name, activator, caller, data )
|
||||
return false
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: UpdateTransmitState
|
||||
Desc: Set the transmit state
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:UpdateTransmitState()
|
||||
return TRANSMIT_PVS
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: Think
|
||||
Desc: Entity's think function.
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:Think()
|
||||
end
|
||||
|
||||
--
|
||||
-- Default generic spawn function
|
||||
-- So you don't have to add one your entitie unless you want to.
|
||||
--
|
||||
function ENT:SpawnFunction( ply, tr, ClassName )
|
||||
|
||||
if ( !tr.Hit ) then return end
|
||||
|
||||
local SpawnPos = tr.HitPos + tr.HitNormal * 10
|
||||
local SpawnAng = ply:EyeAngles()
|
||||
SpawnAng.p = 0
|
||||
SpawnAng.y = SpawnAng.y + 180
|
||||
|
||||
local ent = ents.Create( ClassName )
|
||||
ent:SetCreator( ply )
|
||||
ent:SetPos( SpawnPos )
|
||||
ent:SetAngles( SpawnAng )
|
||||
ent:Spawn()
|
||||
ent:Activate()
|
||||
|
||||
ent:DropToFloor()
|
||||
|
||||
return ent
|
||||
|
||||
end
|
||||
@@ -0,0 +1,80 @@
|
||||
|
||||
-- This is called from ENT:KeyValue(key,value) to store the output from
|
||||
-- the map, it could also be called from ENT:AcceptInput I think, so if
|
||||
-- ent_fire addoutput is used, we can store that too (that hasn't been
|
||||
-- tested though).
|
||||
-- Usage: self:StoreOutput("<name of output>","<entities to fire>,<input name>,<param>,<delay>,<times to be used>")
|
||||
-- If called from ENT:KeyValue, then the first parameter is the key, and
|
||||
-- the second is value.
|
||||
function ENT:StoreOutput( name, info )
|
||||
|
||||
-- Newer Source Engine games use this symbol as a delimiter
|
||||
local rawData = string.Explode( "\x1B", info )
|
||||
if ( #rawData < 2 ) then
|
||||
rawData = string.Explode( ",", info )
|
||||
end
|
||||
|
||||
local Output = {}
|
||||
Output.entities = rawData[1] or ""
|
||||
Output.input = rawData[2] or ""
|
||||
Output.param = rawData[3] or ""
|
||||
Output.delay = tonumber( rawData[4] ) or 0
|
||||
Output.times = tonumber( rawData[5] ) or -1
|
||||
|
||||
self.m_tOutputs = self.m_tOutputs or {}
|
||||
self.m_tOutputs[ name ] = self.m_tOutputs[ name ] or {}
|
||||
|
||||
table.insert( self.m_tOutputs[ name ], Output )
|
||||
|
||||
end
|
||||
|
||||
-- Nice helper function, this does all the work. Returns false if the
|
||||
-- output should be removed from the list.
|
||||
local function FireSingleOutput( output, this, activator, data )
|
||||
|
||||
if ( output.times == 0 ) then return false end
|
||||
|
||||
local entitiesToFire = {}
|
||||
|
||||
if ( output.entities == "!activator" ) then
|
||||
entitiesToFire = { activator }
|
||||
elseif ( output.entities == "!self" ) then
|
||||
entitiesToFire = { this }
|
||||
elseif ( output.entities == "!player" ) then
|
||||
entitiesToFire = player.GetAll()
|
||||
else
|
||||
entitiesToFire = ents.FindByName( output.entities )
|
||||
end
|
||||
|
||||
for _, ent in pairs( entitiesToFire ) do
|
||||
ent:Fire( output.input, data or output.param, output.delay, activator, this )
|
||||
end
|
||||
|
||||
if ( output.times ~= -1 ) then
|
||||
output.times = output.times - 1
|
||||
end
|
||||
|
||||
return ( output.times > 0 ) || ( output.times == -1 )
|
||||
|
||||
end
|
||||
|
||||
-- This function is used to trigger an output.
|
||||
function ENT:TriggerOutput( name, activator, data )
|
||||
|
||||
if ( !self.m_tOutputs ) then return end
|
||||
if ( !self.m_tOutputs[ name ] ) then return end
|
||||
|
||||
local OutputList = self.m_tOutputs[ name ]
|
||||
|
||||
for idx = #OutputList, 1, -1 do
|
||||
|
||||
if ( OutputList[ idx ] and !FireSingleOutput( OutputList[ idx ], self.Entity, activator, data ) ) then
|
||||
|
||||
-- Shift the indexes so this loop doesn't fail later
|
||||
table.remove( self.m_tOutputs[ name ], idx )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
ENT.Base = "base_entity"
|
||||
ENT.Type = "anim"
|
||||
|
||||
ENT.Spawnable = false
|
||||
ENT.AdminOnly = false
|
||||
44
gamemodes/cod_custom/entities/entities/base_filter.lua
Normal file
44
gamemodes/cod_custom/entities/entities/base_filter.lua
Normal file
@@ -0,0 +1,44 @@
|
||||
|
||||
ENT.Base = "base_entity"
|
||||
ENT.Type = "filter"
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: Initialize
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:Initialize()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: KeyValue
|
||||
Desc: Called when a keyvalue is added to us
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:KeyValue( key, value )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: Think
|
||||
Desc: Entity's think function.
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:Think()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: OnRemove
|
||||
Desc: Called just before entity is deleted
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:OnRemove()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: PassesFilter
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:PassesFilter( trigger, ent )
|
||||
return true
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: PassesDamageFilter
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:PassesDamageFilter( dmg )
|
||||
return true
|
||||
end
|
||||
140
gamemodes/cod_custom/entities/entities/base_gmodentity.lua
Normal file
140
gamemodes/cod_custom/entities/entities/base_gmodentity.lua
Normal file
@@ -0,0 +1,140 @@
|
||||
|
||||
AddCSLuaFile()
|
||||
DEFINE_BASECLASS( "base_anim" )
|
||||
|
||||
ENT.Spawnable = false
|
||||
|
||||
if ( CLIENT ) then
|
||||
ENT.MaxWorldTipDistance = 256
|
||||
|
||||
function ENT:BeingLookedAtByLocalPlayer()
|
||||
local ply = LocalPlayer()
|
||||
if ( !IsValid( ply ) ) then return false end
|
||||
|
||||
local view = ply:GetViewEntity()
|
||||
local dist = self.MaxWorldTipDistance
|
||||
dist = dist * dist
|
||||
|
||||
-- If we're spectating a player, perform an eye trace
|
||||
if ( view:IsPlayer() ) then
|
||||
return view:EyePos():DistToSqr( self:GetPos() ) <= dist && view:GetEyeTrace().Entity == self
|
||||
end
|
||||
|
||||
-- If we're not spectating a player, perform a manual trace from the entity's position
|
||||
local pos = view:GetPos()
|
||||
|
||||
if ( pos:DistToSqr( self:GetPos() ) <= dist ) then
|
||||
return util.TraceLine( {
|
||||
start = pos,
|
||||
endpos = pos + ( view:GetAngles():Forward() * dist ),
|
||||
filter = view
|
||||
} ).Entity == self
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
local text = self:GetOverlayText()
|
||||
|
||||
if ( text != "" && self:BeingLookedAtByLocalPlayer() && !self:GetNoDraw() ) then
|
||||
AddWorldTip( self:EntIndex(), text, 0.5, self:GetPos(), self )
|
||||
|
||||
halo.Add( { self }, color_white, 1, 1, 1, true, true )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:SetOverlayText( text )
|
||||
self:SetNWString( "GModOverlayText", text )
|
||||
end
|
||||
|
||||
function ENT:GetOverlayText()
|
||||
|
||||
local txt = self:GetNWString( "GModOverlayText" )
|
||||
|
||||
if ( txt == "" ) then
|
||||
return ""
|
||||
end
|
||||
|
||||
if ( game.SinglePlayer() ) then
|
||||
return txt
|
||||
end
|
||||
|
||||
local PlayerName = self:GetPlayerName()
|
||||
|
||||
return txt .. "\n(" .. PlayerName .. ")"
|
||||
|
||||
end
|
||||
|
||||
function ENT:SetPlayer( ply )
|
||||
|
||||
self.Founder = ply
|
||||
|
||||
if ( IsValid( ply ) ) then
|
||||
|
||||
self:SetNWString( "FounderName", ply:Nick() )
|
||||
self.FounderSID = ply:SteamID64()
|
||||
self.FounderIndex = ply:UniqueID()
|
||||
|
||||
else
|
||||
|
||||
self:SetNWString( "FounderName", "" )
|
||||
self.FounderSID = nil
|
||||
self.FounderIndex = nil
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function ENT:GetPlayer()
|
||||
|
||||
if ( self.Founder == nil ) then
|
||||
|
||||
-- SetPlayer has not been called
|
||||
return NULL
|
||||
|
||||
elseif ( IsValid( self.Founder ) ) then
|
||||
|
||||
-- Normal operations
|
||||
return self.Founder
|
||||
|
||||
end
|
||||
|
||||
-- See if the player has left the server then rejoined
|
||||
local ply = player.GetBySteamID64( self.FounderSID )
|
||||
if ( not IsValid( ply ) ) then
|
||||
|
||||
-- Oh well
|
||||
return NULL
|
||||
|
||||
end
|
||||
|
||||
-- Save us the check next time
|
||||
self:SetPlayer( ply )
|
||||
return ply
|
||||
|
||||
end
|
||||
|
||||
function ENT:GetPlayerIndex()
|
||||
|
||||
return self.FounderIndex or 0
|
||||
|
||||
end
|
||||
|
||||
function ENT:GetPlayerSteamID()
|
||||
|
||||
return self.FounderSID or ""
|
||||
|
||||
end
|
||||
|
||||
function ENT:GetPlayerName()
|
||||
|
||||
local ply = self:GetPlayer()
|
||||
if ( IsValid( ply ) ) then
|
||||
return ply:Nick()
|
||||
end
|
||||
|
||||
return self:GetNWString( "FounderName" )
|
||||
|
||||
end
|
||||
@@ -0,0 +1,55 @@
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
ENT.Base = "base_entity"
|
||||
ENT.PrintName = ""
|
||||
ENT.Author = ""
|
||||
ENT.Contact = ""
|
||||
ENT.Purpose = ""
|
||||
ENT.Instructions = ""
|
||||
ENT.RenderGroup = RENDERGROUP_OPAQUE
|
||||
|
||||
ENT.Type = "nextbot"
|
||||
|
||||
function ENT:Initialize()
|
||||
end
|
||||
|
||||
if ( SERVER ) then
|
||||
|
||||
--
|
||||
-- All of the AI logic is serverside - so we derive it from a
|
||||
-- specialized class on the server.
|
||||
--
|
||||
include( "sv_nextbot.lua" )
|
||||
|
||||
else
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: Draw
|
||||
Desc: Draw it!
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:Draw()
|
||||
self:DrawModel()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: DrawTranslucent
|
||||
Desc: Draw translucent
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:DrawTranslucent()
|
||||
|
||||
-- This is here just to make it backwards compatible.
|
||||
-- You shouldn't really be drawing your model here unless it's translucent
|
||||
|
||||
self:Draw()
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: FireAnimationEvent
|
||||
Desc: Called when an animation event is fired. Return true to suppress
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:FireAnimationEvent( pos, ang, event, options )
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,403 @@
|
||||
|
||||
--
|
||||
-- Name: NEXTBOT:BehaveStart
|
||||
-- Desc: Called to initialize the behaviour.\n\n You shouldn't override this - it's used to kick off the coroutine that runs the bot's behaviour. \n\nThis is called automatically when the NPC is created, there should be no need to call it manually.
|
||||
-- Arg1:
|
||||
-- Ret1:
|
||||
--
|
||||
function ENT:BehaveStart()
|
||||
|
||||
self.BehaveThread = coroutine.create( function() self:RunBehaviour() end )
|
||||
|
||||
end
|
||||
|
||||
function ENT:RunBehaviour()
|
||||
end
|
||||
|
||||
--
|
||||
-- Name: NEXTBOT:BehaveUpdate
|
||||
-- Desc: Called to update the bot's behaviour
|
||||
-- Arg1: number|interval|How long since the last update
|
||||
-- Ret1:
|
||||
--
|
||||
function ENT:BehaveUpdate( fInterval )
|
||||
|
||||
if ( !self.BehaveThread ) then return end
|
||||
|
||||
--
|
||||
-- Give a silent warning to developers if RunBehaviour has returned
|
||||
--
|
||||
if ( coroutine.status( self.BehaveThread ) == "dead" ) then
|
||||
|
||||
self.BehaveThread = nil
|
||||
Msg( self, " Warning: ENT:RunBehaviour() has finished executing\n" )
|
||||
|
||||
return
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Continue RunBehaviour's execution
|
||||
--
|
||||
local ok, message = coroutine.resume( self.BehaveThread )
|
||||
if ( ok == false ) then
|
||||
|
||||
self.BehaveThread = nil
|
||||
ErrorNoHalt( self, " Error: ", message, "\n" )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Name: NEXTBOT:BodyUpdate
|
||||
-- Desc: Called to update the bot's animation
|
||||
-- Arg1:
|
||||
-- Ret1:
|
||||
--
|
||||
function ENT:BodyUpdate()
|
||||
|
||||
local act = self:GetActivity()
|
||||
|
||||
--
|
||||
-- This helper function does a lot of useful stuff for us.
|
||||
-- It sets the bot's move_x move_y pose parameters, sets their animation speed relative to the ground speed, and calls FrameAdvance.
|
||||
--
|
||||
if ( act == ACT_RUN || act == ACT_WALK ) then
|
||||
|
||||
self:BodyMoveXY()
|
||||
|
||||
-- BodyMoveXY() already calls FrameAdvance, calling it twice will affect animation playback, specifically on layers
|
||||
return
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- If we're not walking or running we probably just want to update the anim system
|
||||
--
|
||||
self:FrameAdvance()
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Name: NEXTBOT:OnLeaveGround
|
||||
-- Desc: Called when the bot's feet leave the ground - for whatever reason
|
||||
-- Arg1: Entity|ent|Entity that the NextBot "jumped" from
|
||||
-- Ret1:
|
||||
--
|
||||
function ENT:OnLeaveGround( ent )
|
||||
|
||||
--MsgN( "OnLeaveGround", ent )
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Name: NEXTBOT:OnLeaveGround
|
||||
-- Desc: Called when the bot's feet return to the ground
|
||||
-- Arg1: Entity|ent|Entity that the NextBot landed on
|
||||
-- Ret1:
|
||||
--
|
||||
function ENT:OnLandOnGround( ent )
|
||||
|
||||
--MsgN( "OnLandOnGround", ent )
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Name: NEXTBOT:OnStuck
|
||||
-- Desc: Called when the bot thinks it is stuck
|
||||
-- Arg1:
|
||||
-- Ret1:
|
||||
--
|
||||
function ENT:OnStuck()
|
||||
|
||||
--MsgN( "OnStuck" )
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Name: NEXTBOT:OnUnStuck
|
||||
-- Desc: Called when the bot thinks it is un-stuck
|
||||
-- Arg1:
|
||||
-- Ret1:
|
||||
--
|
||||
function ENT:OnUnStuck()
|
||||
|
||||
--MsgN( "OnUnStuck" )
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Name: NEXTBOT:OnInjured
|
||||
-- Desc: Called when the bot gets hurt
|
||||
-- Arg1: CTakeDamageInfo|info|damage info
|
||||
-- Ret1:
|
||||
--
|
||||
function ENT:OnInjured( damageinfo )
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Name: NEXTBOT:OnKilled
|
||||
-- Desc: Called when the bot gets killed
|
||||
-- Arg1: CTakeDamageInfo|info|damage info
|
||||
-- Ret1:
|
||||
--
|
||||
function ENT:OnKilled( dmginfo )
|
||||
|
||||
hook.Run( "OnNPCKilled", self, dmginfo:GetAttacker(), dmginfo:GetInflictor() )
|
||||
|
||||
self:BecomeRagdoll( dmginfo )
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Name: NEXTBOT:OnOtherKilled
|
||||
-- Desc: Called when someone else or something else has been killed
|
||||
-- Arg1: Entity|victim|entity that was killed
|
||||
-- Arg2: CTakeDamageInfo|info|damage info
|
||||
-- Ret1:
|
||||
--
|
||||
function ENT:OnOtherKilled( victim, info )
|
||||
|
||||
--MsgN( "OnOtherKilled", victim, info )
|
||||
|
||||
end
|
||||
|
||||
function ENT:OnContact( ent )
|
||||
|
||||
--MsgN( "OnContact", ent )
|
||||
|
||||
end
|
||||
|
||||
function ENT:OnIgnite()
|
||||
|
||||
--MsgN( "OnIgnite" )
|
||||
|
||||
end
|
||||
|
||||
function ENT:OnNavAreaChanged( old, new )
|
||||
|
||||
--MsgN( "OnNavAreaChanged", old, new )
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Name: NextBot:FindSpots
|
||||
-- Desc: Returns a table of hiding spots.
|
||||
-- Arg1: table|specs|This table should contain the search info.\n\n * 'type' - the type (either 'hiding')\n * 'pos' - the position to search.\n * 'radius' - the radius to search.\n * 'stepup' - the highest step to step up.\n * 'stepdown' - the highest we can step down without being hurt.
|
||||
-- Ret1: table|An unsorted table of tables containing\n * 'vector' - the position of the hiding spot\n * 'distance' - the distance to that position
|
||||
--
|
||||
function ENT:FindSpots( tbl )
|
||||
|
||||
local tbl = tbl or {}
|
||||
|
||||
tbl.pos = tbl.pos or self:WorldSpaceCenter()
|
||||
tbl.radius = tbl.radius or 1000
|
||||
tbl.stepdown = tbl.stepdown or 20
|
||||
tbl.stepup = tbl.stepup or 20
|
||||
tbl.type = tbl.type or 'hiding'
|
||||
|
||||
-- Use a path to find the length
|
||||
local path = Path( "Follow" )
|
||||
|
||||
-- Find a bunch of areas within this distance
|
||||
local areas = navmesh.Find( tbl.pos, tbl.radius, tbl.stepdown, tbl.stepup )
|
||||
|
||||
local found = {}
|
||||
|
||||
-- In each area
|
||||
for _, area in pairs( areas ) do
|
||||
|
||||
-- get the spots
|
||||
local spots
|
||||
|
||||
if ( tbl.type == 'hiding' ) then spots = area:GetHidingSpots() end
|
||||
|
||||
for k, vec in pairs( spots ) do
|
||||
|
||||
-- Work out the length, and add them to a table
|
||||
path:Invalidate()
|
||||
|
||||
path:Compute( self, vec, 1 ) -- TODO: This is bullshit - it's using 'self.pos' not tbl.pos
|
||||
|
||||
table.insert( found, { vector = vec, distance = path:GetLength() } )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return found
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Name: NextBot:FindSpot
|
||||
-- Desc: Like FindSpots but only returns a vector
|
||||
-- Arg1: string|type|Either "random", "near", "far"
|
||||
-- Arg2: table|options|A table containing a bunch of tweakable options. See the function definition for more details
|
||||
-- Ret1: vector|If it finds a spot it will return a vector. If not it will return nil.
|
||||
--
|
||||
function ENT:FindSpot( type, options )
|
||||
|
||||
local spots = self:FindSpots( options )
|
||||
if ( !spots || #spots == 0 ) then return end
|
||||
|
||||
if ( type == "near" ) then
|
||||
|
||||
table.SortByMember( spots, "distance", true )
|
||||
return spots[1].vector
|
||||
|
||||
end
|
||||
|
||||
if ( type == "far" ) then
|
||||
|
||||
table.SortByMember( spots, "distance", false )
|
||||
return spots[1].vector
|
||||
|
||||
end
|
||||
|
||||
-- random
|
||||
return spots[ math.random( 1, #spots ) ].vector
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Name: NextBot:HandleStuck
|
||||
-- Desc: Called from Lua when the NPC is stuck. This should only be called from the behaviour coroutine - so if you want to override this function and do something special that yields - then go for it.\n\nYou should always call self.loco:ClearStuck() in this function to reset the stuck status - so it knows it's unstuck.
|
||||
-- Arg1:
|
||||
-- Ret1:
|
||||
--
|
||||
function ENT:HandleStuck()
|
||||
|
||||
--
|
||||
-- Clear the stuck status
|
||||
--
|
||||
self.loco:ClearStuck()
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Name: NextBot:MoveToPos
|
||||
-- Desc: To be called in the behaviour coroutine only! Will yield until the bot has reached the goal or is stuck
|
||||
-- Arg1: Vector|pos|The position we want to get to
|
||||
-- Arg2: table|options|A table containing a bunch of tweakable options. See the function definition for more details
|
||||
-- Ret1: string|Either "failed", "stuck", "timeout" or "ok" - depending on how the NPC got on
|
||||
--
|
||||
function ENT:MoveToPos( pos, options )
|
||||
|
||||
local options = options or {}
|
||||
|
||||
local path = Path( "Follow" )
|
||||
path:SetMinLookAheadDistance( options.lookahead or 300 )
|
||||
path:SetGoalTolerance( options.tolerance or 20 )
|
||||
path:Compute( self, pos )
|
||||
|
||||
if ( !path:IsValid() ) then return "failed" end
|
||||
|
||||
while ( path:IsValid() ) do
|
||||
|
||||
path:Update( self )
|
||||
|
||||
-- Draw the path (only visible on listen servers or single player)
|
||||
if ( options.draw ) then
|
||||
path:Draw()
|
||||
end
|
||||
|
||||
-- If we're stuck then call the HandleStuck function and abandon
|
||||
if ( self.loco:IsStuck() ) then
|
||||
|
||||
self:HandleStuck()
|
||||
|
||||
return "stuck"
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- If they set maxage on options then make sure the path is younger than it
|
||||
--
|
||||
if ( options.maxage ) then
|
||||
if ( path:GetAge() > options.maxage ) then return "timeout" end
|
||||
end
|
||||
|
||||
--
|
||||
-- If they set repath then rebuild the path every x seconds
|
||||
--
|
||||
if ( options.repath ) then
|
||||
if ( path:GetAge() > options.repath ) then path:Compute( self, pos ) end
|
||||
end
|
||||
|
||||
coroutine.yield()
|
||||
|
||||
end
|
||||
|
||||
return "ok"
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Name: NextBot:PlaySequenceAndWait
|
||||
-- Desc: To be called in the behaviour coroutine only! Plays an animation sequence and waits for it to end before returning.
|
||||
-- Arg1: string|name|The sequence name
|
||||
-- Arg2: number|the speed (default 1)
|
||||
-- Ret1:
|
||||
--
|
||||
function ENT:PlaySequenceAndWait( name, speed )
|
||||
|
||||
local len = self:SetSequence( name )
|
||||
speed = speed or 1
|
||||
|
||||
self:ResetSequenceInfo()
|
||||
self:SetCycle( 0 )
|
||||
self:SetPlaybackRate( speed )
|
||||
|
||||
-- wait for it to finish
|
||||
coroutine.wait( len / speed )
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Name: NEXTBOT:Use
|
||||
-- Desc: Called when a player 'uses' the entity
|
||||
-- Arg1: entity|activator|The entity that activated the use
|
||||
-- Arg2: entity|called|The entity that called the use
|
||||
-- Arg3: number|type|The type of use (USE_ON, USE_OFF, USE_TOGGLE, USE_SET)
|
||||
-- Arg4: number|value|Any passed value
|
||||
-- Ret1:
|
||||
--
|
||||
function ENT:Use( activator, caller, type, value )
|
||||
end
|
||||
|
||||
--
|
||||
-- Name: NEXTBOT:Think
|
||||
-- Desc: Called periodically
|
||||
-- Arg1:
|
||||
-- Ret1:
|
||||
--
|
||||
function ENT:Think()
|
||||
end
|
||||
|
||||
--
|
||||
-- Name: NEXTBOT:HandleAnimEvent
|
||||
-- Desc: Called for serverside events
|
||||
--
|
||||
function ENT:HandleAnimEvent( event, eventtime, cycle, typee, options )
|
||||
end
|
||||
|
||||
--
|
||||
-- Name: NEXTBOT:OnTraceAttack
|
||||
-- Desc: Called serverside when the nextbot is attacked
|
||||
--
|
||||
function ENT:OnTraceAttack( dmginfo, dir, trace )
|
||||
|
||||
hook.Run( "ScaleNPCDamage", self, trace.HitGroup, dmginfo )
|
||||
|
||||
end
|
||||
|
||||
-- Called when we see a player or another nextbot
|
||||
function ENT:OnEntitySight( subject )
|
||||
end
|
||||
|
||||
-- Called when we see lose sight of a player or a nextbot we saw earlier
|
||||
function ENT:OnEntitySightLost( subject )
|
||||
end
|
||||
45
gamemodes/cod_custom/entities/entities/base_point.lua
Normal file
45
gamemodes/cod_custom/entities/entities/base_point.lua
Normal file
@@ -0,0 +1,45 @@
|
||||
|
||||
ENT.Base = "base_entity"
|
||||
ENT.Type = "point"
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: Initialize
|
||||
Desc: First function called. Use to set up your entity
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:Initialize()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: KeyValue
|
||||
Desc: Called when a keyvalue is added to us
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:KeyValue( key, value )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: Think
|
||||
Desc: Entity's think function.
|
||||
-----------------------------------------------------------]]
|
||||
function ENT:Think()
|
||||
end
|
||||
|
||||
--
|
||||
-- Name: OnRemove
|
||||
-- Desc: Called just before entity is deleted
|
||||
--
|
||||
function ENT:OnRemove()
|
||||
end
|
||||
|
||||
--
|
||||
-- UpdateTransmitState
|
||||
--
|
||||
function ENT:UpdateTransmitState()
|
||||
|
||||
--
|
||||
-- The default behaviour for point entities is to not be networked.
|
||||
-- If you're deriving an entity and want it to appear clientside, override this
|
||||
-- TRANSMIT_ALWAYS = always send, TRANSMIT_PVS = send if in PVS
|
||||
--
|
||||
return TRANSMIT_NEVER
|
||||
|
||||
end
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
-- This is just a simple point entity.
|
||||
|
||||
-- We only use it to represent the position and angle of a spawn point
|
||||
-- So we don't have to do anything here because the baseclass will
|
||||
-- take care of the basics
|
||||
|
||||
-- This file only exists so that the entity is created
|
||||
|
||||
ENT.Type = "point"
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
-- This is just a simple point entity.
|
||||
|
||||
-- We only use it to represent the position and angle of a spawn point
|
||||
-- So we don't have to do anything here because the baseclass will
|
||||
-- take care of the basics
|
||||
|
||||
-- This file only exists so that the entity is created
|
||||
|
||||
ENT.Type = "point"
|
||||
10
gamemodes/cod_custom/entities/entities/dys_spawn_point.lua
Normal file
10
gamemodes/cod_custom/entities/entities/dys_spawn_point.lua
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
-- This is just a simple point entity.
|
||||
|
||||
-- We only use it to represent the position and angle of a spawn point
|
||||
-- So we don't have to do anything here because the baseclass will
|
||||
-- take care of the basics
|
||||
|
||||
-- This file only exists so that the entity is created
|
||||
|
||||
ENT.Type = "point"
|
||||
135
gamemodes/cod_custom/entities/entities/env_skypaint.lua
Normal file
135
gamemodes/cod_custom/entities/entities/env_skypaint.lua
Normal file
@@ -0,0 +1,135 @@
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
ENT.Type = "point"
|
||||
ENT.DisableDuplicator = true
|
||||
|
||||
--
|
||||
-- Make this entity always networked
|
||||
--
|
||||
function ENT:UpdateTransmitState() return TRANSMIT_ALWAYS end
|
||||
|
||||
--
|
||||
-- Networked / Saved Data
|
||||
--
|
||||
function ENT:SetupDataTables()
|
||||
|
||||
self:NetworkVar( "Vector", 0, "TopColor", { KeyName = "topcolor", Edit = { type = "VectorColor", category = "Main", order = 1 } } )
|
||||
self:NetworkVar( "Vector", 1, "BottomColor", { KeyName = "bottomcolor", Edit = { type = "VectorColor", category = "Main", title = "Color Bottom", order = 2 } } )
|
||||
self:NetworkVar( "Float", 0, "FadeBias", { KeyName = "fadebias", Edit = { type = "Float", category = "Main", min = 0, max = 1, order = 3 } } )
|
||||
|
||||
self:NetworkVar( "Float", 4, "SunSize", { KeyName = "sunsize", Edit = { type = "Float", min = 0, max = 10, category = "Sun" } } )
|
||||
self:NetworkVar( "Vector", 2, "SunNormal", { KeyName = "sunnormal" } ) -- No editing this - it's for coders only
|
||||
self:NetworkVar( "Vector", 3, "SunColor", { KeyName = "suncolor", Edit = { type = "VectorColor", category = "Sun" } } )
|
||||
|
||||
self:NetworkVar( "Float", 2, "DuskScale", { KeyName = "duskscale", Edit = { type = "Float", min = 0, max = 1, category = "Dusk" } } )
|
||||
self:NetworkVar( "Float", 3, "DuskIntensity", { KeyName = "duskintensity", Edit = { type = "Float", min = 0, max = 10, category = "Dusk" } } )
|
||||
self:NetworkVar( "Vector", 4, "DuskColor", { KeyName = "duskcolor", Edit = { type = "VectorColor", category = "Dusk" } } )
|
||||
|
||||
self:NetworkVar( "Bool", 0, "DrawStars", { KeyName = "drawstars", Edit = { type = "Boolean", category = "Stars", order = 10 } } )
|
||||
self:NetworkVar( "String", 0, "StarTexture", { KeyName = "startexture", Edit = { type = "Texture", group = "Stars", category = "Stars", order = 11 } } )
|
||||
|
||||
self:NetworkVar( "Int", 0, "StarLayers", { KeyName = "starlayers", Edit = { type = "Int", min = 1, max = 3, category = "Stars", order = 12 } } )
|
||||
self:NetworkVarElement( "Angle", 0, 'p', "StarScale", { KeyName = "starscale", Edit = { type = "Float", min = 0, max = 5, category = "Stars", order = 13 } } )
|
||||
self:NetworkVarElement( "Angle", 0, 'y', "StarFade", { KeyName = "starfade", Edit = { type = "Float", min = 0, max = 5, category = "Stars", order = 14 } } )
|
||||
self:NetworkVarElement( "Angle", 0, 'r', "StarSpeed", { KeyName = "starspeed", Edit = { type = "Float", min = 0, max = 2, category = "Stars", order = 15 } } )
|
||||
|
||||
self:NetworkVar( "Float", 1, "HDRScale", { KeyName = "hdrscale", Edit = { type = "Float", category = "Main", min = 0, max = 1, order = 4 } } )
|
||||
|
||||
--
|
||||
-- Entity defaults
|
||||
--
|
||||
if ( SERVER ) then
|
||||
|
||||
self:SetTopColor( Vector( 0.2, 0.5, 1.0 ) )
|
||||
self:SetBottomColor( Vector( 0.8, 1.0, 1.0 ) )
|
||||
self:SetFadeBias( 1 )
|
||||
|
||||
|
||||
self:SetSunNormal( Vector( 0.4, 0.0, 0.01 ) )
|
||||
self:SetSunColor( Vector( 0.2, 0.1, 0.0 ) )
|
||||
self:SetSunSize( 2.0 )
|
||||
|
||||
self:SetDuskColor( Vector( 1.0, 0.2, 0.0 ) )
|
||||
self:SetDuskScale( 1 )
|
||||
self:SetDuskIntensity( 1 )
|
||||
|
||||
self:SetDrawStars( true )
|
||||
self:SetStarLayers( 1 )
|
||||
self:SetStarSpeed( 0.01 )
|
||||
self:SetStarScale( 0.5 )
|
||||
self:SetStarFade( 1.5 )
|
||||
self:SetStarTexture( "skybox/starfield" )
|
||||
|
||||
self:SetHDRScale( 0.66 )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function ENT:Initialize()
|
||||
end
|
||||
|
||||
function ENT:KeyValue( key, value )
|
||||
|
||||
if ( self:SetNetworkKeyValue( key, value ) ) then
|
||||
return
|
||||
end
|
||||
|
||||
-- TODO: sunposmethod
|
||||
-- 0 : "Custom - Use the Sun Normal to position the sun"
|
||||
-- 1 : "Automatic - Find a env_sun entity and use that"
|
||||
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
|
||||
--
|
||||
-- Find an env_sun - if we don't already have one.
|
||||
--
|
||||
if ( SERVER && self.EnvSun == nil ) then
|
||||
|
||||
-- so this closure only gets called once - even if it fails
|
||||
self.EnvSun = false
|
||||
|
||||
local list = ents.FindByClass( "env_sun" )
|
||||
if ( #list > 0 ) then
|
||||
self.EnvSun = list[1]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- If we have a sun - force our sun normal to its value
|
||||
--
|
||||
if ( SERVER && IsValid( self.EnvSun ) ) then
|
||||
|
||||
local vec = self.EnvSun:GetInternalVariable( "m_vDirection" )
|
||||
|
||||
if ( isvector( vec ) ) then
|
||||
self:SetSunNormal( vec )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Become the active sky again if we're not already
|
||||
--
|
||||
if ( CLIENT && g_SkyPaint != self ) then
|
||||
|
||||
if ( !IsValid( g_SkyPaint ) ) then
|
||||
g_SkyPaint = self
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- To prevent server insanity - only let admins edit the sky.
|
||||
--
|
||||
function ENT:CanEditVariables( ply )
|
||||
|
||||
return ply:IsAdmin()
|
||||
|
||||
end
|
||||
67
gamemodes/cod_custom/entities/entities/gmod_hands.lua
Normal file
67
gamemodes/cod_custom/entities/entities/gmod_hands.lua
Normal file
@@ -0,0 +1,67 @@
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
ENT.Type = "anim"
|
||||
ENT.RenderGroup = RENDERGROUP_OTHER
|
||||
|
||||
function ENT:Initialize()
|
||||
|
||||
hook.Add( "OnViewModelChanged", self, self.ViewModelChanged )
|
||||
|
||||
self:SetNotSolid( true )
|
||||
self:DrawShadow( false )
|
||||
self:SetTransmitWithParent( true ) -- Transmit only when the viewmodel does!
|
||||
|
||||
end
|
||||
|
||||
function ENT:DoSetup( ply, spec )
|
||||
|
||||
-- Set these hands to the player
|
||||
ply:SetHands( self )
|
||||
self:SetOwner( ply )
|
||||
|
||||
-- Which hands should we use? Let the gamemode decide
|
||||
hook.Call( "PlayerSetHandsModel", GAMEMODE, spec or ply, self )
|
||||
|
||||
-- Attach them to the viewmodel
|
||||
local vm = ( spec or ply ):GetViewModel( 0 )
|
||||
self:AttachToViewmodel( vm )
|
||||
|
||||
vm:DeleteOnRemove( self )
|
||||
ply:DeleteOnRemove( self )
|
||||
|
||||
end
|
||||
|
||||
function ENT:GetPlayerColor()
|
||||
|
||||
--
|
||||
-- Make sure there's an owner and they have this function
|
||||
-- before trying to call it!
|
||||
--
|
||||
local owner = self:GetOwner()
|
||||
if ( !IsValid( owner ) ) then return end
|
||||
if ( !owner.GetPlayerColor ) then return end
|
||||
|
||||
return owner:GetPlayerColor()
|
||||
|
||||
end
|
||||
|
||||
function ENT:ViewModelChanged( vm, old, new )
|
||||
|
||||
-- Ignore other peoples viewmodel changes!
|
||||
if ( vm:GetOwner() != self:GetOwner() ) then return end
|
||||
|
||||
self:AttachToViewmodel( vm )
|
||||
|
||||
end
|
||||
|
||||
function ENT:AttachToViewmodel( vm )
|
||||
|
||||
self:AddEffects( EF_BONEMERGE )
|
||||
self:SetParent( vm )
|
||||
self:SetMoveType( MOVETYPE_NONE )
|
||||
|
||||
self:SetPos( vector_origin )
|
||||
self:SetAngles( angle_zero )
|
||||
|
||||
end
|
||||
81
gamemodes/cod_custom/entities/entities/gmod_player_start.lua
Normal file
81
gamemodes/cod_custom/entities/entities/gmod_player_start.lua
Normal file
@@ -0,0 +1,81 @@
|
||||
|
||||
-- This is just a simple point entity.
|
||||
|
||||
-- We only use it to represent the position and angle of a spawn point
|
||||
-- So we don't have to do anything here because the baseclass will
|
||||
-- take care of the basics
|
||||
|
||||
-- This file only exists so that the entity is created
|
||||
|
||||
ENT.Type = "point"
|
||||
|
||||
function ENT:Initialize()
|
||||
|
||||
if ( self.RedTeam or self.GreenTeam or self.YellowTeam or self.BlueTeam ) then
|
||||
|
||||
-- If any of these are set to true then
|
||||
-- make sure that any that aren't setup are
|
||||
-- set to false.
|
||||
|
||||
self.BlueTeam = self.BlueTeam or false
|
||||
self.GreenTeam = self.GreenTeam or false
|
||||
self.YellowTeam = self.YellowTeam or false
|
||||
self.RedTeam = self.RedTeam or false
|
||||
|
||||
else
|
||||
|
||||
-- If none are set then make it so that they all
|
||||
-- are set to true since any team can spawn here.
|
||||
-- This will also happen if we don't have the "spawnflags"
|
||||
-- keyvalue setup.
|
||||
|
||||
self.BlueTeam = true
|
||||
self.GreenTeam = true
|
||||
self.YellowTeam = true
|
||||
self.RedTeam = true
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function ENT:KeyValue( key, value )
|
||||
|
||||
if ( key == "spawnflags" ) then
|
||||
|
||||
local sf = tonumber( value )
|
||||
|
||||
for i = 15, 0, -1 do
|
||||
|
||||
local bit = math.pow( 2, i )
|
||||
|
||||
-- Quick bit if bitwise math to figure out if the spawnflags
|
||||
-- represent red/blue/green or yellow.
|
||||
-- We have to use booleans since the TEAM_ identifiers
|
||||
-- aren't setup at this point.
|
||||
-- (this would be easier if we had bitwise operators in Lua)
|
||||
|
||||
if ( ( sf - bit ) >= 0 ) then
|
||||
|
||||
if ( bit == 8 ) then self.RedTeam = true
|
||||
elseif ( bit == 4 ) then self.GreenTeam = true
|
||||
elseif ( bit == 2 ) then self.YellowTeam = true
|
||||
elseif ( bit == 1 ) then self.BlueTeam = true
|
||||
end
|
||||
|
||||
sf = sf - bit
|
||||
|
||||
else
|
||||
|
||||
if ( bit == 8 ) then self.RedTeam = false
|
||||
elseif ( bit == 4 ) then self.GreenTeam = false
|
||||
elseif ( bit == 2 ) then self.YellowTeam = false
|
||||
elseif ( bit == 1 ) then self.BlueTeam = false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
-- This is just a simple point entity.
|
||||
|
||||
-- We only use it to represent the position and angle of a spawn point
|
||||
-- So we don't have to do anything here because the baseclass will
|
||||
-- take care of the basics
|
||||
|
||||
-- This file only exists so that the entity is created
|
||||
|
||||
ENT.Type = "point"
|
||||
10
gamemodes/cod_custom/entities/entities/info_player_axis.lua
Normal file
10
gamemodes/cod_custom/entities/entities/info_player_axis.lua
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
-- This is just a simple point entity.
|
||||
|
||||
-- We only use it to represent the position and angle of a spawn point
|
||||
-- So we don't have to do anything here because the baseclass will
|
||||
-- take care of the basics
|
||||
|
||||
-- This file only exists so that the entity is created
|
||||
|
||||
ENT.Type = "point"
|
||||
10
gamemodes/cod_custom/entities/entities/info_player_blue.lua
Normal file
10
gamemodes/cod_custom/entities/entities/info_player_blue.lua
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
-- This is just a simple point entity.
|
||||
|
||||
-- We only use it to represent the position and angle of a spawn point
|
||||
-- So we don't have to do anything here because the baseclass will
|
||||
-- take care of the basics
|
||||
|
||||
-- This file only exists so that the entity is created
|
||||
|
||||
ENT.Type = "point"
|
||||
10
gamemodes/cod_custom/entities/entities/info_player_coop.lua
Normal file
10
gamemodes/cod_custom/entities/entities/info_player_coop.lua
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
-- This is just a simple point entity.
|
||||
|
||||
-- We only use it to represent the position and angle of a spawn point
|
||||
-- So we don't have to do anything here because the baseclass will
|
||||
-- take care of the basics
|
||||
|
||||
-- This file only exists so that the entity is created
|
||||
|
||||
ENT.Type = "point"
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
-- This is just a simple point entity.
|
||||
|
||||
-- We only use it to represent the position and angle of a spawn point
|
||||
-- So we don't have to do anything here because the baseclass will
|
||||
-- take care of the basics
|
||||
|
||||
-- This file only exists so that the entity is created
|
||||
|
||||
ENT.Type = "point"
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
-- This is just a simple point entity.
|
||||
|
||||
-- We only use it to represent the position and angle of a spawn point
|
||||
-- So we don't have to do anything here because the baseclass will
|
||||
-- take care of the basics
|
||||
|
||||
-- This file only exists so that the entity is created
|
||||
|
||||
ENT.Type = "point"
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
-- This is just a simple point entity.
|
||||
|
||||
-- We only use it to represent the position and angle of a spawn point
|
||||
-- So we don't have to do anything here because the baseclass will
|
||||
-- take care of the basics
|
||||
|
||||
-- This file only exists so that the entity is created
|
||||
|
||||
ENT.Type = "point"
|
||||
10
gamemodes/cod_custom/entities/entities/info_player_fof.lua
Normal file
10
gamemodes/cod_custom/entities/entities/info_player_fof.lua
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
-- This is just a simple point entity.
|
||||
|
||||
-- We only use it to represent the position and angle of a spawn point
|
||||
-- So we don't have to do anything here because the baseclass will
|
||||
-- take care of the basics
|
||||
|
||||
-- This file only exists so that the entity is created
|
||||
|
||||
ENT.Type = "point"
|
||||
10
gamemodes/cod_custom/entities/entities/info_player_human.lua
Normal file
10
gamemodes/cod_custom/entities/entities/info_player_human.lua
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
-- This is just a simple point entity.
|
||||
|
||||
-- We only use it to represent the position and angle of a spawn point
|
||||
-- So we don't have to do anything here because the baseclass will
|
||||
-- take care of the basics
|
||||
|
||||
-- This file only exists so that the entity is created
|
||||
|
||||
ENT.Type = "point"
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
-- This is just a simple point entity.
|
||||
|
||||
-- We only use it to represent the position and angle of a spawn point
|
||||
-- So we don't have to do anything here because the baseclass will
|
||||
-- take care of the basics
|
||||
|
||||
-- This file only exists so that the entity is created
|
||||
|
||||
ENT.Type = "point"
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
-- This is just a simple point entity.
|
||||
|
||||
-- We only use it to represent the position and angle of a spawn point
|
||||
-- So we don't have to do anything here because the baseclass will
|
||||
-- take care of the basics
|
||||
|
||||
-- This file only exists so that the entity is created
|
||||
|
||||
ENT.Type = "point"
|
||||
10
gamemodes/cod_custom/entities/entities/info_player_red.lua
Normal file
10
gamemodes/cod_custom/entities/entities/info_player_red.lua
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
-- This is just a simple point entity.
|
||||
|
||||
-- We only use it to represent the position and angle of a spawn point
|
||||
-- So we don't have to do anything here because the baseclass will
|
||||
-- take care of the basics
|
||||
|
||||
-- This file only exists so that the entity is created
|
||||
|
||||
ENT.Type = "point"
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
-- This is just a simple point entity.
|
||||
|
||||
-- We only use it to represent the position and angle of a spawn point
|
||||
-- So we don't have to do anything here because the baseclass will
|
||||
-- take care of the basics
|
||||
|
||||
-- This file only exists so that the entity is created
|
||||
|
||||
ENT.Type = "point"
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
-- This is just a simple point entity.
|
||||
|
||||
-- We only use it to represent the position and angle of a spawn point
|
||||
-- So we don't have to do anything here because the baseclass will
|
||||
-- take care of the basics
|
||||
|
||||
-- This file only exists so that the entity is created
|
||||
|
||||
ENT.Type = "point"
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
-- This is just a simple point entity.
|
||||
|
||||
-- We only use it to represent the position and angle of a spawn point
|
||||
-- So we don't have to do anything here because the baseclass will
|
||||
-- take care of the basics
|
||||
|
||||
-- This file only exists so that the entity is created
|
||||
|
||||
ENT.Type = "point"
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
-- This is just a simple point entity.
|
||||
|
||||
-- We only use it to represent the position and angle of a spawn point
|
||||
-- So we don't have to do anything here because the baseclass will
|
||||
-- take care of the basics
|
||||
|
||||
-- This file only exists so that the entity is created
|
||||
|
||||
ENT.Type = "point"
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
-- This is just a simple point entity.
|
||||
|
||||
-- We only use it to represent the position and angle of a spawn point
|
||||
-- So we don't have to do anything here because the baseclass will
|
||||
-- take care of the basics
|
||||
|
||||
-- This file only exists so that the entity is created
|
||||
|
||||
ENT.Type = "point"
|
||||
10
gamemodes/cod_custom/entities/entities/info_spawnpoint.lua
Normal file
10
gamemodes/cod_custom/entities/entities/info_spawnpoint.lua
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
-- This is just a simple point entity.
|
||||
|
||||
-- We only use it to represent the position and angle of a spawn point
|
||||
-- So we don't have to do anything here because the baseclass will
|
||||
-- take care of the basics
|
||||
|
||||
-- This file only exists so that the entity is created
|
||||
|
||||
ENT.Type = "point"
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
-- This is just a simple point entity.
|
||||
|
||||
-- We only use it to represent the position and angle of a spawn point
|
||||
-- So we don't have to do anything here because the baseclass will
|
||||
-- take care of the basics
|
||||
|
||||
-- This file only exists so that the entity is created
|
||||
|
||||
ENT.Type = "point"
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
-- This is just a simple point entity.
|
||||
|
||||
-- We only use it to represent the position and angle of a spawn point
|
||||
-- So we don't have to do anything here because the baseclass will
|
||||
-- take care of the basics
|
||||
|
||||
-- This file only exists so that the entity is created
|
||||
|
||||
ENT.Type = "point"
|
||||
10
gamemodes/cod_custom/entities/entities/ins_spawnpoint.lua
Normal file
10
gamemodes/cod_custom/entities/entities/ins_spawnpoint.lua
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
-- This is just a simple point entity.
|
||||
|
||||
-- We only use it to represent the position and angle of a spawn point
|
||||
-- So we don't have to do anything here because the baseclass will
|
||||
-- take care of the basics
|
||||
|
||||
-- This file only exists so that the entity is created
|
||||
|
||||
ENT.Type = "point"
|
||||
63
gamemodes/cod_custom/entities/entities/lua_run.lua
Normal file
63
gamemodes/cod_custom/entities/entities/lua_run.lua
Normal file
@@ -0,0 +1,63 @@
|
||||
|
||||
-- A spawnflag constant for addons
|
||||
SF_LUA_RUN_ON_SPAWN = 1
|
||||
|
||||
ENT.Type = "point"
|
||||
ENT.DisableDuplicator = true
|
||||
|
||||
AccessorFunc( ENT, "m_bDefaultCode", "DefaultCode" )
|
||||
|
||||
function ENT:Initialize()
|
||||
|
||||
-- If the entity has its first spawnflag set, run the code automatically
|
||||
if ( self:HasSpawnFlags( SF_LUA_RUN_ON_SPAWN ) ) then
|
||||
self:RunCode( self, self, self:GetDefaultCode() )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function ENT:KeyValue( key, value )
|
||||
|
||||
if ( key == "Code" ) then
|
||||
self:SetDefaultCode( value )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function ENT:SetupGlobals( activator, caller )
|
||||
|
||||
ACTIVATOR = activator
|
||||
CALLER = caller
|
||||
|
||||
if ( IsValid( activator ) && activator:IsPlayer() ) then
|
||||
TRIGGER_PLAYER = activator
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function ENT:KillGlobals()
|
||||
|
||||
ACTIVATOR = nil
|
||||
CALLER = nil
|
||||
TRIGGER_PLAYER = nil
|
||||
|
||||
end
|
||||
|
||||
function ENT:RunCode( activator, caller, code )
|
||||
|
||||
self:SetupGlobals( activator, caller )
|
||||
|
||||
RunString( code, "lua_run#" .. self:EntIndex() )
|
||||
|
||||
self:KillGlobals()
|
||||
|
||||
end
|
||||
|
||||
function ENT:AcceptInput( name, activator, caller, data )
|
||||
|
||||
if ( name == "RunCode" ) then self:RunCode( activator, caller, self:GetDefaultCode() ) return true end
|
||||
if ( name == "RunPassedCode" ) then self:RunCode( activator, caller, data ) return true end
|
||||
|
||||
return false
|
||||
|
||||
end
|
||||
267
gamemodes/cod_custom/entities/entities/mwii_down_npc/shared.lua
Normal file
267
gamemodes/cod_custom/entities/entities/mwii_down_npc/shared.lua
Normal file
@@ -0,0 +1,267 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.Type = "anim"
|
||||
ENT.AutomaticFrameAdvance = true
|
||||
|
||||
if SERVER then
|
||||
local function TransferModelData(ent, from)
|
||||
local ent1Model = from:GetModel()
|
||||
local ent1Skin = from:GetSkin()
|
||||
local ent1BodyGroups = from:GetNumBodyGroups()
|
||||
ent:SetModel(ent1Model)
|
||||
ent:SetSkin(ent1Skin)
|
||||
for i = 0, ent1BodyGroups - 1 do
|
||||
ent:SetBodygroup(i, from:GetBodygroup(i))
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:CrawlBack(go)
|
||||
local tr = util.TraceLine({
|
||||
start = self:GetBonePosition(self:LookupBone("ValveBiped.Bip01_Head1")),
|
||||
endpos = self:GetBonePosition(self:LookupBone("ValveBiped.Bip01_Head1"))-self:GetForward()*4,
|
||||
filter = function( ent ) if ent != self.NPC then return true end end
|
||||
})
|
||||
local tr2 = util.TraceLine({
|
||||
start = self:GetBonePosition(self:LookupBone("ValveBiped.Bip01_Spine")),
|
||||
endpos = self:GetBonePosition(self:LookupBone("ValveBiped.Bip01_Spine"))-Vector(0,0,8),
|
||||
filter = function( ent ) if ent != self.NPC then return true end end
|
||||
})
|
||||
local tr3 = util.TraceLine({
|
||||
start = self:GetBonePosition(self:LookupBone("ValveBiped.Bip01_Spine")),
|
||||
endpos = self:GetBonePosition(self:LookupBone("ValveBiped.Bip01_Spine"))-Vector(0,0,4),
|
||||
filter = function( ent ) if ent != self.NPC then return true end end
|
||||
})
|
||||
if tr3.Hit then
|
||||
self:SetPos(self:GetPos()+Vector(0,0,1))
|
||||
end
|
||||
if not tr2.Hit then
|
||||
self:SetPos(self:GetPos()-Vector(0,0,1))
|
||||
end
|
||||
local anim = "laststand_crawl_backward"
|
||||
if go then
|
||||
if self.CanShoot then
|
||||
anim = anim.."_wep"
|
||||
end
|
||||
if not tr.Hit then
|
||||
self:SetPos(self:GetPos()-self:GetForward()*0.3)
|
||||
self:SetSequence(anim)
|
||||
else
|
||||
anim = "laststand_idle"
|
||||
if self.CanShoot then
|
||||
anim = anim.."_wep"
|
||||
end
|
||||
self:SetSequence(anim)
|
||||
end
|
||||
else
|
||||
anim = "laststand_idle"
|
||||
if self.CanShoot then
|
||||
anim = anim.."_wep"
|
||||
end
|
||||
self:SetSequence(anim)
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/player/barney.mdl")
|
||||
self:ResetSequence("laststand_down")
|
||||
self:SetNoDraw(true)
|
||||
self:DrawShadow(false)
|
||||
self.Reviving = false
|
||||
self.TimeBeforeReviving = CurTime() + math.random(5,15)
|
||||
self.NPC:SetNoDraw(true)
|
||||
self.NPC.CantDamageMWII = true
|
||||
self:SetNWFloat("DTeam", self.NPC.Team)
|
||||
local wep = self.NPC:GetActiveWeapon()
|
||||
if IsValid(wep) then
|
||||
wep:SetClip1(0)
|
||||
end
|
||||
|
||||
local tar = self.NPC
|
||||
timer.Simple(0.5, function()
|
||||
if !IsValid(tar) then return end
|
||||
tar.CantDamageMWII = false
|
||||
end)
|
||||
timer.Simple(1.5, function()
|
||||
if !IsValid(self) then return end
|
||||
self.Ready = true
|
||||
|
||||
self:ResetSequence("laststand_idle_wep")
|
||||
self.ShootDelay = CurTime() + 1
|
||||
self.TimeBeforeReviving = CurTime() + math.random(10,20)
|
||||
self.CanShoot = true
|
||||
|
||||
local bd = ents.Create("base_anim")
|
||||
bd:SetModel("models/weapons/w_pistol.mdl")
|
||||
bd:SetParent(self)
|
||||
bd:AddEffects(1)
|
||||
bd:Spawn()
|
||||
self:DeleteOnRemove(bd)
|
||||
|
||||
timer.Simple(20, function()
|
||||
if !IsValid(self) then return end
|
||||
self.NPC:SetHealth(1)
|
||||
self.NPC:TakeDamage(self.NPC:Health())
|
||||
self.NPC:TakeDamage(999999999)
|
||||
end)
|
||||
end)
|
||||
|
||||
local bd = ents.Create("base_anim")
|
||||
bd:SetParent(self)
|
||||
bd:AddEffects(1)
|
||||
bd:Spawn()
|
||||
self.bd = bd
|
||||
TransferModelData(bd, self.NPC)
|
||||
self:DeleteOnRemove(bd)
|
||||
end
|
||||
|
||||
function ENT:Revive(fast)
|
||||
local ow = self.NPC
|
||||
self.Reviving = true
|
||||
self:SetCycle(0)
|
||||
if not fast then
|
||||
self:ResetSequence("laststand_selfrevive")
|
||||
timer.Simple(5, function()
|
||||
if !IsValid(self) then return end
|
||||
|
||||
self:SetCycle(0)
|
||||
self:ResetSequence("laststand_standup")
|
||||
end)
|
||||
timer.Simple(6, function()
|
||||
if !IsValid(ow) then return end
|
||||
|
||||
self.NPC = nil
|
||||
ow:ManipulateBonePosition(ow:LookupBone("ValveBiped.Bip01_Pelvis"), Vector(0, 0, 0))
|
||||
ow:ManipulateBoneAngles(ow:LookupBone("ValveBiped.Bip01_Pelvis"), Angle(0, 0, 0))
|
||||
ow:SetNoDraw(false)
|
||||
ow:SetRenderMode(RENDERMODE_NORMAL)
|
||||
ow:DrawShadow(true)
|
||||
ow.Downed = false
|
||||
ow:RemoveEFlags(EFL_NO_THINK_FUNCTION)
|
||||
local wep = ow:GetActiveWeapon()
|
||||
if IsValid(wep) then
|
||||
wep:SetNoDraw(false)
|
||||
end
|
||||
ow:SetNWEntity('MWIIRag', NULL)
|
||||
end)
|
||||
else
|
||||
self:ResetSequence("laststand_standup")
|
||||
timer.Simple(1, function()
|
||||
if !IsValid(ow) then return end
|
||||
|
||||
self.NPC = nil
|
||||
ow:ManipulateBonePosition(ow:LookupBone("ValveBiped.Bip01_Pelvis"), Vector(0, 0, 0))
|
||||
ow:ManipulateBoneAngles(ow:LookupBone("ValveBiped.Bip01_Pelvis"), Angle(0, 0, 0))
|
||||
ow:SetNoDraw(false)
|
||||
ow:SetRenderMode(RENDERMODE_NORMAL)
|
||||
ow:DrawShadow(true)
|
||||
ow.Downed = false
|
||||
ow:RemoveEFlags(EFL_NO_THINK_FUNCTION)
|
||||
local wep = ow:GetActiveWeapon()
|
||||
if IsValid(wep) then
|
||||
wep:SetNoDraw(false)
|
||||
end
|
||||
ow:SetNWEntity('MWIIRag', NULL)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:AngleToEnemy(enemy)
|
||||
local selfAngles = self:GetAngles()
|
||||
local enemyPos = enemy:GetPos()
|
||||
local angleToEnemy = (enemyPos - self:GetPos()):Angle()
|
||||
angleToEnemy.x = 0
|
||||
angleToEnemy.z = 0
|
||||
local diff = math.AngleDifference(angleToEnemy.y, selfAngles.y)
|
||||
return math.abs(diff)
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
local ow = self.NPC
|
||||
if !IsValid(ow) or ow:Health() <= 0 or ow.Takedowning then
|
||||
self:Remove()
|
||||
else
|
||||
ow:SetNoDraw(true)
|
||||
ow:SetRenderMode(RENDERMODE_NONE)
|
||||
ow.AlreadyWasDowned = true
|
||||
ow:DrawShadow(false)
|
||||
if ow.IsVJBaseSNPC then
|
||||
ow.HasDeathAnimation = false
|
||||
end
|
||||
ow:AddEFlags(EFL_NO_THINK_FUNCTION)
|
||||
ow:SetNWEntity('MWIIRag', self.bd)
|
||||
ow:ManipulateBonePosition(ow:LookupBone("ValveBiped.Bip01_Pelvis"), Vector(0, 0, -20))
|
||||
ow:ManipulateBoneAngles(ow:LookupBone("ValveBiped.Bip01_Pelvis"), Angle(0, 0, -90))
|
||||
local wep = ow:GetActiveWeapon()
|
||||
if IsValid(wep) then
|
||||
wep:SetNoDraw(true)
|
||||
end
|
||||
|
||||
local att = self.Finisher
|
||||
|
||||
if not self.Reviving then
|
||||
local near, dist = nil, math.huge
|
||||
for _, ent in ipairs(ents.FindInSphere(self:GetPos(), 2048)) do
|
||||
if (ent:IsPlayer() and !GetConVar("ai_ignoreplayers"):GetBool() or ent.IsMWIINPC and ent:IsMWIINPC()) and !ow:MWIIsFriend(ent, true) and ent:Health() > 0 and ow:Visible(ent) then
|
||||
local dis = ent:GetPos():DistToSqr(self:GetPos())
|
||||
if dis < dist then
|
||||
near = ent
|
||||
dist = dis
|
||||
end
|
||||
end
|
||||
end
|
||||
if IsValid(near) then
|
||||
local sang = self:GetAngles()
|
||||
local direction = (near:GetPos()-self:GetPos()):GetNormalized():Angle()
|
||||
direction.x = 0
|
||||
direction.z = 0
|
||||
local add, notadd = (direction.y-sang.y)/50, (direction.y-sang.y)/20
|
||||
local add2 = math.AngleDifference( direction.y, sang.y )
|
||||
local adding = sang+(Angle(0,add2/50,0))
|
||||
self:SetAngles(adding)
|
||||
ow:SetAngles(self:GetAngles())
|
||||
ow:SetPos(self:GetPos())
|
||||
|
||||
if self.Ready and (IsValid(ow.TargetReviver) and not ow.TargetReviver.InSeqMWII or !IsValid(ow.TargetReviver)) then
|
||||
self:CrawlBack(dist < 200000 and self:AngleToEnemy(near) < 30)
|
||||
else
|
||||
if self.Ready then
|
||||
self:CrawlBack(false)
|
||||
end
|
||||
end
|
||||
|
||||
if self.CanShoot and self.ShootDelay < CurTime() and self:AngleToEnemy(near) < 15 then
|
||||
self.ShootDelay = CurTime() + math.Rand(0.2,2)
|
||||
ow:EmitSound("weapons/pistol/pistol_fire3.wav", 90, math.random(90,110), 1, CHAN_WEAPON)
|
||||
ow:FireBullets({
|
||||
Damage = 10,
|
||||
Spread = VectorRand(0.00, 0.20),
|
||||
Dir = (near:GetPos()-self:EyePos()):GetNormalized(),
|
||||
Src = self:GetBonePosition(self:LookupBone("ValveBiped.Bip01_R_Hand")),
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
self:SetNoDraw(true)
|
||||
self:DrawShadow(false)
|
||||
self:NextThink(CurTime())
|
||||
return true
|
||||
end
|
||||
else
|
||||
local tm_mat = Material('tdmg/hud/teammate.png')
|
||||
function ENT:Draw()
|
||||
if self:GetNWFloat('DTeam') == LocalPlayer():Team() then
|
||||
local angle = EyeAngles()
|
||||
angle = Angle( 0, angle.y, 0 )
|
||||
angle:RotateAroundAxis( angle:Up(), -90 )
|
||||
angle:RotateAroundAxis( angle:Forward(), 90 )
|
||||
local pos = self:GetBonePosition(LocalPlayer():LookupBone("ValveBiped.Bip01_Head1"))+Vector(0,0,16)
|
||||
cam.Start3D2D( pos, angle, 0.1 )
|
||||
surface.SetDrawColor(5,155,255)
|
||||
surface.SetMaterial(tm_mat)
|
||||
surface.DrawTexturedRect(-12, -12, 24, 24)
|
||||
cam.End3D2D()
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,126 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.Type = "anim"
|
||||
ENT.AutomaticFrameAdvance = true
|
||||
|
||||
if SERVER then
|
||||
local function TransferModelData(ent, from)
|
||||
local ent1Model = from:GetModel()
|
||||
local ent1Skin = from:GetSkin()
|
||||
local ent1BodyGroups = from:GetNumBodyGroups()
|
||||
ent:SetModel(ent1Model)
|
||||
ent:SetSkin(ent1Skin)
|
||||
for i = 0, ent1BodyGroups - 1 do
|
||||
ent:SetBodygroup(i, from:GetBodygroup(i))
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/player/barney.mdl")
|
||||
self:SetNoDraw(true)
|
||||
self:DrawShadow(false)
|
||||
self.NPC:SetNoDraw(true)
|
||||
self:SetNWFloat('DTeam', self.NPC.Team)
|
||||
self.NPC.InSeqMWII = true
|
||||
|
||||
if IsValid(self.Target) then
|
||||
self.HaveTarget = true
|
||||
end
|
||||
|
||||
local anim = ""
|
||||
if self.Sequence == "revive" then
|
||||
anim = "laststand_startrevive"
|
||||
timer.Simple(4, function()
|
||||
if IsValid(self) then
|
||||
local tar = self.Target
|
||||
if !IsValid(tar) then return end
|
||||
if tar:IsPlayer() then
|
||||
tar:Revive()
|
||||
else
|
||||
if !IsValid(tar.DownedEnt) then return end
|
||||
tar.DownedEnt:Revive(true)
|
||||
end
|
||||
end
|
||||
end)
|
||||
timer.Simple(5, function()
|
||||
if IsValid(self) then
|
||||
self:Stop()
|
||||
local tar = self.Target
|
||||
if !IsValid(tar) then return end
|
||||
tar.TargetReviver = nil
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
self:ResetSequence(anim)
|
||||
|
||||
local bd = ents.Create("base_anim")
|
||||
bd:SetParent(self)
|
||||
bd:AddEffects(1)
|
||||
bd:Spawn()
|
||||
self.bd = bd
|
||||
TransferModelData(bd, self.NPC)
|
||||
self:DeleteOnRemove(bd)
|
||||
end
|
||||
|
||||
function ENT:Stop()
|
||||
local ow = self.NPC
|
||||
|
||||
if !IsValid(ow) then return end
|
||||
|
||||
self.NPC = nil
|
||||
ow:SetNoDraw(false)
|
||||
ow:SetRenderMode(RENDERMODE_NORMAL)
|
||||
ow:DrawShadow(true)
|
||||
ow:RemoveEFlags(EFL_NO_THINK_FUNCTION)
|
||||
ow.InSeqMWII = false
|
||||
local wep = ow:GetActiveWeapon()
|
||||
if IsValid(wep) then
|
||||
wep:SetNoDraw(false)
|
||||
end
|
||||
ow:SetNWEntity('MWIIRag', NULL)
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
local ow = self.NPC
|
||||
|
||||
if !IsValid(ow) or ow:Health() <= 0 or ow.Takedowning or ow.Downed or self.HaveTarget and !IsValid(self.Target) then
|
||||
self:Stop()
|
||||
self:Remove()
|
||||
else
|
||||
ow:SetNoDraw(true)
|
||||
ow:SetRenderMode(RENDERMODE_NONE)
|
||||
ow:DrawShadow(false)
|
||||
if ow.IsVJBaseSNPC then
|
||||
ow.HasDeathAnimation = false
|
||||
end
|
||||
ow:AddEFlags(EFL_NO_THINK_FUNCTION)
|
||||
ow:SetNWEntity('MWIIRag', self.bd)
|
||||
local wep = ow:GetActiveWeapon()
|
||||
if IsValid(wep) then
|
||||
wep:SetNoDraw(true)
|
||||
end
|
||||
end
|
||||
self:SetNoDraw(true)
|
||||
self:DrawShadow(false)
|
||||
self:NextThink(CurTime())
|
||||
return true
|
||||
end
|
||||
else
|
||||
local tm_mat = Material('tdmg/hud/teammate.png')
|
||||
function ENT:Draw()
|
||||
if self:GetNWFloat('DTeam') == LocalPlayer():Team() then
|
||||
local angle = EyeAngles()
|
||||
angle = Angle( 0, angle.y, 0 )
|
||||
angle:RotateAroundAxis( angle:Up(), -90 )
|
||||
angle:RotateAroundAxis( angle:Forward(), 90 )
|
||||
local pos = self:GetBonePosition(LocalPlayer():LookupBone("ValveBiped.Bip01_Head1"))+Vector(0,0,16)
|
||||
cam.Start3D2D( pos, angle, 0.1 )
|
||||
surface.SetDrawColor(5,155,255)
|
||||
surface.SetMaterial(tm_mat)
|
||||
surface.DrawTexturedRect(-12, -12, 24, 24)
|
||||
cam.End3D2D()
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,160 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.Type = "anim"
|
||||
ENT.AutomaticFrameAdvance = true
|
||||
|
||||
if SERVER then
|
||||
local function TransferModelData(ent, from)
|
||||
local ent1Model = from:GetModel()
|
||||
local ent1Skin = from:GetSkin()
|
||||
local ent1BodyGroups = from:GetNumBodyGroups()
|
||||
ent:SetModel(ent1Model)
|
||||
ent:SetSkin(ent1Skin)
|
||||
for i = 0, ent1BodyGroups - 1 do
|
||||
ent:SetBodygroup(i, from:GetBodygroup(i))
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/player/breen.mdl")
|
||||
self.Takedowning = true
|
||||
self:ResetSequence(self.Sequence)
|
||||
self:SetNoDraw(true)
|
||||
self:DrawShadow(false)
|
||||
local delay = select(2, self:LookupSequence(self.Sequence))
|
||||
self:SetCycle( ( ( (delay-0.1)/delay )-1)*-1 )
|
||||
if self.AttackerTime then
|
||||
self.Attacker = true
|
||||
end
|
||||
|
||||
local bd = ents.Create("base_anim")
|
||||
bd:SetParent(self)
|
||||
bd:AddEffects(1)
|
||||
bd:Spawn()
|
||||
self.bd = bd
|
||||
self:DeleteOnRemove(bd)
|
||||
TransferModelData(self.bd, self.NPC)
|
||||
self.NPC.HasDeathAnimation = false
|
||||
self:SetNWFloat('DTeam', self.NPC.Team)
|
||||
|
||||
if self.Attacker then
|
||||
timer.Simple(self.AttackerTime, function()
|
||||
local ent = self.ToKill
|
||||
if IsValid(ent) and IsValid(self) then
|
||||
self.TakedownIsFinished = true
|
||||
ent:Freeze(false)
|
||||
local armor = 0
|
||||
if ent:IsPlayer() then
|
||||
armor = ent:Armor()
|
||||
ent:SetSVAnimation("")
|
||||
else
|
||||
ent.CantUseTakedown = true
|
||||
end
|
||||
ent:TakeDamage(ent:Health()+armor, self.NPC)
|
||||
timer.Simple(0.001, function()
|
||||
if !IsValid(ent) then return end
|
||||
ent.Takedowning = false
|
||||
ent.TakedowningTarget = nil
|
||||
end)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
self.NPC.CantDamageMWII = true
|
||||
|
||||
timer.Simple(self.Delay, function()
|
||||
if !IsValid(self) then return end
|
||||
|
||||
if self.Attacker then
|
||||
self:Finish()
|
||||
else
|
||||
self:Finish(true)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function ENT:Finish(kill)
|
||||
local ow = self.NPC
|
||||
if IsValid(ow) then
|
||||
self.NPC = nil
|
||||
ow:SetNoDraw(false)
|
||||
ow:SetRenderMode(RENDERMODE_NORMAL)
|
||||
ow:DrawShadow(true)
|
||||
ow:RemoveEFlags(EFL_NO_THINK_FUNCTION)
|
||||
ow:ManipulateBonePosition(ow:LookupBone("ValveBiped.Bip01_Pelvis"), Vector(0, 0, 0))
|
||||
ow:ManipulateBoneAngles(ow:LookupBone("ValveBiped.Bip01_Pelvis"), Angle(0, 0, 0))
|
||||
local wep = ow:GetActiveWeapon()
|
||||
if IsValid(wep) then
|
||||
wep:SetNoDraw(false)
|
||||
end
|
||||
if kill then
|
||||
if ow.IsDrGNextbot then
|
||||
function ow:OnDeath()
|
||||
local rag = self:BecomeRagdoll()
|
||||
MWIITransferBones(self.bd, rag)
|
||||
end
|
||||
function ow:LastStand() end
|
||||
elseif ow.IsVJBaseSNPC then
|
||||
ow.HasDeathAnimation = false
|
||||
end
|
||||
self.Finisher.TakedownIsFinished = true
|
||||
ow.CantDamageMWII = false
|
||||
ow:TakeDamage(ow:Health(), self.Finisher, self.Finisher)
|
||||
ow:TakeDamage(999999999, self.Finisher, self.Finisher)
|
||||
else
|
||||
ow.CantDamageMWII = false
|
||||
ow.HasDeathAnimation = true
|
||||
ow:SetNWEntity('MWIIRag', NULL)
|
||||
ow.Takedowning = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
local ow = self.NPC
|
||||
if !IsValid(ow) then
|
||||
self:Remove()
|
||||
else
|
||||
ow.Takedowning = true
|
||||
ow:SetNoDraw(true)
|
||||
ow:SetRenderMode(RENDERMODE_NONE)
|
||||
ow:DrawShadow(false)
|
||||
ow:AddEFlags(EFL_NO_THINK_FUNCTION)
|
||||
ow:SetNWEntity('MWIIRag', self.bd)
|
||||
local wep = ow:GetActiveWeapon()
|
||||
if IsValid(wep) then
|
||||
wep:SetNoDraw(true)
|
||||
end
|
||||
|
||||
if !IsValid(self.ToKill) and self.KillingEntityMode and !self.Finisher.TakedownIsFinished then
|
||||
self:Finish()
|
||||
end
|
||||
|
||||
local att = self.Finisher
|
||||
if !IsValid(att) or att:Health() <= 0 or !att.Takedowning then
|
||||
self:Finish()
|
||||
end
|
||||
end
|
||||
self:SetNoDraw(true)
|
||||
self:DrawShadow(false)
|
||||
self:NextThink(CurTime())
|
||||
return true
|
||||
end
|
||||
else
|
||||
local tm_mat = Material('tdmg/hud/teammate.png')
|
||||
function ENT:Draw()
|
||||
if self:GetNWFloat('DTeam') == LocalPlayer():Team() then
|
||||
local angle = EyeAngles()
|
||||
angle = Angle( 0, angle.y, 0 )
|
||||
angle:RotateAroundAxis( angle:Up(), -90 )
|
||||
angle:RotateAroundAxis( angle:Forward(), 90 )
|
||||
local pos = self:GetBonePosition(LocalPlayer():LookupBone("ValveBiped.Bip01_Head1"))+Vector(0,0,16)
|
||||
cam.Start3D2D( pos, angle, 0.1 )
|
||||
surface.SetDrawColor(5,155,255)
|
||||
surface.SetMaterial(tm_mat)
|
||||
surface.DrawTexturedRect(-12, -12, 24, 24)
|
||||
cam.End3D2D()
|
||||
end
|
||||
end
|
||||
end
|
||||
72
gamemodes/cod_custom/entities/entities/npc_tf2_ghost.lua
Normal file
72
gamemodes/cod_custom/entities/entities/npc_tf2_ghost.lua
Normal file
@@ -0,0 +1,72 @@
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
ENT.Base = "base_nextbot"
|
||||
ENT.Spawnable = false
|
||||
|
||||
function ENT:Initialize()
|
||||
|
||||
--self:SetModel( "models/props_halloween/ghost_no_hat.mdl" )
|
||||
--self:SetModel( "models/props_wasteland/controlroom_filecabinet002a.mdl" )
|
||||
self:SetModel( "models/mossman.mdl" )
|
||||
|
||||
end
|
||||
|
||||
function ENT:RunBehaviour()
|
||||
|
||||
while ( true ) do
|
||||
|
||||
self:StartActivity( ACT_WALK ) -- walk anims
|
||||
self.loco:SetDesiredSpeed( 100 ) -- walk speeds
|
||||
|
||||
-- Choose a random location within 400 units of our position
|
||||
local targetPos = self:GetPos() + Vector( math.Rand( -1, 1 ), math.Rand( -1, 1 ), 0 ) * 400
|
||||
|
||||
-- Search for walkable space there, or nearby
|
||||
local area = navmesh.GetNearestNavArea( targetPos )
|
||||
|
||||
-- We found walkable space, get the closest point on that area to where we want to be
|
||||
if ( IsValid( area ) ) then targetPos = area:GetClosestPointOnArea( targetPos ) end
|
||||
|
||||
-- walk to the target place (yielding)
|
||||
self:MoveToPos( targetPos )
|
||||
|
||||
self:StartActivity( ACT_IDLE ) -- revert to idle activity
|
||||
|
||||
self:PlaySequenceAndWait( "idle_to_sit_ground" ) -- Sit on the floor
|
||||
self:SetSequence( "sit_ground" ) -- Stay sitting
|
||||
coroutine.wait( self:PlayScene( "scenes/eli_lab/mo_gowithalyx01.vcd" ) ) -- play a scene and wait for it to finish before progressing
|
||||
self:PlaySequenceAndWait( "sit_ground_to_idle" ) -- Get up
|
||||
|
||||
-- find the furthest away hiding spot
|
||||
local pos = self:FindSpot( "random", { type = 'hiding', radius = 5000 } )
|
||||
|
||||
-- if the position is valid
|
||||
if ( pos ) then
|
||||
self:StartActivity( ACT_RUN ) -- run anim
|
||||
self.loco:SetDesiredSpeed( 200 ) -- run speed
|
||||
self:PlayScene( "scenes/npc/female01/watchout.vcd" ) -- shout something while we run just for a laugh
|
||||
self:MoveToPos( pos ) -- move to position (yielding)
|
||||
self:PlaySequenceAndWait( "fear_reaction" ) -- play a fear animation
|
||||
self:StartActivity( ACT_IDLE ) -- when we finished, go into the idle anim
|
||||
else
|
||||
|
||||
-- some activity to signify that we didn't find shit
|
||||
|
||||
end
|
||||
|
||||
coroutine.yield()
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- List the NPC as spawnable
|
||||
--
|
||||
list.Set( "NPC", "npc_tf2_ghost", {
|
||||
Name = "Example NPC",
|
||||
Class = "npc_tf2_ghost",
|
||||
Category = "Nextbot"
|
||||
} )
|
||||
178
gamemodes/cod_custom/entities/entities/prop_effect.lua
Normal file
178
gamemodes/cod_custom/entities/entities/prop_effect.lua
Normal file
@@ -0,0 +1,178 @@
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
if ( CLIENT ) then
|
||||
CreateConVar( "cl_draweffectrings", "1", 0, "Should the effect green rings be visible?" )
|
||||
end
|
||||
|
||||
ENT.Type = "anim"
|
||||
|
||||
ENT.Spawnable = false
|
||||
|
||||
function ENT:Initialize()
|
||||
|
||||
local Radius = 6
|
||||
local mins = Vector( 1, 1, 1 ) * Radius * -0.5
|
||||
local maxs = Vector( 1, 1, 1 ) * Radius * 0.5
|
||||
|
||||
if ( SERVER ) then
|
||||
|
||||
self.AttachedEntity = ents.Create( "prop_dynamic" )
|
||||
self.AttachedEntity:SetModel( self:GetModel() )
|
||||
self.AttachedEntity:SetAngles( self:GetAngles() )
|
||||
self.AttachedEntity:SetPos( self:GetPos() )
|
||||
self.AttachedEntity:SetSkin( self:GetSkin() )
|
||||
self.AttachedEntity:Spawn()
|
||||
self.AttachedEntity:SetParent( self )
|
||||
self.AttachedEntity:DrawShadow( false )
|
||||
|
||||
self:SetModel( "models/props_junk/watermelon01.mdl" )
|
||||
|
||||
self:DeleteOnRemove( self.AttachedEntity )
|
||||
self.AttachedEntity:DeleteOnRemove( self )
|
||||
|
||||
-- Don't use the model's physics - create a box instead
|
||||
self:PhysicsInitBox( mins, maxs )
|
||||
self:SetSolid( SOLID_VPHYSICS )
|
||||
|
||||
-- Set up our physics object here
|
||||
local phys = self:GetPhysicsObject()
|
||||
if ( IsValid( phys ) ) then
|
||||
phys:Wake()
|
||||
phys:EnableGravity( false )
|
||||
phys:EnableDrag( false )
|
||||
end
|
||||
|
||||
self:DrawShadow( false )
|
||||
self:SetCollisionGroup( COLLISION_GROUP_WEAPON )
|
||||
|
||||
else
|
||||
|
||||
-- So addons can override this
|
||||
self.GripMaterial = Material( "sprites/grip" )
|
||||
self.GripMaterialHover = Material( "sprites/grip_hover" )
|
||||
|
||||
-- Get the attached entity so that clientside functions like properties can interact with it
|
||||
local tab = ents.FindByClassAndParent( "prop_dynamic", self )
|
||||
if ( tab && IsValid( tab[ 1 ] ) ) then self.AttachedEntity = tab[ 1 ] end
|
||||
|
||||
end
|
||||
|
||||
-- Set collision bounds exactly
|
||||
self:SetCollisionBounds( mins, maxs )
|
||||
|
||||
end
|
||||
|
||||
function ENT:Draw()
|
||||
|
||||
if ( halo.RenderedEntity() == self ) then
|
||||
self.AttachedEntity:DrawModel()
|
||||
return
|
||||
end
|
||||
|
||||
if ( GetConVarNumber( "cl_draweffectrings" ) == 0 ) then return end
|
||||
|
||||
-- Don't draw the grip if there's no chance of us picking it up
|
||||
local ply = LocalPlayer()
|
||||
local wep = ply:GetActiveWeapon()
|
||||
if ( !IsValid( wep ) ) then return end
|
||||
|
||||
local weapon_name = wep:GetClass()
|
||||
|
||||
if ( weapon_name != "weapon_physgun" && weapon_name != "weapon_physcannon" && weapon_name != "gmod_tool" ) then
|
||||
return
|
||||
end
|
||||
|
||||
if ( self:BeingLookedAtByLocalPlayer() ) then
|
||||
render.SetMaterial( self.GripMaterialHover )
|
||||
else
|
||||
render.SetMaterial( self.GripMaterial )
|
||||
end
|
||||
|
||||
render.DrawSprite( self:GetPos(), 16, 16, color_white )
|
||||
|
||||
end
|
||||
|
||||
-- Copied from base_gmodentity.lua
|
||||
ENT.MaxWorldTipDistance = 256
|
||||
function ENT:BeingLookedAtByLocalPlayer()
|
||||
local ply = LocalPlayer()
|
||||
if ( !IsValid( ply ) ) then return false end
|
||||
|
||||
local view = ply:GetViewEntity()
|
||||
local dist = self.MaxWorldTipDistance
|
||||
dist = dist * dist
|
||||
|
||||
-- If we're spectating a player, perform an eye trace
|
||||
if ( view:IsPlayer() ) then
|
||||
return view:EyePos():DistToSqr( self:GetPos() ) <= dist && view:GetEyeTrace().Entity == self
|
||||
end
|
||||
|
||||
-- If we're not spectating a player, perform a manual trace from the entity's position
|
||||
local pos = view:GetPos()
|
||||
|
||||
if ( pos:DistToSqr( self:GetPos() ) <= dist ) then
|
||||
return util.TraceLine( {
|
||||
start = pos,
|
||||
endpos = pos + ( view:GetAngles():Forward() * dist ),
|
||||
filter = view
|
||||
} ).Entity == self
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function ENT:PhysicsUpdate( physobj )
|
||||
|
||||
if ( CLIENT ) then return end
|
||||
|
||||
-- Don't do anything if the player isn't holding us
|
||||
if ( !self:IsPlayerHolding() && !self:IsConstrained() ) then
|
||||
|
||||
physobj:SetVelocity( vector_origin )
|
||||
physobj:Sleep()
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function ENT:OnEntityCopyTableFinish( tab )
|
||||
|
||||
-- We need to store the model of the attached entity
|
||||
-- Not the one we have here.
|
||||
tab.Model = self.AttachedEntity:GetModel()
|
||||
|
||||
-- Store the attached entity's table so we can restore it after being pasted
|
||||
tab.AttachedEntityInfo = table.Copy( duplicator.CopyEntTable( self.AttachedEntity ) )
|
||||
tab.AttachedEntityInfo.Pos = nil -- Don't even save angles and position, we are a parented entity
|
||||
tab.AttachedEntityInfo.Angle = nil
|
||||
|
||||
-- Do NOT store the attached entity itself in our table!
|
||||
-- Otherwise, if we copy-paste the prop with the duplicator, its AttachedEntity value will point towards the original prop's attached entity instead, and that'll break stuff
|
||||
tab.AttachedEntity = nil
|
||||
|
||||
end
|
||||
|
||||
function ENT:PostEntityPaste( ply )
|
||||
|
||||
-- Restore the attached entity using the information we've saved
|
||||
if ( IsValid( self.AttachedEntity ) && self.AttachedEntityInfo ) then
|
||||
|
||||
-- Apply skin, bodygroups, bone manipulator, etc.
|
||||
duplicator.DoGeneric( self.AttachedEntity, self.AttachedEntityInfo )
|
||||
|
||||
if ( self.AttachedEntityInfo.EntityMods ) then
|
||||
self.AttachedEntity.EntityMods = table.Copy( self.AttachedEntityInfo.EntityMods )
|
||||
duplicator.ApplyEntityModifiers( ply, self.AttachedEntity )
|
||||
end
|
||||
|
||||
if ( self.AttachedEntityInfo.BoneMods ) then
|
||||
self.AttachedEntity.BoneMods = table.Copy( self.AttachedEntityInfo.BoneMods )
|
||||
duplicator.ApplyBoneModifiers( ply, self.AttachedEntity )
|
||||
end
|
||||
|
||||
self.AttachedEntityInfo = nil
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
304
gamemodes/cod_custom/entities/entities/ragdoll_motion.lua
Normal file
304
gamemodes/cod_custom/entities/entities/ragdoll_motion.lua
Normal file
@@ -0,0 +1,304 @@
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
ENT.Type = "anim"
|
||||
ENT.Spawnable = false
|
||||
ENT.AdminOnly = false
|
||||
ENT.Editable = true
|
||||
|
||||
function ENT:SetupDataTables()
|
||||
|
||||
--
|
||||
-- Scale - how far the ragdoll will move in the game world in relation to how far it moved in the real world
|
||||
--
|
||||
self:NetworkVar( "Float", 0, "Scale", { KeyName = "scale", Edit = { type = "Float", min=1, max=512, order = 1 } } )
|
||||
|
||||
--
|
||||
-- Normalize - if enabled the limbs aren't stretched
|
||||
--
|
||||
self:NetworkVar( "Bool", 0, "Normalize", { KeyName = "normalize", Edit = { type = "Boolean", order = 2 } } )
|
||||
|
||||
--
|
||||
-- Debug - Shows some debug info - only available on a listen server
|
||||
--
|
||||
self:NetworkVar( "Bool", 1, "Debug", { KeyName = "debug", Edit = { type = "Boolean", order = 100 } } )
|
||||
|
||||
--
|
||||
-- Controller - the entity that is currently controlling the ragdoll
|
||||
--
|
||||
self:NetworkVar( "Entity", 0, "Controller" )
|
||||
self:NetworkVar( "Entity", 1, "Target" )
|
||||
|
||||
--
|
||||
-- Defaults
|
||||
--
|
||||
if ( SERVER ) then
|
||||
|
||||
self:SetScale( 36 )
|
||||
self:SetDebug( false )
|
||||
self:SetNormalize( true )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function ENT:Initialize()
|
||||
|
||||
if ( SERVER ) then
|
||||
|
||||
self:SetModel( "models/maxofs2d/motion_sensor.mdl" )
|
||||
self:PhysicsInit( SOLID_VPHYSICS )
|
||||
|
||||
-- Don't collide with the player
|
||||
self:SetCollisionGroup( COLLISION_GROUP_WEAPON )
|
||||
|
||||
self:DrawShadow( false )
|
||||
|
||||
local phys = self:GetPhysicsObject()
|
||||
if ( IsValid( phys ) ) then
|
||||
|
||||
phys:Wake()
|
||||
phys:EnableGravity( false )
|
||||
phys:EnableDrag( false )
|
||||
|
||||
end
|
||||
|
||||
local colors = {
|
||||
Color( 180, 255, 50 ),
|
||||
Color( 0, 150, 255 ),
|
||||
Color( 255, 255, 0 ),
|
||||
Color( 255, 50, 255 )
|
||||
}
|
||||
|
||||
self:SetColor( table.Random( colors ) )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- We don't want to move unless the player moves us or we're constrained to something.
|
||||
--
|
||||
function ENT:PhysicsUpdate( physobj )
|
||||
|
||||
if ( self:IsPlayerHolding() ) then return end
|
||||
if ( self:IsConstrained() ) then return end
|
||||
|
||||
physobj:SetVelocity( vector_origin )
|
||||
physobj:Sleep()
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Clean up on remove
|
||||
--
|
||||
function ENT:OnRemove()
|
||||
|
||||
if ( SERVER ) then
|
||||
|
||||
local ragdoll = self:GetTarget()
|
||||
if ( IsValid( ragdoll ) ) then
|
||||
ragdoll:SetRagdollBuildFunction( nil )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function ENT:Draw()
|
||||
|
||||
--
|
||||
-- Don't draw if we're holding the camera
|
||||
--
|
||||
local ply = LocalPlayer()
|
||||
local wep = ply:GetActiveWeapon()
|
||||
if ( wep:IsValid() ) then
|
||||
if ( wep:GetClass() == "gmod_camera" ) then return end
|
||||
end
|
||||
|
||||
self:DrawModel()
|
||||
|
||||
end
|
||||
|
||||
function ENT:DrawDebug( ragdoll, controller, pos, ang, rotation, scale, center, changed_sensor )
|
||||
|
||||
local UpdateTime = 0.1
|
||||
local StayTime = 0.15
|
||||
|
||||
if ( self.LastDebugUpdate && CurTime() - self.LastDebugUpdate < UpdateTime ) then return end
|
||||
|
||||
self.LastDebugUpdate = CurTime()
|
||||
|
||||
center = center
|
||||
|
||||
local col_bone = color_white
|
||||
local col_point = Color( 255, 0, 0, 255 )
|
||||
local col_tran_bn = Color( 0, 255, 0, 255 )
|
||||
|
||||
local realbonepos = {}
|
||||
local fixedbonepos = {}
|
||||
local min = Vector( 1, 1, 1 ) * -0.5
|
||||
local max = Vector( 1, 1, 1 ) * 0.5
|
||||
|
||||
--
|
||||
-- Draw Points
|
||||
--
|
||||
for i = 0, 19 do
|
||||
|
||||
realbonepos[i] = controller:MotionSensorPos( i ) * scale
|
||||
realbonepos[i]:Rotate( rotation )
|
||||
realbonepos[i] = realbonepos[i] + center
|
||||
|
||||
fixedbonepos[i] = changed_sensor[ i ] * scale
|
||||
-- (already rotated)
|
||||
fixedbonepos[i] = fixedbonepos[i] + center
|
||||
|
||||
|
||||
debugoverlay.Box( realbonepos[i], min, max, StayTime, col_point, true )
|
||||
debugoverlay.Box( fixedbonepos[i], min, max, StayTime, col_tran_bn, true )
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Draw bones
|
||||
--
|
||||
for k, v in pairs( motionsensor.DebugBones ) do
|
||||
|
||||
debugoverlay.Line( realbonepos[ v[1] ], realbonepos[ v[2] ], StayTime, col_bone, true )
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Draw translated sensor bones
|
||||
--
|
||||
for k, v in pairs( motionsensor.DebugBones ) do
|
||||
|
||||
debugoverlay.Line( fixedbonepos[ v[1] ], fixedbonepos[ v[2] ], StayTime, col_tran_bn, true )
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Draw ragdoll physics bones
|
||||
--
|
||||
for i=0, ragdoll:GetPhysicsObjectCount() - 1 do
|
||||
|
||||
local phys = ragdoll:GetPhysicsObjectNum( i )
|
||||
|
||||
local pos = phys:GetPos()
|
||||
local angle = phys:GetAngles()
|
||||
local txt = i
|
||||
|
||||
if ( ang[i] == nil ) then
|
||||
txt = i .. " (UNSET)"
|
||||
end
|
||||
|
||||
debugoverlay.Text( pos, txt, StayTime )
|
||||
debugoverlay.Axis( pos, angle, 5, StayTime, true )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function ENT:SetRagdoll( ragdoll )
|
||||
|
||||
self:SetTarget( ragdoll )
|
||||
ragdoll:PhysWake()
|
||||
|
||||
local buildername = motionsensor.ChooseBuilderFromEntity( ragdoll )
|
||||
|
||||
--
|
||||
-- Set the ragdoll build function.
|
||||
-- This function is called whenever the ragdoll bones are built.
|
||||
-- in this function is the one place you can successfully call ent:SetRagdollBone
|
||||
--
|
||||
ragdoll:SetRagdollBuildFunction( function( ragdoll )
|
||||
|
||||
local controller = self:GetController()
|
||||
if ( !IsValid( controller ) ) then return end
|
||||
|
||||
local builder = list.Get( "SkeletonConvertor" )[ buildername ]
|
||||
local scale = self:GetScale()
|
||||
local rotation = self:GetAngles()
|
||||
local center = self:GetPos()
|
||||
local normalize = self:GetNormalize()
|
||||
local debug = self:GetDebug()
|
||||
|
||||
--
|
||||
-- Call the build skeleton function.
|
||||
-- This is thrown out to a pseudo class because we want to be
|
||||
-- able to add new skeleton types nice and easily.
|
||||
--
|
||||
local pos, ang, changed_sensor = motionsensor.BuildSkeleton( builder, controller, rotation )
|
||||
|
||||
--
|
||||
-- For development
|
||||
--
|
||||
if ( debug ) then
|
||||
self:DrawDebug( ragdoll, controller, pos, ang, rotation, scale, center, changed_sensor )
|
||||
end
|
||||
|
||||
--
|
||||
-- If we don't have 85% of the points, just drop dead
|
||||
--
|
||||
local iSkipped = 0
|
||||
local iMaxSkip = table.Count( pos ) * 0.25
|
||||
for k, v in pairs( pos ) do
|
||||
|
||||
if ( math.abs( v.x ) > 0.05 ) then continue end
|
||||
if ( math.abs( v.y ) > 0.05 ) then continue end
|
||||
|
||||
pos[k] = nil -- don't use this point to control the ragdoll
|
||||
ang[k] = nil -- (use the ragdoll point)
|
||||
|
||||
iSkipped = iSkipped + 1
|
||||
|
||||
if ( iSkipped > iMaxSkip ) then
|
||||
|
||||
ragdoll:RagdollStopControlling()
|
||||
return
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Loop each returned position
|
||||
--
|
||||
for k, v in pairs( pos ) do
|
||||
|
||||
--
|
||||
-- Set the bone angle
|
||||
--
|
||||
if ( ang[ k ] != nil ) then
|
||||
ragdoll:SetRagdollAng( k, ang[ k ] )
|
||||
end
|
||||
|
||||
--
|
||||
-- The root bone, we directly set the position of this one.
|
||||
--
|
||||
if ( k == 0 || !normalize ) then
|
||||
|
||||
local new_position = center + v * scale
|
||||
ragdoll:SetRagdollPos( k, new_position )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Normalize the ragdoll
|
||||
--
|
||||
if ( normalize ) then
|
||||
|
||||
ragdoll:RagdollSolve()
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Makes the physics objects follow the set bone positions
|
||||
--
|
||||
ragdoll:RagdollUpdatePhysics()
|
||||
|
||||
end )
|
||||
|
||||
end
|
||||
410
gamemodes/cod_custom/entities/entities/tdm_ah64/shared.lua
Normal file
410
gamemodes/cod_custom/entities/entities/tdm_ah64/shared.lua
Normal file
@@ -0,0 +1,410 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.Type = "anim"
|
||||
ENT.PrintName = "AH-64"
|
||||
|
||||
if SERVER then
|
||||
util.AddNetworkString("COD.AH64Cam")
|
||||
net.Receive("COD.AH64Cam", function(len, ply)
|
||||
ply.AH64_Cam_Pos = net.ReadVector()
|
||||
ply.AH64_Cam_Ang = net.ReadAngle()
|
||||
end)
|
||||
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/hunter/blocks/cube2x8x1.mdl")
|
||||
self:SetHealth(999999999)
|
||||
self.Velo = {x = 0, y = 0}
|
||||
self:SetSolid(SOLID_VPHYSICS)
|
||||
self:PhysicsInit(SOLID_VPHYSICS)
|
||||
self.MultSpeed = 500
|
||||
self.MaxSpeed = 750
|
||||
self.Height = COD.DataTable["AirVehicle_FlyHeight"]
|
||||
self.Smoking = false
|
||||
self.DeltaTime = 0
|
||||
self.FireDelay = CurTime()+1
|
||||
self.FireDelay2 = CurTime()+1
|
||||
self:SetNWFloat('Rockets', 8)
|
||||
self:SetNWFloat('RemoveTime', CurTime()+50)
|
||||
self:SetNoDraw(true)
|
||||
self:EmitSound(")npc/attack_helicopter/aheli_rotor_loop1.wav", 100, 100, 1, CHAN_BODY)
|
||||
|
||||
timer.Simple(3, function()
|
||||
if !IsValid(self) then return end
|
||||
self:SetHealth(3000)
|
||||
end)
|
||||
|
||||
timer.Simple(0.1, function()
|
||||
local ply = self:GetCreator()
|
||||
if !IsValid(ply) then return end
|
||||
|
||||
net.Start("COD.Cutscene")
|
||||
net.WriteTable({
|
||||
num_of_cutscene = 1,
|
||||
path_of_sound = "tdmg/heli/spawn.wav",
|
||||
fps = 30,
|
||||
screenfade = true,
|
||||
})
|
||||
net.Send(ply)
|
||||
|
||||
net.Start("COD.AH64Cam")
|
||||
net.WriteEntity(self)
|
||||
net.Send(ply)
|
||||
ply.ControllingKillstreak = true
|
||||
end)
|
||||
|
||||
local mod = ents.Create("base_anim")
|
||||
mod:SetModel("models/tdmg/ah64.mdl")
|
||||
mod:SetPos(self:GetPos())
|
||||
mod:SetAngles(self:GetAngles()+Angle(0,90,0))
|
||||
mod:SetParent(self)
|
||||
mod:Spawn()
|
||||
self:DeleteOnRemove(mod)
|
||||
|
||||
timer.Simple(5, function()
|
||||
if !IsValid(self) then return end
|
||||
|
||||
if self.Team == 1 then
|
||||
self.VJ_NPC_Class = {"CLASS_SPECGRU"}
|
||||
elseif self.Team == 2 then
|
||||
self.VJ_NPC_Class = {"CLASS_KORTAC"}
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function ENT:OnRemove()
|
||||
self:StopSound(")npc/attack_helicopter/aheli_rotor_loop1.wav")
|
||||
|
||||
local ply = self:GetCreator()
|
||||
if !IsValid(ply) then return end
|
||||
ply.ControllingKillstreak = false
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
local ply = self:GetCreator()
|
||||
if !IsValid(ply) then
|
||||
self:Remove()
|
||||
else
|
||||
local mu = self.MultSpeed
|
||||
local ms = self.MaxSpeed
|
||||
local phys = self:GetPhysicsObject()
|
||||
local vel = phys:GetVelocity()
|
||||
vel.z = 0
|
||||
|
||||
local pos = self:GetPos()
|
||||
local ang = ply:EyeAngles().y
|
||||
ply:SetActiveWeapon(nil)
|
||||
self:SetPos(Vector(pos.x, pos.y, self.Height))
|
||||
phys:SetVelocityInstantaneous(-vel+self:GetForward()*self.Velo.x+self:GetRight()*self.Velo.y)
|
||||
if ply:KeyDown(IN_MOVERIGHT) then
|
||||
self.Velo.x = math.Clamp(self.Velo.x+FrameTime()*mu, -ms, ms)
|
||||
elseif ply:KeyDown(IN_MOVELEFT) then
|
||||
self.Velo.x = math.Clamp(self.Velo.x-FrameTime()*mu, -ms, ms)
|
||||
end
|
||||
if ply:KeyDown(IN_FORWARD) then
|
||||
self.Velo.y = math.Clamp(self.Velo.y-FrameTime()*mu, -ms, ms)
|
||||
elseif ply:KeyDown(IN_BACK) then
|
||||
self.Velo.y = math.Clamp(self.Velo.y+FrameTime()*mu, -ms, ms)
|
||||
end
|
||||
if not ply:KeyDown(IN_MOVELEFT) and not ply:KeyDown(IN_MOVERIGHT) then
|
||||
if self.Velo.x > 5 or self.Velo.x < -5 then
|
||||
if self.Velo.x > 0 then
|
||||
self.Velo.x = math.Clamp(self.Velo.x-FrameTime()*mu, -ms, ms)
|
||||
elseif self.Velo.x < 0 then
|
||||
self.Velo.x = math.Clamp(self.Velo.x+FrameTime()*mu, -ms, ms)
|
||||
end
|
||||
else
|
||||
self.Velo.x = 0
|
||||
end
|
||||
end
|
||||
if not ply:KeyDown(IN_FORWARD) and not ply:KeyDown(IN_BACK) then
|
||||
if self.Velo.y > 5 or self.Velo.y < -5 then
|
||||
if self.Velo.y > 0 then
|
||||
self.Velo.y = math.Clamp(self.Velo.y-FrameTime()*mu, -ms, ms)
|
||||
elseif self.Velo.y < 0 then
|
||||
self.Velo.y = math.Clamp(self.Velo.y+FrameTime()*mu, -ms, ms)
|
||||
end
|
||||
else
|
||||
self.Velo.y = 0
|
||||
end
|
||||
end
|
||||
if ply:KeyDown(IN_ATTACK) and self.FireDelay < CurTime() then
|
||||
self.FireDelay = CurTime()+0.15
|
||||
self:EmitSound("tdmg/killstreaks/apache_cannon.wav", 100, math.random(90,110), 1, CHAN_WEAPON)
|
||||
ply:ViewPunch(Angle(1,0,0))
|
||||
|
||||
local pos = ply.AH64_Cam_Pos+Vector(0,0,12)
|
||||
local ang = ply.AH64_Cam_Ang
|
||||
|
||||
local explosion = ents.Create("tdm_ah64_rocket1")
|
||||
explosion:SetPos(pos)
|
||||
explosion:SetOwner(self)
|
||||
explosion:SetNWFloat('Team', self.Team)
|
||||
explosion.Team = self.Team
|
||||
explosion:SetAngles(ang)
|
||||
explosion:Spawn()
|
||||
end
|
||||
if ply:KeyDown(IN_ATTACK2) and self.FireDelay2 < CurTime() and self:GetNWFloat('Rockets') > 0 then
|
||||
self.FireDelay2 = CurTime()+0.5
|
||||
self:SetNWFloat('Rockets', self:GetNWFloat('Rockets')-1)
|
||||
self:EmitSound("tdmg/killstreaks/ac130_rocket.wav", 100, math.random(90,110), 1, CHAN_WEAPON)
|
||||
ply:ViewPunch(Angle(5,0,0))
|
||||
|
||||
local pos = ply.AH64_Cam_Pos+Vector(0,0,12)
|
||||
local ang = ply.AH64_Cam_Ang
|
||||
|
||||
local explosion = ents.Create("tdm_ah64_rocket2")
|
||||
explosion:SetPos(pos)
|
||||
explosion:SetOwner(self)
|
||||
explosion:SetNWFloat('Team', self.Team)
|
||||
explosion.Team = self.Team
|
||||
explosion:SetAngles(ang)
|
||||
explosion:Spawn()
|
||||
end
|
||||
if self:GetNWFloat('RemoveTime') < CurTime() then
|
||||
self:Remove()
|
||||
end
|
||||
if self:Health() <= 1000 and not self.Smoking then
|
||||
self.Smoking = true
|
||||
ParticleEffectAttach("Rocket_Smoke_Trail", 1, self, 0)
|
||||
end
|
||||
if self:Health() <= 0 then
|
||||
self:DestroyHeli(self.IsDExplosionDamage)
|
||||
end
|
||||
|
||||
local b = {}
|
||||
b.secondstoarrive = 1
|
||||
b.pos = self:GetPos()
|
||||
b.angle = Angle(0,ang,0)
|
||||
b.maxangular = 10
|
||||
b.maxangulardamp = 5
|
||||
b.maxspeed = 10
|
||||
b.maxspeeddamp = 5
|
||||
b.dampfactor = 0.8
|
||||
b.teleportdistance = 0
|
||||
b.deltatime = CurTime()-self.DeltaTime
|
||||
phys:ComputeShadowControl(b)
|
||||
|
||||
self.DeltaTime = CurTime()
|
||||
self:NextThink(CurTime())
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:OnTakeDamage(dmgt)
|
||||
local dmg = dmgt:GetDamage()
|
||||
local att = dmgt:GetAttacker()
|
||||
if att != self or att:IsPlayer() and att:Team() != self.Team then
|
||||
self:SetHealth(self:Health()-dmg)
|
||||
self.IsDExplosionDamage = dmgt:IsExplosionDamage()
|
||||
if IsValid(self:GetCreator()) then
|
||||
self:GetCreator():ViewPunch(AngleRand(-1,1))
|
||||
self:EmitSound("physics/metal/metal_box_impact_bullet"..math.random(1,3)..".wav")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:DestroyHeli(isrocket)
|
||||
local ply = self:GetCreator()
|
||||
|
||||
if IsValid(ply) then
|
||||
if isrocket then
|
||||
net.Start("COD.Cutscene")
|
||||
net.WriteTable({
|
||||
num_of_cutscene = 3,
|
||||
path_of_sound = "tdmg/heli/shotrocket.wav",
|
||||
fps = 30,
|
||||
screenfade = true,
|
||||
})
|
||||
net.Send(ply)
|
||||
else
|
||||
net.Start("COD.Cutscene")
|
||||
net.WriteTable({
|
||||
num_of_cutscene = 2,
|
||||
path_of_sound = "tdmg/heli/shotbullet.wav",
|
||||
fps = 30,
|
||||
screenfade = true,
|
||||
})
|
||||
net.Send(ply)
|
||||
end
|
||||
end
|
||||
|
||||
ParticleEffect("explosion_huge_h", self:GetPos(), Angle(0,0,0))
|
||||
sound.Play("tdmg/a10_explosion.wav", self:GetPos(), 0)
|
||||
self:Remove()
|
||||
end
|
||||
else
|
||||
local function CanSee(pos1, pos2)
|
||||
local tr = util.TraceLine( {
|
||||
start = pos1,
|
||||
endpos = pos2,
|
||||
filter = function(ent) if ent:IsWorld() then return true end end,
|
||||
})
|
||||
return !tr.Hit
|
||||
end
|
||||
|
||||
local enemyMat = Material("tdmg/hud/radar/enemy.png", "noclamp")
|
||||
local glitchMat = Material("tdmg/hud/screenglitch.jpg", "noclamp")
|
||||
|
||||
net.Receive("COD.AH64Cam", function()
|
||||
local ent = net.ReadEntity()
|
||||
local alpha = 0
|
||||
local downa = false
|
||||
local tab = {
|
||||
[ "$pp_colour_addr" ] = 0,
|
||||
[ "$pp_colour_addg" ] = 0,
|
||||
[ "$pp_colour_addb" ] = 0,
|
||||
[ "$pp_colour_brightness" ] = 0,
|
||||
[ "$pp_colour_contrast" ] = 0.9,
|
||||
[ "$pp_colour_colour" ] = 0.1,
|
||||
[ "$pp_colour_mulr" ] = 0,
|
||||
[ "$pp_colour_mulg" ] = 0,
|
||||
[ "$pp_colour_mulb" ] = 0
|
||||
}
|
||||
|
||||
hook.Add("RenderScreenspaceEffects", "AH64Cam", function()
|
||||
DrawColorModify(tab)
|
||||
end)
|
||||
|
||||
hook.Add("HUDPaint", "AH64Cam", function()
|
||||
surface.SetDrawColor(50,50,50,100)
|
||||
surface.SetMaterial(glitchMat)
|
||||
surface.DrawTexturedRect(0, 0, ScrW(), ScrH())
|
||||
|
||||
surface.SetDrawColor(255,255,255)
|
||||
surface.DrawOutlinedRect(50, 50, ScrW()-100, ScrH()-100, 2)
|
||||
|
||||
surface.SetDrawColor(255,255,255,255)
|
||||
surface.DrawRect(ScrW()/2-200, ScrH()/2, 150, 2)
|
||||
|
||||
surface.SetDrawColor(255,255,255,255)
|
||||
surface.DrawRect(ScrW()/2-200, ScrH()/2-10, 2, 20)
|
||||
|
||||
surface.SetDrawColor(255,255,255,255)
|
||||
surface.DrawRect(ScrW()/2+50, ScrH()/2, 150, 2)
|
||||
|
||||
surface.SetDrawColor(255,255,255,255)
|
||||
surface.DrawRect(ScrW()/2+200, ScrH()/2-10, 2, 20)
|
||||
|
||||
surface.SetDrawColor(255,255,255,255)
|
||||
surface.DrawRect(ScrW()/2, ScrH()/2+50, 2, 150)
|
||||
|
||||
surface.SetDrawColor(255,255,255,255)
|
||||
surface.DrawRect(ScrW()/2-10, ScrH()/2-200, 20, 2)
|
||||
|
||||
surface.SetDrawColor(255,255,255,255)
|
||||
surface.DrawRect(ScrW()/2, ScrH()/2-200, 2, 150)
|
||||
|
||||
surface.SetDrawColor(255,255,255,255)
|
||||
surface.DrawRect(ScrW()/2-10, ScrH()/2+200, 20, 2)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
surface.SetDrawColor(255,255,255,255)
|
||||
surface.DrawRect(ScrW()/2-15, ScrH()/2-1, 30, 2)
|
||||
|
||||
|
||||
surface.SetDrawColor(255,255,255,255)
|
||||
surface.DrawRect(ScrW()/2-1, ScrH()/2-16, 2, 30)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
draw.SimpleText("✷ CHOPPER GUNNER", "DermaLarge", 100, 100, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
|
||||
draw.SimpleText("ACTIVE", "DermaLarge", 100, 130, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
|
||||
|
||||
draw.SimpleText("∾ CANNON ROUNDS", "DermaLarge", ScrW()-100, ScrH()-130, color_white, TEXT_ALIGN_RIGHT, TEXT_ALIGN_TOP)
|
||||
draw.SimpleText(ent:GetNWFloat('Rockets').." HYDRA ROCKETS", "DermaLarge", ScrW()-100, ScrH()-100, color_white, TEXT_ALIGN_RIGHT, TEXT_ALIGN_TOP)
|
||||
|
||||
if ent:Health() < 1000 then
|
||||
draw.SimpleText("WARNING: CRITICAL DAMAGE", "DermaLarge", ScrW()/2, ScrH()/2+300, Color(200,20,20,alpha), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
|
||||
end
|
||||
|
||||
if downa then
|
||||
alpha = alpha - FrameTime()*512
|
||||
if alpha <= 0 then
|
||||
downa = false
|
||||
end
|
||||
else
|
||||
alpha = alpha + FrameTime()*512
|
||||
if alpha >= 255 then
|
||||
downa = true
|
||||
end
|
||||
end
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
surface.SetDrawColor(220,220,220,255)
|
||||
surface.DrawRect(75, ScrH()-220, 300*((ent:GetNWFloat('RemoveTime')-CurTime())/45), 15)
|
||||
|
||||
surface.SetDrawColor(255,255,255,255)
|
||||
surface.DrawOutlinedRect(75, ScrH()-220, 300, 15, 2)
|
||||
|
||||
draw.SimpleText("FUEL", "DermaLarge", 75, ScrH()-250, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
|
||||
|
||||
surface.SetDrawColor(220,220,220,255)
|
||||
surface.DrawRect(75, ScrH()-120, 300*(ent:Health()/3000), 15)
|
||||
|
||||
surface.SetDrawColor(255,255,255)
|
||||
surface.DrawOutlinedRect(75, ScrH()-120, 300, 15, 2)
|
||||
|
||||
draw.SimpleText("HEALTH", "DermaLarge", 75, ScrH()-150, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
|
||||
---------------------------------------------------------------------------------
|
||||
|
||||
for _, ply in ipairs(player.GetAll()) do
|
||||
if ply:Alive() and ply:Team() != LocalPlayer():Team() and ply:GetNWFloat('Perk2') != 4 then
|
||||
local pos = ply:WorldSpaceCenter():ToScreen()
|
||||
|
||||
if CanSee(EyePos(), ply:WorldSpaceCenter()) then
|
||||
surface.SetDrawColor(200,0,0,200)
|
||||
elseif ply:WorldSpaceCenter():DistToSqr(EyePos()) < 2500000 then
|
||||
surface.SetDrawColor(255,255,255,100)
|
||||
surface.DrawRect(pos.x-1, pos.y-5, 1, 10)
|
||||
surface.SetDrawColor(255,255,255,100)
|
||||
surface.DrawRect(pos.x-5, pos.y-1, 10, 1)
|
||||
|
||||
surface.SetDrawColor(200,200,200,50)
|
||||
else
|
||||
surface.SetDrawColor(0,0,0,0)
|
||||
end
|
||||
surface.SetMaterial(enemyMat)
|
||||
surface.DrawTexturedRect(pos.x-20, pos.y-20, 40, 40)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
hook.Add("CreateMove", "AH64Cam", function(cmd)
|
||||
cmd:SetForwardMove(0)
|
||||
cmd:SetSideMove(0)
|
||||
cmd:RemoveKey(IN_JUMP)
|
||||
cmd:RemoveKey(IN_USE)
|
||||
end)
|
||||
|
||||
hook.Add("CalcView", "AH64Cam", function( ply, pos, angles, fov )
|
||||
if IsValid(ent) then
|
||||
COD.HideHUD = true
|
||||
COD.HUD_DisableSomeThink = true
|
||||
local pos1 = ent:GetPos()-ent:GetRight()*128-ent:GetUp()*48
|
||||
local ang1 = angles+Angle(0,90,0)
|
||||
local view = {
|
||||
origin = pos1,
|
||||
angles = ang1,
|
||||
fov = fov,
|
||||
drawviewer = true
|
||||
}
|
||||
|
||||
net.Start("COD.AH64Cam")
|
||||
net.WriteVector(pos1)
|
||||
net.WriteAngle(ang1)
|
||||
net.SendToServer()
|
||||
|
||||
return view
|
||||
else
|
||||
COD.HideHUD = false
|
||||
COD.HUD_DisableSomeThink = false
|
||||
hook.Remove("CalcView", "AH64Cam")
|
||||
hook.Remove("CreateMove", "AH64Cam")
|
||||
hook.Remove("RenderScreenspaceEffects", "AH64Cam")
|
||||
hook.Remove("HUDPaint", "AH64Cam")
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,39 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.Type = "anim"
|
||||
ENT.PrintName = "AH64 Cannon"
|
||||
|
||||
if SERVER then
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/weapons/w_missile_closed.mdl")
|
||||
self:SetSolid(SOLID_VPHYSICS)
|
||||
self:PhysicsInit(SOLID_VPHYSICS)
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
local phys = self:GetPhysicsObject()
|
||||
phys:SetVelocity(self:GetForward()*2500)
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin(self:GetPos())
|
||||
util.Effect("AR2Impact", effectdata)
|
||||
end
|
||||
|
||||
function ENT:Explode()
|
||||
local pos2 = self:GetPos()
|
||||
|
||||
local ef = EffectData()
|
||||
ef:SetOrigin(pos2)
|
||||
util.Effect("HelicopterMegaBomb", ef)
|
||||
util.BlastDamage(self, self, pos2, 128, 48)
|
||||
sound.Play("ambient/explosions/explode_4.wav", pos2, 0, math.random(80,120), 0.2)
|
||||
|
||||
self:Remove()
|
||||
end
|
||||
|
||||
function ENT:PhysicsCollide(data)
|
||||
if data.Speed > 50 then
|
||||
self:Explode()
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,37 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.Type = "anim"
|
||||
ENT.PrintName = "Hydra Missle"
|
||||
|
||||
if SERVER then
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/props_phx/amraam.mdl")
|
||||
self:SetSolid(SOLID_VPHYSICS)
|
||||
self:PhysicsInit(SOLID_VPHYSICS)
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
local phys = self:GetPhysicsObject()
|
||||
phys:SetVelocity(self:GetForward()*2500)
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin(self:GetPos())
|
||||
util.Effect("AR2Impact", effectdata)
|
||||
end
|
||||
|
||||
function ENT:Explode()
|
||||
local pos2 = self:GetPos()
|
||||
|
||||
ParticleEffect("explosion_huge_h", pos2, Angle(0,0,0))
|
||||
sound.Play("tdmg/a10_explosion.wav", pos2, 0)
|
||||
util.BlastDamage(self, self, pos2, 512, 256)
|
||||
|
||||
self:Remove()
|
||||
end
|
||||
|
||||
function ENT:PhysicsCollide(data)
|
||||
if data.Speed > 50 then
|
||||
self:Explode()
|
||||
end
|
||||
end
|
||||
end
|
||||
102
gamemodes/cod_custom/entities/entities/tdm_cmine/shared.lua
Normal file
102
gamemodes/cod_custom/entities/entities/tdm_cmine/shared.lua
Normal file
@@ -0,0 +1,102 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.Type = "anim"
|
||||
ENT.PrintName = "Claster Mine"
|
||||
|
||||
if SERVER then
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/tdmg/fieldupgrade_proximitymine.mdl")
|
||||
self:PhysicsInit(SOLID_VPHYSICS)
|
||||
self:SetMoveType(MOVETYPE_VPHYSICS)
|
||||
self:SetUseType(SIMPLE_USE)
|
||||
self:SetCollisionGroup(COLLISION_GROUP_DEBRIS)
|
||||
self:SetModelScale(1.2, 0)
|
||||
self:SetHealth(250)
|
||||
if not self.Team then
|
||||
self.Team = 1
|
||||
end
|
||||
self:SetNWFloat('Team', self.Team)
|
||||
timer.Simple(2, function()
|
||||
if IsValid(self) then
|
||||
self:Open()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
if self.Activated then
|
||||
local y = self:GetAngles().y
|
||||
self:SetAngles(Angle(0,y,0))
|
||||
if self:Health() <= 0 then
|
||||
self:Explode()
|
||||
end
|
||||
for _, ply in ipairs(ents.FindInSphere(self:GetPos(), 64)) do
|
||||
if ply:IsPlayer() and ply:Team() != self.Team or ply:IsNPC() and ply.Team and ply.Team != self.Team then
|
||||
self:Explode()
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
self:NextThink(CurTime()+0.1)
|
||||
return true
|
||||
end
|
||||
|
||||
function ENT:Open()
|
||||
self.Activated = true
|
||||
self:EmitSound("tdmg/themes/beep2.mp3")
|
||||
for i=1,4 do
|
||||
local mn = ents.Create("tdm_cmine2")
|
||||
mn:SetPos(self:GetPos())
|
||||
mn.Team = self.Team
|
||||
mn:Spawn()
|
||||
local n = 250
|
||||
mn:GetPhysicsObject():SetVelocity(Vector(math.random(-n,n),math.random(-n,n),n))
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Explode()
|
||||
if not self.Activated then return end
|
||||
|
||||
self.Activated = true
|
||||
self:EmitSound("tdmg/themes/beep1.mp3")
|
||||
|
||||
timer.Simple(0.2, function()
|
||||
if !IsValid(self) then return end
|
||||
|
||||
local explosion = ents.Create("env_explosion")
|
||||
explosion:SetPos(self:GetPos())
|
||||
explosion:Spawn()
|
||||
explosion:SetCreator(self)
|
||||
explosion.Team = self.Team
|
||||
explosion:SetKeyValue("iMagnitude", "200")
|
||||
explosion:Fire("Explode", 0, 0)
|
||||
self:Remove()
|
||||
end)
|
||||
end
|
||||
|
||||
function ENT:OnTakeDamage(dmginfo)
|
||||
local dmg = dmginfo:GetDamage()
|
||||
local att = dmginfo:GetAttacker()
|
||||
if att:IsPlayer() and att:Team() != self.Team then
|
||||
self:SetHealth(self:Health()-dmg)
|
||||
end
|
||||
end
|
||||
else
|
||||
local tm_mat = Material('tdmg/hud/teammate.png')
|
||||
function ENT:Draw()
|
||||
self:DrawModel()
|
||||
if self:GetNWFloat('Team') == LocalPlayer():Team() then
|
||||
local angle = EyeAngles()
|
||||
angle = Angle( 0, angle.y, 0 )
|
||||
angle:RotateAroundAxis( angle:Up(), -90 )
|
||||
angle:RotateAroundAxis( angle:Forward(), 90 )
|
||||
local pos = self:GetPos()+Vector(0,0,16)
|
||||
cam.Start3D2D( pos, angle, 0.1 )
|
||||
surface.SetDrawColor(5,155,255)
|
||||
surface.SetMaterial(tm_mat)
|
||||
surface.DrawTexturedRect(-12, -12, 24, 24)
|
||||
cam.End3D2D()
|
||||
end
|
||||
end
|
||||
end
|
||||
90
gamemodes/cod_custom/entities/entities/tdm_cmine2/shared.lua
Normal file
90
gamemodes/cod_custom/entities/entities/tdm_cmine2/shared.lua
Normal file
@@ -0,0 +1,90 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.Type = "anim"
|
||||
ENT.PrintName = "Mini Mine"
|
||||
|
||||
if SERVER then
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/tdmg/fieldupgrade_proximitymine.mdl")
|
||||
self:PhysicsInit(SOLID_VPHYSICS)
|
||||
self:SetMoveType(MOVETYPE_VPHYSICS)
|
||||
self:SetUseType(SIMPLE_USE)
|
||||
self:SetCollisionGroup(COLLISION_GROUP_DEBRIS)
|
||||
self:SetModelScale(0.8, 0)
|
||||
self:SetHealth(200)
|
||||
if not self.Team then
|
||||
self.Team = 1
|
||||
end
|
||||
self:SetNWFloat('Team', self.Team)
|
||||
timer.Simple(math.Rand(2,4), function()
|
||||
if IsValid(self) then
|
||||
self.Activated = true
|
||||
self:EmitSound("tdmg/themes/beep2.mp3")
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
if self.Activated then
|
||||
local y = self:GetAngles().y
|
||||
self:SetAngles(Angle(0,y,0))
|
||||
if self:Health() <= 0 then
|
||||
self:Explode()
|
||||
end
|
||||
for _, ply in ipairs(ents.FindInSphere(self:GetPos(), 32)) do
|
||||
if ply:IsPlayer() and ply:Team() != self.Team or ply:IsNPC() and ply.Team and ply.Team != self.Team then
|
||||
self:Explode()
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
self:NextThink(CurTime()+0.1)
|
||||
return true
|
||||
end
|
||||
|
||||
function ENT:Explode()
|
||||
if not self.Activated then return end
|
||||
|
||||
self.Activated = true
|
||||
self:EmitSound("tdmg/themes/beep1.mp3")
|
||||
|
||||
timer.Simple(0.2, function()
|
||||
if !IsValid(self) then return end
|
||||
|
||||
local explosion = ents.Create("env_explosion")
|
||||
explosion:SetPos(self:GetPos())
|
||||
explosion:Spawn()
|
||||
explosion:SetCreator(self)
|
||||
explosion.Team = self.Team
|
||||
explosion:SetKeyValue("iMagnitude", "150")
|
||||
explosion:Fire("Explode", 0, 0)
|
||||
self:Remove()
|
||||
end)
|
||||
end
|
||||
|
||||
function ENT:OnTakeDamage(dmginfo)
|
||||
local dmg = dmginfo:GetDamage()
|
||||
local att = dmginfo:GetAttacker()
|
||||
if att:IsPlayer() and att:Team() != self.Team then
|
||||
self:SetHealth(self:Health()-dmg)
|
||||
end
|
||||
end
|
||||
else
|
||||
local tm_mat = Material('tdmg/hud/teammate.png')
|
||||
function ENT:Draw()
|
||||
self:DrawModel()
|
||||
if self:GetNWFloat('Team') == LocalPlayer():Team() then
|
||||
local angle = EyeAngles()
|
||||
angle = Angle( 0, angle.y, 0 )
|
||||
angle:RotateAroundAxis( angle:Up(), -90 )
|
||||
angle:RotateAroundAxis( angle:Forward(), 90 )
|
||||
local pos = self:GetPos()+Vector(0,0,16)
|
||||
cam.Start3D2D( pos, angle, 0.1 )
|
||||
surface.SetDrawColor(5,155,255)
|
||||
surface.SetMaterial(tm_mat)
|
||||
surface.DrawTexturedRect(-12, -12, 24, 24)
|
||||
cam.End3D2D()
|
||||
end
|
||||
end
|
||||
end
|
||||
126
gamemodes/cod_custom/entities/entities/tdm_deathanim/init.lua
Normal file
126
gamemodes/cod_custom/entities/entities/tdm_deathanim/init.lua
Normal file
@@ -0,0 +1,126 @@
|
||||
AddCSLuaFile("shared.lua")
|
||||
include("shared.lua")
|
||||
|
||||
local function TransferBones(base, ragdoll)
|
||||
if !IsValid(base) or !IsValid(ragdoll) then return end
|
||||
for i = 0, ragdoll:GetPhysicsObjectCount() - 1 do
|
||||
local bone = ragdoll:GetPhysicsObjectNum( i )
|
||||
if ( IsValid( bone ) ) then
|
||||
local pos, ang = base:GetBonePosition( ragdoll:TranslatePhysBoneToBone( i ) )
|
||||
if ( pos ) then bone:SetPos( pos ) end
|
||||
if ( ang ) then bone:SetAngles( ang ) end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:ToRagdoll()
|
||||
if IsValid(self) then
|
||||
local rag = ents.Create("prop_ragdoll")
|
||||
rag:SetModel(self:GetModel())
|
||||
rag:SetPos(self:GetPos())
|
||||
rag:Spawn()
|
||||
rag:SetCollisionGroup(1)
|
||||
for i=1,math.random(2,8) do
|
||||
timer.Simple(i/math.Rand(2,4), function()
|
||||
if IsValid(rag) then
|
||||
util.Decal("Blood", rag:GetPos()+Vector(0,0,8), rag:GetPos()-Vector(math.random(-32,32), math.random(-32,32), 16))
|
||||
end
|
||||
end)
|
||||
end
|
||||
timer.Simple(42, function()
|
||||
if IsValid(rag) then
|
||||
rag:SetRenderFX(kRenderFxFadeSlow)
|
||||
end
|
||||
end)
|
||||
timer.Simple(45, function()
|
||||
if IsValid(rag) then
|
||||
rag:Remove()
|
||||
end
|
||||
end)
|
||||
if IsValid(self.Transform) then
|
||||
TransferBones(self.Transform, rag)
|
||||
if self.Transform.HeadBlow == true then
|
||||
self.Transform.HeadBlow = false
|
||||
rag:ManipulateBoneScale(rag:LookupBone("ValveBiped.Bip01_Head1"), Vector(0,0,0))
|
||||
for i=1,4 do
|
||||
local pos = rag:GetBonePosition(rag:LookupBone("ValveBiped.Bip01_Head1"))
|
||||
local m = ents.Create("prop_physics")
|
||||
m:SetModel("models/Gibs/HGIBS_scapula.mdl")
|
||||
m:SetPos(pos)
|
||||
m:SetAngles(AngleRand())
|
||||
m:Spawn()
|
||||
m:SetMaterial("models/flesh")
|
||||
m:SetCollisionGroup(1)
|
||||
m:GetPhysicsObject():SetVelocity(VectorRand(-64,64))
|
||||
|
||||
local ef = EffectData()
|
||||
ef:SetOrigin(pos)
|
||||
util.Effect("BloodImpact", ef)
|
||||
|
||||
timer.Simple(15, function()
|
||||
if !IsValid(m) then return end
|
||||
m:Remove()
|
||||
end)
|
||||
end
|
||||
end
|
||||
else
|
||||
TransferBones(self, rag)
|
||||
end
|
||||
self:Remove()
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Initialize()
|
||||
if !IsValid(self.Transform) then
|
||||
local anim = "dead"..math.random(1,54)
|
||||
|
||||
timer.Simple(0.1, function()
|
||||
if !IsValid(self) then return end
|
||||
net.Start("tdm.giveanim")
|
||||
net.WriteEntity(self)
|
||||
net.WriteString(anim)
|
||||
net.Broadcast()
|
||||
end)
|
||||
|
||||
self:ResetSequence(anim)
|
||||
self:EmitSound("tdmg/ply/death"..math.random(1,14)..".wav")
|
||||
|
||||
local mod = select(2, self:LookupSequence(anim))
|
||||
timer.Simple(mod, function()
|
||||
if !IsValid(self) then return end
|
||||
self:ToRagdoll()
|
||||
end)
|
||||
else
|
||||
self:ToRagdoll()
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
local tr1 = util.TraceLine({
|
||||
start = self:GetBonePosition(self:LookupBone('ValveBiped.Bip01_Head1')),
|
||||
endpos = self:GetBonePosition(self:LookupBone('ValveBiped.Bip01_Head1'))-self:GetForward()*4,
|
||||
filter = function( ent ) return ( ent:GetClass() == "prop_static" or ent:GetClass() == "prop_dynamic" or ent:GetClass() == "func_door" or ent:GetClass() == "func_door_rotating" or ent:GetClass() == "prop_door_rotating" ) end
|
||||
})
|
||||
local tr2 = util.TraceLine({
|
||||
start = self:GetBonePosition(self:LookupBone('ValveBiped.Bip01_Pelvis')),
|
||||
endpos = self:GetBonePosition(self:LookupBone('ValveBiped.Bip01_Pelvis'))-self:GetForward()*4,
|
||||
filter = function( ent ) return ( ent:GetClass() == "prop_static" or ent:GetClass() == "prop_dynamic" or ent:GetClass() == "func_door" or ent:GetClass() == "func_door_rotating" or ent:GetClass() == "prop_door_rotating" ) end
|
||||
})
|
||||
local tr3 = util.TraceLine({
|
||||
start = self:GetBonePosition(self:LookupBone('ValveBiped.Bip01_Head1')),
|
||||
endpos = self:GetBonePosition(self:LookupBone('ValveBiped.Bip01_Head1'))+self:GetForward()*4,
|
||||
filter = function( ent ) return ( ent:GetClass() == "prop_static" or ent:GetClass() == "prop_dynamic" or ent:GetClass() == "func_door" or ent:GetClass() == "func_door_rotating" or ent:GetClass() == "prop_door_rotating" ) end
|
||||
})
|
||||
local tr4 = util.TraceLine({
|
||||
start = self:GetBonePosition(self:LookupBone('ValveBiped.Bip01_Pelvis')),
|
||||
endpos = self:GetBonePosition(self:LookupBone('ValveBiped.Bip01_Pelvis'))+self:GetForward()*4,
|
||||
filter = function( ent ) return ( ent:GetClass() == "prop_static" or ent:GetClass() == "prop_dynamic" or ent:GetClass() == "func_door" or ent:GetClass() == "func_door_rotating" or ent:GetClass() == "prop_door_rotating" ) end
|
||||
})
|
||||
|
||||
if tr1.Hit or tr2.Hit or tr3.Hit or tr4.Hit then
|
||||
self:ToRagdoll()
|
||||
end
|
||||
|
||||
self:NextThink(CurTime())
|
||||
return true
|
||||
end
|
||||
@@ -0,0 +1,21 @@
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.Type = "anim"
|
||||
ENT.AutomaticFrameAdvance = true
|
||||
|
||||
function ENT:Think()
|
||||
self:NextThink(CurTime())
|
||||
return true
|
||||
end
|
||||
|
||||
if CLIENT then
|
||||
net.Receive("tdm.giveanim", function()
|
||||
local ent = net.ReadEntity()
|
||||
local str = net.ReadString()
|
||||
if IsValid(ent) then
|
||||
ent:SetCycle(0)
|
||||
ent:ResetSequence(str)
|
||||
end
|
||||
end)
|
||||
else
|
||||
util.AddNetworkString("tdm.giveanim")
|
||||
end
|
||||
@@ -0,0 +1,281 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.Type = "anim"
|
||||
ENT.AutomaticFrameAdvance = true
|
||||
|
||||
local SpeedMultiplier = 5
|
||||
|
||||
function ENT:GetLetter(small)
|
||||
local type = self:GetNWFloat('Point')
|
||||
local letter = ""
|
||||
if type == 1 then
|
||||
letter = "A"
|
||||
elseif type == 2 then
|
||||
letter = "B"
|
||||
elseif type == 3 then
|
||||
letter = "C"
|
||||
end
|
||||
if small then
|
||||
letter = string.lower(letter)
|
||||
end
|
||||
return letter
|
||||
end
|
||||
|
||||
if SERVER then
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/tdmg/anim_flag_rework.mdl")
|
||||
self:SetSolid(SOLID_VPHYSICS)
|
||||
self:SetMaterial('models/debug/debugwhite')
|
||||
self:ResetSequence("idle")
|
||||
self:SetModelScale(0.4, 0)
|
||||
self:SetNWFloat('Point', #ents.FindByClass("tdm_domination_flag"))
|
||||
self:SetNWFloat('Team', 0)
|
||||
self:SetNWFloat('Progress', 0)
|
||||
self:SetCollisionGroup(1)
|
||||
self.PreviousTakingTeam = 0
|
||||
self.CurrentTakingTeam = 0
|
||||
end
|
||||
|
||||
function ENT:PlayPhrase(type, team)
|
||||
for k, pl in ipairs(player.GetAll()) do
|
||||
if pl:Team() == team then
|
||||
if type == "capture" then
|
||||
pl:SendLua([[
|
||||
COD:SpeakerSay('tdmg/speaker/domination/friendly_captured_]]..self:GetLetter(true)..[[.wav')
|
||||
]])
|
||||
elseif type == "all_captured" then
|
||||
pl:SendLua([[
|
||||
COD:SpeakerSay('tdmg/speaker/domination/friendly_captured_all.wav')
|
||||
]])
|
||||
elseif type == "taking" then
|
||||
pl:SendLua([[
|
||||
COD:SpeakerSay('tdmg/speaker/domination/friendly_taking_]]..self:GetLetter(true)..[[ ('..math.random(1,3)..').wav')
|
||||
]])
|
||||
end
|
||||
else
|
||||
if type == "capture" then
|
||||
pl:SendLua([[
|
||||
COD:SpeakerSay('tdmg/speaker/domination/hostile_captured_]]..self:GetLetter(true)..[[ ('..math.random(1,2)..').wav')
|
||||
]])
|
||||
elseif type == "all_captured" then
|
||||
pl:SendLua([[
|
||||
COD:SpeakerSay('tdmg/speaker/domination/hostile_captured_all.wav')
|
||||
]])
|
||||
elseif type == "taking" then
|
||||
pl:SendLua([[
|
||||
COD:SpeakerSay('tdmg/speaker/domination/hostile_taking_]]..self:GetLetter(true)..[[ ('..math.random(1,3)..').wav')
|
||||
]])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Capture(team, plytab)
|
||||
if plytab then
|
||||
if self:GetNWFloat('Team') == 0 then
|
||||
COD:GiveMessageCenter(plytab, 10)
|
||||
for _, p in ipairs(plytab) do
|
||||
p:ChangeScore(200)
|
||||
end
|
||||
else
|
||||
COD:GiveMessageCenter(plytab, 11)
|
||||
for _, p in ipairs(plytab) do
|
||||
p:ChangeScore(100)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local type = self:GetLetter()
|
||||
self:SetNWFloat('Team', team)
|
||||
self:SetNWFloat('Progress', 0)
|
||||
self:PlayPhrase("capture", team)
|
||||
|
||||
local all = true
|
||||
for _, f in ipairs(ents.FindByClass("tdm_domination_flag")) do
|
||||
if f:GetNWFloat('Team') != team then
|
||||
all = false
|
||||
break
|
||||
end
|
||||
end
|
||||
if all then
|
||||
self:PlayPhrase("all_captured", team)
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
local t = self:GetNWFloat('Team')
|
||||
local prog = self:GetNWFloat('Progress')
|
||||
local haveplayers = false
|
||||
local teamcapture = 0
|
||||
local count = 0
|
||||
local plytab = {}
|
||||
|
||||
for k, v in ipairs(ents.FindInSphere(self:GetPos(), 72)) do
|
||||
if v:IsPlayer() and v:Alive() then
|
||||
if teamcapture == 0 then
|
||||
teamcapture = v:Team()
|
||||
count = count+1
|
||||
else
|
||||
if v:Team() == teamcapture then
|
||||
count = count+1
|
||||
elseif v:Team() != teamcapture then
|
||||
teamcapture = 0
|
||||
end
|
||||
end
|
||||
if teamcapture == v:Team() then
|
||||
table.insert(plytab, v)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self.PreviousTakingTeam = teamcapture
|
||||
|
||||
if teamcapture > 0 then
|
||||
if teamcapture == t then
|
||||
self:SetNWFloat('Progress', math.max(self:GetNWFloat('Progress')-FrameTime()/100*count*SpeedMultiplier, 0))
|
||||
else
|
||||
self:SetNWFloat('Progress', math.min(self:GetNWFloat('Progress')+FrameTime()/100*count*SpeedMultiplier, 1))
|
||||
if self.CurrentTakingTeam != self.PreviousTakingTeam then
|
||||
self:PlayPhrase("taking", teamcapture)
|
||||
end
|
||||
end
|
||||
if prog >= 1 then
|
||||
self:Capture(teamcapture, plytab)
|
||||
end
|
||||
self.CurrentTakingTeam = self.PreviousTakingTeam
|
||||
else
|
||||
self.CurrentTakingTeam = 0
|
||||
end
|
||||
|
||||
self:NextThink(CurTime())
|
||||
return true
|
||||
end
|
||||
else
|
||||
function ENT:Draw()
|
||||
self:DrawModel()
|
||||
local ply = LocalPlayer()
|
||||
local pteam = ply:Team()
|
||||
local fteam = self:GetNWFloat('Team')
|
||||
if fteam > 0 then
|
||||
if pteam == fteam then
|
||||
self:SetColor(Color(40,140,240))
|
||||
else
|
||||
self:SetColor(Color(240,0,0))
|
||||
end
|
||||
else
|
||||
self:SetColor(Color(200,200,200))
|
||||
end
|
||||
end
|
||||
hook.Add("HUDPaint", "TDM_DominationFlags", function()
|
||||
if COD.DataTable["Gamemode"] == 5 and not COD.HideHUD then
|
||||
for k, ent in ipairs(ents.FindByClass("tdm_domination_flag")) do
|
||||
if ent:GetPos():DistToSqr(LocalPlayer():GetPos()) <= 5184 then
|
||||
LocalPlayer().DrawDominationFlag = ent
|
||||
break
|
||||
else
|
||||
LocalPlayer().DrawDominationFlag = NULL
|
||||
end
|
||||
end
|
||||
local df = LocalPlayer().DrawDominationFlag
|
||||
for k, v in ipairs(ents.FindByClass("tdm_domination_flag")) do
|
||||
local t = v:GetNWFloat('Team')
|
||||
local type = v:GetNWFloat('Point')
|
||||
local prog = v:GetNWFloat('Progress')
|
||||
local myteam = LocalPlayer():Team() == t
|
||||
local pos = (v:GetPos()+Vector(0,0,180)):ToScreen()
|
||||
|
||||
if t > 0 then
|
||||
if myteam then
|
||||
surface.SetDrawColor(40,140,240)
|
||||
surface.DrawRect(pos.x-16, pos.y-16, 32, 32)
|
||||
|
||||
surface.SetDrawColor(240,0,0)
|
||||
surface.DrawRect(pos.x-16, pos.y-16, 32, 32*prog)
|
||||
|
||||
draw.SimpleText(COD.Language["hud_domination_2"], "Trebuchet18", pos.x, pos.y-32, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
|
||||
else
|
||||
surface.SetDrawColor(240,0,0)
|
||||
surface.DrawRect(pos.x-16, pos.y-16, 32, 32)
|
||||
|
||||
surface.SetDrawColor(40,140,240)
|
||||
surface.DrawRect(pos.x-16, pos.y-16, 32, 32*prog)
|
||||
|
||||
draw.SimpleText(COD.Language["hud_domination_1"], "Trebuchet18", pos.x, pos.y-32, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
|
||||
end
|
||||
else
|
||||
surface.SetDrawColor(200,200,200)
|
||||
surface.DrawRect(pos.x-16, pos.y-16, 32, 32)
|
||||
|
||||
surface.SetDrawColor(100,100,100)
|
||||
surface.DrawRect(pos.x-16, pos.y-16, 32, 32*prog)
|
||||
|
||||
draw.SimpleText(COD.Language["hud_domination_1"], "Trebuchet18", pos.x, pos.y-32, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
|
||||
end
|
||||
|
||||
draw.SimpleText(math.floor(LocalPlayer():GetPos():Distance(v:GetPos())/40).." m", "Trebuchet18", pos.x, pos.y+32, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
|
||||
|
||||
local letter = v:GetLetter()
|
||||
draw.SimpleText(letter, "DermaLarge", pos.x, pos.y, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
|
||||
end
|
||||
if IsValid(df) and LocalPlayer():Alive() then
|
||||
local prog = df:GetNWFloat('Progress')
|
||||
local lt = df:GetLetter()
|
||||
local t = df:GetNWFloat('Team') == LocalPlayer():Team()
|
||||
|
||||
if prog > 0 then
|
||||
surface.SetDrawColor(50,50,50)
|
||||
surface.DrawRect(ScrW()/2-150, 250, 300, 6)
|
||||
|
||||
surface.SetDrawColor(200,200,200)
|
||||
surface.DrawRect(ScrW()/2-150, 220, 24, 24)
|
||||
|
||||
draw.SimpleText(lt, "Trebuchet18", ScrW()/2-137, 233, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
|
||||
|
||||
if t then
|
||||
draw.SimpleText(COD.Language["hud_domination_2"], "Trebuchet18", ScrW()/2+150, 245, color_white, TEXT_ALIGN_RIGHT, TEXT_ALIGN_BOTTOM)
|
||||
|
||||
surface.SetDrawColor(250,0,0)
|
||||
surface.DrawRect(ScrW()/2-149, 251, 298*prog, 4)
|
||||
else
|
||||
COD:BeatsPlay("flag", prog)
|
||||
draw.SimpleText(COD.Language["hud_domination_3"], "Trebuchet18", ScrW()/2+150, 245, color_white, TEXT_ALIGN_RIGHT, TEXT_ALIGN_BOTTOM)
|
||||
|
||||
surface.SetDrawColor(50,150,250)
|
||||
surface.DrawRect(ScrW()/2-149, 251, 298*prog, 4)
|
||||
end
|
||||
else
|
||||
if t then
|
||||
draw.SimpleText(COD.Language["hud_domination_2"], "DermaLarge", ScrW()/2, 245, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
|
||||
|
||||
surface.SetDrawColor(0,100,200)
|
||||
surface.DrawRect(ScrW()/2-12, 265, 24, 24)
|
||||
|
||||
draw.SimpleText(lt, "Trebuchet18", ScrW()/2, 277, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
local beatdelay = 0
|
||||
function COD:BeatsPlay(type, float)
|
||||
if beatdelay > CurTime() or !GetConVar("cod_music_enable"):GetBool() then return end
|
||||
|
||||
local snd = ""
|
||||
if type == "flag" then
|
||||
if float > 0.9 then
|
||||
snd = "tdmg/themes/flag4.wav"
|
||||
elseif float > 0.7 then
|
||||
snd = "tdmg/themes/flag3.wav"
|
||||
elseif float > 0.4 then
|
||||
snd = "tdmg/themes/flag2.wav"
|
||||
else
|
||||
snd = "tdmg/themes/flag1.wav"
|
||||
end
|
||||
end
|
||||
|
||||
surface.PlaySound(snd)
|
||||
beatdelay = CurTime() + SoundDuration(snd)
|
||||
end
|
||||
end
|
||||
308
gamemodes/cod_custom/entities/entities/tdm_drone/shared.lua
Normal file
308
gamemodes/cod_custom/entities/entities/tdm_drone/shared.lua
Normal file
@@ -0,0 +1,308 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.Type = "anim"
|
||||
ENT.PrintName = "Bomb Drone"
|
||||
|
||||
if SERVER then
|
||||
util.AddNetworkString("COD.DroneCam")
|
||||
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/tdmg/drone_ex.mdl")
|
||||
self:ResetSequence("idle")
|
||||
self:SetHealth(100)
|
||||
self.Velo = {x = 0, y = 0, z = 0}
|
||||
self:SetSolid(SOLID_VPHYSICS)
|
||||
self:PhysicsInit(SOLID_VPHYSICS)
|
||||
self.MultSpeed = 200
|
||||
self.MaxSpeed = 200
|
||||
self.Smoking = false
|
||||
self.DeltaTime = 0
|
||||
self:SetNWFloat('RemoveTime', CurTime()+30)
|
||||
self:EmitSound("ambient/machines/spin_loop.wav", 80, 120, 1, CHAN_BODY)
|
||||
|
||||
timer.Simple(0.1, function()
|
||||
local ply = self:GetCreator()
|
||||
if !IsValid(ply) then return end
|
||||
|
||||
net.Start("COD.DroneCam")
|
||||
net.WriteEntity(self)
|
||||
net.Send(ply)
|
||||
|
||||
ply.ControllingKillstreak = true
|
||||
end)
|
||||
end
|
||||
|
||||
function ENT:OnRemove()
|
||||
self:StopSound("ambient/machines/spin_loop.wav")
|
||||
|
||||
local ply = self:GetCreator()
|
||||
if !IsValid(ply) then return end
|
||||
ply.ControllingKillstreak = false
|
||||
end
|
||||
|
||||
function ENT:PathNotBlock()
|
||||
local tr = util.TraceLine( {
|
||||
start = self:GetPos(),
|
||||
endpos = self:GetPos() - self:GetRight() * 16,
|
||||
filter = function(ent)
|
||||
if ent != self then
|
||||
return true
|
||||
end
|
||||
end
|
||||
})
|
||||
return not tr.Hit
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
local ply = self:GetCreator()
|
||||
if !IsValid(ply) then
|
||||
self:Remove()
|
||||
else
|
||||
local mu = self.MultSpeed
|
||||
local ms = self.MaxSpeed
|
||||
local phys = self:GetPhysicsObject()
|
||||
local vel = phys:GetVelocity()
|
||||
|
||||
local pos = self:GetPos()
|
||||
local ang = ply:EyeAngles().y
|
||||
ply:SetActiveWeapon(nil)
|
||||
if self:PathNotBlock() then
|
||||
phys:SetVelocityInstantaneous(self:GetForward()*self.Velo.x+self:GetRight()*self.Velo.y+self:GetUp()*self.Velo.z+Vector(0,0,10))
|
||||
else
|
||||
phys:SetVelocityInstantaneous(Vector(0,0,10))
|
||||
end
|
||||
if ply:KeyDown(IN_FORWARD) then
|
||||
self.Velo.x = math.Clamp(self.Velo.x+FrameTime()*mu, -ms, ms)
|
||||
elseif ply:KeyDown(IN_BACK) then
|
||||
self.Velo.x = math.Clamp(self.Velo.x-FrameTime()*mu, -ms, ms)
|
||||
end
|
||||
if ply:KeyDown(IN_MOVELEFT) then
|
||||
self.Velo.y = math.Clamp(self.Velo.y-FrameTime()*mu, -ms, ms)
|
||||
elseif ply:KeyDown(IN_MOVERIGHT) then
|
||||
self.Velo.y = math.Clamp(self.Velo.y+FrameTime()*mu, -ms, ms)
|
||||
end
|
||||
if ply:KeyDown(IN_DUCK) then
|
||||
self.Velo.z = math.Clamp(self.Velo.z-FrameTime()*mu, -ms, ms)
|
||||
elseif ply:KeyDown(IN_SPEED) then
|
||||
self.Velo.z = math.Clamp(self.Velo.z+FrameTime()*mu, -ms, ms)
|
||||
end
|
||||
if not ply:KeyDown(IN_FORWARD) and not ply:KeyDown(IN_BACK) then
|
||||
if self.Velo.x > 5 or self.Velo.x < -5 then
|
||||
if self.Velo.x > 0 then
|
||||
self.Velo.x = math.Clamp(self.Velo.x-FrameTime()*mu, -ms, ms)
|
||||
elseif self.Velo.x < 0 then
|
||||
self.Velo.x = math.Clamp(self.Velo.x+FrameTime()*mu, -ms, ms)
|
||||
end
|
||||
else
|
||||
self.Velo.x = 0
|
||||
end
|
||||
end
|
||||
if not ply:KeyDown(IN_SPEED) and not ply:KeyDown(IN_DUCK) then
|
||||
if self.Velo.z > 5 or self.Velo.z < -5 then
|
||||
if self.Velo.z > 0 then
|
||||
self.Velo.z = math.Clamp(self.Velo.z-FrameTime()*mu, -ms, ms)
|
||||
elseif self.Velo.z < 0 then
|
||||
self.Velo.z = math.Clamp(self.Velo.z+FrameTime()*mu, -ms, ms)
|
||||
end
|
||||
else
|
||||
self.Velo.z = 0
|
||||
end
|
||||
end
|
||||
if not ply:KeyDown(IN_MOVELEFT) and not ply:KeyDown(IN_MOVERIGHT) then
|
||||
if self.Velo.y > 5 or self.Velo.y < -5 then
|
||||
if self.Velo.y > 0 then
|
||||
self.Velo.y = math.Clamp(self.Velo.y-FrameTime()*mu, -ms, ms)
|
||||
elseif self.Velo.y < 0 then
|
||||
self.Velo.y = math.Clamp(self.Velo.y+FrameTime()*mu, -ms, ms)
|
||||
end
|
||||
else
|
||||
self.Velo.y = 0
|
||||
end
|
||||
end
|
||||
if ply:KeyDown(IN_ATTACK) or self:Health() < 0 or self:GetNWFloat('RemoveTime') < CurTime() then
|
||||
self:Explode()
|
||||
end
|
||||
|
||||
local b = {}
|
||||
b.secondstoarrive = 1
|
||||
b.pos = self:GetPos()
|
||||
b.angle = Angle(0,ang,0)
|
||||
b.maxangular = 20
|
||||
b.maxangulardamp = 5
|
||||
b.maxspeed = 10
|
||||
b.maxspeeddamp = 5
|
||||
b.dampfactor = 0.8
|
||||
b.teleportdistance = 0
|
||||
b.deltatime = CurTime()-self.DeltaTime
|
||||
phys:ComputeShadowControl(b)
|
||||
|
||||
self.DeltaTime = CurTime()
|
||||
self:NextThink(CurTime())
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Explode()
|
||||
local explosion = ents.Create("env_explosion")
|
||||
explosion:SetPos(self:GetPos())
|
||||
explosion:Spawn()
|
||||
explosion:SetCreator(self)
|
||||
explosion.Team = self.Team
|
||||
explosion:SetKeyValue("iMagnitude", "300")
|
||||
explosion:Fire("Explode", 0, 0)
|
||||
self:Remove()
|
||||
end
|
||||
|
||||
function ENT:OnTakeDamage(dmgt)
|
||||
local dmg = dmgt:GetDamage()
|
||||
local att = dmgt:GetAttacker()
|
||||
if att != self or att:IsPlayer() and att:Team() != self.Team then
|
||||
self:SetHealth(self:Health()-dmg)
|
||||
if IsValid(self:GetCreator()) then
|
||||
self:GetCreator():ViewPunch(AngleRand(-1,1))
|
||||
self:EmitSound("physics/metal/metal_box_impact_bullet"..math.random(1,3)..".wav")
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
local function CanSee(pos1, pos2)
|
||||
local tr = util.TraceLine( {
|
||||
start = pos1,
|
||||
endpos = pos2,
|
||||
filter = function(ent) if ent:IsWorld() then return true end end,
|
||||
})
|
||||
return !tr.Hit
|
||||
end
|
||||
|
||||
local enemyMat = Material("tdmg/hud/radar/enemy.png", "noclamp")
|
||||
local glitchMat = Material("tdmg/hud/screenglitch.jpg", "noclamp")
|
||||
|
||||
net.Receive("COD.DroneCam", function()
|
||||
local ent = net.ReadEntity()
|
||||
local alpha = 0
|
||||
local downa = false
|
||||
local tab = {
|
||||
[ "$pp_colour_addr" ] = 0,
|
||||
[ "$pp_colour_addg" ] = 0,
|
||||
[ "$pp_colour_addb" ] = 0,
|
||||
[ "$pp_colour_brightness" ] = 0,
|
||||
[ "$pp_colour_contrast" ] = 0.9,
|
||||
[ "$pp_colour_colour" ] = 0.1,
|
||||
[ "$pp_colour_mulr" ] = 0,
|
||||
[ "$pp_colour_mulg" ] = 0,
|
||||
[ "$pp_colour_mulb" ] = 0
|
||||
}
|
||||
|
||||
hook.Add("RenderScreenspaceEffects", "DroneCam", function()
|
||||
DrawColorModify(tab)
|
||||
end)
|
||||
|
||||
hook.Add("HUDPaint", "DroneCam", function()
|
||||
surface.SetDrawColor(50,50,50,100)
|
||||
surface.SetMaterial(glitchMat)
|
||||
surface.DrawTexturedRect(0, 0, ScrW(), ScrH())
|
||||
|
||||
surface.SetDrawColor(255,255,255)
|
||||
surface.DrawOutlinedRect(50, 50, ScrW()-100, ScrH()-100, 2)
|
||||
|
||||
surface.SetDrawColor(255,255,255,255)
|
||||
surface.DrawRect(ScrW()/2-15, ScrH()/2-1, 30, 2)
|
||||
|
||||
|
||||
surface.SetDrawColor(255,255,255,255)
|
||||
surface.DrawRect(ScrW()/2-1, ScrH()/2-16, 2, 30)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
draw.SimpleText("✷ BOMB DRONE", "DermaLarge", 100, 100, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
|
||||
draw.SimpleText("ACTIVE", "DermaLarge", 100, 130, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
|
||||
|
||||
draw.SimpleText("PRESS LMB TO EXPLODE", "DermaLarge", ScrW()-100, ScrH()-130, color_white, TEXT_ALIGN_RIGHT, TEXT_ALIGN_TOP)
|
||||
draw.SimpleText("SHIFT TO UPPER", "DermaLarge", ScrW()-100, ScrH()-160, color_white, TEXT_ALIGN_RIGHT, TEXT_ALIGN_TOP)
|
||||
draw.SimpleText("CTRL TO LOWER", "DermaLarge", ScrW()-100, ScrH()-190, color_white, TEXT_ALIGN_RIGHT, TEXT_ALIGN_TOP)
|
||||
|
||||
if downa then
|
||||
alpha = alpha - FrameTime()*512
|
||||
if alpha <= 0 then
|
||||
downa = false
|
||||
end
|
||||
else
|
||||
alpha = alpha + FrameTime()*512
|
||||
if alpha >= 255 then
|
||||
downa = true
|
||||
end
|
||||
end
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
surface.SetDrawColor(220,220,220,255)
|
||||
surface.DrawRect(75, ScrH()-220, 300*((ent:GetNWFloat('RemoveTime')-CurTime())/30), 15)
|
||||
|
||||
surface.SetDrawColor(255,255,255,255)
|
||||
surface.DrawOutlinedRect(75, ScrH()-220, 300, 15, 2)
|
||||
|
||||
draw.SimpleText("BATTERY", "DermaLarge", 75, ScrH()-250, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
|
||||
|
||||
surface.SetDrawColor(220,220,220,255)
|
||||
surface.DrawRect(75, ScrH()-120, 300*(ent:Health()/100), 15)
|
||||
|
||||
surface.SetDrawColor(255,255,255)
|
||||
surface.DrawOutlinedRect(75, ScrH()-120, 300, 15, 2)
|
||||
|
||||
draw.SimpleText("HEALTH", "DermaLarge", 75, ScrH()-150, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
|
||||
---------------------------------------------------------------------------------
|
||||
|
||||
for _, ply in ipairs(player.GetAll()) do
|
||||
if ply:Alive() and ply:Team() != LocalPlayer():Team() and ply:GetNWFloat('Perk2') != 4 then
|
||||
local pos = ply:WorldSpaceCenter():ToScreen()
|
||||
|
||||
if CanSee(EyePos(), ply:WorldSpaceCenter()) then
|
||||
surface.SetDrawColor(200,0,0,200)
|
||||
elseif ply:WorldSpaceCenter():DistToSqr(EyePos()) < 1500000 then
|
||||
surface.SetDrawColor(255,255,255,100)
|
||||
surface.DrawRect(pos.x-1, pos.y-5, 1, 10)
|
||||
surface.SetDrawColor(255,255,255,100)
|
||||
surface.DrawRect(pos.x-5, pos.y-1, 10, 1)
|
||||
|
||||
surface.SetDrawColor(200,200,200,50)
|
||||
else
|
||||
surface.SetDrawColor(0,0,0,0)
|
||||
end
|
||||
surface.SetMaterial(enemyMat)
|
||||
surface.DrawTexturedRect(pos.x-20, pos.y-20, 40, 40)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
hook.Add("CreateMove", "DroneCam", function(cmd)
|
||||
cmd:SetForwardMove(0)
|
||||
cmd:SetSideMove(0)
|
||||
cmd:RemoveKey(IN_JUMP)
|
||||
cmd:RemoveKey(IN_USE)
|
||||
end)
|
||||
|
||||
hook.Add("CalcView", "DroneCam", function( ply, pos, angles, fov )
|
||||
if IsValid(ent) then
|
||||
COD.HideHUD = true
|
||||
COD.HUD_DisableSomeThink = true
|
||||
local pos1 = ent:GetPos()-ent:GetUp()*1-ent:GetForward()*4
|
||||
local ang1 = angles
|
||||
local view = {
|
||||
origin = pos1,
|
||||
angles = ang1,
|
||||
fov = fov,
|
||||
drawviewer = true
|
||||
}
|
||||
|
||||
return view
|
||||
else
|
||||
COD.HideHUD = false
|
||||
COD.HUD_DisableSomeThink = false
|
||||
hook.Remove("CalcView", "DroneCam")
|
||||
hook.Remove("CreateMove", "DroneCam")
|
||||
hook.Remove("RenderScreenspaceEffects", "DroneCam")
|
||||
hook.Remove("HUDPaint", "DroneCam")
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end
|
||||
75
gamemodes/cod_custom/entities/entities/tdm_flash/shared.lua
Normal file
75
gamemodes/cod_custom/entities/entities/tdm_flash/shared.lua
Normal file
@@ -0,0 +1,75 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.Type = "anim"
|
||||
ENT.PrintName = "Flash Grenade"
|
||||
|
||||
if SERVER then
|
||||
util.AddNetworkString("COD.FlashLight")
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/weapons/w_eq_flashbang.mdl")
|
||||
self:PhysicsInit(SOLID_VPHYSICS)
|
||||
self:SetMoveType(MOVETYPE_VPHYSICS)
|
||||
self:SetUseType(SIMPLE_USE)
|
||||
self:SetCollisionGroup(COLLISION_GROUP_DEBRIS)
|
||||
timer.Simple(3, function()
|
||||
if IsValid(self) then
|
||||
self:Explode(self.Player)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function ENT:PhysicsCollide( data, phys )
|
||||
if data.Speed > 50 then
|
||||
self:EmitSound("weapons/flashbang/grenade_hit1.wav")
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Explode(ply)
|
||||
local givehitmarker = false
|
||||
for _, p in ipairs(ents.FindInSphere(self:GetPos(), 400)) do
|
||||
if p:IsPlayer() and (p:Team() != ply:Team() or p == ply) and p:IsLineOfSightClear(self) then
|
||||
p:SetDSP(32)
|
||||
p:ScreenFade(SCREENFADE.IN, color_white, 4, 4)
|
||||
givehitmarker = true
|
||||
end
|
||||
if p.FlashEntity and p.Team != ply:Team() and p:IsLineOfSightClear(self) then
|
||||
p:FlashEntity()
|
||||
end
|
||||
end
|
||||
|
||||
if givehitmarker then
|
||||
net.Start("COD.HitMarkEnemy")
|
||||
net.WriteBool(false)
|
||||
net.WriteBool(false)
|
||||
net.Send(ply)
|
||||
end
|
||||
|
||||
net.Start("COD.FlashLight")
|
||||
net.WriteEntity(self)
|
||||
net.Broadcast()
|
||||
|
||||
self:EmitSound("weapons/flashbang/flashbang_explode2.wav")
|
||||
timer.Simple(0.1, function()
|
||||
if !IsValid(self) then return end
|
||||
self:Remove()
|
||||
end)
|
||||
end
|
||||
else
|
||||
net.Receive("COD.FlashLight", function()
|
||||
local ent = net.ReadEntity()
|
||||
if IsValid(ent) then
|
||||
local dl = DynamicLight(ent)
|
||||
if dl then
|
||||
dl.pos = ent:GetPos()
|
||||
dl.r = 255
|
||||
dl.g = 255
|
||||
dl.b = 255
|
||||
dl.brightness = 2
|
||||
dl.Decay = 1000
|
||||
dl.Size = 256
|
||||
dl.DieTime = CurTime() + 1
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
38
gamemodes/cod_custom/entities/entities/tdm_frag/shared.lua
Normal file
38
gamemodes/cod_custom/entities/entities/tdm_frag/shared.lua
Normal file
@@ -0,0 +1,38 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.Type = "anim"
|
||||
ENT.PrintName = "Frag Grenade"
|
||||
|
||||
if SERVER then
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/cod/eqp_lethal_frag.mdl")
|
||||
self:PhysicsInit(SOLID_VPHYSICS)
|
||||
self:SetMoveType(MOVETYPE_VPHYSICS)
|
||||
self:SetUseType(SIMPLE_USE)
|
||||
self:SetCollisionGroup(COLLISION_GROUP_DEBRIS)
|
||||
timer.Simple(4, function()
|
||||
if IsValid(self) then
|
||||
self:Explode(self.Player)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function ENT:PhysicsCollide( data, phys )
|
||||
if data.Speed > 50 then
|
||||
self:EmitSound("weapons/hegrenade/he_bounce-1.wav")
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Explode(ply)
|
||||
util.BlastDamage(ply, ply, self:GetPos(), 400, 200)
|
||||
local detonate = ents.Create( "env_explosion" )
|
||||
detonate:SetPos(self.Entity:GetPos())
|
||||
detonate:SetKeyValue("iMagnitude", "0")
|
||||
detonate:Spawn()
|
||||
detonate:Activate()
|
||||
detonate:Fire("Explode", "", 0)
|
||||
self:EmitSound("ambient/explosions/explode_2.wav")
|
||||
self:Remove()
|
||||
end
|
||||
end
|
||||
229
gamemodes/cod_custom/entities/entities/tdm_harrier/shared.lua
Normal file
229
gamemodes/cod_custom/entities/entities/tdm_harrier/shared.lua
Normal file
@@ -0,0 +1,229 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.Type = "anim"
|
||||
ENT.PrintName = "VTOL"
|
||||
ENT.AutomaticFrameAdvance = true
|
||||
|
||||
if SERVER then
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/tdmg/harrier.mdl")
|
||||
self:SetHealth(3500)
|
||||
self.Velo = {x = 0, y = 0}
|
||||
self:SetSolid(SOLID_VPHYSICS)
|
||||
self:PhysicsInit(SOLID_VPHYSICS)
|
||||
self.Height = COD.DataTable["AirVehicle_FlyHeight"]
|
||||
self.Smoking = false
|
||||
self.DisableThinkPart = false
|
||||
self.CantBeDamaged = true
|
||||
self.FireDelay = CurTime() + 1
|
||||
self.SeekDelay = CurTime() + 2
|
||||
self:SetNWFloat('RemoveTime', CurTime() + 60)
|
||||
self.Removing = false
|
||||
self.Target = nil
|
||||
self.Team = 1
|
||||
self.Actions = {
|
||||
["MoveForward"] = false,
|
||||
["MoveBack"] = false,
|
||||
["MoveLeft"] = false,
|
||||
["MoveRight"] = false,
|
||||
}
|
||||
self:SetBodygroup(3, 1)
|
||||
self:SetBodygroup(4, 1)
|
||||
self:ManipulateBoneScale(10, Vector(0,0,0))
|
||||
self:ManipulateBoneScale(11, Vector(0,0,0))
|
||||
self:ManipulateBoneScale(7, Vector(0,0,0))
|
||||
timer.Simple(1, function()
|
||||
if !IsValid(self) then return end
|
||||
self:EmitSound("ambient/machines/aircraft_distant_flyby3.wav", 90, 90, 1)
|
||||
end)
|
||||
self:PlaySeq("arrive", 10, function()
|
||||
self:EmitSound(")ambient/energy/force_field_loop1.wav", 90, 70, 1)
|
||||
end)
|
||||
|
||||
timer.Simple(5, function()
|
||||
if !IsValid(self) then return end
|
||||
|
||||
if self.Team == 1 then
|
||||
self.VJ_NPC_Class = {"CLASS_SPECGRU"}
|
||||
elseif self.Team == 2 then
|
||||
self.VJ_NPC_Class = {"CLASS_KORTAC"}
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function ENT:PlaySeq(name, long, onfinish)
|
||||
self:SetCycle(0)
|
||||
self:ResetSequence(name)
|
||||
self.CantBeDamaged = true
|
||||
self:SetNotSolid(true)
|
||||
|
||||
if !isfunction(onfinish) then
|
||||
onfinish = function() end
|
||||
end
|
||||
|
||||
timer.Create("MI24Anim"..self:EntIndex(), long, 1, function()
|
||||
if !IsValid(self) then return end
|
||||
|
||||
self:ResetSequence("idle")
|
||||
self:SetNotSolid(false)
|
||||
self.CantBeDamaged = false
|
||||
onfinish()
|
||||
end)
|
||||
end
|
||||
|
||||
function ENT:OnRemove()
|
||||
self:StopSound(")ambient/energy/force_field_loop1.wav")
|
||||
end
|
||||
|
||||
function ENT:GetTurretPos()
|
||||
local bone = self:GetPos()+self:GetForward()*96
|
||||
return bone
|
||||
end
|
||||
|
||||
function ENT:Attack()
|
||||
local tar = self.Target
|
||||
|
||||
if !IsValid(tar) then
|
||||
local tab = ents.FindInSphere(self:GetPos(), 4096)
|
||||
table.Shuffle(tab)
|
||||
for _, ent in ipairs(tab) do
|
||||
if self:VisibleVec(ent:GetPos()) then
|
||||
if ent:IsNPC() and ent:Health() > 0 and (ent.Team and ent.Team != self.Team or !ent.Team) then
|
||||
self.Target = ent
|
||||
break
|
||||
end
|
||||
if ent:IsPlayer() and ent:Alive() and ent:Team() != self.Team and ent:GetNWFloat('Perk2') != 4 then
|
||||
self.Target = ent
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if IsValid(tar) and self.FireDelay < CurTime() then
|
||||
self.FireDelay = CurTime() + 0.06
|
||||
|
||||
if self:AngleToEnemy(tar) < 45 and self.SeekDelay < CurTime() then
|
||||
local dir = (tar:GetPos()-self:GetTurretPos()):GetNormalized()
|
||||
|
||||
self:EmitSound("weapons/ar2/fire1.wav", 90, 85, 1, CHAN_WEAPON)
|
||||
self:FireBullets({
|
||||
IgnoreEntity = self,
|
||||
Spread = VectorRand(-0.06, 0.06),
|
||||
Damage = 25,
|
||||
Dir = dir,
|
||||
Src = self:GetTurretPos(),
|
||||
})
|
||||
end
|
||||
|
||||
if not self:VisibleVec(tar:GetPos()) or tar:Health() <= 0 then
|
||||
self.SeekDelay = CurTime() + 2
|
||||
self.Target = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:AngleToEnemy(enemy)
|
||||
local selfAngles = self:GetAngles()
|
||||
local enemyPos = enemy:GetPos()
|
||||
local angleToEnemy = (enemyPos - self:GetPos()):Angle()
|
||||
angleToEnemy.x = 0
|
||||
angleToEnemy.z = 0
|
||||
local diff = math.AngleDifference(angleToEnemy.y, selfAngles.y)
|
||||
return math.abs(diff)
|
||||
end
|
||||
|
||||
function ENT:RotateToEntity(ent2, divisor)
|
||||
local ent1Angles = self:GetAngles()
|
||||
local targetAngles = (ent2:GetPos() - self:GetPos()):Angle()
|
||||
local yawDiff = math.NormalizeAngle(targetAngles.y - ent1Angles.y)
|
||||
|
||||
self:SetAngles(Angle(0, ent1Angles.y + yawDiff / divisor, 0))
|
||||
end
|
||||
|
||||
function ENT:Controls()
|
||||
local tar = self.Target
|
||||
if IsValid(tar) then
|
||||
self:RotateToEntity(tar, 45)
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
local mu = self.MultSpeed
|
||||
local ms = self.MaxSpeed
|
||||
local vel = self:GetPhysicsObject():GetVelocity()
|
||||
vel.z = 0
|
||||
|
||||
if not self.DisableThinkPart then
|
||||
if not self.CantBeDamaged then
|
||||
self:Attack()
|
||||
self:Controls()
|
||||
end
|
||||
|
||||
local pos = self:GetPos()
|
||||
self:SetPos(Vector(pos.x, pos.y, self.Height))
|
||||
local ang = self:GetAngles().y
|
||||
self:SetAngles(Angle(0,ang,0))
|
||||
|
||||
if self:GetNWFloat('RemoveTime') < CurTime() and not self.Removing and not self.DisableThinkPart then
|
||||
self.Removing = true
|
||||
self:EmitSound("ambient/machines/aircraft_distant_flyby1.wav", 90, 90, 1)
|
||||
self:StopSound("ambient/energy/force_field_loop1.wav")
|
||||
self:PlaySeq("finish", 4, function()
|
||||
self:Remove()
|
||||
end)
|
||||
end
|
||||
if self:Health() <= 1000 and not self.Smoking then
|
||||
self.Smoking = true
|
||||
ParticleEffectAttach("Rocket_Smoke_Trail", 4, self, 2)
|
||||
end
|
||||
if self:Health() <= 0 then
|
||||
self:DestroyHeli()
|
||||
end
|
||||
end
|
||||
|
||||
self:ManipulateBoneAngles(0, Angle(0,(math.sin(CurTime())*4),(math.sin(CurTime()*2)*4)))
|
||||
self:ManipulateBonePosition(0, Vector(0,0,(math.sin(CurTime())*10)))
|
||||
|
||||
self:NextThink(CurTime())
|
||||
return true
|
||||
end
|
||||
|
||||
function ENT:OnTakeDamage(dmgt)
|
||||
if self.CantBeDamaged then return end
|
||||
local dmg = dmgt:GetDamage()
|
||||
local att = dmgt:GetAttacker()
|
||||
if att != self or att:IsPlayer() and att:Team() != self.Team then
|
||||
self:SetHealth(self:Health()-dmg)
|
||||
if IsValid(self:GetCreator()) then
|
||||
self:GetCreator():ViewPunch(AngleRand(-1,1))
|
||||
self:EmitSound("physics/metal/metal_box_impact_bullet"..math.random(1,3)..".wav")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:DestroyHeli()
|
||||
self.DisableThinkPart = true
|
||||
self.DestroyVelocity = 2000
|
||||
self:EmitSound("ambient/explosions/explode_9.wav")
|
||||
self.PhysicsCollide = function(self)
|
||||
ParticleEffect("explosion_huge_h", self:GetPos()+Vector(0,0,32), Angle(0,0,0))
|
||||
self:EmitSound("tdmg/a10_explosion.wav", 0)
|
||||
self:Remove()
|
||||
end
|
||||
self.Think = function(self)
|
||||
local RPM = self.DestroyVelocity
|
||||
local p = self:GetPhysicsObject()
|
||||
if IsValid(p) then
|
||||
local angvel = p:GetAngleVelocity()
|
||||
p:AddAngleVelocity(Vector(angvel.x > 100 and 0 or RPM*0.01,0,angvel.z > 200 and 0 or math.Clamp(RPM,0,4000)*0.04))
|
||||
|
||||
local vel = p:GetVelocity()
|
||||
p:SetVelocity(-vel-Vector(0,0,500))
|
||||
end
|
||||
self:NextThink(CurTime())
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
include("shared.lua")
|
||||
|
||||
function ENT:DrawTranslucent(flags)
|
||||
self:DrawModel(flags)
|
||||
end
|
||||
@@ -0,0 +1,4 @@
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
|
||||
include("shared.lua")
|
||||
266
gamemodes/cod_custom/entities/entities/tdm_infil/shared.lua
Normal file
266
gamemodes/cod_custom/entities/entities/tdm_infil/shared.lua
Normal file
@@ -0,0 +1,266 @@
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.Type = "anim"
|
||||
|
||||
ENT.Spawnable = true
|
||||
ENT.AdminOnly = true
|
||||
ENT.PrintName = "Helicoper"
|
||||
ENT.Category = "BWA"
|
||||
ENT.RenderGroup = RENDERGROUP_TRANSLUCENT
|
||||
ENT.Model = Model("models/tdmg/heli.mdl")
|
||||
ENT.AutomaticFrameAdvance = true
|
||||
|
||||
ENT.SoundTable = {
|
||||
{
|
||||
t = 0,
|
||||
s = "tdmg/sas1_veh1_int_quad_front_stat.wav",
|
||||
b = "tag_main_rotor_static",
|
||||
v = 250
|
||||
},
|
||||
{
|
||||
t = 0,
|
||||
s = "tdmg/sas1_veh1_ceilingrattles_spot_stat.wav",
|
||||
b = "tag_main_rotor_static"
|
||||
},
|
||||
{
|
||||
t = 0,
|
||||
s = "tdmg/sas1_veh1_int_quad_rear_stat.wav",
|
||||
b = "tail_rotor_jnt",
|
||||
v = 135
|
||||
},
|
||||
{
|
||||
t = 22 / 30,
|
||||
s = "tdmg/sas1_veh1_foley_doorman_npc.wav",
|
||||
b = "tag_origin"
|
||||
},
|
||||
{
|
||||
t = 22 / 30,
|
||||
s = "tdmg/sas1_veh1_door_ster_pan.wav",
|
||||
b = "tag_origin"
|
||||
},
|
||||
{
|
||||
t = 0,
|
||||
s = "tdmg/sas1_veh1_foley_seat1_plr.wav",
|
||||
b = "tag_origin"
|
||||
},
|
||||
{
|
||||
t = 42 / 30,
|
||||
s = "tdmg/sas1_veh1_rope_spot_stat.wav",
|
||||
b = "tag_origin"
|
||||
},
|
||||
{
|
||||
t = 184 / 30,
|
||||
s = "tdmg/sas1_veh1_foley_seat1_npc.wav",
|
||||
b = "tag_origin"
|
||||
},
|
||||
{
|
||||
t = 190 / 30,
|
||||
s = "tdmg/sas1_veh1_foley_seat2_npc.wav",
|
||||
b = "tag_origin"
|
||||
},
|
||||
{
|
||||
t = 280 / 30,
|
||||
s = "tdmg/sas1_veh1_foley_seat3_npc.wav",
|
||||
b = "tag_origin"
|
||||
},
|
||||
{
|
||||
t = 328 / 30,
|
||||
s = "tdmg/sas1_veh1_ext_ster_pan.wav",
|
||||
b = "tag_origin"
|
||||
},
|
||||
}
|
||||
|
||||
function ENT:Initialize()
|
||||
self:SetModel(self.Model)
|
||||
|
||||
if SERVER then
|
||||
self:SetHealth(1)
|
||||
self:SetPos(self:GetPos() + Vector(0, 0, 10))
|
||||
|
||||
local tr = {
|
||||
start = self:GetPos(),
|
||||
endpos = self:GetPos() + Vector(0, 0, 512)
|
||||
}
|
||||
|
||||
if tr.HitSky then
|
||||
self:SetAngles(Angle(0, math.Rand(0, 360), 0))
|
||||
else
|
||||
local testpos = self:GetPos() + Vector(0, 0, 512)
|
||||
|
||||
local amt = 15
|
||||
|
||||
local best = 0
|
||||
local best_dist = math.huge
|
||||
|
||||
local offset = math.Rand(0, 360)
|
||||
|
||||
for i = 1, amt do
|
||||
local angle = math.Rand(0, 360)
|
||||
|
||||
local str = util.TraceLine({
|
||||
start = testpos,
|
||||
endpos = testpos + Angle(0, angle + offset, 0):Forward() * 10000
|
||||
})
|
||||
|
||||
if str.HitSky then
|
||||
best = angle
|
||||
break
|
||||
elseif str.Fraction == 1 then
|
||||
best = angle
|
||||
break
|
||||
elseif str.Fraction * 10000 > best_dist then
|
||||
best = angle
|
||||
best_dist = str.Fraction * 10000
|
||||
end
|
||||
end
|
||||
|
||||
self:SetAngles(Angle(0, best + offset + 180 - 10, 0))
|
||||
self:SetPos(self:LocalToWorld(-Vector(107.472321, -70.542793, 0)))
|
||||
end
|
||||
end
|
||||
|
||||
timer.Simple(14, function()
|
||||
if !IsValid(self) then return end
|
||||
self:Finish()
|
||||
end)
|
||||
|
||||
timer.Simple(31.6, function()
|
||||
if !IsValid(self) then return end
|
||||
|
||||
self:SetRenderFX(kRenderFxFadeSlow)
|
||||
end)
|
||||
|
||||
timer.Simple(36.6, function()
|
||||
if !IsValid(self) then return end
|
||||
|
||||
if SERVER then
|
||||
self:Remove()
|
||||
end
|
||||
end)
|
||||
|
||||
if CLIENT then return end
|
||||
self:ResetSequence("spawn")
|
||||
|
||||
for _, s in ipairs(self.SoundTable) do
|
||||
timer.Simple(s.t, function()
|
||||
if !IsValid(self) then return end
|
||||
|
||||
local sproxy = ents.Create("tdm_infil_soundproxy")
|
||||
sproxy:SetOwner(self:GetOwner())
|
||||
sproxy:SetPos(self:GetPos())
|
||||
sproxy:SetAngles(self:GetAngles())
|
||||
sproxy:SetParent(self)
|
||||
sproxy.Sound = s.s
|
||||
sproxy.Bone = s.b
|
||||
sproxy.Vol = s.v or 100
|
||||
sproxy:Spawn()
|
||||
end)
|
||||
end
|
||||
|
||||
self.mod1, self.mod1_1 = self:CreateSoldierModel(1)
|
||||
self.mod2, self.mod2_1 = self:CreateSoldierModel(2)
|
||||
self.mod3, self.mod3_1 = self:CreateSoldierModel(3)
|
||||
self.mod4, self.mod4_1 = self:CreateSoldierModel(4)
|
||||
|
||||
timer.Simple(11.5, function()
|
||||
if IsValid(self.mod1) then
|
||||
self:CreateSoldierNPCFromModel(1)
|
||||
self.mod1:Remove()
|
||||
end
|
||||
end)
|
||||
timer.Simple(12.5, function()
|
||||
if IsValid(self.mod2) then
|
||||
self:CreateSoldierNPCFromModel(2)
|
||||
self.mod2:Remove()
|
||||
end
|
||||
end)
|
||||
timer.Simple(14, function()
|
||||
if IsValid(self.mod3) then
|
||||
self:CreateSoldierNPCFromModel(3)
|
||||
self.mod3:Remove()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function ENT:Finish()
|
||||
if CLIENT then return end
|
||||
self:SetBodygroup(3, 1)
|
||||
if IsValid(self.mod4) then
|
||||
self.mod4:Remove()
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:CreateSoldierModel(type)
|
||||
local friend = ents.Create("prop_dynamic")
|
||||
local friend2 = ents.Create("base_anim")
|
||||
if type == 1 then
|
||||
friend:SetModel("models/tdmg/guy01.mdl")
|
||||
elseif type == 2 then
|
||||
friend:SetModel("models/tdmg/guy02.mdl")
|
||||
elseif type == 3 then
|
||||
friend:SetModel("models/tdmg/guy03.mdl")
|
||||
elseif type == 4 then
|
||||
friend:SetModel("models/tdmg/chiefl.mdl")
|
||||
end
|
||||
friend:SetPos(self:GetPos())
|
||||
friend:SetAngles(self:GetAngles())
|
||||
friend:SetParent(self)
|
||||
friend:Spawn()
|
||||
friend:ResetSequence('spawn')
|
||||
if self.Team2Team then
|
||||
friend2:SetModel("models/tdmg/pm/kortac_1_"..math.random(1,4).."_pm.mdl")
|
||||
if self.Invasion then
|
||||
friend2:SetModel("models/bread/cod/characters/shadow_company/shadow_company_cqc.mdl")
|
||||
end
|
||||
else
|
||||
friend2:SetModel("models/tdmg/pm/specgru_milsim_"..math.random(1,4).."_1_pm.mdl")
|
||||
if self.Invasion then
|
||||
friend2:SetModel("models/humangrunt/mw2/tf141_brazil_pm.mdl")
|
||||
end
|
||||
end
|
||||
friend2:SetPos(self:GetPos())
|
||||
friend2:SetAngles(self:GetAngles())
|
||||
friend2:SetParent(friend)
|
||||
friend2:AddEffects(1)
|
||||
friend2:Spawn()
|
||||
return friend, friend2
|
||||
end
|
||||
|
||||
function ENT:CreateSoldierNPCFromModel(type)
|
||||
local pos = self:GetPos()
|
||||
local ang = self:GetAngles()
|
||||
local bgs = self
|
||||
if type == 1 then
|
||||
pos = self:LocalToWorld(Vector(112.3, -73.6, -10))
|
||||
ang = self.mod1:GetAngles()+Angle(0,180,0)
|
||||
bgs = self.mod1_1
|
||||
elseif type == 2 then
|
||||
pos = self:LocalToWorld(Vector(66.85, -115.5, -10))
|
||||
ang = self.mod2:GetAngles()+Angle(0,180,0)
|
||||
bgs = self.mod2_1
|
||||
elseif type == 3 then
|
||||
pos = self:LocalToWorld(Vector(73.1, -40.8, -10))
|
||||
ang = self.mod3:GetAngles()+Angle(0,180,0)
|
||||
bgs = self.mod3_1
|
||||
end
|
||||
local class = "vj_tdm_npc"
|
||||
if self.Invasion then
|
||||
class = "vj_tdm_invasion_soldier1"
|
||||
if self.Team2Team then
|
||||
class = "vj_tdm_invasion_soldier2"
|
||||
end
|
||||
end
|
||||
local friend = ents.Create(class)
|
||||
friend:SetPos(pos)
|
||||
friend:SetAngles(ang)
|
||||
if self.Team2Team then
|
||||
friend.Team = 2
|
||||
else
|
||||
friend.Team = 1
|
||||
end
|
||||
friend:Spawn()
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
self:NextThink(CurTime())
|
||||
return true
|
||||
end
|
||||
@@ -0,0 +1,56 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.Type = "anim"
|
||||
|
||||
ENT.Spawnable = false
|
||||
ENT.AdminOnly = false
|
||||
ENT.PrintName = "Soundproxy"
|
||||
ENT.RenderGroup = RENDERGROUP_TRANSLUCENT
|
||||
|
||||
ENT.Bone = ""
|
||||
ENT.Sound = ""
|
||||
ENT.DieTime = 0
|
||||
ENT.Vol = 100
|
||||
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/editor/axis_helper.mdl")
|
||||
|
||||
if CLIENT then return end
|
||||
if !IsValid(self:GetParent()) then self:Remove() return end
|
||||
|
||||
local filter = RecipientFilter()
|
||||
filter:AddAllPlayers()
|
||||
|
||||
self.DieTime = CurTime() + SoundDuration(self.Sound)
|
||||
self.PlayedSound = CreateSound(self, self.Sound, filter)
|
||||
self.PlayedSound:Play()
|
||||
self.PlayedSound:ChangeVolume(self.Vol, 0)
|
||||
end
|
||||
|
||||
function ENT:OnRemove()
|
||||
if self.PlayedSound then
|
||||
self.PlayedSound:Stop()
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
if CLIENT then return end
|
||||
if !IsValid(self:GetParent()) then self:Remove() return end
|
||||
|
||||
local parent = self:GetParent()
|
||||
|
||||
local boneid = parent:LookupBone(self.Bone)
|
||||
|
||||
if !boneid then self:Remove() return end
|
||||
|
||||
local pos = parent:GetBonePosition(boneid)
|
||||
|
||||
self:SetPos(pos)
|
||||
|
||||
if self.DieTime < CurTime() then self:Remove() return end
|
||||
end
|
||||
|
||||
function ENT:Draw()
|
||||
return
|
||||
end
|
||||
292
gamemodes/cod_custom/entities/entities/tdm_mi24/shared.lua
Normal file
292
gamemodes/cod_custom/entities/entities/tdm_mi24/shared.lua
Normal file
@@ -0,0 +1,292 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.Type = "anim"
|
||||
ENT.PrintName = "MI24"
|
||||
ENT.AutomaticFrameAdvance = true
|
||||
|
||||
if SERVER then
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/tdmg/mi24d.mdl")
|
||||
self:SetHealth(5000)
|
||||
self.Velo = {x = 0, y = 0}
|
||||
self:SetSolid(SOLID_VPHYSICS)
|
||||
self:PhysicsInit(SOLID_VPHYSICS)
|
||||
self.MultSpeed = 100
|
||||
self.MaxSpeed = 300
|
||||
self.Height = COD.DataTable["AirVehicle_FlyHeight"]
|
||||
self.Smoking = false
|
||||
self.DisableThinkPart = false
|
||||
self.CantBeDamaged = true
|
||||
self.FireDelay = CurTime() + 1
|
||||
self.SeekDelay = CurTime() + 2
|
||||
self.ControlDelay = CurTime() + 1
|
||||
self:SetNWFloat('RemoveTime', CurTime() + 60)
|
||||
self.Removing = false
|
||||
self.Target = nil
|
||||
self.Team = 1
|
||||
self.Actions = {
|
||||
["MoveForward"] = false,
|
||||
["MoveBack"] = false,
|
||||
["MoveLeft"] = false,
|
||||
["MoveRight"] = false,
|
||||
}
|
||||
self:SetBodygroup(3, 1)
|
||||
self:SetBodygroup(4, 1)
|
||||
self:ManipulateBoneScale(10, Vector(0,0,0))
|
||||
self:ManipulateBoneScale(11, Vector(0,0,0))
|
||||
self:ManipulateBoneScale(7, Vector(0,0,0))
|
||||
self:ManipulateBoneAngles(5, Angle(0,40,0))
|
||||
timer.Simple(1, function()
|
||||
if !IsValid(self) then return end
|
||||
self:EmitSound("ambient/levels/streetwar/heli_distant1.wav", 90, 90, 1)
|
||||
end)
|
||||
self:PlaySeq("arrive", 5, function()
|
||||
self:EmitSound(")npc/attack_helicopter/aheli_rotor_loop1.wav", 90, 90, 1)
|
||||
end)
|
||||
|
||||
timer.Simple(5, function()
|
||||
if !IsValid(self) then return end
|
||||
|
||||
if self.Team == 1 then
|
||||
self.VJ_NPC_Class = {"CLASS_SPECGRU"}
|
||||
elseif self.Team == 2 then
|
||||
self.VJ_NPC_Class = {"CLASS_KORTAC"}
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function ENT:PlaySeq(name, long, onfinish)
|
||||
self:SetCycle(0)
|
||||
self:ResetSequence(name)
|
||||
self.CantBeDamaged = true
|
||||
self:SetNotSolid(true)
|
||||
|
||||
if !isfunction(onfinish) then
|
||||
onfinish = function() end
|
||||
end
|
||||
|
||||
timer.Create("MI24Anim"..self:EntIndex(), long, 1, function()
|
||||
if !IsValid(self) then return end
|
||||
|
||||
self:ResetSequence("idle")
|
||||
self:SetNotSolid(false)
|
||||
self.CantBeDamaged = false
|
||||
onfinish()
|
||||
end)
|
||||
end
|
||||
|
||||
function ENT:OnRemove()
|
||||
self:StopSound("npc/attack_helicopter/aheli_rotor_loop1.wav")
|
||||
end
|
||||
|
||||
function ENT:GetTurretPos()
|
||||
local bone = self:GetBonePosition(8)
|
||||
return bone
|
||||
end
|
||||
|
||||
function ENT:Attack()
|
||||
local tar = self.Target
|
||||
|
||||
if !IsValid(tar) then
|
||||
local tab = ents.FindInSphere(self:GetPos(), 4096)
|
||||
table.Shuffle(tab)
|
||||
for _, ent in ipairs(tab) do
|
||||
if self:VisibleVec(ent:GetPos()) then
|
||||
if ent:IsNPC() and ent:Health() > 0 and (ent.Team and ent.Team != self.Team or !ent.Team) then
|
||||
self.Target = ent
|
||||
break
|
||||
end
|
||||
if ent:IsPlayer() and ent:Alive() and ent:Team() != self.Team and ent:GetNWFloat('Perk2') != 4 then
|
||||
self.Target = ent
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if IsValid(tar) and self.FireDelay < CurTime() then
|
||||
self.FireDelay = CurTime() + 0.06
|
||||
|
||||
if self:AngleToEnemy(tar) < 45 and self.SeekDelay < CurTime() then
|
||||
local dir = (tar:GetPos()-self:GetTurretPos()):GetNormalized()
|
||||
|
||||
self:EmitSound("weapons/ar2/fire1.wav", 90, 80, 1, CHAN_WEAPON)
|
||||
self:FireBullets({
|
||||
IgnoreEntity = self,
|
||||
Spread = VectorRand(-0.06, 0.06),
|
||||
Damage = 30,
|
||||
Dir = dir,
|
||||
Src = self:GetTurretPos(),
|
||||
})
|
||||
end
|
||||
|
||||
if not self:VisibleVec(tar:GetPos()) or tar:Health() <= 0 then
|
||||
self.ControlDelay = CurTime() + 4
|
||||
self.SeekDelay = CurTime() + 2
|
||||
self.Target = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:AngleToEnemy(enemy)
|
||||
local selfAngles = self:GetAngles()
|
||||
local enemyPos = enemy:GetPos()
|
||||
local angleToEnemy = (enemyPos - self:GetPos()):Angle()
|
||||
angleToEnemy.x = 0
|
||||
angleToEnemy.z = 0
|
||||
local diff = math.AngleDifference(angleToEnemy.y, selfAngles.y)
|
||||
return math.abs(diff)
|
||||
end
|
||||
|
||||
function ENT:RotateToEntity(ent2, divisor)
|
||||
local ent1Angles = self:GetAngles()
|
||||
local targetAngles = (ent2:GetPos() - self:GetPos()):Angle()
|
||||
local yawDiff = math.NormalizeAngle(targetAngles.y - ent1Angles.y)
|
||||
|
||||
self:SetAngles(Angle(0, ent1Angles.y + yawDiff / divisor, 0))
|
||||
end
|
||||
|
||||
function ENT:Controls()
|
||||
local tar = self.Target
|
||||
--[[self.Actions = {
|
||||
["MoveForward"] = false,
|
||||
["MoveBack"] = false,
|
||||
["MoveLeft"] = false,
|
||||
["MoveRight"] = false,
|
||||
}]]--
|
||||
if IsValid(tar) then
|
||||
if self.ControlDelay < CurTime() then
|
||||
self.ControlDelay = CurTime() + math.Rand(1,5)
|
||||
self.Actions = {
|
||||
["MoveForward"] = math.random(1,2) == 1,
|
||||
["MoveBack"] = math.random(1,6) == 1,
|
||||
["MoveLeft"] = math.random(1,4) == 1,
|
||||
["MoveRight"] = math.random(1,4) == 1,
|
||||
}
|
||||
end
|
||||
self:RotateToEntity(tar, 75)
|
||||
else
|
||||
if self.ControlDelay < CurTime() then
|
||||
self.Actions = {
|
||||
["MoveForward"] = false,
|
||||
["MoveBack"] = false,
|
||||
["MoveLeft"] = false,
|
||||
["MoveRight"] = false,
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
local mu = self.MultSpeed
|
||||
local ms = self.MaxSpeed
|
||||
local vel = self:GetPhysicsObject():GetVelocity()
|
||||
vel.z = 0
|
||||
|
||||
if not self.DisableThinkPart then
|
||||
if not self.CantBeDamaged then
|
||||
self:Attack()
|
||||
self:Controls()
|
||||
self:GetPhysicsObject():SetVelocity(-vel+self:GetForward()*self.Velo.x+self:GetRight()*self.Velo.y)
|
||||
end
|
||||
|
||||
local pos = self:GetPos()
|
||||
self:SetPos(Vector(pos.x, pos.y, self.Height))
|
||||
local ang = self:GetAngles().y
|
||||
self:SetAngles(Angle(0,ang,0))
|
||||
|
||||
if self.Actions["MoveRight"] then
|
||||
self.Velo.x = math.Clamp(self.Velo.x+FrameTime()*mu, -ms, ms)
|
||||
elseif self.Actions["MoveLeft"] then
|
||||
self.Velo.x = math.Clamp(self.Velo.x-FrameTime()*mu, -ms, ms)
|
||||
end
|
||||
if self.Actions["MoveForward"] then
|
||||
self.Velo.y = math.Clamp(self.Velo.y-FrameTime()*mu, -ms, ms)
|
||||
elseif self.Actions["MoveBack"] then
|
||||
self.Velo.y = math.Clamp(self.Velo.y+FrameTime()*mu, -ms, ms)
|
||||
end
|
||||
if not self.Actions["MoveLeft"] and not self.Actions["MoveRight"] then
|
||||
if self.Velo.x > 5 or self.Velo.x < -5 then
|
||||
if self.Velo.x > 0 then
|
||||
self.Velo.x = math.Clamp(self.Velo.x-FrameTime()*mu, -ms, ms)
|
||||
elseif self.Velo.x < 0 then
|
||||
self.Velo.x = math.Clamp(self.Velo.x+FrameTime()*mu, -ms, ms)
|
||||
end
|
||||
else
|
||||
self.Velo.x = 0
|
||||
end
|
||||
end
|
||||
if not self.Actions["MoveForward"] and not self.Actions["MoveBack"] then
|
||||
if self.Velo.y > 5 or self.Velo.y < -5 then
|
||||
if self.Velo.y > 0 then
|
||||
self.Velo.y = math.Clamp(self.Velo.y-FrameTime()*mu, -ms, ms)
|
||||
elseif self.Velo.y < 0 then
|
||||
self.Velo.y = math.Clamp(self.Velo.y+FrameTime()*mu, -ms, ms)
|
||||
end
|
||||
else
|
||||
self.Velo.y = 0
|
||||
end
|
||||
end
|
||||
if self:GetNWFloat('RemoveTime') < CurTime() and not self.Removing and not self.DisableThinkPart then
|
||||
self.Removing = true
|
||||
self:EmitSound("ambient/levels/streetwar/heli_distant1.wav", 90, 90, 1)
|
||||
self:StopSound("npc/attack_helicopter/aheli_rotor_loop1.wav")
|
||||
self:PlaySeq("finish", 8, function()
|
||||
self:Remove()
|
||||
end)
|
||||
end
|
||||
if self:Health() <= 1000 and not self.Smoking then
|
||||
self.Smoking = true
|
||||
ParticleEffectAttach("Rocket_Smoke_Trail", 4, self, 2)
|
||||
end
|
||||
if self:Health() <= 0 then
|
||||
self:DestroyHeli()
|
||||
end
|
||||
end
|
||||
|
||||
self:ManipulateBoneAngles(0, Angle(0,(math.sin(CurTime())*4),(math.sin(CurTime()*2)*4)))
|
||||
self:ManipulateBonePosition(0, Vector(0,0,(math.sin(CurTime())*10)))
|
||||
|
||||
self:NextThink(CurTime())
|
||||
return true
|
||||
end
|
||||
|
||||
function ENT:OnTakeDamage(dmgt)
|
||||
if self.CantBeDamaged then return end
|
||||
local dmg = dmgt:GetDamage()
|
||||
local att = dmgt:GetAttacker()
|
||||
if att != self or att:IsPlayer() and att:Team() != self.Team then
|
||||
self:SetHealth(self:Health()-dmg)
|
||||
if IsValid(self:GetCreator()) then
|
||||
self:GetCreator():ViewPunch(AngleRand(-1,1))
|
||||
self:EmitSound("physics/metal/metal_box_impact_bullet"..math.random(1,3)..".wav")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:DestroyHeli()
|
||||
self.DisableThinkPart = true
|
||||
self.DestroyVelocity = 2500
|
||||
self:EmitSound("tdmg/mi24/spindown.wav")
|
||||
self.PhysicsCollide = function(self)
|
||||
ParticleEffect("explosion_huge_h", self:GetPos()+Vector(0,0,32), Angle(0,0,0))
|
||||
self:EmitSound("tdmg/a10_explosion.wav", 0)
|
||||
self:StopSound("tdmg/mi24/spindown.wav")
|
||||
self:Remove()
|
||||
end
|
||||
self.Think = function(self)
|
||||
local RPM = self.DestroyVelocity
|
||||
local p = self:GetPhysicsObject()
|
||||
if IsValid(p) then
|
||||
local angvel = p:GetAngleVelocity()
|
||||
p:AddAngleVelocity(Vector(angvel.x > 100 and 0 or RPM*0.01,0,angvel.z > 200 and 0 or math.Clamp(RPM,0,4000)*0.04))
|
||||
|
||||
local vel = p:GetVelocity()
|
||||
p:SetVelocity(-vel-Vector(0,0,750))
|
||||
end
|
||||
self:NextThink(CurTime())
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,78 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.Type = "anim"
|
||||
ENT.PrintName = "Care Package"
|
||||
|
||||
if SERVER then
|
||||
local function get_random_key(tbl)
|
||||
local total = 0
|
||||
for k,v in pairs(tbl) do
|
||||
total = total + v
|
||||
end
|
||||
|
||||
local rand = math.random(0, total)
|
||||
local count = 0
|
||||
|
||||
for k,v in pairs(tbl) do
|
||||
count = count + v
|
||||
if rand <= count then
|
||||
return k
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local Items = {
|
||||
[1] = 50,
|
||||
[2] = 50,
|
||||
[3] = 50,
|
||||
[5] = 50,
|
||||
[6] = 50,
|
||||
[7] = 50,
|
||||
[8] = 50,
|
||||
[9] = 40,
|
||||
[10] = 35,
|
||||
[11] = 30,
|
||||
[12] = 30,
|
||||
[13] = 20,
|
||||
[14] = 20,
|
||||
[15] = 20,
|
||||
[16] = 15,
|
||||
[17] = 15,
|
||||
[18] = 10,
|
||||
[20] = 5,
|
||||
[21] = 5,
|
||||
}
|
||||
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/cod/score_carepackage.mdl")
|
||||
self:PhysicsInit(SOLID_VPHYSICS)
|
||||
self:SetMoveType(MOVETYPE_VPHYSICS)
|
||||
self:SetUseType(SIMPLE_USE)
|
||||
|
||||
self.Item = get_random_key(Items)
|
||||
self:GetPhysicsObject():SetVelocity(Vector(0,0,-256))
|
||||
self:SetNWFloat('Item', self.Item)
|
||||
end
|
||||
|
||||
function ENT:Open(ply)
|
||||
if self.Item == 0 then
|
||||
local wep = ply:GetActiveWeapon()
|
||||
ply:GiveAmmo(wep:GetMaxClip1()*10, wep:GetPrimaryAmmoType(), false)
|
||||
else
|
||||
COD:KillstreakAddOther(ply, false, self.Item)
|
||||
net.Start("COD.KillstreaksHUD")
|
||||
net.WriteFloat(self.Item)
|
||||
net.Send(ply)
|
||||
end
|
||||
self:EmitSound("items/ammocrate_open.wav")
|
||||
self:Remove()
|
||||
end
|
||||
|
||||
net.Receive("COD.PickupCarePackage", function(len, ply)
|
||||
local ent = net.ReadEntity()
|
||||
if IsValid(ent) then
|
||||
ent:Open(ply)
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,415 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
ENT.Type = "anim"
|
||||
ENT.AutomaticFrameAdvance = true
|
||||
|
||||
ENT.TypeOfInfil = {
|
||||
["Van"] = {
|
||||
model = "models/tdmg/van_hackney/van_hackney.mdl",
|
||||
seq = "spawn",
|
||||
chiefmodel = "models/tdmg/van_hackney/players.mdl",
|
||||
chiefseq = "spawnChief",
|
||||
drivermodel = "models/tdmg/van_hackney/players.mdl",
|
||||
driverseq = "spawnDriver",
|
||||
haveweapons = true,
|
||||
playermodel = {
|
||||
{
|
||||
model = "models/tdmg/van_hackney/players.mdl",
|
||||
seq = "spawn1",
|
||||
delay = 12.5,
|
||||
pos = Vector(-250, 75, 0),
|
||||
ang = Angle(0,180,0),
|
||||
},
|
||||
{
|
||||
model = "models/tdmg/van_hackney/players.mdl",
|
||||
seq = "spawn2",
|
||||
delay = 13,
|
||||
pos = Vector(-260, -82, 0),
|
||||
ang = Angle(0,180,0),
|
||||
},
|
||||
{
|
||||
model = "models/tdmg/van_hackney/players.mdl",
|
||||
seq = "spawn3",
|
||||
delay = 13.5,
|
||||
pos = Vector(-236, 2, 0),
|
||||
ang = Angle(0,180,0),
|
||||
},
|
||||
{
|
||||
model = "models/tdmg/van_hackney/players.mdl",
|
||||
seq = "spawn4",
|
||||
delay = 14,
|
||||
pos = Vector(-198, -50, 0),
|
||||
ang = Angle(0,180,0),
|
||||
},
|
||||
{
|
||||
model = "models/tdmg/van_hackney/players.mdl",
|
||||
seq = "spawn5",
|
||||
delay = 14.5,
|
||||
pos = Vector(-200, 42, 0),
|
||||
ang = Angle(0,180,0),
|
||||
},
|
||||
{
|
||||
model = "models/tdmg/van_hackney/players.mdl",
|
||||
seq = "spawn6",
|
||||
delay = 15,
|
||||
pos = Vector(-187, -6, 0),
|
||||
ang = Angle(0,180,0),
|
||||
},
|
||||
},
|
||||
sounds = {
|
||||
{
|
||||
path = "tdm_infil/van/alqatala1_veh1_int_front_ster_pan.wav",
|
||||
delay = 0,
|
||||
},
|
||||
{
|
||||
path = "tdm_infil/van/alqatala1_veh1_int_rear_ster_pan.wav",
|
||||
delay = 0,
|
||||
},
|
||||
{
|
||||
path = "tdm_infil/van/alqatala1_veh1_door_ster_pan.wav",
|
||||
delay = 7.5,
|
||||
},
|
||||
{
|
||||
path = "tdm_infil/van/alqatala1_veh1_door_ster_pan2.wav",
|
||||
delay = 15,
|
||||
},
|
||||
{
|
||||
path = "tdm_infil/van/alqatala1_foley_seat1_npc.wav",
|
||||
delay = 8,
|
||||
crewmin = 1,
|
||||
},
|
||||
{
|
||||
path = "tdm_infil/van/alqatala1_foley_seat2_npc.wav",
|
||||
delay = 8.5,
|
||||
crewmin = 2,
|
||||
},
|
||||
{
|
||||
path = "tdm_infil/van/alqatala1_foley_seat3_npc.wav",
|
||||
delay = 9,
|
||||
crewmin = 3,
|
||||
},
|
||||
{
|
||||
path = "tdm_infil/van/alqatala1_foley_seat4_npc.wav",
|
||||
delay = 9.5,
|
||||
crewmin = 4,
|
||||
},
|
||||
{
|
||||
path = "tdm_infil/van/alqatala1_foley_seat5_npc.wav",
|
||||
delay = 10,
|
||||
crewmin = 5,
|
||||
},
|
||||
{
|
||||
path = "tdm_infil/van/alqatala1_foley_seat6_npc.wav",
|
||||
delay = 10.5,
|
||||
crewmin = 6,
|
||||
},
|
||||
},
|
||||
animdelay = 0.21,
|
||||
delaystep = 17.5,
|
||||
offset = Vector(0,0,0),
|
||||
driveaway = true,
|
||||
},
|
||||
["Heli"] = {
|
||||
model = "models/tdmg/heli.mdl",
|
||||
seq = "spawn",
|
||||
chiefmodel = "models/tdmg/chiefl.mdl",
|
||||
chiefseq = "spawn",
|
||||
playermodel = {
|
||||
{
|
||||
model = "models/tdmg/guy01.mdl",
|
||||
seq = "spawn",
|
||||
pos = Vector(112.3, -73.6, 0),
|
||||
ang = Angle(0,180,0),
|
||||
delay = 12,
|
||||
},
|
||||
{
|
||||
model = "models/tdmg/guy02.mdl",
|
||||
seq = "spawn",
|
||||
pos = Vector(66.85, -115.5, 0),
|
||||
ang = Angle(0,180,0),
|
||||
delay = 13.5,
|
||||
},
|
||||
{
|
||||
model = "models/tdmg/guy03.mdl",
|
||||
seq = "spawn",
|
||||
pos = Vector(73.1, -40.8, 0),
|
||||
ang = Angle(0,180,0),
|
||||
delay = 15,
|
||||
},
|
||||
},
|
||||
sounds = {
|
||||
{
|
||||
delay = 0,
|
||||
path = "tdmg/sas1_veh1_int_quad_front_stat.wav",
|
||||
},
|
||||
{
|
||||
delay = 0,
|
||||
path = "tdmg/sas1_veh1_ceilingrattles_spot_stat.wav",
|
||||
},
|
||||
{
|
||||
delay = 0,
|
||||
path = "tdmg/sas1_veh1_int_quad_rear_stat.wav",
|
||||
},
|
||||
{
|
||||
delay = 22 / 30,
|
||||
path = "tdmg/sas1_veh1_foley_doorman_npc.wav",
|
||||
},
|
||||
{
|
||||
delay = 22 / 30,
|
||||
path = "tdmg/sas1_veh1_door_ster_pan.wav",
|
||||
},
|
||||
{
|
||||
delay = 0,
|
||||
path = "tdmg/sas1_veh1_foley_seat1_plr.wav",
|
||||
},
|
||||
{
|
||||
delay = 42 / 30,
|
||||
path = "tdmg/sas1_veh1_rope_spot_stat.wav",
|
||||
},
|
||||
{
|
||||
delay = 184 / 30,
|
||||
path = "tdmg/sas1_veh1_foley_seat1_npc.wav",
|
||||
},
|
||||
{
|
||||
delay = 190 / 30,
|
||||
path = "tdmg/sas1_veh1_foley_seat2_npc.wav",
|
||||
},
|
||||
{
|
||||
delay = 280 / 30,
|
||||
path = "tdmg/sas1_veh1_foley_seat3_npc.wav",
|
||||
},
|
||||
{
|
||||
delay = 328 / 30,
|
||||
path = "tdmg/sas1_veh1_ext_ster_pan.wav",
|
||||
},
|
||||
},
|
||||
animdelay = 0.15,
|
||||
delaystep = 15,
|
||||
offset = Vector(0,0,4),
|
||||
driveaway = false,
|
||||
},
|
||||
}
|
||||
|
||||
if SERVER then
|
||||
util.AddNetworkString("COD.InfilCrewCam")
|
||||
|
||||
function ENT:MakePlayerTable(index, max)
|
||||
local tab = {}
|
||||
local count = 0
|
||||
local plys = team.GetPlayers(index)
|
||||
table.Shuffle(plys)
|
||||
|
||||
for k, v in pairs(plys) do
|
||||
if not v.UsingInfil and count < max then
|
||||
table.insert(tab, v)
|
||||
v.UsingInfil = true
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
|
||||
if #tab > 0 then
|
||||
self.PlayerTable = tab
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Initialize()
|
||||
self.InfilType = self.TypeOfInfil[self.Infil]
|
||||
|
||||
local tab = self.InfilType
|
||||
|
||||
self:SetModel(tab.model)
|
||||
self.CrewTable = {}
|
||||
self:MakePlayerTable(self.TeamChoose, #tab.playermodel)
|
||||
if not self.PlayerTable then
|
||||
self:Remove()
|
||||
end
|
||||
self.DriveVel = 0
|
||||
|
||||
local chiefmod = "models/tdmg/pm/specgru_milsim_"..math.random(1,4).."_1_pm.mdl"
|
||||
if self.TeamChoose == 2 then
|
||||
chiefmod = "models/tdmg/pm/kortac_1_"..math.random(1,4).."_pm.mdl"
|
||||
end
|
||||
|
||||
timer.Simple(0.01, function()
|
||||
if !IsValid(self) or not self.PlayerTable then return end
|
||||
|
||||
self:SetPos(tab.offset+self:GetPos())
|
||||
timer.Simple(tab.animdelay, function()
|
||||
if !IsValid(self) then return end
|
||||
self:ResetSequence(tab.seq)
|
||||
end)
|
||||
for k, v in pairs(self.PlayerTable) do
|
||||
if k <= #tab.playermodel then
|
||||
local tab1 = tab.playermodel[k]
|
||||
self:AddCrewModel(tab1.model, tab1.seq, tab1.delay, v, tab1.pos, tab1.ang)
|
||||
end
|
||||
end
|
||||
|
||||
for k, v in pairs(tab.sounds) do
|
||||
timer.Simple(v.delay, function()
|
||||
if !IsValid(self) or v.crewmin and v.crewmin > #self.CrewTable-2 then return end
|
||||
self:EmitSound(v.path, 75, 100, 1, CHAN_AUTO, SND_SHOULDPAUSE)
|
||||
end)
|
||||
end
|
||||
|
||||
self:AddCrewModel(tab.chiefmodel, tab.chiefseq, 0, chiefmod)
|
||||
|
||||
if tab.drivermodel then
|
||||
self:AddCrewModel(tab.drivermodel, tab.driverseq, 0, chiefmod)
|
||||
end
|
||||
|
||||
timer.Simple(tab.delaystep, function()
|
||||
if !IsValid(self) then return end
|
||||
|
||||
self:SetBodygroup(3, 1)
|
||||
self.DriveAway = tab.driveaway
|
||||
timer.Simple(10, function()
|
||||
if !IsValid(self) then return end
|
||||
|
||||
self:Remove()
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
function ENT:ConnectWeapon(ply, model, lang, lpos, scale, attachment, usebonemerge, boneang)
|
||||
if !IsValid(ply) then return end
|
||||
local wep = ents.Create('base_anim')
|
||||
local attach = ply:GetAttachment(ply:LookupAttachment(attachment))
|
||||
if attach then
|
||||
wep:SetPos(attach.Pos)
|
||||
wep:SetModel(model)
|
||||
wep:SetAngles(attach.Ang)
|
||||
wep:SetParent(ply, ply:LookupAttachment(attachment))
|
||||
if usebonemerge then
|
||||
wep:AddEffects(EF_BONEMERGE)
|
||||
end
|
||||
if boneang and ply:LookupBone(boneang) then
|
||||
wep:SetAngles(select(2, ply:GetBonePosition(ply:LookupBone(boneang))))
|
||||
end
|
||||
wep:Spawn()
|
||||
wep:SetLocalAngles(lang)
|
||||
wep:SetLocalPos(lpos)
|
||||
wep:SetModelScale(scale, 0)
|
||||
function wep:Think()
|
||||
if !IsValid(ply) then
|
||||
wep:Remove()
|
||||
end
|
||||
end
|
||||
end
|
||||
return wep
|
||||
end
|
||||
|
||||
function ENT:AddCrewModel(model, sequence, deletetime, ply, pos, ang)
|
||||
local modelply = "models/tfusion/playermodels/mw3/juggernaut_c.mdl"
|
||||
local wepenable = false
|
||||
|
||||
if ply and !isstring(ply) then
|
||||
modelply = ply:GetModel()
|
||||
ply:Freeze(true)
|
||||
ply:SetNoDraw(true)
|
||||
ply:GodEnable()
|
||||
ply.PreviousInfilWeapon = ply:GetActiveWeapon()
|
||||
ply:SetActiveWeapon(nil)
|
||||
wepenable = true
|
||||
elseif ply and isstring(ply) then
|
||||
modelply = ply
|
||||
end
|
||||
|
||||
local m = ents.Create("prop_dynamic")
|
||||
m:SetModel(model)
|
||||
m:SetPos(self:GetPos())
|
||||
m:SetAngles(self:GetAngles())
|
||||
m:Spawn()
|
||||
m:ResetSequence(sequence)
|
||||
m.Player = ply
|
||||
self:DeleteOnRemove(m)
|
||||
|
||||
local b = ents.Create("base_anim")
|
||||
b:SetModel(modelply)
|
||||
b:SetPos(self:GetPos())
|
||||
b:AddEffects(1)
|
||||
b:SetParent(m)
|
||||
b:Spawn()
|
||||
b:SetNWEntity('Vehicle', self)
|
||||
m:DeleteOnRemove(b)
|
||||
if wepenable and self.InfilType.haveweapons then
|
||||
self:ConnectWeapon(b, "models/viper/mw/weapons/w_galima.mdl", Angle(-0,0,0), Vector(-4,-2,-0), 1, "anim_attachment_RH")
|
||||
end
|
||||
|
||||
table.insert(self.CrewTable, m)
|
||||
|
||||
local time1 = deletetime
|
||||
if time1 == 0 then
|
||||
time1 = select(2, m:LookupSequence(sequence))
|
||||
end
|
||||
|
||||
timer.Simple(1, function()
|
||||
if !IsValid(b) or !IsValid(ply) then return end
|
||||
|
||||
net.Start("COD.InfilCrewCam")
|
||||
net.WriteEntity(b)
|
||||
net.Send(ply)
|
||||
end)
|
||||
|
||||
timer.Simple(time1, function()
|
||||
if !IsValid(m) then return end
|
||||
|
||||
local ply1 = m.Player
|
||||
if IsValid(ply1) then
|
||||
ply1:Freeze(false)
|
||||
ply1:SetNoDraw(false)
|
||||
ply1:GodDisable()
|
||||
ply1:SetPos(self:LocalToWorld(pos-self.InfilType.offset))
|
||||
ply1:SetEyeAngles(self:GetAngles()+ang)
|
||||
ply1.UsingInfil = false
|
||||
if IsValid(ply.PreviousInfilWeapon) then
|
||||
ply1:SelectWeapon(ply1.PreviousInfilWeapon:GetClass())
|
||||
ply1.PreviousInfilWeapon = nil
|
||||
end
|
||||
end
|
||||
|
||||
m:Remove()
|
||||
end)
|
||||
|
||||
return m, b
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
if self.DriveAway then
|
||||
self.DriveVel = self.DriveVel + FrameTime()*2
|
||||
self:SetPos(self:GetPos()+self:GetForward()*self.DriveVel)
|
||||
end
|
||||
|
||||
self:NextThink(CurTime())
|
||||
return true
|
||||
end
|
||||
else
|
||||
net.Receive("COD.InfilCrewCam", function()
|
||||
local ent = net.ReadEntity()
|
||||
hook.Add("CalcView", "InfilCrewCam", function(ply, pos, angles, fov)
|
||||
if IsValid(ent) then
|
||||
--[[local veh = ent:GetNWEntity('Vehicle')
|
||||
if IsValid(veh) then
|
||||
print( ent:GetPos()-veh:GetPos() )
|
||||
end]]--
|
||||
COD.HideHUD = true
|
||||
|
||||
ent:ManipulateBoneScale(ent:LookupBone("ValveBiped.Bip01_Head1"), Vector(0,0,0))
|
||||
pos = ent:GetAttachment(ent:LookupAttachment("eyes")).Pos
|
||||
angles = ent:GetAttachment(ent:LookupAttachment("eyes")).Ang
|
||||
angles.z = 0
|
||||
local view = {
|
||||
origin = pos,
|
||||
angles = angles,
|
||||
fov = fov,
|
||||
drawviewer = false
|
||||
}
|
||||
|
||||
return view
|
||||
else
|
||||
hook.Remove("CalcView", "InfilCrewCam")
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end
|
||||
251
gamemodes/cod_custom/entities/entities/tdm_sentry/shared.lua
Normal file
251
gamemodes/cod_custom/entities/entities/tdm_sentry/shared.lua
Normal file
@@ -0,0 +1,251 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.Type = "anim"
|
||||
ENT.PrintName = "Sentry Gun"
|
||||
|
||||
if SERVER then
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/tdmg/sentry.mdl")
|
||||
self:SetHealth(1500)
|
||||
self:SetSolid(SOLID_VPHYSICS)
|
||||
self.DestroyedAng = 0
|
||||
self.DisableThinkPart = false
|
||||
self.FireDelay = CurTime() + 1
|
||||
self.RemoveDelay = CurTime() + 120
|
||||
self.Target = nil
|
||||
self.Smoking = false
|
||||
self.StartingShoot = false
|
||||
self.StartingShootDelay = 0
|
||||
self.StartedShoot = false
|
||||
self.Team = 1
|
||||
self.DelayRespin = 2
|
||||
self.BeepDelay = CurTime() + 3
|
||||
self:SetSequence("rotation_barrels2x")
|
||||
|
||||
local t = ents.Create("base_anim")
|
||||
t:SetModel('models/props_junk/PopCan01a.mdl')
|
||||
t:SetPos(self:GetTurretPos())
|
||||
t:SetAngles(self:GetAngles())
|
||||
t:SetParent(self)
|
||||
t:SetOwner(self)
|
||||
t:SetNoDraw(true)
|
||||
t:Spawn()
|
||||
self.ShootEntity = t
|
||||
|
||||
self:ManipulateBoneAngles(3, Angle(-70, 0, 0))
|
||||
timer.Simple(0.1, function()
|
||||
if !IsValid(self) then return end
|
||||
self:EmitSound("tdmg/sentry/mw2_sentryplace.wav")
|
||||
end)
|
||||
|
||||
timer.Simple(5, function()
|
||||
if !IsValid(self) then return end
|
||||
|
||||
if self.Team == 1 then
|
||||
self.VJ_NPC_Class = {"CLASS_SPECGRU"}
|
||||
elseif self.Team == 2 then
|
||||
self.VJ_NPC_Class = {"CLASS_KORTAC"}
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function ENT:OnRemove()
|
||||
--self:StopSound("npc/attack_helicopter/aheli_rotor_loop1.wav")
|
||||
end
|
||||
|
||||
function ENT:GetTurretPos()
|
||||
local pos, ang = self:GetBonePosition(4)
|
||||
return pos, ang
|
||||
end
|
||||
|
||||
function ENT:IsInFOV(entity)
|
||||
local direction = (entity:GetPos() - self:GetTurretPos()):GetNormalized()
|
||||
local viewAngle = self:GetForward()
|
||||
local dot = direction:Dot(viewAngle)
|
||||
|
||||
if dot >= math.cos(math.rad(180 / 2)) then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:GetNextTarget()
|
||||
local target = nil
|
||||
local tab = ents.FindInSphere(self:GetPos(), 8000)
|
||||
table.Shuffle(tab)
|
||||
for _, ent in ipairs(tab) do
|
||||
if self:IsInFOV(ent) and self:VisibleVec(ent:WorldSpaceCenter()) then
|
||||
if ent:IsNPC() and ent:Health() > 0 and (ent.Team and ent.Team != self.Team or !ent.Team) then
|
||||
target = ent
|
||||
break
|
||||
end
|
||||
if ent:IsPlayer() and ent:Alive() and ent:Team() != self.Team and ent:GetNWFloat('Perk2') != 4 then
|
||||
target = ent
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
return target
|
||||
end
|
||||
|
||||
function ENT:Attack()
|
||||
local tar = self.Target
|
||||
|
||||
if !IsValid(tar) then
|
||||
self.Target = self:GetNextTarget()
|
||||
self:RotateToEntity(self:GetAngles(), 45)
|
||||
if self.BeepDelay < CurTime() then
|
||||
self.BeepDelay = CurTime() + 3
|
||||
self:EmitSound("tdmg/sentry/mw2_sentrybeep.wav")
|
||||
end
|
||||
else
|
||||
if self.StartedShoot then
|
||||
self:RotateToEntity(tar, 10)
|
||||
else
|
||||
self:RotateToEntity(tar, 30)
|
||||
end
|
||||
end
|
||||
|
||||
if IsValid(tar) then
|
||||
self:Shoot(true)
|
||||
|
||||
if not self:VisibleVec(tar:GetPos()) or not self:IsInFOV(tar) or tar:Health() <= 0 then
|
||||
self.ControlDelay = CurTime() + 4
|
||||
self.Target = self:GetNextTarget()
|
||||
end
|
||||
else
|
||||
self:Shoot(false)
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Shoot(bool)
|
||||
if not bool then
|
||||
self.StartedShoot = false
|
||||
if self.StartingShoot and not bool and self.StartingShootDelay < CurTime() then
|
||||
self.StartingShootDelay = CurTime() + self.DelayRespin
|
||||
self:EmitSound("tdmg/sentry/mw2_sentryspindown.wav")
|
||||
if self.FireSound then
|
||||
self:StopLoopingSound(self.FireSound)
|
||||
self.FireSound = -1
|
||||
end
|
||||
end
|
||||
else
|
||||
if not self.StartingShoot and bool and self.StartingShootDelay < CurTime() then
|
||||
self.StartingShootDelay = CurTime() + self.DelayRespin
|
||||
self:EmitSound("tdmg/sentry/mw2_sentryspinup.wav")
|
||||
end
|
||||
end
|
||||
|
||||
self.StartingShoot = bool
|
||||
|
||||
if not self.StartingShoot then
|
||||
local num = math.max(1*(self.StartingShootDelay-CurTime())/self.DelayRespin, 0)
|
||||
self:SetPlaybackRate(num)
|
||||
end
|
||||
|
||||
if self.StartingShoot then
|
||||
local num = math.min(((1*(self.StartingShootDelay-CurTime())/self.DelayRespin)-1)*-1, 1)
|
||||
self:SetPlaybackRate(num)
|
||||
end
|
||||
|
||||
if self.StartingShoot and self.StartingShootDelay < CurTime() then
|
||||
self.StartedShoot = true
|
||||
self:SetPlaybackRate(1)
|
||||
if not self.FireSound or self.FireSound < 0 then
|
||||
self.FireSound = self:StartLoopingSound("tdmg/sentry/mw2_sentryfirebullet.wav")
|
||||
end
|
||||
if self.FireDelay < CurTime() then
|
||||
self.FireDelay = CurTime() + 0.04
|
||||
|
||||
local pos1, ang1 = self:GetTurretPos()
|
||||
|
||||
self.ShootEntity:FireBullets({
|
||||
Src = pos1,
|
||||
Dir = ang1:Forward(),
|
||||
Spread = VectorRand(-0.10, 0.10),
|
||||
Damage = 20,
|
||||
IgnoreEntity = self,
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:AngleToEnemy(enemy)
|
||||
local selfPos, selfAngles = self:GetBonePosition(3)
|
||||
selfAngles = selfAngles
|
||||
local enemyPos = enemy:GetPos()
|
||||
local angleToEnemy = (enemyPos - self:GetTurretPos()):Angle()
|
||||
angleToEnemy.z = 0
|
||||
local diff = math.AngleDifference(angleToEnemy.y, selfAngles.y)
|
||||
return math.abs(diff)
|
||||
end
|
||||
|
||||
function ENT:RotateToEntity(ent2, divisor)
|
||||
local selfPos, selfAngles = self:GetBonePosition(3)
|
||||
selfAngles = selfAngles
|
||||
local targetAngles = Angle(0,0,0)
|
||||
if isangle(ent2) then
|
||||
targetAngles = ent2
|
||||
else
|
||||
targetAngles = (ent2:WorldSpaceCenter() - self:GetTurretPos()):Angle()
|
||||
end
|
||||
local yawDiff = math.NormalizeAngle(targetAngles.y - selfAngles.y)
|
||||
local xDiff = math.NormalizeAngle(targetAngles.x - selfAngles.x)
|
||||
|
||||
self:ManipulateBoneAngles(3, Angle(self:GetManipulateBoneAngles(3).x + xDiff / divisor, self:GetManipulateBoneAngles(3).y + yawDiff / divisor, 0))
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
if not self.DisableThinkPart then
|
||||
self:Attack()
|
||||
self.DestroyedAng = 0
|
||||
|
||||
local id, long = self:LookupSequence(self:GetSequenceName(self:GetSequence()))
|
||||
local addframe = FrameTime()/long*self:GetPlaybackRate()
|
||||
if self:GetCycle() >= 1 then
|
||||
self:SetCycle(0)
|
||||
else
|
||||
self:SetCycle(self:GetCycle()+addframe)
|
||||
end
|
||||
|
||||
if self:Health() <= 0 or self.RemoveDelay < CurTime() then
|
||||
self:Destroy()
|
||||
end
|
||||
else
|
||||
print(self.DestroyedAng)
|
||||
self.DestroyedAng = math.min(45, self.DestroyedAng+FrameTime()/0.01)
|
||||
self:ManipulateBoneAngles(3, Angle(self.DestroyedAng, 0, 0))
|
||||
end
|
||||
|
||||
self:NextThink(CurTime())
|
||||
return true
|
||||
end
|
||||
|
||||
function ENT:OnTakeDamage(dmgt)
|
||||
local dmg = dmgt:GetDamage()
|
||||
local att = dmgt:GetAttacker()
|
||||
if att != self or att:IsPlayer() and att:Team() != self.Team then
|
||||
self:SetHealth(self:Health()-dmg)
|
||||
self:EmitSound("physics/metal/metal_box_impact_bullet"..math.random(1,3)..".wav")
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Destroy()
|
||||
if self.DisableThinkPart then return end
|
||||
|
||||
if self.FireSound then
|
||||
self:StopLoopingSound(self.FireSound)
|
||||
self.FireSound = -1
|
||||
end
|
||||
self.DisableThinkPart = true
|
||||
ParticleEffectAttach("Rocket_Smoke_Trail", 4, self, 0)
|
||||
self:EmitSound("tdmg/sentry/mw2_sentrydestroyed.wav")
|
||||
|
||||
timer.Simple(15, function()
|
||||
if !IsValid(self) then return end
|
||||
self:Remove()
|
||||
end)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,238 @@
|
||||
AddCSLuaFile("shared.lua")
|
||||
include('shared.lua')
|
||||
/*-----------------------------------------------
|
||||
*** Copyright (c) 2012-2022 by DrVrej, All rights reserved. ***
|
||||
No parts of this code or any of its contents may be reproduced, copied, modified or adapted,
|
||||
without the prior written consent of the author, unless otherwise indicated for stand-alone materials.
|
||||
-----------------------------------------------*/
|
||||
ENT.StartHealth = 100
|
||||
ENT.UsePlayerModelMovement = true
|
||||
ENT.Model = {}
|
||||
|
||||
ENT.BloodColor = "Red"
|
||||
|
||||
ENT.VJ_NPC_Class = {"CLASS_SPECGRU"}
|
||||
|
||||
ENT.HasMeleeAttack = true
|
||||
ENT.AnimTbl_MeleeAttack = {"tdm_melee_weapon"}
|
||||
ENT.MeleeAttackDamage = 25
|
||||
ENT.MeleeAttackReps = 3
|
||||
|
||||
ENT.FootStepTimeRun = 0.3
|
||||
ENT.FootStepTimeWalk = 0.5
|
||||
ENT.DropWeaponOnDeath = false
|
||||
|
||||
ENT.HasDeathAnimation = true
|
||||
ENT.AnimTbl_Death = {}
|
||||
for i = 1, 54 do
|
||||
table.insert(ENT.AnimTbl_Death, "dead"..i)
|
||||
end
|
||||
ENT.DeathAnimationChance = 1
|
||||
|
||||
ENT.CanFlinch = 1
|
||||
ENT.FlinchChance = 2
|
||||
ENT.AnimTbl_Flinch = {}
|
||||
for i = 1, 7 do
|
||||
table.insert(ENT.AnimTbl_Flinch, "tdm_stun"..i)
|
||||
end
|
||||
|
||||
ENT.SoundTbl_FootStep = {"npc/footsteps/hardboot_generic1.wav","npc/footsteps/hardboot_generic2.wav","npc/footsteps/hardboot_generic3.wav","npc/footsteps/hardboot_generic4.wav","npc/footsteps/hardboot_generic5.wav","npc/footsteps/hardboot_generic6.wav","npc/footsteps/hardboot_generic8.wav"}
|
||||
ENT.SoundTbl_Death = {}
|
||||
for i = 1, 14 do
|
||||
table.insert(ENT.SoundTbl_Death, ")tdmg/ply/death"..i..".wav")
|
||||
end
|
||||
|
||||
ENT.SoundTbl_CombatIdle = {}
|
||||
for i = 1, 25 do
|
||||
table.insert(ENT.SoundTbl_CombatIdle, ")tdmg/npc/combat ("..i..").wav")
|
||||
end
|
||||
|
||||
ENT.SoundTbl_Suppressing = {}
|
||||
for i = 1, 7 do
|
||||
table.insert(ENT.SoundTbl_Suppressing, ")tdmg/npc/contact ("..i..").wav")
|
||||
end
|
||||
|
||||
ENT.SoundTbl_OnKilledEnemy = {}
|
||||
for i = 1, 13 do
|
||||
table.insert(ENT.SoundTbl_CombatIdle, ")tdmg/npc/kill ("..i..").wav")
|
||||
end
|
||||
|
||||
ENT.SoundTbl_AllyDeath = {}
|
||||
for i = 1, 17 do
|
||||
table.insert(ENT.SoundTbl_CombatIdle, ")tdmg/npc/friendlydown"..i..".wav")
|
||||
end
|
||||
|
||||
ENT.SoundTbl_WeaponReload = {}
|
||||
for i = 1, 15 do
|
||||
table.insert(ENT.SoundTbl_WeaponReload, ")tdmg/npc/reload ("..i..").wav")
|
||||
end
|
||||
|
||||
ENT.HasItemDropsOnDeath = false
|
||||
|
||||
ENT.DeathCorpseFade = false
|
||||
|
||||
ENT.AnimTbl_Medic_GiveHealth = {"gesture_item_give_original"}
|
||||
ENT.AnimTbl_CallForHelp = {"gesture_signal_forward_original"}
|
||||
ENT.CallForBackUpOnDamageAnimation = {"gesture_signal_group_original"}
|
||||
|
||||
ENT.FollowPlayer = false
|
||||
|
||||
ENT.SightAngle = 60
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
function ENT:CustomOnPreInitialize()
|
||||
if not self.Team then
|
||||
self.Team = 1
|
||||
end
|
||||
|
||||
self.Type = "Light"
|
||||
|
||||
if math.random(1,6) == 1 then
|
||||
self.Type = "Patrol"
|
||||
elseif math.random(1,6) == 1 then
|
||||
self.Type = "Medic"
|
||||
elseif math.random(1,8) == 1 then
|
||||
self.Type = "Sniper"
|
||||
elseif math.random(1,10) == 1 and COD_Invasion.HeavyUnits then
|
||||
self.Type = "Bomber"
|
||||
elseif math.random(1,2) == 1 and COD_Invasion.HeavyUnits then
|
||||
self.Type = "Heavy"
|
||||
end
|
||||
|
||||
if math.random(1,2) == 1 then
|
||||
self.WaitForEnemyToComeOut = false
|
||||
end
|
||||
|
||||
if self.Type == "Medic" then
|
||||
self.Model = {"models/humangrunt/mw2/brazilian_militia_pm.mdl"}
|
||||
self.IsMedicSNPC = true
|
||||
elseif self.Type == "Bomber" then
|
||||
self.Model = {"models/wap/callofduty/mw4/chr/operators/coalition/milsim/fireteam/body_western_fireteam_west_dmr_1_2_pm.mdl"}
|
||||
elseif self.Type == "Patrol" then
|
||||
self.Model = {"models/humangrunt/mw2/brazilian_militia_pm.mdl"}
|
||||
elseif self.Type == "Sniper" then
|
||||
self.Model = {"models/humangrunt/mw2/brazilian_militia_pm.mdl"}
|
||||
elseif self.Type == "Heavy" then
|
||||
self.Model = {"models/wap/callofduty/mw4/chr/operators/coalition/milsim/fireteam/body_western_fireteam_west_ar_1_2_pm.mdl", "models/wap/callofduty/mw4/chr/operators/coalition/milsim/fireteam/body_western_fireteam_west_lmg_1_2_pm.mdl"}
|
||||
else
|
||||
self.Model = {"models/humangrunt/mw2/tf141_brazil_pm.mdl"}
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:CustomOnInitialize()
|
||||
if self.Type == "Medic" then
|
||||
self:SetBodygroup(6, math.random(0,4))
|
||||
self:SetBodygroup(5, math.random(0,12))
|
||||
self:SetBodygroup(4, math.random(0,3))
|
||||
self:SetBodygroup(3, math.random(0,1))
|
||||
self:SetBodygroup(3, math.random(0,1))
|
||||
self:SetBodygroup(2, math.random(0,1))
|
||||
self:SetBodygroup(1, math.random(0,3))
|
||||
self:SetSkin(math.random(0,1))
|
||||
|
||||
self:Give("weapon_vj_tdm_r870")
|
||||
self:SetHealth(125)
|
||||
elseif self.Type == "Sniper" then
|
||||
self:SetBodygroup(6, math.random(0,4))
|
||||
self:SetBodygroup(5, math.random(0,12))
|
||||
self:SetBodygroup(4, math.random(0,3))
|
||||
self:SetBodygroup(3, math.random(0,1))
|
||||
self:SetBodygroup(3, math.random(0,1))
|
||||
self:SetBodygroup(2, math.random(0,1))
|
||||
self:SetBodygroup(1, math.random(0,3))
|
||||
self:SetSkin(math.random(0,1))
|
||||
|
||||
self:Give("weapon_vj_tdm_m24")
|
||||
elseif self.Type == "Patrol" then
|
||||
self:SetBodygroup(6, math.random(0,4))
|
||||
self:SetBodygroup(5, math.random(0,12))
|
||||
self:SetBodygroup(4, math.random(0,3))
|
||||
self:SetBodygroup(3, math.random(0,1))
|
||||
self:SetBodygroup(3, math.random(0,1))
|
||||
self:SetBodygroup(2, math.random(0,1))
|
||||
self:SetBodygroup(1, math.random(0,3))
|
||||
self:SetSkin(math.random(0,1))
|
||||
|
||||
self:Give("weapon_vj_tdm_m9")
|
||||
self:SetHealth(75)
|
||||
elseif self.Type == "Bomber" then
|
||||
self:Give("weapon_vj_rpg")
|
||||
self:SetHealth(175)
|
||||
elseif self.Type == "Heavy" then
|
||||
if math.random(1,3) == 1 then
|
||||
self:Give("weapon_vj_tdm_m249")
|
||||
else
|
||||
self:Give("weapon_vj_tdm_m4a1")
|
||||
end
|
||||
self:SetHealth(200)
|
||||
else
|
||||
self:SetBodygroup(6, math.random(0,1))
|
||||
self:SetBodygroup(5, math.random(0,1))
|
||||
self:SetBodygroup(4, math.random(0,2))
|
||||
self:SetBodygroup(3, math.random(0,2))
|
||||
self:SetBodygroup(2, math.random(0,1))
|
||||
self:SetBodygroup(1, math.random(0,4))
|
||||
self:SetBodygroup(0, math.random(0,3))
|
||||
self:SetSkin(math.random(0,1))
|
||||
|
||||
if math.random(1,3) == 1 then
|
||||
self:Give("weapon_vj_tdm_m14")
|
||||
else
|
||||
self:Give("weapon_vj_tdm_ump")
|
||||
end
|
||||
end
|
||||
|
||||
self:SetNWFloat('Team', self.Team)
|
||||
self.SearchCooldown = 0
|
||||
self.StuckCooldown = CurTime()+60
|
||||
end
|
||||
|
||||
function ENT:FlashEntity()
|
||||
self.Flinching = true
|
||||
self:StopAttacks(true)
|
||||
self.PlayingAttackAnimation = false
|
||||
local animTbl = self.AnimTbl_Flinch
|
||||
local anim = VJ_PICK(animTbl)
|
||||
local animDur = self.NextMoveAfterFlinchTime == false and self:DecideAnimationLength(anim, false, self.FlinchAnimationDecreaseLengthAmount) or self.NextMoveAfterFlinchTime
|
||||
self:VJ_ACT_PLAYACTIVITY(anim, true, animDur, false, 0, {SequenceDuration=animDur, PlayBackRateCalculated=true})
|
||||
timer.Create("timer_act_flinching"..self:EntIndex(), animDur, 1, function() self.Flinching = false end)
|
||||
self:CustomOnFlinch_AfterFlinch(dmginfo, hitgroup)
|
||||
self.NextFlinchT = CurTime() + self.NextFlinchTime
|
||||
end
|
||||
|
||||
function ENT:CustomOnThink()
|
||||
if self.SearchCooldown < CurTime() then
|
||||
for _, ent in ipairs(ents.FindInSphere(self:GetPos(), 5000)) do
|
||||
if ent:IsPlayer() and ent:Team() != self.Team or ent:IsNPC() and ent.Team != self.Team and math.random(1,4) == 1 then
|
||||
self:SetLastPosition(ent:GetPos())
|
||||
self:VJ_TASK_GOTO_LASTPOS()
|
||||
break
|
||||
end
|
||||
end
|
||||
self.SearchCooldown = CurTime()+math.random(15,45)
|
||||
end
|
||||
|
||||
if IsValid(self:GetEnemy()) then
|
||||
self.SearchCooldown = CurTime()+math.random(15,45)
|
||||
end
|
||||
|
||||
local colmins, colmaxs = self:GetCollisionBounds()
|
||||
local tr = util.TraceHull({
|
||||
start = self:GetPos(),
|
||||
endpos = self:GetPos(),
|
||||
filter = self,
|
||||
mins = colmins,
|
||||
maxs = colmaxs,
|
||||
mask = MASK_SHOT_HULL
|
||||
})
|
||||
if not tr.Hit then
|
||||
self.StuckCooldown = CurTime()+15
|
||||
end
|
||||
|
||||
if self.StuckCooldown < CurTime() then
|
||||
self:TakeDamage(self:Health())
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:CustomOnMeleeAttack_AfterChecks(hitEnt, isProp)
|
||||
return self.Takedowning
|
||||
end
|
||||
@@ -0,0 +1,22 @@
|
||||
ENT.Base = "npc_vj_human_base"
|
||||
ENT.Type = "ai"
|
||||
ENT.PrintName = "Soldier"
|
||||
|
||||
if CLIENT then
|
||||
local tm_mat = Material('tdmg/hud/teammate.png')
|
||||
function ENT:Draw()
|
||||
self:DrawModel()
|
||||
if self:GetNWFloat('Team') == LocalPlayer():Team() then
|
||||
local angle = EyeAngles()
|
||||
angle = Angle( 0, angle.y, 0 )
|
||||
angle:RotateAroundAxis( angle:Up(), -90 )
|
||||
angle:RotateAroundAxis( angle:Forward(), 90 )
|
||||
local pos = self:GetBonePosition(LocalPlayer():LookupBone("ValveBiped.Bip01_Head1"))+Vector(0,0,16)
|
||||
cam.Start3D2D( pos, angle, 0.1 )
|
||||
surface.SetDrawColor(5,155,255)
|
||||
surface.SetMaterial(tm_mat)
|
||||
surface.DrawTexturedRect(-12, -12, 24, 24)
|
||||
cam.End3D2D()
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,242 @@
|
||||
AddCSLuaFile("shared.lua")
|
||||
include('shared.lua')
|
||||
/*-----------------------------------------------
|
||||
*** Copyright (c) 2012-2022 by DrVrej, All rights reserved. ***
|
||||
No parts of this code or any of its contents may be reproduced, copied, modified or adapted,
|
||||
without the prior written consent of the author, unless otherwise indicated for stand-alone materials.
|
||||
-----------------------------------------------*/
|
||||
ENT.StartHealth = 100
|
||||
ENT.UsePlayerModelMovement = true
|
||||
ENT.Model = {}
|
||||
|
||||
ENT.BloodColor = "Red"
|
||||
|
||||
ENT.HasMeleeAttack = true
|
||||
ENT.AnimTbl_MeleeAttack = {"tdm_melee_weapon"}
|
||||
ENT.MeleeAttackDamage = 25
|
||||
ENT.MeleeAttackReps = 3
|
||||
|
||||
ENT.FootStepTimeRun = 0.3
|
||||
ENT.FootStepTimeWalk = 0.5
|
||||
ENT.DropWeaponOnDeath = false
|
||||
|
||||
ENT.VJ_NPC_Class = {"CLASS_KORTAC"}
|
||||
|
||||
ENT.HasDeathAnimation = true
|
||||
ENT.AnimTbl_Death = {}
|
||||
for i = 1, 54 do
|
||||
table.insert(ENT.AnimTbl_Death, "dead"..i)
|
||||
end
|
||||
ENT.DeathAnimationChance = 1
|
||||
|
||||
ENT.CanFlinch = 1
|
||||
ENT.FlinchChance = 2
|
||||
ENT.AnimTbl_Flinch = {}
|
||||
for i = 1, 7 do
|
||||
table.insert(ENT.AnimTbl_Flinch, "tdm_stun"..i)
|
||||
end
|
||||
|
||||
ENT.SoundTbl_FootStep = {"npc/footsteps/hardboot_generic1.wav","npc/footsteps/hardboot_generic2.wav","npc/footsteps/hardboot_generic3.wav","npc/footsteps/hardboot_generic4.wav","npc/footsteps/hardboot_generic5.wav","npc/footsteps/hardboot_generic6.wav","npc/footsteps/hardboot_generic8.wav"}
|
||||
ENT.SoundTbl_Death = {}
|
||||
for i = 1, 14 do
|
||||
table.insert(ENT.SoundTbl_Death, ")tdmg/ply/death"..i..".wav")
|
||||
end
|
||||
|
||||
ENT.SoundTbl_CombatIdle = {}
|
||||
for i = 1, 25 do
|
||||
table.insert(ENT.SoundTbl_CombatIdle, ")tdmg/npc/combat ("..i..").wav")
|
||||
end
|
||||
|
||||
ENT.SoundTbl_Suppressing = {}
|
||||
for i = 1, 7 do
|
||||
table.insert(ENT.SoundTbl_Suppressing, ")tdmg/npc/contact ("..i..").wav")
|
||||
end
|
||||
|
||||
ENT.SoundTbl_OnKilledEnemy = {}
|
||||
for i = 1, 13 do
|
||||
table.insert(ENT.SoundTbl_CombatIdle, ")tdmg/npc/kill ("..i..").wav")
|
||||
end
|
||||
|
||||
ENT.SoundTbl_AllyDeath = {}
|
||||
for i = 1, 17 do
|
||||
table.insert(ENT.SoundTbl_CombatIdle, ")tdmg/npc/friendlydown"..i..".wav")
|
||||
end
|
||||
|
||||
ENT.SoundTbl_WeaponReload = {}
|
||||
for i = 1, 15 do
|
||||
table.insert(ENT.SoundTbl_WeaponReload, ")tdmg/npc/reload ("..i..").wav")
|
||||
end
|
||||
|
||||
ENT.HasItemDropsOnDeath = false
|
||||
|
||||
ENT.DeathCorpseFade = false
|
||||
|
||||
ENT.AnimTbl_Medic_GiveHealth = {"gesture_item_give_original"}
|
||||
ENT.AnimTbl_CallForHelp = {"gesture_signal_forward_original"}
|
||||
ENT.CallForBackUpOnDamageAnimation = {"gesture_signal_group_original"}
|
||||
|
||||
ENT.FollowPlayer = false
|
||||
|
||||
ENT.SightAngle = 60
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
function ENT:CustomOnPreInitialize()
|
||||
if not self.Team then
|
||||
self.Team = 2
|
||||
end
|
||||
|
||||
self.Type = "Light"
|
||||
|
||||
if math.random(1,6) == 1 then
|
||||
self.Type = "Patrol"
|
||||
elseif math.random(1,6) == 1 then
|
||||
self.Type = "Medic"
|
||||
elseif math.random(1,8) == 1 then
|
||||
self.Type = "Sniper"
|
||||
elseif math.random(1,10) == 1 and COD_Invasion.HeavyUnits then
|
||||
self.Type = "Bomber"
|
||||
elseif math.random(1,2) == 1 and COD_Invasion.HeavyUnits then
|
||||
self.Type = "Heavy"
|
||||
end
|
||||
|
||||
if math.random(1,2) == 1 then
|
||||
self.WaitForEnemyToComeOut = false
|
||||
end
|
||||
|
||||
if self.Type == "Medic" then
|
||||
self.Model = {"models/ops_casual/operator1.mdl"}
|
||||
self.IsMedicSNPC = true
|
||||
elseif self.Type == "Bomber" then
|
||||
self.Model = {"models/bread/cod/characters/milsim/shadow_company.mdl"}
|
||||
elseif self.Type == "Patrol" then
|
||||
self.Model = {"models/ops_casual/operator1.mdl"}
|
||||
elseif self.Type == "Sniper" then
|
||||
self.Model = {"models/ops_casual/operator1.mdl"}
|
||||
elseif self.Type == "Heavy" then
|
||||
self.Model = {"models/bread/cod/characters/milsim/shadow_company.mdl"}
|
||||
else
|
||||
self.Model = {"models/bread/cod/characters/shadow_company/shadow_company_cqc.mdl"}
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:CustomOnInitialize()
|
||||
if self.Type == "Medic" then
|
||||
self:SetBodygroup(1, math.random(0,5))
|
||||
self:SetBodygroup(2, math.random(0,8))
|
||||
self:SetBodygroup(3, math.random(0,6))
|
||||
self:SetBodygroup(4, math.random(0,2))
|
||||
self:SetBodygroup(5, math.random(0,3))
|
||||
self:SetBodygroup(6, math.random(0,6))
|
||||
self:SetBodygroup(7, math.random(0,3))
|
||||
self:SetBodygroup(8, math.random(0,3))
|
||||
self:SetBodygroup(9, math.random(0,10))
|
||||
self:SetSkin(math.random(0,14))
|
||||
|
||||
local rnd = math.random(50,200)
|
||||
self:SetColor(Color(rnd,rnd,rnd))
|
||||
|
||||
self:Give("weapon_vj_tdm_r870")
|
||||
self:SetHealth(125)
|
||||
elseif self.Type == "Sniper" then
|
||||
self:SetBodygroup(1, math.random(0,5))
|
||||
self:SetBodygroup(2, math.random(0,8))
|
||||
self:SetBodygroup(3, math.random(0,6))
|
||||
self:SetBodygroup(4, math.random(0,2))
|
||||
self:SetBodygroup(5, math.random(0,3))
|
||||
self:SetBodygroup(6, math.random(0,6))
|
||||
self:SetBodygroup(7, math.random(0,3))
|
||||
self:SetBodygroup(8, math.random(0,3))
|
||||
self:SetBodygroup(9, math.random(0,10))
|
||||
self:SetSkin(math.random(0,14))
|
||||
local rnd = math.random(50,200)
|
||||
self:SetColor(Color(rnd,rnd,rnd))
|
||||
|
||||
self:Give("weapon_vj_tdm_m24")
|
||||
elseif self.Type == "Patrol" then
|
||||
self:SetBodygroup(1, math.random(0,5))
|
||||
self:SetBodygroup(2, math.random(0,8))
|
||||
self:SetBodygroup(3, math.random(0,6))
|
||||
self:SetBodygroup(4, math.random(0,2))
|
||||
self:SetBodygroup(5, math.random(0,3))
|
||||
self:SetBodygroup(6, math.random(0,6))
|
||||
self:SetBodygroup(7, math.random(0,3))
|
||||
self:SetBodygroup(8, math.random(0,3))
|
||||
self:SetBodygroup(9, math.random(0,10))
|
||||
self:SetSkin(math.random(0,14))
|
||||
local rnd = math.random(50,200)
|
||||
self:SetColor(Color(rnd,rnd,rnd))
|
||||
|
||||
self:Give("weapon_vj_tdm_makarov")
|
||||
self:SetHealth(75)
|
||||
elseif self.Type == "Bomber" then
|
||||
self:Give("weapon_vj_rpg")
|
||||
self:SetHealth(175)
|
||||
elseif self.Type == "Heavy" then
|
||||
if math.random(1,3) == 1 then
|
||||
self:Give("weapon_vj_tdm_m249")
|
||||
else
|
||||
self:Give("weapon_vj_tdm_ak47")
|
||||
end
|
||||
self:SetHealth(200)
|
||||
else
|
||||
if math.random(1,3) == 1 then
|
||||
self:Give("weapon_vj_tdm_m14")
|
||||
else
|
||||
self:Give("weapon_vj_tdm_ump")
|
||||
end
|
||||
end
|
||||
|
||||
self:SetNWFloat('Team', self.Team)
|
||||
self.SearchCooldown = 0
|
||||
self.StuckCooldown = CurTime()+60
|
||||
end
|
||||
|
||||
function ENT:FlashEntity()
|
||||
self.Flinching = true
|
||||
self:StopAttacks(true)
|
||||
self.PlayingAttackAnimation = false
|
||||
local animTbl = self.AnimTbl_Flinch
|
||||
local anim = VJ_PICK(animTbl)
|
||||
local animDur = self.NextMoveAfterFlinchTime == false and self:DecideAnimationLength(anim, false, self.FlinchAnimationDecreaseLengthAmount) or self.NextMoveAfterFlinchTime
|
||||
self:VJ_ACT_PLAYACTIVITY(anim, true, animDur, false, 0, {SequenceDuration=animDur, PlayBackRateCalculated=true})
|
||||
timer.Create("timer_act_flinching"..self:EntIndex(), animDur, 1, function() self.Flinching = false end)
|
||||
self:CustomOnFlinch_AfterFlinch(dmginfo, hitgroup)
|
||||
self.NextFlinchT = CurTime() + self.NextFlinchTime
|
||||
end
|
||||
|
||||
function ENT:CustomOnThink()
|
||||
if self.SearchCooldown < CurTime() then
|
||||
for _, ent in ipairs(ents.FindInSphere(self:GetPos(), 5000)) do
|
||||
if ent:IsPlayer() and ent:Team() != self.Team or ent:IsNPC() and ent.Team != self.Team and math.random(1,4) == 1 then
|
||||
self:SetLastPosition(ent:GetPos())
|
||||
self:VJ_TASK_GOTO_LASTPOS()
|
||||
break
|
||||
end
|
||||
end
|
||||
self.SearchCooldown = CurTime()+math.random(15,45)
|
||||
end
|
||||
|
||||
if IsValid(self:GetEnemy()) then
|
||||
self.SearchCooldown = CurTime()+math.random(15,45)
|
||||
end
|
||||
|
||||
local colmins, colmaxs = self:GetCollisionBounds()
|
||||
local tr = util.TraceHull({
|
||||
start = self:GetPos(),
|
||||
endpos = self:GetPos(),
|
||||
filter = self,
|
||||
mins = colmins,
|
||||
maxs = colmaxs,
|
||||
mask = MASK_SHOT_HULL
|
||||
})
|
||||
if not tr.Hit then
|
||||
self.StuckCooldown = CurTime()+15
|
||||
end
|
||||
|
||||
if self.StuckCooldown < CurTime() then
|
||||
self:TakeDamage(self:Health())
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:CustomOnMeleeAttack_AfterChecks(hitEnt, isProp)
|
||||
return self.Takedowning
|
||||
end
|
||||
@@ -0,0 +1,22 @@
|
||||
ENT.Base = "npc_vj_human_base"
|
||||
ENT.Type = "ai"
|
||||
ENT.PrintName = "Soldier"
|
||||
|
||||
if CLIENT then
|
||||
local tm_mat = Material('tdmg/hud/teammate.png')
|
||||
function ENT:Draw()
|
||||
self:DrawModel()
|
||||
if self:GetNWFloat('Team') == LocalPlayer():Team() then
|
||||
local angle = EyeAngles()
|
||||
angle = Angle( 0, angle.y, 0 )
|
||||
angle:RotateAroundAxis( angle:Up(), -90 )
|
||||
angle:RotateAroundAxis( angle:Forward(), 90 )
|
||||
local pos = self:GetBonePosition(LocalPlayer():LookupBone("ValveBiped.Bip01_Head1"))+Vector(0,0,16)
|
||||
cam.Start3D2D( pos, angle, 0.1 )
|
||||
surface.SetDrawColor(5,155,255)
|
||||
surface.SetMaterial(tm_mat)
|
||||
surface.DrawTexturedRect(-12, -12, 24, 24)
|
||||
cam.End3D2D()
|
||||
end
|
||||
end
|
||||
end
|
||||
59
gamemodes/cod_custom/entities/entities/vj_tdm_k9/init.lua
Normal file
59
gamemodes/cod_custom/entities/entities/vj_tdm_k9/init.lua
Normal file
@@ -0,0 +1,59 @@
|
||||
AddCSLuaFile("shared.lua")
|
||||
include('shared.lua')
|
||||
/*-----------------------------------------------
|
||||
*** Copyright (c) 2012-2022 by DrVrej, All rights reserved. ***
|
||||
No parts of this code or any of its contents may be reproduced, copied, modified or adapted,
|
||||
without the prior written consent of the author, unless otherwise indicated for stand-alone materials.
|
||||
-----------------------------------------------*/
|
||||
ENT.StartHealth = 300
|
||||
ENT.Model = {"models/tdmg/dog_enemy.mdl"}
|
||||
|
||||
ENT.BloodColor = "Red"
|
||||
|
||||
ENT.VJ_NPC_Class = {""}
|
||||
|
||||
ENT.HasMeleeAttack = true
|
||||
ENT.AnimTbl_MeleeAttack = {"attack"}
|
||||
ENT.MeleeAttackDamage = 150
|
||||
|
||||
ENT.HasDeathAnimation = true
|
||||
ENT.AnimTbl_Death = {"death"}
|
||||
ENT.DeathAnimationChance = 1
|
||||
ENT.SoundTbl_Death = {""}
|
||||
ENT.CanFlinch = 1 -- 0 = Don't flinch | 1 = Flinch at any damage | 2 = Flinch only from certain damages
|
||||
ENT.FlinchChance = 2 -- Chance of it flinching from 1 to x | 1 will make it always flinch
|
||||
ENT.AnimTbl_Flinch = {"run_pain"} -- If it uses normal based animation, use this
|
||||
for i=1,8 do
|
||||
table.insert(ENT.SoundTbl_Death, "tdmg/dog/pain ("..math.random(1,8)..").wav")
|
||||
end
|
||||
|
||||
ENT.HasItemDropsOnDeath = false
|
||||
ENT.MeleeAttackDistance = 96
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
function ENT:CustomOnInitialize()
|
||||
self:SetNWFloat('Team', self.Team)
|
||||
self.BarkDelay = CurTime()+1
|
||||
if self.Team == 1 then
|
||||
self.VJ_NPC_Class = {"CLASS_SPECGRU"}
|
||||
else
|
||||
self.VJ_NPC_Class = {"CLASS_KORTAC"}
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:CustomOnTakeDamage_AfterDamage(dmginfo, hitgroup)
|
||||
if dmginfo:GetDamage() >= self:Health() then
|
||||
self.BarkDelay = CurTime()+5
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:FindTargets()
|
||||
local enemy = self:GetEnemy()
|
||||
if IsValid(enemy) and self.BarkDelay < CurTime() then
|
||||
self.BarkDelay = CurTime()+math.Rand(0.4,1.2)
|
||||
self:EmitSound("tdmg/dog/bark ("..math.random(1,8)..").wav")
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:CustomOnThink()
|
||||
self:FindTargets()
|
||||
end
|
||||
22
gamemodes/cod_custom/entities/entities/vj_tdm_k9/shared.lua
Normal file
22
gamemodes/cod_custom/entities/entities/vj_tdm_k9/shared.lua
Normal file
@@ -0,0 +1,22 @@
|
||||
ENT.Base = "npc_vj_creature_base"
|
||||
ENT.Type = "ai"
|
||||
ENT.PrintName = "NPC"
|
||||
|
||||
if CLIENT then
|
||||
local tm_mat = Material('tdmg/hud/teammate.png')
|
||||
function ENT:Draw()
|
||||
self:DrawModel()
|
||||
if self:GetNWFloat('Team') == LocalPlayer():Team() then
|
||||
local angle = EyeAngles()
|
||||
angle = Angle( 0, angle.y, 0 )
|
||||
angle:RotateAroundAxis( angle:Up(), -90 )
|
||||
angle:RotateAroundAxis( angle:Forward(), 90 )
|
||||
local pos = self:GetBonePosition(24)+Vector(0,0,16)
|
||||
cam.Start3D2D( pos, angle, 0.1 )
|
||||
surface.SetDrawColor(5,155,255)
|
||||
surface.SetMaterial(tm_mat)
|
||||
surface.DrawTexturedRect(-12, -12, 24, 24)
|
||||
cam.End3D2D()
|
||||
end
|
||||
end
|
||||
end
|
||||
70
gamemodes/cod_custom/entities/entities/vj_tdm_npc/init.lua
Normal file
70
gamemodes/cod_custom/entities/entities/vj_tdm_npc/init.lua
Normal file
@@ -0,0 +1,70 @@
|
||||
AddCSLuaFile("shared.lua")
|
||||
include('shared.lua')
|
||||
/*-----------------------------------------------
|
||||
*** Copyright (c) 2012-2022 by DrVrej, All rights reserved. ***
|
||||
No parts of this code or any of its contents may be reproduced, copied, modified or adapted,
|
||||
without the prior written consent of the author, unless otherwise indicated for stand-alone materials.
|
||||
-----------------------------------------------*/
|
||||
ENT.StartHealth = 250
|
||||
ENT.UsePlayerModelMovement = true
|
||||
ENT.Model = {}
|
||||
|
||||
ENT.BloodColor = "Red"
|
||||
|
||||
ENT.VJ_NPC_Class = {""}
|
||||
|
||||
ENT.HasMeleeAttack = true
|
||||
ENT.AnimTbl_MeleeAttack = {"vjseq_seq_meleeattack01"}
|
||||
ENT.AnimTbl_CallForHelp = {}
|
||||
ENT.MeleeAttackDamage = 50
|
||||
|
||||
ENT.FootStepTimeRun = 0.3
|
||||
ENT.FootStepTimeWalk = 0.5
|
||||
ENT.DropWeaponOnDeath = false
|
||||
|
||||
ENT.HasDeathAnimation = true
|
||||
ENT.AnimTbl_Death = {}
|
||||
for i = 1, 54 do
|
||||
table.insert(ENT.AnimTbl_Death, "dead"..i)
|
||||
end
|
||||
ENT.DeathAnimationChance = 1
|
||||
|
||||
ENT.SoundTbl_FootStep = {"npc/footsteps/hardboot_generic1.wav","npc/footsteps/hardboot_generic2.wav","npc/footsteps/hardboot_generic3.wav","npc/footsteps/hardboot_generic4.wav","npc/footsteps/hardboot_generic5.wav","npc/footsteps/hardboot_generic6.wav","npc/footsteps/hardboot_generic8.wav"}
|
||||
|
||||
ENT.HasItemDropsOnDeath = false
|
||||
|
||||
ENT.DeathCorpseFade = false
|
||||
|
||||
ENT.CallForBackUpOnDamageAnimation = {}
|
||||
|
||||
ENT.SoundTbl_Death = {}
|
||||
for i = 1, 14 do
|
||||
table.insert(ENT.SoundTbl_Death, "tdmg/ply/death"..i..".wav")
|
||||
end
|
||||
|
||||
ENT.SoundTbl_WeaponReload = {}
|
||||
for i = 1, 15 do
|
||||
table.insert(ENT.SoundTbl_WeaponReload, "tdmg/npc/reloading"..i..".wav")
|
||||
end
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
function ENT:CustomOnPreInitialize()
|
||||
if self.Team == 2 then
|
||||
self.Model = {"models/tdmg/pm/kortac_1_"..math.random(1,4).."_pm.mdl"}
|
||||
else
|
||||
self.Model = {"models/tdmg/pm/specgru_milsim_"..math.random(1,4).."_1_pm.mdl"}
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:CustomOnInitialize()
|
||||
if self.Team == 2 then
|
||||
self:Give("weapon_vj_tdm_ak47")
|
||||
else
|
||||
self:Give("weapon_vj_tdm_m4a1")
|
||||
end
|
||||
self:SetNWFloat('Team', self.Team)
|
||||
if self.Team == 1 then
|
||||
self.VJ_NPC_Class = {"CLASS_SPECGRU"}
|
||||
else
|
||||
self.VJ_NPC_Class = {"CLASS_KORTAC"}
|
||||
end
|
||||
end
|
||||
22
gamemodes/cod_custom/entities/entities/vj_tdm_npc/shared.lua
Normal file
22
gamemodes/cod_custom/entities/entities/vj_tdm_npc/shared.lua
Normal file
@@ -0,0 +1,22 @@
|
||||
ENT.Base = "npc_vj_human_base"
|
||||
ENT.Type = "ai"
|
||||
ENT.PrintName = "NPC"
|
||||
|
||||
if CLIENT then
|
||||
local tm_mat = Material('tdmg/hud/teammate.png')
|
||||
function ENT:Draw()
|
||||
self:DrawModel()
|
||||
if self:GetNWFloat('Team') == LocalPlayer():Team() then
|
||||
local angle = EyeAngles()
|
||||
angle = Angle( 0, angle.y, 0 )
|
||||
angle:RotateAroundAxis( angle:Up(), -90 )
|
||||
angle:RotateAroundAxis( angle:Forward(), 90 )
|
||||
local pos = self:GetBonePosition(LocalPlayer():LookupBone("ValveBiped.Bip01_Head1"))+Vector(0,0,16)
|
||||
cam.Start3D2D( pos, angle, 0.1 )
|
||||
surface.SetDrawColor(5,155,255)
|
||||
surface.SetMaterial(tm_mat)
|
||||
surface.DrawTexturedRect(-12, -12, 24, 24)
|
||||
cam.End3D2D()
|
||||
end
|
||||
end
|
||||
end
|
||||
69
gamemodes/cod_custom/entities/weapons/tdm_grenade.lua
Normal file
69
gamemodes/cod_custom/entities/weapons/tdm_grenade.lua
Normal file
@@ -0,0 +1,69 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
SWEP.PrintName = "Grenade"
|
||||
SWEP.Slot = 0
|
||||
SWEP.SlotPos = 4
|
||||
SWEP.Instructions = ""
|
||||
SWEP.ViewModel = "models/tdmg/wep/c_lethal_frag.mdl"
|
||||
SWEP.ViewModelFOV = 75
|
||||
SWEP.UseHands = true
|
||||
|
||||
SWEP.Primary.Automatic = false
|
||||
SWEP.Primary.ClipSize = -1
|
||||
SWEP.Primary.DefaultClip = -1
|
||||
SWEP.Secondary.ClipSize = -1
|
||||
SWEP.Secondary.DefaultClip = -1
|
||||
SWEP.Secondary.Automatic = false
|
||||
|
||||
SWEP.DrawAmmo = false
|
||||
|
||||
function SWEP:Initialize()
|
||||
self:SetHoldType("grenade")
|
||||
end
|
||||
|
||||
function SWEP:Throw()
|
||||
self:SendWeaponAnim(ACT_VM_PRIMARYATTACK)
|
||||
|
||||
local ply = self:GetOwner()
|
||||
timer.Simple(0.1, function()
|
||||
if !IsValid(ply) then return end
|
||||
ply:SetAnimation(PLAYER_ATTACK1)
|
||||
end)
|
||||
|
||||
if SERVER then
|
||||
timer.Simple(0.5, function()
|
||||
if !IsValid(ply) or !IsValid(self) then return end
|
||||
|
||||
local class = "tdm_frag"
|
||||
if self.IsFlash then
|
||||
class = "tdm_flash"
|
||||
end
|
||||
|
||||
local ent = ents.Create(class)
|
||||
ent:SetPos(ply:EyePos()+ply:GetForward()*16)
|
||||
ent.Player = ply
|
||||
ent:Spawn()
|
||||
ent:GetPhysicsObject():SetVelocity(ply:GetAimVector()*750+Vector(0,0,50))
|
||||
|
||||
ply:ViewPunch(Angle(10,0,0))
|
||||
ply:EmitSound("tdmg/wep/knife_miss.wav")
|
||||
end)
|
||||
timer.Simple(1, function()
|
||||
if !IsValid(ply) or !IsValid(self) then return end
|
||||
|
||||
ply:SetActiveWeapon(nil)
|
||||
ply:SelectWeapon(ply.FastKnifeBeforeWep)
|
||||
self:Remove()
|
||||
end)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function SWEP:PrimaryAttack() end
|
||||
|
||||
function SWEP:SecondaryAttack() end
|
||||
|
||||
function SWEP:Reload() end
|
||||
|
||||
function SWEP:DrawWorldModel() end
|
||||
101
gamemodes/cod_custom/entities/weapons/tdm_infection_knife.lua
Normal file
101
gamemodes/cod_custom/entities/weapons/tdm_infection_knife.lua
Normal file
@@ -0,0 +1,101 @@
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
SWEP.PrintName = "Knife"
|
||||
SWEP.Slot = 0
|
||||
SWEP.SlotPos = 4
|
||||
SWEP.Spawnable = true
|
||||
|
||||
SWEP.ViewModel = Model( "models/tdmg/wep/c_knife.mdl" )
|
||||
SWEP.WorldModel = ""
|
||||
SWEP.ViewModelFOV = 70
|
||||
SWEP.UseHands = true
|
||||
|
||||
SWEP.Primary.ClipSize = -1
|
||||
SWEP.Primary.DefaultClip = -1
|
||||
SWEP.Primary.Automatic = true
|
||||
SWEP.Primary.Ammo = "none"
|
||||
|
||||
SWEP.Secondary.ClipSize = -1
|
||||
SWEP.Secondary.DefaultClip = -1
|
||||
SWEP.Secondary.Automatic = true
|
||||
SWEP.Secondary.Ammo = "none"
|
||||
|
||||
SWEP.DrawAmmo = false
|
||||
|
||||
SWEP.HitDistance = 48
|
||||
|
||||
local SwingSound = Sound( "WeaponFrag.Throw" )
|
||||
local HitSound = Sound( "Flesh.ImpactHard" )
|
||||
|
||||
function SWEP:Initialize()
|
||||
self:SetHoldType( "fist" )
|
||||
end
|
||||
|
||||
function SWEP:PrimaryAttack()
|
||||
self:SetNextPrimaryFire(CurTime()+0.75)
|
||||
self:SendWeaponAnim(ACT_VM_HITRIGHT)
|
||||
self:SetAnimation(PLAYER_ATTACK1)
|
||||
if SERVER then
|
||||
timer.Simple(0.1, function()
|
||||
if !IsValid(self) then return end
|
||||
self:DealDamage()
|
||||
end)
|
||||
end
|
||||
timer.Simple(0.6, function()
|
||||
if !IsValid(self) then return end
|
||||
self:SendWeaponAnim(ACT_VM_IDLE)
|
||||
end)
|
||||
end
|
||||
|
||||
function SWEP:SecondaryAttack() end
|
||||
|
||||
function SWEP:DealDamage()
|
||||
local tr = util.TraceLine( {
|
||||
start = self.Owner:GetShootPos(),
|
||||
endpos = self.Owner:GetShootPos() + self.Owner:GetAimVector() * self.HitDistance,
|
||||
filter = self.Owner,
|
||||
mask = MASK_SHOT_HULL
|
||||
} )
|
||||
|
||||
if ( !IsValid( tr.Entity ) ) then
|
||||
tr = util.TraceHull( {
|
||||
start = self.Owner:GetShootPos(),
|
||||
endpos = self.Owner:GetShootPos() + self.Owner:GetAimVector() * self.HitDistance,
|
||||
filter = self.Owner,
|
||||
mins = Vector( -10, -10, -8 ),
|
||||
maxs = Vector( 10, 10, 8 ),
|
||||
mask = MASK_SHOT_HULL
|
||||
} )
|
||||
end
|
||||
|
||||
local tar = tr.Entity
|
||||
if IsValid(tar) then
|
||||
tar:TakeDamage(100, self:GetOwner(), self)
|
||||
if tar:IsPlayer() or tar:IsNPC() then
|
||||
self:EmitSound("tdmg/wep/melee_knife_0"..math.random(1,2)..".wav")
|
||||
else
|
||||
self:EmitSound("tdmg/wep/knife_impact_world"..math.random(1,2)..".wav")
|
||||
end
|
||||
else
|
||||
self:EmitSound("tdmg/wep/knife_swing_miss"..math.random(1,2)..".wav")
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:OnDrop()
|
||||
self:Remove()
|
||||
end
|
||||
|
||||
function SWEP:Deploy()
|
||||
self:EmitSound("tdmg/wep/knife_deploy.wav")
|
||||
self:SendWeaponAnim(ACT_VM_DRAW)
|
||||
timer.Simple(1, function()
|
||||
if !IsValid(self) then return end
|
||||
self:SendWeaponAnim(ACT_VM_IDLE)
|
||||
end)
|
||||
return true
|
||||
end
|
||||
|
||||
function SWEP:Holster()
|
||||
return true
|
||||
end
|
||||
86
gamemodes/cod_custom/entities/weapons/tdm_knife.lua
Normal file
86
gamemodes/cod_custom/entities/weapons/tdm_knife.lua
Normal file
@@ -0,0 +1,86 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
SWEP.PrintName = "Knife"
|
||||
SWEP.Slot = 0
|
||||
SWEP.SlotPos = 4
|
||||
SWEP.Instructions = ""
|
||||
SWEP.ViewModel = "models/tdmg/wep/c_combat_knife.mdl"
|
||||
SWEP.ViewModelFOV = 75
|
||||
SWEP.UseHands = true
|
||||
|
||||
SWEP.Primary.Automatic = false
|
||||
SWEP.Primary.ClipSize = -1
|
||||
SWEP.Primary.DefaultClip = -1
|
||||
SWEP.Secondary.ClipSize = -1
|
||||
SWEP.Secondary.DefaultClip = -1
|
||||
SWEP.Secondary.Automatic = false
|
||||
|
||||
SWEP.HitDistance = 56
|
||||
|
||||
SWEP.DrawAmmo = false
|
||||
|
||||
function SWEP:Initialize()
|
||||
self:SetHoldType("knife")
|
||||
end
|
||||
|
||||
function SWEP:Knifing()
|
||||
self:SendWeaponAnim(ACT_VM_PRIMARYATTACK)
|
||||
|
||||
local ply = self:GetOwner()
|
||||
ply:ViewPunch(Angle(0,-20,10))
|
||||
timer.Simple(0.1, function()
|
||||
if !IsValid(ply) then return end
|
||||
ply:SetAnimation(PLAYER_ATTACK1)
|
||||
end)
|
||||
|
||||
if SERVER then
|
||||
ply:EmitSound("tdmg/wep/knife_miss.wav")
|
||||
timer.Simple(0.15, function()
|
||||
if !IsValid(ply) or !IsValid(self) then return end
|
||||
|
||||
local tr = util.TraceLine( {
|
||||
start = self.Owner:GetShootPos(),
|
||||
endpos = self.Owner:GetShootPos() + self.Owner:GetAimVector() * self.HitDistance,
|
||||
filter = self.Owner,
|
||||
mask = MASK_SHOT_HULL
|
||||
} )
|
||||
|
||||
if ( !IsValid( tr.Entity ) ) then
|
||||
tr = util.TraceHull( {
|
||||
start = self.Owner:GetShootPos(),
|
||||
endpos = self.Owner:GetShootPos() + self.Owner:GetAimVector() * self.HitDistance,
|
||||
filter = self.Owner,
|
||||
mins = Vector( -16, -16, -8 ),
|
||||
maxs = Vector( 16, 16, 8 ),
|
||||
mask = MASK_SHOT_HULL
|
||||
} )
|
||||
end
|
||||
|
||||
local ent = tr.Entity
|
||||
|
||||
if IsValid(ent) and (ent:IsPlayer() or ent:IsNPC()) then
|
||||
ent:TakeDamage(250, ply, self)
|
||||
ply:EmitSound("tdmg/wep/knife_hit"..math.random(1,3)..".wav")
|
||||
elseif tr.Hit then
|
||||
ply:EmitSound("physics/concrete/rock_impact_hard"..math.random(1,6)..".wav")
|
||||
end
|
||||
end)
|
||||
timer.Simple(0.5, function()
|
||||
if !IsValid(ply) or !IsValid(self) then return end
|
||||
|
||||
ply:SetActiveWeapon(nil)
|
||||
ply:SelectWeapon(ply.FastKnifeBeforeWep)
|
||||
self:Remove()
|
||||
end)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function SWEP:PrimaryAttack() end
|
||||
|
||||
function SWEP:SecondaryAttack() end
|
||||
|
||||
function SWEP:Reload() end
|
||||
|
||||
function SWEP:DrawWorldModel() end
|
||||
111
gamemodes/cod_custom/entities/weapons/tdm_radio.lua
Normal file
111
gamemodes/cod_custom/entities/weapons/tdm_radio.lua
Normal file
@@ -0,0 +1,111 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
SWEP.PrintName = "Radio"
|
||||
SWEP.Slot = 0
|
||||
SWEP.SlotPos = 4
|
||||
SWEP.Instructions = "LMB - Mark Position, RMB - Zoom"
|
||||
SWEP.ViewModel = "models/tdmg/wep/chands_smallradio.mdl"
|
||||
SWEP.ViewModelFOV = 75
|
||||
SWEP.UseHands = true
|
||||
|
||||
SWEP.Primary.Automatic = false
|
||||
SWEP.Secondary.Automatic = false
|
||||
|
||||
SWEP.DrawAmmo = false
|
||||
|
||||
function SWEP:Initialize()
|
||||
self.Called = false
|
||||
self.FOVED = false
|
||||
self.EndAfter = 0
|
||||
self.PosTable = {}
|
||||
self:SetNWBool('drawarrow', true)
|
||||
if not self.Killstreak then
|
||||
self.Killstreak = "package"
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:Deploy()
|
||||
self:SendWeaponAnim(ACT_VM_DRAW)
|
||||
self:SetHoldType("slam")
|
||||
return true
|
||||
end
|
||||
|
||||
function SWEP:CheckSky()
|
||||
local tr = self:GetOwner():GetEyeTrace().HitPos
|
||||
|
||||
local tr2 = util.TraceLine({
|
||||
start = tr,
|
||||
endpos = tr+Vector(0,0,99999),
|
||||
filter = function( ent ) return ( ent:GetClass() == "prop_static" ) end,
|
||||
})
|
||||
|
||||
return tr2.HitSky
|
||||
end
|
||||
|
||||
function SWEP:PrimaryAttack()
|
||||
if self.Called then return end
|
||||
if not self:CheckSky() then return end
|
||||
self.Called = true
|
||||
self:SendWeaponAnim(ACT_VM_PULLBACK)
|
||||
timer.Simple(0.3, function()
|
||||
if !IsValid(self) then return end
|
||||
self:EmitSound("tdmg/radio_apply.wav")
|
||||
self:SendWeaponAnim(ACT_VM_IDLE)
|
||||
end)
|
||||
if SERVER then
|
||||
local ply = self:GetOwner()
|
||||
local pos = ply:GetEyeTrace().HitPos
|
||||
local cannext = true
|
||||
if self.ManyTimes then
|
||||
table.insert(self.PosTable, pos)
|
||||
pos = self.PosTable
|
||||
|
||||
self.EndAfter = self.EndAfter - 1
|
||||
if self.EndAfter > 0 then
|
||||
cannext = false
|
||||
end
|
||||
end
|
||||
if cannext then
|
||||
ply:SetFOV(0, 0.25)
|
||||
self:SetNWBool('drawarrow', false)
|
||||
timer.Simple(0.3, function()
|
||||
if !IsValid(self) then return end
|
||||
COD:ChooseKillstreakRadio(ply, self, pos)
|
||||
end)
|
||||
timer.Simple(1.2, function()
|
||||
if !IsValid(self) then return end
|
||||
if IsValid(ply) then
|
||||
ply:SelectWeapon(ply.RadioBeforeWep)
|
||||
end
|
||||
self:Remove()
|
||||
end)
|
||||
else
|
||||
timer.Simple(1, function()
|
||||
if !IsValid(self) then return end
|
||||
self.Called = false
|
||||
end)
|
||||
end
|
||||
end
|
||||
timer.Simple(0.4, function()
|
||||
if !IsValid(self) then return end
|
||||
if self.EndAfter == 0 then
|
||||
self:SendWeaponAnim(ACT_VM_HOLSTER)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function SWEP:SecondaryAttack()
|
||||
if self.Called then return end
|
||||
if SERVER then
|
||||
local ply = self:GetOwner()
|
||||
if not self.FOVED then
|
||||
self.FOVED = true
|
||||
ply:SetFOV(50, 0.25)
|
||||
else
|
||||
self.FOVED = false
|
||||
ply:SetFOV(0, 0.25)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:DrawWorldModel() end
|
||||
@@ -0,0 +1,192 @@
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: SetupWeaponHoldTypeForAI
|
||||
Desc: Sets up ACT translations from generic activities to NPC specific activies. In a seperate file to clean up the init.lua
|
||||
Not all NPCs have support for all animations (for example Citizens don't have pistol animations)
|
||||
This only supports the holdtypes the default NPC models can support
|
||||
All of these are taken directly from IMPLEMENT_ACTTABLE() macro of the C++ weapons
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:SetupWeaponHoldTypeForAI( t )
|
||||
|
||||
self.ActivityTranslateAI = {}
|
||||
|
||||
-- Default is pistol/revolver for reasons
|
||||
self.ActivityTranslateAI[ ACT_IDLE ] = ACT_IDLE_PISTOL
|
||||
self.ActivityTranslateAI[ ACT_IDLE_ANGRY ] = ACT_IDLE_ANGRY_PISTOL
|
||||
self.ActivityTranslateAI[ ACT_RANGE_ATTACK1 ] = ACT_RANGE_ATTACK_PISTOL
|
||||
self.ActivityTranslateAI[ ACT_RELOAD ] = ACT_RELOAD_PISTOL
|
||||
self.ActivityTranslateAI[ ACT_WALK_AIM ] = ACT_WALK_AIM_PISTOL
|
||||
self.ActivityTranslateAI[ ACT_RUN_AIM ] = ACT_RUN_AIM_PISTOL
|
||||
self.ActivityTranslateAI[ ACT_GESTURE_RANGE_ATTACK1 ] = ACT_GESTURE_RANGE_ATTACK_PISTOL
|
||||
self.ActivityTranslateAI[ ACT_RELOAD_LOW ] = ACT_RELOAD_PISTOL_LOW
|
||||
|
||||
self.ActivityTranslateAI[ ACT_RANGE_ATTACK1_LOW ] = ACT_RANGE_ATTACK_PISTOL_LOW
|
||||
self.ActivityTranslateAI[ ACT_COVER_LOW ] = ACT_COVER_PISTOL_LOW
|
||||
self.ActivityTranslateAI[ ACT_RANGE_AIM_LOW ] = ACT_RANGE_AIM_PISTOL_LOW
|
||||
self.ActivityTranslateAI[ ACT_GESTURE_RELOAD ] = ACT_GESTURE_RELOAD_PISTOL
|
||||
|
||||
self.ActivityTranslateAI[ ACT_WALK ] = ACT_WALK_PISTOL
|
||||
self.ActivityTranslateAI[ ACT_RUN ] = ACT_RUN_PISTOL
|
||||
|
||||
self.ActivityTranslateAI[ ACT_IDLE_RELAXED ] = ACT_IDLE_PISTOL
|
||||
self.ActivityTranslateAI[ ACT_IDLE_STIMULATED ] = ACT_IDLE_STIMULATED
|
||||
self.ActivityTranslateAI[ ACT_IDLE_AGITATED ] = ACT_IDLE_ANGRY_PISTOL
|
||||
self.ActivityTranslateAI[ ACT_IDLE_STEALTH ] = ACT_IDLE_STEALTH_PISTOL
|
||||
|
||||
self.ActivityTranslateAI[ ACT_WALK_RELAXED ] = ACT_WALK
|
||||
self.ActivityTranslateAI[ ACT_WALK_STIMULATED ] = ACT_WALK_STIMULATED
|
||||
self.ActivityTranslateAI[ ACT_WALK_AGITATED ] = ACT_WALK_AIM_PISTOL
|
||||
self.ActivityTranslateAI[ ACT_WALK_STEALTH ] = ACT_WALK_STEALTH_PISTOL
|
||||
|
||||
self.ActivityTranslateAI[ ACT_RUN_RELAXED ] = ACT_RUN
|
||||
self.ActivityTranslateAI[ ACT_RUN_STIMULATED ] = ACT_RUN_STIMULATED
|
||||
self.ActivityTranslateAI[ ACT_RUN_AGITATED ] = ACT_RUN_AIM_PISTOL
|
||||
self.ActivityTranslateAI[ ACT_RUN_STEALTH ] = ACT_RUN_STEALTH_PISTOL
|
||||
|
||||
self.ActivityTranslateAI[ ACT_IDLE_AIM_RELAXED ] = ACT_IDLE_PISTOL
|
||||
self.ActivityTranslateAI[ ACT_IDLE_AIM_STIMULATED ] = ACT_IDLE_ANGRY_PISTOL
|
||||
self.ActivityTranslateAI[ ACT_IDLE_AIM_AGITATED ] = ACT_IDLE_ANGRY_PISTOL
|
||||
self.ActivityTranslateAI[ ACT_IDLE_AIM_STEALTH ] = ACT_IDLE_STEALTH_PISTOL
|
||||
|
||||
self.ActivityTranslateAI[ ACT_WALK_AIM_RELAXED ] = ACT_WALK
|
||||
self.ActivityTranslateAI[ ACT_WALK_AIM_STIMULATED ] = ACT_WALK_AIM_PISTOL
|
||||
self.ActivityTranslateAI[ ACT_WALK_AIM_AGITATED ] = ACT_WALK_AIM_PISTOL
|
||||
self.ActivityTranslateAI[ ACT_WALK_AIM_STEALTH ] = ACT_WALK_AIM_STEALTH_PISTOL
|
||||
|
||||
self.ActivityTranslateAI[ ACT_RUN_AIM_RELAXED ] = ACT_RUN
|
||||
self.ActivityTranslateAI[ ACT_RUN_AIM_STIMULATED ] = ACT_RUN_AIM_PISTOL
|
||||
self.ActivityTranslateAI[ ACT_RUN_AIM_AGITATED ] = ACT_RUN_AIM_PISTOL
|
||||
self.ActivityTranslateAI[ ACT_RUN_AIM_STEALTH ] = ACT_RUN_AIM_STEALTH_PISTOL
|
||||
|
||||
self.ActivityTranslateAI[ ACT_CROUCHIDLE_STIMULATED] = ACT_CROUCHIDLE_STIMULATED
|
||||
self.ActivityTranslateAI[ ACT_CROUCHIDLE_AIM_STIMULATED ] = ACT_RANGE_AIM_PISTOL_LOW
|
||||
self.ActivityTranslateAI[ ACT_CROUCHIDLE_AGITATED ] = ACT_RANGE_AIM_PISTOL_LOW
|
||||
|
||||
self.ActivityTranslateAI[ ACT_READINESS_RELAXED_TO_STIMULATED ] = ACT_READINESS_PISTOL_RELAXED_TO_STIMULATED
|
||||
self.ActivityTranslateAI[ ACT_READINESS_RELAXED_TO_STIMULATED_WALK ] = ACT_READINESS_PISTOL_RELAXED_TO_STIMULATED_WALK
|
||||
self.ActivityTranslateAI[ ACT_READINESS_AGITATED_TO_STIMULATED ] = ACT_READINESS_PISTOL_AGITATED_TO_STIMULATED
|
||||
self.ActivityTranslateAI[ ACT_READINESS_STIMULATED_TO_RELAXED ] = ACT_READINESS_PISTOL_STIMULATED_TO_RELAXED
|
||||
|
||||
if ( t == "ar2" || t == "smg" ) then
|
||||
|
||||
self.ActivityTranslateAI[ ACT_RANGE_ATTACK1 ] = ACT_RANGE_ATTACK_AR2
|
||||
self.ActivityTranslateAI[ ACT_RELOAD ] = ACT_RELOAD_SMG1
|
||||
self.ActivityTranslateAI[ ACT_IDLE ] = ACT_IDLE_SMG1
|
||||
self.ActivityTranslateAI[ ACT_IDLE_ANGRY ] = ACT_IDLE_ANGRY_SMG1
|
||||
|
||||
self.ActivityTranslateAI[ ACT_WALK ] = ACT_WALK_RIFLE
|
||||
self.ActivityTranslateAI[ ACT_WALK_AIM ] = ACT_WALK_AIM_RIFLE
|
||||
|
||||
self.ActivityTranslateAI[ ACT_IDLE_RELAXED ] = ACT_IDLE_SMG1_RELAXED
|
||||
self.ActivityTranslateAI[ ACT_IDLE_STIMULATED ] = ACT_IDLE_SMG1_STIMULATED
|
||||
self.ActivityTranslateAI[ ACT_IDLE_AGITATED ] = ACT_IDLE_ANGRY_SMG1
|
||||
|
||||
self.ActivityTranslateAI[ ACT_WALK_RELAXED ] = ACT_WALK_RIFLE_RELAXED
|
||||
self.ActivityTranslateAI[ ACT_WALK_STIMULATED ] = ACT_WALK_RIFLE_STIMULATED
|
||||
self.ActivityTranslateAI[ ACT_WALK_AGITATED ] = ACT_WALK_AIM_RIFLE
|
||||
|
||||
self.ActivityTranslateAI[ ACT_RUN_RELAXED ] = ACT_RUN_RIFLE_RELAXED
|
||||
self.ActivityTranslateAI[ ACT_RUN_STIMULATED ] = ACT_RUN_RIFLE_STIMULATED
|
||||
self.ActivityTranslateAI[ ACT_RUN_AGITATED ] = ACT_RUN_AIM_RIFLE
|
||||
|
||||
self.ActivityTranslateAI[ ACT_IDLE_AIM_RELAXED ] = ACT_IDLE_SMG1_RELAXED
|
||||
self.ActivityTranslateAI[ ACT_IDLE_AIM_STIMULATED ] = ACT_IDLE_AIM_RIFLE_STIMULATED
|
||||
self.ActivityTranslateAI[ ACT_IDLE_AIM_AGITATED ] = ACT_IDLE_ANGRY_SMG1
|
||||
|
||||
self.ActivityTranslateAI[ ACT_WALK_AIM_RELAXED ] = ACT_WALK_RIFLE_RELAXED
|
||||
self.ActivityTranslateAI[ ACT_WALK_AIM_STIMULATED ] = ACT_WALK_AIM_RIFLE_STIMULATED
|
||||
self.ActivityTranslateAI[ ACT_WALK_AIM_AGITATED ] = ACT_WALK_AIM_RIFLE
|
||||
|
||||
self.ActivityTranslateAI[ ACT_RUN_AIM_RELAXED ] = ACT_RUN_RIFLE_RELAXED
|
||||
self.ActivityTranslateAI[ ACT_RUN_AIM_STIMULATED ] = ACT_RUN_AIM_RIFLE_STIMULATED
|
||||
self.ActivityTranslateAI[ ACT_RUN_AIM_AGITATED ] = ACT_RUN_AIM_RIFLE
|
||||
|
||||
self.ActivityTranslateAI[ ACT_WALK_CROUCH ] = ACT_WALK_CROUCH_RIFLE
|
||||
self.ActivityTranslateAI[ ACT_WALK_CROUCH_AIM ] = ACT_WALK_CROUCH_AIM_RIFLE
|
||||
self.ActivityTranslateAI[ ACT_RUN ] = ACT_RUN_RIFLE
|
||||
self.ActivityTranslateAI[ ACT_RUN_AIM ] = ACT_RUN_AIM_RIFLE
|
||||
self.ActivityTranslateAI[ ACT_RUN_CROUCH ] = ACT_RUN_CROUCH_RIFLE
|
||||
self.ActivityTranslateAI[ ACT_RUN_CROUCH_AIM ] = ACT_RUN_CROUCH_AIM_RIFLE
|
||||
self.ActivityTranslateAI[ ACT_GESTURE_RANGE_ATTACK1 ] = ACT_GESTURE_RANGE_ATTACK_AR2
|
||||
self.ActivityTranslateAI[ ACT_RANGE_ATTACK1_LOW ] = ACT_RANGE_ATTACK_SMG1_LOW
|
||||
self.ActivityTranslateAI[ ACT_COVER_LOW ] = ACT_COVER_SMG1_LOW
|
||||
self.ActivityTranslateAI[ ACT_RANGE_AIM_LOW ] = ACT_RANGE_AIM_AR2_LOW
|
||||
self.ActivityTranslateAI[ ACT_RELOAD_LOW ] = ACT_RELOAD_SMG1_LOW
|
||||
self.ActivityTranslateAI[ ACT_GESTURE_RELOAD ] = ACT_GESTURE_RELOAD_SMG1
|
||||
|
||||
-- Extra overrides for SMG holdtype
|
||||
if ( t == "smg" ) then
|
||||
self.ActivityTranslateAI[ ACT_RANGE_ATTACK1 ] = ACT_RANGE_ATTACK_SMG1
|
||||
self.ActivityTranslateAI[ ACT_GESTURE_RANGE_ATTACK1 ] = ACT_GESTURE_RANGE_ATTACK_SMG1
|
||||
self.ActivityTranslateAI[ ACT_RANGE_AIM_LOW ] = ACT_RANGE_AIM_SMG1_LOW
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
if ( t == "shotgun" || t == "crossbow" ) then
|
||||
self.ActivityTranslateAI[ ACT_IDLE ] = ACT_IDLE_SMG1
|
||||
|
||||
self.ActivityTranslateAI[ ACT_RANGE_ATTACK1 ] = ACT_RANGE_ATTACK_SHOTGUN
|
||||
self.ActivityTranslateAI[ ACT_RELOAD ] = ACT_RELOAD_SHOTGUN
|
||||
self.ActivityTranslateAI[ ACT_WALK ] = ACT_WALK_RIFLE
|
||||
self.ActivityTranslateAI[ ACT_IDLE_ANGRY ] = ACT_IDLE_ANGRY_SHOTGUN
|
||||
|
||||
self.ActivityTranslateAI[ ACT_IDLE_RELAXED ] = ACT_IDLE_SHOTGUN_RELAXED
|
||||
self.ActivityTranslateAI[ ACT_IDLE_STIMULATED ] = ACT_IDLE_SHOTGUN_STIMULATED
|
||||
self.ActivityTranslateAI[ ACT_IDLE_AGITATED ] = ACT_IDLE_SHOTGUN_AGITATED
|
||||
|
||||
self.ActivityTranslateAI[ ACT_WALK_RELAXED ] = ACT_WALK_RIFLE_RELAXED
|
||||
self.ActivityTranslateAI[ ACT_WALK_STIMULATED ] = ACT_WALK_RIFLE_STIMULATED
|
||||
self.ActivityTranslateAI[ ACT_WALK_AGITATED ] = ACT_WALK_AIM_RIFLE
|
||||
|
||||
self.ActivityTranslateAI[ ACT_RUN_RELAXED ] = ACT_RUN_RIFLE_RELAXED
|
||||
self.ActivityTranslateAI[ ACT_RUN_STIMULATED ] = ACT_RUN_RIFLE_STIMULATED
|
||||
self.ActivityTranslateAI[ ACT_RUN_AGITATED ] = ACT_RUN_AIM_RIFLE
|
||||
|
||||
self.ActivityTranslateAI[ ACT_IDLE_AIM_RELAXED ] = ACT_IDLE_SMG1_RELAXED
|
||||
self.ActivityTranslateAI[ ACT_IDLE_AIM_STIMULATED ] = ACT_IDLE_AIM_RIFLE_STIMULATED
|
||||
self.ActivityTranslateAI[ ACT_IDLE_AIM_AGITATED ] = ACT_IDLE_ANGRY_SMG1
|
||||
|
||||
self.ActivityTranslateAI[ ACT_WALK_AIM_RELAXED ] = ACT_WALK_RIFLE_RELAXED
|
||||
self.ActivityTranslateAI[ ACT_WALK_AIM_STIMULATED ] = ACT_WALK_AIM_RIFLE_STIMULATED
|
||||
self.ActivityTranslateAI[ ACT_WALK_AIM_AGITATED ] = ACT_WALK_AIM_RIFLE
|
||||
|
||||
self.ActivityTranslateAI[ ACT_RUN_AIM_RELAXED ] = ACT_RUN_RIFLE_RELAXED
|
||||
self.ActivityTranslateAI[ ACT_RUN_AIM_STIMULATED ] = ACT_RUN_AIM_RIFLE_STIMULATED
|
||||
self.ActivityTranslateAI[ ACT_RUN_AIM_AGITATED ] = ACT_RUN_AIM_RIFLE
|
||||
|
||||
self.ActivityTranslateAI[ ACT_WALK_AIM ] = ACT_WALK_AIM_SHOTGUN
|
||||
self.ActivityTranslateAI[ ACT_WALK_CROUCH ] = ACT_WALK_CROUCH_RIFLE
|
||||
self.ActivityTranslateAI[ ACT_WALK_CROUCH_AIM ] = ACT_WALK_CROUCH_AIM_RIFLE
|
||||
self.ActivityTranslateAI[ ACT_RUN ] = ACT_RUN_RIFLE
|
||||
self.ActivityTranslateAI[ ACT_RUN_AIM ] = ACT_RUN_AIM_SHOTGUN
|
||||
self.ActivityTranslateAI[ ACT_RUN_CROUCH ] = ACT_RUN_CROUCH_RIFLE
|
||||
self.ActivityTranslateAI[ ACT_RUN_CROUCH_AIM ] = ACT_RUN_CROUCH_AIM_RIFLE
|
||||
self.ActivityTranslateAI[ ACT_GESTURE_RANGE_ATTACK1 ] = ACT_GESTURE_RANGE_ATTACK_SHOTGUN
|
||||
self.ActivityTranslateAI[ ACT_RANGE_ATTACK1_LOW ] = ACT_RANGE_ATTACK_SHOTGUN_LOW
|
||||
self.ActivityTranslateAI[ ACT_RELOAD_LOW ] = ACT_RELOAD_SHOTGUN_LOW
|
||||
self.ActivityTranslateAI[ ACT_GESTURE_RELOAD ] = ACT_GESTURE_RELOAD_SHOTGUN
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
if ( t == "rpg" ) then
|
||||
self.ActivityTranslateAI[ ACT_RANGE_ATTACK1 ] = ACT_RANGE_ATTACK_RPG
|
||||
|
||||
self.ActivityTranslateAI[ ACT_IDLE_RELAXED ] = ACT_IDLE_RPG_RELAXED
|
||||
self.ActivityTranslateAI[ ACT_IDLE_STIMULATED ] = ACT_IDLE_ANGRY_RPG
|
||||
self.ActivityTranslateAI[ ACT_IDLE_AGITATED ] = ACT_IDLE_ANGRY_RPG
|
||||
|
||||
self.ActivityTranslateAI[ ACT_IDLE ] = ACT_IDLE_RPG
|
||||
self.ActivityTranslateAI[ ACT_IDLE_ANGRY ] = ACT_IDLE_ANGRY_RPG
|
||||
self.ActivityTranslateAI[ ACT_WALK ] = ACT_WALK_RPG
|
||||
self.ActivityTranslateAI[ ACT_WALK_CROUCH ] = ACT_WALK_CROUCH_RPG
|
||||
self.ActivityTranslateAI[ ACT_RUN ] = ACT_RUN_RPG
|
||||
self.ActivityTranslateAI[ ACT_RUN_CROUCH ] = ACT_RUN_CROUCH_RPG
|
||||
self.ActivityTranslateAI[ ACT_COVER_LOW ] = ACT_COVER_LOW_RPG
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
end
|
||||
212
gamemodes/cod_custom/entities/weapons/weapon_base/cl_init.lua
Normal file
212
gamemodes/cod_custom/entities/weapons/weapon_base/cl_init.lua
Normal file
@@ -0,0 +1,212 @@
|
||||
|
||||
include( "ai_translations.lua" )
|
||||
include( "sh_anim.lua" )
|
||||
include( "shared.lua" )
|
||||
|
||||
SWEP.Slot = 0 -- Slot in the weapon selection menu
|
||||
SWEP.SlotPos = 10 -- Position in the slot
|
||||
SWEP.DrawAmmo = true -- Should draw the default HL2 ammo counter
|
||||
SWEP.DrawCrosshair = true -- Should draw the default crosshair
|
||||
SWEP.DrawWeaponInfoBox = true -- Should draw the weapon info box
|
||||
SWEP.BounceWeaponIcon = true -- Should the weapon icon bounce?
|
||||
SWEP.SwayScale = 1.0 -- The scale of the viewmodel sway
|
||||
SWEP.BobScale = 1.0 -- The scale of the viewmodel bob
|
||||
|
||||
SWEP.RenderGroup = RENDERGROUP_OPAQUE
|
||||
|
||||
-- Override this in your SWEP to set the icon in the weapon selection
|
||||
SWEP.WepSelectIcon = surface.GetTextureID( "weapons/swep" )
|
||||
|
||||
-- This is the corner of the speech bubble
|
||||
SWEP.SpeechBubbleLid = surface.GetTextureID( "gui/speech_lid" )
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
You can draw to the HUD here - it will only draw when
|
||||
the client has the weapon deployed..
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:DrawHUD()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Checks the objects before any action is taken
|
||||
This is to make sure that the entities haven't been removed
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:DrawWeaponSelection( x, y, wide, tall, alpha )
|
||||
|
||||
-- Set us up the texture
|
||||
surface.SetDrawColor( 255, 255, 255, alpha )
|
||||
surface.SetTexture( self.WepSelectIcon )
|
||||
|
||||
-- Lets get a sin wave to make it bounce
|
||||
local fsin = 0
|
||||
|
||||
if ( self.BounceWeaponIcon == true ) then
|
||||
fsin = math.sin( CurTime() * 10 ) * 5
|
||||
end
|
||||
|
||||
-- Borders
|
||||
y = y + 10
|
||||
x = x + 10
|
||||
wide = wide - 20
|
||||
|
||||
-- Draw that mother
|
||||
surface.DrawTexturedRect( x + fsin, y - fsin, wide - fsin * 2 , ( wide / 2 ) + fsin )
|
||||
|
||||
-- Draw weapon info box
|
||||
self:PrintWeaponInfo( x + wide + 20, y + tall * 0.95, alpha )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
This draws the weapon info box
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:PrintWeaponInfo( x, y, alpha )
|
||||
|
||||
if ( self.DrawWeaponInfoBox == false ) then return end
|
||||
|
||||
if (self.InfoMarkup == nil ) then
|
||||
local str
|
||||
local title_color = "<color=230,230,230,255>"
|
||||
local text_color = "<color=150,150,150,255>"
|
||||
|
||||
str = "<font=HudSelectionText>"
|
||||
if ( self.Author != "" ) then str = str .. title_color .. "Author:</color>\t" .. text_color .. self.Author .. "</color>\n" end
|
||||
if ( self.Contact != "" ) then str = str .. title_color .. "Contact:</color>\t" .. text_color .. self.Contact .. "</color>\n\n" end
|
||||
if ( self.Purpose != "" ) then str = str .. title_color .. "Purpose:</color>\n" .. text_color .. self.Purpose .. "</color>\n\n" end
|
||||
if ( self.Instructions != "" ) then str = str .. title_color .. "Instructions:</color>\n" .. text_color .. self.Instructions .. "</color>\n" end
|
||||
str = str .. "</font>"
|
||||
|
||||
self.InfoMarkup = markup.Parse( str, 250 )
|
||||
end
|
||||
|
||||
surface.SetDrawColor( 60, 60, 60, alpha )
|
||||
surface.SetTexture( self.SpeechBubbleLid )
|
||||
|
||||
surface.DrawTexturedRect( x, y - 64 - 5, 128, 64 )
|
||||
draw.RoundedBox( 8, x - 5, y - 6, 260, self.InfoMarkup:GetHeight() + 18, Color( 60, 60, 60, alpha ) )
|
||||
|
||||
self.InfoMarkup:Draw( x + 5, y + 5, nil, nil, alpha )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: SWEP:FreezeMovement()
|
||||
Desc: Return true to freeze moving the view
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:FreezeMovement()
|
||||
return false
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: SWEP:ViewModelDrawn( viewModel )
|
||||
Desc: Called straight after the viewmodel has been drawn
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:ViewModelDrawn( vm )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: OnRestore
|
||||
Desc: Called immediately after a "load"
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:OnRestore()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: CustomAmmoDisplay
|
||||
Desc: Return a table
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:CustomAmmoDisplay()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: GetViewModelPosition
|
||||
Desc: Allows you to re-position the view model
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:GetViewModelPosition( pos, ang )
|
||||
|
||||
return pos, ang
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: TranslateFOV
|
||||
Desc: Allows the weapon to translate the player's FOV (clientside)
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:TranslateFOV( current_fov )
|
||||
|
||||
return current_fov
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: DrawWorldModel
|
||||
Desc: Draws the world model (not the viewmodel)
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:DrawWorldModel()
|
||||
|
||||
self:DrawModel()
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: DrawWorldModelTranslucent
|
||||
Desc: Draws the world model (not the viewmodel)
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:DrawWorldModelTranslucent()
|
||||
|
||||
self:DrawModel()
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: AdjustMouseSensitivity
|
||||
Desc: Allows you to adjust the mouse sensitivity.
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:AdjustMouseSensitivity()
|
||||
|
||||
return nil
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: GetTracerOrigin
|
||||
Desc: Allows you to override where the tracer comes from (in first person view)
|
||||
returning anything but a vector indicates that you want the default action
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:GetTracerOrigin()
|
||||
|
||||
--[[
|
||||
local ply = self:GetOwner()
|
||||
local pos = ply:EyePos() + ply:EyeAngles():Right() * -5
|
||||
return pos
|
||||
--]]
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: FireAnimationEvent
|
||||
Desc: Allows you to override weapon animation events
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:FireAnimationEvent( pos, ang, event, options )
|
||||
|
||||
if ( !self.CSMuzzleFlashes ) then return end
|
||||
|
||||
-- CS Muzzle flashes
|
||||
if ( event == 5001 or event == 5011 or event == 5021 or event == 5031 ) then
|
||||
|
||||
local data = EffectData()
|
||||
data:SetFlags( 0 )
|
||||
data:SetEntity( self.Owner:GetViewModel() )
|
||||
data:SetAttachment( math.floor( ( event - 4991 ) / 10 ) )
|
||||
data:SetScale( 1 )
|
||||
|
||||
if ( self.CSMuzzleX ) then
|
||||
util.Effect( "CS_MuzzleFlash_X", data )
|
||||
else
|
||||
util.Effect( "CS_MuzzleFlash", data )
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
end
|
||||
104
gamemodes/cod_custom/entities/weapons/weapon_base/init.lua
Normal file
104
gamemodes/cod_custom/entities/weapons/weapon_base/init.lua
Normal file
@@ -0,0 +1,104 @@
|
||||
|
||||
AddCSLuaFile( "cl_init.lua" )
|
||||
AddCSLuaFile( "ai_translations.lua" )
|
||||
AddCSLuaFile( "sh_anim.lua" )
|
||||
AddCSLuaFile( "shared.lua" )
|
||||
|
||||
include( "ai_translations.lua" )
|
||||
include( "sh_anim.lua" )
|
||||
include( "shared.lua" )
|
||||
|
||||
SWEP.Weight = 5 -- Decides whether we should switch from/to this
|
||||
SWEP.AutoSwitchTo = true -- Auto switch to if we pick it up
|
||||
SWEP.AutoSwitchFrom = true -- Auto switch from if you pick up a better weapon
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: OnRestore
|
||||
Desc: The game has just been reloaded. This is usually the right place
|
||||
to call the GetNW* functions to restore the script's values.
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:OnRestore()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: AcceptInput
|
||||
Desc: Accepts input, return true to override/accept input
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:AcceptInput( name, activator, caller, data )
|
||||
return false
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: KeyValue
|
||||
Desc: Called when a keyvalue is added to us
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:KeyValue( key, value )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: Equip
|
||||
Desc: A player or NPC has picked the weapon up
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:Equip( newOwner )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: EquipAmmo
|
||||
Desc: The player has picked up the weapon and has taken the ammo from it
|
||||
The weapon will be removed immidiately after this call.
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:EquipAmmo( newOwner )
|
||||
end
|
||||
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: OnDrop
|
||||
Desc: Weapon was dropped
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:OnDrop()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: ShouldDropOnDie
|
||||
Desc: Should this weapon be dropped when its owner dies?
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:ShouldDropOnDie()
|
||||
return true
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: GetCapabilities
|
||||
Desc: For NPCs, returns what they should try to do with it.
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:GetCapabilities()
|
||||
|
||||
return CAP_WEAPON_RANGE_ATTACK1
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: NPCShoot_Secondary
|
||||
Desc: NPC tried to fire secondary attack
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:NPCShoot_Secondary( shootPos, shootDir )
|
||||
|
||||
self:SecondaryAttack()
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: NPCShoot_Secondary
|
||||
Desc: NPC tried to fire primary attack
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:NPCShoot_Primary( shootPos, shootDir )
|
||||
|
||||
self:PrimaryAttack()
|
||||
|
||||
end
|
||||
|
||||
-- These tell the NPC how to use the weapon
|
||||
AccessorFunc( SWEP, "fNPCMinBurst", "NPCMinBurst" )
|
||||
AccessorFunc( SWEP, "fNPCMaxBurst", "NPCMaxBurst" )
|
||||
AccessorFunc( SWEP, "fNPCFireRate", "NPCFireRate" )
|
||||
AccessorFunc( SWEP, "fNPCMinRestTime", "NPCMinRest" )
|
||||
AccessorFunc( SWEP, "fNPCMaxRestTime", "NPCMaxRest" )
|
||||
@@ -0,0 +1,87 @@
|
||||
|
||||
local ActIndex = {
|
||||
[ "pistol" ] = ACT_HL2MP_IDLE_PISTOL,
|
||||
[ "smg" ] = ACT_HL2MP_IDLE_SMG1,
|
||||
[ "grenade" ] = ACT_HL2MP_IDLE_GRENADE,
|
||||
[ "ar2" ] = ACT_HL2MP_IDLE_AR2,
|
||||
[ "shotgun" ] = ACT_HL2MP_IDLE_SHOTGUN,
|
||||
[ "rpg" ] = ACT_HL2MP_IDLE_RPG,
|
||||
[ "physgun" ] = ACT_HL2MP_IDLE_PHYSGUN,
|
||||
[ "crossbow" ] = ACT_HL2MP_IDLE_CROSSBOW,
|
||||
[ "melee" ] = ACT_HL2MP_IDLE_MELEE,
|
||||
[ "slam" ] = ACT_HL2MP_IDLE_SLAM,
|
||||
[ "normal" ] = ACT_HL2MP_IDLE,
|
||||
[ "fist" ] = ACT_HL2MP_IDLE_FIST,
|
||||
[ "melee2" ] = ACT_HL2MP_IDLE_MELEE2,
|
||||
[ "passive" ] = ACT_HL2MP_IDLE_PASSIVE,
|
||||
[ "knife" ] = ACT_HL2MP_IDLE_KNIFE,
|
||||
[ "duel" ] = ACT_HL2MP_IDLE_DUEL,
|
||||
[ "camera" ] = ACT_HL2MP_IDLE_CAMERA,
|
||||
[ "magic" ] = ACT_HL2MP_IDLE_MAGIC,
|
||||
[ "revolver" ] = ACT_HL2MP_IDLE_REVOLVER
|
||||
}
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: SetWeaponHoldType
|
||||
Desc: Sets up the translation table, to translate from normal
|
||||
standing idle pose, to holding weapon pose.
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:SetWeaponHoldType( t )
|
||||
|
||||
t = string.lower( t )
|
||||
local index = ActIndex[ t ]
|
||||
|
||||
if ( index == nil ) then
|
||||
Msg( "SWEP:SetWeaponHoldType - ActIndex[ \"" .. t .. "\" ] isn't set! (defaulting to normal)\n" )
|
||||
t = "normal"
|
||||
index = ActIndex[ t ]
|
||||
end
|
||||
|
||||
self.ActivityTranslate = {}
|
||||
self.ActivityTranslate[ ACT_MP_STAND_IDLE ] = index
|
||||
self.ActivityTranslate[ ACT_MP_WALK ] = index + 1
|
||||
self.ActivityTranslate[ ACT_MP_RUN ] = index + 2
|
||||
self.ActivityTranslate[ ACT_MP_CROUCH_IDLE ] = index + 3
|
||||
self.ActivityTranslate[ ACT_MP_CROUCHWALK ] = index + 4
|
||||
self.ActivityTranslate[ ACT_MP_ATTACK_STAND_PRIMARYFIRE ] = index + 5
|
||||
self.ActivityTranslate[ ACT_MP_ATTACK_CROUCH_PRIMARYFIRE ] = index + 5
|
||||
self.ActivityTranslate[ ACT_MP_RELOAD_STAND ] = index + 6
|
||||
self.ActivityTranslate[ ACT_MP_RELOAD_CROUCH ] = index + 6
|
||||
self.ActivityTranslate[ ACT_MP_JUMP ] = index + 7
|
||||
self.ActivityTranslate[ ACT_RANGE_ATTACK1 ] = index + 8
|
||||
self.ActivityTranslate[ ACT_MP_SWIM ] = index + 9
|
||||
|
||||
-- "normal" jump animation doesn't exist
|
||||
if ( t == "normal" ) then
|
||||
self.ActivityTranslate[ ACT_MP_JUMP ] = ACT_HL2MP_JUMP_SLAM
|
||||
end
|
||||
|
||||
self:SetupWeaponHoldTypeForAI( t )
|
||||
|
||||
end
|
||||
|
||||
-- Default hold pos is the pistol
|
||||
SWEP:SetWeaponHoldType( "pistol" )
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: weapon:TranslateActivity()
|
||||
Desc: Translate a player's Activity into a weapon's activity
|
||||
So for example, ACT_HL2MP_RUN becomes ACT_HL2MP_RUN_PISTOL
|
||||
Depending on how you want the player to be holding the weapon
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:TranslateActivity( act )
|
||||
|
||||
if ( self.Owner:IsNPC() ) then
|
||||
if ( self.ActivityTranslateAI[ act ] ) then
|
||||
return self.ActivityTranslateAI[ act ]
|
||||
end
|
||||
return -1
|
||||
end
|
||||
|
||||
if ( self.ActivityTranslate[ act ] != nil ) then
|
||||
return self.ActivityTranslate[ act ]
|
||||
end
|
||||
|
||||
return -1
|
||||
|
||||
end
|
||||
273
gamemodes/cod_custom/entities/weapons/weapon_base/shared.lua
Normal file
273
gamemodes/cod_custom/entities/weapons/weapon_base/shared.lua
Normal file
@@ -0,0 +1,273 @@
|
||||
|
||||
-- Variables that are used on both client and server
|
||||
|
||||
SWEP.PrintName = "Scripted Weapon" -- 'Nice' Weapon name (Shown on HUD)
|
||||
SWEP.Author = ""
|
||||
SWEP.Contact = ""
|
||||
SWEP.Purpose = ""
|
||||
SWEP.Instructions = ""
|
||||
|
||||
SWEP.ViewModelFOV = 62
|
||||
SWEP.ViewModelFlip = false
|
||||
SWEP.ViewModel = "models/weapons/v_pistol.mdl"
|
||||
SWEP.WorldModel = "models/weapons/w_357.mdl"
|
||||
|
||||
SWEP.Spawnable = false
|
||||
SWEP.AdminOnly = false
|
||||
|
||||
SWEP.Primary.ClipSize = 8 -- Size of a clip
|
||||
SWEP.Primary.DefaultClip = 32 -- Default number of bullets in a clip
|
||||
SWEP.Primary.Automatic = false -- Automatic/Semi Auto
|
||||
SWEP.Primary.Ammo = "Pistol"
|
||||
|
||||
SWEP.Secondary.ClipSize = 8 -- Size of a clip
|
||||
SWEP.Secondary.DefaultClip = 32 -- Default number of bullets in a clip
|
||||
SWEP.Secondary.Automatic = false -- Automatic/Semi Auto
|
||||
SWEP.Secondary.Ammo = "Pistol"
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: SWEP:Initialize()
|
||||
Desc: Called when the weapon is first loaded
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:Initialize()
|
||||
|
||||
self:SetHoldType( "pistol" )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: SWEP:PrimaryAttack()
|
||||
Desc: +attack1 has been pressed
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:PrimaryAttack()
|
||||
|
||||
-- Make sure we can shoot first
|
||||
if ( !self:CanPrimaryAttack() ) then return end
|
||||
|
||||
-- Play shoot sound
|
||||
self:EmitSound( "Weapon_AR2.Single" )
|
||||
|
||||
-- Shoot 9 bullets, 150 damage, 0.75 aimcone
|
||||
self:ShootBullet( 150, 1, 0.01, self.Primary.Ammo )
|
||||
|
||||
-- Remove 1 bullet from our clip
|
||||
self:TakePrimaryAmmo( 1 )
|
||||
|
||||
-- Punch the player's view
|
||||
if ( !self.Owner:IsNPC() ) then self.Owner:ViewPunch( Angle( -1, 0, 0 ) ) end
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: SWEP:SecondaryAttack()
|
||||
Desc: +attack2 has been pressed
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:SecondaryAttack()
|
||||
|
||||
-- Make sure we can shoot first
|
||||
if ( !self:CanSecondaryAttack() ) then return end
|
||||
|
||||
-- Play shoot sound
|
||||
self:EmitSound("Weapon_Shotgun.Single")
|
||||
|
||||
-- Shoot 9 bullets, 150 damage, 0.75 aimcone
|
||||
self:ShootBullet( 150, 9, 0.2, self.Secondary.Ammo )
|
||||
|
||||
-- Remove 1 bullet from our clip
|
||||
self:TakeSecondaryAmmo( 1 )
|
||||
|
||||
-- Punch the player's view
|
||||
if ( !self.Owner:IsNPC() ) then self.Owner:ViewPunch( Angle( -10, 0, 0 ) ) end
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: SWEP:Reload()
|
||||
Desc: Reload is being pressed
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:Reload()
|
||||
self:DefaultReload( ACT_VM_RELOAD )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: SWEP:Think()
|
||||
Desc: Called every frame
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:Think()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: SWEP:Holster( weapon_to_swap_to )
|
||||
Desc: Weapon wants to holster
|
||||
RetV: Return true to allow the weapon to holster
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:Holster( wep )
|
||||
return true
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: SWEP:Deploy()
|
||||
Desc: Whip it out
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:Deploy()
|
||||
return true
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: SWEP:ShootEffects()
|
||||
Desc: A convenience function to create shoot effects
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:ShootEffects()
|
||||
|
||||
self:SendWeaponAnim( ACT_VM_PRIMARYATTACK ) -- View model animation
|
||||
self.Owner:MuzzleFlash() -- Crappy muzzle light
|
||||
self.Owner:SetAnimation( PLAYER_ATTACK1 ) -- 3rd Person Animation
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: SWEP:ShootBullet()
|
||||
Desc: A convenience function to shoot bullets
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:ShootBullet( damage, num_bullets, aimcone, ammo_type, force, tracer )
|
||||
|
||||
local bullet = {}
|
||||
bullet.Num = num_bullets
|
||||
bullet.Src = self.Owner:GetShootPos() -- Source
|
||||
bullet.Dir = self.Owner:GetAimVector() -- Dir of bullet
|
||||
bullet.Spread = Vector( aimcone, aimcone, 0 ) -- Aim Cone
|
||||
bullet.Tracer = tracer || 5 -- Show a tracer on every x bullets
|
||||
bullet.Force = force || 1 -- Amount of force to give to phys objects
|
||||
bullet.Damage = damage
|
||||
bullet.AmmoType = ammo_type || self.Primary.Ammo
|
||||
|
||||
self.Owner:FireBullets( bullet )
|
||||
|
||||
self:ShootEffects()
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: SWEP:TakePrimaryAmmo()
|
||||
Desc: A convenience function to remove ammo
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:TakePrimaryAmmo( num )
|
||||
|
||||
-- Doesn't use clips
|
||||
if ( self:Clip1() <= 0 ) then
|
||||
|
||||
if ( self:Ammo1() <= 0 ) then return end
|
||||
|
||||
self.Owner:RemoveAmmo( num, self:GetPrimaryAmmoType() )
|
||||
|
||||
return end
|
||||
|
||||
self:SetClip1( self:Clip1() - num )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: SWEP:TakeSecondaryAmmo()
|
||||
Desc: A convenience function to remove ammo
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:TakeSecondaryAmmo( num )
|
||||
|
||||
-- Doesn't use clips
|
||||
if ( self:Clip2() <= 0 ) then
|
||||
|
||||
if ( self:Ammo2() <= 0 ) then return end
|
||||
|
||||
self.Owner:RemoveAmmo( num, self:GetSecondaryAmmoType() )
|
||||
|
||||
return end
|
||||
|
||||
self:SetClip2( self:Clip2() - num )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: SWEP:CanPrimaryAttack()
|
||||
Desc: Helper function for checking for no ammo
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:CanPrimaryAttack()
|
||||
|
||||
if ( self:Clip1() <= 0 ) then
|
||||
|
||||
self:EmitSound( "Weapon_Pistol.Empty" )
|
||||
self:SetNextPrimaryFire( CurTime() + 0.2 )
|
||||
self:Reload()
|
||||
return false
|
||||
|
||||
end
|
||||
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: SWEP:CanSecondaryAttack()
|
||||
Desc: Helper function for checking for no ammo
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:CanSecondaryAttack()
|
||||
|
||||
if ( self:Clip2() <= 0 ) then
|
||||
|
||||
self:EmitSound( "Weapon_Pistol.Empty" )
|
||||
self:SetNextSecondaryFire( CurTime() + 0.2 )
|
||||
return false
|
||||
|
||||
end
|
||||
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: OnRemove
|
||||
Desc: Called just before entity is deleted
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:OnRemove()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: OwnerChanged
|
||||
Desc: When weapon is dropped or picked up by a new player
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:OwnerChanged()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: Ammo1
|
||||
Desc: Returns how much of ammo1 the player has
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:Ammo1()
|
||||
return self.Owner:GetAmmoCount( self:GetPrimaryAmmoType() )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: Ammo2
|
||||
Desc: Returns how much of ammo2 the player has
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:Ammo2()
|
||||
return self.Owner:GetAmmoCount( self:GetSecondaryAmmoType() )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: SetDeploySpeed
|
||||
Desc: Sets the weapon deploy speed.
|
||||
This value needs to match on client and server.
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:SetDeploySpeed( speed )
|
||||
self.m_WeaponDeploySpeed = tonumber( speed )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: DoImpactEffect
|
||||
Desc: Callback so the weapon can override the impact effects it makes
|
||||
return true to not do the default thing - which is to call UTIL_ImpactTrace in c++
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:DoImpactEffect( tr, nDamageType )
|
||||
|
||||
return false
|
||||
|
||||
end
|
||||
@@ -0,0 +1,54 @@
|
||||
if (!file.Exists("autorun/vj_base_autorun.lua","LUA")) then return end
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.Base = "weapon_vj_base"
|
||||
SWEP.PrintName = "AK47"
|
||||
SWEP.Author = "DrVrej"
|
||||
SWEP.Contact = "http://steamcommunity.com/groups/vrejgaming"
|
||||
SWEP.Purpose = "This weapon is made for Players and NPCs"
|
||||
SWEP.Instructions = "Controls are like a regular weapon."
|
||||
SWEP.Category = "VJ Base"
|
||||
-- Client Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
if CLIENT then
|
||||
SWEP.Slot = 1 -- Which weapon slot you want your SWEP to be in? (1 2 3 4 5 6)
|
||||
SWEP.SlotPos = 1 -- Which part of that slot do you want the SWEP to be in? (1 2 3 4 5 6)
|
||||
SWEP.SwayScale = 2 -- Default is 1, The scale of the viewmodel sway
|
||||
end
|
||||
-- NPC Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.NPC_NextPrimaryFire = 0.12 -- Next time it can use primary fire
|
||||
SWEP.NPC_CustomSpread = 0.8 -- This is added on top of the custom spread that's set inside the SNPC! | Starting from 1: Closer to 0 = better accuracy, Farther than 1 = worse accuracy
|
||||
-- Main Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.HoldType = "ar2"
|
||||
SWEP.ViewModelFOV = 70 -- Player FOV for the view model
|
||||
SWEP.Spawnable = true
|
||||
SWEP.AdminSpawnable = false
|
||||
-- Primary Fire ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.Primary.AllowFireInWater = true -- If true, you will be able to use primary fire in water
|
||||
SWEP.Primary.Damage = 16 -- Damage
|
||||
SWEP.Primary.PlayerDamage = 16 -- Only applies for players | "Same" = Same as self.Primary.Damage, "Double" = Double the self.Primary.Damage OR put a number to be different from self.Primary.Damage
|
||||
SWEP.Primary.Force = 5 -- Force applied on the object the bullet hits
|
||||
SWEP.Primary.ClipSize = 30 -- Max amount of bullets per clip
|
||||
SWEP.Primary.Recoil = 0.3 -- How much recoil does the player get?
|
||||
SWEP.Primary.Cone = 5 -- How accurate is the bullet? (Players)
|
||||
SWEP.Primary.Delay = 0.01 -- Time until it can shoot again
|
||||
SWEP.Primary.Automatic = true -- Is it automatic?
|
||||
SWEP.Primary.Ammo = "AR2" -- Ammo type
|
||||
SWEP.Primary.Sound = {"viper/weapons/akilo47/weap_akilo47_fire_plr_01.ogg", "viper/weapons/akilo47/weap_akilo47_fire_plr_02.ogg", "viper/weapons/akilo47/weap_akilo47_fire_plr_03.ogg", "viper/weapons/akilo47/weap_akilo47_fire_plr_04.ogg", "viper/weapons/akilo47/weap_akilo47_fire_plr_05.ogg", "viper/weapons/akilo47/weap_akilo47_fire_plr_06.ogg"}
|
||||
SWEP.Primary.DistantSound = {"viper/weapons/akilo47/weap_akilo47_fire_plr_01.ogg", "viper/weapons/akilo47/weap_akilo47_fire_plr_02.ogg", "viper/weapons/akilo47/weap_akilo47_fire_plr_03.ogg", "viper/weapons/akilo47/weap_akilo47_fire_plr_04.ogg", "viper/weapons/akilo47/weap_akilo47_fire_plr_05.ogg", "viper/weapons/akilo47/weap_akilo47_fire_plr_06.ogg"}
|
||||
SWEP.PrimaryEffects_MuzzleAttachment = 1
|
||||
SWEP.PrimaryEffects_ShellAttachment = "ejectbrass"
|
||||
SWEP.PrimaryEffects_ShellType = "VJ_Weapon_PistolShell1"
|
||||
SWEP.MadeForNPCsOnly = true -- Is this weapon meant to be for NPCs only?
|
||||
-- Deployment Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.DelayOnDeploy = 0.4 -- Time until it can shoot again after deploying the weapon
|
||||
SWEP.AnimTbl_Deploy = {ACT_VM_IDLE_TO_LOWERED}
|
||||
-- Reload Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.HasReloadSound = true -- Does it have a reload sound? Remember even if this is set to false, the animation sound will still play!
|
||||
SWEP.ReloadSound = "vj_weapons/glock_17/reload.wav"
|
||||
SWEP.Reload_TimeUntilAmmoIsSet = 1.5 -- Time until ammo is set to the weapon
|
||||
SWEP.Reload_TimeUntilFinished = 2 -- How much time until the player can play idle animation, shoot, etc.
|
||||
|
||||
SWEP.WorldModel_UseCustomPosition = true -- Should the gun use custom position? This can be used to fix guns that are in the crotch
|
||||
SWEP.WorldModel_CustomPositionAngle = Vector(-8, -5, 180)
|
||||
SWEP.WorldModel_CustomPositionOrigin = Vector(0, 4, 1)
|
||||
|
||||
SWEP.WorldModel = "models/tdmg/invasion/w_akm.mdl"
|
||||
@@ -0,0 +1,54 @@
|
||||
if (!file.Exists("autorun/vj_base_autorun.lua","LUA")) then return end
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.Base = "weapon_vj_base"
|
||||
SWEP.PrintName = "M14"
|
||||
SWEP.Author = "DrVrej"
|
||||
SWEP.Contact = "http://steamcommunity.com/groups/vrejgaming"
|
||||
SWEP.Purpose = "This weapon is made for Players and NPCs"
|
||||
SWEP.Instructions = "Controls are like a regular weapon."
|
||||
SWEP.Category = "VJ Base"
|
||||
-- Client Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
if CLIENT then
|
||||
SWEP.Slot = 1 -- Which weapon slot you want your SWEP to be in? (1 2 3 4 5 6)
|
||||
SWEP.SlotPos = 1 -- Which part of that slot do you want the SWEP to be in? (1 2 3 4 5 6)
|
||||
SWEP.SwayScale = 2 -- Default is 1, The scale of the viewmodel sway
|
||||
end
|
||||
-- NPC Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.NPC_NextPrimaryFire = 0.3 -- Next time it can use primary fire
|
||||
SWEP.NPC_CustomSpread = 0.3 -- This is added on top of the custom spread that's set inside the SNPC! | Starting from 1: Closer to 0 = better accuracy, Farther than 1 = worse accuracy
|
||||
-- Main Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.HoldType = "ar2"
|
||||
SWEP.ViewModelFOV = 70 -- Player FOV for the view model
|
||||
SWEP.Spawnable = true
|
||||
SWEP.AdminSpawnable = false
|
||||
-- Primary Fire ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.Primary.AllowFireInWater = true -- If true, you will be able to use primary fire in water
|
||||
SWEP.Primary.Damage = 25 -- Damage
|
||||
SWEP.Primary.PlayerDamage = 25 -- Only applies for players | "Same" = Same as self.Primary.Damage, "Double" = Double the self.Primary.Damage OR put a number to be different from self.Primary.Damage
|
||||
SWEP.Primary.Force = 5 -- Force applied on the object the bullet hits
|
||||
SWEP.Primary.ClipSize = 30 -- Max amount of bullets per clip
|
||||
SWEP.Primary.Recoil = 0.3 -- How much recoil does the player get?
|
||||
SWEP.Primary.Cone = 5 -- How accurate is the bullet? (Players)
|
||||
SWEP.Primary.Delay = 0.01 -- Time until it can shoot again
|
||||
SWEP.Primary.Automatic = true -- Is it automatic?
|
||||
SWEP.Primary.Ammo = "AR2" -- Ammo type
|
||||
SWEP.Primary.Sound = {"viper/weapons/mike14/weap_mike14_fire_plr_01.ogg"}
|
||||
SWEP.Primary.DistantSound = {"viper/weapons/mike14/weap_mike14_fire_plr_01.ogg"}
|
||||
SWEP.PrimaryEffects_MuzzleAttachment = 1
|
||||
SWEP.PrimaryEffects_ShellAttachment = "ejectbrass"
|
||||
SWEP.PrimaryEffects_ShellType = "VJ_Weapon_PistolShell1"
|
||||
SWEP.MadeForNPCsOnly = true -- Is this weapon meant to be for NPCs only?
|
||||
-- Deployment Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.DelayOnDeploy = 0.4 -- Time until it can shoot again after deploying the weapon
|
||||
SWEP.AnimTbl_Deploy = {ACT_VM_IDLE_TO_LOWERED}
|
||||
-- Reload Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.HasReloadSound = true -- Does it have a reload sound? Remember even if this is set to false, the animation sound will still play!
|
||||
SWEP.ReloadSound = "vj_weapons/glock_17/reload.wav"
|
||||
SWEP.Reload_TimeUntilAmmoIsSet = 1.5 -- Time until ammo is set to the weapon
|
||||
SWEP.Reload_TimeUntilFinished = 2 -- How much time until the player can play idle animation, shoot, etc.
|
||||
|
||||
SWEP.WorldModel_UseCustomPosition = true -- Should the gun use custom position? This can be used to fix guns that are in the crotch
|
||||
SWEP.WorldModel_CustomPositionAngle = Vector(-8, -5, 180)
|
||||
SWEP.WorldModel_CustomPositionOrigin = Vector(0, 2, 0)
|
||||
|
||||
SWEP.WorldModel = "models/tdmg/invasion/w_mini14.mdl"
|
||||
@@ -0,0 +1,57 @@
|
||||
if (!file.Exists("autorun/vj_base_autorun.lua","LUA")) then return end
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.Base = "weapon_vj_base"
|
||||
SWEP.PrintName = "M24"
|
||||
SWEP.Author = "DrVrej"
|
||||
SWEP.Contact = "http://steamcommunity.com/groups/vrejgaming"
|
||||
SWEP.Purpose = "This weapon is made for Players and NPCs"
|
||||
SWEP.Instructions = "Controls are like a regular weapon."
|
||||
SWEP.Category = "VJ Base"
|
||||
-- Client Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
if CLIENT then
|
||||
SWEP.Slot = 1 -- Which weapon slot you want your SWEP to be in? (1 2 3 4 5 6)
|
||||
SWEP.SlotPos = 1 -- Which part of that slot do you want the SWEP to be in? (1 2 3 4 5 6)
|
||||
SWEP.SwayScale = 2 -- Default is 1, The scale of the viewmodel sway
|
||||
end
|
||||
-- NPC Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.NPC_NextPrimaryFire = 1.5 -- Next time it can use primary fire
|
||||
SWEP.NPC_CustomSpread = 0.1 -- This is added on top of the custom spread that's set inside the SNPC! | Starting from 1: Closer to 0 = better accuracy, Farther than 1 = worse accuracy
|
||||
-- Main Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.HoldType = "rpg"
|
||||
SWEP.ViewModelFOV = 70 -- Player FOV for the view model
|
||||
SWEP.Spawnable = true
|
||||
SWEP.AdminSpawnable = false
|
||||
-- Primary Fire ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.Primary.AllowFireInWater = true -- If true, you will be able to use primary fire in water
|
||||
SWEP.Primary.Damage = 50 -- Damage
|
||||
SWEP.Primary.PlayerDamage = 50 -- Only applies for players | "Same" = Same as self.Primary.Damage, "Double" = Double the self.Primary.Damage OR put a number to be different from self.Primary.Damage
|
||||
SWEP.Primary.Force = 5 -- Force applied on the object the bullet hits
|
||||
SWEP.Primary.ClipSize = 5 -- Max amount of bullets per clip
|
||||
SWEP.Primary.Recoil = 0.3 -- How much recoil does the player get?
|
||||
SWEP.Primary.Cone = 5 -- How accurate is the bullet? (Players)
|
||||
SWEP.Primary.Delay = 0.01 -- Time until it can shoot again
|
||||
SWEP.Primary.Automatic = true -- Is it automatic?
|
||||
SWEP.Primary.Ammo = "AR2" -- Ammo type
|
||||
SWEP.Primary.Sound = {"weapons/romeo700/weap_romeo700_fire_bang_plr_01.ogg"}
|
||||
SWEP.Primary.DistantSound = {"weapons/romeo700/weap_romeo700_fire_bang_plr_01.ogg"}
|
||||
SWEP.PrimaryEffects_MuzzleAttachment = 1
|
||||
SWEP.PrimaryEffects_ShellAttachment = "ejectbrass"
|
||||
SWEP.PrimaryEffects_ShellType = "VJ_Weapon_PistolShell1"
|
||||
SWEP.MadeForNPCsOnly = true -- Is this weapon meant to be for NPCs only?
|
||||
-- Deployment Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.DelayOnDeploy = 0.4 -- Time until it can shoot again after deploying the weapon
|
||||
SWEP.AnimTbl_Deploy = {ACT_VM_IDLE_TO_LOWERED}
|
||||
-- Reload Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.HasReloadSound = true -- Does it have a reload sound? Remember even if this is set to false, the animation sound will still play!
|
||||
SWEP.ReloadSound = "vj_weapons/reload_boltaction.wav"
|
||||
SWEP.Reload_TimeUntilAmmoIsSet = 1.5 -- Time until ammo is set to the weapon
|
||||
SWEP.Reload_TimeUntilFinished = 2 -- How much time until the player can play idle animation, shoot, etc.
|
||||
|
||||
SWEP.NPC_ExtraFireSound = {"vj_weapons/perform_boltaction.wav"} -- Plays an extra sound after it fires (Example: Bolt action sound)
|
||||
SWEP.NPC_ExtraFireSoundTime = 0.4 -- How much time until it plays the sound (After Firing)?
|
||||
|
||||
SWEP.WorldModel_UseCustomPosition = true -- Should the gun use custom position? This can be used to fix guns that are in the crotch
|
||||
SWEP.WorldModel_CustomPositionAngle = Vector(-8, -5, 180)
|
||||
SWEP.WorldModel_CustomPositionOrigin = Vector(0, 4, 1)
|
||||
|
||||
SWEP.WorldModel = "models/tdmg/invasion/w_m40.mdl"
|
||||
@@ -0,0 +1,54 @@
|
||||
if (!file.Exists("autorun/vj_base_autorun.lua","LUA")) then return end
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.Base = "weapon_vj_base"
|
||||
SWEP.PrintName = "M249"
|
||||
SWEP.Author = "DrVrej"
|
||||
SWEP.Contact = "http://steamcommunity.com/groups/vrejgaming"
|
||||
SWEP.Purpose = "This weapon is made for Players and NPCs"
|
||||
SWEP.Instructions = "Controls are like a regular weapon."
|
||||
SWEP.Category = "VJ Base"
|
||||
-- Client Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
if CLIENT then
|
||||
SWEP.Slot = 1 -- Which weapon slot you want your SWEP to be in? (1 2 3 4 5 6)
|
||||
SWEP.SlotPos = 1 -- Which part of that slot do you want the SWEP to be in? (1 2 3 4 5 6)
|
||||
SWEP.SwayScale = 2 -- Default is 1, The scale of the viewmodel sway
|
||||
end
|
||||
-- NPC Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.NPC_NextPrimaryFire = 0.1 -- Next time it can use primary fire
|
||||
SWEP.NPC_CustomSpread = 1 -- This is added on top of the custom spread that's set inside the SNPC! | Starting from 1: Closer to 0 = better accuracy, Farther than 1 = worse accuracy
|
||||
-- Main Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.HoldType = "ar2"
|
||||
SWEP.ViewModelFOV = 70 -- Player FOV for the view model
|
||||
SWEP.Spawnable = true
|
||||
SWEP.AdminSpawnable = false
|
||||
-- Primary Fire ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.Primary.AllowFireInWater = true -- If true, you will be able to use primary fire in water
|
||||
SWEP.Primary.Damage = 10 -- Damage
|
||||
SWEP.Primary.PlayerDamage = 10 -- Only applies for players | "Same" = Same as self.Primary.Damage, "Double" = Double the self.Primary.Damage OR put a number to be different from self.Primary.Damage
|
||||
SWEP.Primary.Force = 5 -- Force applied on the object the bullet hits
|
||||
SWEP.Primary.ClipSize = 100 -- Max amount of bullets per clip
|
||||
SWEP.Primary.Recoil = 0.3 -- How much recoil does the player get?
|
||||
SWEP.Primary.Cone = 5 -- How accurate is the bullet? (Players)
|
||||
SWEP.Primary.Delay = 0.01 -- Time until it can shoot again
|
||||
SWEP.Primary.Automatic = true -- Is it automatic?
|
||||
SWEP.Primary.Ammo = "AR2" -- Ammo type
|
||||
SWEP.Primary.Sound = {"viper/weapons/scharlie/weap_scharlie_fire_plr_02.ogg"}
|
||||
SWEP.Primary.DistantSound = {"viper/weapons/scharlie/weap_scharlie_fire_plr_02.ogg"}
|
||||
SWEP.PrimaryEffects_MuzzleAttachment = 1
|
||||
SWEP.PrimaryEffects_ShellAttachment = "ejectbrass"
|
||||
SWEP.PrimaryEffects_ShellType = "VJ_Weapon_PistolShell1"
|
||||
SWEP.MadeForNPCsOnly = true -- Is this weapon meant to be for NPCs only?
|
||||
-- Deployment Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.DelayOnDeploy = 0.4 -- Time until it can shoot again after deploying the weapon
|
||||
SWEP.AnimTbl_Deploy = {ACT_VM_IDLE_TO_LOWERED}
|
||||
-- Reload Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.HasReloadSound = true -- Does it have a reload sound? Remember even if this is set to false, the animation sound will still play!
|
||||
SWEP.ReloadSound = "vj_weapons/glock_17/reload.wav"
|
||||
SWEP.Reload_TimeUntilAmmoIsSet = 1.5 -- Time until ammo is set to the weapon
|
||||
SWEP.Reload_TimeUntilFinished = 2 -- How much time until the player can play idle animation, shoot, etc.
|
||||
|
||||
SWEP.WorldModel_UseCustomPosition = true -- Should the gun use custom position? This can be used to fix guns that are in the crotch
|
||||
SWEP.WorldModel_CustomPositionAngle = Vector(-8, -5, 180)
|
||||
SWEP.WorldModel_CustomPositionOrigin = Vector(0, 4, 1)
|
||||
|
||||
SWEP.WorldModel = "models/tdmg/invasion/w_m249.mdl"
|
||||
@@ -0,0 +1,54 @@
|
||||
if (!file.Exists("autorun/vj_base_autorun.lua","LUA")) then return end
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.Base = "weapon_vj_base"
|
||||
SWEP.PrintName = "M4A1"
|
||||
SWEP.Author = "DrVrej"
|
||||
SWEP.Contact = "http://steamcommunity.com/groups/vrejgaming"
|
||||
SWEP.Purpose = "This weapon is made for Players and NPCs"
|
||||
SWEP.Instructions = "Controls are like a regular weapon."
|
||||
SWEP.Category = "VJ Base"
|
||||
-- Client Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
if CLIENT then
|
||||
SWEP.Slot = 1 -- Which weapon slot you want your SWEP to be in? (1 2 3 4 5 6)
|
||||
SWEP.SlotPos = 1 -- Which part of that slot do you want the SWEP to be in? (1 2 3 4 5 6)
|
||||
SWEP.SwayScale = 2 -- Default is 1, The scale of the viewmodel sway
|
||||
end
|
||||
-- NPC Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.NPC_NextPrimaryFire = 0.12 -- Next time it can use primary fire
|
||||
SWEP.NPC_CustomSpread = 0.8 -- This is added on top of the custom spread that's set inside the SNPC! | Starting from 1: Closer to 0 = better accuracy, Farther than 1 = worse accuracy
|
||||
-- Main Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.HoldType = "ar2"
|
||||
SWEP.ViewModelFOV = 70 -- Player FOV for the view model
|
||||
SWEP.Spawnable = true
|
||||
SWEP.AdminSpawnable = false
|
||||
-- Primary Fire ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.Primary.AllowFireInWater = true -- If true, you will be able to use primary fire in water
|
||||
SWEP.Primary.Damage = 16 -- Damage
|
||||
SWEP.Primary.PlayerDamage = 16 -- Only applies for players | "Same" = Same as self.Primary.Damage, "Double" = Double the self.Primary.Damage OR put a number to be different from self.Primary.Damage
|
||||
SWEP.Primary.Force = 5 -- Force applied on the object the bullet hits
|
||||
SWEP.Primary.ClipSize = 30 -- Max amount of bullets per clip
|
||||
SWEP.Primary.Recoil = 0.3 -- How much recoil does the player get?
|
||||
SWEP.Primary.Cone = 5 -- How accurate is the bullet? (Players)
|
||||
SWEP.Primary.Delay = 0.01 -- Time until it can shoot again
|
||||
SWEP.Primary.Automatic = true -- Is it automatic?
|
||||
SWEP.Primary.Ammo = "AR2" -- Ammo type
|
||||
SWEP.Primary.Sound = {"viper/weapons/mike4/weap_mike4_fire_plr_01.ogg", "viper/weapons/mike4/weap_mike4_fire_plr_02.ogg", "viper/weapons/mike4/weap_mike4_fire_plr_03.ogg", "viper/weapons/mike4/weap_mike4_fire_plr_04.ogg", "viper/weapons/mike4/weap_mike4_fire_plr_05.ogg", "viper/weapons/mike4/weap_mike4_fire_plr_06.ogg"}
|
||||
SWEP.Primary.DistantSound = {"viper/weapons/mike4/weap_mike4_fire_plr_01.ogg", "viper/weapons/mike4/weap_mike4_fire_plr_02.ogg", "viper/weapons/mike4/weap_mike4_fire_plr_03.ogg", "viper/weapons/mike4/weap_mike4_fire_plr_04.ogg", "viper/weapons/mike4/weap_mike4_fire_plr_05.ogg", "viper/weapons/mike4/weap_mike4_fire_plr_06.ogg"}
|
||||
SWEP.PrimaryEffects_MuzzleAttachment = 1
|
||||
SWEP.PrimaryEffects_ShellAttachment = "ejectbrass"
|
||||
SWEP.PrimaryEffects_ShellType = "VJ_Weapon_PistolShell1"
|
||||
SWEP.MadeForNPCsOnly = true -- Is this weapon meant to be for NPCs only?
|
||||
-- Deployment Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.DelayOnDeploy = 0.4 -- Time until it can shoot again after deploying the weapon
|
||||
SWEP.AnimTbl_Deploy = {ACT_VM_IDLE_TO_LOWERED}
|
||||
-- Reload Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.HasReloadSound = true -- Does it have a reload sound? Remember even if this is set to false, the animation sound will still play!
|
||||
SWEP.ReloadSound = "vj_weapons/glock_17/reload.wav"
|
||||
SWEP.Reload_TimeUntilAmmoIsSet = 1.5 -- Time until ammo is set to the weapon
|
||||
SWEP.Reload_TimeUntilFinished = 2 -- How much time until the player can play idle animation, shoot, etc.
|
||||
|
||||
SWEP.WorldModel_UseCustomPosition = true -- Should the gun use custom position? This can be used to fix guns that are in the crotch
|
||||
SWEP.WorldModel_CustomPositionAngle = Vector(-8, -5, 180)
|
||||
SWEP.WorldModel_CustomPositionOrigin = Vector(0, 4, 1)
|
||||
|
||||
SWEP.WorldModel = "models/tdmg/invasion/w_m16.mdl"
|
||||
@@ -0,0 +1,54 @@
|
||||
if (!file.Exists("autorun/vj_base_autorun.lua","LUA")) then return end
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.Base = "weapon_vj_base"
|
||||
SWEP.PrintName = "M9"
|
||||
SWEP.Author = "DrVrej"
|
||||
SWEP.Contact = "http://steamcommunity.com/groups/vrejgaming"
|
||||
SWEP.Purpose = "This weapon is made for Players and NPCs"
|
||||
SWEP.Instructions = "Controls are like a regular weapon."
|
||||
SWEP.Category = "VJ Base"
|
||||
-- Client Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
if CLIENT then
|
||||
SWEP.Slot = 1 -- Which weapon slot you want your SWEP to be in? (1 2 3 4 5 6)
|
||||
SWEP.SlotPos = 1 -- Which part of that slot do you want the SWEP to be in? (1 2 3 4 5 6)
|
||||
SWEP.SwayScale = 2 -- Default is 1, The scale of the viewmodel sway
|
||||
end
|
||||
-- NPC Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.NPC_NextPrimaryFire = 0.18 -- Next time it can use primary fire
|
||||
SWEP.NPC_CustomSpread = 0.5 -- This is added on top of the custom spread that's set inside the SNPC! | Starting from 1: Closer to 0 = better accuracy, Farther than 1 = worse accuracy
|
||||
-- Main Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.HoldType = "revolver"
|
||||
SWEP.ViewModelFOV = 70 -- Player FOV for the view model
|
||||
SWEP.Spawnable = true
|
||||
SWEP.AdminSpawnable = false
|
||||
-- Primary Fire ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.Primary.AllowFireInWater = true -- If true, you will be able to use primary fire in water
|
||||
SWEP.Primary.Damage = 9 -- Damage
|
||||
SWEP.Primary.PlayerDamage = 9 -- Only applies for players | "Same" = Same as self.Primary.Damage, "Double" = Double the self.Primary.Damage OR put a number to be different from self.Primary.Damage
|
||||
SWEP.Primary.Force = 5 -- Force applied on the object the bullet hits
|
||||
SWEP.Primary.ClipSize = 15 -- Max amount of bullets per clip
|
||||
SWEP.Primary.Recoil = 0.3 -- How much recoil does the player get?
|
||||
SWEP.Primary.Cone = 5 -- How accurate is the bullet? (Players)
|
||||
SWEP.Primary.Delay = 0.01 -- Time until it can shoot again
|
||||
SWEP.Primary.Automatic = true -- Is it automatic?
|
||||
SWEP.Primary.Ammo = "AR2" -- Ammo type
|
||||
SWEP.Primary.Sound = {"weapons/mike9/weap_mike9a3_fire_plr_01.ogg"}
|
||||
SWEP.Primary.DistantSound = {"weapons/mike9/weap_mike9a3_fire_plr_01.ogg"}
|
||||
SWEP.PrimaryEffects_MuzzleAttachment = 1
|
||||
SWEP.PrimaryEffects_ShellAttachment = "ejectbrass"
|
||||
SWEP.PrimaryEffects_ShellType = "VJ_Weapon_PistolShell1"
|
||||
SWEP.MadeForNPCsOnly = true -- Is this weapon meant to be for NPCs only?
|
||||
-- Deployment Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.DelayOnDeploy = 0.4 -- Time until it can shoot again after deploying the weapon
|
||||
SWEP.AnimTbl_Deploy = {ACT_VM_IDLE_TO_LOWERED}
|
||||
-- Reload Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.HasReloadSound = true -- Does it have a reload sound? Remember even if this is set to false, the animation sound will still play!
|
||||
SWEP.ReloadSound = "vj_weapons/glock_17/reload.wav"
|
||||
SWEP.Reload_TimeUntilAmmoIsSet = 1.5 -- Time until ammo is set to the weapon
|
||||
SWEP.Reload_TimeUntilFinished = 2 -- How much time until the player can play idle animation, shoot, etc.
|
||||
|
||||
SWEP.WorldModel_UseCustomPosition = true -- Should the gun use custom position? This can be used to fix guns that are in the crotch
|
||||
SWEP.WorldModel_CustomPositionAngle = Vector(-8, -5, 180)
|
||||
SWEP.WorldModel_CustomPositionOrigin = Vector(0, 0, -1.5)
|
||||
|
||||
SWEP.WorldModel = "models/tdmg/wep/m18.mdl"
|
||||
@@ -0,0 +1,54 @@
|
||||
if (!file.Exists("autorun/vj_base_autorun.lua","LUA")) then return end
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.Base = "weapon_vj_base"
|
||||
SWEP.PrintName = "Makarov"
|
||||
SWEP.Author = "DrVrej"
|
||||
SWEP.Contact = "http://steamcommunity.com/groups/vrejgaming"
|
||||
SWEP.Purpose = "This weapon is made for Players and NPCs"
|
||||
SWEP.Instructions = "Controls are like a regular weapon."
|
||||
SWEP.Category = "VJ Base"
|
||||
-- Client Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
if CLIENT then
|
||||
SWEP.Slot = 1 -- Which weapon slot you want your SWEP to be in? (1 2 3 4 5 6)
|
||||
SWEP.SlotPos = 1 -- Which part of that slot do you want the SWEP to be in? (1 2 3 4 5 6)
|
||||
SWEP.SwayScale = 2 -- Default is 1, The scale of the viewmodel sway
|
||||
end
|
||||
-- NPC Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.NPC_NextPrimaryFire = 0.2 -- Next time it can use primary fire
|
||||
SWEP.NPC_CustomSpread = 0.5 -- This is added on top of the custom spread that's set inside the SNPC! | Starting from 1: Closer to 0 = better accuracy, Farther than 1 = worse accuracy
|
||||
-- Main Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.HoldType = "revolver"
|
||||
SWEP.ViewModelFOV = 70 -- Player FOV for the view model
|
||||
SWEP.Spawnable = true
|
||||
SWEP.AdminSpawnable = false
|
||||
-- Primary Fire ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.Primary.AllowFireInWater = true -- If true, you will be able to use primary fire in water
|
||||
SWEP.Primary.Damage = 14 -- Damage
|
||||
SWEP.Primary.PlayerDamage = 14 -- Only applies for players | "Same" = Same as self.Primary.Damage, "Double" = Double the self.Primary.Damage OR put a number to be different from self.Primary.Damage
|
||||
SWEP.Primary.Force = 5 -- Force applied on the object the bullet hits
|
||||
SWEP.Primary.ClipSize = 8 -- Max amount of bullets per clip
|
||||
SWEP.Primary.Recoil = 0.3 -- How much recoil does the player get?
|
||||
SWEP.Primary.Cone = 5 -- How accurate is the bullet? (Players)
|
||||
SWEP.Primary.Delay = 0.01 -- Time until it can shoot again
|
||||
SWEP.Primary.Automatic = true -- Is it automatic?
|
||||
SWEP.Primary.Ammo = "AR2" -- Ammo type
|
||||
SWEP.Primary.Sound = {"weapons/mike/weap_mike_fire_plr.ogg"}
|
||||
SWEP.Primary.DistantSound = {"weapons/mike/weap_mike_fire_plr.ogg"}
|
||||
SWEP.PrimaryEffects_MuzzleAttachment = 1
|
||||
SWEP.PrimaryEffects_ShellAttachment = "ejectbrass"
|
||||
SWEP.PrimaryEffects_ShellType = "VJ_Weapon_PistolShell1"
|
||||
SWEP.MadeForNPCsOnly = true -- Is this weapon meant to be for NPCs only?
|
||||
-- Deployment Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.DelayOnDeploy = 0.4 -- Time until it can shoot again after deploying the weapon
|
||||
SWEP.AnimTbl_Deploy = {ACT_VM_IDLE_TO_LOWERED}
|
||||
-- Reload Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.HasReloadSound = true -- Does it have a reload sound? Remember even if this is set to false, the animation sound will still play!
|
||||
SWEP.ReloadSound = "vj_weapons/glock_17/reload.wav"
|
||||
SWEP.Reload_TimeUntilAmmoIsSet = 1.5 -- Time until ammo is set to the weapon
|
||||
SWEP.Reload_TimeUntilFinished = 2 -- How much time until the player can play idle animation, shoot, etc.
|
||||
|
||||
SWEP.WorldModel_UseCustomPosition = true -- Should the gun use custom position? This can be used to fix guns that are in the crotch
|
||||
SWEP.WorldModel_CustomPositionAngle = Vector(-8, -5, 180)
|
||||
SWEP.WorldModel_CustomPositionOrigin = Vector(0, 4, 1)
|
||||
|
||||
SWEP.WorldModel = "models/tdmg/invasion/w_makarov.mdl"
|
||||
@@ -0,0 +1,58 @@
|
||||
if (!file.Exists("autorun/vj_base_autorun.lua","LUA")) then return end
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.Base = "weapon_vj_base"
|
||||
SWEP.PrintName = "R870"
|
||||
SWEP.Author = "DrVrej"
|
||||
SWEP.Contact = "http://steamcommunity.com/groups/vrejgaming"
|
||||
SWEP.Purpose = "This weapon is made for Players and NPCs"
|
||||
SWEP.Instructions = "Controls are like a regular weapon."
|
||||
SWEP.Category = "VJ Base"
|
||||
-- Client Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
if CLIENT then
|
||||
SWEP.Slot = 1 -- Which weapon slot you want your SWEP to be in? (1 2 3 4 5 6)
|
||||
SWEP.SlotPos = 1 -- Which part of that slot do you want the SWEP to be in? (1 2 3 4 5 6)
|
||||
SWEP.SwayScale = 2 -- Default is 1, The scale of the viewmodel sway
|
||||
end
|
||||
-- NPC Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.NPC_NextPrimaryFire = 1 -- Next time it can use primary fire
|
||||
SWEP.NPC_CustomSpread = 2 -- This is added on top of the custom spread that's set inside the SNPC! | Starting from 1: Closer to 0 = better accuracy, Farther than 1 = worse accuracy
|
||||
-- Main Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.HoldType = "ar2"
|
||||
SWEP.ViewModelFOV = 70 -- Player FOV for the view model
|
||||
SWEP.Spawnable = true
|
||||
SWEP.AdminSpawnable = false
|
||||
-- Primary Fire ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.Primary.AllowFireInWater = true -- If true, you will be able to use primary fire in water
|
||||
SWEP.Primary.Damage = 18 -- Damage
|
||||
SWEP.Primary.PlayerDamage = 18 -- Only applies for players | "Same" = Same as self.Primary.Damage, "Double" = Double the self.Primary.Damage OR put a number to be different from self.Primary.Damage
|
||||
SWEP.Primary.Force = 5 -- Force applied on the object the bullet hits
|
||||
SWEP.Primary.ClipSize = 6 -- Max amount of bullets per clip
|
||||
SWEP.Primary.Recoil = 0.3 -- How much recoil does the player get?
|
||||
SWEP.Primary.Cone = 5 -- How accurate is the bullet? (Players)
|
||||
SWEP.Primary.Delay = 0.01 -- Time until it can shoot again
|
||||
SWEP.Primary.Automatic = true -- Is it automatic?
|
||||
SWEP.Primary.NumberOfShots = 6
|
||||
SWEP.Primary.Ammo = "AR2" -- Ammo type
|
||||
SWEP.Primary.Sound = {"weapons/romeo870/weap_romeo870_fire_plr_01.ogg"}
|
||||
SWEP.Primary.DistantSound = {"weapons/romeo870/weap_romeo870_fire_plr_01.ogg"}
|
||||
SWEP.PrimaryEffects_MuzzleAttachment = 1
|
||||
SWEP.PrimaryEffects_ShellAttachment = "ejectbrass"
|
||||
SWEP.PrimaryEffects_ShellType = "VJ_Weapon_PistolShell1"
|
||||
SWEP.MadeForNPCsOnly = true -- Is this weapon meant to be for NPCs only?
|
||||
-- Deployment Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.DelayOnDeploy = 0.4 -- Time until it can shoot again after deploying the weapon
|
||||
SWEP.AnimTbl_Deploy = {ACT_VM_IDLE_TO_LOWERED}
|
||||
-- Reload Settings ---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
SWEP.HasReloadSound = true -- Does it have a reload sound? Remember even if this is set to false, the animation sound will still play!
|
||||
SWEP.ReloadSound = "vj_weapons/glock_17/reload.wav"
|
||||
SWEP.Reload_TimeUntilAmmoIsSet = 1.5 -- Time until ammo is set to the weapon
|
||||
SWEP.Reload_TimeUntilFinished = 2 -- How much time until the player can play idle animation, shoot, etc.
|
||||
|
||||
SWEP.NPC_ExtraFireSound = {"vj_weapons/perform_shotgunpump.wav"} -- Plays an extra sound after it fires (Example: Bolt action sound)
|
||||
SWEP.NPC_FiringDistanceScale = 0.5 -- Changes how far the NPC can fire | 1 = No change, x < 1 = closer, x > 1 = farther
|
||||
|
||||
SWEP.WorldModel_UseCustomPosition = true -- Should the gun use custom position? This can be used to fix guns that are in the crotch
|
||||
SWEP.WorldModel_CustomPositionAngle = Vector(-8, -5, 180)
|
||||
SWEP.WorldModel_CustomPositionOrigin = Vector(0, 4, 1)
|
||||
|
||||
SWEP.WorldModel = "models/tdmg/invasion/w_m590.mdl"
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user