Advertisement
Guest User

Untitled

a guest
Mar 26th, 2015
211
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 36.29 KB | None | 0 0
  1. local AI = {}
  2.  
  3.  
  4. AI.Name = "Librarian"
  5.  
  6. function AI:Spawn(pos)
  7. local ENT = ents.Create("rp_enemy")
  8. ENT:SetModel("models/zombie/poison.mdl")
  9.  
  10. ENT:SetPos(pos + Vector(0,0,30))
  11. ENT.Damage = 40
  12.  
  13. ENT.BumpSpeed = 700
  14. ENT.AnimSpeed = 0.3
  15. ENT.AttackTime = 0.2
  16. ENT.AttackDelay = 1
  17. ENT.BaseHealth = 2000
  18. ENT:SetHealth(ENT.BaseHealth)
  19. ENT.MaxAttackDelay = 0.6
  20. ENT.MeleeDistance = 84
  21. ENT.BreakableDistance = 86
  22. ENT.MoveSpeed = 60
  23. ENT.RunSpeed = 200
  24. ENT:SetColor(Color(255,255,255,255))
  25. ENT:SetCollisionBounds(Vector(-1,-1,0),Vector(1,1,50))
  26. ENT.AttackRow = 0
  27.  
  28. --local e = RP:HandleClothing(ENT,"models/zombie/classic_torso.mdl",5)
  29. -- e:SetColor(Color(50,50,50,255))
  30.  
  31. --[[
  32. local ent = ents.Create("status_overridemodel")
  33. if ent:IsValid() then
  34. ent:Spawn()
  35.  
  36. ent:SetPlayer(ENT)
  37. if ent and ent:IsValid() then
  38.  
  39. ent:SetModel("models/zombie/poison.mdl")
  40.  
  41. end
  42. end
  43. ]]--
  44.  
  45.  
  46. ENT.NextFoot = nil
  47. ENT.oldposzslaaa = Vector(0,0,0)
  48. ENT.pitchy = math.random(90,110);
  49.  
  50. function ENT:OnInjured( dmginfo )
  51. self.lastDmginfo = dmginfo
  52. self.NoEnemyTime = 0
  53. self.AggLevel = self.AggLevel + 20
  54. if not self.Angered then
  55. for k,v in pairs(ents.FindInSphere(self:GetPos(),800)) do if v.IsZombie then v.Angered = true end end
  56. self.Angered = true
  57. end
  58. self:SetAngles(self:GetAngles() + Angle(0,math.random(-60,60),0))
  59. self.washeadshot = false
  60. if self.Climbing then
  61. self:UnClimb()
  62. self:KnockDown(3)
  63. end
  64. if IsValid(dmginfo:GetAttacker()) then
  65. if dmginfo:GetAttacker():IsPlayer() then self.Injured = true
  66. self.Enemy = dmginfo:GetAttacker() self.EnemyCur = CurTime() + 10 end
  67. if dmginfo:GetDamagePosition().z > self:GetPos().z + 60 then
  68. dmginfo:ScaleDamage(3)
  69. self.washeadshot = true
  70. self:SetHeadshotter(dmginfo:GetAttacker(),true)
  71. else
  72. self:SetHeadshotter(dmginfo:GetAttacker(),false)
  73. end
  74.  
  75. end
  76. if dmginfo:IsDamageType(DMG_BURN) and self.FireProof then
  77. dmginfo:SetDamage(0) return
  78. end
  79.  
  80.  
  81. if dmginfo:IsBulletDamage() then
  82.  
  83. if dmginfo:GetDamage() > 30 then
  84. self:EmitSound("npc/infected/gore/bullets/bullet_gib_0" .. math.random(1,8) .. ".wav",70,math.random(90,110))
  85.  
  86. else
  87. self:EmitSound("npc/infected/gore/bullets/bullet_impact_0" .. math.random(1,8) .. ".wav",70,math.random(90,110))
  88. end
  89.  
  90.  
  91. end
  92. if dmginfo:IsExplosionDamage() then
  93.  
  94. dmginfo:ScaleDamage( 1.75 )
  95.  
  96. elseif not self.Entity:IsOnFire() then
  97.  
  98. local snd = "physics/flesh/flesh_impact_bullet" .. math.random(1,5) .. ".wav"
  99. sound.Play( snd, self.Entity:GetPos() + Vector(0,0,50), 75, math.random( 90, 110 ), 1.0 )
  100.  
  101. end
  102.  
  103. //self.Entity:SetHealth( math.Clamp( self.Entity:Health() - dmginfo:GetDamage(), 0, 1000 ) )
  104. self.Entity:AddDamageTaken( dmginfo:GetAttacker(), dmginfo:GetDamage() )
  105.  
  106.  
  107. if ( IsValid( dmginfo:GetAttacker() ) and dmginfo:GetAttacker():GetClass() == "trigger_hurt") or self:Health() < 0 or self:Health() <= dmginfo:GetDamage() then
  108.  
  109. self.Entity:OnKilled(dmginfo)
  110.  
  111. return
  112.  
  113. end
  114.  
  115. end
  116. function ENT:OnDeath()
  117.  
  118. end
  119. function ENT:CanTarget( v )
  120.  
  121. return ( ( v:IsPlayer() and v:Alive() and ( v:CanBeTarget(self) or self.Injured or self:GetPos():Distance(v:GetPos()) < 200) ) or ( v.NextBot ) or (not v:IsPlayer() ))
  122.  
  123. end
  124. ENT:SetName("rp_librarian")
  125.  
  126. function ENT:SpawnRagdoll( damageinfo, model, pos, override )
  127. if IsValid(self._ragdoll) then self:SetPos(self._ragdoll:GetPos()) end
  128. timer.Simple( 0.2, function() if IsValid( self.Entity ) then self.Entity:Remove() end end )
  129.  
  130. if not model and damageinfo:GetDamage() <= 300 then
  131.  
  132. --[[umsg.Start( "Ragdoll" )
  133. umsg.Vector( self.Entity:GetPos() )
  134.  
  135. if self.Entity:OnFire() then
  136.  
  137. umsg.Short(2)
  138.  
  139. else
  140.  
  141. umsg.Short(1)
  142.  
  143. end
  144.  
  145. umsg.Short( self.Entity:EntIndex() )
  146. umsg.End()
  147.  
  148. //self:Fire( "BecomeRagdoll", "", 0 ) ]]
  149.  
  150. if not damageinfo:IsDamageType(DMG_CLUB) and not damageinfo:IsDamageType(DMG_SLASH) then
  151. local e = self.Entity if IsValid(damageinfo:GetAttacker()) then e = damageinfo:GetAttacker() end
  152. local sc = math.max(10,1000 - self.Entity:GetPos():Distance(e:GetPos()))
  153.  
  154. if not self.washeadshot then
  155. damageinfo:SetDamageForce( damageinfo:GetDamageForce():Angle():Forward() * (damageinfo:GetDamage() * sc * 0.1 ))
  156. end end self.Entity:EmitSound("npc/infected/gore/bullets/bullet_gib_0" .. math.random(1,9) .. ".wav",100,math.random(90,110))
  157.  
  158. if self.washeadshot then
  159. local pofs,fasa = self:GetBonePosition(self:LookupBone("ValveBiped.Bip01_Head1"))
  160.  
  161. if pofs then
  162. local dmginfo = damageinfo
  163.  
  164. local effectdata = EffectData()
  165. effectdata:SetOrigin(dmginfo:GetDamagePosition())
  166. local force = dmginfo:GetDamageForce()
  167. effectdata:SetMagnitude(force:Length() * 3)
  168. effectdata:SetNormal(force:GetNormalized())
  169. effectdata:SetEntity(self.Entity)
  170. effectdata:SetScale(0.5)
  171. util.Effect("headshot", effectdata, true, true)
  172. end
  173. end
  174.  
  175. local a = ents.Create("prop_ragdoll")
  176.  
  177. a:SetModel(self:GetModel())
  178.  
  179. a:SetSkin(self:GetSkin())
  180. a:SetMaterial(self:GetMaterial())
  181. a:SetColor(self:GetColor())
  182. a:SetPos(self:GetPos())
  183. a:SetAngles(self:GetAngles())
  184.  
  185. a:Spawn()
  186. a.notFound = true
  187. a.Heal = 3000
  188. a:SetCollisionGroup(COLLISION_GROUP_WORLD)
  189. local ENT = a
  190. local head = RP.HandleGears(ENT,"models/Gibs/Antlion_gib_Large_2.mdl","chest",Vector(20,2,0),Angle( 0, 10,-90),Vector(0.6,0.7,0.6) * 1.1)
  191. local head2 = RP.HandleGears(ENT,"models/Gibs/Antlion_gib_Large_2.mdl","chest",Vector(20,-2,0),Angle( 0, -10, 90),Vector(0.6,0.7,0.6 ) * 1.1)
  192. head:SetColor(Color(150,110,0,255))
  193. head2:SetColor(Color(150,110,0,255))
  194.  
  195. ENT:ManipulateBoneScale(ENT:LookupBone("ValveBiped.Bip01_L_UpperArm"),Vector(2,2,2))
  196. ENT:ManipulateBoneScale(ENT:LookupBone("ValveBiped.Bip01_R_UpperArm"),Vector(2,2,2))
  197. ENT:ManipulateBoneScale(ENT:LookupBone("ValveBiped.Bip01_L_Foot"),Vector(2,2,2))
  198. ENT:ManipulateBoneScale(ENT:LookupBone("ValveBiped.Bip01_R_Foot"),Vector(2,2,2))
  199. local ply = self
  200. local rag = a
  201. -- position the bones
  202. local num = rag:GetPhysicsObjectCount()-1
  203. local v = ply:GetVelocity() + ( damageinfo:GetDamageForce() )
  204.  
  205. -- bullets have a lot of force, which feels better when shooting props,
  206. -- but makes bodies fly, so dampen that here
  207. if pofs then
  208. if math.random(1,2) == 2 then
  209. local f = ents.Create("prop_physics")
  210. f:SetModel("models/gibs/hgibs.mdl")
  211. f:SetPos(pofs + Vector(0,0,30))
  212. f:SetAngles(self:GetAngles())
  213. f:Spawn()
  214. f:SetCollisionGroup(COLLISION_GROUP_WORLD)
  215. a:EmitSound("runner/nhzombie_headexplode_jet.wav")
  216.  
  217. timer.Create("bloodysak",0.4,6,function()
  218. if IsValid(f) then
  219. util.Blood(f:GetPos(), math.random(2), Vector(0, 0, 1), 100, 1, true)
  220.  
  221. end
  222. end)
  223. f:SetMaterial("models/flesh")
  224. f:GetPhysicsObject():Wake()
  225. local v = v * 2
  226. v.z = math.max(100,v.z)
  227. f:GetPhysicsObject():SetVelocity(v )
  228. f:Fire("kill",5,5,5)
  229. end
  230. end if damageinfo:IsDamageType(DMG_BULLET) or damageinfo:IsDamageType(DMG_SLASH) then
  231. v = v / 10
  232. end
  233. for i=0, num do
  234. local bone = rag:GetPhysicsObjectNum(i)
  235. if IsValid(bone) then
  236. local bp, ba = ply:GetBonePosition(rag:TranslatePhysBoneToBone(i))
  237. if bp and ba then
  238. bone:SetPos(bp)
  239. bone:SetAngles(ba)
  240. end
  241.  
  242. -- not sure if this will work:
  243. bone:SetVelocity(v)
  244. end
  245. end
  246.  
  247. if pofs then
  248. if v:Length() <= 50 then
  249. rag:Fire("disablemotion")
  250. rag:Fire("enablemotion",0.2,0.2,0.2) end
  251. local d = self:LookupBone("ValveBiped.Bip01_Head1")
  252. rag:ManipulateBoneScale(d,Vector(0,0,0))
  253. end
  254. rag:Fire("kill",15,15,15)
  255.  
  256. self:Remove()
  257.  
  258.  
  259.  
  260. else
  261.  
  262. local ang = self.Entity:GetAngles()
  263. if IsValid(self._ragdoll) then self._ragdoll:Remove() end
  264. if self.alrey then return end
  265. self.alrey = true
  266. if (ZSL.NextGib or 0) < CurTime() or #ents.FindByClass("env_shooter") < 5 then
  267. ZSL.NextGib = CurTime() + 1
  268. local shooter = ents.Create( "env_shooter" )
  269. shooter:SetPos( pos or self.Entity:GetPos() )
  270. shooter:SetKeyValue( "m_iGibs", "1" )
  271. shooter:SetKeyValue( "shootsounds", "3" )
  272. shooter:SetKeyValue( "gibangles", ang.p.." "..ang.y.." "..ang.r )
  273. shooter:SetKeyValue( "angles", ang.p.." "..ang.y.." "..ang.r )
  274. shooter:SetKeyValue( "model",model)
  275. shooter:SetKeyValue( "simulation", "2" )
  276. shooter:SetKeyValue( "gibanglevelocity", math.random(-50,50).." "..math.random(-150,150).." "..math.random(-150,150) )
  277. shooter:SetKeyValue( "m_flVelocity", tostring( math.Rand( -20, 20 ) ) )
  278. shooter:SetKeyValue( "m_flVariance", tostring( math.Rand( -2, 2 ) ) )
  279. shooter:SetName("zenv_shooter")
  280. shooter:Spawn()
  281.  
  282. shooter:Fire( "shoot", 0, 0 )
  283. shooter:Fire( "kill", 0.1, 0.1 )
  284. end
  285. if not override then
  286.  
  287. self.Entity:Remove()
  288.  
  289. end
  290.  
  291. end
  292. end
  293. ENT.NoFriendTable = {}
  294. ENT.FriendTable = {}
  295. ENT.NoEnemyTime = 0
  296. ENT.FriendMeter = 0
  297. function ENT:FindEnemy()
  298.  
  299. if self.OnFindEnemy then
  300. local e = self:OnFindEnemy() if e and IsValid(e) then return e end end
  301. local tbl = RP:GetCharacterPlayers()
  302. if IsValid(self.Enemy) and (self.EnemyCur or 0) >= CurTime() then
  303. return self.Enemy
  304. else
  305. self.EnemyCur = 0
  306. end
  307.  
  308. self.EnemyTable = tbl
  309.  
  310. if #tbl < 1 then
  311. self.wasshot = false;
  312. return NULL,true
  313.  
  314. else
  315.  
  316. local enemy = NULL
  317. local dist = self.Angered and 1000 or 800
  318. if self.NoEnemyTime > CurTime() then
  319. dist = 150
  320. end
  321. for k,v in pairs( tbl ) do
  322.  
  323. local compare = v:GetPos():Distance( self.Entity:GetPos() )
  324.  
  325. if compare < dist and self.Entity:CanTarget( v ) and not v.notFound then
  326. if self.FriendTable[v:EntIndex()] and self.FriendTable[v:EntIndex()][2] >= CurTime() and compare > 150 then
  327.  
  328. else
  329. self.FriendTable[v:EntIndex()] = nil
  330. enemy = v
  331. dist = compare
  332.  
  333. end
  334.  
  335. end
  336.  
  337. end
  338. if IsValid(enemy) then
  339. if self.Target != enemy then
  340. self.IgnoreTime = CurTime() + 5
  341. self.FriendMeter = 0
  342. self:Growl()
  343. self.AggLevel = (self.AggLevel + 4)
  344. self.FoundEnemy = true
  345. if IsValid(self.Target) then
  346. self.NoFriendTable[self.Target:EntIndex()] = self.AggLevel
  347. end
  348. if self.NoFriendTable[enemy:EntIndex()] then
  349. self.AggLevel = self.NoFriendTable[enemy:EntIndex()]
  350.  
  351. end
  352. -- self:EmitSound("runner/nhguard_charge" .. math.random(1,2) .. ".mp3",100,100)
  353.  
  354. else
  355.  
  356. end
  357.  
  358.  
  359. self.LastKnownPos = enemy:GetPos()
  360. self.Target = enemy
  361. return enemy
  362.  
  363. end end
  364.  
  365. end
  366. function ENT:CanAttack( ent )
  367.  
  368. return IsValid( ent ) and self.Entity:CanTarget( ent ) and ent:GetPos():Distance( self.Entity:GetPos() + Vector(0,0,50) ) <= (self.MeleeDistance + math.Clamp( ent:GetVelocity():Length() ,0,50)) * 1.2 and (not ent:IsPlayer() or self.Entity:MeleeTrace( ent ))
  369.  
  370. end
  371.  
  372. function ENT:MeleeTrace( ent )
  373. if (ent:GetPos():Distance(self:GetPos()) < 100) then return true end
  374. local trace = {}
  375. trace.start = self.Entity:GetPos() + Vector(0,0,67)
  376. trace.endpos = ent:GetPos() + Vector(0,0,67)
  377. trace.filter = { ent, self.Entity }
  378.  
  379. local tr = util.TraceLine( trace )
  380.  
  381. if not tr.Hit then
  382.  
  383. return true
  384.  
  385. end
  386. if tr.Entity == ent then return true end
  387. if tr.HitWorld or tr.Entity:GetClass() == "prop_door_rotating" or tr.Entity:GetClass() == "func_breakable" or tr.Entity:GetClass() == "func_physbox" or tr.Entity:GetClass() == "func_breakable_surf" then
  388.  
  389. return false
  390.  
  391. end
  392.  
  393. return true
  394.  
  395. end
  396. ENT.CollisionCode = 2338
  397. function ENT:CanAttackEnemy( ent )
  398.  
  399. if self.Entity:CanAttack( ent ) then
  400.  
  401. return ent
  402.  
  403. end
  404.  
  405. if #self.EnemyTable < 1 then return end
  406.  
  407. for k,v in pairs( self.EnemyTable ) do
  408.  
  409. if self.Entity:CanAttack( v ) then
  410.  
  411. return v
  412.  
  413. end
  414.  
  415. end
  416.  
  417. end
  418.  
  419. function ENT:GetBreakable()
  420. --
  421. --local tbl = ents.FindByModel( "models/props_debris/wood_board04a.mdl" )
  422. -- tbl = table.Add(tbl,ents.FindByClass("func_physbox"))
  423. --tbl = table.Add( tbl, table.Copy( GAMEMODE.Breakables ) )
  424.  
  425. local remove
  426. local p = self:GetPos()
  427. for k,v in pairs(ents.FindInSphere(p + Vector(0,0,50), self.BreakableDistance * 0.7 )) do
  428.  
  429. if IsValid(v) and (table.HasValue( RP.Breakables, v) or table.HasValue( RP.PropBreakableClasses,v:GetClass())) and v:Visible(self) then
  430.  
  431. return v
  432. end
  433. end
  434. --[[
  435. for k,v in pairs( tbl ) do
  436.  
  437. if IsValid( v ) and v:GetPos() != Vector(0,0,0) and v:GetPos():Distance( self.Entity:GetPos() ) <= self.BreakableDistance then
  438.  
  439. return v
  440.  
  441. end
  442.  
  443. end
  444. ]]--
  445. local trace = {}
  446. trace.start = self.Entity:GetPos() + Vector(0,0,50)
  447. trace.endpos = trace.start + self.Entity:GetForward() * self.BreakableDistance
  448. trace.filter = self.Entity
  449.  
  450. local tr = util.TraceLine( trace )
  451.  
  452. if table.HasValue( RP.Breakables, tr.Entity ) or (IsValid(tr.Entity) and table.HasValue( RP.PropBreakableClasses,tr.Entity:GetClass() )) then
  453.  
  454. return tr.Entity
  455.  
  456. end
  457.  
  458. return NULL
  459.  
  460. end
  461. ENT.isZombie = true
  462. function ENT:OnStuck()
  463.  
  464. local ent = self.Entity:GetBreakable()
  465.  
  466. if IsValid( ent ) then
  467.  
  468. self.Obstructed = true
  469.  
  470. else
  471.  
  472. self.Obstructed = false
  473.  
  474. self.loco:SetDesiredSpeed( self.BumpSpeed )
  475. self.loco:Jump()
  476. self.loco:SetDesiredSpeed( self.BumpSpeed )
  477.  
  478. end
  479.  
  480. self.loco:ClearStuck()
  481.  
  482. end
  483.  
  484. function ENT:OnUnStuck()
  485.  
  486. self.Obstructed = false
  487.  
  488. end
  489.  
  490. function ENT:BreakableRoutine() if IsValid(self._ragdoll) then
  491. return
  492. end
  493. if self.CurAttackDelay >= CurTime() then self:PlaySequenceAndWait("ACT_HL2MP_IDLE_ZOMBIE",1.5) return end
  494. local ent = self.Entity:GetBreakable()
  495.  
  496. if IsValid(ent) and self:WorldToLocal(ent:GetPos()).x > 0 then
  497. local anim = "ACT_IDLE"
  498. --if self.Entity:CanAttackEnemy( ent ) then
  499. if (not self.CurAttack or self.CurAttack <= CurTime()) and (self.CurAttackDelay <= CurTime()) then
  500. self.Entity:StartAttack( ent )
  501.  
  502. self.CurAttackDelay = CurTime() + 0.1
  503. end
  504. -- ent = self.Entity:GetBreakable()
  505. --else
  506. --break
  507. --end
  508. end
  509.  
  510. end
  511. ENT.CurAttackDelay = 0
  512. function ENT:FindSpots( tbl )
  513.  
  514. local tbl = tbl or {}
  515.  
  516. tbl.pos = tbl.pos or self:WorldSpaceCenter()
  517. tbl.radius = tbl.radius or 1000
  518. tbl.stepdown = tbl.stepdown or 20
  519. tbl.stepup = tbl.stepup or 20
  520. tbl.type = tbl.type or 'hiding'
  521.  
  522. -- Use a path to find the length
  523. local path = Path( "Follow" )
  524.  
  525. -- Find a bunch of areas within this distance
  526. local areas = navmesh.Find( tbl.pos, tbl.radius, tbl.stepdown, tbl.stepup )
  527.  
  528. local found = {}
  529.  
  530. -- In each area
  531. for _, area in pairs( areas ) do
  532.  
  533. -- get the spots
  534. local spots
  535.  
  536. if ( tbl.type == 'hiding' ) then spots = area:GetHidingSpots() end
  537.  
  538. for k, vec in pairs( spots ) do
  539.  
  540. -- Work out the length, and add them to a table
  541. path:Invalidate()
  542.  
  543. path:Compute( self, vec, 1 ) -- TODO: This is bullshit - it's using 'self.pos' not tbl.pos
  544.  
  545. table.insert( found, { vector = vec, distance = (path:GetLength() == 0 and vec:Distance(pos) or path:GetLength()) } )
  546.  
  547. end
  548.  
  549. end
  550.  
  551. return found
  552.  
  553. end
  554. function ENT:StartAttack( enemy )
  555.  
  556. self.Stuck = CurTime() + 10
  557.  
  558. self.CurAttack = CurTime() + self.AttackTime
  559.  
  560. self.AttackRow = self.AttackRow + 1
  561.  
  562. self.CurEnemy = enemy
  563. --self.Entity:SetPlaybackRate(0.8)
  564. self.Entity:RestartGesture(ACT_MELEE_ATTACK1)
  565.  
  566. self.CurAttackDelay = CurTime() + self.AttackDelay
  567.  
  568. --self.Entity:SetPlaybackRate(0.8)
  569. -- self.Entity:sVoiceSound( self.VoiceSounds.Attack )
  570.  
  571. end
  572. ENT.DmgTable = {}
  573. function ENT:OnHitEnemy( enemy )
  574. local dmg = DamageInfo()
  575. self.AggLevel = self.AggLevel - 5
  576. local dd = IsValid(self.weapon) and self.weapon.Damage or self.Damage
  577. if enemy:GetPos().z > self:GetPos().z + 50 then return end
  578. if enemy:IsPlayer() then
  579. -- if self.Targetsa != enemy then
  580. -- self.Targetsa = enemy
  581. -- enemy:SendLua("LocalPlayer():EmitSound([[runner/weird1.wav]],500,90)")
  582. -- end
  583. -- if (enemy.lastAttacked or 0) < CurTime() then
  584. -- enemy.lastAttacked = CurTime() + 15
  585. --end
  586. if (enemy.nextBeingPushed or 0) < CurTime() then enemy.nextBeingPushed = CurTime() + 0.5 enemy:ViewPunch(Angle(math.random(-6,6) ,math.random(-6,6),math.random(-2,2)) * self.Damage)
  587. local tac = {}
  588. tac.start = enemy:GetShootPos()
  589. tac.endpos = tac.start - ((enemy:GetForward() * 200) + Vector(0,0,200))
  590. tac.filter = {enemy,self}
  591. local tr = util.TraceLine(tac)
  592. local f = 300
  593. if tr.HitPos.z + 120 < tac.start.z then f = 500 end
  594. enemy.was_pushed = self
  595. enemy.last_pushed = CurTime() + 2
  596. enemy:SetVelocity(((enemy:GetPos() + Vector(0,0,5)) - self:GetPos()):Angle():Forward() * (f)) end
  597. if enemy:WorldToLocal(self:GetPos()).x < 0 then
  598. dd = dd * 4
  599.  
  600. end
  601. else
  602. dd = dd * 3
  603. end
  604. enemy:SetLocalVelocity(Vector(0,0,0))
  605. dmg:SetDamage(dd + (enemy:IsPlayer() and enemy:Armor() > 0 and 0 or 5))
  606. dmg:SetAttacker(self)
  607. dmg:SetInflictor(self.Inflictor and self.Inflictor or self)
  608. dmg:SetDamageType(self.DamageType and self.DamageType or DMG_CLUB)
  609. dmg:SetDamageForce(self:GetForward() * 50)
  610.  
  611. enemy:TakeDamageInfo(dmg)
  612. end
  613. function ENT:PlayHitSound()
  614. self:EmitSound("npc/infected/hit/hit_punch_0" .. math.random(1,8) .. ".wav",70) end
  615.  
  616. function ENT:EnemyRoutine() if IsValid(self._ragdoll) then
  617. return
  618. end
  619. local closest = self.Entity:CanAttackEnemy( enemy )
  620. -- if self:GetVelocity():Length() <= 4 then self:SetVelocity((self:GetForward() + Vector(0,0,0.01)) * 400) end
  621. if closest and (not self.CurAttack or self.CurAttack <= CurTime()) and (self.CurAttackDelay <= CurTime()) then
  622.  
  623. -- local anim = "ACT_HL2MP_IDLE_ZOMBIE" -- table.Random( self.AttackAnims )
  624.  
  625. self.Entity:StartAttack( closest )
  626. //self.Entity:StartActivity( ACT_MELEE_ATTACK1 )
  627. end
  628.  
  629.  
  630. end
  631.  
  632. ENT.LastPos = ENT:GetPos()
  633. ENT.sLastPos = ENT:GetPos()
  634. function ENT:StuckThink()
  635.  
  636. -- if self.LastPos:Distance( self.Entity:GetPos() ) < 50 then
  637. --self:DropToFloor()
  638. -- self.Entity:StartRespawn()
  639. -- end
  640.  
  641. end
  642. ENT.AggLevel = 0
  643. ENT.Aggrm = 0
  644. ENT.Aggr = 0
  645. ENT.ClawMiss = {"npc/zombie/claw_miss1.wav","npc/zombie/claw_miss2.wav"}
  646. ENT.IgnoreTime = 0
  647. ENT.ClawHit = {"physics/flesh/phys_bullet_impact_flesh_01.wav","physics/flesh/phys_bullet_impact_flesh_02.wav","physics/flesh/phys_bullet_impact_flesh_03.wav"}
  648. function ENT:Think()
  649. if IsValid(self._ragdoll) then
  650. return
  651. end
  652. self.Entity:OnThink()
  653.  
  654. if self.NextFoot and self.NextFoot < CurTime() then
  655. local enemy = self.Enemy
  656. local pos = self:GetPos()
  657. if IsValid(enemy) and (not self:Visible(enemy) or ( enemy:IsPlayer() and CanSee(enemy,pos + (self:GetForward() * 40) + Vector(0,0,60),40) and (enemy:GetPos() - pos):Length() > 150)) then
  658.  
  659. self.FriendMeter = self.FriendMeter + 1
  660. if self.FriendMeter >= 40 and (not self.FriendTable[enemy:EntIndex()] or self.FriendTable[enemy:EntIndex()][2] < CurTime()) then
  661. self.FriendTable[enemy:EntIndex()] = {enemy,CurTime() + 30}
  662. self.NoEnemyTime = CurTime() + 10
  663. self.FriendMeter = 0
  664. self:EmitSound("npc/zombie_poison/pz_idle4.wav",150,90)
  665. end
  666. if self.AggLevel > 0 then
  667.  
  668. self.AggLevel = self.AggLevel - 1
  669. end
  670. self.Aggr = 1
  671. self.NoFriendTable[enemy:EntIndex()] = self.AggLevel
  672. elseif IsValid(enemy) and (enemy:GetPos():Distance(pos) < 600) and self.IgnoreTime < CurTime() then
  673. self.AggLevel = math.Clamp(self.AggLevel + 5,0,20)
  674. self.FriendMeter = 0
  675. self.Aggr = 2
  676.  
  677. self.NoFriendTable[enemy:EntIndex()] = self.AggLevel
  678. end
  679.  
  680. if self.Aggrm != self.Aggr then
  681. self.Aggrm = self.Aggr
  682. if self.Aggr == 2 then
  683.  
  684. self:EmitSound("npc/zombie_poison/pz_idle2.wav",100,95)
  685. else
  686. self:EmitSound("npc/zombie_poison/pz_idle3.wav",100,95)
  687. end
  688. end
  689. if self.AggLevel > 10 and not self.Aggressive then
  690.  
  691. self.Aggressive = true
  692. elseif (self.AggLevel <= 0 ) then
  693. self.Aggressive = false
  694. end
  695. self.NextFoot = nil if self:Health() <= 0 and self.LastDmginfo then self:OnKilled(self.LastDmginfo) end
  696.  
  697. if self:OnGround() and self:GetActivity() == ACT_RUN then
  698. self.oldposzslaaa = self:GetPos()
  699.  
  700. self:EmitSound("npc/antlion_guard/foot_heavy" .. math.random(1,2) .. ".wav",60,98)
  701. end
  702. elseif not self.NextFoot then
  703.  
  704. self.NextFoot = CurTime() + 0.4
  705. end
  706. if ( self.IdleTalk or 0 ) < CurTime() then
  707. local cs = {}
  708. for k,v in pairs(ents.FindInSphere(self:GetPos(),10)) do
  709. if v.IsZombie and not v:IsPlayer() and v != self then
  710. self:SetSolid(SOLID_NONE)
  711. timer.Simple(4,function() if IsValid(self) then self:SetSolid(SOLID_BBOX) end end)
  712. return
  713. end
  714. end
  715. if not self:OnGround() and not self.Isjumping and not self.Climbing then self:DropToFloor() end
  716. --[[if self:GetSequence() != self.Zombie_Run then
  717. self:ResetSequence(self.Zombie_Run)
  718. end]]--
  719. local vis = IsValid(self.Enemy) and (self.Enemy:Visible(self))
  720.  
  721. --self.Entity:sVoiceSound( self.VoiceSounds.Taunt )
  722. local ps = self:GetPos()
  723. self.IdleTalk = CurTime() + (self.IdleTalkDelay or vis and math.Rand(1,3) or math.Rand(3,6))
  724. local ac = {}
  725. ac.start = pos
  726.  
  727. if vis then
  728. if vis != self.LastVis then self.LastVis = vis
  729. self:Growl()
  730.  
  731. else
  732. self:Growl()
  733. end
  734. elseif IsValid(self.Enemy) then
  735.  
  736. self:Growl() else
  737. self.IdleTalk = CurTime() + math.random(3,5) end
  738. end
  739.  
  740. if ( self.Stuck or 0 ) < CurTime() then
  741.  
  742. self.Entity:StuckThink()
  743.  
  744. self.Stuck = CurTime() + 5
  745. self.LastPos = self.Entity:GetPos()
  746.  
  747. end
  748.  
  749.  
  750.  
  751. if self.CurAttack and self.CurAttack <= CurTime() then
  752.  
  753. self.CurAttack = nil
  754. self:Growl(true)
  755.  
  756. -- self:sVoiceSound("npc/infected/action/rageat/" .. self.Gender .. "/rage_at_victim" .. math.random(20,34) .. ".wav",100,self.pitchy)
  757. if IsValid( self.CurEnemy ) then
  758.  
  759. if self.CurEnemy:IsPlayer() then
  760.  
  761. local enemy = self.Entity:CanAttackEnemy( self.CurEnemy )
  762.  
  763. if IsValid( enemy ) then
  764. if self.PlayHitSound then self:PlayHitSound() else
  765. local snd = table.Random( self.ClawHit )
  766. self.Entity:EmitSound( snd, 100, math.random(90,110) ) end
  767. self.Entity:OnHitEnemy( enemy )
  768.  
  769. else
  770. self.Entity.CurAttackDelay = 0
  771. local snd = table.Random( self.ClawMiss )
  772. self.Entity:EmitSound( snd, 100, math.random(90,110) )
  773.  
  774. end
  775.  
  776. elseif self.CurEnemy.NextBot then
  777.  
  778. local enemy = self.Entity:CanAttackEnemy( self.CurEnemy )
  779.  
  780. if IsValid( enemy ) then
  781.  
  782. local snd = table.Random( self.ClawHit )
  783. self.Entity:EmitSound( snd, 100, math.random(90,110) )
  784. self.Entity:OnHitBot( enemy )
  785.  
  786. else
  787.  
  788. local snd = table.Random( self.ClawMiss )
  789. self.Entity:EmitSound( snd, 100, math.random(90,110) )
  790.  
  791. end
  792.  
  793. elseif ( self.CurEnemy:GetPos():Distance( self.Entity:GetPos() ) <= (self.BreakableDistance * 1.4) ) or self.CurEnemy == self.Entity:GetBreakable() then
  794. --local enemy = self.Entity:CanAttackEnemy( self.CurEnemy )
  795. -- if enemy then
  796.  
  797. local snd = table.Random( self.ClawMiss )
  798. self.Entity:EmitSound( snd, 100, math.random(90,110) )
  799. -- self.CurEnemy:EmitSound( self.DoorHit, 100, math.random(90,110) )
  800. self.Entity:OnHitBreakable( self.CurEnemy ) end
  801. -- end
  802.  
  803. else
  804.  
  805. local snd = table.Random( self.ClawMiss )
  806. self.Entity:EmitSound( snd, 100, math.random(90,110) )
  807.  
  808. end
  809.  
  810. end
  811.  
  812. end
  813.  
  814. ENT.ForcePower = 1.5
  815. ENT.PropDamage = 5
  816. ENT.MuscleLimit = 200
  817. function ENT:OnHitBot( enemy )
  818. local dmg = DamageInfo()
  819. self:EmitSound("npc/infected/hit/hit_punch_0" .. math.random(1,8) .. ".wav",100,self.pitchy)
  820. local dd = self.Damage
  821. enemy:SetLocalVelocity(( (enemy:GetPos() + Vector(0,0,30)) - self:GetPos()):Angle():Forward() * 150)
  822. dmg:SetDamage(dd)
  823. dmg:SetAttacker(self)
  824. dmg:SetInflictor(self.Inflictor and self.Inflictor or self)
  825. dmg:SetDamageType(self.DamageType and self.DamageType or DMG_CLUB)
  826. dmg:SetDamageForce(self:GetForward() * 50)
  827. enemy:EmitSound("npc/infected/hit/hit_punch_0" .. math.random(1,8) .. ".wav",70)
  828. enemy:TakeDamageInfo(dmg)
  829. end
  830.  
  831. function ENT:OnHitBreakable( ent )
  832.  
  833. if not IsValid( ent ) or ent.NextBot or ent.NoBreak then return end
  834.  
  835.  
  836.  
  837. if IsValid(ent:GetPhysicsObject()) then
  838. local targpos = self:GetForward() + Vector(0,0,0.3) -- (ent:GetPos() + Vector(0,0,20)) - self:GetPos()
  839. if IsValid(self.Target) then
  840. targpos = (self.Target:GetPos() + Vector(0,0,60)) - self:GetPos()
  841. end
  842.  
  843. if ent:GetPhysicsObject():GetMass() <= self.MuscleLimit and not ent.NoPush then
  844. ent:GetPhysicsObject():SetVelocity((targpos):Angle():Forward() * (math.random(100,300) * self.ForcePower))
  845. end
  846.  
  847. local d = DamageInfo()
  848. d:SetDamage(IsValid(self.weapon) and self.weapon.Damage or self.Damage)
  849. d:SetDamageType(DMG_CLUB)
  850. d:SetAttacker(self)
  851. ent:TakeDamageInfo(d)
  852. if string.find(ent:GetModel(),"explosive") then
  853. ent:Ignite(10)
  854. ent:SetHealth(ent:Health() * 0.3)
  855. end
  856. end
  857. if string.find( ent:GetClass(), "func_breakable" ) or string.find( ent:GetClass(), "func_physbox") then
  858.  
  859. if ent:GetClass() == "func_breakable_surf" then
  860.  
  861. ent:Fire( "shatter", "1 1 1", 0 )
  862.  
  863. else
  864. ent:EmitSound( self.WoodBust )
  865. local d = DamageInfo()
  866. d:SetDamage(self.Damage * 10 )
  867. d:SetDamageType(DMG_CLUB)
  868. d:SetAttacker(self)
  869. ent:TakeDamageInfo(d)
  870. end
  871.  
  872. elseif string.find( ent:GetClass(), "func_door" ) then
  873.  
  874. ent:Remove()
  875.  
  876. elseif string.find(ent:GetClass(),"prop_door") then
  877.  
  878. local d = DamageInfo()
  879. d:SetDamage(self.Damage )
  880. d:SetDamageType(DMG_CLUB)
  881. d:SetAttacker(self)
  882. ent:TakeDamageInfo(d)
  883. elseif ent:GetClass() == "prop_ragdoll" then
  884. ent.Mutilated = (ent.Mutilated or 0) + 1
  885. local f = EffectData()
  886. self:SetHealth(math.Clamp(self:Health() + 20,0,self.BaseHealth * 2))
  887. f:SetOrigin(ent:GetPos() )
  888. f:SetScale(2)
  889. util.Effect("Blood",f)
  890. util.StartBleeding(ent,30,30)
  891. local jitter = VectorRand() * 30
  892. jitter.z = 20
  893.  
  894. util.PaintDown(ent:GetPos() + jitter, "Blood", ent)
  895. ent:EmitSound("runner/nhzombie_headexplode.wav")
  896. ent:ManipulateBoneScale(math.random(1,30),Vector(0,0,0))
  897. ent:ManipulateBoneScale(math.random(1,30),Vector(0,0,0))
  898.  
  899. local d = DamageInfo()
  900. d:SetDamage(self.Damage )
  901. d:SetDamageType(DMG_CLUB)
  902. d:SetAttacker(self)
  903. ent:TakeDamageInfo(d)
  904. else
  905.  
  906. if not ent.Hits then
  907.  
  908. ent.Hits = 1
  909. ent.MaxHits = math.random(10,20)
  910.  
  911.  
  912.  
  913. elseif IsValid(ent) and IsValid(ent:GetPhysicsObject()) and ent.GetModel then
  914.  
  915. ent.Hits = ent.Hits + 1
  916.  
  917. if ent.Hits > ent.MaxHits then
  918.  
  919. if ent:GetModel() != "models/props_debris/wood_board04a.mdl" then
  920.  
  921. local prop = ents.Create( "prop_physics" )
  922. prop:SetModel( ent:GetModel() )
  923. prop:SetPos( ent:GetPos() )
  924. prop:SetAngles( ent:GetAngles() + Angle( math.random(-10,10), math.random(-5,5), math.random(-5,5) ) )
  925. prop:SetSkin( ent:GetSkin() )
  926. prop:SetCollisionGroup( COLLISION_GROUP_DEBRIS )
  927. prop:Spawn()
  928.  
  929. local dir = ( ent:GetPos() - self.Entity:GetPos() ):Normalize()
  930. local phys = prop:GetPhysicsObject()
  931.  
  932. if IsValid( phys ) and dir then
  933.  
  934. phys:ApplyForceCenter( dir * phys:GetMass() * 800 )
  935. phys:AddAngleVelocity( VectorRand() * 200 )
  936.  
  937. end
  938.  
  939. ent:EmitSound( self.WoodBust )
  940. ent:Remove()
  941.  
  942. else
  943.  
  944. ent:Fire( "break", "", 0 )
  945.  
  946. end
  947.  
  948. else
  949.  
  950.  
  951. end
  952.  
  953. end
  954.  
  955. end
  956.  
  957. end
  958.  
  959. ENT.NextTeleport = 0
  960. ENT.SpawnedAt = CurTime()
  961. ENT.NextAnim = 0
  962. ENT.RunAnim = ACT_WALK
  963. ENT.MoveAnim = ACT_WALK
  964. ENT.loco:SetAcceleration(800)
  965. function ENT:Growl(t)
  966. if t then
  967. self:EmitSound("npc/antlion_guard/angry" .. math.random(1,3) .. ".wav",80,90)
  968.  
  969. else
  970. self:EmitSound("npc/antlion_guard/angry" .. math.random(1,3) .. ".wav",30,90)
  971.  
  972. end
  973. --self:EmitSound("runner/nhguard_alert" .. math.random(2,7) .. ".mp3",100,110)
  974. end
  975.  
  976. function ENT:TeleportVent(ply)
  977.  
  978. local f = nil
  979. if IsValid(ply) then
  980.  
  981. f = self:FindSpot( "random", { type = "hiding", pos = ply:GetPos() , radius = ply:GetPos():Distance(self:GetPos()) * 1.2,stepup = 300 } )
  982. else
  983. f = ply
  984. end
  985. if f then
  986. local ac = {}
  987.  
  988. ac.start = f
  989. ac.endpos = ac.start + Vector(0,0,500)
  990. if IsValid(ply) then
  991.  
  992.  
  993. ac.filter = {self,ply}
  994. else
  995. ac.filter = {self}
  996. end
  997. ac.mask = MASK_SOLID
  998. local tr = util.TraceLine(ac)
  999. if tr.HitPos.z - ac.start.z >= 70 then
  1000. local e = ents.Create("prop_physics")
  1001.  
  1002. e:SetModel("models/props_junk/vent001.mdl")
  1003. e:SetPos(tr.HitPos)
  1004. e:Spawn()
  1005. e:EmitSound("physics/metal/metal_box_break" .. math.random(1,2) .. ".wav")
  1006. e:Fire("break")
  1007.  
  1008. local dd = "zskclimb" .. self:EntIndex()
  1009. self:SetPos(tr.HitPos - Vector(0,0,70))
  1010.  
  1011.  
  1012. end
  1013. end
  1014. end
  1015. function ENT:BehaveUpdate( fInterval )
  1016.  
  1017. if ( !self.BehaveThread ) then return end
  1018.  
  1019. local ok, message = coroutine.resume( self.BehaveThread )
  1020. if ( ok == false ) then
  1021.  
  1022. self.BehaveThread = nil
  1023. end
  1024.  
  1025. end
  1026. function ENT:RunBehaviour()
  1027. while ( true ) do
  1028.  
  1029. if IsValid(self._ragdoll) then
  1030. coroutine.yield()
  1031. end
  1032.  
  1033. local enemy = self.Entity:FindEnemy()
  1034.  
  1035. if not IsValid( enemy ) then
  1036.  
  1037. self.Enemy = enemy
  1038.  
  1039. local ac = {}
  1040.  
  1041. if self.LastKnownPos then
  1042. self.Entity:StartActivity( self.MoveAnim )
  1043. self.loco:SetDesiredSpeed( self.MoveSpeed )
  1044.  
  1045. local age = math.Clamp( math.min( self.LastKnownPos:Distance(self:GetPos()), 1000 ) / 1000, 0.2, 1 )
  1046. local opts = { lookahead = 600, draw = self.ShouldDrawPath, maxage = 10 * age, tolerance = 101 }
  1047.  
  1048. local pos = self:GetPos()
  1049. local p = self.LastKnownPos
  1050. if pos.z + 20 < p.z then
  1051. local k = p
  1052. k.z = pos.z
  1053. local z = math.max(100,p.z - pos.z)
  1054. local a = {}
  1055. a.start = self:GetPos()
  1056. a.endpos = a.start + Vector(0,0,z)
  1057. a.mask = MASK_SOLID
  1058. a.filter = {self,enemy}
  1059. if not a.HitWorld then
  1060. self.loco:SetDesiredSpeed( self.BumpSpeed * 3)
  1061. self:SetAngles(Angle(0, (p - pos):Angle().yaw,0))
  1062. self.loco:SetJumpHeight(z + 40)
  1063. self.loco:Jump()
  1064.  
  1065. self.loco:SetDesiredSpeed( self.RunSpeed ) end
  1066. end
  1067. self.Entity:MoveToPos( self.LastKnownPos ,opts)
  1068. if self.Entity:GetPos():Distance(self.LastKnownPos) < 100 then
  1069. self.LastKnownPos = nil
  1070. self:EmitSound("npc/antlion_guard/angry" .. math.random(1,3) .. ".wav",80,80)
  1071.  
  1072. end
  1073.  
  1074. else
  1075.  
  1076.  
  1077. self.Entity:StartActivity( self.MoveAnim )
  1078. self.loco:SetDesiredSpeed( self.MoveSpeed )
  1079.  
  1080. ac.start = self:GetPos() + Vector(0,0,10)
  1081. ac.endpos = (ac.start + (Vector( math.Rand( -1, 1 ), math.Rand( -1, 1 ), 0 ) * 300) ) - Vector(0,0,15)
  1082. ac.filter = {self}
  1083. local tr = util.TraceLine(ac)
  1084.  
  1085. if tr.Hit then
  1086.  
  1087. local age = math.Clamp( math.min( tr.HitPos:Distance(ac.start), 1000 ) / 1000, 0.2, 1 )
  1088. local opts = { lookahead = 600, draw = self.ShouldDrawPath, maxage = 10 * age, tolerance = 11 }
  1089.  
  1090. self.Entity:MoveToPos( tr.HitPos ,opts)
  1091. self:BreakableRoutine()
  1092. end end
  1093. coroutine.yield()
  1094. else
  1095.  
  1096. if self.MustTel then
  1097. local f= false
  1098. for k,v in pairs(player.GetAll()) do if v:GetMoveType() != MOVETYPE_NOCLIP and v:Alive() and v:Visible(self) then
  1099.  
  1100. f = true
  1101. break
  1102. end
  1103.  
  1104. end if not f then self:TeleportVent(enemy) self.MustTel = nil end end
  1105. if not self:Visible(enemy) then
  1106.  
  1107. self.NotVisibleCount = (self.NotVisibleCount or 0) + 1
  1108. if (self.NotVisibleCount >= 4) then
  1109.  
  1110. local f= false
  1111. for k,v in pairs(player.GetAll()) do if v:GetMoveType() != MOVETYPE_NOCLIP and v:Alive() and v:Visible(self) then
  1112.  
  1113. f = true
  1114. break
  1115. end
  1116.  
  1117. end
  1118. if not f then
  1119. self.loco:SetJumpHeight(550)
  1120. self:SetNoDraw(true)
  1121. self.loco:Jump()
  1122. local a = self:FindSpot( "random", { type = "hiding", pos = enemy:GetPos() , radius = enemy:GetPos():Distance(self:GetPos()) * 1.2,stepup = 300 } )
  1123. if a then
  1124. local c = {}
  1125. c.start = a
  1126. c.endpos = a +Vector(0,0,300)
  1127. c.mask = MASK_SOLID
  1128. local tr = util.TraceLine(c)
  1129. a = tr.HitPos
  1130. timer.Create("ventStepping" .. self:EntIndex(),0.2,8,function()
  1131. if IsValid(self ) then sound.Play("MetalVent.StepLeft",a + (Vector(math.random(-50,50),math.random(-50,50),0)),150,100) end
  1132. end)
  1133. end
  1134. coroutine.wait(math.random(1,3))
  1135. self:SetNoDraw(false)
  1136. self:TeleportVent(enemy)
  1137. self.NotVisibleCount = 0
  1138.  
  1139. end
  1140. end
  1141. else
  1142. self.NotVisibleCount = 0
  1143. end
  1144. self.Angered = true
  1145. self.Enemy = enemy
  1146.  
  1147. -- local dd = (enemy:GetPos() - self:GetPos()):Length() > 200
  1148.  
  1149.  
  1150. self.Entity:StartActivity( (dd and self.RunAnim or self.MoveAnim) )
  1151.  
  1152. local pos = self.Entity:GetPos()
  1153.  
  1154. local r = (self.Aggressive and self.RunSpeed or self.MoveSpeed) --+ ((self:Visible(self.Enemy) or dd) and 50 or 0)
  1155. self.loco:SetDesiredSpeed( r)
  1156. local p = enemy:GetPos()
  1157. if self.Obstructed2 and self.Obstructed and pos:Distance(p) > 60 and self.Aggressive then
  1158.  
  1159. self.Obstructed2 = nil
  1160. self.loco:SetDesiredSpeed( self.BumpSpeed )
  1161. self.loco:Jump()
  1162. self.loco:SetDesiredSpeed(r)
  1163. end
  1164. if self.Climbing then
  1165. self:PlaySequenceAndWait("ACT_CLIMB_UP",1)
  1166. self:ResetSequence(10)
  1167. coroutine.yield()
  1168. end
  1169.  
  1170. if self.Obstructed then
  1171. self.Obstructed2 = true
  1172. self.Obstructed = nil
  1173. self.Entity:BreakableRoutine()
  1174.  
  1175. coroutine.yield()
  1176.  
  1177. end
  1178. self.Obstructed2 = nil
  1179. local pos = self.Entity:GetPos()
  1180.  
  1181. self.loco:SetDesiredSpeed( r)
  1182. local p = enemy:GetPos()
  1183. local age = math.Clamp( math.min( enemy:GetPos():Distance( pos), 1000 ) / 1000, 0.2, 1 )
  1184.  
  1185. self.loco:FaceTowards( p)
  1186. if pos.z + 20 < p.z and self.Aggressive then
  1187. local k = p
  1188. k.z = pos.z
  1189.  
  1190. if ( k - p):Length() < 400 then
  1191.  
  1192. local trace = {}
  1193.  
  1194. trace.start = self.Entity:GetPos() + Vector(0,0,37)
  1195. trace.endpos = trace.start + (self.Entity:GetForward() * 400)
  1196. trace.filter = { self}
  1197.  
  1198. local tr = util.TraceLine( trace )
  1199. if tr.Hit then
  1200.  
  1201.  
  1202. local z = math.max(100,p.z - pos.z)
  1203. local a = {}
  1204. a.start = self:GetPos()
  1205. a.endpos = a.start + Vector(0,0,z)
  1206. a.mask = MASK_SOLID
  1207. a.filter = {self,enemy}
  1208. if not a.HitWorld then
  1209. self.loco:SetDesiredSpeed( self.BumpSpeed * 3)
  1210. self:SetAngles(Angle(0, (p - pos):Angle().yaw,0))
  1211. self.loco:SetJumpHeight(z + 150)
  1212. self.loco:Jump()
  1213. self.loco:SetDesiredSpeed( self.RunSpeed ) end
  1214. end
  1215. end
  1216. end
  1217.  
  1218. local opts = { lookahead = 1600, draw = self.ShouldDrawPath, maxage = 10 * age, tolerance = (self.Aggressive and 40 or 200) }
  1219.  
  1220. local p = enemy:GetPos()
  1221. local d = enemy:GetPos():Distance( pos)
  1222. local age = math.Clamp( math.min(d, 1000 ) / 1000, 0.2, 1 )
  1223. local c = 200
  1224. if math.random(1,30) == 2 then c = 50 end
  1225. local ff = (p - pos):Length()
  1226. if ff > 11 and (self.Aggressive or ff > c) then
  1227. self.loco:Approach(p,1)
  1228. self.Entity:MoveToPos( p, opts )
  1229.  
  1230. else
  1231. self.Entity:StartActivity( ACT_IDLE)
  1232. if math.random(1,10) <= self.AggLevel then
  1233. self:Growl(true)
  1234.  
  1235. self.Entity:RestartGesture(ACT_MELEE_ATTACK1)
  1236. coroutine.wait(2)
  1237. end
  1238. end
  1239.  
  1240. self.Entity:BreakableRoutine()
  1241. if self:GetPos():Distance(enemy:GetPos()) <= self.MeleeDistance then
  1242. self.Entity:EnemyRoutine()
  1243. end
  1244. end
  1245.  
  1246. coroutine.yield()
  1247.  
  1248. end
  1249.  
  1250. end
  1251.  
  1252. function ENT:MakeClimbing(tr)
  1253. self.ClimbPos = self:GetPos()
  1254. self.Climbing = ( -1 * tr.HitNormal):Angle()
  1255. self:SetAngles(self.Climbing)
  1256. self.ClimbingTR = tr
  1257. if not IsValid(self.status_overridemodel) then
  1258. local ent = ents.Create("status_overridemodel")
  1259. if ent:IsValid() then
  1260. ent:Spawn()
  1261.  
  1262.  
  1263. ent:SetPlayer(self)
  1264. self.status_overridemodels = ent
  1265. if ent and ent:IsValid() then
  1266. ent:SetModel(self:GetModel() )
  1267. self:SetModel("models/zombie/fast.mdl")
  1268.  
  1269. self:PlaySequenceAndWait("ACT_CLIMB_UP",0.5)
  1270. end
  1271. end
  1272. end
  1273.  
  1274.  
  1275. end
  1276. ENT:SetCollisionGroup(COLLISION_GROUP_NPC)
  1277. ENT:Spawn()
  1278. ENT:Activate()
  1279. ENT.StartPos = ENT:GetPos()
  1280. -- local head = RP.HandleGears(ENT,"models/Gibs/HGIBS.mdl","chest",Vector(20,2,0),Angle( 0, 10,-90),Vector(1.2,0.7,0.6) * 1.1)
  1281. -- local head2 = RP.HandleGears(ENT,"models/Gibs/Antlion_gib_Large_2.mdl","chest",Vector(20,-2,0),Angle( 0, -10, 90),Vector(0.6,0.7,0.6 ) * 1.1)
  1282. -- head:SetColor(Color(150,110,0,255))
  1283. -- head2:SetColor(Color(150,110,0,255))
  1284.  
  1285. --ENT:ManipulateBoneScale(ENT:LookupBone("ValveBiped.Bip01_Spine"),Vector(2,2,2))
  1286. ENT:ManipulateBonePosition(ENT:LookupBone("ValveBiped.Bip01_L_ForeArm"),Vector(10,0,0))
  1287. ENT:ManipulateBonePosition(ENT:LookupBone("ValveBiped.Bip01_R_ForeArm"),Vector(10,0,0))
  1288. ENT:ManipulateBoneScale(ENT:LookupBone("ValveBiped.Bip01_L_Foot"),Vector(2,2,2))
  1289. ENT:ManipulateBoneScale(ENT:LookupBone("ValveBiped.Bip01_R_Foot"),Vector(2,2,2))
  1290. ENT:SetModelScale(1.3,0)
  1291.  
  1292.  
  1293. ENT:SetMaterial(table.Random({"models/Barnacle/Barnacle_sheet","models/antlion_guard/bodyside"}))
  1294. return ENT
  1295.  
  1296.  
  1297. end
  1298. print("Load")
  1299.  
  1300. RP:RegisterAI(AI)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement