diff options
| author | Alexander Pickering <alexandermpickering@gmail.com> | 2016-05-30 20:51:42 -0400 |
|---|---|---|
| committer | Alexander Pickering <alexandermpickering@gmail.com> | 2016-05-30 20:51:42 -0400 |
| commit | c38f00182ba6c282806eecb39a42e64d5feafa37 (patch) | |
| tree | 016d2755c750b1b276edbbde46117b5eb49de544 | |
| parent | 87c27d81d9c7feda1f5fe70e6ced2ddc367b0dc6 (diff) | |
| download | redead-c38f00182ba6c282806eecb39a42e64d5feafa37.tar.gz redead-c38f00182ba6c282806eecb39a42e64d5feafa37.tar.bz2 redead-c38f00182ba6c282806eecb39a42e64d5feafa37.zip | |
Prevented scientest npc from useing invalid navigation object
| -rw-r--r-- | entities/entities/npc_scientist/shared.lua | 414 | ||||
| -rw-r--r-- | gamemode/moddable.lua | 5 |
2 files changed, 210 insertions, 209 deletions
diff --git a/entities/entities/npc_scientist/shared.lua b/entities/entities/npc_scientist/shared.lua index a39a533..d9d76dd 100644 --- a/entities/entities/npc_scientist/shared.lua +++ b/entities/entities/npc_scientist/shared.lua @@ -12,17 +12,17 @@ ENT.BaseHealth = 100 ENT.MoveSpeed = 175 ENT.MoveAnim = ACT_RUN -ENT.Models = { Model( "models/characters/hostage_04.mdl" ), Model( "models/kleiner.mdl" ) } +ENT.Models = { Model( "models/characters/hostage_04.mdl" ), Model( "models/kleiner.mdl" ) } ENT.Legs = Model( "models/zombie/classic_legs.mdl" ) -ENT.Pain = { "vo/k_lab/kl_ahhhh.wav", -"vo/k_lab/kl_dearme.wav", +ENT.Pain = { "vo/k_lab/kl_ahhhh.wav", +"vo/k_lab/kl_dearme.wav", "vo/k_lab/kl_getoutrun02.wav", "vo/k_lab/kl_interference.wav", "vo/k_lab/kl_mygoodness01.wav", "vo/k_lab/kl_ohdear.wav" } -ENT.Death = { "vo/k_lab/kl_ahhhh.wav", +ENT.Death = { "vo/k_lab/kl_ahhhh.wav", "vo/k_lab/kl_getoutrun03.wav", "vo/k_lab/kl_hedyno03.wav", "vo/k_lab2/kl_greatscott.wav", @@ -60,17 +60,19 @@ function ENT:Initialize() local model = table.Random( self.Models ) self.Entity:SetModel( model ) - + self.Entity:SetHealth( self.BaseHealth ) self.Entity:SetCollisionGroup( COLLISION_GROUP_NPC ) - self.Entity:SetCollisionBounds( Vector(-4,-4,0), Vector(4,4,64) ) - - self.loco:SetDeathDropHeight( 1000 ) - self.loco:SetAcceleration( 500 ) - + self.Entity:SetCollisionBounds( Vector(-4,-4,0), Vector(4,4,64) ) + + if ! self.loco then return end + + self.loco:SetDeathDropHeight( 1000 ) + self.loco:SetAcceleration( 500 ) + self.LastPos = self.Entity:GetPos() self.Stuck = CurTime() + 10 - + end function ENT:Heal( ply ) @@ -84,50 +86,50 @@ function ENT:Heal( ply ) end function ENT:Think() - + if ( self.Stuck or 0 ) < CurTime() then - + self.Entity:StuckThink() - + self.Stuck = CurTime() + 10 - self.LastPos = self.Entity:GetPos() - + self.LastPos = self.Entity:GetPos() + end - + if self.Entity:OnFire() and self.FireDamageTime < CurTime() then - + self.FireDamageTime = CurTime() + 0.25 - + self.Entity:TakeDamage( 10, self.FireAttacker ) - + elseif self.FireSound and not self.Entity:OnFire() then - + self.Entity:StopFireSounds() - + end - + if ( self.ZombieTimer or 0 ) < CurTime() then - + self.ZombieTimer = CurTime() + 10 - + if self.Entity:NearZombie() then - + self.Entity:VoiceSound( self.Alert ) - + end - + end - + if self.CurAttack and self.CurAttack < CurTime() then - + self.CurAttack = nil - + if IsValid( self.CurEnemy ) and self.Entity:CanAttack( self.CurEnemy ) then - + self.Entity:Heal( self.CurEnemy ) - + end - + end end @@ -135,13 +137,13 @@ end function ENT:NearZombie() for k,v in pairs( ents.FindByClass( "npc_nb*" ) ) do - + if v:GetPos():Distance( self.Entity:GetPos() ) < 300 then - + return v - + end - + end end @@ -149,9 +151,9 @@ end function ENT:StuckThink() self.LastPos = self.LastPos or Vector(0,0,0) if self.LastPos:Distance( self.Entity:GetPos() ) < 50 then - + self.Entity:Respawn() - + end end @@ -159,31 +161,31 @@ end function ENT:Respawn() for k,v in pairs( GAMEMODE.NPCSpawns ) do - + if IsValid( v ) then - + local box = ents.FindInBox( v:GetPos() + Vector( -32, -32, 0 ), v:GetPos() + Vector( 32, 32, 64 ) ) local can = true - + for k,v in pairs( box ) do - + if v.NextBot then - + can = false - + end - + end - - if can then - + + if can then + self.Entity:SetPos( v:GetPos() ) return - + end - + end - + end end @@ -193,37 +195,37 @@ function ENT:OnLimbHit( hitgroup, dmginfo ) if not IsValid( self.Entity ) then return end if hitgroup == HITGROUP_HEAD then - + self.Entity:EmitSound( self.HeadshotNoise, 80, math.random( 100, 120 ) ) self.Entity:SetHeadshotter( dmginfo:GetAttacker(), true ) - + local effectdata = EffectData() effectdata:SetOrigin( dmginfo:GetDamagePosition() ) util.Effect( "headshot", effectdata, true, true ) - - dmginfo:ScaleDamage( 2.75 ) - + + dmginfo:ScaleDamage( 2.75 ) + elseif hitgroup == HITGROUP_CHEST then - - dmginfo:ScaleDamage( 1.25 ) - + + dmginfo:ScaleDamage( 1.25 ) + self.Entity:SetHeadshotter( dmginfo:GetAttacker(), false ) dmginfo:GetAttacker():ResetHeadshots() - + elseif hitgroup == HITGROUP_STOMACH then - - dmginfo:ScaleDamage( 0.75 ) - + + dmginfo:ScaleDamage( 0.75 ) + self.Entity:SetHeadshotter( dmginfo:GetAttacker(), false ) dmginfo:GetAttacker():ResetHeadshots() - + else - + dmginfo:ScaleDamage( 0.50 ) - + self.Entity:SetHeadshotter( dmginfo:GetAttacker(), false ) dmginfo:GetAttacker():ResetHeadshots() - + end end @@ -231,69 +233,69 @@ end function ENT:OnInjured( dmginfo ) if dmginfo:IsExplosionDamage() then - + dmginfo:ScaleDamage( 1.75 ) - + elseif not self.Entity:OnFire() then - + local snd = table.Random( GAMEMODE.GoreBullet ) sound.Play( snd, self.Entity:GetPos() + Vector(0,0,50), 75, math.random( 90, 110 ), 1.0 ) - + end self.Entity:AddDamageTaken( dmginfo:GetAttacker(), dmginfo:GetDamage() ) - + if self.Entity:Health() > 0 and math.random(1,2) == 1 then - + self.Entity:VoiceSound( self.Pain ) - + end - + local att = dmginfo:GetAttacker() - + if IsValid( att ) and att.NextBot then - + //self.Entity:OnKilled( dmginfo ) - + end - -end + +end function ENT:SpawnRagdoll( dmginfo, model, pos, override ) timer.Simple( 0.2, function() if IsValid( self.Entity ) then self.Entity:Remove() end end ) if not model then - + self.Entity:BecomeRagdoll( dmginfo ) - + else - + local ang = self.Entity:GetAngles() - + local shooter = ents.Create( "env_shooter" ) shooter:SetPos( pos or self.Entity:GetPos() ) shooter:SetKeyValue( "m_iGibs", "1" ) shooter:SetKeyValue( "shootsounds", "3" ) shooter:SetKeyValue( "gibangles", ang.p.." "..ang.y.." "..ang.r ) shooter:SetKeyValue( "angles", ang.p.." "..ang.y.." "..ang.r ) - shooter:SetKeyValue( "shootmodel", model ) + shooter:SetKeyValue( "shootmodel", model ) shooter:SetKeyValue( "simulation", "2" ) shooter:SetKeyValue( "gibanglevelocity", math.random(-50,50).." "..math.random(-150,150).." "..math.random(-150,150) ) shooter:SetKeyValue( "m_flVelocity", tostring( math.Rand( -20, 20 ) ) ) shooter:SetKeyValue( "m_flVariance", tostring( math.Rand( -2, 2 ) ) ) - + shooter:Spawn() - + shooter:Fire( "shoot", 0, 0 ) shooter:Fire( "kill", 0.1, 0.1 ) - + if not override then - + self.Entity:Remove() - + end - + end end @@ -301,130 +303,130 @@ end function ENT:OnKilled( dmginfo ) if self.Dying then return end - + self.Dying = true - + self.Entity:OnDeath( dmginfo ) self.Entity:SetNWBool( "Dead", true ) - + if dmginfo then - + local ent1 = self.Entity:GetHighestDamager() - + if IsValid( ent1 ) then - + if dmginfo:IsExplosionDamage() then - + local snd = table.Random( GAMEMODE.GoreSplash ) self.Entity:EmitSound( snd, 90, math.random( 60, 80 ) ) - + local effectdata = EffectData() effectdata:SetOrigin( self.Entity:GetPos() + Vector(0,0,20) ) util.Effect( "body_gib", effectdata, true, true ) - + local ed = EffectData() ed:SetOrigin( self.Entity:GetPos() ) util.Effect( "gore_explosion", ed, true, true ) - + local corpse = table.Random( GAMEMODE.Corpses ) self.Entity:SpawnRagdoll( dmginfo, corpse ) - + elseif ent1:HasShotgun() and ent1:GetPos():Distance( self.Entity:GetPos() ) < 100 then - + local snd = table.Random( GAMEMODE.GoreSplash ) self.Entity:EmitSound( snd, 90, math.random( 60, 80 ) ) - + local effectdata = EffectData() effectdata:SetOrigin( self.Entity:GetPos() + Vector(0,0,20) ) util.Effect( "body_gib", effectdata, true, true ) - + self.Entity:SpawnRagdoll( dmginfo, self.Legs ) - + elseif ent1:HasMelee() then - + self.Entity:VoiceSound( self.Death ) self.Entity:SpawnRagdoll( dmginfo ) - + if self.Entity:OnFire() then - + umsg.Start( "Burned" ) umsg.Vector( self.Entity:GetPos() ) umsg.End() - + end - + elseif self.Entity:GetHeadshotter( ent1 ) then //self.HeadshotEffects - + local snd = table.Random( GAMEMODE.GoreSplash ) self.Entity:EmitSound( snd, 90, math.random( 90, 110 ) ) - + local effectdata = EffectData() effectdata:SetOrigin( self.Entity:GetPos() + Vector(0,0,40) ) util.Effect( "head_gib", effectdata, true, true ) - + umsg.Start( "Headless" ) umsg.Vector( self.Entity:GetPos() ) umsg.End() - + if self.Entity:OnFire() then - + umsg.Start( "Burned" ) umsg.Vector( self.Entity:GetPos() ) umsg.End() - + end - + self.Entity:SpawnRagdoll( dmginfo ) - + else - + self.Entity:VoiceSound( self.Death ) self.Entity:SpawnRagdoll( dmginfo ) - + if self.Entity:OnFire() then - + umsg.Start( "Burned" ) umsg.Vector( self.Entity:GetPos() ) umsg.End() - + end - + end - + else - + self.Entity:SpawnRagdoll( dmginfo ) - + end - + end - + end function ENT:OnDeath( dmginfo ) for i=1, math.random(1,3) do - + local tbl = item.RandomItem( ITEM_SUPPLY ) - + local prop = ents.Create( "prop_physics" ) prop:SetPos( self.Entity:GetPos() + Vector(0,0,30) + VectorRand() * 5 ) prop:SetModel( tbl.Model ) prop:SetCollisionGroup( COLLISION_GROUP_WEAPON ) prop:Spawn() - + end - + if math.random(1,4) != 1 then - + local model = table.Random{ "models/healthvial.mdl", "models/items/healthkit.mdl" } - + local prop = ents.Create( "prop_physics" ) prop:SetPos( self.Entity:GetPos() + Vector(0,0,30) + VectorRand() * 5 ) prop:SetModel( model ) prop:SetCollisionGroup( COLLISION_GROUP_WEAPON ) prop:Spawn() - + end end @@ -438,21 +440,21 @@ end function ENT:DoIgnite( att ) if self.Entity:OnFire() then return end - + if IsValid( att ) and att:IsPlayer() and att:Team() == TEAM_ARMY then - + att:AddStat( "Igniter" ) - + end - + self.FireTime = CurTime() + 5 self.FireAttacker = att self.FireSound = true - + local ed = EffectData() ed:SetEntity( self.Entity ) util.Effect( "immolate", ed, true, true ) - + self.Entity:EmitSound( table.Random( GAMEMODE.Burning ), 100, 80 ) self.Entity:EmitSound( GAMEMODE.BurnFlesh ) @@ -469,18 +471,18 @@ function ENT:AddDamageTaken( attacker, dmg ) if not attacker:IsPlayer() then return end if not self.DmgTable[ attacker ] then - + self.DmgTable[ attacker ] = {} self.DmgTable[ attacker ].Dmg = dmg - + elseif not self.DmgTable[ attacker ].Dmg then - + self.DmgTable[ attacker ].Dmg = dmg - + else - + self.DmgTable[ attacker ].Dmg = self.DmgTable[ attacker ].Dmg + dmg - + end end @@ -488,7 +490,7 @@ end function ENT:GetHeadshotter( attacker ) if not self.DmgTable[ attacker ] then return false end - + return self.DmgTable[ attacker ].Headshot end @@ -496,11 +498,11 @@ end function ENT:SetHeadshotter( attacker, head ) if not self.DmgTable[ attacker ] then - + self.DmgTable[ attacker ] = {} - + end - + self.DmgTable[ attacker ].Headshot = head end @@ -511,18 +513,18 @@ function ENT:GetHighestDamager() local high = 0 for k,v in pairs( self.DmgTable ) do - + if IsValid( k ) and v.Dmg and v.Dmg > high then - + high = v.Dmg ent1 = k - + end - + end return ent1 - + end function ENT:VoiceSound( tbl ) @@ -530,10 +532,10 @@ function ENT:VoiceSound( tbl ) if ( self.VoiceTime or 0 ) > CurTime() then return end self.VoiceTime = CurTime() + 1.5 - + local snd = table.Random( tbl ) sound.Play( snd, self.Entity:GetPos() + Vector(0,0,50), 75, 100, 0.7 ) - + end function ENT:StartAttack( enemy ) @@ -568,67 +570,67 @@ end function ENT:FindHuman() local tbl = team.GetPlayers( TEAM_ARMY ) - + self.EnemyTable = tbl if #tbl < 1 then - + return NULL - + else - + local enemy = NULL local dist = 99999 - + for k,v in pairs( tbl ) do - + local compare = v:GetPos():Distance( self.Entity:GetPos() ) - + if compare < dist and self.Entity:CanTarget( v ) then - + enemy = v dist = compare - + end - + end - + return enemy - + end - + end function ENT:CanAttack( ent ) - return IsValid( ent ) and self.Entity:CanTarget( ent ) and ent:GetPos():Distance( self.Entity:GetPos() ) <= self.HealDistance + return IsValid( ent ) and self.Entity:CanTarget( ent ) and ent:GetPos():Distance( self.Entity:GetPos() ) <= self.HealDistance end function ENT:CanAttackEnemy( ent ) if self.Entity:CanAttack( ent ) then - + return ent - + end if #self.EnemyTable < 1 then return end for k,v in pairs( self.EnemyTable ) do - + if self.Entity:CanAttack( v ) then - + return v - + end - + end end function ENT:OnStuck() - + //self.loco:ClearStuck() self.Entity:VoiceSound( self.Alert ) @@ -650,16 +652,16 @@ end function ENT:EnemyRoutine() local closest = self.Entity:CanAttackEnemy( enemy ) - + while IsValid( closest ) do - + self.Entity:StartAttack( closest ) self.Entity:PlaySequenceAndWait( "open_door_away", self.AnimSpeed ) - + coroutine.wait( 1.0 ) - + closest = self.Entity:CanAttackEnemy( closest ) - + end end @@ -667,33 +669,33 @@ end function ENT:RunBehaviour() while true do - - self.Entity:StartActivity( self.MoveAnim ) + + self.Entity:StartActivity( self.MoveAnim ) self.loco:SetDesiredSpeed( self.MoveSpeed ) - + local enemy = self.Entity:FindHuman() - + if not IsValid( enemy ) then - + self.Entity:MoveToPos( self.Entity:GetPos() + Vector( math.Rand( -1, 1 ), math.Rand( -1, 1 ), 0 ) * 500 ) - self.Entity:StartActivity( ACT_IDLE ) - + self.Entity:StartActivity( ACT_IDLE ) + else - + local opts = { draw = self.ShouldDrawPath, maxage = 1, tolerance = self.HealDistance } - - self.Entity:MoveToPos( enemy:GetPos(), opts ) - - self.Entity:StartActivity( ACT_IDLE ) - + + self.Entity:MoveToPos( enemy:GetPos(), opts ) + + self.Entity:StartActivity( ACT_IDLE ) + self.Entity:EnemyRoutine() - - self.Entity:StartActivity( ACT_IDLE ) - + + self.Entity:StartActivity( ACT_IDLE ) + end - + coroutine.yield() - + end - + end diff --git a/gamemode/moddable.lua b/gamemode/moddable.lua index a5cdfeb..a089bdb 100644 --- a/gamemode/moddable.lua +++ b/gamemode/moddable.lua @@ -13,7 +13,7 @@ GM.BloodName = "BLOOD" GM.ShopName = "UNCLE VIKTOR'S RUSSKI WEAPON SHOPPE" GM.ShopDesc = "A HAPPY CUSTOMER IS A DEAD ONE!" -// Team names +// Team names GM.ArmyTeamName = "Unit 9" GM.ZombieTeamName = "The Undead" @@ -217,7 +217,7 @@ GM.PlayerZombieKillValue = 3 // Human movespeeds -GM.WalkSpeed = 175 +GM.WalkSpeed = 175 GM.RunSpeed = 250 // Chances to spawn each zombie type ( from 100 to 0 %) @@ -235,4 +235,3 @@ GM.Waves[1] = { "npc_nb_common" } GM.Waves[2] = { "npc_nb_common", "npc_nb_leaper" } GM.Waves[3] = { "npc_nb_common", "npc_nb_contagion", "npc_nb_leaper" } GM.Waves[4] = { "npc_nb_common", "npc_nb_contagion", "npc_nb_leaper", "npc_nb_poison" } - |
