mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-16 21:33:46 +03:00
Upload
This commit is contained in:
5
gamemodes/base/base.txt
Normal file
5
gamemodes/base/base.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
"base"
|
||||
{
|
||||
"title" "Base"
|
||||
"base" ""
|
||||
}
|
||||
49
gamemodes/base/entities/effects/base.lua
Normal file
49
gamemodes/base/entities/effects/base.lua
Normal file
@@ -0,0 +1,49 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
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
|
||||
65
gamemodes/base/entities/effects/dof_node.lua
Normal file
65
gamemodes/base/entities/effects/dof_node.lua
Normal file
@@ -0,0 +1,65 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
EFFECT.Mat = Material( "pp/dof" )
|
||||
|
||||
function EFFECT:Init( data )
|
||||
|
||||
table.insert( DOF_Ents, self )
|
||||
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
|
||||
68
gamemodes/base/entities/effects/tooltracer.lua
Normal file
68
gamemodes/base/entities/effects/tooltracer.lua
Normal file
@@ -0,0 +1,68 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
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
|
||||
20
gamemodes/base/entities/entities/aoc_spawnpoint.lua
Normal file
20
gamemodes/base/entities/entities/aoc_spawnpoint.lua
Normal file
@@ -0,0 +1,20 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
-- 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"
|
||||
33
gamemodes/base/entities/entities/base_ai/cl_init.lua
Normal file
33
gamemodes/base/entities/entities/base_ai/cl_init.lua
Normal file
@@ -0,0 +1,33 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
include( "shared.lua" )
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
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
|
||||
147
gamemodes/base/entities/entities/base_ai/init.lua
Normal file
147
gamemodes/base/entities/entities/base_ai/init.lua
Normal file
@@ -0,0 +1,147 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
AddCSLuaFile( "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 to update which sounds the NPC should be able to hear
|
||||
function ENT:GetSoundInterests()
|
||||
-- Hear thumper sound hints
|
||||
-- return 256
|
||||
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
|
||||
216
gamemodes/base/entities/entities/base_ai/schedules.lua
Normal file
216
gamemodes/base/entities/entities/base_ai/schedules.lua
Normal file
@@ -0,0 +1,216 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
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 )
|
||||
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 )
|
||||
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
|
||||
|
||||
function ENT:TranslateActivity( act )
|
||||
|
||||
-- Return a value to translate the activity to a new one
|
||||
-- if ( act == ACT_WALK ) then return ACT_RUN end
|
||||
|
||||
end
|
||||
54
gamemodes/base/entities/entities/base_ai/shared.lua
Normal file
54
gamemodes/base/entities/entities/base_ai/shared.lua
Normal file
@@ -0,0 +1,54 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
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
|
||||
90
gamemodes/base/entities/entities/base_ai/tasks.lua
Normal file
90
gamemodes/base/entities/entities/base_ai/tasks.lua
Normal file
@@ -0,0 +1,90 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
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 )
|
||||
|
||||
for k, v in ipairs( ents.FindInSphere( self:GetPos(), data.Radius or 512 ) ) 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
|
||||
114
gamemodes/base/entities/entities/base_anim.lua
Normal file
114
gamemodes/base/entities/entities/base_anim.lua
Normal file
@@ -0,0 +1,114 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
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
|
||||
66
gamemodes/base/entities/entities/base_brush.lua
Normal file
66
gamemodes/base/entities/entities/base_brush.lua
Normal file
@@ -0,0 +1,66 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
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
|
||||
34
gamemodes/base/entities/entities/base_entity/cl_init.lua
Normal file
34
gamemodes/base/entities/entities/base_entity/cl_init.lua
Normal file
@@ -0,0 +1,34 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
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
|
||||
87
gamemodes/base/entities/entities/base_entity/init.lua
Normal file
87
gamemodes/base/entities/entities/base_entity/init.lua
Normal file
@@ -0,0 +1,87 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
AddCSLuaFile( "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
|
||||
133
gamemodes/base/entities/entities/base_entity/outputs.lua
Normal file
133
gamemodes/base/entities/entities/base_entity/outputs.lua
Normal file
@@ -0,0 +1,133 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
-- 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
|
||||
|
||||
-- This works like SetNetworkKeyValue, call it from ENT:KeyValue and it'll
|
||||
-- return true if it successfully added an output from the passed KV pair.
|
||||
function ENT:AddOutputFromKeyValue( key, value )
|
||||
|
||||
if ( key:sub( 1, 2 ) == "On" ) then
|
||||
|
||||
self:StoreOutput( key, value )
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
return false
|
||||
|
||||
end
|
||||
|
||||
-- Call from ENT:AcceptInput and it'll return true if the input was AddOutput
|
||||
-- and if it successfully added an output.
|
||||
-- Note that to be strictly compatible with Source entities, AddOutput should
|
||||
-- allow setting arbitrary keyvalues, but this implementation does not.
|
||||
function ENT:AddOutputFromAcceptInput( name, value )
|
||||
|
||||
if ( name ~= "AddOutput" ) then
|
||||
|
||||
return false
|
||||
|
||||
end
|
||||
|
||||
local pos = string.find( value, " ", 1, true )
|
||||
if ( pos == nil ) then
|
||||
|
||||
return false
|
||||
|
||||
end
|
||||
|
||||
name, value = value:sub( 1, pos - 1 ), value:sub( pos + 1 )
|
||||
|
||||
-- This is literally KeyValue but as an input and with ,s as :s.
|
||||
value = value:gsub( ":", "," )
|
||||
|
||||
return self:AddOutputFromKeyValue( name, value )
|
||||
|
||||
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 ipairs( 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, activator, data ) ) then
|
||||
|
||||
-- Shift the indexes so this loop doesn't fail later
|
||||
table.remove( self.m_tOutputs[ name ], idx )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
16
gamemodes/base/entities/entities/base_entity/shared.lua
Normal file
16
gamemodes/base/entities/entities/base_entity/shared.lua
Normal file
@@ -0,0 +1,16 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
ENT.Base = "base_entity"
|
||||
ENT.Type = "anim"
|
||||
|
||||
ENT.Spawnable = false
|
||||
ENT.AdminOnly = false
|
||||
54
gamemodes/base/entities/entities/base_filter.lua
Normal file
54
gamemodes/base/entities/entities/base_filter.lua
Normal file
@@ -0,0 +1,54 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
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
|
||||
64
gamemodes/base/entities/entities/base_nextbot/shared.lua
Normal file
64
gamemodes/base/entities/entities/base_nextbot/shared.lua
Normal file
@@ -0,0 +1,64 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
ENT.Base = "base_entity"
|
||||
ENT.PrintName = ""
|
||||
ENT.Author = ""
|
||||
ENT.Contact = ""
|
||||
ENT.Purpose = ""
|
||||
ENT.Instructions = ""
|
||||
|
||||
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
|
||||
425
gamemodes/base/entities/entities/base_nextbot/sv_nextbot.lua
Normal file
425
gamemodes/base/entities/entities/base_nextbot/sv_nextbot.lua
Normal file
@@ -0,0 +1,425 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
--
|
||||
-- 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:OnTakeDamage
|
||||
-- Desc: Called when the bot is about to take damage
|
||||
-- Arg1: CTakeDamageInfo|info|damage info
|
||||
-- Ret1: number|how much damage was taken, prevents default damage code from running
|
||||
--
|
||||
function ENT:OnTakeDamage( damageinfo )
|
||||
|
||||
-- return 0
|
||||
|
||||
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 ipairs( areas ) do
|
||||
|
||||
-- get the spots
|
||||
local spots
|
||||
|
||||
if ( tbl.type == 'hiding' ) then spots = area:GetHidingSpots() end
|
||||
|
||||
for k, vec in ipairs( spots ) do
|
||||
|
||||
-- Work out the length, and add them to a table
|
||||
path:Invalidate()
|
||||
|
||||
path:Compute( self, vec ) -- 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
|
||||
55
gamemodes/base/entities/entities/base_point.lua
Normal file
55
gamemodes/base/entities/entities/base_point.lua
Normal file
@@ -0,0 +1,55 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
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
|
||||
20
gamemodes/base/entities/entities/diprip_start_team_blue.lua
Normal file
20
gamemodes/base/entities/entities/diprip_start_team_blue.lua
Normal file
@@ -0,0 +1,20 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
-- 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"
|
||||
20
gamemodes/base/entities/entities/diprip_start_team_red.lua
Normal file
20
gamemodes/base/entities/entities/diprip_start_team_red.lua
Normal file
@@ -0,0 +1,20 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
-- 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"
|
||||
20
gamemodes/base/entities/entities/dys_spawn_point.lua
Normal file
20
gamemodes/base/entities/entities/dys_spawn_point.lua
Normal file
@@ -0,0 +1,20 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
-- 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"
|
||||
142
gamemodes/base/entities/entities/env_skypaint.lua
Normal file
142
gamemodes/base/entities/entities/env_skypaint.lua
Normal file
@@ -0,0 +1,142 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
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 sunlist = ents.FindByClass( "env_sun" )
|
||||
if ( #sunlist > 0 ) then
|
||||
self.EnvSun = sunlist[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 && !IsValid( g_SkyPaint ) ) then
|
||||
|
||||
g_SkyPaint = self
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- To prevent server insanity - only let admins edit the sky.
|
||||
--
|
||||
function ENT:CanEditVariables( ply )
|
||||
|
||||
return ply:IsAdmin() || game.SinglePlayer()
|
||||
|
||||
end
|
||||
77
gamemodes/base/entities/entities/gmod_hands.lua
Normal file
77
gamemodes/base/entities/entities/gmod_hands.lua
Normal file
@@ -0,0 +1,77 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
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
|
||||
91
gamemodes/base/entities/entities/gmod_player_start.lua
Normal file
91
gamemodes/base/entities/entities/gmod_player_start.lua
Normal file
@@ -0,0 +1,91 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
-- 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
|
||||
20
gamemodes/base/entities/entities/info_player_allies.lua
Normal file
20
gamemodes/base/entities/entities/info_player_allies.lua
Normal file
@@ -0,0 +1,20 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
-- 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"
|
||||
20
gamemodes/base/entities/entities/info_player_axis.lua
Normal file
20
gamemodes/base/entities/entities/info_player_axis.lua
Normal file
@@ -0,0 +1,20 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
-- 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"
|
||||
20
gamemodes/base/entities/entities/info_player_blue.lua
Normal file
20
gamemodes/base/entities/entities/info_player_blue.lua
Normal file
@@ -0,0 +1,20 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
-- 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"
|
||||
20
gamemodes/base/entities/entities/info_player_coop.lua
Normal file
20
gamemodes/base/entities/entities/info_player_coop.lua
Normal file
@@ -0,0 +1,20 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
-- 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,20 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
-- 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"
|
||||
20
gamemodes/base/entities/entities/info_player_deathmatch.lua
Normal file
20
gamemodes/base/entities/entities/info_player_deathmatch.lua
Normal file
@@ -0,0 +1,20 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
-- 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"
|
||||
20
gamemodes/base/entities/entities/info_player_desperado.lua
Normal file
20
gamemodes/base/entities/entities/info_player_desperado.lua
Normal file
@@ -0,0 +1,20 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
-- 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"
|
||||
20
gamemodes/base/entities/entities/info_player_fof.lua
Normal file
20
gamemodes/base/entities/entities/info_player_fof.lua
Normal file
@@ -0,0 +1,20 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
-- 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"
|
||||
20
gamemodes/base/entities/entities/info_player_human.lua
Normal file
20
gamemodes/base/entities/entities/info_player_human.lua
Normal file
@@ -0,0 +1,20 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
-- 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"
|
||||
20
gamemodes/base/entities/entities/info_player_knight.lua
Normal file
20
gamemodes/base/entities/entities/info_player_knight.lua
Normal file
@@ -0,0 +1,20 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
-- 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"
|
||||
20
gamemodes/base/entities/entities/info_player_pirate.lua
Normal file
20
gamemodes/base/entities/entities/info_player_pirate.lua
Normal file
@@ -0,0 +1,20 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
-- 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"
|
||||
20
gamemodes/base/entities/entities/info_player_red.lua
Normal file
20
gamemodes/base/entities/entities/info_player_red.lua
Normal file
@@ -0,0 +1,20 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
-- 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"
|
||||
20
gamemodes/base/entities/entities/info_player_terrorist.lua
Normal file
20
gamemodes/base/entities/entities/info_player_terrorist.lua
Normal file
@@ -0,0 +1,20 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
-- 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"
|
||||
20
gamemodes/base/entities/entities/info_player_vigilante.lua
Normal file
20
gamemodes/base/entities/entities/info_player_vigilante.lua
Normal file
@@ -0,0 +1,20 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
-- 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"
|
||||
20
gamemodes/base/entities/entities/info_player_viking.lua
Normal file
20
gamemodes/base/entities/entities/info_player_viking.lua
Normal file
@@ -0,0 +1,20 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
-- 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"
|
||||
20
gamemodes/base/entities/entities/info_player_zombie.lua
Normal file
20
gamemodes/base/entities/entities/info_player_zombie.lua
Normal file
@@ -0,0 +1,20 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
-- 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,20 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
-- 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"
|
||||
20
gamemodes/base/entities/entities/info_spawnpoint.lua
Normal file
20
gamemodes/base/entities/entities/info_spawnpoint.lua
Normal file
@@ -0,0 +1,20 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
-- 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"
|
||||
20
gamemodes/base/entities/entities/info_survivor_position.lua
Normal file
20
gamemodes/base/entities/entities/info_survivor_position.lua
Normal file
@@ -0,0 +1,20 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
-- 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"
|
||||
20
gamemodes/base/entities/entities/info_survivor_rescue.lua
Normal file
20
gamemodes/base/entities/entities/info_survivor_rescue.lua
Normal file
@@ -0,0 +1,20 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
-- 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"
|
||||
20
gamemodes/base/entities/entities/ins_spawnpoint.lua
Normal file
20
gamemodes/base/entities/entities/ins_spawnpoint.lua
Normal file
@@ -0,0 +1,20 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
-- 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"
|
||||
73
gamemodes/base/entities/entities/lua_run.lua
Normal file
73
gamemodes/base/entities/entities/lua_run.lua
Normal file
@@ -0,0 +1,73 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
-- 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
|
||||
82
gamemodes/base/entities/entities/npc_tf2_ghost.lua
Normal file
82
gamemodes/base/entities/entities/npc_tf2_ghost.lua
Normal file
@@ -0,0 +1,82 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
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"
|
||||
} )
|
||||
188
gamemodes/base/entities/entities/prop_effect.lua
Normal file
188
gamemodes/base/entities/entities/prop_effect.lua
Normal file
@@ -0,0 +1,188 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
if ( CLIENT ) then
|
||||
CreateConVar( "cl_draweffectrings", "1", 0, "Should the green effect 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
|
||||
317
gamemodes/base/entities/entities/ragdoll_motion.lua
Normal file
317
gamemodes/base/entities/entities/ragdoll_motion.lua
Normal file
@@ -0,0 +1,317 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
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 )
|
||||
|
||||
if ( IsValid( ragdoll.MotionSensorController ) && ragdoll.MotionSensorController == self ) then
|
||||
ragdoll.MotionSensorController = nil
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function ENT:Draw()
|
||||
|
||||
--
|
||||
-- Don't draw if we're holding the camera
|
||||
--
|
||||
local ply = LocalPlayer()
|
||||
local wep = ply:GetActiveWeapon()
|
||||
if ( IsValid( wep ) && wep:GetClass() == "gmod_camera" ) then
|
||||
return
|
||||
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 )
|
||||
debugoverlay.Box( fixedbonepos[i], min, max, StayTime, col_tran_bn )
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Draw bones
|
||||
--
|
||||
for k, v in ipairs( motionsensor.DebugBones ) do
|
||||
|
||||
debugoverlay.Line( realbonepos[ v[1] ], realbonepos[ v[2] ], StayTime, col_bone, true )
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Draw translated sensor bones
|
||||
--
|
||||
for k, v in ipairs( 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 position = phys:GetPos()
|
||||
local angle = phys:GetAngles()
|
||||
local txt = tostring( i )
|
||||
|
||||
if ( ang[i] == nil ) then
|
||||
txt = i .. " (UNSET)"
|
||||
end
|
||||
|
||||
debugoverlay.Text( position, txt, StayTime )
|
||||
debugoverlay.Axis( position, angle, 5, StayTime, true )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function ENT:SetRagdoll( ragdoll )
|
||||
|
||||
ragdoll.MotionSensorController = self
|
||||
|
||||
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
|
||||
202
gamemodes/base/entities/weapons/weapon_base/ai_translations.lua
Normal file
202
gamemodes/base/entities/weapons/weapon_base/ai_translations.lua
Normal file
@@ -0,0 +1,202 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
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
|
||||
221
gamemodes/base/entities/weapons/weapon_base/cl_init.lua
Normal file
221
gamemodes/base/entities/weapons/weapon_base/cl_init.lua
Normal file
@@ -0,0 +1,221 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
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 title_color = "<color=230,230,230,255>"
|
||||
local text_color = "<color=150,150,150,255>"
|
||||
|
||||
local 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:GetOwner():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
|
||||
114
gamemodes/base/entities/weapons/weapon_base/init.lua
Normal file
114
gamemodes/base/entities/weapons/weapon_base/init.lua
Normal file
@@ -0,0 +1,114 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
AddCSLuaFile( "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 immediately 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" )
|
||||
97
gamemodes/base/entities/weapons/weapon_base/sh_anim.lua
Normal file
97
gamemodes/base/entities/weapons/weapon_base/sh_anim.lua
Normal file
@@ -0,0 +1,97 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
local 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:GetOwner():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
|
||||
280
gamemodes/base/entities/weapons/weapon_base/shared.lua
Normal file
280
gamemodes/base/entities/weapons/weapon_base/shared.lua
Normal file
@@ -0,0 +1,280 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
-- Variables that are used on both client and server
|
||||
|
||||
SWEP.PrintName = "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
|
||||
local owner = self:GetOwner()
|
||||
if ( !owner:IsNPC() ) then 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
|
||||
local owner = self:GetOwner()
|
||||
if ( !owner:IsNPC() ) then 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()
|
||||
|
||||
local owner = self:GetOwner()
|
||||
|
||||
self:SendWeaponAnim( ACT_VM_PRIMARYATTACK ) -- View model animation
|
||||
owner:MuzzleFlash() -- Crappy muzzle light
|
||||
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 owner = self:GetOwner()
|
||||
|
||||
local bullet = {}
|
||||
bullet.Num = num_bullets
|
||||
bullet.Src = owner:GetShootPos() -- Source
|
||||
bullet.Dir = 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
|
||||
|
||||
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:GetOwner():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:GetOwner():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:GetOwner():GetAmmoCount( self:GetPrimaryAmmoType() )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: Ammo2
|
||||
Desc: Returns how much of ammo2 the player has
|
||||
-----------------------------------------------------------]]
|
||||
function SWEP:Ammo2()
|
||||
return self:GetOwner():GetAmmoCount( self:GetSecondaryAmmoType() )
|
||||
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
|
||||
406
gamemodes/base/gamemode/animations.lua
Normal file
406
gamemodes/base/gamemode/animations.lua
Normal file
@@ -0,0 +1,406 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
function GM:HandlePlayerJumping( ply, velocity, plyTable )
|
||||
|
||||
if ( !plyTable ) then plyTable = ply:GetTable() end
|
||||
|
||||
if ( ply:GetMoveType() == MOVETYPE_NOCLIP ) then
|
||||
plyTable.m_bJumping = false
|
||||
return
|
||||
end
|
||||
|
||||
-- airwalk more like hl2mp, we airwalk until we have 0 velocity, then it's the jump animation
|
||||
-- underwater we're alright we airwalking
|
||||
if ( !plyTable.m_bJumping && !ply:OnGround() && ply:WaterLevel() <= 0 ) then
|
||||
|
||||
if ( !plyTable.m_fGroundTime ) then
|
||||
|
||||
plyTable.m_fGroundTime = CurTime()
|
||||
|
||||
elseif ( ( CurTime() - plyTable.m_fGroundTime ) > 0 && velocity:Length2DSqr() < 0.25 ) then
|
||||
|
||||
plyTable.m_bJumping = true
|
||||
plyTable.m_bFirstJumpFrame = false
|
||||
plyTable.m_flJumpStartTime = 0
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
if ( plyTable.m_bJumping ) then
|
||||
|
||||
if ( plyTable.m_bFirstJumpFrame ) then
|
||||
|
||||
plyTable.m_bFirstJumpFrame = false
|
||||
ply:AnimRestartMainSequence()
|
||||
|
||||
end
|
||||
|
||||
if ( ( ply:WaterLevel() >= 2 ) || ( ( CurTime() - plyTable.m_flJumpStartTime ) > 0.2 && ply:OnGround() ) ) then
|
||||
|
||||
plyTable.m_bJumping = false
|
||||
plyTable.m_fGroundTime = nil
|
||||
ply:AnimRestartMainSequence()
|
||||
|
||||
end
|
||||
|
||||
if ( plyTable.m_bJumping ) then
|
||||
plyTable.CalcIdeal = ACT_MP_JUMP
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
|
||||
end
|
||||
|
||||
function GM:HandlePlayerDucking( ply, velocity, plyTable )
|
||||
|
||||
if ( !plyTable ) then plyTable = ply:GetTable() end
|
||||
|
||||
if ( !ply:IsFlagSet( FL_ANIMDUCKING ) ) then return false end
|
||||
|
||||
if ( velocity:Length2DSqr() > 0.25 ) then
|
||||
plyTable.CalcIdeal = ACT_MP_CROUCHWALK
|
||||
else
|
||||
plyTable.CalcIdeal = ACT_MP_CROUCH_IDLE
|
||||
end
|
||||
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
function GM:HandlePlayerNoClipping( ply, velocity, plyTable )
|
||||
|
||||
if ( !plyTable ) then plyTable = ply:GetTable() end
|
||||
|
||||
if ( ply:GetMoveType() != MOVETYPE_NOCLIP || ply:InVehicle() ) then
|
||||
|
||||
if ( plyTable.m_bWasNoclipping ) then
|
||||
|
||||
plyTable.m_bWasNoclipping = nil
|
||||
ply:AnimResetGestureSlot( GESTURE_SLOT_CUSTOM )
|
||||
if ( CLIENT ) then ply:SetIK( true ) end
|
||||
|
||||
end
|
||||
|
||||
return
|
||||
|
||||
end
|
||||
|
||||
if ( !plyTable.m_bWasNoclipping ) then
|
||||
|
||||
ply:AnimRestartGesture( GESTURE_SLOT_CUSTOM, ACT_GMOD_NOCLIP_LAYER, false )
|
||||
if ( CLIENT ) then ply:SetIK( false ) end
|
||||
|
||||
end
|
||||
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
function GM:HandlePlayerVaulting( ply, velocity, plyTable )
|
||||
|
||||
if ( !plyTable ) then plyTable = ply:GetTable() end
|
||||
|
||||
if ( velocity:LengthSqr() < 1000000 ) then return end
|
||||
if ( ply:IsOnGround() ) then return end
|
||||
|
||||
plyTable.CalcIdeal = ACT_MP_SWIM
|
||||
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
function GM:HandlePlayerSwimming( ply, velocity, plyTable )
|
||||
|
||||
if ( !plyTable ) then plyTable = ply:GetTable() end
|
||||
|
||||
if ( ply:WaterLevel() < 2 || ply:IsOnGround() ) then
|
||||
plyTable.m_bInSwim = false
|
||||
return false
|
||||
end
|
||||
|
||||
plyTable.CalcIdeal = ACT_MP_SWIM
|
||||
plyTable.m_bInSwim = true
|
||||
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
function GM:HandlePlayerLanding( ply, velocity, WasOnGround )
|
||||
|
||||
if ( ply:GetMoveType() == MOVETYPE_NOCLIP ) then return end
|
||||
|
||||
if ( ply:IsOnGround() && !WasOnGround ) then
|
||||
ply:AnimRestartGesture( GESTURE_SLOT_JUMP, ACT_LAND, true )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function GM:HandlePlayerDriving( ply, plyTable )
|
||||
|
||||
if ( !plyTable ) then plyTable = ply:GetTable() end
|
||||
|
||||
-- The player must have a parent to be in a vehicle. If there's no parent, we are in the exit anim, so don't do sitting in 3rd person anymore
|
||||
if ( !ply:InVehicle() || !IsValid( ply:GetParent() ) ) then return false end
|
||||
|
||||
local pVehicle = ply:GetVehicle()
|
||||
|
||||
if ( !pVehicle.HandleAnimation && pVehicle.GetVehicleClass ) then
|
||||
local c = pVehicle:GetVehicleClass()
|
||||
local t = list.Get( "Vehicles" )[ c ]
|
||||
if ( t && t.Members && t.Members.HandleAnimation ) then
|
||||
pVehicle.HandleAnimation = t.Members.HandleAnimation
|
||||
else
|
||||
pVehicle.HandleAnimation = true -- Prevent this if block from trying to assign HandleAnimation again.
|
||||
end
|
||||
end
|
||||
|
||||
if ( isfunction( pVehicle.HandleAnimation ) ) then
|
||||
local seq = pVehicle:HandleAnimation( ply )
|
||||
if ( seq != nil ) then
|
||||
plyTable.CalcSeqOverride = seq
|
||||
end
|
||||
end
|
||||
|
||||
if ( plyTable.CalcSeqOverride == -1 ) then -- pVehicle.HandleAnimation did not give us an animation
|
||||
local class = pVehicle:GetClass()
|
||||
if ( class == "prop_vehicle_jeep" ) then
|
||||
plyTable.CalcSeqOverride = ply:LookupSequence( "drive_jeep" )
|
||||
elseif ( class == "prop_vehicle_airboat" ) then
|
||||
plyTable.CalcSeqOverride = ply:LookupSequence( "drive_airboat" )
|
||||
elseif ( class == "prop_vehicle_prisoner_pod" && pVehicle:GetModel() == "models/vehicles/prisoner_pod_inner.mdl" ) then
|
||||
-- HACK!!
|
||||
plyTable.CalcSeqOverride = ply:LookupSequence( "drive_pd" )
|
||||
else
|
||||
plyTable.CalcSeqOverride = ply:LookupSequence( "sit_rollercoaster" )
|
||||
end
|
||||
end
|
||||
|
||||
local use_anims = ( plyTable.CalcSeqOverride == ply:LookupSequence( "sit_rollercoaster" ) || plyTable.CalcSeqOverride == ply:LookupSequence( "sit" ) )
|
||||
if ( use_anims && ply:GetAllowWeaponsInVehicle() && IsValid( ply:GetActiveWeapon() ) ) then
|
||||
local holdtype = ply:GetActiveWeapon():GetHoldType()
|
||||
if ( holdtype == "smg" ) then holdtype = "smg1" end
|
||||
|
||||
local seqid = ply:LookupSequence( "sit_" .. holdtype )
|
||||
if ( seqid != -1 ) then
|
||||
plyTable.CalcSeqOverride = seqid
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:UpdateAnimation()
|
||||
Desc: Animation updates (pose params etc) should be done here
|
||||
-----------------------------------------------------------]]
|
||||
function GM:UpdateAnimation( ply, velocity, maxseqgroundspeed )
|
||||
|
||||
local len = velocity:Length()
|
||||
local movement = 1.0
|
||||
|
||||
if ( len > 0.2 ) then
|
||||
movement = ( len / maxseqgroundspeed )
|
||||
end
|
||||
|
||||
local rate = math.min( movement, 2 )
|
||||
|
||||
-- if we're under water we want to constantly be swimming..
|
||||
if ( ply:WaterLevel() >= 2 ) then
|
||||
rate = math.max( rate, 0.5 )
|
||||
elseif ( !ply:IsOnGround() && len >= 1000 ) then
|
||||
rate = 0.1
|
||||
end
|
||||
|
||||
ply:SetPlaybackRate( rate )
|
||||
|
||||
-- We only need to do this clientside..
|
||||
if ( CLIENT ) then
|
||||
if ( ply:InVehicle() ) then
|
||||
--
|
||||
-- This is used for the 'rollercoaster' arms
|
||||
--
|
||||
local Vehicle = ply:GetVehicle()
|
||||
local Velocity = Vehicle:GetVelocity()
|
||||
local fwd = Vehicle:GetUp()
|
||||
local dp = fwd:Dot( Vector( 0, 0, 1 ) )
|
||||
|
||||
ply:SetPoseParameter( "vertical_velocity", ( dp < 0 && dp || 0 ) + fwd:Dot( Velocity ) * 0.005 )
|
||||
|
||||
-- Pass the vehicles steer param down to the player
|
||||
local steer = Vehicle:GetPoseParameter( "vehicle_steer" )
|
||||
steer = steer * 2 - 1 -- convert from 0..1 to -1..1
|
||||
if ( Vehicle:GetClass() == "prop_vehicle_prisoner_pod" ) then steer = 0 ply:SetPoseParameter( "aim_yaw", math.NormalizeAngle( ply:GetAimVector():Angle().y - Vehicle:GetAngles().y - 90 ) ) end
|
||||
ply:SetPoseParameter( "vehicle_steer", steer )
|
||||
|
||||
end
|
||||
|
||||
GAMEMODE:GrabEarAnimation( ply )
|
||||
GAMEMODE:MouthMoveAnimation( ply )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- If you don't want the player to grab his ear in your gamemode then
|
||||
-- just override this.
|
||||
--
|
||||
function GM:GrabEarAnimation( ply, plyTable )
|
||||
|
||||
if ( !plyTable ) then plyTable = ply:GetTable() end
|
||||
|
||||
plyTable.ChatGestureWeight = plyTable.ChatGestureWeight || 0
|
||||
|
||||
-- Don't show this when we're playing a taunt!
|
||||
if ( ply:IsPlayingTaunt() ) then return end
|
||||
|
||||
if ( ply:IsTyping() ) then
|
||||
plyTable.ChatGestureWeight = math.Approach( plyTable.ChatGestureWeight, 1, FrameTime() * 5.0 )
|
||||
else
|
||||
plyTable.ChatGestureWeight = math.Approach( plyTable.ChatGestureWeight, 0, FrameTime() * 5.0 )
|
||||
end
|
||||
|
||||
if ( plyTable.ChatGestureWeight > 0 ) then
|
||||
|
||||
ply:AnimRestartGesture( GESTURE_SLOT_VCD, ACT_GMOD_IN_CHAT, true )
|
||||
ply:AnimSetGestureWeight( GESTURE_SLOT_VCD, plyTable.ChatGestureWeight )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Moves the mouth when talking on voicecom
|
||||
--
|
||||
function GM:MouthMoveAnimation( ply )
|
||||
|
||||
local flexes = {
|
||||
ply:GetFlexIDByName( "jaw_drop" ),
|
||||
ply:GetFlexIDByName( "left_part" ),
|
||||
ply:GetFlexIDByName( "right_part" ),
|
||||
ply:GetFlexIDByName( "left_mouth_drop" ),
|
||||
ply:GetFlexIDByName( "right_mouth_drop" )
|
||||
}
|
||||
|
||||
local weight = ply:IsSpeaking() && math.Clamp( ply:VoiceVolume() * 2, 0, 2 ) || 0
|
||||
|
||||
for k, v in ipairs( flexes ) do
|
||||
|
||||
ply:SetFlexWeight( v, weight )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function GM:CalcMainActivity( ply, velocity )
|
||||
|
||||
local plyTable = ply:GetTable()
|
||||
plyTable.CalcIdeal = ACT_MP_STAND_IDLE
|
||||
plyTable.CalcSeqOverride = -1
|
||||
|
||||
self:HandlePlayerLanding( ply, velocity, plyTable.m_bWasOnGround )
|
||||
|
||||
if !( self:HandlePlayerNoClipping( ply, velocity, plyTable ) ||
|
||||
self:HandlePlayerDriving( ply, plyTable ) ||
|
||||
self:HandlePlayerVaulting( ply, velocity, plyTable ) ||
|
||||
self:HandlePlayerJumping( ply, velocity, plyTable ) ||
|
||||
self:HandlePlayerSwimming( ply, velocity, plyTable ) ||
|
||||
self:HandlePlayerDucking( ply, velocity, plyTable ) ) then
|
||||
|
||||
local len2d = velocity:Length2DSqr()
|
||||
if ( len2d > 22500 ) then plyTable.CalcIdeal = ACT_MP_RUN elseif ( len2d > 0.25 ) then plyTable.CalcIdeal = ACT_MP_WALK end
|
||||
|
||||
end
|
||||
|
||||
plyTable.m_bWasOnGround = ply:IsOnGround()
|
||||
plyTable.m_bWasNoclipping = ( ply:GetMoveType() == MOVETYPE_NOCLIP && !ply:InVehicle() )
|
||||
|
||||
return plyTable.CalcIdeal, plyTable.CalcSeqOverride
|
||||
|
||||
end
|
||||
|
||||
local IdleActivity = ACT_HL2MP_IDLE
|
||||
local IdleActivityTranslate = {}
|
||||
IdleActivityTranslate[ ACT_MP_STAND_IDLE ] = IdleActivity
|
||||
IdleActivityTranslate[ ACT_MP_WALK ] = IdleActivity + 1
|
||||
IdleActivityTranslate[ ACT_MP_RUN ] = IdleActivity + 2
|
||||
IdleActivityTranslate[ ACT_MP_CROUCH_IDLE ] = IdleActivity + 3
|
||||
IdleActivityTranslate[ ACT_MP_CROUCHWALK ] = IdleActivity + 4
|
||||
IdleActivityTranslate[ ACT_MP_ATTACK_STAND_PRIMARYFIRE ] = IdleActivity + 5
|
||||
IdleActivityTranslate[ ACT_MP_ATTACK_CROUCH_PRIMARYFIRE ] = IdleActivity + 5
|
||||
IdleActivityTranslate[ ACT_MP_RELOAD_STAND ] = IdleActivity + 6
|
||||
IdleActivityTranslate[ ACT_MP_RELOAD_CROUCH ] = IdleActivity + 6
|
||||
IdleActivityTranslate[ ACT_MP_JUMP ] = ACT_HL2MP_JUMP_SLAM
|
||||
IdleActivityTranslate[ ACT_MP_SWIM ] = IdleActivity + 9
|
||||
IdleActivityTranslate[ ACT_LAND ] = ACT_LAND
|
||||
|
||||
-- it is preferred you return ACT_MP_* in CalcMainActivity, and if you have a specific need to not translate through the weapon do it here
|
||||
function GM:TranslateActivity( ply, act )
|
||||
|
||||
local newact = ply:TranslateWeaponActivity( act )
|
||||
|
||||
-- select idle anims if the weapon didn't decide
|
||||
if ( act == newact ) then
|
||||
return IdleActivityTranslate[ act ]
|
||||
end
|
||||
|
||||
return newact
|
||||
|
||||
end
|
||||
|
||||
function GM:DoAnimationEvent( ply, event, data )
|
||||
|
||||
if ( event == PLAYERANIMEVENT_ATTACK_PRIMARY ) then
|
||||
|
||||
if ply:IsFlagSet( FL_ANIMDUCKING ) then
|
||||
ply:AnimRestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_ATTACK_CROUCH_PRIMARYFIRE, true )
|
||||
else
|
||||
ply:AnimRestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_ATTACK_STAND_PRIMARYFIRE, true )
|
||||
end
|
||||
|
||||
return ACT_VM_PRIMARYATTACK
|
||||
|
||||
elseif ( event == PLAYERANIMEVENT_ATTACK_SECONDARY ) then
|
||||
|
||||
-- there is no gesture, so just fire off the VM event
|
||||
return ACT_VM_SECONDARYATTACK
|
||||
|
||||
elseif ( event == PLAYERANIMEVENT_RELOAD ) then
|
||||
|
||||
if ply:IsFlagSet( FL_ANIMDUCKING ) then
|
||||
ply:AnimRestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_CROUCH, true )
|
||||
else
|
||||
ply:AnimRestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_STAND, true )
|
||||
end
|
||||
|
||||
return ACT_INVALID
|
||||
|
||||
elseif ( event == PLAYERANIMEVENT_JUMP ) then
|
||||
|
||||
ply.m_bJumping = true
|
||||
ply.m_bFirstJumpFrame = true
|
||||
ply.m_flJumpStartTime = CurTime()
|
||||
|
||||
ply:AnimRestartMainSequence()
|
||||
|
||||
return ACT_INVALID
|
||||
|
||||
elseif ( event == PLAYERANIMEVENT_CANCEL_RELOAD ) then
|
||||
|
||||
ply:AnimResetGestureSlot( GESTURE_SLOT_ATTACK_AND_RELOAD )
|
||||
|
||||
return ACT_INVALID
|
||||
end
|
||||
|
||||
end
|
||||
302
gamemodes/base/gamemode/cl_deathnotice.lua
Normal file
302
gamemodes/base/gamemode/cl_deathnotice.lua
Normal file
@@ -0,0 +1,302 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
local hud_deathnotice_time = CreateConVar( "hud_deathnotice_time", "6", FCVAR_REPLICATED, "Amount of time to show death notice (kill feed) for" )
|
||||
local cl_drawhud = GetConVar( "cl_drawhud" )
|
||||
|
||||
-- These are our kill icons
|
||||
local Color_Icon = Color( 255, 80, 0, 255 )
|
||||
local NPC_Color_Enemy = Color( 250, 50, 50, 255 )
|
||||
local NPC_Color_Friendly = Color( 50, 200, 50, 255 )
|
||||
|
||||
killicon.AddFont( "prop_physics", "HL2MPTypeDeath", "9", Color_Icon, 0.52 )
|
||||
killicon.AddFont( "weapon_smg1", "HL2MPTypeDeath", "/", Color_Icon, 0.55 )
|
||||
killicon.AddFont( "weapon_357", "HL2MPTypeDeath", ".", Color_Icon, 0.55 )
|
||||
killicon.AddFont( "weapon_ar2", "HL2MPTypeDeath", "2", Color_Icon, 0.6 )
|
||||
killicon.AddFont( "crossbow_bolt", "HL2MPTypeDeath", "1", Color_Icon, 0.5 )
|
||||
killicon.AddFont( "weapon_shotgun", "HL2MPTypeDeath", "0", Color_Icon, 0.45 )
|
||||
killicon.AddFont( "rpg_missile", "HL2MPTypeDeath", "3", Color_Icon, 0.35 )
|
||||
killicon.AddFont( "npc_grenade_frag", "HL2MPTypeDeath", "4", Color_Icon, 0.56 )
|
||||
killicon.AddFont( "weapon_pistol", "HL2MPTypeDeath", "-", Color_Icon, 0.52 )
|
||||
killicon.AddFont( "prop_combine_ball", "HL2MPTypeDeath", "8", Color_Icon, 0.5 )
|
||||
killicon.AddFont( "grenade_ar2", "HL2MPTypeDeath", "7", Color_Icon, 0.35 )
|
||||
killicon.AddFont( "weapon_stunstick", "HL2MPTypeDeath", "!", Color_Icon, 0.6 )
|
||||
killicon.AddFont( "npc_satchel", "HL2MPTypeDeath", "*", Color_Icon, 0.53 )
|
||||
killicon.AddAlias( "npc_tripmine", "npc_satchel" )
|
||||
killicon.AddFont( "weapon_crowbar", "HL2MPTypeDeath", "6", Color_Icon, 0.45 )
|
||||
killicon.AddFont( "weapon_physcannon", "HL2MPTypeDeath", ",", Color_Icon, 0.55 )
|
||||
|
||||
-- Prop like objects get the prop kill icon
|
||||
killicon.AddAlias( "prop_ragdoll", "prop_physics" )
|
||||
killicon.AddAlias( "prop_physics_respawnable", "prop_physics" )
|
||||
killicon.AddAlias( "func_physbox", "prop_physics" )
|
||||
killicon.AddAlias( "func_physbox_multiplayer", "prop_physics" )
|
||||
killicon.AddAlias( "trigger_vphysics_motion", "prop_physics" )
|
||||
killicon.AddAlias( "func_movelinear", "prop_physics" )
|
||||
killicon.AddAlias( "func_plat", "prop_physics" )
|
||||
killicon.AddAlias( "func_platrot", "prop_physics" )
|
||||
killicon.AddAlias( "func_pushable", "prop_physics" )
|
||||
killicon.AddAlias( "func_rotating", "prop_physics" )
|
||||
killicon.AddAlias( "func_rot_button", "prop_physics" )
|
||||
killicon.AddAlias( "func_tracktrain", "prop_physics" )
|
||||
killicon.AddAlias( "func_train", "prop_physics" )
|
||||
|
||||
local function HandleAchievements( victimType )
|
||||
|
||||
-- Try to find by name
|
||||
for id, tab in pairs( list.Get( "NPC" ) ) do
|
||||
if ( tab.Name == victimType ) then
|
||||
victimType = tab.Class
|
||||
end
|
||||
end
|
||||
-- If fails, try to omit the translation system #
|
||||
if ( victimType:StartsWith( "#" ) ) then
|
||||
victimType = victimType:sub( 2 )
|
||||
end
|
||||
|
||||
local bIsEnemy = IsEnemyEntityName( victimType )
|
||||
local bIsFriend = IsFriendEntityName( victimType )
|
||||
|
||||
if ( bIsEnemy ) then
|
||||
achievements.IncBaddies()
|
||||
end
|
||||
|
||||
if ( bIsFriend ) then
|
||||
achievements.IncGoodies()
|
||||
end
|
||||
|
||||
if ( !bIsFriend && !bIsEnemy ) then
|
||||
achievements.IncBystander()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- Backwards compatiblity for addons
|
||||
net.Receive( "PlayerKilledByPlayer", function()
|
||||
|
||||
local victim = net.ReadEntity()
|
||||
local inflictor = net.ReadString()
|
||||
local attacker = net.ReadEntity()
|
||||
|
||||
if ( !IsValid( attacker ) ) then return end
|
||||
if ( !IsValid( victim ) ) then return end
|
||||
|
||||
hook.Run( "AddDeathNotice", attacker:Name(), attacker:Team(), inflictor, victim:Name(), victim:Team(), 0 )
|
||||
|
||||
end )
|
||||
|
||||
net.Receive( "PlayerKilledSelf", function()
|
||||
|
||||
local victim = net.ReadEntity()
|
||||
if ( !IsValid( victim ) ) then return end
|
||||
|
||||
hook.Run( "AddDeathNotice", nil, 0, "suicide", victim:Name(), victim:Team(), 0 )
|
||||
|
||||
end )
|
||||
|
||||
net.Receive( "PlayerKilled", function()
|
||||
|
||||
local victim = net.ReadEntity()
|
||||
if ( !IsValid( victim ) ) then return end
|
||||
|
||||
local inflictor = net.ReadString()
|
||||
local attacker = net.ReadString()
|
||||
|
||||
hook.Run( "AddDeathNotice", "#" .. attacker, -1, inflictor, victim:Name(), victim:Team(), 0 )
|
||||
|
||||
end )
|
||||
|
||||
net.Receive( "PlayerKilledNPC", function()
|
||||
|
||||
local victimtype = net.ReadString()
|
||||
local inflictor = net.ReadString()
|
||||
local attacker = net.ReadEntity()
|
||||
|
||||
--
|
||||
-- For some reason the killer isn't known to us, so don't proceed.
|
||||
--
|
||||
if ( !IsValid( attacker ) ) then return end
|
||||
|
||||
hook.Run( "AddDeathNotice", attacker:Name(), attacker:Team(), inflictor, "#" .. victimtype, -1, 0 )
|
||||
|
||||
local bIsLocalPlayer = ( IsValid( attacker ) && attacker == LocalPlayer() )
|
||||
if ( bIsLocalPlayer ) then
|
||||
HandleAchievements( victimtype )
|
||||
end
|
||||
|
||||
end )
|
||||
|
||||
net.Receive( "NPCKilledNPC", function()
|
||||
|
||||
local victim = "#" .. net.ReadString()
|
||||
local inflictor = net.ReadString()
|
||||
local attacker = "#" .. net.ReadString()
|
||||
|
||||
hook.Run( "AddDeathNotice", attacker, -1, inflictor, victim, -1, 0 )
|
||||
|
||||
end )
|
||||
|
||||
-- The new way
|
||||
DEATH_NOTICE_FRIENDLY_VICTIM = 1
|
||||
DEATH_NOTICE_FRIENDLY_ATTACKER = 2
|
||||
--DEATH_NOTICE_HEADSHOT = 4
|
||||
--DEATH_NOTICE_PENETRATION = 8
|
||||
net.Receive( "DeathNoticeEvent", function()
|
||||
|
||||
local attacker = nil
|
||||
local attackerType = net.ReadUInt( 2 )
|
||||
if ( attackerType == 1 ) then
|
||||
attacker = net.ReadString()
|
||||
elseif ( attackerType == 2 ) then
|
||||
attacker = net.ReadEntity()
|
||||
end
|
||||
|
||||
local inflictor = net.ReadString()
|
||||
|
||||
local victim = nil
|
||||
local victimType = net.ReadUInt( 2 )
|
||||
if ( victimType == 1 ) then
|
||||
victim = net.ReadString()
|
||||
elseif ( victimType == 2 ) then
|
||||
victim = net.ReadEntity()
|
||||
end
|
||||
|
||||
local flags = net.ReadUInt( 8 )
|
||||
|
||||
local bIsLocalPlayer = ( isentity( attacker ) && IsValid( attacker ) && attacker == LocalPlayer() )
|
||||
if ( bIsLocalPlayer && isstring( victim ) ) then
|
||||
HandleAchievements( victim )
|
||||
end
|
||||
|
||||
local team_a = -1
|
||||
local team_v = -1
|
||||
if ( bit.band( flags, DEATH_NOTICE_FRIENDLY_VICTIM ) != 0 ) then team_v = -2 end
|
||||
if ( bit.band( flags, DEATH_NOTICE_FRIENDLY_ATTACKER ) != 0 ) then team_a = -2 end
|
||||
|
||||
-- Handle player entities
|
||||
if ( isentity( attacker ) and attacker:IsValid() and attacker:IsPlayer() ) then team_a = attacker:Team() attacker = attacker:Name() end
|
||||
if ( isentity( victim ) and victim:IsValid() and victim:IsPlayer() ) then team_v = victim:Team() victim = victim:Name() end
|
||||
|
||||
-- Handle other entities
|
||||
if ( isentity( attacker ) and attacker:IsValid() ) then attacker = attacker:GetClass() end
|
||||
if ( isentity( victim ) and victim:IsValid() ) then victim = victim:GetClass() end
|
||||
|
||||
hook.Run( "AddDeathNotice", attacker, team_a, inflictor, victim, team_v, flags )
|
||||
|
||||
end )
|
||||
|
||||
local Deaths = {}
|
||||
|
||||
local function getDeathColor( teamID, target )
|
||||
|
||||
if ( teamID == -1 ) then
|
||||
return table.Copy( NPC_Color_Enemy )
|
||||
end
|
||||
|
||||
if ( teamID == -2 ) then
|
||||
return table.Copy( NPC_Color_Friendly )
|
||||
end
|
||||
|
||||
return table.Copy( team.GetColor( teamID ) )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:AddDeathNotice( Attacker, team1, Inflictor, Victim, team2, flags )
|
||||
Desc: Adds an death notice entry
|
||||
-----------------------------------------------------------]]
|
||||
function GM:AddDeathNotice( attacker, team1, inflictor, victim, team2, flags )
|
||||
|
||||
if ( inflictor == "suicide" ) then attacker = nil end
|
||||
|
||||
local Death = {}
|
||||
Death.time = CurTime()
|
||||
|
||||
Death.left = attacker
|
||||
Death.right = victim
|
||||
Death.icon = inflictor
|
||||
Death.flags = flags
|
||||
|
||||
Death.color1 = getDeathColor( team1, Death.left )
|
||||
Death.color2 = getDeathColor( team2, Death.right )
|
||||
|
||||
table.insert( Deaths, Death )
|
||||
|
||||
end
|
||||
|
||||
local function DrawDeath( x, y, death, time )
|
||||
|
||||
local w, h = killicon.GetSize( death.icon )
|
||||
if ( !w or !h ) then return end
|
||||
|
||||
local fadeout = ( death.time + time ) - CurTime()
|
||||
|
||||
local alpha = math.Clamp( fadeout * 255, 0, 255 )
|
||||
death.color1.a = alpha
|
||||
death.color2.a = alpha
|
||||
|
||||
-- Draw Icon
|
||||
killicon.Render( x - w / 2, y, death.icon, alpha )
|
||||
|
||||
-- Draw KILLER
|
||||
if ( death.left ) then
|
||||
draw.SimpleText( death.left, "ChatFont", x - ( w / 2 ) - 16, y + h / 2, death.color1, TEXT_ALIGN_RIGHT, TEXT_ALIGN_CENTER )
|
||||
end
|
||||
|
||||
-- Draw VICTIM
|
||||
draw.SimpleText( death.right, "ChatFont", x + ( w / 2 ) + 16, y + h / 2, death.color2, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER )
|
||||
|
||||
return math.ceil( y + h * 0.75 )
|
||||
|
||||
-- Font killicons are too high when height corrected, and changing that is not backwards compatible
|
||||
--return math.ceil( y + math.max( h, 28 ) )
|
||||
|
||||
end
|
||||
|
||||
function GM:DrawDeathNotice( x, y )
|
||||
|
||||
if ( cl_drawhud:GetInt() == 0 ) then return end
|
||||
|
||||
local time = hud_deathnotice_time:GetFloat()
|
||||
local reset = Deaths[1] != nil -- Don't reset it if there's nothing in it
|
||||
|
||||
x = x * ScrW()
|
||||
y = y * ScrH()
|
||||
|
||||
-- Draw
|
||||
for k, Death in ipairs( Deaths ) do
|
||||
|
||||
if ( Death.time + time > CurTime() ) then
|
||||
|
||||
if ( Death.lerp ) then
|
||||
x = x * 0.3 + Death.lerp.x * 0.7
|
||||
y = y * 0.3 + Death.lerp.y * 0.7
|
||||
end
|
||||
|
||||
Death.lerp = Death.lerp or {}
|
||||
Death.lerp.x = x
|
||||
Death.lerp.y = y
|
||||
|
||||
y = DrawDeath( math.floor( x ), math.floor( y ), Death, time )
|
||||
reset = false
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- We want to maintain the order of the table so instead of removing
|
||||
-- expired entries one by one we will just clear the entire table
|
||||
-- once everything is expired.
|
||||
if ( reset ) then
|
||||
Deaths = {}
|
||||
end
|
||||
|
||||
end
|
||||
183
gamemodes/base/gamemode/cl_hudpickup.lua
Normal file
183
gamemodes/base/gamemode/cl_hudpickup.lua
Normal file
@@ -0,0 +1,183 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
GM.PickupHistory = {}
|
||||
GM.PickupHistoryLast = 0
|
||||
GM.PickupHistoryTop = ScrH() / 2
|
||||
GM.PickupHistoryWide = 300
|
||||
GM.PickupHistoryCorner = surface.GetTextureID( "gui/corner8" )
|
||||
|
||||
local function AddGenericPickup( self, itemname )
|
||||
local pickup = {}
|
||||
pickup.time = CurTime()
|
||||
pickup.name = itemname
|
||||
pickup.holdtime = 5
|
||||
pickup.font = "DermaDefaultBold"
|
||||
pickup.fadein = 0.04
|
||||
pickup.fadeout = 0.3
|
||||
|
||||
surface.SetFont( pickup.font )
|
||||
local w, h = surface.GetTextSize( pickup.name )
|
||||
pickup.height = h
|
||||
pickup.width = w
|
||||
|
||||
--[[if ( self.PickupHistoryLast >= pickup.time ) then
|
||||
pickup.time = self.PickupHistoryLast + 0.05
|
||||
end]]
|
||||
|
||||
table.insert( self.PickupHistory, pickup )
|
||||
self.PickupHistoryLast = pickup.time
|
||||
|
||||
return pickup
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:HUDWeaponPickedUp( wep )
|
||||
Desc: The game wants you to draw on the HUD that a weapon has been picked up
|
||||
-----------------------------------------------------------]]
|
||||
function GM:HUDWeaponPickedUp( wep )
|
||||
|
||||
if ( !IsValid( LocalPlayer() ) || !LocalPlayer():Alive() ) then return end
|
||||
if ( !IsValid( wep ) ) then return end
|
||||
if ( !isfunction( wep.GetPrintName ) ) then return end
|
||||
|
||||
local pickup = AddGenericPickup( self, wep:GetPrintName() )
|
||||
pickup.color = Color( 255, 200, 50, 255 )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:HUDItemPickedUp( itemname )
|
||||
Desc: An item has been picked up..
|
||||
-----------------------------------------------------------]]
|
||||
function GM:HUDItemPickedUp( itemname )
|
||||
|
||||
if ( !IsValid( LocalPlayer() ) || !LocalPlayer():Alive() ) then return end
|
||||
|
||||
local pickup = AddGenericPickup( self, "#" .. itemname )
|
||||
pickup.color = Color( 180, 255, 180, 255 )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:HUDAmmoPickedUp( itemname, amount )
|
||||
Desc: Ammo has been picked up..
|
||||
-----------------------------------------------------------]]
|
||||
function GM:HUDAmmoPickedUp( itemname, amount )
|
||||
|
||||
if ( !IsValid( LocalPlayer() ) || !LocalPlayer():Alive() ) then return end
|
||||
|
||||
-- Try to tack it onto an exisiting ammo pickup
|
||||
if ( self.PickupHistory ) then
|
||||
|
||||
for k, v in pairs( self.PickupHistory ) do
|
||||
|
||||
if ( v.name == "#" .. itemname .. "_ammo" ) then
|
||||
|
||||
v.amount = tostring( tonumber( v.amount ) + amount )
|
||||
v.time = CurTime() - v.fadein
|
||||
return
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local pickup = AddGenericPickup( self, "#" .. itemname .. "_ammo" )
|
||||
pickup.color = Color( 180, 200, 255, 255 )
|
||||
pickup.amount = tostring( amount )
|
||||
|
||||
local w, h = surface.GetTextSize( pickup.amount )
|
||||
pickup.width = pickup.width + w + 16
|
||||
|
||||
end
|
||||
|
||||
function GM:HUDDrawPickupHistory()
|
||||
|
||||
if ( self.PickupHistory == nil ) then return end
|
||||
|
||||
local x, y = ScrW() - self.PickupHistoryWide - 20, self.PickupHistoryTop
|
||||
local tall = 0
|
||||
local wide = 0
|
||||
|
||||
for k, v in pairs( self.PickupHistory ) do
|
||||
|
||||
if ( !istable( v ) ) then
|
||||
|
||||
Msg( tostring( v ) .. "\n" )
|
||||
PrintTable( self.PickupHistory )
|
||||
self.PickupHistory[ k ] = nil
|
||||
return
|
||||
end
|
||||
|
||||
if ( v.time < CurTime() ) then
|
||||
|
||||
if ( v.y == nil ) then v.y = y end
|
||||
|
||||
v.y = ( v.y * 5 + y ) / 6
|
||||
|
||||
local delta = ( v.time + v.holdtime ) - CurTime()
|
||||
delta = delta / v.holdtime
|
||||
|
||||
local alpha = 255
|
||||
local colordelta = math.Clamp( delta, 0.6, 0.7 )
|
||||
|
||||
-- Fade in/out
|
||||
if ( delta > 1 - v.fadein ) then
|
||||
alpha = math.Clamp( ( 1.0 - delta ) * ( 255 / v.fadein ), 0, 255 )
|
||||
elseif ( delta < v.fadeout ) then
|
||||
alpha = math.Clamp( delta * ( 255 / v.fadeout ), 0, 255 )
|
||||
end
|
||||
|
||||
v.x = x + self.PickupHistoryWide - ( self.PickupHistoryWide * ( alpha / 255 ) )
|
||||
|
||||
local rx, ry, rw, rh = math.Round( v.x - 4 ), math.Round( v.y - ( v.height / 2 ) - 4 ), math.Round( self.PickupHistoryWide + 9 ), math.Round( v.height + 8 )
|
||||
local bordersize = 8
|
||||
|
||||
surface.SetTexture( self.PickupHistoryCorner )
|
||||
|
||||
surface.SetDrawColor( v.color.r, v.color.g, v.color.b, alpha )
|
||||
surface.DrawTexturedRectRotated( rx + bordersize / 2, ry + bordersize / 2, bordersize, bordersize, 0 )
|
||||
surface.DrawTexturedRectRotated( rx + bordersize / 2, ry + rh -bordersize / 2, bordersize, bordersize, 90 )
|
||||
surface.DrawRect( rx, ry + bordersize, bordersize, rh-bordersize * 2 )
|
||||
surface.DrawRect( rx + bordersize, ry, v.height - 4, rh )
|
||||
|
||||
surface.SetDrawColor( 230 * colordelta, 230 * colordelta, 230 * colordelta, alpha )
|
||||
surface.DrawTexturedRectRotated( rx + rw - bordersize / 2 , ry + rh - bordersize / 2, bordersize, bordersize, 180 )
|
||||
surface.DrawTexturedRectRotated( rx + rw - bordersize / 2 , ry + bordersize / 2, bordersize, bordersize, 270 )
|
||||
surface.DrawRect( rx + rw - bordersize, ry + bordersize, bordersize, rh-bordersize * 2 )
|
||||
surface.DrawRect( rx + bordersize + v.height - 4, ry, rw - ( v.height - 4 ) - bordersize * 2, rh )
|
||||
|
||||
draw.SimpleText( v.name, v.font, v.x + v.height + 9, ry + ( rh / 2 ) + 1, Color( 0, 0, 0, alpha * 0.5 ), TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER )
|
||||
draw.SimpleText( v.name, v.font, v.x + v.height + 8, ry + ( rh / 2 ), Color( 255, 255, 255, alpha ), TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER )
|
||||
|
||||
if ( v.amount ) then
|
||||
|
||||
draw.SimpleText( v.amount, v.font, v.x + self.PickupHistoryWide + 1, ry + ( rh / 2 ) + 1, Color( 0, 0, 0, alpha * 0.5 ), TEXT_ALIGN_RIGHT, TEXT_ALIGN_CENTER )
|
||||
draw.SimpleText( v.amount, v.font, v.x + self.PickupHistoryWide, ry + ( rh / 2 ), Color( 255, 255, 255, alpha ), TEXT_ALIGN_RIGHT, TEXT_ALIGN_CENTER )
|
||||
|
||||
end
|
||||
|
||||
y = y + ( v.height + 16 )
|
||||
tall = tall + v.height + 18
|
||||
wide = math.max( wide, v.width + v.height + 24 )
|
||||
|
||||
if ( alpha == 0 ) then self.PickupHistory[ k ] = nil end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
self.PickupHistoryTop = ( self.PickupHistoryTop * 5 + ( ScrH() * 0.75 - tall ) / 2 ) / 6
|
||||
self.PickupHistoryWide = ( self.PickupHistoryWide * 5 + wide ) / 6
|
||||
|
||||
end
|
||||
746
gamemodes/base/gamemode/cl_init.lua
Normal file
746
gamemodes/base/gamemode/cl_init.lua
Normal file
@@ -0,0 +1,746 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
include( "shared.lua" )
|
||||
include( "cl_scoreboard.lua" )
|
||||
include( "cl_targetid.lua" )
|
||||
include( "cl_hudpickup.lua" )
|
||||
include( "cl_spawnmenu.lua" )
|
||||
include( "cl_deathnotice.lua" )
|
||||
include( "cl_pickteam.lua" )
|
||||
include( "cl_voice.lua" )
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:Initialize()
|
||||
Desc: Called immediately after starting the gamemode
|
||||
-----------------------------------------------------------]]
|
||||
function GM:Initialize()
|
||||
|
||||
GAMEMODE.ShowScoreboard = false
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:InitPostEntity()
|
||||
Desc: Called as soon as all map entities have been spawned
|
||||
-----------------------------------------------------------]]
|
||||
function GM:InitPostEntity()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:Think()
|
||||
Desc: Called every frame
|
||||
-----------------------------------------------------------]]
|
||||
function GM:Think()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerBindPress()
|
||||
Desc: A player pressed a bound key - return true to override action
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerBindPress( pl, bind, down )
|
||||
|
||||
return false
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:HUDShouldDraw( name )
|
||||
Desc: return true if we should draw the named element
|
||||
-----------------------------------------------------------]]
|
||||
function GM:HUDShouldDraw( name )
|
||||
|
||||
-- Allow the weapon to override this
|
||||
local ply = LocalPlayer()
|
||||
if ( IsValid( ply ) ) then
|
||||
|
||||
local wep = ply:GetActiveWeapon()
|
||||
|
||||
if ( IsValid( wep ) ) then
|
||||
|
||||
local fShouldDraw = wep.HUDShouldDraw
|
||||
|
||||
if ( isfunction( fShouldDraw ) ) then
|
||||
|
||||
local ret = fShouldDraw( wep, name )
|
||||
if ( ret != nil ) then return ret end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:HUDPaint()
|
||||
Desc: Use this section to paint your HUD
|
||||
-----------------------------------------------------------]]
|
||||
function GM:HUDPaint()
|
||||
|
||||
hook.Run( "HUDDrawTargetID" )
|
||||
hook.Run( "HUDDrawPickupHistory" )
|
||||
hook.Run( "DrawDeathNotice", 0.85, 0.04 )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:HUDPaintBackground()
|
||||
Desc: Same as HUDPaint except drawn before
|
||||
-----------------------------------------------------------]]
|
||||
function GM:HUDPaintBackground()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:GUIMouseReleased( mousecode )
|
||||
Desc: The mouse was double clicked
|
||||
-----------------------------------------------------------]]
|
||||
function GM:GUIMouseDoublePressed( mousecode, AimVector )
|
||||
-- We don't capture double clicks by default,
|
||||
-- We just treat them as regular presses
|
||||
GAMEMODE:GUIMousePressed( mousecode, AimVector )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:ShutDown( )
|
||||
Desc: Called when the Lua system is about to shut down
|
||||
-----------------------------------------------------------]]
|
||||
function GM:ShutDown()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:RenderScreenspaceEffects( )
|
||||
Desc: Bloom etc should be drawn here (or using this hook)
|
||||
-----------------------------------------------------------]]
|
||||
function GM:RenderScreenspaceEffects()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:GetTeamColor( ent )
|
||||
Desc: Return the color for this ent's team
|
||||
This is for chat and deathnotice text
|
||||
-----------------------------------------------------------]]
|
||||
function GM:GetTeamColor( ent )
|
||||
|
||||
local team = TEAM_UNASSIGNED
|
||||
if ( ent.Team ) then team = ent:Team() end
|
||||
return GAMEMODE:GetTeamNumColor( team )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:GetTeamNumColor( num )
|
||||
Desc: returns the colour for this team num
|
||||
-----------------------------------------------------------]]
|
||||
function GM:GetTeamNumColor( num )
|
||||
|
||||
return team.GetColor( num )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:OnPlayerChat()
|
||||
Process the player's chat.. return true for no default
|
||||
-----------------------------------------------------------]]
|
||||
function GM:OnPlayerChat( player, strText, bTeamOnly, bPlayerIsDead )
|
||||
|
||||
--
|
||||
-- I've made this all look more complicated than it is. Here's the easy version
|
||||
--
|
||||
-- chat.AddText( player, color_white, ": ", strText )
|
||||
--
|
||||
|
||||
local tab = {}
|
||||
|
||||
if ( bPlayerIsDead ) then
|
||||
table.insert( tab, Color( 255, 30, 40 ) )
|
||||
table.insert( tab, "*DEAD* " )
|
||||
end
|
||||
|
||||
if ( bTeamOnly ) then
|
||||
table.insert( tab, Color( 30, 160, 40 ) )
|
||||
table.insert( tab, "(TEAM) " )
|
||||
end
|
||||
|
||||
if ( IsValid( player ) ) then
|
||||
table.insert( tab, player )
|
||||
else
|
||||
table.insert( tab, "Console" )
|
||||
end
|
||||
|
||||
local filter_context = TEXT_FILTER_GAME_CONTENT
|
||||
if ( bit.band( GetConVarNumber( "cl_chatfilters" ), 64 ) != 0 ) then filter_context = TEXT_FILTER_CHAT end
|
||||
|
||||
table.insert( tab, color_white )
|
||||
table.insert( tab, ": " .. util.FilterText( strText, filter_context, IsValid( player ) and player or nil ) )
|
||||
|
||||
chat.AddText( unpack( tab ) )
|
||||
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:OnChatTab( str )
|
||||
Desc: Tab is pressed when typing (Auto-complete names, IRC style)
|
||||
-----------------------------------------------------------]]
|
||||
function GM:OnChatTab( str )
|
||||
|
||||
str = string.TrimRight(str)
|
||||
|
||||
local LastWord
|
||||
for word in string.gmatch( str, "[^ ]+" ) do
|
||||
LastWord = word
|
||||
end
|
||||
|
||||
if ( LastWord == nil ) then return str end
|
||||
|
||||
for k, v in ipairs( player.GetAll() ) do
|
||||
|
||||
local nickname = v:Nick()
|
||||
|
||||
if ( string.len( LastWord ) < string.len( nickname ) && string.find( string.lower( nickname ), string.lower( LastWord ), 0, true ) == 1 ) then
|
||||
|
||||
str = string.sub( str, 1, ( string.len( LastWord ) * -1 ) - 1 )
|
||||
str = str .. nickname
|
||||
return str
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return str
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:StartChat( teamsay )
|
||||
Desc: Start Chat.
|
||||
|
||||
If you want to display your chat shit different here's what you'd do:
|
||||
In StartChat show your text box and return true to hide the default
|
||||
Update the text in your box with the text passed to ChatTextChanged
|
||||
Close and clear your text box when FinishChat is called.
|
||||
Return true in ChatText to not show the default chat text
|
||||
|
||||
-----------------------------------------------------------]]
|
||||
function GM:StartChat( teamsay )
|
||||
|
||||
return false
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:FinishChat()
|
||||
-----------------------------------------------------------]]
|
||||
function GM:FinishChat()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:ChatTextChanged( text)
|
||||
-----------------------------------------------------------]]
|
||||
function GM:ChatTextChanged( text )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: ChatText
|
||||
Allows override of the chat text
|
||||
-----------------------------------------------------------]]
|
||||
function GM:ChatText( playerindex, playername, text, filter )
|
||||
|
||||
if ( filter == "chat" ) then
|
||||
Msg( playername, ": ", text, "\n" )
|
||||
else
|
||||
Msg( text, "\n" )
|
||||
end
|
||||
|
||||
return false
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PostProcessPermitted( str )
|
||||
Desc: return true/false depending on whether this post process should be allowed
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PostProcessPermitted( str )
|
||||
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PostRenderVGUI( )
|
||||
Desc: Called after VGUI has been rendered
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PostRenderVGUI()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PreRender( )
|
||||
Desc: Called before all rendering
|
||||
Return true to NOT render this frame for some reason (danger!)
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PreRender()
|
||||
return false
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PostRender( )
|
||||
Desc: Called after all rendering
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PostRender()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:RenderScene( )
|
||||
Desc: Render the scene
|
||||
-----------------------------------------------------------]]
|
||||
function GM:RenderScene( origin, angle, fov )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: CalcVehicleView
|
||||
-----------------------------------------------------------]]
|
||||
function GM:CalcVehicleView( Vehicle, ply, view )
|
||||
|
||||
if ( Vehicle.GetThirdPersonMode == nil || ply:GetViewEntity() != ply ) then
|
||||
-- This shouldn't ever happen.
|
||||
return
|
||||
end
|
||||
|
||||
--
|
||||
-- If we're not in third person mode - then get outa here stalker
|
||||
--
|
||||
if ( !Vehicle:GetThirdPersonMode() ) then return view end
|
||||
|
||||
-- Don't roll the camera
|
||||
-- view.angles.roll = 0
|
||||
|
||||
local mn, mx = Vehicle:GetRenderBounds()
|
||||
local radius = ( mn - mx ):Length()
|
||||
local radius = radius + radius * Vehicle:GetCameraDistance()
|
||||
|
||||
-- Trace back from the original eye position, so we don't clip through walls/objects
|
||||
local TargetOrigin = view.origin + ( view.angles:Forward() * -radius )
|
||||
local WallOffset = 4
|
||||
|
||||
local tr = util.TraceHull( {
|
||||
start = view.origin,
|
||||
endpos = TargetOrigin,
|
||||
filter = function( e )
|
||||
local c = e:GetClass() -- Avoid contact with entities that can potentially be attached to the vehicle. Ideally, we should check if "e" is constrained to "Vehicle".
|
||||
return !c:StartsWith( "prop_physics" ) &&!c:StartsWith( "prop_dynamic" ) && !c:StartsWith( "phys_bone_follower" ) && !c:StartsWith( "prop_ragdoll" ) && !e:IsVehicle() && !c:StartsWith( "gmod_" )
|
||||
end,
|
||||
mins = Vector( -WallOffset, -WallOffset, -WallOffset ),
|
||||
maxs = Vector( WallOffset, WallOffset, WallOffset ),
|
||||
} )
|
||||
|
||||
view.origin = tr.HitPos
|
||||
view.drawviewer = true
|
||||
|
||||
--
|
||||
-- If the trace hit something, put the camera there.
|
||||
--
|
||||
if ( tr.Hit && !tr.StartSolid) then
|
||||
view.origin = view.origin + tr.HitNormal * WallOffset
|
||||
end
|
||||
|
||||
return view
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: CalcView
|
||||
Allows override of the default view
|
||||
-----------------------------------------------------------]]
|
||||
function GM:CalcView( ply, origin, angles, fov, znear, zfar )
|
||||
|
||||
local Vehicle = ply:GetVehicle()
|
||||
local Weapon = ply:GetActiveWeapon()
|
||||
|
||||
local view = {
|
||||
["origin"] = origin,
|
||||
["angles"] = angles,
|
||||
["fov"] = fov,
|
||||
["znear"] = znear,
|
||||
["zfar"] = zfar,
|
||||
["drawviewer"] = false,
|
||||
}
|
||||
|
||||
--
|
||||
-- Let the vehicle override the view and allows the vehicle view to be hooked
|
||||
--
|
||||
if ( IsValid( Vehicle ) ) then return hook.Run( "CalcVehicleView", Vehicle, ply, view ) end
|
||||
|
||||
--
|
||||
-- Let drive possibly alter the view
|
||||
--
|
||||
if ( drive.CalcView( ply, view ) ) then return view end
|
||||
|
||||
--
|
||||
-- Give the player manager a turn at altering the view
|
||||
--
|
||||
player_manager.RunClass( ply, "CalcView", view )
|
||||
|
||||
-- Give the active weapon a go at changing the view
|
||||
if ( IsValid( Weapon ) ) then
|
||||
|
||||
local func = Weapon.CalcView
|
||||
if ( func ) then
|
||||
local origin, angles, fov = func( Weapon, ply, Vector( view.origin ), Angle( view.angles ), view.fov ) -- Note: Constructor to copy the object so the child function can't edit it.
|
||||
view.origin, view.angles, view.fov = origin or view.origin, angles or view.angles, fov or view.fov
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return view
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- If return true: Will draw the local player
|
||||
-- If return false: Won't draw the local player
|
||||
-- If return nil: Will carry out default action
|
||||
--
|
||||
function GM:ShouldDrawLocalPlayer( ply )
|
||||
|
||||
return player_manager.RunClass( ply, "ShouldDrawLocal" )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:AdjustMouseSensitivity()
|
||||
Desc: Allows you to adjust the mouse sensitivity.
|
||||
The return is a fraction of the normal sensitivity (0.5 would be half as sensitive)
|
||||
Return -1 to not override.
|
||||
-----------------------------------------------------------]]
|
||||
function GM:AdjustMouseSensitivity( fDefault )
|
||||
|
||||
local ply = LocalPlayer()
|
||||
if ( !IsValid( ply ) ) then return -1 end
|
||||
|
||||
local wep = ply:GetActiveWeapon()
|
||||
if ( wep && wep.AdjustMouseSensitivity ) then
|
||||
return wep:AdjustMouseSensitivity()
|
||||
end
|
||||
|
||||
return -1
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:ForceDermaSkin()
|
||||
Desc: Return the name of skin this gamemode should use.
|
||||
If nil is returned the skin will use default
|
||||
-----------------------------------------------------------]]
|
||||
function GM:ForceDermaSkin()
|
||||
|
||||
--return "example"
|
||||
return nil
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PostPlayerDraw()
|
||||
Desc: The player has just been drawn.
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PostPlayerDraw( ply )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PrePlayerDraw()
|
||||
Desc: The player is just about to be drawn.
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PrePlayerDraw( ply )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:GetMotionBlurSettings()
|
||||
Desc: Allows you to edit the motion blur values
|
||||
-----------------------------------------------------------]]
|
||||
function GM:GetMotionBlurValues( x, y, fwd, spin )
|
||||
|
||||
-- fwd = 0.5 + math.sin( CurTime() * 5 ) * 0.5
|
||||
|
||||
return x, y, fwd, spin
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:InputMouseApply()
|
||||
Desc: Allows you to control how moving the mouse affects the view angles
|
||||
-----------------------------------------------------------]]
|
||||
function GM:InputMouseApply( cmd, x, y, angle )
|
||||
|
||||
--angle.roll = angle.roll + 1
|
||||
--cmd:SetViewAngles( Ang )
|
||||
--return true
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:OnAchievementAchieved()
|
||||
-----------------------------------------------------------]]
|
||||
function GM:OnAchievementAchieved( ply, achid )
|
||||
|
||||
chat.AddText( ply, Color( 230, 230, 230 ), " earned the achievement ", Color( 255, 200, 0 ), achievements.GetName( achid ) )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PreDrawSkyBox()
|
||||
Desc: Called before drawing the skybox. Return true to not draw the skybox.
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PreDrawSkyBox()
|
||||
|
||||
--return true
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PostDrawSkyBox()
|
||||
Desc: Called after drawing the skybox
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PostDrawSkyBox()
|
||||
end
|
||||
|
||||
--
|
||||
-- Name: GM:PostDraw2DSkyBox
|
||||
-- Desc: Called right after the 2D skybox has been drawn - allowing you to draw over it.
|
||||
-- Arg1:
|
||||
-- Ret1:
|
||||
--
|
||||
function GM:PostDraw2DSkyBox()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PreDrawOpaqueRenderables()
|
||||
Desc: Called before drawing opaque entities
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PreDrawOpaqueRenderables( bDrawingDepth, bDrawingSkybox )
|
||||
|
||||
-- return true
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PreDrawOpaqueRenderables()
|
||||
Desc: Called before drawing opaque entities
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PostDrawOpaqueRenderables( bDrawingDepth, bDrawingSkybox )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PreDrawOpaqueRenderables()
|
||||
Desc: Called before drawing opaque entities
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PreDrawTranslucentRenderables( bDrawingDepth, bDrawingSkybox )
|
||||
|
||||
-- return true
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PreDrawOpaqueRenderables()
|
||||
Desc: Called before drawing opaque entities
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PostDrawTranslucentRenderables( bDrawingDepth, bDrawingSkybox )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:CalcViewModelView()
|
||||
Desc: Called to set the view model's position
|
||||
-----------------------------------------------------------]]
|
||||
function GM:CalcViewModelView( Weapon, ViewModel, OldEyePos, OldEyeAng, EyePos, EyeAng )
|
||||
|
||||
if ( !IsValid( Weapon ) ) then return end
|
||||
|
||||
local vm_origin, vm_angles = EyePos, EyeAng
|
||||
|
||||
-- Controls the position of all viewmodels
|
||||
local func = Weapon.GetViewModelPosition
|
||||
if ( func ) then
|
||||
local pos, ang = func( Weapon, EyePos*1, EyeAng*1 )
|
||||
vm_origin = pos or vm_origin
|
||||
vm_angles = ang or vm_angles
|
||||
end
|
||||
|
||||
-- Controls the position of individual viewmodels
|
||||
func = Weapon.CalcViewModelView
|
||||
if ( func ) then
|
||||
local pos, ang = func( Weapon, ViewModel, OldEyePos*1, OldEyeAng*1, EyePos*1, EyeAng*1 )
|
||||
vm_origin = pos or vm_origin
|
||||
vm_angles = ang or vm_angles
|
||||
end
|
||||
|
||||
return vm_origin, vm_angles
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PreDrawViewModel()
|
||||
Desc: Called before drawing the view model
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PreDrawViewModel( ViewModel, Player, Weapon )
|
||||
|
||||
if ( !IsValid( Weapon ) ) then return false end
|
||||
|
||||
player_manager.RunClass( Player, "PreDrawViewModel", ViewModel, Weapon )
|
||||
|
||||
if ( Weapon.PreDrawViewModel == nil ) then return false end
|
||||
return Weapon:PreDrawViewModel( ViewModel, Weapon, Player )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PostDrawViewModel()
|
||||
Desc: Called after drawing the view model
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PostDrawViewModel( ViewModel, Player, Weapon )
|
||||
|
||||
if ( !IsValid( Weapon ) ) then return false end
|
||||
|
||||
if ( Weapon.UseHands || !Weapon:IsScripted() ) then
|
||||
|
||||
local hands = Player:GetHands()
|
||||
if ( IsValid( hands ) && IsValid( hands:GetParent() ) ) then
|
||||
|
||||
if ( not hook.Call( "PreDrawPlayerHands", self, hands, ViewModel, Player, Weapon ) ) then
|
||||
|
||||
if ( Weapon.ViewModelFlip ) then render.CullMode( MATERIAL_CULLMODE_CW ) end
|
||||
hands:DrawModel()
|
||||
render.CullMode( MATERIAL_CULLMODE_CCW )
|
||||
|
||||
end
|
||||
|
||||
hook.Call( "PostDrawPlayerHands", self, hands, ViewModel, Player, Weapon )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
player_manager.RunClass( Player, "PostDrawViewModel", ViewModel, Weapon )
|
||||
|
||||
if ( Weapon.PostDrawViewModel == nil ) then return false end
|
||||
return Weapon:PostDrawViewModel( ViewModel, Weapon, Player )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:DrawPhysgunBeam()
|
||||
Desc: Return false to override completely
|
||||
-----------------------------------------------------------]]
|
||||
function GM:DrawPhysgunBeam( ply, weapon, bOn, target, boneid, pos )
|
||||
|
||||
-- Do nothing
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:NetworkEntityCreated()
|
||||
Desc: Entity is created over the network
|
||||
-----------------------------------------------------------]]
|
||||
function GM:NetworkEntityCreated( ent )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:CreateMove( command )
|
||||
Desc: Allows the client to change the move commands
|
||||
before it's send to the server
|
||||
-----------------------------------------------------------]]
|
||||
function GM:CreateMove( cmd )
|
||||
|
||||
if ( drive.CreateMove( cmd ) ) then return true end
|
||||
|
||||
if ( player_manager.RunClass( LocalPlayer(), "CreateMove", cmd ) ) then return true end
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PreventScreenClicks()
|
||||
Desc: The player is hovering over a ScreenClickable world
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PreventScreenClicks( cmd )
|
||||
|
||||
--
|
||||
-- Returning true in this hook will prevent screen clicking sending IN_ATTACK
|
||||
-- commands to the weapons. We want to do this in the properties system, so
|
||||
-- that you don't fire guns when opening the properties menu. Holla!
|
||||
--
|
||||
|
||||
return false
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:GUIMousePressed( mousecode )
|
||||
Desc: The mouse has been pressed on the game screen
|
||||
-----------------------------------------------------------]]
|
||||
function GM:GUIMousePressed( mousecode, AimVector )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:GUIMouseReleased( mousecode )
|
||||
Desc: The mouse has been released on the game screen
|
||||
-----------------------------------------------------------]]
|
||||
function GM:GUIMouseReleased( mousecode, AimVector )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Player class has been changed
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerClassChanged( ply, newID )
|
||||
|
||||
-- No class is set
|
||||
if ( newID < 1 ) then return end
|
||||
|
||||
-- Invalid class ID?
|
||||
local classname = util.NetworkIDToString( newID )
|
||||
if ( !classname ) then return end
|
||||
|
||||
-- Initialize the class on client
|
||||
player_manager.SetPlayerClass( ply, classname )
|
||||
|
||||
end
|
||||
|
||||
function GM:PreDrawHUD()
|
||||
end
|
||||
|
||||
function GM:PostDrawHUD()
|
||||
end
|
||||
|
||||
function GM:DrawOverlay()
|
||||
end
|
||||
|
||||
function GM:DrawMonitors()
|
||||
end
|
||||
|
||||
function GM:PreDrawEffects()
|
||||
end
|
||||
|
||||
function GM:PostDrawEffects()
|
||||
end
|
||||
|
||||
function GM:PreDrawHalos()
|
||||
end
|
||||
|
||||
function GM:CloseDermaMenus()
|
||||
end
|
||||
|
||||
function GM:CreateClientsideRagdoll( entity, ragdoll )
|
||||
end
|
||||
|
||||
function GM:VehicleMove( ply, vehicle, mv )
|
||||
end
|
||||
75
gamemodes/base/gamemode/cl_pickteam.lua
Normal file
75
gamemodes/base/gamemode/cl_pickteam.lua
Normal file
@@ -0,0 +1,75 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:ShowTeam()
|
||||
Desc:
|
||||
-----------------------------------------------------------]]
|
||||
function GM:ShowTeam()
|
||||
|
||||
if ( IsValid( self.TeamSelectFrame ) ) then return end
|
||||
|
||||
-- Simple team selection box
|
||||
self.TeamSelectFrame = vgui.Create( "DFrame" )
|
||||
self.TeamSelectFrame:SetTitle( "Pick Team" )
|
||||
|
||||
local AllTeams = team.GetAllTeams()
|
||||
local y = 30
|
||||
for ID, TeamInfo in pairs ( AllTeams ) do
|
||||
|
||||
if ( ID != TEAM_CONNECTING && ID != TEAM_UNASSIGNED ) then
|
||||
|
||||
local Team = vgui.Create( "DButton", self.TeamSelectFrame )
|
||||
function Team.DoClick() self:HideTeam() RunConsoleCommand( "changeteam", ID ) end
|
||||
Team:SetPos( 10, y )
|
||||
Team:SetSize( 130, 20 )
|
||||
Team:SetText( TeamInfo.Name )
|
||||
|
||||
if ( IsValid( LocalPlayer() ) && LocalPlayer():Team() == ID ) then
|
||||
Team:SetEnabled( false )
|
||||
end
|
||||
|
||||
y = y + 30
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if ( GAMEMODE.AllowAutoTeam ) then
|
||||
|
||||
local Team = vgui.Create( "DButton", self.TeamSelectFrame )
|
||||
function Team.DoClick() self:HideTeam() RunConsoleCommand( "autoteam" ) end
|
||||
Team:SetPos( 10, y )
|
||||
Team:SetSize( 130, 20 )
|
||||
Team:SetText( "Auto" )
|
||||
y = y + 30
|
||||
|
||||
end
|
||||
|
||||
self.TeamSelectFrame:SetSize( 150, y )
|
||||
self.TeamSelectFrame:Center()
|
||||
self.TeamSelectFrame:MakePopup()
|
||||
self.TeamSelectFrame:SetKeyboardInputEnabled( false )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:HideTeam()
|
||||
Desc:
|
||||
-----------------------------------------------------------]]
|
||||
function GM:HideTeam()
|
||||
|
||||
if ( IsValid(self.TeamSelectFrame) ) then
|
||||
self.TeamSelectFrame:Remove()
|
||||
self.TeamSelectFrame = nil
|
||||
end
|
||||
|
||||
end
|
||||
305
gamemodes/base/gamemode/cl_scoreboard.lua
Normal file
305
gamemodes/base/gamemode/cl_scoreboard.lua
Normal file
@@ -0,0 +1,305 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
surface.CreateFont( "ScoreboardDefault", {
|
||||
font = "Helvetica",
|
||||
size = 22,
|
||||
weight = 800
|
||||
} )
|
||||
|
||||
surface.CreateFont( "ScoreboardDefaultTitle", {
|
||||
font = "Helvetica",
|
||||
size = 32,
|
||||
weight = 800
|
||||
} )
|
||||
|
||||
--
|
||||
-- This defines a new panel type for the player row. The player row is given a player
|
||||
-- and then from that point on it pretty much looks after itself. It updates player info
|
||||
-- in the think function, and removes itself when the player leaves the server.
|
||||
--
|
||||
local PLAYER_LINE = {
|
||||
Init = function( self )
|
||||
|
||||
self.AvatarButton = self:Add( "DButton" )
|
||||
self.AvatarButton:Dock( LEFT )
|
||||
self.AvatarButton:SetSize( 32, 32 )
|
||||
self.AvatarButton.DoClick = function() self.Player:ShowProfile() end
|
||||
|
||||
self.Avatar = vgui.Create( "AvatarImage", self.AvatarButton )
|
||||
self.Avatar:SetSize( 32, 32 )
|
||||
self.Avatar:SetMouseInputEnabled( false )
|
||||
|
||||
self.Name = self:Add( "DLabel" )
|
||||
self.Name:Dock( FILL )
|
||||
self.Name:SetFont( "ScoreboardDefault" )
|
||||
self.Name:SetTextColor( Color( 93, 93, 93 ) )
|
||||
self.Name:DockMargin( 8, 0, 0, 0 )
|
||||
|
||||
self.Mute = self:Add( "DImageButton" )
|
||||
self.Mute:SetSize( 32, 32 )
|
||||
self.Mute:Dock( RIGHT )
|
||||
|
||||
self.Ping = self:Add( "DLabel" )
|
||||
self.Ping:Dock( RIGHT )
|
||||
self.Ping:SetWidth( 50 )
|
||||
self.Ping:SetFont( "ScoreboardDefault" )
|
||||
self.Ping:SetTextColor( Color( 93, 93, 93 ) )
|
||||
self.Ping:SetContentAlignment( 5 )
|
||||
|
||||
self.Deaths = self:Add( "DLabel" )
|
||||
self.Deaths:Dock( RIGHT )
|
||||
self.Deaths:SetWidth( 50 )
|
||||
self.Deaths:SetFont( "ScoreboardDefault" )
|
||||
self.Deaths:SetTextColor( Color( 93, 93, 93 ) )
|
||||
self.Deaths:SetContentAlignment( 5 )
|
||||
|
||||
self.Kills = self:Add( "DLabel" )
|
||||
self.Kills:Dock( RIGHT )
|
||||
self.Kills:SetWidth( 50 )
|
||||
self.Kills:SetFont( "ScoreboardDefault" )
|
||||
self.Kills:SetTextColor( Color( 93, 93, 93 ) )
|
||||
self.Kills:SetContentAlignment( 5 )
|
||||
|
||||
self:Dock( TOP )
|
||||
self:DockPadding( 3, 3, 3, 3 )
|
||||
self:SetHeight( 32 + 3 * 2 )
|
||||
self:DockMargin( 2, 0, 2, 2 )
|
||||
|
||||
end,
|
||||
|
||||
Setup = function( self, pl )
|
||||
|
||||
self.Player = pl
|
||||
|
||||
self.Avatar:SetPlayer( pl )
|
||||
|
||||
self:Think( self )
|
||||
|
||||
--local friend = self.Player:GetFriendStatus()
|
||||
--MsgN( pl, " Friend: ", friend )
|
||||
|
||||
end,
|
||||
|
||||
Think = function( self )
|
||||
|
||||
if ( !IsValid( self.Player ) ) then
|
||||
self:SetZPos( 9999 ) -- Causes a rebuild
|
||||
self:Remove()
|
||||
return
|
||||
end
|
||||
|
||||
if ( self.PName == nil || self.PName != self.Player:Nick() ) then
|
||||
self.PName = self.Player:Nick()
|
||||
self.Name:SetText( self.PName )
|
||||
end
|
||||
|
||||
if ( self.NumKills == nil || self.NumKills != self.Player:Frags() ) then
|
||||
self.NumKills = self.Player:Frags()
|
||||
self.Kills:SetText( self.NumKills )
|
||||
end
|
||||
|
||||
if ( self.NumDeaths == nil || self.NumDeaths != self.Player:Deaths() ) then
|
||||
self.NumDeaths = self.Player:Deaths()
|
||||
self.Deaths:SetText( self.NumDeaths )
|
||||
end
|
||||
|
||||
if ( self.NumPing == nil || self.NumPing != self.Player:Ping() ) then
|
||||
self.NumPing = self.Player:Ping()
|
||||
self.Ping:SetText( self.NumPing )
|
||||
end
|
||||
|
||||
--
|
||||
-- Change the icon of the mute button based on state
|
||||
--
|
||||
if ( self.Muted == nil || self.Muted != self.Player:IsMuted() ) then
|
||||
|
||||
self.Muted = self.Player:IsMuted()
|
||||
if ( self.Muted ) then
|
||||
self.Mute:SetImage( "icon32/muted.png" )
|
||||
else
|
||||
self.Mute:SetImage( "icon32/unmuted.png" )
|
||||
end
|
||||
|
||||
self.Mute.DoClick = function( s ) self.Player:SetMuted( !self.Muted ) end
|
||||
self.Mute.OnMouseWheeled = function( s, delta )
|
||||
self.Player:SetVoiceVolumeScale( self.Player:GetVoiceVolumeScale() + ( delta / 100 * 5 ) )
|
||||
s.LastTick = CurTime()
|
||||
end
|
||||
|
||||
self.Mute.PaintOver = function( s, w, h )
|
||||
if ( !IsValid( self.Player ) ) then return end
|
||||
|
||||
local a = 255 - math.Clamp( CurTime() - ( s.LastTick or 0 ), 0, 3 ) * 255
|
||||
if ( a <= 0 ) then return end
|
||||
|
||||
draw.RoundedBox( 4, 0, 0, w, h, Color( 0, 0, 0, a * 0.75 ) )
|
||||
draw.SimpleText( math.ceil( self.Player:GetVoiceVolumeScale() * 100 ) .. "%", "DermaDefaultBold", w / 2, h / 2, Color( 255, 255, 255, a ), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Connecting players go at the very bottom
|
||||
--
|
||||
if ( self.Player:Team() == TEAM_CONNECTING ) then
|
||||
self:SetZPos( 2000 + self.Player:EntIndex() )
|
||||
return
|
||||
end
|
||||
|
||||
--
|
||||
-- This is what sorts the list. The panels are docked in the z order,
|
||||
-- so if we set the z order according to kills they'll be ordered that way!
|
||||
-- Careful though, it's a signed short internally, so needs to range between -32,768k and +32,767
|
||||
--
|
||||
self:SetZPos( ( self.NumKills * -50 ) + self.NumDeaths + self.Player:EntIndex() )
|
||||
|
||||
end,
|
||||
|
||||
Paint = function( self, w, h )
|
||||
|
||||
if ( !IsValid( self.Player ) ) then
|
||||
return
|
||||
end
|
||||
|
||||
--
|
||||
-- We draw our background a different colour based on the status of the player
|
||||
--
|
||||
|
||||
if ( self.Player:Team() == TEAM_CONNECTING ) then
|
||||
draw.RoundedBox( 4, 0, 0, w, h, Color( 200, 200, 200, 200 ) )
|
||||
return
|
||||
end
|
||||
|
||||
if ( !self.Player:Alive() ) then
|
||||
draw.RoundedBox( 4, 0, 0, w, h, Color( 230, 200, 200, 255 ) )
|
||||
return
|
||||
end
|
||||
|
||||
if ( self.Player:IsAdmin() ) then
|
||||
draw.RoundedBox( 4, 0, 0, w, h, Color( 230, 255, 230, 255 ) )
|
||||
return
|
||||
end
|
||||
|
||||
draw.RoundedBox( 4, 0, 0, w, h, Color( 230, 230, 230, 255 ) )
|
||||
|
||||
end
|
||||
}
|
||||
|
||||
--
|
||||
-- Convert it from a normal table into a Panel Table based on DPanel
|
||||
--
|
||||
PLAYER_LINE = vgui.RegisterTable( PLAYER_LINE, "DPanel" )
|
||||
|
||||
--
|
||||
-- Here we define a new panel table for the scoreboard. It basically consists
|
||||
-- of a header and a scrollpanel - into which the player lines are placed.
|
||||
--
|
||||
local SCORE_BOARD = {
|
||||
Init = function( self )
|
||||
|
||||
self.Header = self:Add( "Panel" )
|
||||
self.Header:Dock( TOP )
|
||||
self.Header:SetHeight( 100 )
|
||||
|
||||
self.Name = self.Header:Add( "DLabel" )
|
||||
self.Name:SetFont( "ScoreboardDefaultTitle" )
|
||||
self.Name:SetTextColor( color_white )
|
||||
self.Name:Dock( TOP )
|
||||
self.Name:SetHeight( 40 )
|
||||
self.Name:SetContentAlignment( 5 )
|
||||
self.Name:SetExpensiveShadow( 2, Color( 0, 0, 0, 200 ) )
|
||||
|
||||
--self.NumPlayers = self.Header:Add( "DLabel" )
|
||||
--self.NumPlayers:SetFont( "ScoreboardDefault" )
|
||||
--self.NumPlayers:SetTextColor( color_white )
|
||||
--self.NumPlayers:SetPos( 0, 100 - 30 )
|
||||
--self.NumPlayers:SetSize( 300, 30 )
|
||||
--self.NumPlayers:SetContentAlignment( 4 )
|
||||
|
||||
self.Scores = self:Add( "DScrollPanel" )
|
||||
self.Scores:Dock( FILL )
|
||||
|
||||
end,
|
||||
|
||||
PerformLayout = function( self )
|
||||
|
||||
self:SetSize( 700, ScrH() - 200 )
|
||||
self:SetPos( ScrW() / 2 - 350, 100 )
|
||||
|
||||
end,
|
||||
|
||||
Paint = function( self, w, h )
|
||||
|
||||
--draw.RoundedBox( 4, 0, 0, w, h, Color( 0, 0, 0, 200 ) )
|
||||
|
||||
end,
|
||||
|
||||
Think = function( self, w, h )
|
||||
|
||||
self.Name:SetText( GetHostName() )
|
||||
|
||||
--
|
||||
-- Loop through each player, and if one doesn't have a score entry - create it.
|
||||
--
|
||||
|
||||
for id, pl in ipairs( player.GetAll() ) do
|
||||
|
||||
if ( IsValid( pl.ScoreEntry ) ) then continue end
|
||||
|
||||
pl.ScoreEntry = vgui.CreateFromTable( PLAYER_LINE, pl.ScoreEntry )
|
||||
pl.ScoreEntry:Setup( pl )
|
||||
|
||||
self.Scores:AddItem( pl.ScoreEntry )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
}
|
||||
|
||||
SCORE_BOARD = vgui.RegisterTable( SCORE_BOARD, "EditablePanel" )
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:ScoreboardShow( )
|
||||
Desc: Sets the scoreboard to visible
|
||||
-----------------------------------------------------------]]
|
||||
function GM:ScoreboardShow()
|
||||
|
||||
if ( !IsValid( g_Scoreboard ) ) then
|
||||
g_Scoreboard = vgui.CreateFromTable( SCORE_BOARD )
|
||||
end
|
||||
|
||||
if ( IsValid( g_Scoreboard ) ) then
|
||||
g_Scoreboard:Show()
|
||||
g_Scoreboard:MakePopup()
|
||||
g_Scoreboard:SetKeyboardInputEnabled( false )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:ScoreboardHide( )
|
||||
Desc: Hides the scoreboard
|
||||
-----------------------------------------------------------]]
|
||||
function GM:ScoreboardHide()
|
||||
|
||||
if ( IsValid( g_Scoreboard ) ) then
|
||||
g_Scoreboard:Hide()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:HUDDrawScoreBoard( )
|
||||
Desc: If you prefer to draw your scoreboard the stupid way (without vgui)
|
||||
-----------------------------------------------------------]]
|
||||
function GM:HUDDrawScoreBoard()
|
||||
end
|
||||
46
gamemodes/base/gamemode/cl_spawnmenu.lua
Normal file
46
gamemodes/base/gamemode/cl_spawnmenu.lua
Normal file
@@ -0,0 +1,46 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Spawn Menu
|
||||
-----------------------------------------------------------]]
|
||||
function GM:OnSpawnMenuOpen()
|
||||
end
|
||||
|
||||
function GM:OnSpawnMenuClose()
|
||||
end
|
||||
|
||||
concommand.Add( "+menu", function()
|
||||
hook.Run( "OnSpawnMenuOpen" )
|
||||
end, nil, "Opens the spawnmenu", FCVAR_DONTRECORD )
|
||||
|
||||
concommand.Add( "-menu", function()
|
||||
if ( input.IsKeyTrapping() ) then return end
|
||||
hook.Run( "OnSpawnMenuClose" )
|
||||
end, nil, "Closes the spawnmenu", FCVAR_DONTRECORD )
|
||||
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Context Menu
|
||||
-----------------------------------------------------------]]
|
||||
function GM:OnContextMenuOpen()
|
||||
end
|
||||
|
||||
function GM:OnContextMenuClose()
|
||||
end
|
||||
|
||||
concommand.Add( "+menu_context", function()
|
||||
hook.Run( "OnContextMenuOpen" )
|
||||
end, nil, "Opens the context menu", FCVAR_DONTRECORD )
|
||||
|
||||
concommand.Add( "-menu_context", function()
|
||||
if ( input.IsKeyTrapping() ) then return end
|
||||
hook.Run( "OnContextMenuClose" )
|
||||
end, nil, "Closes the context menu", FCVAR_DONTRECORD )
|
||||
70
gamemodes/base/gamemode/cl_targetid.lua
Normal file
70
gamemodes/base/gamemode/cl_targetid.lua
Normal file
@@ -0,0 +1,70 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:HUDDrawTargetID( )
|
||||
Desc: Draw the target id (the name of the player you're currently looking at)
|
||||
-----------------------------------------------------------]]
|
||||
function GM:HUDDrawTargetID()
|
||||
|
||||
local tr = util.GetPlayerTrace( LocalPlayer() )
|
||||
local trace = util.TraceLine( tr )
|
||||
if ( !trace.Hit ) then return end
|
||||
if ( !trace.HitNonWorld ) then return end
|
||||
|
||||
local text = "ERROR"
|
||||
local font = "TargetID"
|
||||
|
||||
if ( trace.Entity:IsPlayer() ) then
|
||||
text = trace.Entity:Nick()
|
||||
else
|
||||
--text = trace.Entity:GetClass()
|
||||
return
|
||||
end
|
||||
|
||||
surface.SetFont( font )
|
||||
local w, h = surface.GetTextSize( text )
|
||||
|
||||
local MouseX, MouseY = input.GetCursorPos()
|
||||
|
||||
if ( MouseX == 0 && MouseY == 0 || !vgui.CursorVisible() ) then
|
||||
|
||||
MouseX = ScrW() / 2
|
||||
MouseY = ScrH() / 2
|
||||
|
||||
end
|
||||
|
||||
local x = MouseX
|
||||
local y = MouseY
|
||||
|
||||
x = x - w / 2
|
||||
y = y + 30
|
||||
|
||||
-- The fonts internal drop shadow looks lousy with AA on
|
||||
draw.SimpleText( text, font, x + 1, y + 1, Color( 0, 0, 0, 120 ) )
|
||||
draw.SimpleText( text, font, x + 2, y + 2, Color( 0, 0, 0, 50 ) )
|
||||
draw.SimpleText( text, font, x, y, self:GetTeamColor( trace.Entity ) )
|
||||
|
||||
y = y + h + 5
|
||||
|
||||
-- Draw the health
|
||||
text = trace.Entity:Health() .. "%"
|
||||
font = "TargetIDSmall"
|
||||
|
||||
surface.SetFont( font )
|
||||
w, h = surface.GetTextSize( text )
|
||||
x = MouseX - w / 2
|
||||
|
||||
draw.SimpleText( text, font, x + 1, y + 1, Color( 0, 0, 0, 120 ) )
|
||||
draw.SimpleText( text, font, x + 2, y + 2, Color( 0, 0, 0, 50 ) )
|
||||
draw.SimpleText( text, font, x, y, self:GetTeamColor( trace.Entity ) )
|
||||
|
||||
end
|
||||
154
gamemodes/base/gamemode/cl_voice.lua
Normal file
154
gamemodes/base/gamemode/cl_voice.lua
Normal file
@@ -0,0 +1,154 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
local PANEL = {}
|
||||
local PlayerVoicePanels = {}
|
||||
|
||||
function PANEL:Init()
|
||||
|
||||
self.LabelName = vgui.Create( "DLabel", self )
|
||||
self.LabelName:SetFont( "GModNotify" )
|
||||
self.LabelName:Dock( FILL )
|
||||
self.LabelName:DockMargin( 8, 0, 0, 0 )
|
||||
self.LabelName:SetTextColor( color_white )
|
||||
|
||||
self.Avatar = vgui.Create( "AvatarImage", self )
|
||||
self.Avatar:Dock( LEFT )
|
||||
self.Avatar:SetSize( 32, 32 )
|
||||
|
||||
self.Color = color_transparent
|
||||
|
||||
self:SetSize( 250, 32 + 8 )
|
||||
self:DockPadding( 4, 4, 4, 4 )
|
||||
self:DockMargin( 2, 2, 2, 2 )
|
||||
self:Dock( BOTTOM )
|
||||
|
||||
end
|
||||
|
||||
function PANEL:Setup( ply )
|
||||
|
||||
self.ply = ply
|
||||
self.LabelName:SetText( ply:Nick() )
|
||||
self.Avatar:SetPlayer( ply )
|
||||
|
||||
self.Color = team.GetColor( ply:Team() )
|
||||
|
||||
self:InvalidateLayout()
|
||||
|
||||
end
|
||||
|
||||
function PANEL:Paint( w, h )
|
||||
|
||||
if ( !IsValid( self.ply ) ) then return end
|
||||
draw.RoundedBox( 4, 0, 0, w, h, Color( 0, self.ply:VoiceVolume() * 255, 0, 240 ) )
|
||||
|
||||
end
|
||||
|
||||
function PANEL:Think()
|
||||
|
||||
if ( IsValid( self.ply ) ) then
|
||||
self.LabelName:SetText( self.ply:Nick() )
|
||||
end
|
||||
|
||||
if ( self.fadeAnim ) then
|
||||
self.fadeAnim:Run()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function PANEL:FadeOut( anim, delta, data )
|
||||
|
||||
if ( anim.Finished ) then
|
||||
|
||||
if ( IsValid( PlayerVoicePanels[ self.ply ] ) ) then
|
||||
PlayerVoicePanels[ self.ply ]:Remove()
|
||||
PlayerVoicePanels[ self.ply ] = nil
|
||||
return
|
||||
end
|
||||
|
||||
return end
|
||||
|
||||
self:SetAlpha( 255 - ( 255 * delta ) )
|
||||
|
||||
end
|
||||
|
||||
derma.DefineControl( "VoiceNotify", "", PANEL, "DPanel" )
|
||||
|
||||
|
||||
|
||||
function GM:PlayerStartVoice( ply )
|
||||
|
||||
if ( !IsValid( g_VoicePanelList ) ) then return end
|
||||
|
||||
-- There'd be an exta one if voice_loopback is on, so remove it.
|
||||
GAMEMODE:PlayerEndVoice( ply )
|
||||
|
||||
|
||||
if ( IsValid( PlayerVoicePanels[ ply ] ) ) then
|
||||
|
||||
if ( PlayerVoicePanels[ ply ].fadeAnim ) then
|
||||
PlayerVoicePanels[ ply ].fadeAnim:Stop()
|
||||
PlayerVoicePanels[ ply ].fadeAnim = nil
|
||||
end
|
||||
|
||||
PlayerVoicePanels[ ply ]:SetAlpha( 255 )
|
||||
|
||||
return
|
||||
|
||||
end
|
||||
|
||||
if ( !IsValid( ply ) ) then return end
|
||||
|
||||
local pnl = g_VoicePanelList:Add( "VoiceNotify" )
|
||||
pnl:Setup( ply )
|
||||
|
||||
PlayerVoicePanels[ ply ] = pnl
|
||||
|
||||
end
|
||||
|
||||
local function VoiceClean()
|
||||
|
||||
for k, v in pairs( PlayerVoicePanels ) do
|
||||
|
||||
if ( !IsValid( k ) ) then
|
||||
GAMEMODE:PlayerEndVoice( k )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
timer.Create( "VoiceClean", 10, 0, VoiceClean )
|
||||
|
||||
function GM:PlayerEndVoice( ply )
|
||||
|
||||
if ( IsValid( PlayerVoicePanels[ ply ] ) ) then
|
||||
|
||||
if ( PlayerVoicePanels[ ply ].fadeAnim ) then return end
|
||||
|
||||
PlayerVoicePanels[ ply ].fadeAnim = Derma_Anim( "FadeOut", PlayerVoicePanels[ ply ], PlayerVoicePanels[ ply ].FadeOut )
|
||||
PlayerVoicePanels[ ply ].fadeAnim:Start( 2 )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function CreateVoiceVGUI()
|
||||
|
||||
g_VoicePanelList = vgui.Create( "DPanel" )
|
||||
|
||||
g_VoicePanelList:ParentToHUD()
|
||||
g_VoicePanelList:SetPos( ScrW() - 300, 100 )
|
||||
g_VoicePanelList:SetSize( 250, ScrH() - 200 )
|
||||
g_VoicePanelList:SetPaintBackground( false )
|
||||
|
||||
end
|
||||
|
||||
hook.Add( "InitPostEntity", "CreateVoiceVGUI", CreateVoiceVGUI )
|
||||
46
gamemodes/base/gamemode/gravitygun.lua
Normal file
46
gamemodes/base/gamemode/gravitygun.lua
Normal file
@@ -0,0 +1,46 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:GravGunPunt()
|
||||
Desc: We're about to punt an entity (primary fire).
|
||||
Return true if we're allowed to.
|
||||
-----------------------------------------------------------]]
|
||||
function GM:GravGunPunt( ply, ent )
|
||||
return true
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:GravGunPickupAllowed()
|
||||
Desc: Return true if we're allowed to pickup entity
|
||||
-----------------------------------------------------------]]
|
||||
function GM:GravGunPickupAllowed( ply, ent )
|
||||
return true
|
||||
end
|
||||
|
||||
if ( SERVER ) then
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:GravGunOnPickedUp()
|
||||
Desc: The entity has been picked up
|
||||
-----------------------------------------------------------]]
|
||||
function GM:GravGunOnPickedUp( ply, ent )
|
||||
end
|
||||
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:GravGunOnDropped()
|
||||
Desc: The entity has been dropped
|
||||
-----------------------------------------------------------]]
|
||||
function GM:GravGunOnDropped( ply, ent )
|
||||
end
|
||||
|
||||
end
|
||||
190
gamemodes/base/gamemode/init.lua
Normal file
190
gamemodes/base/gamemode/init.lua
Normal file
@@ -0,0 +1,190 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
include( 'shared.lua' )
|
||||
include( 'player.lua' )
|
||||
include( 'npc.lua' )
|
||||
include( 'variable_edit.lua' )
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:Initialize()
|
||||
Desc: Called immediately after starting the gamemode
|
||||
-----------------------------------------------------------]]
|
||||
function GM:Initialize()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:InitPostEntity()
|
||||
Desc: Called as soon as all map entities have been spawned
|
||||
-----------------------------------------------------------]]
|
||||
function GM:InitPostEntity()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:Think()
|
||||
Desc: Called every frame
|
||||
-----------------------------------------------------------]]
|
||||
function GM:Think()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:ShutDown()
|
||||
Desc: Called when the Lua system is about to shut down
|
||||
-----------------------------------------------------------]]
|
||||
function GM:ShutDown()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:DoPlayerDeath( )
|
||||
Desc: Carries out actions when the player dies
|
||||
-----------------------------------------------------------]]
|
||||
function GM:DoPlayerDeath( ply, attacker, dmginfo )
|
||||
|
||||
if ( !dmginfo:IsDamageType( DMG_REMOVENORAGDOLL ) ) then
|
||||
ply:CreateRagdoll()
|
||||
end
|
||||
|
||||
ply:AddDeaths( 1 )
|
||||
|
||||
if ( attacker:IsValid() && attacker:IsPlayer() ) then
|
||||
|
||||
if ( attacker == ply ) then
|
||||
attacker:AddFrags( -1 )
|
||||
else
|
||||
attacker:AddFrags( 1 )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerShouldTakeDamage
|
||||
Return true if this player should take damage from this attacker
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerShouldTakeDamage( ply, attacker )
|
||||
return true
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:EntityTakeDamage( ent, info )
|
||||
Desc: The entity has received damage
|
||||
-----------------------------------------------------------]]
|
||||
function GM:EntityTakeDamage( ent, info )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerHurt( )
|
||||
Desc: Called when a player is hurt.
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerHurt( player, attacker, healthleft, healthtaken )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:CreateEntityRagdoll( entity, ragdoll )
|
||||
Desc: A ragdoll of an entity has been created
|
||||
-----------------------------------------------------------]]
|
||||
function GM:CreateEntityRagdoll( entity, ragdoll )
|
||||
end
|
||||
|
||||
-- Set the ServerName every 30 seconds in case it changes..
|
||||
-- This is for backwards compatibility only - client can now use GetHostName()
|
||||
local function HostnameThink()
|
||||
|
||||
SetGlobalString( "ServerName", GetHostName() )
|
||||
|
||||
end
|
||||
|
||||
timer.Create( "HostnameThink", 30, 0, HostnameThink )
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Show the default team selection screen
|
||||
-----------------------------------------------------------]]
|
||||
function GM:ShowTeam( ply )
|
||||
|
||||
if ( !GAMEMODE.TeamBased ) then return end
|
||||
|
||||
local TimeBetweenSwitches = GAMEMODE.SecondsBetweenTeamSwitches or 10
|
||||
if ( ply.LastTeamSwitch && RealTime() - ply.LastTeamSwitch < TimeBetweenSwitches ) then
|
||||
ply.LastTeamSwitch = ply.LastTeamSwitch + 1
|
||||
ply:ChatPrint( Format( "Please wait %i more seconds before trying to change team again", ( TimeBetweenSwitches - ( RealTime() - ply.LastTeamSwitch ) ) + 1 ) )
|
||||
return
|
||||
end
|
||||
|
||||
-- For clientside see cl_pickteam.lua
|
||||
ply:SendLua( "GAMEMODE:ShowTeam()" )
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- CheckPassword( steamid, networkid, server_password, password, name )
|
||||
--
|
||||
-- Called every time a non-localhost player joins the server. steamid is their 64bit
|
||||
-- steamid. Return false and a reason to reject their join. Return true to allow
|
||||
-- them to join.
|
||||
--
|
||||
function GM:CheckPassword( steamid, networkid, server_password, password, name )
|
||||
|
||||
-- The server has sv_password set
|
||||
if ( server_password != "" ) then
|
||||
|
||||
-- The joining clients password doesn't match sv_password
|
||||
if ( server_password != password ) then
|
||||
return false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Returning true means they're allowed to join the server
|
||||
--
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:FinishMove( player, movedata )
|
||||
-----------------------------------------------------------]]
|
||||
function GM:VehicleMove( ply, vehicle, mv )
|
||||
|
||||
--
|
||||
-- On duck toggle third person view
|
||||
--
|
||||
if ( mv:KeyPressed( IN_DUCK ) && vehicle.SetThirdPersonMode ) then
|
||||
vehicle:SetThirdPersonMode( !vehicle:GetThirdPersonMode() )
|
||||
end
|
||||
|
||||
--
|
||||
-- Adjust the camera distance with the mouse wheel
|
||||
--
|
||||
local iWheel = ply:GetCurrentCommand():GetMouseWheel()
|
||||
if ( iWheel != 0 && vehicle.SetCameraDistance ) then
|
||||
-- The distance is a multiplier
|
||||
-- Actual camera distance = ( renderradius + renderradius * dist )
|
||||
-- so -1 will be zero.. clamp it there.
|
||||
local newdist = math.Clamp( vehicle:GetCameraDistance() - iWheel * 0.03 * ( 1.1 + vehicle:GetCameraDistance() ), -1, 10 )
|
||||
vehicle:SetCameraDistance( newdist )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PreUndo( undo )
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PreUndo( undo )
|
||||
return true
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PreUndo( undo )
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PostUndo( undo, count )
|
||||
end
|
||||
211
gamemodes/base/gamemode/npc.lua
Normal file
211
gamemodes/base/gamemode/npc.lua
Normal file
@@ -0,0 +1,211 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
-- Backwards compatibility with addons
|
||||
util.AddNetworkString( "PlayerKilledNPC" )
|
||||
util.AddNetworkString( "NPCKilledNPC" )
|
||||
util.AddNetworkString( "PlayerKilled" )
|
||||
util.AddNetworkString( "PlayerKilledSelf" )
|
||||
util.AddNetworkString( "PlayerKilledByPlayer" )
|
||||
|
||||
-- New way
|
||||
util.AddNetworkString( "DeathNoticeEvent" )
|
||||
|
||||
DEATH_NOTICE_FRIENDLY_VICTIM = 1
|
||||
DEATH_NOTICE_FRIENDLY_ATTACKER = 2
|
||||
--DEATH_NOTICE_HEADSHOT = 4
|
||||
--DEATH_NOTICE_PENETRATION = 8
|
||||
function GM:SendDeathNotice( attacker, inflictor, victim, flags )
|
||||
|
||||
net.Start( "DeathNoticeEvent" )
|
||||
|
||||
if ( !attacker ) then
|
||||
net.WriteUInt( 0, 2 )
|
||||
elseif ( isstring( attacker ) ) then
|
||||
net.WriteUInt( 1, 2 )
|
||||
net.WriteString( attacker )
|
||||
elseif ( IsValid( attacker ) ) then
|
||||
net.WriteUInt( 2, 2 )
|
||||
net.WriteEntity( attacker )
|
||||
end
|
||||
|
||||
net.WriteString( inflictor )
|
||||
|
||||
if ( !victim ) then
|
||||
net.WriteUInt( 0, 2 )
|
||||
elseif ( isstring( victim ) ) then
|
||||
net.WriteUInt( 1, 2 )
|
||||
net.WriteString( victim )
|
||||
elseif ( IsValid( victim ) ) then
|
||||
net.WriteUInt( 2, 2 )
|
||||
net.WriteEntity( victim )
|
||||
end
|
||||
|
||||
net.WriteUInt( flags, 8 )
|
||||
|
||||
net.Broadcast()
|
||||
|
||||
end
|
||||
|
||||
function GM:GetDeathNoticeEntityName( ent )
|
||||
|
||||
-- Some specific HL2 NPCs, just for fun
|
||||
-- TODO: Localization strings?
|
||||
if ( ent:GetClass() == "npc_citizen" ) then
|
||||
if ( ent:GetName() == "griggs" ) then return "Griggs" end
|
||||
if ( ent:GetName() == "sheckley" ) then return "Sheckley" end
|
||||
if ( ent:GetName() == "tobias" ) then return "Laszlo" end
|
||||
if ( ent:GetName() == "stanley" ) then return "Sandy" end
|
||||
end
|
||||
|
||||
-- Custom vehicle and NPC names from spawnmenu
|
||||
if ( ent:IsVehicle() and ent.VehicleTable and ent.VehicleTable.Name ) then
|
||||
return ent.VehicleTable.Name
|
||||
end
|
||||
if ( ent:IsNPC() and ent.NPCTable and ent.NPCTable.Name ) then
|
||||
return ent.NPCTable.Name
|
||||
end
|
||||
|
||||
-- Map spawned Odessa or Rebels, etc..
|
||||
for unique_class, NPC in pairs( list.Get( "NPC" ) ) do
|
||||
if ( unique_class == NPC.Class or ent:GetClass() != NPC.Class ) then continue end
|
||||
|
||||
local allGood = true
|
||||
if ( NPC.Model and ent:GetModel() != NPC.Model ) then
|
||||
allGood = false
|
||||
end
|
||||
|
||||
if ( NPC.Skin and ent:GetSkin() != NPC.Skin ) then
|
||||
allGood = false
|
||||
end
|
||||
|
||||
-- For Rebels, etc.
|
||||
if ( NPC.KeyValues ) then
|
||||
for k, v in pairs( NPC.KeyValues ) do
|
||||
local kL = k:lower()
|
||||
if ( kL != "squadname" and kL != "numgrenades" and ent:GetInternalVariable( k ) != v ) then
|
||||
allGood = false
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- They get unset often :(
|
||||
--if ( NPC.SpawnFlags and ent:HasSpawnFlags( NPC.SpawnFlags ) ) then allGood = false end
|
||||
end
|
||||
|
||||
-- Medics, ew..
|
||||
if ( unique_class == "Medic" and !ent:HasSpawnFlags( SF_CITIZEN_MEDIC ) ) then allGood = false end
|
||||
if ( unique_class == "Rebel" and ent:HasSpawnFlags( SF_CITIZEN_MEDIC ) ) then allGood = false end
|
||||
|
||||
if ( allGood ) then return NPC.Name end
|
||||
end
|
||||
|
||||
-- Unfortunately the code above still doesn't work for Antlion Workers, because they change their classname..
|
||||
if ( ent:GetClass() == "npc_antlion" and ent:GetModel() == "models/antlion_worker.mdl" ) then
|
||||
return list.Get( "NPC" )[ "npc_antlion_worker" ].Name
|
||||
end
|
||||
|
||||
-- Fallback to old behavior
|
||||
return "#" .. ent:GetClass()
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:OnNPCKilled( entity, attacker, inflictor )
|
||||
Desc: The NPC has died
|
||||
-----------------------------------------------------------]]
|
||||
function GM:OnNPCKilled( ent, attacker, inflictor )
|
||||
|
||||
-- Don't spam the killfeed with scripted stuff
|
||||
if ( ent:GetClass() == "npc_bullseye" or ent:GetClass() == "npc_launcher" ) then return end
|
||||
|
||||
-- If killed by trigger_hurt, act as if NPC killed itself
|
||||
if ( IsValid( attacker ) and attacker:GetClass() == "trigger_hurt" ) then attacker = ent end
|
||||
|
||||
-- NPC got run over..
|
||||
if ( IsValid( attacker ) and attacker:IsVehicle() and IsValid( attacker:GetDriver() ) ) then
|
||||
attacker = attacker:GetDriver()
|
||||
end
|
||||
|
||||
if ( !IsValid( inflictor ) and IsValid( attacker ) ) then
|
||||
inflictor = attacker
|
||||
end
|
||||
|
||||
-- Convert the inflictor to the weapon that they're holding if we can.
|
||||
if ( IsValid( inflictor ) and attacker == inflictor and ( inflictor:IsPlayer() or inflictor:IsNPC() ) ) then
|
||||
|
||||
inflictor = inflictor:GetActiveWeapon()
|
||||
if ( !IsValid( attacker ) ) then inflictor = attacker end
|
||||
|
||||
end
|
||||
|
||||
local InflictorClass = "worldspawn"
|
||||
local AttackerClass = game.GetWorld()
|
||||
|
||||
if ( IsValid( inflictor ) ) then InflictorClass = inflictor:GetClass() end
|
||||
if ( IsValid( attacker ) ) then
|
||||
|
||||
AttackerClass = attacker
|
||||
|
||||
-- If there is no valid inflictor, use the attacker (i.e. manhacks)
|
||||
if ( !IsValid( inflictor ) ) then InflictorClass = attacker:GetClass() end
|
||||
|
||||
if ( attacker:IsPlayer() ) then
|
||||
|
||||
local flags = 0
|
||||
if ( ent:IsNPC() and ent:Disposition( attacker ) != D_HT ) then flags = flags + DEATH_NOTICE_FRIENDLY_VICTIM end
|
||||
|
||||
self:SendDeathNotice( attacker, InflictorClass, self:GetDeathNoticeEntityName( ent ), flags )
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- Floor turret got knocked over
|
||||
if ( ent:GetClass() == "npc_turret_floor" ) then AttackerClass = ent end
|
||||
|
||||
-- It was NPC suicide..
|
||||
if ( ent == AttackerClass ) then InflictorClass = "suicide" end
|
||||
|
||||
local flags = 0
|
||||
if ( IsValid( Entity( 1 ) ) and ent:IsNPC() and ent:Disposition( Entity( 1 ) ) == D_LI ) then flags = flags + DEATH_NOTICE_FRIENDLY_VICTIM end
|
||||
if ( IsValid( Entity( 1 ) ) and AttackerClass:IsNPC() and AttackerClass:Disposition( Entity( 1 ) ) == D_LI ) then flags = flags + DEATH_NOTICE_FRIENDLY_ATTACKER end
|
||||
|
||||
self:SendDeathNotice( self:GetDeathNoticeEntityName( AttackerClass ), InflictorClass, self:GetDeathNoticeEntityName( ent ), flags )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:ScaleNPCDamage( ply, hitgroup, dmginfo )
|
||||
Desc: Scale the damage based on being shot in a hitbox
|
||||
-----------------------------------------------------------]]
|
||||
function GM:ScaleNPCDamage( npc, hitgroup, dmginfo )
|
||||
|
||||
-- More damage if we're shot in the head
|
||||
if ( hitgroup == HITGROUP_HEAD ) then
|
||||
|
||||
dmginfo:ScaleDamage( 2 )
|
||||
|
||||
end
|
||||
|
||||
-- Less damage if we're shot in the arms or legs
|
||||
if ( hitgroup == HITGROUP_LEFTARM or
|
||||
hitgroup == HITGROUP_RIGHTARM or
|
||||
hitgroup == HITGROUP_LEFTLEG or
|
||||
hitgroup == HITGROUP_RIGHTLEG or
|
||||
hitgroup == HITGROUP_GEAR ) then
|
||||
|
||||
dmginfo:ScaleDamage( 0.25 )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
223
gamemodes/base/gamemode/obj_player_extend.lua
Normal file
223
gamemodes/base/gamemode/obj_player_extend.lua
Normal file
@@ -0,0 +1,223 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
local meta = FindMetaTable( "Player" )
|
||||
if ( !meta ) then return end
|
||||
|
||||
-- In this file we're adding functions to the player meta table.
|
||||
-- This means you'll be able to call functions here straight from the player object
|
||||
-- You can even override already existing functions.
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: AddFrozenPhysicsObject
|
||||
Desc: For the Physgun, adds a frozen object to the player's list
|
||||
-----------------------------------------------------------]]
|
||||
function meta:AddFrozenPhysicsObject( ent, phys )
|
||||
|
||||
-- Get the player's table
|
||||
local tab = self:GetTable()
|
||||
|
||||
-- Make sure the physics objects table exists
|
||||
tab.FrozenPhysicsObjects = tab.FrozenPhysicsObjects or {}
|
||||
|
||||
-- Make a new table that contains the info
|
||||
local entry = {}
|
||||
entry.ent = ent
|
||||
entry.phys = phys
|
||||
|
||||
table.insert( tab.FrozenPhysicsObjects, entry )
|
||||
|
||||
gamemode.Call( "PlayerFrozeObject", self, ent, phys )
|
||||
|
||||
end
|
||||
|
||||
local function PlayerUnfreezeObject( ply, ent, object )
|
||||
|
||||
-- Not frozen!
|
||||
if ( object:IsMoveable() ) then return 0 end
|
||||
|
||||
-- Unfreezable means it can't be frozen or unfrozen.
|
||||
-- This prevents the player unfreezing the gmod_anchor entity.
|
||||
if ( ent:GetUnFreezable() ) then return 0 end
|
||||
|
||||
-- NOTE: IF YOU'RE MAKING SOME KIND OF PROP PROTECTOR THEN HOOK "CanPlayerUnfreeze"
|
||||
if ( !gamemode.Call( "CanPlayerUnfreeze", ply, ent, object ) ) then return 0 end
|
||||
|
||||
object:EnableMotion( true )
|
||||
object:Wake()
|
||||
|
||||
gamemode.Call( "PlayerUnfrozeObject", ply, ent, object )
|
||||
|
||||
return 1
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: UnfreezePhysicsObjects
|
||||
Desc: For the Physgun, unfreezes all frozen physics objects
|
||||
-----------------------------------------------------------]]
|
||||
function meta:PhysgunUnfreeze()
|
||||
|
||||
-- Get the player's table
|
||||
local tab = self:GetTable()
|
||||
if ( !tab.FrozenPhysicsObjects ) then return 0 end
|
||||
|
||||
-- Detect double click. Unfreeze all objects on double click.
|
||||
if ( tab.LastPhysUnfreeze && CurTime() - tab.LastPhysUnfreeze < 0.25 ) then
|
||||
return self:UnfreezePhysicsObjects()
|
||||
end
|
||||
|
||||
local tr = self:GetEyeTrace()
|
||||
if ( tr.HitNonWorld && IsValid( tr.Entity ) ) then
|
||||
|
||||
local Ents = constraint.GetAllConstrainedEntities( tr.Entity )
|
||||
local UnfrozenObjects = 0
|
||||
|
||||
for k, ent in pairs( Ents ) do
|
||||
|
||||
local objects = ent:GetPhysicsObjectCount()
|
||||
|
||||
for i = 1, objects do
|
||||
|
||||
local physobject = ent:GetPhysicsObjectNum( i - 1 )
|
||||
UnfrozenObjects = UnfrozenObjects + PlayerUnfreezeObject( self, ent, physobject )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
return UnfrozenObjects
|
||||
|
||||
end
|
||||
|
||||
tab.LastPhysUnfreeze = CurTime()
|
||||
return 0
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: UnfreezePhysicsObjects
|
||||
Desc: For the Physgun, unfreezes all frozen physics objects
|
||||
-----------------------------------------------------------]]
|
||||
function meta:UnfreezePhysicsObjects()
|
||||
|
||||
-- Get the player's table
|
||||
local tab = self:GetTable()
|
||||
|
||||
-- If the table doesn't exist then quit here
|
||||
if ( !tab.FrozenPhysicsObjects ) then return 0 end
|
||||
|
||||
local Count = 0
|
||||
|
||||
-- Loop through each table in our table
|
||||
for k, v in pairs( tab.FrozenPhysicsObjects ) do
|
||||
|
||||
-- Make sure the entity to which the physics object
|
||||
-- is attached is still valid (still exists)
|
||||
if ( isentity( v.ent ) && IsValid( v.ent ) ) then
|
||||
|
||||
-- We can't directly test to see if EnableMotion is false right now
|
||||
-- but IsMovable seems to do the job just fine.
|
||||
-- We only test so the count isn't wrong
|
||||
if ( IsValid( v.phys ) && !v.phys:IsMoveable() ) then
|
||||
|
||||
-- We need to freeze/unfreeze all physobj's in jeeps to stop it spazzing
|
||||
if ( v.ent:GetClass() == "prop_vehicle_jeep" ) then
|
||||
|
||||
-- How many physics objects we have
|
||||
local objects = v.ent:GetPhysicsObjectCount()
|
||||
|
||||
-- Loop through each one
|
||||
for i = 0, objects - 1 do
|
||||
|
||||
local physobject = v.ent:GetPhysicsObjectNum( i )
|
||||
PlayerUnfreezeObject( self, v.ent, physobject )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
Count = Count + PlayerUnfreezeObject( self, v.ent, v.phys )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- Remove the table
|
||||
tab.FrozenPhysicsObjects = nil
|
||||
|
||||
return Count
|
||||
|
||||
end
|
||||
|
||||
local g_UniqueIDTable = {}
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
This table will persist between client deaths and reconnects
|
||||
-----------------------------------------------------------]]
|
||||
function meta:UniqueIDTable( key )
|
||||
|
||||
local id = 0
|
||||
if ( SERVER ) then id = self:SteamID64() end
|
||||
|
||||
g_UniqueIDTable[ id ] = g_UniqueIDTable[ id ] or {}
|
||||
g_UniqueIDTable[ id ][ key ] = g_UniqueIDTable[ id ][ key ] or {}
|
||||
|
||||
return g_UniqueIDTable[ id ][ key ]
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Player Eye Trace
|
||||
-----------------------------------------------------------]]
|
||||
function meta:GetEyeTrace()
|
||||
if ( CLIENT ) then
|
||||
local framenum = FrameNumber()
|
||||
|
||||
-- Cache the trace results for the current frame, unless we're serverside
|
||||
-- in which case it wouldn't play well with lag compensation at all
|
||||
if ( self.LastPlayerTrace == framenum ) then
|
||||
return self.PlayerTrace
|
||||
end
|
||||
|
||||
self.LastPlayerTrace = framenum
|
||||
end
|
||||
|
||||
local tr = util.TraceLine( util.GetPlayerTrace( self ) )
|
||||
self.PlayerTrace = tr
|
||||
|
||||
return tr
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
GetEyeTraceIgnoreCursor
|
||||
Like GetEyeTrace but doesn't use the cursor aim vector..
|
||||
-----------------------------------------------------------]]
|
||||
function meta:GetEyeTraceNoCursor()
|
||||
if ( CLIENT ) then
|
||||
local framenum = FrameNumber()
|
||||
|
||||
if ( self.LastPlayerAimTrace == framenum ) then
|
||||
return self.PlayerAimTrace
|
||||
end
|
||||
|
||||
self.LastPlayerAimTrace = framenum
|
||||
end
|
||||
|
||||
local tr = util.TraceLine( util.GetPlayerTrace( self, self:EyeAngles():Forward() ) )
|
||||
self.PlayerAimTrace = tr
|
||||
|
||||
return tr
|
||||
end
|
||||
861
gamemodes/base/gamemode/player.lua
Normal file
861
gamemodes/base/gamemode/player.lua
Normal file
@@ -0,0 +1,861 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:OnPhysgunFreeze( weapon, phys, ent, player )
|
||||
Desc: The physgun wants to freeze a prop
|
||||
-----------------------------------------------------------]]
|
||||
function GM:OnPhysgunFreeze( weapon, phys, ent, ply )
|
||||
|
||||
-- Non vphysics entity, we don't know how to handle that
|
||||
if ( !IsValid( phys ) ) then return end
|
||||
|
||||
-- Object is already frozen (!?)
|
||||
if ( !phys:IsMoveable() ) then return end
|
||||
if ( ent:GetUnFreezable() ) then return end
|
||||
|
||||
phys:EnableMotion( false )
|
||||
|
||||
-- Add it to the player's frozen props
|
||||
ply:AddFrozenPhysicsObject( ent, phys )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:OnPhysgunReload( weapon, player )
|
||||
Desc: The physgun wants to freeze a prop
|
||||
-----------------------------------------------------------]]
|
||||
function GM:OnPhysgunReload( weapon, ply )
|
||||
|
||||
ply:PhysgunUnfreeze()
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerAuthed()
|
||||
Desc: Player's STEAMID has been authed
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerAuthed( ply, SteamID, UniqueID )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerCanPickupWeapon()
|
||||
Desc: Called when a player tries to pickup a weapon.
|
||||
return true to allow the pickup.
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerCanPickupWeapon( ply, entity )
|
||||
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerCanPickupItem()
|
||||
Desc: Called when a player tries to pickup an item.
|
||||
return true to allow the pickup.
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerCanPickupItem( ply, entity )
|
||||
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:CanPlayerUnfreeze()
|
||||
Desc: Can the player unfreeze this entity & physobject
|
||||
-----------------------------------------------------------]]
|
||||
function GM:CanPlayerUnfreeze( ply, entity, physobject )
|
||||
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerDisconnected()
|
||||
Desc: Player has disconnected from the server.
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerDisconnected( ply )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerSay()
|
||||
Desc: A player (or server) has used say. Return a string
|
||||
for the player to say. Return an empty string if the
|
||||
player should say nothing.
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerSay( ply, text, teamonly )
|
||||
|
||||
return text
|
||||
|
||||
end
|
||||
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerDeathThink( player )
|
||||
Desc: Called when the player is waiting to respawn
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerDeathThink( pl )
|
||||
|
||||
if ( pl.NextSpawnTime && pl.NextSpawnTime > CurTime() ) then return end
|
||||
|
||||
if ( pl:IsBot() || pl:KeyPressed( IN_ATTACK ) || pl:KeyPressed( IN_ATTACK2 ) || pl:KeyPressed( IN_JUMP ) ) then
|
||||
|
||||
pl:Spawn()
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerUse( player, entity )
|
||||
Desc: A player has attempted to use a specific entity
|
||||
Return true if the player can use it
|
||||
------------------------------------------------------------]]
|
||||
function GM:PlayerUse( ply, entity )
|
||||
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerSilentDeath()
|
||||
Desc: Called when a player dies silently
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerSilentDeath( Victim )
|
||||
|
||||
Victim.NextSpawnTime = CurTime() + 2
|
||||
Victim.DeathTime = CurTime()
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerDeath()
|
||||
Desc: Called when a player dies.
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerDeath( ply, inflictor, attacker )
|
||||
|
||||
-- Don't spawn for at least 2 seconds
|
||||
ply.NextSpawnTime = CurTime() + 2
|
||||
ply.DeathTime = CurTime()
|
||||
|
||||
if ( IsValid( attacker ) && attacker:GetClass() == "trigger_hurt" ) then attacker = ply end
|
||||
|
||||
if ( IsValid( attacker ) && attacker:IsVehicle() && IsValid( attacker:GetDriver() ) ) then
|
||||
attacker = attacker:GetDriver()
|
||||
end
|
||||
|
||||
if ( !IsValid( inflictor ) && IsValid( attacker ) ) then
|
||||
inflictor = attacker
|
||||
end
|
||||
|
||||
-- Convert the inflictor to the weapon that they're holding if we can.
|
||||
-- This can be right or wrong with NPCs since combine can be holding a
|
||||
-- pistol but kill you by hitting you with their arm.
|
||||
if ( IsValid( inflictor ) && inflictor == attacker && ( inflictor:IsPlayer() || inflictor:IsNPC() ) ) then
|
||||
|
||||
inflictor = inflictor:GetActiveWeapon()
|
||||
if ( !IsValid( inflictor ) ) then inflictor = attacker end
|
||||
|
||||
end
|
||||
|
||||
player_manager.RunClass( ply, "Death", inflictor, attacker )
|
||||
|
||||
if ( attacker == ply ) then
|
||||
|
||||
self:SendDeathNotice( nil, "suicide", ply, 0 )
|
||||
|
||||
MsgAll( attacker:Nick() .. " suicided!\n" )
|
||||
|
||||
return end
|
||||
|
||||
if ( attacker:IsPlayer() ) then
|
||||
|
||||
self:SendDeathNotice( attacker, inflictor:GetClass(), ply, 0 )
|
||||
|
||||
MsgAll( attacker:Nick() .. " killed " .. ply:Nick() .. " using " .. inflictor:GetClass() .. "\n" )
|
||||
|
||||
return end
|
||||
|
||||
local flags = 0
|
||||
if ( attacker:IsNPC() and attacker:Disposition( ply ) != D_HT ) then flags = flags + DEATH_NOTICE_FRIENDLY_ATTACKER end
|
||||
|
||||
self:SendDeathNotice( self:GetDeathNoticeEntityName( attacker ), inflictor:GetClass(), ply, 0 )
|
||||
|
||||
MsgAll( ply:Nick() .. " was killed by " .. attacker:GetClass() .. "\n" )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerInitialSpawn()
|
||||
Desc: Called just before the player's first spawn
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerInitialSpawn( pl, transiton )
|
||||
|
||||
pl:SetTeam( TEAM_UNASSIGNED )
|
||||
|
||||
if ( GAMEMODE.TeamBased ) then
|
||||
pl:ConCommand( "gm_showteam" )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerSpawnAsSpectator()
|
||||
Desc: Player spawns as a spectator
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerSpawnAsSpectator( pl )
|
||||
|
||||
pl:StripWeapons()
|
||||
|
||||
if ( pl:Team() == TEAM_UNASSIGNED ) then
|
||||
|
||||
pl:Spectate( OBS_MODE_FIXED )
|
||||
return
|
||||
|
||||
end
|
||||
|
||||
pl:SetTeam( TEAM_SPECTATOR )
|
||||
pl:Spectate( OBS_MODE_ROAMING )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerSpawn()
|
||||
Desc: Called when a player spawns
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerSpawn( pl, transiton )
|
||||
|
||||
--
|
||||
-- If the player doesn't have a team in a TeamBased game
|
||||
-- then spawn him as a spectator
|
||||
--
|
||||
if ( self.TeamBased && ( pl:Team() == TEAM_SPECTATOR || pl:Team() == TEAM_UNASSIGNED ) ) then
|
||||
|
||||
self:PlayerSpawnAsSpectator( pl )
|
||||
return
|
||||
|
||||
end
|
||||
|
||||
-- Stop observer mode
|
||||
pl:UnSpectate()
|
||||
|
||||
player_manager.OnPlayerSpawn( pl, transiton )
|
||||
player_manager.RunClass( pl, "Spawn" )
|
||||
|
||||
-- If we are in transition, do not touch player's weapons
|
||||
if ( !transiton ) then
|
||||
-- Call item loadout function
|
||||
hook.Call( "PlayerLoadout", GAMEMODE, pl )
|
||||
end
|
||||
|
||||
-- Set player model
|
||||
hook.Call( "PlayerSetModel", GAMEMODE, pl )
|
||||
|
||||
pl:SetupHands()
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerSetModel()
|
||||
Desc: Set the player's model
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerSetModel( pl )
|
||||
|
||||
player_manager.RunClass( pl, "SetModel" )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerSetHandsModel()
|
||||
Desc: Sets the player's view model hands model
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerSetHandsModel( pl, ent )
|
||||
|
||||
local info = player_manager.RunClass( pl, "GetHandsModel" )
|
||||
if ( !info ) then
|
||||
local playermodel = player_manager.TranslateToPlayerModelName( pl:GetModel() )
|
||||
info = player_manager.TranslatePlayerHands( playermodel )
|
||||
end
|
||||
|
||||
if ( info ) then
|
||||
ent:SetModel( info.model )
|
||||
ent:SetSkin( info.matchBodySkin and pl:GetSkin() or info.skin )
|
||||
ent:SetBodyGroups( info.body )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerLoadout()
|
||||
Desc: Give the player the default spawning weapons/ammo
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerLoadout( pl )
|
||||
|
||||
player_manager.RunClass( pl, "Loadout" )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerSelectTeamSpawn( player )
|
||||
Desc: Find a spawn point entity for this player's team
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerSelectTeamSpawn( TeamID, pl )
|
||||
|
||||
local SpawnPoints = team.GetSpawnPoints( TeamID )
|
||||
if ( !SpawnPoints || table.IsEmpty( SpawnPoints ) ) then return end
|
||||
|
||||
local ChosenSpawnPoint = nil
|
||||
|
||||
for i = 0, 6 do
|
||||
|
||||
ChosenSpawnPoint = table.Random( SpawnPoints )
|
||||
if ( hook.Call( "IsSpawnpointSuitable", GAMEMODE, pl, ChosenSpawnPoint, i == 6 ) ) then
|
||||
return ChosenSpawnPoint
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return ChosenSpawnPoint
|
||||
|
||||
end
|
||||
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:IsSpawnpointSuitable( player )
|
||||
Desc: Find out if the spawnpoint is suitable or not
|
||||
-----------------------------------------------------------]]
|
||||
local spawnpointmin = Vector( -16, -16, 0 )
|
||||
local spawnpointmax = Vector( 16, 16, 64 )
|
||||
function GM:IsSpawnpointSuitable( pl, spawnpointent, bMakeSuitable )
|
||||
|
||||
local Pos = spawnpointent:GetPos()
|
||||
|
||||
-- Note that we're searching the default hull size here for a player in the way of our spawning.
|
||||
-- This seems pretty rough, seeing as our player's hull could be different.. but it should do the job
|
||||
-- (HL2DM kills everything within a 128 unit radius)
|
||||
if ( pl:Team() == TEAM_SPECTATOR ) then return true end
|
||||
|
||||
local Blockers = 0
|
||||
for k, v in ipairs( ents.FindInBox( Pos + spawnpointmin, Pos + spawnpointmax ) ) do
|
||||
if ( IsValid( v ) && v != pl && v:GetClass() == "player" && v:Alive() ) then
|
||||
|
||||
Blockers = Blockers + 1
|
||||
|
||||
if ( bMakeSuitable ) then
|
||||
v:Kill()
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
if ( bMakeSuitable ) then return true end
|
||||
if ( Blockers > 0 ) then return false end
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerSelectSpawn( player )
|
||||
Desc: Find a spawn point entity for this player
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerSelectSpawn( pl, transiton )
|
||||
|
||||
-- If we are in transition, do not reset player's position
|
||||
if ( transiton ) then return end
|
||||
|
||||
if ( self.TeamBased ) then
|
||||
|
||||
local ent = self:PlayerSelectTeamSpawn( pl:Team(), pl )
|
||||
if ( IsValid( ent ) ) then return ent end
|
||||
|
||||
end
|
||||
|
||||
-- Save information about all of the spawn points
|
||||
-- in a team based game you'd split up the spawns
|
||||
if ( !IsTableOfEntitiesValid( self.SpawnPoints ) ) then
|
||||
|
||||
self.LastSpawnPoint = 0
|
||||
self.SpawnPoints = ents.FindByClass( "info_player_start" )
|
||||
self.SpawnPoints = table.Add( self.SpawnPoints, ents.FindByClass( "info_player_deathmatch" ) )
|
||||
self.SpawnPoints = table.Add( self.SpawnPoints, ents.FindByClass( "info_player_combine" ) )
|
||||
self.SpawnPoints = table.Add( self.SpawnPoints, ents.FindByClass( "info_player_rebel" ) )
|
||||
|
||||
-- CS Maps
|
||||
self.SpawnPoints = table.Add( self.SpawnPoints, ents.FindByClass( "info_player_counterterrorist" ) )
|
||||
self.SpawnPoints = table.Add( self.SpawnPoints, ents.FindByClass( "info_player_terrorist" ) )
|
||||
|
||||
-- DOD Maps
|
||||
self.SpawnPoints = table.Add( self.SpawnPoints, ents.FindByClass( "info_player_axis" ) )
|
||||
self.SpawnPoints = table.Add( self.SpawnPoints, ents.FindByClass( "info_player_allies" ) )
|
||||
|
||||
-- (Old) GMod Maps
|
||||
self.SpawnPoints = table.Add( self.SpawnPoints, ents.FindByClass( "gmod_player_start" ) )
|
||||
|
||||
-- TF Maps
|
||||
self.SpawnPoints = table.Add( self.SpawnPoints, ents.FindByClass( "info_player_teamspawn" ) )
|
||||
|
||||
-- INS Maps
|
||||
self.SpawnPoints = table.Add( self.SpawnPoints, ents.FindByClass( "ins_spawnpoint" ) )
|
||||
|
||||
-- AOC Maps
|
||||
self.SpawnPoints = table.Add( self.SpawnPoints, ents.FindByClass( "aoc_spawnpoint" ) )
|
||||
|
||||
-- Dystopia Maps
|
||||
self.SpawnPoints = table.Add( self.SpawnPoints, ents.FindByClass( "dys_spawn_point" ) )
|
||||
|
||||
-- PVKII Maps
|
||||
self.SpawnPoints = table.Add( self.SpawnPoints, ents.FindByClass( "info_player_pirate" ) )
|
||||
self.SpawnPoints = table.Add( self.SpawnPoints, ents.FindByClass( "info_player_viking" ) )
|
||||
self.SpawnPoints = table.Add( self.SpawnPoints, ents.FindByClass( "info_player_knight" ) )
|
||||
|
||||
-- DIPRIP Maps
|
||||
self.SpawnPoints = table.Add( self.SpawnPoints, ents.FindByClass( "diprip_start_team_blue" ) )
|
||||
self.SpawnPoints = table.Add( self.SpawnPoints, ents.FindByClass( "diprip_start_team_red" ) )
|
||||
|
||||
-- OB Maps
|
||||
self.SpawnPoints = table.Add( self.SpawnPoints, ents.FindByClass( "info_player_red" ) )
|
||||
self.SpawnPoints = table.Add( self.SpawnPoints, ents.FindByClass( "info_player_blue" ) )
|
||||
|
||||
-- SYN Maps
|
||||
self.SpawnPoints = table.Add( self.SpawnPoints, ents.FindByClass( "info_player_coop" ) )
|
||||
|
||||
-- ZPS Maps
|
||||
self.SpawnPoints = table.Add( self.SpawnPoints, ents.FindByClass( "info_player_human" ) )
|
||||
self.SpawnPoints = table.Add( self.SpawnPoints, ents.FindByClass( "info_player_zombie" ) )
|
||||
|
||||
-- ZM Maps
|
||||
self.SpawnPoints = table.Add( self.SpawnPoints, ents.FindByClass( "info_player_zombiemaster" ) )
|
||||
|
||||
-- FOF Maps
|
||||
self.SpawnPoints = table.Add( self.SpawnPoints, ents.FindByClass( "info_player_fof" ) )
|
||||
self.SpawnPoints = table.Add( self.SpawnPoints, ents.FindByClass( "info_player_desperado" ) )
|
||||
self.SpawnPoints = table.Add( self.SpawnPoints, ents.FindByClass( "info_player_vigilante" ) )
|
||||
|
||||
-- L4D Maps
|
||||
self.SpawnPoints = table.Add( self.SpawnPoints, ents.FindByClass( "info_survivor_rescue" ) )
|
||||
-- Removing this one for the time being, c1m4_atrium has one of these in a box under the map
|
||||
--self.SpawnPoints = table.Add( self.SpawnPoints, ents.FindByClass( "info_survivor_position" ) )
|
||||
|
||||
end
|
||||
|
||||
local Count = table.Count( self.SpawnPoints )
|
||||
|
||||
if ( Count == 0 ) then
|
||||
Msg("[PlayerSelectSpawn] Error! No spawn points!\n")
|
||||
return nil
|
||||
end
|
||||
|
||||
-- If any of the spawnpoints have a MASTER flag then only use that one.
|
||||
-- This is needed for single player maps.
|
||||
for k, v in pairs( self.SpawnPoints ) do
|
||||
|
||||
if ( v:HasSpawnFlags( 1 ) && hook.Call( "IsSpawnpointSuitable", GAMEMODE, pl, v, true ) ) then
|
||||
return v
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local ChosenSpawnPoint = nil
|
||||
|
||||
-- Try to work out the best, random spawnpoint
|
||||
for i = 1, Count do
|
||||
|
||||
ChosenSpawnPoint = table.Random( self.SpawnPoints )
|
||||
|
||||
if ( IsValid( ChosenSpawnPoint ) && ChosenSpawnPoint:IsInWorld() ) then
|
||||
if ( ( ChosenSpawnPoint == pl:GetVar( "LastSpawnpoint" ) || ChosenSpawnPoint == self.LastSpawnPoint ) && Count > 1 ) then continue end
|
||||
|
||||
if ( hook.Call( "IsSpawnpointSuitable", GAMEMODE, pl, ChosenSpawnPoint, i == Count ) ) then
|
||||
|
||||
self.LastSpawnPoint = ChosenSpawnPoint
|
||||
pl:SetVar( "LastSpawnpoint", ChosenSpawnPoint )
|
||||
return ChosenSpawnPoint
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return ChosenSpawnPoint
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:WeaponEquip( weapon )
|
||||
Desc: Player just picked up (or was given) weapon
|
||||
-----------------------------------------------------------]]
|
||||
function GM:WeaponEquip( weapon )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:ScalePlayerDamage( ply, hitgroup, dmginfo )
|
||||
Desc: Scale the damage based on being shot in a hitbox
|
||||
Return true to not take damage
|
||||
-----------------------------------------------------------]]
|
||||
function GM:ScalePlayerDamage( ply, hitgroup, dmginfo )
|
||||
|
||||
-- More damage if we're shot in the head
|
||||
if ( hitgroup == HITGROUP_HEAD ) then
|
||||
|
||||
dmginfo:ScaleDamage( 2 )
|
||||
|
||||
end
|
||||
|
||||
-- Less damage if we're shot in the arms or legs
|
||||
if ( hitgroup == HITGROUP_LEFTARM ||
|
||||
hitgroup == HITGROUP_RIGHTARM ||
|
||||
hitgroup == HITGROUP_LEFTLEG ||
|
||||
hitgroup == HITGROUP_RIGHTLEG ||
|
||||
hitgroup == HITGROUP_GEAR ) then
|
||||
|
||||
dmginfo:ScaleDamage( 0.25 )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerDeathSound()
|
||||
Desc: Return true to not play the default sounds
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerDeathSound()
|
||||
return false
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:SetupPlayerVisibility()
|
||||
Desc: Add extra positions to the player's PVS
|
||||
-----------------------------------------------------------]]
|
||||
function GM:SetupPlayerVisibility( pPlayer, pViewEntity )
|
||||
--AddOriginToPVS( vector_position_here )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:OnDamagedByExplosion( ply, dmginfo)
|
||||
Desc: Player has been hurt by an explosion
|
||||
-----------------------------------------------------------]]
|
||||
function GM:OnDamagedByExplosion( ply, dmginfo )
|
||||
ply:SetDSP( 35, false )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:CanPlayerSuicide( ply )
|
||||
Desc: Player typed KILL in the console. Can they kill themselves?
|
||||
-----------------------------------------------------------]]
|
||||
function GM:CanPlayerSuicide( ply )
|
||||
return true
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:CanPlayerEnterVehicle( player, vehicle, role )
|
||||
Desc: Return true if player can enter vehicle
|
||||
-----------------------------------------------------------]]
|
||||
function GM:CanPlayerEnterVehicle( ply, vehicle, role )
|
||||
return true
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerEnteredVehicle( player, vehicle, role )
|
||||
Desc: Player entered the vehicle fine
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerEnteredVehicle( ply, vehicle, role )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:CanExitVehicle()
|
||||
Desc: If the player is allowed to leave the vehicle, return true
|
||||
-----------------------------------------------------------]]
|
||||
function GM:CanExitVehicle( vehicle, passenger )
|
||||
return true
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerLeaveVehicle()
|
||||
Desc: Player left the vehicle
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerLeaveVehicle( ply, vehicle )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerSwitchFlashlight()
|
||||
Desc: Return true to allow action
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerSwitchFlashlight( ply, SwitchOn )
|
||||
return ply:CanUseFlashlight()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerCanJoinTeam( ply, teamid )
|
||||
Desc: Allow mods/addons to easily determine whether a player
|
||||
can join a team or not
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerCanJoinTeam( ply, teamid )
|
||||
|
||||
local TimeBetweenSwitches = GAMEMODE.SecondsBetweenTeamSwitches or 10
|
||||
if ( ply.LastTeamSwitch && RealTime() - ply.LastTeamSwitch < TimeBetweenSwitches ) then
|
||||
ply.LastTeamSwitch = ply.LastTeamSwitch + 1
|
||||
ply:ChatPrint( Format( "Please wait %i more seconds before trying to change team again", ( TimeBetweenSwitches - ( RealTime() - ply.LastTeamSwitch ) ) + 1 ) )
|
||||
return false
|
||||
end
|
||||
|
||||
-- Already on this team!
|
||||
if ( ply:Team() == teamid ) then
|
||||
ply:ChatPrint( "You're already on that team" )
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerRequestTeam()
|
||||
Desc: Player wants to change team
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerRequestTeam( ply, teamid )
|
||||
|
||||
-- No changing teams if not teambased!
|
||||
if ( !GAMEMODE.TeamBased ) then return end
|
||||
|
||||
-- This team isn't joinable
|
||||
if ( !team.Joinable( teamid ) ) then
|
||||
ply:ChatPrint( "You can't join that team" )
|
||||
return end
|
||||
|
||||
-- This team isn't joinable
|
||||
if ( !GAMEMODE:PlayerCanJoinTeam( ply, teamid ) ) then
|
||||
-- Messages here should be outputted by this function
|
||||
return end
|
||||
|
||||
GAMEMODE:PlayerJoinTeam( ply, teamid )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerJoinTeam()
|
||||
Desc: Make player join this team
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerJoinTeam( ply, teamid )
|
||||
|
||||
local iOldTeam = ply:Team()
|
||||
|
||||
if ( ply:Alive() ) then
|
||||
if ( iOldTeam == TEAM_SPECTATOR || iOldTeam == TEAM_UNASSIGNED ) then
|
||||
ply:KillSilent()
|
||||
else
|
||||
ply:Kill()
|
||||
end
|
||||
end
|
||||
|
||||
ply:SetTeam( teamid )
|
||||
ply.LastTeamSwitch = RealTime()
|
||||
|
||||
GAMEMODE:OnPlayerChangedTeam( ply, iOldTeam, teamid )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:OnPlayerChangedTeam( ply, oldteam, newteam )
|
||||
-----------------------------------------------------------]]
|
||||
function GM:OnPlayerChangedTeam( ply, oldteam, newteam )
|
||||
|
||||
-- Here's an immediate respawn thing by default. If you want to
|
||||
-- re-create something more like CS or some shit you could probably
|
||||
-- change to a spectator or something while dead.
|
||||
if ( newteam == TEAM_SPECTATOR ) then
|
||||
|
||||
-- If we changed to spectator mode, respawn where we are
|
||||
local Pos = ply:EyePos()
|
||||
ply:Spawn()
|
||||
ply:SetPos( Pos )
|
||||
|
||||
elseif ( oldteam == TEAM_SPECTATOR ) then
|
||||
|
||||
-- If we're changing from spectator, join the game
|
||||
ply:Spawn()
|
||||
|
||||
else
|
||||
|
||||
-- If we're straight up changing teams just hang
|
||||
-- around until we're ready to respawn onto the
|
||||
-- team that we chose
|
||||
|
||||
end
|
||||
|
||||
PrintMessage( HUD_PRINTTALK, Format( "%s joined '%s'", ply:Nick(), team.GetName( newteam ) ) )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerSpray()
|
||||
Desc: Return true to prevent player spraying
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerSpray( ply )
|
||||
|
||||
return false
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:OnPlayerHitGround()
|
||||
Desc: Return true to disable default action
|
||||
-----------------------------------------------------------]]
|
||||
function GM:OnPlayerHitGround( ply, bInWater, bOnFloater, flFallSpeed )
|
||||
|
||||
-- Apply damage and play collision sound here
|
||||
-- then return true to disable the default action
|
||||
--MsgN( ply, bInWater, bOnFloater, flFallSpeed )
|
||||
--return true
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:GetFallDamage()
|
||||
Desc: return amount of damage to do due to fall
|
||||
-----------------------------------------------------------]]
|
||||
local mp_falldamage = GetConVar( "mp_falldamage" )
|
||||
|
||||
function GM:GetFallDamage( ply, flFallSpeed )
|
||||
|
||||
if ( mp_falldamage:GetBool() ) then -- realistic fall damage is on
|
||||
return ( flFallSpeed - 526.5 ) * ( 100 / 396 ) -- the Source SDK value
|
||||
end
|
||||
|
||||
return 10
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerCanSeePlayersChat()
|
||||
Desc: Can this player see the other player's chat?
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerCanSeePlayersChat( strText, bTeamOnly, pListener, pSpeaker )
|
||||
|
||||
if ( bTeamOnly ) then
|
||||
if ( !IsValid( pSpeaker ) || !IsValid( pListener ) ) then return false end
|
||||
if ( pListener:Team() != pSpeaker:Team() ) then return false end
|
||||
end
|
||||
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
local sv_alltalk = GetConVar( "sv_alltalk" )
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerCanHearPlayersVoice()
|
||||
Desc: Can this player see the other player's voice?
|
||||
Returns 2 bools.
|
||||
1. Can the player hear the other player
|
||||
2. Can they hear them spacially
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerCanHearPlayersVoice( pListener, pTalker )
|
||||
|
||||
local alltalk = sv_alltalk:GetInt()
|
||||
if ( alltalk >= 1 ) then return true, alltalk == 2 end
|
||||
|
||||
return pListener:Team() == pTalker:Team(), false
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:NetworkIDValidated()
|
||||
Desc: Called when Steam has validated this as a valid player
|
||||
-----------------------------------------------------------]]
|
||||
function GM:NetworkIDValidated( name, steamid )
|
||||
|
||||
-- MsgN( "GM:NetworkIDValidated", name, steamid )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerShouldTaunt( ply, actid )
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerShouldTaunt( ply, actid )
|
||||
|
||||
-- The default behaviour is to always let them act
|
||||
-- Some gamemodes will obviously want to stop this for certain players by returning false
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerStartTaunt( ply, actid, length )
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerStartTaunt( ply, actid, length )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:AllowPlayerPickup( ply, object )
|
||||
-----------------------------------------------------------]]
|
||||
function GM:AllowPlayerPickup( ply, object )
|
||||
|
||||
-- Should the player be allowed to pick this object up (using ENTER)?
|
||||
-- If no then return false. Default is HELL YEAH
|
||||
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerDroppedWeapon()
|
||||
Desc: Player has dropped a weapon
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerDroppedWeapon( ply, weapon )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
These are buttons that the client is pressing. They're used
|
||||
in Sandbox mode to control things like wheels, thrusters etc.
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerButtonDown( ply, btn ) end
|
||||
function GM:PlayerButtonUp( ply, btn ) end
|
||||
|
||||
concommand.Add( "changeteam", function( pl, cmd, args ) hook.Call( "PlayerRequestTeam", GAMEMODE, pl, tonumber( args[ 1 ] ) ) end )
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:HandlePlayerArmorReduction()
|
||||
Desc: Handle player armor reduction
|
||||
-----------------------------------------------------------]]
|
||||
function GM:HandlePlayerArmorReduction( ply, dmginfo )
|
||||
|
||||
-- If no armor, or special damage types, bypass armor
|
||||
if ( ply:Armor() <= 0 || bit.band( dmginfo:GetDamageType(), DMG_FALL + DMG_DROWN + DMG_POISON + DMG_RADIATION ) != 0 ) then return end
|
||||
|
||||
local flBonus = 1.0 -- Each Point of Armor is worth 1/x points of health
|
||||
local flRatio = 0.2 -- Armor Takes 80% of the damage
|
||||
if ( GetConVar( "player_old_armor" ):GetBool() ) then
|
||||
flBonus = 0.5
|
||||
end
|
||||
|
||||
local flNew = dmginfo:GetDamage() * flRatio
|
||||
local flArmor = (dmginfo:GetDamage() - flNew) * flBonus
|
||||
|
||||
if ( !GetConVar( "player_old_armor" ):GetBool() ) then
|
||||
if ( flArmor < 0.1 ) then flArmor = 0 end -- Let's not have tiny amounts of damage reduce a lot of our armor
|
||||
else if ( flArmor < 1.0 ) then flArmor = 1.0 end
|
||||
end
|
||||
|
||||
-- Does this use more armor than we have?
|
||||
if ( flArmor > ply:Armor() ) then
|
||||
|
||||
flArmor = ply:Armor() * ( 1 / flBonus )
|
||||
flNew = dmginfo:GetDamage() - flArmor
|
||||
ply:SetArmor( 0 )
|
||||
|
||||
else
|
||||
ply:SetArmor( ply:Armor() - flArmor )
|
||||
end
|
||||
|
||||
dmginfo:SetDamage( flNew )
|
||||
|
||||
end
|
||||
145
gamemodes/base/gamemode/player_class/player_default.lua
Normal file
145
gamemodes/base/gamemode/player_class/player_default.lua
Normal file
@@ -0,0 +1,145 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
include( "taunt_camera.lua" )
|
||||
|
||||
local PLAYER = {}
|
||||
|
||||
PLAYER.DisplayName = "Default Class"
|
||||
|
||||
PLAYER.SlowWalkSpeed = 200 -- How fast to move when slow-walking (+WALK)
|
||||
PLAYER.WalkSpeed = 400 -- How fast to move when not running
|
||||
PLAYER.RunSpeed = 600 -- How fast to move when running
|
||||
PLAYER.CrouchedWalkSpeed = 0.3 -- Multiply move speed by this when crouching
|
||||
PLAYER.DuckSpeed = 0.3 -- How fast to go from not ducking, to ducking
|
||||
PLAYER.UnDuckSpeed = 0.3 -- How fast to go from ducking, to not ducking
|
||||
PLAYER.JumpPower = 200 -- How powerful our jump should be
|
||||
PLAYER.CanUseFlashlight = true -- Can we use the flashlight
|
||||
PLAYER.MaxHealth = 100 -- Max health we can have
|
||||
PLAYER.MaxArmor = 100 -- Max armor we can have
|
||||
PLAYER.StartHealth = 100 -- How much health we start with
|
||||
PLAYER.StartArmor = 0 -- How much armour we start with
|
||||
PLAYER.DropWeaponOnDie = false -- Do we drop our weapon when we die
|
||||
PLAYER.TeammateNoCollide = true -- Do we collide with teammates or run straight through them
|
||||
PLAYER.AvoidPlayers = true -- Automatically swerves around other players
|
||||
PLAYER.UseVMHands = true -- Uses viewmodel hands
|
||||
|
||||
--
|
||||
-- Name: PLAYER:SetupDataTables
|
||||
-- Desc: Set up the network table accessors
|
||||
-- Arg1:
|
||||
-- Ret1:
|
||||
--
|
||||
function PLAYER:SetupDataTables()
|
||||
end
|
||||
|
||||
--
|
||||
-- Name: PLAYER:Init
|
||||
-- Desc: Called when the class object is created (shared)
|
||||
-- Arg1:
|
||||
-- Ret1:
|
||||
--
|
||||
function PLAYER:Init()
|
||||
end
|
||||
|
||||
--
|
||||
-- Name: PLAYER:Spawn
|
||||
-- Desc: Called serverside only when the player spawns
|
||||
-- Arg1:
|
||||
-- Ret1:
|
||||
--
|
||||
function PLAYER:Spawn()
|
||||
end
|
||||
|
||||
--
|
||||
-- Name: PLAYER:Loadout
|
||||
-- Desc: Called on spawn to give the player their default loadout
|
||||
-- Arg1:
|
||||
-- Ret1:
|
||||
--
|
||||
function PLAYER:Loadout()
|
||||
|
||||
self.Player:Give( "weapon_pistol" )
|
||||
self.Player:GiveAmmo( 255, "Pistol", true )
|
||||
|
||||
end
|
||||
|
||||
function PLAYER:SetModel()
|
||||
|
||||
local cl_playermodel = self.Player:GetInfo( "cl_playermodel" )
|
||||
local modelname = player_manager.TranslatePlayerModel( cl_playermodel )
|
||||
util.PrecacheModel( modelname )
|
||||
self.Player:SetModel( modelname )
|
||||
|
||||
end
|
||||
|
||||
function PLAYER:Death( inflictor, attacker )
|
||||
end
|
||||
|
||||
-- Clientside only
|
||||
function PLAYER:CalcView( view ) end -- Setup the player's view
|
||||
function PLAYER:CreateMove( cmd ) end -- Creates the user command on the client
|
||||
function PLAYER:ShouldDrawLocal() end -- Return true if we should draw the local player
|
||||
|
||||
-- Shared
|
||||
function PLAYER:StartMove( cmd, mv ) end -- Copies from the user command to the move
|
||||
function PLAYER:Move( mv ) end -- Runs the move (can run multiple times for the same client)
|
||||
function PLAYER:FinishMove( mv ) end -- Copy the results of the move back to the Player
|
||||
|
||||
--
|
||||
-- Name: PLAYER:ViewModelChanged
|
||||
-- Desc: Called when the player changes their weapon to another one causing their viewmodel model to change
|
||||
-- Arg1: Entity|viewmodel|The viewmodel that is changing
|
||||
-- Arg2: string|old|The old model
|
||||
-- Arg3: string|new|The new model
|
||||
-- Ret1:
|
||||
--
|
||||
function PLAYER:ViewModelChanged( vm, old, new )
|
||||
end
|
||||
|
||||
--
|
||||
-- Name: PLAYER:PreDrawViewmodel
|
||||
-- Desc: Called before the viewmodel is being drawn (clientside)
|
||||
-- Arg1: Entity|viewmodel|The viewmodel
|
||||
-- Arg2: Entity|weapon|The weapon
|
||||
-- Ret1:
|
||||
--
|
||||
function PLAYER:PreDrawViewModel( vm, weapon )
|
||||
end
|
||||
|
||||
--
|
||||
-- Name: PLAYER:PostDrawViewModel
|
||||
-- Desc: Called after the viewmodel has been drawn (clientside)
|
||||
-- Arg1: Entity|viewmodel|The viewmodel
|
||||
-- Arg2: Entity|weapon|The weapon
|
||||
-- Ret1:
|
||||
--
|
||||
function PLAYER:PostDrawViewModel( vm, weapon )
|
||||
end
|
||||
|
||||
--
|
||||
-- Name: PLAYER:GetHandsModel
|
||||
-- Desc: Called on player spawn to determine which hand model to use
|
||||
-- Arg1:
|
||||
-- Ret1: table|info|A table containing model, skin and body
|
||||
--
|
||||
function PLAYER:GetHandsModel()
|
||||
|
||||
-- return { model = "models/weapons/c_arms_cstrike.mdl", skin = 1, body = "0100000" }
|
||||
|
||||
local playermodel = player_manager.TranslateToPlayerModelName( self.Player:GetModel() )
|
||||
return player_manager.TranslatePlayerHands( playermodel )
|
||||
|
||||
end
|
||||
|
||||
player_manager.RegisterClass( "player_default", PLAYER, nil )
|
||||
133
gamemodes/base/gamemode/player_class/taunt_camera.lua
Normal file
133
gamemodes/base/gamemode/player_class/taunt_camera.lua
Normal file
@@ -0,0 +1,133 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
--
|
||||
-- This is designed so you can call it like
|
||||
--
|
||||
-- tauntcam = TauntCamera()
|
||||
--
|
||||
-- Then you have your own copy.
|
||||
--
|
||||
function TauntCamera()
|
||||
|
||||
local CAM = {}
|
||||
|
||||
local WasOn = false
|
||||
|
||||
local CustomAngles = angle_zero
|
||||
local PlayerLockAngles = nil
|
||||
|
||||
local InLerp = 0
|
||||
local OutLerp = 1
|
||||
|
||||
--
|
||||
-- Draw the local player if we're active in any way
|
||||
--
|
||||
CAM.ShouldDrawLocalPlayer = function( self, ply, on )
|
||||
|
||||
return on || OutLerp < 1
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Implements the third person, rotation view (with lerping in/out)
|
||||
--
|
||||
CAM.CalcView = function( self, view, ply, on )
|
||||
|
||||
if ( !ply:Alive() || !IsValid( ply:GetViewEntity() ) || ply:GetViewEntity() != ply ) then on = false end
|
||||
|
||||
if ( WasOn != on ) then
|
||||
|
||||
if ( on ) then InLerp = 0 end
|
||||
if ( !on ) then OutLerp = 0 end
|
||||
|
||||
WasOn = on
|
||||
|
||||
end
|
||||
|
||||
if ( !on && OutLerp >= 1 ) then
|
||||
|
||||
CustomAngles = view.angles * 1
|
||||
CustomAngles.r = 0
|
||||
PlayerLockAngles = nil
|
||||
InLerp = 0
|
||||
return
|
||||
|
||||
end
|
||||
|
||||
if ( PlayerLockAngles == nil ) then return end
|
||||
|
||||
--
|
||||
-- Simple 3rd person camera
|
||||
--
|
||||
local TargetOrigin = view.origin - CustomAngles:Forward() * 100
|
||||
local tr = util.TraceHull( { start = view.origin, endpos = TargetOrigin, mask = MASK_SHOT, filter = player.GetAll(), mins = Vector( -8, -8, -8 ), maxs = Vector( 8, 8, 8 ) } )
|
||||
TargetOrigin = tr.HitPos + tr.HitNormal
|
||||
|
||||
if ( InLerp < 1 ) then
|
||||
|
||||
InLerp = InLerp + FrameTime() * 5.0
|
||||
view.origin = LerpVector( InLerp, view.origin, TargetOrigin )
|
||||
view.angles = LerpAngle( InLerp, PlayerLockAngles, CustomAngles )
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
if ( OutLerp < 1 ) then
|
||||
|
||||
OutLerp = OutLerp + FrameTime() * 3.0
|
||||
view.origin = LerpVector( 1-OutLerp, view.origin, TargetOrigin )
|
||||
view.angles = LerpAngle( 1-OutLerp, PlayerLockAngles, CustomAngles )
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
view.angles = CustomAngles * 1
|
||||
view.origin = TargetOrigin
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Freezes the player in position and uses the input from the user command to
|
||||
-- rotate the custom third person camera
|
||||
--
|
||||
CAM.CreateMove = function( self, cmd, ply, on )
|
||||
|
||||
if ( !ply:Alive() ) then on = false end
|
||||
if ( !on ) then return end
|
||||
|
||||
if ( PlayerLockAngles == nil ) then
|
||||
PlayerLockAngles = CustomAngles * 1
|
||||
end
|
||||
|
||||
--
|
||||
-- Rotate our view
|
||||
--
|
||||
CustomAngles.pitch = CustomAngles.pitch + cmd:GetMouseY() * 0.01
|
||||
CustomAngles.yaw = CustomAngles.yaw - cmd:GetMouseX() * 0.01
|
||||
|
||||
--
|
||||
-- Lock the player's controls and angles
|
||||
--
|
||||
cmd:SetViewAngles( PlayerLockAngles )
|
||||
cmd:ClearButtons()
|
||||
cmd:ClearMovement()
|
||||
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
return CAM
|
||||
|
||||
end
|
||||
145
gamemodes/base/gamemode/player_shd.lua
Normal file
145
gamemodes/base/gamemode/player_shd.lua
Normal file
@@ -0,0 +1,145 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerTraceAttack( )
|
||||
Desc: A bullet has been fired and hit this player
|
||||
Return true to completely override internals
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerTraceAttack( ply, dmginfo, dir, trace )
|
||||
|
||||
return false
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:SetPlayerSpeed( )
|
||||
Desc: Sets the player's run/walk speed
|
||||
-----------------------------------------------------------]]
|
||||
function GM:SetPlayerSpeed( ply, walk, run )
|
||||
|
||||
ply:SetWalkSpeed( walk )
|
||||
ply:SetRunSpeed( run )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerFootstep( ply, vPos, iFoot, strSoundName, fVolume, pFilter )
|
||||
Desc: Called when a player steps
|
||||
pFilter is the recipient filter to use for effects/sounds
|
||||
and is only valid SERVERSIDE. Clientside needs no filter!
|
||||
Return true to not play normal sound
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerFootstep( ply, vPos, iFoot, strSoundName, fVolume, pFilter )
|
||||
if ( IsValid( ply ) and !ply:Alive() ) then
|
||||
return true
|
||||
end
|
||||
|
||||
--[[
|
||||
-- Draw effect on footdown
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin( vPos )
|
||||
util.Effect( "phys_unfreeze", effectdata, true, pFilter )
|
||||
--]]
|
||||
|
||||
--[[
|
||||
-- Don't play left foot
|
||||
if ( iFoot == 0 ) then return true end
|
||||
--]]
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerStepSoundTime( ply, iType, bWalking )
|
||||
Desc: Return the time between footsteps
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerStepSoundTime( ply, iType, bWalking )
|
||||
|
||||
local fStepTime = 350
|
||||
local fMaxSpeed = ply:GetMaxSpeed()
|
||||
|
||||
if ( iType == STEPSOUNDTIME_NORMAL || iType == STEPSOUNDTIME_WATER_FOOT ) then
|
||||
|
||||
if ( fMaxSpeed <= 100 ) then
|
||||
fStepTime = 400
|
||||
elseif ( fMaxSpeed <= 300 ) then
|
||||
fStepTime = 350
|
||||
else
|
||||
fStepTime = 250
|
||||
end
|
||||
|
||||
elseif ( iType == STEPSOUNDTIME_ON_LADDER ) then
|
||||
|
||||
fStepTime = 450
|
||||
|
||||
elseif ( iType == STEPSOUNDTIME_WATER_KNEE ) then
|
||||
|
||||
fStepTime = 600
|
||||
|
||||
end
|
||||
|
||||
-- Step slower if crouching
|
||||
if ( ply:Crouching() ) then
|
||||
fStepTime = fStepTime + 50
|
||||
end
|
||||
|
||||
return fStepTime
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerNoClip( player, bool )
|
||||
Desc: Player pressed the noclip key, return true if
|
||||
the player is allowed to noclip, false to block
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerNoClip( pl, on )
|
||||
if ( !on ) then return true end
|
||||
-- Allow noclip if we're in single player and living
|
||||
return game.SinglePlayer() && IsValid( pl ) && pl:Alive()
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- FindUseEntity
|
||||
--
|
||||
function GM:FindUseEntity( ply, ent )
|
||||
|
||||
-- ent is what the game found to use by default
|
||||
-- return what you REALLY want it to use
|
||||
|
||||
-- Simple fix to allow entities inside playerclip brushes to be used. Necessary for c1a0c map in Half-Life: Source
|
||||
if ( !IsValid( ent ) ) then
|
||||
local traceEnt = util.TraceLine( {
|
||||
start = ply:GetShootPos(),
|
||||
endpos = ply:GetShootPos() + ply:GetAimVector() * 72,
|
||||
filter = ply
|
||||
} ).Entity
|
||||
if ( IsValid( traceEnt ) ) then return traceEnt end
|
||||
end
|
||||
|
||||
return ent
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Player tick
|
||||
--
|
||||
function GM:PlayerTick( ply, mv )
|
||||
end
|
||||
|
||||
--
|
||||
-- Player is switching weapon. Return true to prevent the switch.
|
||||
--
|
||||
function GM:PlayerSwitchWeapon( ply, oldwep, newwep )
|
||||
|
||||
return false
|
||||
|
||||
end
|
||||
282
gamemodes/base/gamemode/shared.lua
Normal file
282
gamemodes/base/gamemode/shared.lua
Normal file
@@ -0,0 +1,282 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
|
||||
This file should contain variables and functions that are
|
||||
the same on both client and server.
|
||||
|
||||
This file will get sent to the client - so don't add
|
||||
anything to this file that you don't want them to be
|
||||
able to see.
|
||||
|
||||
-----------------------------------------------------------]]
|
||||
|
||||
include( "obj_player_extend.lua" )
|
||||
|
||||
include( "gravitygun.lua" )
|
||||
include( "player_shd.lua" )
|
||||
include( "animations.lua" )
|
||||
include( "player_class/player_default.lua" )
|
||||
|
||||
GM.Name = "Base Gamemode"
|
||||
GM.Author = "Garry Newman"
|
||||
GM.Email = "garrynewman@gmail.com"
|
||||
GM.Website = "www.garry.tv"
|
||||
GM.TeamBased = false
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:KeyPress( )
|
||||
Desc: Player pressed a key (see IN enums)
|
||||
-----------------------------------------------------------]]
|
||||
function GM:KeyPress( player, key )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:KeyRelease( )
|
||||
Desc: Player released a key (see IN enums)
|
||||
-----------------------------------------------------------]]
|
||||
function GM:KeyRelease( player, key )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PlayerConnect( )
|
||||
Desc: Player has connects to the server (hasn't spawned)
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerConnect( name, address )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PropBreak( )
|
||||
Desc: Prop has been broken
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PropBreak( attacker, prop )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PhysgunPickup( )
|
||||
Desc: Return true if player can pickup entity
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PhysgunPickup( ply, ent )
|
||||
|
||||
-- Don't pick up players
|
||||
if ( ent:GetClass() == "player" ) then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:PhysgunDrop( )
|
||||
Desc: Dropped an entity
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PhysgunDrop( ply, ent )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: Text to show in the server browser
|
||||
-----------------------------------------------------------]]
|
||||
function GM:GetGameDescription()
|
||||
return self.Name
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: Saved
|
||||
-----------------------------------------------------------]]
|
||||
function GM:Saved()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: Restored
|
||||
-----------------------------------------------------------]]
|
||||
function GM:Restored()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: EntityRemoved
|
||||
Desc: Called right before an entity is removed. Note that this
|
||||
isn't going to be totally reliable on the client since the client
|
||||
only knows about entities that it has had in its PVS.
|
||||
-----------------------------------------------------------]]
|
||||
function GM:EntityRemoved( ent )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: Tick
|
||||
Desc: Like Think except called every tick on both client and server
|
||||
-----------------------------------------------------------]]
|
||||
function GM:Tick()
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: OnEntityCreated
|
||||
Desc: Called right after the Entity has been made visible to Lua
|
||||
-----------------------------------------------------------]]
|
||||
function GM:OnEntityCreated( Ent )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:EntityKeyValue( ent, key, value )
|
||||
Desc: Called when an entity has a keyvalue set
|
||||
Returning a string it will override the value
|
||||
-----------------------------------------------------------]]
|
||||
function GM:EntityKeyValue( ent, key, value )
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:CreateTeams()
|
||||
Desc: Note - HAS to be shared.
|
||||
-----------------------------------------------------------]]
|
||||
function GM:CreateTeams()
|
||||
|
||||
-- Don't do this if not teambased. But if it is teambased we
|
||||
-- create a few teams here as an example. If you're making a teambased
|
||||
-- gamemode you should override this function in your gamemode
|
||||
|
||||
if ( !GAMEMODE.TeamBased ) then return end
|
||||
|
||||
TEAM_BLUE = 1
|
||||
team.SetUp( TEAM_BLUE, "Blue Team", Color( 0, 0, 255 ) )
|
||||
team.SetSpawnPoint( TEAM_BLUE, "ai_hint" ) -- <-- This would be info_terrorist or some entity that is in your map
|
||||
|
||||
TEAM_ORANGE = 2
|
||||
team.SetUp( TEAM_ORANGE, "Orange Team", Color( 255, 150, 0 ) )
|
||||
team.SetSpawnPoint( TEAM_ORANGE, "sky_camera" ) -- <-- This would be info_terrorist or some entity that is in your map
|
||||
|
||||
TEAM_SEXY = 3
|
||||
team.SetUp( TEAM_SEXY, "Sexy Team", Color( 255, 150, 150 ) )
|
||||
team.SetSpawnPoint( TEAM_SEXY, "info_player_start" ) -- <-- This would be info_terrorist or some entity that is in your map
|
||||
|
||||
team.SetSpawnPoint( TEAM_SPECTATOR, "worldspawn" )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:ShouldCollide( Ent1, Ent2 )
|
||||
Desc: This should always return true unless you have
|
||||
a good reason for it not to.
|
||||
-----------------------------------------------------------]]
|
||||
function GM:ShouldCollide( Ent1, Ent2 )
|
||||
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:Move
|
||||
This basically overrides the NOCLIP, PLAYERMOVE movement stuff.
|
||||
It's what actually performs the move.
|
||||
Return true to not perform any default movement actions. (completely override)
|
||||
-----------------------------------------------------------]]
|
||||
function GM:Move( ply, mv )
|
||||
|
||||
if ( drive.Move( ply, mv ) ) then return true end
|
||||
if ( player_manager.RunClass( ply, "Move", mv ) ) then return true end
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
-- Purpose: This is called pre player movement and copies all the data necessary
|
||||
-- from the player for movement. Copy from the usercmd to move.
|
||||
-----------------------------------------------------------]]
|
||||
function GM:SetupMove( ply, mv, cmd )
|
||||
|
||||
if ( drive.StartMove( ply, mv, cmd ) ) then return true end
|
||||
if ( player_manager.RunClass( ply, "StartMove", mv, cmd ) ) then return true end
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Name: gamemode:FinishMove( player, movedata )
|
||||
-----------------------------------------------------------]]
|
||||
function GM:FinishMove( ply, mv )
|
||||
|
||||
if ( drive.FinishMove( ply, mv ) ) then return true end
|
||||
if ( player_manager.RunClass( ply, "FinishMove", mv ) ) then return true end
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Called after the player's think.
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerPostThink( ply )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
A player has started driving an entity
|
||||
-----------------------------------------------------------]]
|
||||
function GM:StartEntityDriving( ent, ply )
|
||||
|
||||
drive.Start( ply, ent )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
A player has stopped driving an entity
|
||||
-----------------------------------------------------------]]
|
||||
function GM:EndEntityDriving( ent, ply )
|
||||
|
||||
drive.End( ply, ent )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
To update the player's animation during a drive
|
||||
-----------------------------------------------------------]]
|
||||
function GM:PlayerDriveAnimate( ply )
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
The gamemode has been reloaded
|
||||
-----------------------------------------------------------]]
|
||||
function GM:OnReloaded()
|
||||
end
|
||||
|
||||
function GM:PreGamemodeLoaded()
|
||||
end
|
||||
|
||||
function GM:OnGamemodeLoaded()
|
||||
end
|
||||
|
||||
function GM:PostGamemodeLoaded()
|
||||
end
|
||||
|
||||
--
|
||||
-- Name: GM:OnViewModelChanged
|
||||
-- Desc: Called when the player changes their weapon to another one - and their viewmodel model changes
|
||||
-- Arg1: Entity|viewmodel|The viewmodel that is changing
|
||||
-- Arg2: string|old|The old model
|
||||
-- Arg3: string|new|The new model
|
||||
-- Ret1:
|
||||
--
|
||||
function GM:OnViewModelChanged( vm, old, new )
|
||||
|
||||
local ply = vm:GetOwner()
|
||||
if ( IsValid( ply ) ) then
|
||||
player_manager.RunClass( ply, "ViewModelChanged", vm, old, new )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Disable properties serverside for all non-sandbox derived gamemodes.
|
||||
-----------------------------------------------------------]]
|
||||
function GM:CanProperty( pl, property, ent )
|
||||
return false
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------
|
||||
Allow hooks to override bullet without ignoring all other hooks
|
||||
-----------------------------------------------------------]]
|
||||
function GM:EntityFireBullets( ent, bullets )
|
||||
return true
|
||||
end
|
||||
42
gamemodes/base/gamemode/variable_edit.lua
Normal file
42
gamemodes/base/gamemode/variable_edit.lua
Normal file
@@ -0,0 +1,42 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
--
|
||||
-- Called when we've received a call from a client who wants to edit
|
||||
-- a particular entity.
|
||||
--
|
||||
function GM:VariableEdited( ent, ply, key, val, editor )
|
||||
|
||||
if ( !IsValid( ent ) ) then return end
|
||||
if ( !IsValid( ply ) ) then return end
|
||||
|
||||
--
|
||||
-- Check with the gamemode that we can edit the entity
|
||||
--
|
||||
local CanEdit = hook.Run( "CanEditVariable", ent, ply, key, val, editor )
|
||||
if ( !CanEdit ) then return end
|
||||
|
||||
--
|
||||
-- Actually apply the edited value
|
||||
--
|
||||
ent:EditValue( key, val )
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Your gamemode should use this hook to allow/dissallow editing
|
||||
-- By default only admins can edit entities.
|
||||
--
|
||||
function GM:CanEditVariable( ent, ply, key, val, editor )
|
||||
|
||||
return ply:IsAdmin() || game.SinglePlayer()
|
||||
|
||||
end
|
||||
32
gamemodes/base/send.txt
Normal file
32
gamemodes/base/send.txt
Normal file
@@ -0,0 +1,32 @@
|
||||
#
|
||||
# These files aren't fully sent to the client because they
|
||||
# should never change. Instead we send the CRC of this file
|
||||
# so the client can load their version - and we know it's kewl.
|
||||
#
|
||||
gamemodes\base\gamemode\player_class\player_default.lua
|
||||
gamemodes\base\entities\weapons\weapon_base\cl_init.lua
|
||||
gamemodes\base\entities\weapons\weapon_base\shared.lua
|
||||
gamemodes\base\entities\weapons\weapon_base\ai_translations.lua
|
||||
gamemodes\base\entities\weapons\weapon_base\sh_anim.lua
|
||||
gamemodes\base\entities\entities\base_point.lua
|
||||
gamemodes\base\entities\entities\base_ai\cl_init.lua
|
||||
gamemodes\base\entities\entities\base_ai\shared.lua
|
||||
gamemodes\base\entities\entities\base_anim.lua
|
||||
gamemodes\base\entities\entities\base_entity\cl_init.lua
|
||||
gamemodes\base\entities\entities\base_entity\shared.lua
|
||||
gamemodes\base\entities\entities\prop_effect.lua
|
||||
gamemodes\base\entities\effects\base.lua
|
||||
gamemodes\base\entities\effects\dof_node.lua
|
||||
gamemodes\base\gamemode\cl_init.lua
|
||||
gamemodes\base\gamemode\shared.lua
|
||||
gamemodes\base\gamemode\cl_scoreboard.lua
|
||||
gamemodes\base\gamemode\cl_targetid.lua
|
||||
gamemodes\base\gamemode\cl_hudpickup.lua
|
||||
gamemodes\base\gamemode\cl_spawnmenu.lua
|
||||
gamemodes\base\gamemode\cl_deathnotice.lua
|
||||
gamemodes\base\gamemode\cl_pickteam.lua
|
||||
gamemodes\base\gamemode\cl_voice.lua
|
||||
gamemodes\base\gamemode\gravitygun.lua
|
||||
gamemodes\base\gamemode\player_shd.lua
|
||||
gamemodes\base\gamemode\animations.lua
|
||||
gamemodes\base\gamemode\obj_player_extend.lua
|
||||
Reference in New Issue
Block a user