Залив
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