CapsAdmin

Untitled

Jul 30th, 2011
219
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 21.44 KB | None | 0 0
  1. local spawn = true
  2.  
  3. seagulls = seagulls or {} local s = seagulls
  4.  
  5. seagulls.ClassName = "hunting_mod_seagull"
  6. --seagulls.Nest = Vector(-6637.6226, 7677.0718, -3747.9688) --freesace06
  7. --seagulls.Nest = Vector(-10385.2158, -11214.9980, 100) --flat constr
  8. seagulls.Nest = Vector(-805.6716, -7304.4014, 448.0312) -- bigcity
  9. seagulls.NestRadius = 800
  10. seagulls.MaxSeagulls = 70
  11.  
  12. --seagulls.Min = Vector(14303.9688, -14303.9688, 1)
  13. --seagulls.Max = Vector(-3048.6169, -3062.0076, 8320.1709)
  14.  
  15. do -- precalc
  16.    
  17. end
  18.  
  19. do -- util
  20.     function seagulls.GetNest()
  21.         return seagulls.Nest
  22.     end
  23.  
  24.     function seagulls.SetNest(vec)
  25.         seagulls.RoofZ = util.QuickTrace(vec, vector_up * 32000).HitPos.z
  26.         seagulls.Nest = vec
  27.     end
  28.  
  29.     function seagulls.GetAll()
  30.         return ents.FindByClass(seagulls.ClassName)
  31.     end
  32.  
  33.     function seagulls.Create()
  34.         if #seagulls.GetAll() < seagulls.MaxSeagulls then
  35.             local ent = ents.Create(seagulls.ClassName)
  36.             ent:SetPos(seagulls.Nest + Vector(math.Rand(-1,1), math.Rand(-1,1), math.Rand(0,1)) * seagulls.NestRadius)
  37.             ent:Spawn()
  38.             return ent
  39.         end
  40.         return NULL
  41.     end
  42. end
  43.  
  44. do -- meta
  45.     local function AccessorFunc(tbl, name, dt)
  46.         tbl["Set" .. name] = function(self, var)
  47.             if dt and self.dt then
  48.                 self.dt[name] = var
  49.             else
  50.                 self[name] = var
  51.             end
  52.         end
  53.  
  54.         tbl["Get" .. name] = function(self, var)
  55.             if dt and self.dt then
  56.                 return self.dt[name]
  57.             else
  58.                 return self[name]
  59.             end
  60.         end
  61.     end
  62.  
  63.     local ENT = {}
  64.  
  65.     ENT.IsSeagull = true
  66.     ENT.ClassName = seagulls.ClassName
  67.  
  68.     ENT.Model = "models/seagull.mdl"
  69.     ENT.Type = "anim"
  70.  
  71.     ENT.Target = NULL
  72.     ENT.Size = 1
  73.  
  74.     ENT.Animations = {
  75.         Fly = "fly",
  76.         Run = "run",
  77.         Walk = "walk",
  78.         Idle = "idle01",
  79.     }
  80.  
  81.     ENT.Sounds = {
  82.         Pain= {
  83.             "ambient/creatures/seagull_pain1.wav",
  84.             "ambient/creatures/seagull_pain2.wav",
  85.             "ambient/creatures/seagull_pain3.wav",
  86.         },
  87.         Idle= {
  88.             "ambient/creatures/seagull_idle1.wav",
  89.             "ambient/creatures/seagull_idle2.wav",
  90.             "ambient/creatures/seagull_idle3.wav",
  91.         },
  92.         AmbientIdle= {
  93.             "ambient/levels/coast/seagulls_ambient1.wav",
  94.             "ambient/levels/coast/seagulls_ambient2.wav",
  95.             "ambient/levels/coast/seagulls_ambient3.wav",
  96.             "ambient/levels/coast/seagulls_ambient4.wav",
  97.             "ambient/levels/coast/seagulls_ambient5.wav",
  98.         },
  99.         Impact= {
  100.             "physics/body/body_medium_impact_soft1.wav",
  101.             "physics/body/body_medium_impact_soft2.wav",
  102.             "physics/body/body_medium_impact_soft3.wav",
  103.             "physics/body/body_medium_impact_soft4.wav",
  104.             "physics/body/body_medium_impact_soft5.wav",
  105.             "physics/body/body_medium_impact_soft6.wav",
  106.             "physics/body/body_medium_impact_soft7.wav",
  107.         },
  108.     }
  109.  
  110.     AccessorFunc(ENT, "Size", true)
  111.  
  112.     function ENT:SetupDataTables()
  113.         self:DTVar("Float", 0, "Size")
  114.         self:DTVar("Float", 1, "HeldEntityMass")
  115.     end
  116.  
  117.     do -- util
  118.         function ENT:PlaySound(type)
  119.             self:EmitSound(
  120.                 table.Random(self.Sounds[type]),
  121.                 math.Clamp(math.Rand(40, 60) * self:GetSize(), 1, 160),
  122.                 math.Clamp(math.random(90,110) / self:GetSize(), 25, 255)
  123.             )
  124.         end
  125.  
  126.         function ENT:GetBottom(offset)
  127.             offset = offset or 1
  128.             return self:GetPos() + ((vector_up * self:GetSize() * -5) * offset)
  129.         end
  130.  
  131.         function ENT:GetOnGround()
  132.             if not self.LastOnGround or self.LastOnGround < CurTime() then
  133.                 self.OnGroundCache = util.QuickTrace(self:GetBottom(1.1), vector_up * 3, {self, self.HeldEntity, self.FetchEntity}).Hit
  134.                 self.LastOnGround = CurTime() + 0.4
  135.             end
  136.            
  137.             return self.OnGroundCache
  138.         end
  139.        
  140.         function ENT:GetEntityFilter()
  141.             if not self.LastFilterTime or self.LastFilterTime < CurTime() then
  142.                 local pos = self and self:GetPos() or vector_origin -- FIX ME
  143.                 self.LastFilter = {self, unpack(ents.FindInSphere(pos, self:GetSize()))}
  144.                 self.LastFilterTime = CurTime() + 0.3
  145.             end
  146.             return self.LastFilter
  147.         end
  148.        
  149.         local mn, mx = seagulls.Min, seagulls.Max
  150.         function seagulls.IsWithinMinMax(p)
  151.             if ms then
  152.             return
  153.                 p.x > mn.x and p.y > mn.y and p.z > mn.z and               
  154.                 p.x < mx.x and p.y < mx.y and p.z < mx.z               
  155.             else
  156.                 return true
  157.             end
  158.         end
  159.        
  160.         function ENT:IsWithinMinMax(p)
  161.             return seagulls.IsWithinMinMax(p)
  162.         end
  163.     end
  164.  
  165.     if CLIENT then
  166.  
  167.         do -- util
  168.             function ENT:SetAnim(anim)
  169.                 self:SetSequence(self:LookupSequence(self.Animations[anim]))
  170.             end
  171.         end
  172.  
  173.         do -- calc
  174.             ENT.Cycle = 0
  175.             ENT.Noise = 0
  176.  
  177.             function ENT:AnimationThink(vel, len, ang)
  178.  
  179.                 if self:GetOnGround() then
  180.  
  181.                     if len < 3 then
  182.                         self:SetAnim("Idle")
  183.                         len = 15 / self:GetSize() * (self.Noise * 2)
  184.                     else
  185.                         self:StepSoundThink()
  186.  
  187.                         if len > 50 then
  188.                             self:SetAnim("Run")
  189.                         else
  190.                             self:SetAnim("Walk")
  191.                         end
  192.                     end
  193.  
  194.                     self.ang = Angle(0, ang.y, ang.r)
  195.                     self.Noise = (self.Noise + (math.Rand(-1,1) - self.Noise) * FrameTime() * 4)
  196.                 else
  197.                     self:SetAnim("Fly")
  198.  
  199.                     if vel.z > 0 then
  200.                         len = len / 10
  201.                     else
  202.                         len = 0
  203.                         self.Cycle = 0.2
  204.                     end
  205.  
  206.                     if self.dt.HeldEntityMass > 0 then
  207.                         len = len * self.dt.HeldEntityMass * 0.03
  208.                     end
  209.                 end
  210.  
  211.                 self.Cycle = self.Cycle + (FrameTime() * len * 0.07)
  212.                 self:SetCycle(self.Cycle)
  213.             end
  214.  
  215.             function ENT:StepSoundThink()
  216.                 local stepped = self.Cycle%0.5
  217.                 if stepped  < 0.3 then
  218.                     if not self.stepped then
  219.                         self:EmitSound(
  220.                             "npc/fast_zombie/foot2.wav",
  221.                             math.Clamp(20 * self:GetSize(), 70, 155) + math.Rand(-5,5),
  222.                             math.Clamp(100 / (self:GetSize()/2), 40, 200) + math.Rand(-10,10)
  223.                         )
  224.                         self.stepped = true
  225.                     end
  226.                 else
  227.                     self.stepped = false
  228.                 end
  229.             end
  230.         end
  231.  
  232.         do -- standard
  233.             function ENT:Draw()
  234.                 self.vel = self:GetVelocity() / self:GetSize()
  235.                 self.len = self.vel:Length()
  236.                 self.ang = self.vel:Angle()
  237.  
  238.                 self:AnimationThink(self.vel, self.len, self.ang)
  239.  
  240.                 self:SetModelScale(Vector() * self:GetSize())
  241.                 if self.len > 5 or not self.lastang then
  242.                     self:SetAngles(self.ang)
  243.                     self.lastang = self.ang
  244.                 else
  245.                     self:SetAngles(self.lastang)
  246.                 end
  247.  
  248.                 self:SetRenderOrigin(self:GetBottom())
  249.  
  250.                 local min, max = self:GetRenderBounds()
  251.                 local size = self:GetSize() * 2
  252.                 self:SetRenderBounds(min * size, max * size)
  253.  
  254.                 self:DrawShadow(false)
  255.                 self:SetupBones()
  256.                 self:DrawModel()
  257.                 self:SetRenderOrigin(nil)
  258.             end
  259.  
  260.             function ENT:Think()
  261.                 if math.random() > 0.999 then
  262.                     self:EmitSound(table.Random(self.Sounds.AmbientIdle), 120, math.Clamp(100 / self:GetSize(), 30, 200) + math.Rand(-10,10))
  263.                 end
  264.             end
  265.         end
  266.  
  267.     end
  268.  
  269.     if SERVER then
  270.         do -- util
  271.             function ENT:GetAverageFlockPos()
  272.                 local pos = vector_origin
  273.                 local gulls = seagulls.GetAll()
  274.  
  275.                 for _, ent in pairs(gulls) do
  276.                     if ent ~= self then
  277.                         pos = pos + ent:GetPos()
  278.                     end
  279.                 end
  280.  
  281.                 local div = #gulls - 1
  282.  
  283.                 if div ~= 0 then
  284.                     return pos / div
  285.                 end
  286.  
  287.                 return seagulls.Nest
  288.             end
  289.         end
  290.        
  291.         do -- kill
  292.             function ENT:KillTarget(ent)
  293.                 self:SetTargetPos(ent, "kill")
  294.                 self.Killing = true
  295.             end
  296.         end
  297.  
  298.         do -- move
  299.             ENT.SmoothNoise = VectorRand()
  300.             ENT.NextTry = 0
  301.  
  302.             AccessorFunc(ENT, "MoveDamping")
  303.             AccessorFunc(ENT, "MovePos")
  304.  
  305.             function ENT:GetPrefferedStopRadius()
  306.                 return self.FetchEntity:IsValid() and 10 or 10 * self:GetSize()
  307.             end
  308.  
  309.             function ENT:StopMoving()
  310.                 self.phys:AddVelocity(-self.phys:GetVelocity() * Vector(1,1,0))
  311.                 self.stop = true
  312.             end
  313.  
  314.             function ENT:Trace(a, b)
  315.                 if not self.LastTrace or self.LastTrace < CurTime() then
  316.                     self.CachedTraceResults = util.TraceLine{
  317.                         start = a,
  318.                         endpos = b,
  319.                         filter = self:GetEntityFilter(),
  320.                     }
  321.                     self.LastTrace = CurTime() + 0.2
  322.                 end
  323.                 return self.CachedTraceResults
  324.             end
  325.  
  326.             function ENT:CanSeePos(pos, threshold)
  327.                 return self:Trace(self:GetPos(), pos).HitPos:Distance(pos) < (threshold or 200)
  328.             end
  329.            
  330.             function ENT:TryHeightPos(pos)
  331.                 self:SetMovePos(Vector(pos.x, pos.y, seagulls.RoofZ))
  332.                 self.Trying = "height"
  333.             end
  334.  
  335.             function ENT:TryTracePos(pos)
  336.                 local hit_pos = self:Trace(self:GetPos(), pos).HitPos
  337.                 if hit_pos:Distance(pos) < 2000 then
  338.                     local try = pos + Vector(math.Rand(-1000,1000), math.Rand(-1000,1000), 0)
  339.                     if self:CanSeePos(try) then
  340.                         self:SetMovePos(try)
  341.                         self.Trying = "trace"
  342.                     end
  343.                 end
  344.             end
  345.  
  346.             function ENT:SetTargetPos(var, msg)
  347.                 local pos = IsVector(var) and var or IsEntity(var) and IsValid(var) and var:GetPos()
  348.                
  349.                 if not pos or  pos:Distance(self:GetPos()) < self:GetPrefferedStopRadius() then return end
  350.  
  351.                 self.TargetPos = var
  352.                 self.TargetReachMessage = msg
  353.  
  354.                 if self:CanSeePos(pos) then
  355.                     self:SetMovePos(pos)
  356.                 else
  357.                     self:TryHeightPos(pos)
  358.                 end
  359.             end
  360.  
  361.             function ENT:GetTargetPos()
  362.                 return self.TargetPos and (IsVector(self.TargetPos) and self.TargetPos or self.TargetPos:GetPos())
  363.             end
  364.         end
  365.  
  366.         do -- pickup
  367.             ENT.FetchEntity = NULL
  368.             ENT.HeldEntity = NULL
  369.             AccessorFunc(ENT, "HeldEntity")
  370.  
  371.             function ENT:Pickup(ent)
  372.                 if ent:IsValid() and not self.HeldEntity:IsValid() then
  373.                     constraint.RemoveAll(ent)
  374.                     if ent:IsPlayer() then
  375.                         self.HoldingPlayer = true
  376.                     elseif ent:IsNPC() then
  377.                         ent:SetParent(self)
  378.                     else
  379.                         --ent:SetPos(self:GetPos())
  380.                         local weld = constraint.Weld(self, ent)
  381.                         if weld then
  382.                             ent:GetPhysicsObject():EnableMotion(true)
  383.  
  384.                             for key, ent in pairs(constraint.GetAllConstrainedEntities(ent)) do
  385.                                 ent:GetPhysicsObject():EnableMotion(true)
  386.                             end
  387.  
  388.                             self.weld = weld
  389.                             self:SetHeldEntity(ent)
  390.                             self.dt.HeldEntityMass = self:GetPhysicsObject():GetMass()
  391.  
  392.                             ent.seagull_carriers = ent.seagull_carriers or {}
  393.                             table.insert(ent.seagull_carriers, self)
  394.                         end
  395.                     end
  396.                    
  397.                     ent:CallOnRemove(seagulls.ClassName, function()
  398.                         if self.IsSeagull and self.FetchEntity == ent then
  399.                             self:Drop()
  400.                         end
  401.                     end)
  402.                 end
  403.             end
  404.  
  405.             function ENT:Drop()
  406.                 constraint.RemoveAll(self)
  407.                 local ent = self.FetchEntity
  408.                 if ent:IsValid() then
  409.                     if ent:IsPlayer() then
  410.                         ent:SetMoveType(MOVETYPE_WALK)
  411.                     elseif ent:IsNPC() then
  412.                         ent:SetParent()
  413.                     else
  414.                         ent:SetPos(self.FetchEntity:GetPos())
  415.                         if ent.seagull_carriers then
  416.                             for key, value in pairs(ent.seagull_carriers) do
  417.                                 if value.IsSeagull and value ~= self then
  418.                                     value.DropIt = true
  419.                                 end
  420.                             end
  421.                         end
  422.                     end
  423.                     ent.seagull_lift = nil
  424.                 end
  425.                 self.dt.HeldEntityMass = 0
  426.  
  427.                 self.FetchEntity = NULL
  428.                 self.HeldEntity = NULL
  429.  
  430.                 self.TargetPos = nil
  431.                 self.MovePos = nil
  432.  
  433.                 self.HoldingPlayer = false
  434.             end
  435.  
  436.             function ENT:Fetch(ent)
  437.                 if ent:IsValid() and not self.FetchEntity:IsValid() then
  438.                     ent.seagull_lift = (ent.seagull_lift or 0) + self:GetSize()
  439.                     self.FetchEntity = ent
  440.                     self:SetTargetPos(ent, "pickup")
  441.                 end
  442.             end
  443.  
  444.             function ENT:IsPickupAllowed(ent)
  445.                 if math.random() > 0.5 then return false end
  446.                
  447.                 if ent == seagulls.Platform then return false end
  448.                
  449.                 if not self:IsWithinMinMax(ent:GetPos()) then
  450.                     return false
  451.                 end
  452.                
  453.                 if ent:GetPos():Distance(seagulls.Nest) < seagulls.NestRadius then
  454.                     return false
  455.                 end
  456.  
  457.                 if
  458.                     not ent.IsSeagull and
  459.                     util.IsValidPhysicsObject(ent) and
  460.                     ent:GetMoveType() == MOVETYPE_VPHYSICS and
  461.                     (not ent.seagull_lift or (390 * ent.seagull_lift) < ent:GetPhysicsObject():GetMass() + 300) --and
  462.                     --not util.QuickTrace(ent:GetPos(), vector_up * 700, ent).Hit
  463.                 then
  464.                     return true
  465.                 end
  466.                
  467.                 if (ent:IsPlayer() and  ent:Alive() or ent:IsNPC()) and not ent:GetParent().IsSeagull and not ent.seagull_lift then
  468.                     return true
  469.                 end
  470.             end
  471.  
  472.             function ENT:FetchRandom()
  473.                 for key, ent in pairs(ents.GetAll()) do
  474.                     if self:IsPickupAllowed(ent) then
  475.                         self:Fetch(ent)
  476.                         break
  477.                     end
  478.                 end
  479.             end
  480.         end
  481.  
  482.         do -- calc
  483.             function ENT:IdleThink(phys)
  484.                 if not self.TargetPos then
  485.                     local vel = (seagulls.Nest - phys:GetPos()) * 0.03
  486.  
  487.                     if self:GetOnGround() then
  488.                         if (self.LastIdleDir or 0) < CurTime() then
  489.                             phys:AddVelocity(VectorRand() * Vector(1,1,0) * 300)
  490.                             self.LastIdleDir = CurTime() + math.Rand(1.5,4)
  491.                         end
  492.                     end
  493.  
  494.                     if self:GetPos():Distance(seagulls.Nest) > seagulls.NestRadius then
  495.                         phys:AddVelocity(seagulls.Nest - phys:GetPos())
  496.                     end
  497.  
  498.                     phys:AddVelocity(phys:GetVelocity() *- 0.03)
  499.                 end
  500.             end
  501.  
  502.             function ENT:TryThink()
  503.                 if self.NextTry < CurTime() then
  504.                     local pos = self:GetTargetPos()
  505.  
  506.                     if pos then
  507.                         if self:CanSeePos(pos) then
  508.                             self:SetMovePos(pos)
  509.                             self.NextTry = 0
  510.                         else
  511.                             if
  512.                                 self.Trying == "height" and
  513.                                 (pos - self.pos):Length2D() < self:GetPrefferedStopRadius()
  514.                             then
  515.                                 self:TryTracePos(pos)
  516.                             end
  517.  
  518.                             if
  519.                                 self.Trying == "trace" and
  520.                                 (
  521.                                     self.len < 100 or
  522.                                     self.pos:Distance(pos) < self:GetPrefferedStopRadius()
  523.                                 )
  524.                             then
  525.                                 self.Trying = false
  526.                             end
  527.  
  528.                             if self.MovePos and not self:CanSeePos(self.MovePos) and self.MovePos:Distance(pos) < 1000  then
  529.                                 self:TryHeightPos(pos)
  530.                             end
  531.  
  532.                             if not self.Trying then
  533.                                 self:TryHeightPos(pos)
  534.                             end
  535.  
  536.                             self.NextTry = CurTime() + math.Rand(0.2,0.4)
  537.                         end
  538.                     end
  539.                 end
  540.             end
  541.  
  542.             function ENT:MoveThink(phys, pos, movepos, distance)
  543.                 local vel = movepos - pos
  544.                 phys:AddVelocity(vel:Normalize() * (math.Clamp(vel:Length()*0.1, 30, 500) * self:GetSize()))
  545.                
  546.                 if self.TouchEntity:IsValid() then
  547.                     local phys, ent = self.TouchEntity:GetPhysicsObject(), self.TouchEntity
  548.                     if ent ~= self.FetchEntity  and not ent.seagull_lift and ent ~= seagulls.Platform and phys:IsValid() and ent:GetMoveType() == MOVETYPE_VPHYSICS  then
  549.                         constraint.RemoveAll(ent)
  550.                         phys:EnableMotion(true)
  551.                         phys:AddVelocity(VectorRand()*10000)
  552.                        
  553.                         local ef = EffectData()
  554.                         ef:SetOrigin(ent:GetPos())
  555.                         util.Effect("explosion", ef)
  556.                     end
  557.                 end
  558.             end
  559.         end
  560.  
  561.         do -- standard
  562.             function ENT:Initialize()
  563.                 self:SetSize(math.Rand(0.5, 10.5))
  564.  
  565.                 self:SetModel(self.Model)
  566.                 self:PhysicsInitSphere(5 * self:GetSize())
  567.                 self:StartMotionController()
  568.                 self:SetCollisionGroup(COLLISION_GROUP_INTERACTIVE_DEBRIS)
  569.  
  570.                 self.flight_dir = math.Rand(0.3,1) * (math.random() > 0.5 and -1 or 1)
  571.  
  572.                 local phys = self:GetPhysicsObject()
  573.                     phys:SetMass(20 * self:GetSize())
  574.                     phys:SetMaterial("default_silent")
  575.                 self.phys = phys
  576.             end
  577.  
  578.             function ENT:Think()
  579.                 self:PhysWake()
  580.                 self:FetchRandom()
  581.                 self:NextThink(CurTime() + math.Rand(1,5))
  582.                 return true
  583.             end
  584.  
  585.             function ENT:PhysicsSimulate(phys, delta)
  586.                 self.vel = phys:GetVelocity()
  587.                 self.len = self.vel:Length()
  588.                 self.len2d = self.vel:Length2D()
  589.                 self.pos = phys:GetPos()
  590.                
  591.                 if self.DropIt then
  592.                     self:Drop()
  593.                     self.DropIt = false
  594.                 end
  595.                
  596.                 if not self.FetchEntity:IsValid() then
  597.                     self:Drop()
  598.                 end
  599.  
  600.                 if ms and self.FetchEntity:IsValid() and not self:IsWithinMinMax(self.FetchEntity:GetPos()) then
  601.                     self:Drop()
  602.                 end
  603.  
  604.                 if self.HoldingPlayer then
  605.                     self.FetchEntity:SetMoveType(MOVETYPE_NOCLIP)
  606.                     self.FetchEntity:GetPhysicsObject():SetVelocity(vector_origin)
  607.                     self.FetchEntity:SetVelocity(vector_origin)
  608.                     self.FetchEntity:SetPos(self:GetPos())
  609.                 end
  610.  
  611.                 local reached_message
  612.  
  613.                 if self:GetOnGround() then
  614.                     self.MoveDamping = 0.4
  615.                 elseif self.len2d > 10 then
  616.                     self.MoveDamping = 0.1
  617.                     phys:AddVelocity(vector_up * (self.len2d * 0.003))
  618.                 end
  619.  
  620.                 if self.MovePos then
  621.                     self:TryThink()
  622.                    
  623.                     self.MoveDistance = (self.MovePos-phys:GetPos()):LengthSqr()
  624.  
  625.                     if
  626.                         IsVector(self.TargetPos) and (self:GetTargetPos()-self.pos):LengthSqr() < 1300 or
  627.                         IsEntity(self.TargetPos) and (self.TouchEntity == self.TargetPos or (self:GetTargetPos()-self.pos):LengthSqr() < 10)
  628.                     then
  629.                         reached_message = self.TargetReachMessage
  630.                     end
  631.  
  632.                     if self.MoveDistance < self:GetPrefferedStopRadius()*100 then
  633.                         self:StopMoving()
  634.                     else
  635.                         self:MoveThink(phys, self.pos, self.MovePos, self.MoveDistance)
  636.  
  637.                         phys:AddVelocity(-phys:GetVelocity() * self:GetMoveDamping() * math.min(self.len2d / 1000, 1000))
  638.                         phys:AddVelocity(self.SmoothNoise * Vector(1,1,0.5) * self:GetSize() * 30)
  639.                     end
  640.                 end
  641.                
  642.                 if not self.Killing then
  643.                     self:IdleThink(phys)
  644.                 end
  645.  
  646.                 if reached_message == "pickup" then
  647.                     timer.Simple(0, function()
  648.                         self:Pickup(self.FetchEntity)
  649.                         self:SetTargetPos(seagulls.Nest, "nest")
  650.                     end)
  651.                 elseif reached_message == "nest idle" then
  652.                     self.TargetPos = nil
  653.                     self.MovePos = nil
  654.                     --self:FetchRandom()
  655.                 elseif reached_message == "kill" then
  656.                     if self.TargetPos:IsPlayer() then
  657.                         self.TargetPos:TakeDamage(self:GetSize() * 10)
  658.                        
  659.                         if not self.TargetPos:Alive() then
  660.                             self.Killing = false
  661.                         end
  662.                     end
  663.                 elseif reached_message == "nest" then
  664.                     self:Drop()
  665.                 end
  666.                
  667. --[[                if self.FetchEntity:IsPlayer() then
  668.                     if self.FetchEntity:GetMoveType() ~= MOVETYPE_WALK then
  669.                         self.FetchEntity:SetMoveType(MOVETYPE_WALK)
  670.                     end
  671.                     if self.FetchEntity:GetPos():Distance(self:GetPos()) < 5000 then
  672.                         self.FetchEntity.seagull_noclip_disallowed = self
  673.                     else
  674.                         self.FetchEntity.seagull_noclip_disallowed = nil
  675.                     end
  676.                 end ]]
  677.  
  678.                 self.Stop = false
  679.                 self.SmoothNoise = self.SmoothNoise + (((VectorRand() * 0.1) - self.SmoothNoise) * FrameTime())
  680.             end
  681.  
  682.             ENT.HP = 100
  683.             function ENT:OnTakeDamage(dmg)
  684.                 local ply = dmg:GetAttacker()
  685.                 local allowed = (dmg:GetInflictor():IsPlayer() and dmg:GetAttacker():IsPlayer())
  686.                 if not allowed then
  687.                     print("seagull coin drop dissallowed", dmg:GetInflictor(), dmg:GetAttacker(), dmg:GetDamageType())
  688.                     self.DontSpawnCoin = true
  689.                 end
  690.                
  691.                 if ply:IsPlayer() then
  692.                     self:KillTarget(ply)
  693.                 end
  694.            
  695.                 self.HP = self.HP - (dmg:GetDamage() / (self:GetSize()*0.3))
  696.                 for i=1, 100 do self:EmitSound(table.Random(self.Sounds.Pain), 160, 100) end
  697.                 if self.HP < 0 then
  698.                     self:Die()
  699.                     timer.Simple(math.random(10), function()
  700.                         seagulls.Create()
  701.                     end)
  702.                 end
  703.             end
  704.  
  705.             ENT.TouchEntity = NULL
  706.  
  707.             function ENT:StartTouch(ent)
  708.                 self.TouchEntity = ent
  709.             end
  710.  
  711.             function ENT:EndTouch(...)
  712.                 self.TouchEntity = NULL
  713.             end
  714.  
  715.             function ENT:PhysicsCollide(data)
  716.                 self.TouchEntity = data.HitEntity
  717.             end
  718.  
  719.             function ENT:Die()
  720.                 if not self.DontSpawnCoin and coins then
  721.                     local coin = coins.Create(self:GetPos(), math.floor(self:GetSize()*100))
  722.                     coin:GetPhysicsObject():AddVelocity(VectorRand()*150)
  723.                 end
  724.                 self:Remove()
  725.                 self:PlaySound("Impact")
  726.             end
  727.  
  728.             function ENT:OnRemove()
  729.                 self:Drop()
  730.             end
  731.         end
  732.     end
  733.  
  734.     scripted_ents.Register(ENT, s.ClassName, true)
  735.  
  736.     seagulls.EntityMeta = ENT
  737. end
  738.  
  739. do -- "external" hooks
  740.  
  741.     function seagulls.Call(name, ...)
  742.         for key, ent in pairs(ents.FindByClass(seagulls.ClassName)) do
  743.             if type(ent[name]) == "function" then
  744.                 ent[name](ent, ...)
  745.             end
  746.         end
  747.     end
  748.  
  749.     function seagulls.EntHook(name)
  750.         hook.Add(name, seagulls.ClassName .. "_hook", function(...)
  751.             seagulls.Call(name, ...)
  752.         end)
  753.     end
  754.  
  755.     function seagulls.Hook(name, func)
  756.         hook.Add(name, seagulls.ClassName .. "_hook", func or seagulls[name])
  757.     end
  758.  
  759.     function seagulls.DissallowPickup(ply, ent)
  760.         if ent.IsSeagull then
  761.             return false
  762.         end
  763.     end
  764.     seagulls.Hook("PhysgunDrop", seagulls.DissallowPickup)
  765.     seagulls.Hook("PhysgunPickup", seagulls.DissallowPickup)
  766.    
  767.     function seagulls.PlayerNoClip(ply)
  768.         --if IsValid(ply.seagull_noclip_disallowed) then
  769.         --  return false
  770.         --end
  771.        
  772.         if seagulls.IsWithinMinMax(ply:GetPos()) then
  773.             return false
  774.         end
  775.     end
  776.     seagulls.Hook("PlayerNoClip")
  777.    
  778.     function seagulls.PlayerDeath(ply,ent)     
  779.         if coins and ent.IsSeagull then
  780.             ply:DropCoins(ent:GetSize()*50)
  781.             ply:PayCoins(ent:GetSize()*50)
  782.             ply:SetParent()
  783.         end
  784.     end
  785.     seagulls.Hook("PlayerDeath")
  786.    
  787.     function seagulls.PlayerShouldTakeDamage(ply, ent)
  788.         if ent.IsSeagull then
  789.             return true
  790.         end
  791.     end
  792.     seagulls.Hook("PlayerShouldTakeDamage")
  793.    
  794.     if SERVER then
  795.         function seagulls.PlayerInitialSpawn()         
  796.             seagulls.RoofZ = util.QuickTrace(seagulls.Nest, vector_up * 32000).HitPos.z - 300
  797.        
  798.             if IsValid(seagulls.Platform) then seagulls.Platform:Remove() end
  799.  
  800.             seagulls.Platform = "models/props_combine/CombineInnerwallCluster1024_001a.mdl"
  801.             local platform = ents.Create("prop_physics")
  802.             platform:SetModel(seagulls.Platform)
  803.             platform:SetPos(seagulls.Nest + Vector(0,0,-200))
  804.             platform:Spawn()
  805.             platform:PhysicsInit(SOLID_VPHYSICS)
  806.             platform:SetSolid(SOLID_VPHYSICS)
  807.             platform:SetMoveType(MOVETYPE_VPHYSICS)
  808.             platform:GetPhysicsObject():EnableMotion(false)
  809.             platform:SetAngles(Angle(-80,0,0))
  810.             constraint.Weld(platform, GetWorldEntity())
  811.             seagulls.Platform = platform
  812.                
  813.             for key, value in pairs(seagulls.GetAll()) do
  814.                 value:Remove()
  815.             end
  816.  
  817.             for key, value in pairs(ents.GetAll()) do
  818.                 value.seagull_lift = nil
  819.             end
  820.  
  821.             timer.Simple(0.2, function()
  822.                 for i=1, 50 do
  823.                     seagulls.Create()
  824.                 end
  825.             end)
  826.            
  827.             hook.Remove("PlayerInitialSpawn", seagulls.ClassName .. "_hook")
  828.         end
  829.         seagulls.Hook("PlayerInitialSpawn")
  830.        
  831.         timer.Create("seagulls", 1000, 1, seagulls.PlayerInitialSpawn)
  832.     end
  833. end
  834.  
  835. seagulls.PlayerInitialSpawn()
Advertisement
Add Comment
Please, Sign In to add comment