mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 13:53:45 +03:00
Upload
This commit is contained in:
558
lua/entities/obj_vj_npccontroller/init.lua
Normal file
558
lua/entities/obj_vj_npccontroller/init.lua
Normal file
@@ -0,0 +1,558 @@
|
||||
--[[
|
||||
| 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("shared.lua")
|
||||
include('shared.lua')
|
||||
/*--------------------------------------------------
|
||||
*** Copyright (c) 2012-2023 by DrVrej, All rights reserved. ***
|
||||
No parts of this code or any of its contents may be reproduced, copied, modified or adapted,
|
||||
without the prior written consent of the author, unless otherwise indicated for stand-alone materials.
|
||||
--------------------------------------------------*/
|
||||
ENT.VJC_Player_CanExit = true -- Can the player exit the controller?
|
||||
ENT.VJC_Player_CanRespawn = true -- If false, the player will die when the NPC dies!
|
||||
ENT.VJC_Player_DrawHUD = true -- Should the controller HUD be displayed?
|
||||
ENT.VJC_BullseyeTracking = false -- Activates bullseye tracking (Will not turn to the move location!)
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
------ Customization Functions ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Use the functions below to customize certain parts of the base or to add new custom systems
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
function ENT:CustomOnInitialize() end
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
function ENT:CustomOnSetControlledNPC() end
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
function ENT:CustomOnThink() end
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Different from self:CustomOnKeyBindPressed(), this uses: https://wiki.facepunch.com/gmod/Enums/KEY
|
||||
function ENT:CustomOnKeyPressed(key) end
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Different from self:CustomOnKeyPressed(), this uses: https://wiki.facepunch.com/gmod/Enums/IN
|
||||
function ENT:CustomOnKeyBindPressed(key) end
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
function ENT:CustomOnStopControlling() end
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
function ENT:CustomOnRemove() end
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
------ ///// WARNING: Don't touch anything below this line! \\\\\ ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
ENT.VJC_Data_Player = nil -- A hash table to hold all the values that need to be reset after the player stops controlling
|
||||
ENT.VJC_Data_NPC = nil -- A hash table to hold all the values that need to be reset after the NPC is uncontrolled
|
||||
ENT.VJC_Camera_Mode = 1 -- Current camera mode | 1 = Third, 2 = First
|
||||
ENT.VJC_Camera_CurZoom = Vector(0, 0, 0)
|
||||
ENT.VJC_Key_Last = BUTTON_CODE_NONE -- The last button the user pressed
|
||||
ENT.VJC_Key_LastTime = 0 -- Time since the user last pressed a key
|
||||
ENT.VJC_NPC_LastPos = Vector(0, 0, 0)
|
||||
ENT.VJC_NPC_LastIdleAngle = 0
|
||||
ENT.VJC_Removed = false
|
||||
|
||||
/* Important entities:
|
||||
- self.VJCE_Bullseye The bullseye entity used for the NPC to target
|
||||
- self.VJCE_Camera The camera object
|
||||
- self.VJCE_Player The player that's controlling
|
||||
- self.VJCE_NPC The NPC that's being controlled
|
||||
*/
|
||||
|
||||
util.AddNetworkString("vj_controller_data")
|
||||
util.AddNetworkString("vj_controller_cldata")
|
||||
util.AddNetworkString("vj_controller_hud")
|
||||
|
||||
local vecDef = Vector(0, 0, 0)
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
function ENT:Initialize()
|
||||
self:SetMoveType(MOVETYPE_NONE)
|
||||
self:SetSolid(SOLID_NONE)
|
||||
self:CustomOnInitialize()
|
||||
end
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
local color0000 = Color(0, 0, 0, 0)
|
||||
--
|
||||
function ENT:StartControlling()
|
||||
-- Set up the camera entity
|
||||
local npc = self.VJCE_NPC
|
||||
local camEnt = ents.Create("prop_dynamic")
|
||||
camEnt:SetPos(npc:GetPos() + Vector(0, 0, npc:OBBMaxs().z)) //npc:EyePos()
|
||||
camEnt:SetModel("models/props_junk/watermelon01_chunk02c.mdl")
|
||||
camEnt:SetParent(npc)
|
||||
camEnt:SetRenderMode(RENDERMODE_NONE)
|
||||
camEnt:Spawn()
|
||||
camEnt:SetColor(color0000)
|
||||
camEnt:SetNoDraw(false)
|
||||
camEnt:DrawShadow(false)
|
||||
self:DeleteOnRemove(camEnt)
|
||||
self.VJCE_Camera = camEnt
|
||||
|
||||
-- Set up the player
|
||||
local plyEnt = self.VJCE_Player
|
||||
plyEnt.IsControlingNPC = true
|
||||
plyEnt.VJ_TheControllerEntity = self
|
||||
plyEnt:Spectate(OBS_MODE_CHASE)
|
||||
plyEnt:SpectateEntity(camEnt)
|
||||
plyEnt:SetNoTarget(true)
|
||||
plyEnt:DrawShadow(false)
|
||||
plyEnt:SetNoDraw(true)
|
||||
plyEnt:SetMoveType(MOVETYPE_OBSERVER)
|
||||
plyEnt:DrawViewModel(false)
|
||||
plyEnt:DrawWorldModel(false)
|
||||
local weps = {}
|
||||
for _, v in ipairs(plyEnt:GetWeapons()) do
|
||||
weps[#weps+1] = v:GetClass()
|
||||
end
|
||||
self.VJC_Data_Player = {
|
||||
[1] = plyEnt:Health(),
|
||||
[2] = plyEnt:Armor(),
|
||||
[3] = weps,
|
||||
[4] = (IsValid(plyEnt:GetActiveWeapon()) and plyEnt:GetActiveWeapon():GetClass()) or "",
|
||||
}
|
||||
plyEnt:StripWeapons()
|
||||
if plyEnt:GetInfoNum("vj_npc_cont_diewithnpc", 0) == 1 then self.VJC_Player_CanRespawn = false end
|
||||
|
||||
hook.Add("PlayerButtonDown", self, function(ent, ply, button)
|
||||
if ply.IsControlingNPC == true && IsValid(ply.VJ_TheControllerEntity) then
|
||||
local cent = ply.VJ_TheControllerEntity
|
||||
cent.VJC_Key_Last = button
|
||||
cent.VJC_Key_LastTime = CurTime()
|
||||
cent:CustomOnKeyPressed(button)
|
||||
|
||||
-- Stop Controlling
|
||||
if cent.VJC_Player_CanExit == true and button == KEY_END then
|
||||
cent:StopControlling(true)
|
||||
end
|
||||
|
||||
-- Tracking
|
||||
if button == KEY_T then
|
||||
cent:ToggleBullseyeTracking()
|
||||
end
|
||||
|
||||
-- Camera mode
|
||||
if button == KEY_H then
|
||||
cent.VJC_Camera_Mode = (cent.VJC_Camera_Mode == 1 and 2) or 1
|
||||
end
|
||||
|
||||
-- Allow movement jumping
|
||||
if button == KEY_J then
|
||||
cent:ToggleMovementJumping()
|
||||
end
|
||||
|
||||
-- Zoom
|
||||
local zoom = ply:GetInfoNum("vj_npc_cont_zoomdist", 5)
|
||||
if button == KEY_LEFT then
|
||||
cent.VJC_Camera_CurZoom = cent.VJC_Camera_CurZoom - Vector(0, zoom, 0)
|
||||
elseif button == KEY_RIGHT then
|
||||
cent.VJC_Camera_CurZoom = cent.VJC_Camera_CurZoom + Vector(0, zoom, 0)
|
||||
elseif button == KEY_UP then
|
||||
cent.VJC_Camera_CurZoom = cent.VJC_Camera_CurZoom + (ply:KeyDown(IN_SPEED) and Vector(0, 0, zoom) or Vector(zoom, 0, 0))
|
||||
elseif button == KEY_DOWN then
|
||||
cent.VJC_Camera_CurZoom = cent.VJC_Camera_CurZoom - (ply:KeyDown(IN_SPEED) and Vector(0, 0, zoom) or Vector(zoom, 0, 0))
|
||||
end
|
||||
if button == KEY_BACKSPACE then
|
||||
cent.VJC_Camera_CurZoom = vecDef
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
hook.Add("KeyPress", self, function(ent, ply, key)
|
||||
//print(key)
|
||||
if ply.IsControlingNPC == true && IsValid(ply.VJ_TheControllerEntity) then
|
||||
local cent = ply.VJ_TheControllerEntity
|
||||
cent:CustomOnKeyBindPressed(key)
|
||||
end
|
||||
end)
|
||||
end
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
function ENT:SetControlledNPC(GetEntity)
|
||||
-- Set the bullseye entity values
|
||||
local bullseyeEnt = ents.Create("obj_vj_bullseye")
|
||||
bullseyeEnt:SetPos(GetEntity:GetPos() + GetEntity:GetForward()*100 + GetEntity:GetUp()*50)//Vector(GetEntity:OBBMaxs().x +20,0,GetEntity:OBBMaxs().z +20))
|
||||
bullseyeEnt:SetModel("models/hunter/blocks/cube025x025x025.mdl")
|
||||
//bullseyeEnt:SetParent(GetEntity)
|
||||
bullseyeEnt:SetRenderMode(RENDERMODE_NONE)
|
||||
bullseyeEnt:Spawn()
|
||||
bullseyeEnt:SetCollisionGroup(COLLISION_GROUP_IN_VEHICLE)
|
||||
bullseyeEnt.VJ_AlwaysEnemyToEnt = GetEntity
|
||||
bullseyeEnt:SetColor(color0000)
|
||||
bullseyeEnt:SetNoDraw(false)
|
||||
bullseyeEnt:DrawShadow(false)
|
||||
self:DeleteOnRemove(bullseyeEnt)
|
||||
self.VJCE_Bullseye = bullseyeEnt
|
||||
|
||||
-- Set the NPC values
|
||||
if !GetEntity.VJC_Data then
|
||||
GetEntity.VJC_Data ={
|
||||
CameraMode = 1, -- Sets the default camera mode | 1 = Third Person, 2 = First Person
|
||||
ThirdP_Offset = Vector(0, 0, 0), -- The offset for the controller when the camera is in third person
|
||||
FirstP_Bone = "ValveBiped.Bip01_Head1", -- If left empty, the base will attempt to calculate a position for first person
|
||||
FirstP_Offset = Vector(0, 0, 5), -- The offset for the controller when the camera is in first person
|
||||
FirstP_ShrinkBone = true, -- Should the bone shrink? Useful if the bone is obscuring the player's view
|
||||
}
|
||||
end
|
||||
local plyEnt = self.VJCE_Player
|
||||
self.VJC_Camera_Mode = GetEntity.VJC_Data.CameraMode -- Get the NPC's default camera mode
|
||||
self.VJC_NPC_LastPos = GetEntity:GetPos()
|
||||
GetEntity.VJ_IsBeingControlled = true
|
||||
GetEntity.VJ_TheController = plyEnt
|
||||
GetEntity.VJ_TheControllerEntity = self
|
||||
GetEntity.VJ_TheControllerBullseye = bullseyeEnt
|
||||
GetEntity:SetEnemy(NULL)
|
||||
GetEntity:VJ_Controller_InitialMessage(plyEnt, self)
|
||||
if GetEntity.IsVJBaseSNPC == true then
|
||||
GetEntity:Controller_Initialize(plyEnt, self)
|
||||
local EntityEnemy = GetEntity:GetEnemy()
|
||||
if IsValid(EntityEnemy) then
|
||||
GetEntity:AddEntityRelationship(EntityEnemy, D_NU, 10)
|
||||
EntityEnemy:AddEntityRelationship(GetEntity, D_NU, 10)
|
||||
GetEntity:ResetEnemy(false)
|
||||
GetEntity:SetEnemy(bullseyeEnt)
|
||||
end
|
||||
self.VJC_Data_NPC = {
|
||||
[1] = GetEntity.DisableWandering,
|
||||
[2] = GetEntity.DisableChasingEnemy,
|
||||
[3] = GetEntity.DisableTakeDamageFindEnemy,
|
||||
[4] = GetEntity.DisableTouchFindEnemy,
|
||||
[5] = GetEntity.DisableSelectSchedule,
|
||||
[6] = GetEntity.CallForHelp,
|
||||
[7] = GetEntity.CallForBackUpOnDamage,
|
||||
[8] = GetEntity.BringFriendsOnDeath,
|
||||
[9] = GetEntity.FollowPlayer,
|
||||
[10] = GetEntity.CanDetectDangers,
|
||||
[11] = GetEntity.Passive_RunOnTouch,
|
||||
[12] = GetEntity.Passive_RunOnDamage,
|
||||
[13] = GetEntity.IsGuard,
|
||||
}
|
||||
GetEntity.DisableWandering = true
|
||||
GetEntity.DisableChasingEnemy = true
|
||||
GetEntity.DisableTakeDamageFindEnemy = true
|
||||
GetEntity.DisableTouchFindEnemy = true
|
||||
GetEntity.DisableSelectSchedule = true
|
||||
GetEntity.CallForHelp = false
|
||||
GetEntity.CallForBackUpOnDamage = false
|
||||
GetEntity.BringFriendsOnDeath = false
|
||||
GetEntity.FollowPlayer = false
|
||||
GetEntity.CanDetectDangers = false
|
||||
GetEntity.Passive_RunOnTouch = false
|
||||
GetEntity.Passive_RunOnDamage = false
|
||||
GetEntity.IsGuard = false
|
||||
|
||||
GetEntity.vACT_StopAttacks = true
|
||||
GetEntity.NextThrowGrenadeT = 0
|
||||
end
|
||||
GetEntity:ClearSchedule()
|
||||
GetEntity:StopMoving()
|
||||
self.VJCE_NPC = GetEntity
|
||||
timer.Simple(0, function() -- This only needs to be 0 seconds because we just need a tick to pass
|
||||
if IsValid(self) && IsValid(self.VJCE_NPC) then
|
||||
self.VJCE_NPC.vACT_StopAttacks = false
|
||||
self.VJCE_NPC:SetEnemy(self.VJCE_Bullseye)
|
||||
end
|
||||
end)
|
||||
self:CustomOnSetControlledNPC()
|
||||
end
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Sadly no other way, this is the most reliable way to sync the position from client to server in time
|
||||
-- Also avoids garbage positions that output from other methods
|
||||
net.Receive("vj_controller_cldata", function(len, ply)
|
||||
-- Set the controller's bullseye position if the player is controlling an NPC AND controller entity exists AND Bullseye exists --> Protect against spam ?
|
||||
if ply.IsControlingNPC == true && IsValid(ply.VJ_TheControllerEntity) && IsValid(ply.VJ_TheControllerEntity.VJCE_Bullseye) then
|
||||
ply.VJ_TheControllerEntity.VJCE_Bullseye:SetPos(net.ReadVector())
|
||||
end
|
||||
end)
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
function ENT:SendDataToClient(reset)
|
||||
local ply = self.VJCE_Player
|
||||
local npc = self.VJCE_NPC
|
||||
local npcData = npc.VJC_Data
|
||||
|
||||
net.Start("vj_controller_data")
|
||||
net.WriteBool(ply.IsControlingNPC)
|
||||
net.WriteUInt((reset == true and nil) or self.VJCE_Camera:EntIndex(), 14)
|
||||
net.WriteUInt((reset == true and nil) or npc:EntIndex(), 14)
|
||||
net.WriteUInt((reset == true and 1) or self.VJC_Camera_Mode, 2)
|
||||
net.WriteVector((reset == true and vecDef) or (npcData.ThirdP_Offset + self.VJC_Camera_CurZoom))
|
||||
net.WriteVector((reset == true and vecDef) or npcData.FirstP_Offset)
|
||||
local bone = -1
|
||||
if reset != true then
|
||||
bone = npc:LookupBone(npcData.FirstP_Bone) or -1
|
||||
end
|
||||
net.WriteInt(bone, 10)
|
||||
net.WriteBool((reset != true and npcData.FirstP_ShrinkBone) or false)
|
||||
net.WriteUInt((reset != true and npcData.FirstP_CameraBoneAng) or 0, 2)
|
||||
net.WriteInt((reset != true and npcData.FirstP_CameraBoneAng_Offset) or 0, 10)
|
||||
net.Send(ply)
|
||||
end
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
local vecZ20 = Vector(0, 0, 20)
|
||||
local defAttackTypes = {MeleeAttack=false, RangeAttack=false, LeapAttack=false, WeaponAttack=false, GrenadeAttack=false, Ammo="---"}
|
||||
--
|
||||
function ENT:Think()
|
||||
local ply = self.VJCE_Player
|
||||
local npc = self.VJCE_NPC
|
||||
local camera = self.VJCE_Camera
|
||||
if (!camera:IsValid()) then self:StopControlling() return end
|
||||
if !IsValid(ply) /*or ply:KeyDown(IN_USE)*/ or ply:Health() <= 0 or (!ply.IsControlingNPC) or !IsValid(npc) or (npc:Health() <= 0) then self:StopControlling() return end
|
||||
if ply.IsControlingNPC != true then return end
|
||||
local curTime = CurTime()
|
||||
if ply.IsControlingNPC && IsValid(npc) then
|
||||
local npcWeapon = npc:GetActiveWeapon()
|
||||
self.VJC_NPC_LastPos = npc:GetPos()
|
||||
ply:SetPos(self.VJC_NPC_LastPos + vecZ20) -- Set the player's location
|
||||
self:SendDataToClient()
|
||||
|
||||
-- HUD
|
||||
local AttackTypes = defAttackTypes -- Optimization?
|
||||
if npc.IsVJBaseSNPC == true then
|
||||
if npc.HasMeleeAttack == true then AttackTypes["MeleeAttack"] = ((npc.IsAbleToMeleeAttack != true or npc.AttackType == VJ_ATTACK_MELEE) and 2) or true end
|
||||
if npc.HasRangeAttack == true then AttackTypes["RangeAttack"] = ((npc.IsAbleToRangeAttack != true or npc.AttackType == VJ_ATTACK_RANGE) and 2) or true end
|
||||
if npc.HasLeapAttack == true then AttackTypes["LeapAttack"] = ((npc.IsAbleToLeapAttack != true or npc.AttackType == VJ_ATTACK_LEAP) and 2) or true end
|
||||
if IsValid(npcWeapon) then AttackTypes["WeaponAttack"] = true AttackTypes["Ammo"] = npcWeapon:Clip1() end
|
||||
if npc.HasGrenadeAttack == true then AttackTypes["GrenadeAttack"] = (curTime <= npc.NextThrowGrenadeT and 2) or true end
|
||||
end
|
||||
if self.VJC_Player_DrawHUD then
|
||||
net.Start("vj_controller_hud")
|
||||
net.WriteBool(ply:GetInfoNum("vj_npc_cont_hud", 1) == 1)
|
||||
net.WriteFloat(npc:GetMaxHealth())
|
||||
net.WriteFloat(npc:Health())
|
||||
net.WriteString(npc:GetName())
|
||||
net.WriteTable(AttackTypes)
|
||||
net.Send(ply)
|
||||
end
|
||||
|
||||
if #ply:GetWeapons() > 0 then ply:StripWeapons() end
|
||||
-- Depreciated, the hit position is now sent by the net message
|
||||
/*local tr_ply = util.TraceLine({start = ply:EyePos(), endpos = ply:EyePos() + (ply:GetAimVector() * 32768), filter = {ply,npc}})
|
||||
if IsValid(self.VJCE_Bullseye) then
|
||||
self.VJCE_Bullseye:SetPos(tr_ply.HitPos)
|
||||
end*/
|
||||
local bullseyePos = self.VJCE_Bullseye:GetPos()
|
||||
if ply:GetInfoNum("vj_npc_cont_devents", 0) == 1 then
|
||||
VJ_CreateTestObject(ply:GetPos(), self:GetAngles(), Color(0,109,160))
|
||||
VJ_CreateTestObject(camera:GetPos(), self:GetAngles(), Color(255,200,260))
|
||||
VJ_CreateTestObject(bullseyePos, self:GetAngles(), Color(255,0,0)) -- Bullseye's position
|
||||
end
|
||||
|
||||
self:CustomOnThink()
|
||||
|
||||
local canTurn = true
|
||||
|
||||
-- Weapon attack
|
||||
if npc.IsVJBaseSNPC_Human == true then
|
||||
if IsValid(npcWeapon) && !npc:IsMoving() && npcWeapon.IsVJBaseWeapon == true && ply:KeyDown(IN_ATTACK2) && npc.AttackType == VJ_ATTACK_NONE && npc.vACT_StopAttacks == false && npc:GetWeaponState() == VJ_WEP_STATE_READY then
|
||||
//npc:SetAngles(Angle(0,math.ApproachAngle(npc:GetAngles().y,ply:GetAimVector():Angle().y,100),0))
|
||||
npc:FaceCertainPosition(bullseyePos, 0.2)
|
||||
canTurn = false
|
||||
if VJ_IsCurrentAnimation(npc, npc:TranslateToWeaponAnim(npc.CurrentWeaponAnimation)) == false && VJ_IsCurrentAnimation(npc, npc.AnimTbl_WeaponAttack) == false then
|
||||
npc:CustomOnWeaponAttack()
|
||||
npc.CurrentWeaponAnimation = VJ_PICK(npc.AnimTbl_WeaponAttack)
|
||||
npc:VJ_ACT_PLAYACTIVITY(npc.CurrentWeaponAnimation, false, 2, false)
|
||||
npc.DoingWeaponAttack = true
|
||||
npc.DoingWeaponAttack_Standing = true
|
||||
end
|
||||
end
|
||||
if !ply:KeyDown(IN_ATTACK2) then
|
||||
npc.DoingWeaponAttack = false
|
||||
npc.DoingWeaponAttack_Standing = false
|
||||
end
|
||||
end
|
||||
|
||||
if npc.Flinching == true or (((npc.CurrentSchedule && npc.CurrentSchedule.IsPlayActivity != true) or npc.CurrentSchedule == nil) && npc:GetNavType() == NAV_JUMP) then return end
|
||||
|
||||
if !npc.PlayingAttackAnimation && curTime > npc.NextChaseTime && npc.IsVJBaseSNPC_Tank != true then
|
||||
-- Turning
|
||||
if !npc:IsMoving() && canTurn && npc.MovementType != VJ_MOVETYPE_PHYSICS && ((npc.IsVJBaseSNPC_Human && npc:GetWeaponState() != VJ_WEP_STATE_RELOADING) or (!npc.IsVJBaseSNPC_Human)) then
|
||||
//npc:SetAngles(Angle(0,ply:GetAimVector():Angle().y,0))
|
||||
local angdif = math.abs(math.AngleDifference(ply:EyeAngles().y, self.VJC_NPC_LastIdleAngle))
|
||||
self.VJC_NPC_LastIdleAngle = npc:EyeAngles().y //tr_ply.HitPos
|
||||
npc:VJ_TASK_IDLE_STAND()
|
||||
if ((npc.MovementType != VJ_MOVETYPE_STATIONARY) or (npc.MovementType == VJ_MOVETYPE_STATIONARY && npc.CanTurnWhileStationary == true)) then
|
||||
if (VJ_AnimationExists(npc, ACT_TURN_LEFT) == false && VJ_AnimationExists(npc, ACT_TURN_RIGHT) == false) or (angdif <= 50 && npc:GetActivity() != ACT_TURN_LEFT && npc:GetActivity() != ACT_TURN_RIGHT) then
|
||||
//npc:VJ_TASK_IDLE_STAND()
|
||||
npc:FaceCertainPosition(bullseyePos, 0.1)
|
||||
else
|
||||
self.NextIdleStandTime = 0
|
||||
npc:SetLastPosition(bullseyePos) // ply:GetEyeTrace().HitPos
|
||||
npc:VJ_TASK_FACE_X("TASK_FACE_LASTPOSITION")
|
||||
end
|
||||
end
|
||||
//self.TestLerp = npc:GetAngles().y
|
||||
//npc:SetAngles(Angle(0,Lerp(100*FrameTime(),self.TestLerp,ply:GetAimVector():Angle().y),0))
|
||||
end
|
||||
|
||||
-- Movement
|
||||
npc:Controller_Movement(self, ply, bullseyePos)
|
||||
|
||||
//if (ply:KeyDown(IN_USE)) then
|
||||
//npc:StopMoving()
|
||||
//self:StopControlling()
|
||||
//end
|
||||
end
|
||||
end
|
||||
self:NextThink(curTime + (0.069696968793869 + FrameTime()))
|
||||
end
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
function ENT:StartMovement(Dir, Rot)
|
||||
local npc = self.VJCE_NPC
|
||||
local ply = self.VJCE_Player
|
||||
if npc:GetState() != VJ_STATE_NONE then return end
|
||||
|
||||
local DontMove = false
|
||||
local PlyAimVec = Dir
|
||||
PlyAimVec.z = 0
|
||||
PlyAimVec:Rotate(Rot)
|
||||
local NPCOrigin = npc:GetPos()
|
||||
local CenterToPos = npc:OBBCenter():Distance(npc:OBBMins()) + 20 // npc:OBBMaxs().z
|
||||
local NPCPos = NPCOrigin + npc:GetUp()*CenterToPos
|
||||
local groundSpeed = math.Clamp(npc:GetSequenceGroundSpeed(npc:GetSequence()), 300, 9999)
|
||||
local defaultFilter = {npc,ply,self}
|
||||
local forwardtr = util.TraceLine({start = NPCPos, endpos = NPCPos + PlyAimVec * groundSpeed, filter = defaultFilter})
|
||||
local forwardDist = NPCPos:Distance(forwardtr.HitPos)
|
||||
local CalculateWallToNPC = forwardDist - (npc:OBBMaxs().y) -- Use Y instead of X because X is left/right whereas Y is forward/backward
|
||||
|
||||
if ply:GetInfoNum("vj_npc_cont_devents", 0) == 1 then
|
||||
VJ_CreateTestObject(NPCPos, self:GetAngles(), Color(0,255,255)) -- NPC's calculated position
|
||||
VJ_CreateTestObject(forwardtr.HitPos, self:GetAngles(), Color(255,255,0)) -- forward trace position
|
||||
end
|
||||
if forwardDist >= 25 then
|
||||
local FinalPos = Vector((NPCOrigin+PlyAimVec*CalculateWallToNPC).x,(NPCOrigin+PlyAimVec*CalculateWallToNPC).y,forwardtr.HitPos.z)
|
||||
local downtr = util.TraceLine({start = FinalPos, endpos = FinalPos + self:GetUp()*-(200+CenterToPos), filter = defaultFilter})
|
||||
local CalculateDownDistance = (FinalPos.z-CenterToPos) - downtr.HitPos.z
|
||||
if CalculateDownDistance >= 150 then -- If the drop is this big, then don't move!
|
||||
DontMove = true
|
||||
CalculateWallToNPC = CalculateWallToNPC - CalculateDownDistance
|
||||
end
|
||||
FinalPos = Vector((NPCOrigin+PlyAimVec*CalculateWallToNPC).x, (NPCOrigin+PlyAimVec*CalculateWallToNPC).y, forwardtr.HitPos.z)
|
||||
if ply:GetInfoNum("vj_npc_cont_devents", 0) == 1 then
|
||||
VJ_CreateTestObject(downtr.HitPos, self:GetAngles(), Color(255,0,255)) -- Down trace position
|
||||
VJ_CreateTestObject(FinalPos, self:GetAngles(), Color(0,255,0)) -- Final move position
|
||||
end
|
||||
if DontMove == false then
|
||||
npc:SetLastPosition(FinalPos)
|
||||
local movetype = "TASK_WALK_PATH"
|
||||
if (ply:KeyDown(IN_SPEED)) then movetype = "TASK_RUN_PATH" end
|
||||
npc:VJ_TASK_GOTO_LASTPOS(movetype,function(x)
|
||||
if ply:KeyDown(IN_ATTACK2) && npc.IsVJBaseSNPC_Human == true then
|
||||
x.ConstantlyFaceEnemy = true
|
||||
x.CanShootWhenMoving = true
|
||||
else
|
||||
if self.VJC_BullseyeTracking == true then
|
||||
x.ConstantlyFaceEnemy = true
|
||||
else
|
||||
x:EngTask("TASK_FACE_LASTPOSITION", 0)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
function ENT:ToggleBullseyeTracking()
|
||||
if !self.VJC_BullseyeTracking then
|
||||
self.VJCE_Player:ChatPrint("#vjbase.print.npccontroller.tracking.activated")
|
||||
self.VJC_BullseyeTracking = true
|
||||
else
|
||||
self.VJCE_Player:ChatPrint("#vjbase.print.npccontroller.tracking.deactivated")
|
||||
self.VJC_BullseyeTracking = false
|
||||
end
|
||||
end
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
function ENT:ToggleMovementJumping()
|
||||
if !self.VJCE_NPC.AllowMovementJumping then
|
||||
self.VJCE_Player:ChatPrint("#vjbase.print.npccontroller.movementjump.enable")
|
||||
self.VJCE_NPC.AllowMovementJumping = true
|
||||
else
|
||||
self.VJCE_Player:ChatPrint("#vjbase.print.npccontroller.movementjump.disable")
|
||||
self.VJCE_NPC.AllowMovementJumping = false
|
||||
end
|
||||
end
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
function ENT:StopControlling(endKey)
|
||||
//if !IsValid(self.VJCE_Player) then return self:Remove() end
|
||||
endKey = endKey or false
|
||||
self:CustomOnStopControlling()
|
||||
|
||||
local npc = self.VJCE_NPC
|
||||
local ply = self.VJCE_Player
|
||||
if IsValid(ply) then
|
||||
local plyData = self.VJC_Data_Player
|
||||
ply:UnSpectate()
|
||||
ply:KillSilent() -- If we don't, we will get bugs like no being able to pick up weapons when walking over them.
|
||||
if self.VJC_Player_CanRespawn == true or endKey == true then
|
||||
ply:Spawn()
|
||||
ply:SetHealth(plyData[1])
|
||||
ply:SetArmor(plyData[2])
|
||||
for _, v in ipairs(plyData[3]) do
|
||||
ply:Give(v)
|
||||
end
|
||||
ply:SelectWeapon(plyData[4])
|
||||
end
|
||||
if IsValid(npc) then
|
||||
ply:SetPos(npc:GetPos() + npc:OBBMaxs() + vecZ20)
|
||||
else
|
||||
ply:SetPos(self.VJC_NPC_LastPos)
|
||||
end
|
||||
/*if IsValid(self.VJCE_Camera) then
|
||||
ply:SetPos(self.VJCE_Camera:GetPos() +self.VJCE_Camera:GetUp()*100) else
|
||||
ply:SetPos(ply:GetPos()) end*/
|
||||
ply:SetNoDraw(false)
|
||||
ply:DrawShadow(true)
|
||||
ply:SetNoTarget(false)
|
||||
//ply:Spectate(OBS_MODE_NONE)
|
||||
ply:DrawViewModel(true)
|
||||
ply:DrawWorldModel(true)
|
||||
//ply:SetMoveType(MOVETYPE_WALK)
|
||||
ply.IsControlingNPC = false
|
||||
ply.VJ_TheControllerEntity = NULL
|
||||
self:SendDataToClient(true)
|
||||
end
|
||||
self.VJCE_Player = NULL
|
||||
|
||||
if IsValid(npc) then
|
||||
local npcData = self.VJC_Data_NPC
|
||||
//npc:StopMoving()
|
||||
npc.VJ_IsBeingControlled = false
|
||||
npc.VJ_TheController = NULL
|
||||
npc.VJ_TheControllerEntity = NULL
|
||||
//npc:ClearSchedule()
|
||||
if npc.IsVJBaseSNPC == true then
|
||||
npc.DisableWandering = npcData[1]
|
||||
npc.DisableChasingEnemy = npcData[2]
|
||||
npc.DisableTakeDamageFindEnemy = npcData[3]
|
||||
npc.DisableTouchFindEnemy = npcData[4]
|
||||
npc.DisableSelectSchedule = npcData[5]
|
||||
npc.CallForHelp = npcData[6]
|
||||
npc.CallForBackUpOnDamage = npcData[7]
|
||||
npc.BringFriendsOnDeath = npcData[8]
|
||||
npc.FollowPlayer = npcData[9]
|
||||
npc.CanDetectDangers = npcData[10]
|
||||
npc.Passive_RunOnTouch = npcData[11]
|
||||
npc.Passive_RunOnDamage = npcData[12]
|
||||
npc.IsGuard = npcData[13]
|
||||
end
|
||||
end
|
||||
//self.VJCE_Camera:Remove()
|
||||
self.VJC_Removed = true
|
||||
self:Remove()
|
||||
end
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
function ENT:OnRemove()
|
||||
self:CustomOnRemove()
|
||||
if self.VJC_Removed == false then
|
||||
self:StopControlling()
|
||||
end
|
||||
net.Start("vj_controller_hud")
|
||||
net.WriteBool(false)
|
||||
net.WriteFloat(0)
|
||||
net.WriteFloat(0)
|
||||
net.WriteString(" ")
|
||||
net.WriteTable({})
|
||||
net.Broadcast()
|
||||
end
|
||||
212
lua/entities/obj_vj_npccontroller/shared.lua
Normal file
212
lua/entities/obj_vj_npccontroller/shared.lua
Normal file
@@ -0,0 +1,212 @@
|
||||
--[[
|
||||
| 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.PrintName = "NPC Controller Base"
|
||||
ENT.Author = "DrVrej"
|
||||
ENT.Contact = "http://steamcommunity.com/groups/vrejgaming"
|
||||
ENT.Purpose = "To make my (S)NPCs controllable."
|
||||
ENT.Instructions = "Don't change anything."
|
||||
ENT.Category = "VJ Base"
|
||||
|
||||
ENT.Spawnable = false
|
||||
ENT.AdminSpawnable = false
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
if CLIENT then
|
||||
function ENT:Draw() end
|
||||
|
||||
local vec0 = Vector(0, 0, 0)
|
||||
local vec1 = Vector(1, 1, 1)
|
||||
local viewLerpVec = Vector(0, 0, 0)
|
||||
local viewLerpAng = Angle(0, 0, 0)
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
hook.Add("CalcView", "VJ_MyCalcView", function(ply, origin, angles, fov)
|
||||
if !ply.IsControlingNPC then return end
|
||||
local camera = ply.VJCE_Camera -- Camera entity
|
||||
local npc = ply.VJCE_NPC -- The NPC that's being controlled
|
||||
if !IsValid(ply.VJCE_Camera) or !IsValid(ply.VJCE_NPC) then return end
|
||||
if IsValid(ply:GetViewEntity()) && ply:GetViewEntity():GetClass() == "gmod_cameraprop" then return end
|
||||
local cameraMode = ply.VJC_Camera_Mode
|
||||
|
||||
local pos = origin -- The position that will be set
|
||||
local ang = ply:EyeAngles()
|
||||
if cameraMode == 2 then -- First person
|
||||
local setPos = npc:EyePos() + npc:GetForward()*20
|
||||
local offset = ply.VJC_FP_Offset
|
||||
//camera:SetLocalPos(camera:GetLocalPos() + ply.VJC_TP_Offset) -- Help keep the camera stable
|
||||
if ply.VJC_FP_Bone != -1 then -- If the bone does exist, then use the bone position
|
||||
local bonePos, boneAng = npc:GetBonePosition(ply.VJC_FP_Bone)
|
||||
setPos = bonePos
|
||||
if ply.VJC_FP_CameraBoneAng > 0 then
|
||||
ang[3] = boneAng[ply.VJC_FP_CameraBoneAng] + ply.VJC_FP_CameraBoneAng_Offset
|
||||
end
|
||||
if ply.VJC_FP_ShrinkBone then
|
||||
npc:ManipulateBoneScale(ply.VJC_FP_Bone, vec0) -- Bone manipulate to make it easier to see
|
||||
end
|
||||
end
|
||||
pos = setPos + (npc:GetForward()*offset.x + npc:GetRight()*offset.y + npc:GetUp()*offset.z)
|
||||
else -- Third person
|
||||
if ply.VJC_FP_Bone != -1 then -- Reset the NPC's bone manipulation!
|
||||
ply.VJCE_NPC:ManipulateBoneScale(ply.VJC_FP_Bone, vec1)
|
||||
end
|
||||
local offset = ply.VJC_TP_Offset + Vector(0, 0, npc:OBBMaxs().z - npc:OBBMins().z) // + vectp
|
||||
//camera:SetLocalPos(camera:GetLocalPos() + ply.VJC_TP_Offset) -- Help keep the camera stable
|
||||
local tr = util.TraceHull({
|
||||
start = npc:GetPos() + npc:OBBCenter(),
|
||||
endpos = npc:GetPos() + npc:OBBCenter() + angles:Forward()*-camera.Zoom + (npc:GetForward()*offset.x + npc:GetRight()*offset.y + npc:GetUp()*offset.z),
|
||||
filter = {ply, camera, npc},
|
||||
mins = Vector(-5, -5, -5),
|
||||
maxs = Vector(5, 5, 5),
|
||||
mask = MASK_SHOT,
|
||||
})
|
||||
pos = tr.HitPos + tr.HitNormal*2
|
||||
end
|
||||
|
||||
if npc.Controller_CalcView then -- Allows custom calcview overrides
|
||||
local data = npc:Controller_CalcView(ply, pos, ang, fov, origin, angles, cameraMode)
|
||||
if data then
|
||||
pos = data.origin or pos
|
||||
ang = data.angles or ang
|
||||
fov = data.fov or fov
|
||||
end
|
||||
end
|
||||
|
||||
-- Lerp the position and the angle
|
||||
local lerpSpeed = ply:GetInfoNum("vj_npc_cont_cam_speed", 6)
|
||||
viewLerpVec = (cameraMode == 2 and pos) or LerpVector(FrameTime()*lerpSpeed, viewLerpVec, pos)
|
||||
viewLerpAng = LerpAngle(FrameTime()*lerpSpeed, viewLerpAng, ang)
|
||||
|
||||
-- Send the player's hit position to the controller entity
|
||||
local tr = util.TraceLine({start = viewLerpVec, endpos = viewLerpVec + viewLerpAng:Forward()*32768, filter = {ply, camera, npc}})
|
||||
//ParticleEffect("vj_impact1_centaurspit", tr.HitPos, Angle(0,0,0), npc)
|
||||
net.Start("vj_controller_cldata")
|
||||
net.WriteVector(tr.HitPos)
|
||||
net.SendToServer()
|
||||
|
||||
local view = {
|
||||
origin = viewLerpVec,
|
||||
angles = viewLerpAng,
|
||||
fov = fov,
|
||||
drawviewer = false, //(cameraMode == 2 and true) or false
|
||||
}
|
||||
return view
|
||||
end)
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
hook.Add("PlayerBindPress", "vj_controller_PlayerBindPress", function(ply, bind, pressed)
|
||||
-- For scroll wheel zooming
|
||||
if (bind == "invprev" or bind == "invnext") && ply.IsControlingNPC && IsValid(ply.VJCE_Camera) && ply.VJC_Camera_Mode != 2 then
|
||||
ply.VJCE_Camera.Zoom = ply.VJCE_Camera.Zoom or 100
|
||||
if bind == "invprev" then
|
||||
ply.VJCE_Camera.Zoom = math.Clamp(ply.VJCE_Camera.Zoom - ply:GetInfoNum("vj_npc_cont_cam_zoomspeed", 10), 0, 500)
|
||||
else
|
||||
ply.VJCE_Camera.Zoom = math.Clamp(ply.VJCE_Camera.Zoom + ply:GetInfoNum("vj_npc_cont_cam_zoomspeed", 10), 0, 500)
|
||||
end
|
||||
end
|
||||
end)
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
net.Receive("vj_controller_data", function(len)
|
||||
//print("Data Sent!")
|
||||
//print(len)
|
||||
local ply = LocalPlayer()
|
||||
ply.IsControlingNPC = net.ReadBool()
|
||||
ply.VJCE_Camera = ents.GetByIndex(net.ReadUInt(14))
|
||||
ply.VJCE_Camera.Zoom = ply.VJCE_Camera.Zoom or 100
|
||||
-- If the controller has stopped then reset the NPC's bone manipulation!
|
||||
if ply.IsControlingNPC == false && IsValid(ply.VJCE_NPC) && ply.VJC_FP_Bone != -1 then
|
||||
ply.VJCE_NPC:ManipulateBoneScale(ply.VJC_FP_Bone, vec1)
|
||||
end
|
||||
ply.VJCE_NPC = ents.GetByIndex(net.ReadUInt(14))
|
||||
ply.VJC_Camera_Mode = net.ReadUInt(2)
|
||||
ply.VJC_TP_Offset = net.ReadVector()
|
||||
ply.VJC_FP_Offset = net.ReadVector()
|
||||
ply.VJC_FP_Bone = net.ReadInt(10)
|
||||
ply.VJC_FP_ShrinkBone = net.ReadBool()
|
||||
ply.VJC_FP_CameraBoneAng = net.ReadUInt(2) or 0
|
||||
ply.VJC_FP_CameraBoneAng_Offset = net.ReadInt(10) or 0
|
||||
end)
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
local lerp_hp = 0
|
||||
local atk_col_red = Color(255, 60, 60, 255)
|
||||
local atk_col_orange = Color(204, 123, 60, 255)
|
||||
local atk_col_green = Color(60, 220, 60, 255)
|
||||
local mat_icon_melee = Material("vj_base/hud_controller/melee.png")
|
||||
local mat_icon_range = Material("vj_base/hud_controller/range.png")
|
||||
local mat_icon_leap = Material("vj_base/hud_controller/leap.png")
|
||||
local mat_icon_grenade = Material("vj_base/hud_controller/grenade.png")
|
||||
local mat_icon_gun = Material("vj_base/hud_controller/gun.png")
|
||||
local mat_icon_camera = Material("vj_base/hud_controller/camera.png")
|
||||
local mat_icon_zoom = Material("vj_base/hud_controller/camera_zoom.png")
|
||||
net.Receive("vj_controller_hud", function(len)
|
||||
//print(len)
|
||||
local enabled = net.ReadBool()
|
||||
local maxhp = net.ReadFloat()
|
||||
local hp = net.ReadFloat()
|
||||
local name = net.ReadString()
|
||||
local AtkTbl = net.ReadTable()
|
||||
local ply = LocalPlayer()
|
||||
hook.Add("HUDPaint", "vj_controller_HUD", function()
|
||||
draw.RoundedBox(1, ScrW() / 2.25, ScrH()-120, 220, 100, Color(0, 0, 0, 150))
|
||||
draw.SimpleText(name, "VJFont_Trebuchet24_SmallMedium", ScrW() / 2.21, ScrH()-115, Color(255,255,255,255), 0, 0)
|
||||
|
||||
local hp_r = 255
|
||||
local hp_g = 153
|
||||
local hp_b = 0
|
||||
lerp_hp = Lerp(5*FrameTime(),lerp_hp,hp)
|
||||
draw.RoundedBox(0, ScrW() / 2.21, ScrH()-95, 180, 20, Color(hp_r,hp_g,hp_b,40))
|
||||
draw.RoundedBox(0, ScrW() / 2.21, ScrH()-95, (190*math.Clamp(lerp_hp,0,maxhp))/maxhp,20, Color(hp_r,hp_g,hp_b,255))
|
||||
surface.SetDrawColor(hp_r,hp_g,hp_b,255)
|
||||
surface.DrawOutlinedRect( ScrW() / 2.21, ScrH()-95,180,20)
|
||||
|
||||
local finalhp = tostring(string.format("%.0f", lerp_hp).."/"..maxhp)
|
||||
local distlen = string.len(finalhp)
|
||||
local move = 0
|
||||
if distlen > 1 then
|
||||
move = move - (0.009*(distlen-1))
|
||||
end
|
||||
draw.SimpleText(finalhp, "VJFont_Trebuchet24_SmallMedium", ScrW() / (2-move), ScrH()-94, Color(255,255,255,255), 0, 0)
|
||||
|
||||
-- Attack Icons
|
||||
surface.SetMaterial(mat_icon_melee)
|
||||
surface.SetDrawColor((AtkTbl["MeleeAttack"] == false and atk_col_red) or ((AtkTbl["MeleeAttack"] == 2 and atk_col_orange) or atk_col_green))
|
||||
surface.DrawTexturedRect(ScrW() / 2.21, ScrH()-73, 28, 28)
|
||||
|
||||
surface.SetMaterial(mat_icon_range)
|
||||
surface.SetDrawColor((AtkTbl["RangeAttack"] == false and atk_col_red) or ((AtkTbl["RangeAttack"] == 2 and atk_col_orange) or atk_col_green))
|
||||
surface.DrawTexturedRect(ScrW() / 2.14, ScrH()-73, 28, 28)
|
||||
|
||||
surface.SetMaterial(mat_icon_leap)
|
||||
surface.SetDrawColor((AtkTbl["LeapAttack"] == false and atk_col_red) or ((AtkTbl["LeapAttack"] == 2 and atk_col_orange) or atk_col_green))
|
||||
surface.DrawTexturedRect(ScrW() / 2.065, ScrH()-73, 28, 28)
|
||||
|
||||
surface.SetMaterial(mat_icon_grenade)
|
||||
surface.SetDrawColor((AtkTbl["GrenadeAttack"] == false and atk_col_red) or ((AtkTbl["GrenadeAttack"] == 2 and atk_col_orange) or atk_col_green))
|
||||
surface.DrawTexturedRect(ScrW() / 2.005, ScrH()-73, 28, 28)
|
||||
|
||||
surface.SetMaterial(mat_icon_gun)
|
||||
surface.SetDrawColor((AtkTbl["WeaponAttack"] != true and atk_col_red) or ((AtkTbl["Ammo"] <= 0 and atk_col_orange) or atk_col_green))
|
||||
surface.DrawTexturedRect(ScrW() / 1.94, ScrH()-73, 28, 28) // 1.865
|
||||
draw.SimpleText(AtkTbl["Ammo"], "VJFont_Trebuchet24_Medium", ScrW() / 1.885, ScrH()-70, (AtkTbl["WeaponAttack"] != true and atk_col_red) or ((AtkTbl["Ammo"] <= 0 and atk_col_orange) or atk_col_green), 0, 0)
|
||||
|
||||
-- Camera
|
||||
surface.SetMaterial(mat_icon_camera)
|
||||
surface.SetDrawColor(Color(255, 255, 255, 255))
|
||||
surface.DrawTexturedRect(ScrW() / 2.21, ScrH()-45, 22, 22)
|
||||
draw.SimpleText((ply.VJC_Camera_Mode == 1 and "Third") or "First", "VJFont_Trebuchet24_SmallMedium", ScrW() / 2.155, ScrH()-43, Color(255, 255, 255, 255), 0, 0) // VJFont_Trebuchet24_SmallMedium
|
||||
|
||||
-- Zoom Camera
|
||||
surface.SetMaterial(mat_icon_zoom)
|
||||
surface.SetDrawColor(Color(255, 255, 255, 255))
|
||||
surface.DrawTexturedRect(ScrW() / 2.065, ScrH()-45, 22, 22)
|
||||
draw.SimpleText(ply.VJCE_Camera.Zoom, "VJFont_Trebuchet24_Medium", ScrW() / 2.005, ScrH()-45, Color(255, 255, 255, 255), 0, 0) // VJFont_Trebuchet24_SmallMedium
|
||||
end)
|
||||
if enabled != true then hook.Remove("HUDPaint", "vj_controller_HUD") end
|
||||
end)
|
||||
end
|
||||
Reference in New Issue
Block a user