Created
June 2, 2020 02:58
-
-
Save brandonsturgeon/c88ca76d0b22726253303a43b736f036 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local RED = Color(255, 0, 0, 235) | |
local BLUE = Color(0, 0, 255, 235) | |
local WHITE = Color(255, 255, 255, 230) | |
local beamColor = RED | |
local beams = {} | |
local claws = ents.FindByClass("npc_clawscanner") | |
local Sounds = { | |
Pursuing = { | |
name = "npc_clawscanner_pursuing", | |
channel = CHAN_STATIC, | |
volume = 1.0, | |
level = 60, | |
pitch = 100, | |
sound = "ambient/alarms/apc_alarm_loop1.wav" | |
} | |
} | |
sound.Add( Sounds.Pursuing ) | |
local function setRelationship(claw, ply, relationship) | |
if claw:Disposition( ply ) == relationship then return end | |
if not claw.RelationshipPriorities then | |
claw.RelationshipPriorities = {} | |
end | |
-- Our global AddRelationship starts at 45 | |
claw.RelationshipPriorities[ply] = claw.RelationshipPriorities[ply] or 45 | |
local prioIndex = claw.RelationshipPriorities[ply] + 1 | |
print(prioIndex) | |
claw:AddEntityRelationship(ply, relationship, prioIndex) | |
claw.RelationshipPriorities[ply] = prioIndex | |
end | |
local function newScanner( claw ) | |
claw:SetSaveValue("m_flModelScale", 0.5) | |
claw:SetSaveValue("m_flAttackRange", 2000) | |
claw:SetSaveValue("m_flAttackFarDist", 1600) | |
claw:SetSaveValue("SpotlightLength", 450) | |
claw:SetSaveValue("SpotlightWidth", 125) | |
claw:SetSaveValue("ignoreunseenenemies", true) | |
claw:SetSaveValue("OnlyInspectPlayers", true) | |
claw:AddRelationship("player D_LI 45") | |
for k, ply in pairs(player.GetHumans()) do | |
local isWanted = ply:getDarkRPVar("wanted") | |
if isWanted then | |
setRelationship(claw, ply, D_HT) | |
end | |
if claw:TestPVS(ply) then | |
claw:UpdateEnemyMemory(ply, ply:GetPos()) | |
end | |
end | |
table.insert(claws, claw) | |
end | |
hook.Remove("OnEntityCreated", "dothethingtothescanners") | |
hook.Add("OnEntityCreated", "dothethingtothescanners", function( ent ) | |
if not IsValid( ent ) then return end | |
if ent:GetClass() ~= "npc_clawscanner" then return end | |
timer.Simple(0, function() | |
newScanner( ent ) | |
end) | |
end ) | |
local function setOpen( claw ) | |
local isOpen = claw:GetSaveTable()["m_bIsOpen"] | |
if not isOpen then | |
claw:SetSaveValue("m_bIsOpen", true) | |
end | |
end | |
local function setClosed( claw ) | |
local isOpen = claw:GetSaveTable()["m_bIsOpen"] | |
if isOpen then | |
claw:SetSaveValue("m_bIsOpen", false) | |
end | |
end | |
local function targetEvaded(claw) | |
local target = claw:GetTarget() | |
claw:MarkEnemyAsEluded() | |
setRelationship(claw, target, D_LI) | |
claw:ClearEnemyMemory() | |
claw:ClearSchedule() | |
claw:ExitScriptedSequence() | |
claw:ClearGoal() | |
claw:LostEnemySound() | |
claw:SetSaveValue( "ShouldInspect", false ) | |
claw:Fire("ClearFollowTarget") | |
claw:SetSchedule( SCHED_IDLE_WANDER ) | |
-- Probably doesn't work | |
-- TODO: How the hell do we get this thing to clear its target | |
claw:SetSaveValue("m_hTargetEnt", NULL ) | |
setClosed( claw ) | |
end | |
local function stopSound(claw) | |
if claw.IsPlaying then | |
claw.IsPlaying = false | |
claw:StopSound( Sounds.Pursuing.name ) | |
end | |
end | |
local function startSound(claw) | |
if not claw.IsPlaying then | |
claw.IsPlaying = true | |
claw:EmitSound(Sounds.Pursuing.name) | |
end | |
end | |
local function setClawBeamColor(claw, col) | |
if IsValid( claw.beam ) then claw.beam:SetColor( col ) end | |
end | |
local function handleTargetInteraction(claw) | |
local target = claw:GetTarget() | |
if not IsValid( target ) then | |
stopSound(claw) | |
setClawBeamColor(claw, WHITE) | |
return | |
end | |
if not target:IsPlayer() then | |
stopSound(claw) | |
targetEvaded(claw) | |
setClawBeamColor(claw, WHITE) | |
return | |
end | |
local targetIsWanted = target:getDarkRPVar( "wanted" ) | |
local canSeeTarget = claw:TestPVS( target ) | |
if not targetIsWanted then | |
stopSound(claw) | |
targetEvaded(claw) | |
setClawBeamColor(claw, WHITE) | |
return | |
end | |
if canSeeTarget then | |
startSound(claw) | |
setOpen( claw ) | |
setClawBeamColor(claw, beamColor) | |
claw:SetSaveValue( "ShouldInspect", true ) | |
claw.lastSeenTarget = CurTime() | |
for k, v in pairs(claws) do | |
claw:UpdateEnemyMemory(target, target:GetPos()) | |
end | |
return | |
end | |
local hasEvaded = claw.lastSeenTarget and claw.lastSeenTarget <= CurTime() - 5 | |
if hasEvaded then | |
print("Target evaded us (last seen too long ago") | |
stopSound(claw) | |
targetEvaded(claw) | |
setClawBeamColor(claw, WHITE) | |
end | |
end | |
timer.Remove("claw-target-think") | |
timer.Create("claw-target-think", 0.5, 0, function() | |
beamColor = ( beamColor == RED and BLUE ) or RED | |
for k, claw in pairs(claws) do | |
if IsValid( claw ) then | |
handleTargetInteraction( claw ) | |
else | |
table.remove( claws, k ) | |
end | |
end | |
end) | |
--[[ | |
hook.Add("Think", "ClearClawTargets", function() | |
for k, claw in pairs( claws ) do | |
if IsValid( claw ) then | |
local target = claw:GetTarget() | |
if not ( target and IsValid( target ) and target:IsPlayer() and target:getDarkRPVar( "wanted" ) == true ) then | |
print("Target isn't valid or isn't wanted. Clearing") | |
targetEvaded( claw ) | |
print("Ran Target Evaded") | |
if claw:GetCurrentSchedule() ~= SCHED_IDLE_WANDER then | |
print("Forcing IDLE WANDER") | |
claw:ClearSchedule() | |
claw:SetSchedule(SCHED_IDLE_WANDER) | |
end | |
end | |
else | |
table.remove( claws, k ) | |
end | |
end | |
end ) | |
--]] | |
timer.Remove("clawtest") | |
timer.Create("clawtest", 0.1, 0, function() | |
for k, claw in pairs(claws) do | |
if IsValid( claw ) then | |
local target = claw:GetTarget() | |
if target and IsValid( target ) and target:IsPlayer() then | |
local isWanted = target:getDarkRPVar( "wanted" ) | |
if isWanted then | |
-- Next attack is the next Flash, setting it to 0 seems to force an instant flash | |
claw:SetSaveValue("m_flNextAttack", math.Rand(0, 0.1)) | |
claw:SetSaveValue( "m_flNextFlinchTime", 0 ) | |
-- Seems to fire at -9ish seconds for some reason | |
claw:SetSaveValue("m_fNextSpotlightTime", -9) | |
claw:SetSaveValue( "m_bPerformAvoidance", true ) | |
claw:SetSaveValue( "m_bPlayerAvoidState", true ) | |
else | |
targetEvaded( claw ) | |
end | |
end | |
else | |
table.remove( claws, k ) | |
end | |
end | |
end) | |
hook.Remove("OnEntityCreated", "ClawTest") | |
hook.Add("OnEntityCreated", "ClawTest", function(ent) | |
if ent:GetClass() ~= "beam" then return end | |
timer.Simple( 0, function() | |
if not IsValid( ent ) then return end | |
local ownerEnt = ent:GetSaveTable()["m_hOwnerEntity"] | |
if not IsValid( ownerEnt ) then return end | |
if ownerEnt:GetClass() ~= "npc_clawscanner" then return end | |
beams[ent] = true | |
ownerEnt.beam = ent | |
end) | |
end) | |
hook.Remove("EntityRemoved", "ClawTest3") | |
hook.Add("EntityRemoved", "ClawTest3", function(ent) | |
if beams[ent] then | |
beams[ent] = nil | |
local ownerEnt = ent:GetSaveTable()["m_pParent"] | |
if not IsValid( ownerEnt ) then return end | |
ownerEnt.beam = nil | |
return | |
end | |
if table.HasValue(claws, ent) then | |
stopSound( ent ) | |
table.RemoveByValue( claws, ent ) | |
end | |
end) | |
hook.Remove("DarkRPVarChanged", "Clawtest4") | |
hook.Add("DarkRPVarChanged", "Clawtest4", function(ply, var, old, new) | |
if var ~= "wanted" then return end | |
-- Has become wanted | |
if new == true then | |
for k, claw in pairs( claws ) do | |
if IsValid( claw ) then | |
claw:ClearEnemyMemory() | |
setRelationship(claw, ply, D_HT) | |
claw:UpdateEnemyMemory(ply, ply:GetPos()) | |
claw:NavSetGoalTarget( ply, Vector(100,100,100) ) | |
if not claw:GetTarget() then | |
claw:SetTarget( ply ) | |
claw:SetSaveValue( "ShouldInspect", true ) | |
end | |
end | |
end | |
return | |
end | |
-- Has become unwanted | |
for k, claw in pairs( claws ) do | |
if IsValid( claw ) then | |
if claw:GetTarget() == ply then | |
targetEvaded( claw ) | |
end | |
setRelationship(claw, ply, D_LI) | |
else | |
table.remove( claws, k ) | |
end | |
end | |
end) | |
hook.Add("PostEntityTakeDamage", "ClawTakeDamage", function( ent, dmg, took ) | |
if not took then return end | |
if ent:GetClass() ~= "npc_clawscanner" then return end | |
local attacker = dmg:GetAttacker() | |
if not IsValid( attacker ) then return end | |
if not attacker:IsPlayer() then return end | |
local isWanted = attacker:getDarkRPVar( "wanted" ) | |
if isWanted then return end | |
attacker:setDarkRPVar( "wanted", true ) | |
attacker:setDarkRPVar( "wantedReason", "Attacking government property" ) | |
end ) | |
local recipientJobs = { ["Civil Protection"] = true, ["Civil Protection Chief"] = true, ["Mayor"] = true } | |
-- Destruction detection | |
hook.Remove("OnNPCKilled", "ClawScannerDestroyed") | |
hook.Add("OnNPCKilled", "ClawScannerDestroyed", function( killedEnt, attacker, inflictor ) | |
print("Ent killed: " .. killedEnt:GetClass()) | |
if not IsValid( killedEnt ) then return end | |
if killedEnt:GetClass() ~= "npc_clawscanner" then return end | |
local recipients = {} | |
for k, ply in pairs(player.GetAll()) do | |
local job = team.GetName( ply:Team() ) | |
if recipientJobs[job] then table.insert(recipients, ply) end | |
end | |
--[[ | |
net.Start("CPScannerKilled") | |
net.WriteEntity(killedEnt) | |
net.Send(recipients) | |
--]] | |
end) | |
for k, claw in pairs( claws ) do | |
if IsValid( claw ) then | |
newScanner( claw ) | |
else | |
table.remove( claws, k ) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment