CapsAdmin

Untitled

Nov 12th, 2012
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.91 KB | None | 0 0
  1. local function AccessorFunc(tbl, name, dt)
  2.     tbl["Set" .. name] = function(self, var)
  3.         if dt and self.dt then
  4.             self.dt[name] = var
  5.         else
  6.             self[name] = var
  7.         end
  8.     end
  9.  
  10.     tbl["Get" .. name] = function(self, var)
  11.         if dt and self.dt then
  12.             return self.dt[name]
  13.         else
  14.             return self[name]
  15.         end
  16.     end
  17. end
  18.  
  19. easylua.StartEntity("seagull_mount")
  20.  
  21. ENT.IsSeagullMount = true
  22. ENT.ClassName = "seagull_mount"
  23.  
  24. ENT.Model = "models/seagull.mdl"
  25. ENT.Type = "anim"
  26. ENT.Base = "base_anim"
  27.  
  28. ENT.Target = NULL
  29. ENT.Size = 1
  30.  
  31. ENT.Animations = {
  32.     Fly = "Fly",
  33.     Run = "run",
  34.     Walk = "walk",
  35.     Idle = "idle01",
  36. }
  37.  
  38. ENT.Sounds = {
  39.     Pain= {
  40.         "ambient/creatures/seagull_pain1.wav",
  41.         "ambient/creatures/seagull_pain2.wav",
  42.         "ambient/creatures/seagull_pain3.wav",
  43.     },
  44.     Idle= {
  45.         "ambient/creatures/seagull_idle1.wav",
  46.         "ambient/creatures/seagull_idle2.wav",
  47.         "ambient/creatures/seagull_idle3.wav",
  48.     },
  49.     AmbientIdle= {
  50.         "ambient/levels/coast/seagulls_ambient1.wav",
  51.         "ambient/levels/coast/seagulls_ambient2.wav",
  52.         "ambient/levels/coast/seagulls_ambient3.wav",
  53.         "ambient/levels/coast/seagulls_ambient4.wav",
  54.         "ambient/levels/coast/seagulls_ambient5.wav",
  55.     },
  56.     Impact= {
  57.         "physics/body/body_medium_impact_soft1.wav",
  58.         "physics/body/body_medium_impact_soft2.wav",
  59.         "physics/body/body_medium_impact_soft3.wav",
  60.         "physics/body/body_medium_impact_soft4.wav",
  61.         "physics/body/body_medium_impact_soft5.wav",
  62.         "physics/body/body_medium_impact_soft6.wav",
  63.         "physics/body/body_medium_impact_soft7.wav",
  64.     },
  65. }
  66.  
  67. AccessorFunc(ENT, "Size", true)
  68. AccessorFunc(ENT, "SetWingCycle", true)
  69.  
  70. function ENT:SetupDataTables()
  71.     self:DTVar("Float", 0, "Size")
  72. end
  73.  
  74. do -- util
  75.     function ENT:PlaySound(type)
  76.         self:EmitSound(
  77.             table.Random(self.Sounds[type]),
  78.             math.Clamp(math.Rand(40, 60) * self:GetSize(), 1, 160),
  79.             math.Clamp(math.random(90,110) / self:GetSize(), 25, 255)
  80.         )
  81.     end
  82.  
  83.     function ENT:GetBottom()
  84.         return self:GetPos() + Vector(0,0,-5 * self:GetSize())
  85.     end
  86.  
  87.     function ENT:GetTop()
  88.         return self:GetPos() + Vector(0,0,5 * self:GetSize())
  89.     end
  90.  
  91.     function ENT:GetOnGround()
  92.         if not self.LastOnGround or self.LastOnGround < CurTime() then
  93.             self.OnGroundCache = util.QuickTrace(self:GetBottom(), vector_up * -10, {self}).Hit
  94.             self.LastOnGround = CurTime() + 0.05
  95.         end
  96.  
  97.         return self.OnGroundCache
  98.     end
  99.    
  100.     function ENT:GetPlayerPosition()
  101.         return self:GetPos() + Vector(0,0,self:GetSize() * 7)
  102.     end
  103. end
  104.  
  105. local function setup_player(ply, ent)
  106.     if CLIENT then
  107.         ent:InvalidateBoneCache()
  108.         ply:InvalidateBoneCache()
  109.     end
  110.     local pos, ang = ent:GetTop(), ent:GetAngles()
  111.    
  112.     pos, ang = LocalToWorld(Vector(5,3,0) * ent:GetSize(), Angle(0,10,-90), pos, ang)          
  113.    
  114.     ply:SetPos(pos)
  115.     ply:SetAngles(ang)
  116.     ply:SetRenderOrigin(pos)
  117.     ply:SetRenderAngles(ang)
  118.    
  119.     ply:SetupBones()
  120.    
  121.     local wep = ply:GetActiveWeapon()
  122.     if wep:IsValid() then
  123.         wep:SetPos(pos)
  124.         wep:SetAngles(ang)
  125.         wep:SetRenderOrigin(pos)
  126.         wep:SetRenderAngles(ang)
  127.        
  128.         wep:SetupBones()
  129.     end
  130. end
  131.  
  132. if CLIENT then
  133.     language.Add("seagull_mount", "Seagull Mount")
  134.  
  135.     do -- util
  136.         function ENT:SetAnim(anim)
  137.             self:SetSequence(self:LookupSequence(self.Animations[anim]))
  138.         end
  139.     end
  140.  
  141.     do -- calc
  142.         ENT.Cycle = 0
  143.         ENT.Noise = 0
  144.  
  145.         function ENT:AnimationThink(vel, len, ang)         
  146.             local siz = self:GetSize()
  147.             len = len / siz
  148.            
  149.             if self:GetOnGround() then
  150.                 if len < 3 / siz then
  151.                     self:SetAnim("Idle")
  152.                     len = 15 / self:GetSize() * (self.Noise * 2)
  153.                 else
  154.                     self:StepSoundThink()
  155.  
  156.                     if len > 50 / siz then
  157.                         self:SetAnim("Run")
  158.                     else
  159.                         self:SetAnim("Walk")
  160.                     end
  161.                 end
  162.                
  163.                 self.Noise = (self.Noise + (math.Rand(-1,1) - self.Noise) * FrameTime())
  164.             else
  165.                 self:SetAnim("Fly")
  166.  
  167.                 if vel.z > 0 then
  168.                     len = len / 20
  169.                 else
  170.                     len = 0
  171.                     self.Cycle = 0.2
  172.                 end
  173.             end
  174.  
  175.             self.Cycle = (self.Cycle + (len / (15 / siz)) * FrameTime()) % 1
  176.             self:SetCycle(self.Cycle)
  177.         end
  178.  
  179.         function ENT:StepSoundThink()
  180.             local stepped = self.Cycle%0.5
  181.             if stepped  < 0.3 then
  182.                 if not self.stepped then
  183.                     WorldSound(
  184.                         "npc/fast_zombie/foot2.wav",
  185.                         self:GetPos(),
  186.                         math.Clamp(30 * self:GetSize(), 70, 160) + math.Rand(-5,5),
  187.                         math.Clamp(100 / (self:GetSize()/2), 40, 200) + math.Rand(-10,10)
  188.                     )
  189.                     self.stepped = true
  190.                 end
  191.             else
  192.                 self.stepped = false
  193.             end
  194.         end
  195.     end
  196.  
  197.     do -- standard
  198.         function ENT:Draw()
  199.             self.vel = self:GetVelocity() / self:GetSize()
  200.             self.len = self.vel:Length()
  201.             self.ang = self.vel:Angle()
  202.            
  203.             self:AnimationThink(self.vel, self.len, self.ang)
  204.  
  205.             self:SetModelScale(self:GetSize(), 0)
  206.            
  207.             if self.len > 5 or not self.lastang then
  208.                 self:SetAngles(self.ang)
  209.                 self.lastang = self.ang
  210.             else
  211.                 self:SetAngles(self.lastang)
  212.             end
  213.            
  214.             if self:GetOnGround() then
  215.                 self.ang = Angle(0, self.ang.y, 0)
  216.                 self.lastang = Angle(0, self.lastang and self.lastang.y or self.ang.y, 0)
  217.             end
  218.  
  219.             self:SetRenderOrigin(self:GetBottom())
  220.  
  221.             local min, max = self:GetRenderBounds()
  222.             local size = self:GetSize() * 2
  223.             self:SetRenderBounds(min * size, max * size)
  224.  
  225.             self:DrawShadow(false)
  226.             --self:SetupBones()
  227.             self:DrawModel()
  228.             self:SetRenderOrigin(nil)
  229.         end
  230.  
  231.         function ENT:Think()                   
  232.             if math.random() > 0.999 then
  233.             --  self:EmitSound(table.Random(self.Sounds.AmbientIdle), 120, math.Clamp(100 / self:GetSize(), 30, 200) + math.Rand(-10,10))
  234.             end
  235.         end
  236.     end
  237.    
  238.     local P = {}
  239.    
  240.     hook.Add("CalcView", ENT.ClassName, function(ply)
  241.         local ent = ply:GetOwner()
  242.    
  243.         if ent.IsSeagullMount and not ply:ShouldDrawLocalPlayer() then
  244.            
  245.             P.origin = ent:GetPlayerPosition()
  246.             --P.angles = ply:EyeAngles()
  247.            
  248.             setup_player(ply, ent)
  249.            
  250.             return P
  251.         end
  252.     end)
  253.    
  254.     hook.Add("PrePlayerDraw", ENT.ClassName, function(ply)
  255.         local ent = ply:GetOwner()
  256.    
  257.         if ent.IsSeagullMount then
  258.             setup_player(ply, ent)         
  259.         end
  260.     end)
  261.    
  262.     hook.Add("PostPlayerDraw", ENT.ClassName, function(ply)
  263.         local ent = ply:GetOwner()
  264.    
  265.         if ent.IsSeagullMount then         
  266.             setup_player(ply, ent)
  267.         end
  268.     end)
  269. end
  270.    
  271. local translate_sit = {
  272.     pistol = "sit_pistol",
  273.     smg = "sit_smg1",
  274.     grenade = "sit_grenade",
  275.     ar2 = "sit_ar2",
  276.     shotgun = "sit_shotgun",
  277.     rpg = "sit_rpg",
  278.     physgun = "sit_gravgun",
  279.     crossbow = "sit_crossbow",
  280.     melee = "sit_melee",
  281.     slam = "sit_slam",
  282.     normal = "sit_rollercoaster",
  283.     fists = "sit_fist",
  284.     fist = "sit_fist",
  285. }
  286.  
  287. hook.Add("UpdateAnimation", ENT.ClassName, function(ply)
  288.     local ent = ply:GetOwner()
  289.  
  290.     if ent.IsSeagullMount then 
  291.         local wep = ply:GetActiveWeapon()
  292.        
  293.         if wep:IsValid() and wep.GetHoldType and wep:GetHoldType() and #wep:GetHoldType() > 0 then
  294.             ply:SetSequence(ply:LookupSequence(translate_sit[wep:GetHoldType()]))
  295.         else
  296.             ply:SetSequence(ply:LookupSequence("sit_rollercoaster"))
  297.         end
  298.        
  299.         if CLIENT then
  300.             --setup_player(ply, ent)
  301.         end
  302.        
  303.         return true
  304.     end
  305. end)   
  306.  
  307. if SERVER then
  308.     function ENT:SetSize(siz)  
  309.         self.dt.Size = siz
  310.         self:PhysicsInitSphere(5 * self:GetSize())
  311.         self:GetPhysicsObject():SetMass(20 * self:GetSize())
  312.         self:StartMotionController()
  313.     end
  314.  
  315.     function ENT:Initialize()  
  316.         self:SetSize(math.Rand(0.75, 4))
  317.        
  318.         self:SetModel(self.Model)
  319.         self:PhysicsInitSphere(5 * self:GetSize())
  320.         self:StartMotionController()
  321.         self:SetCollisionGroup(COLLISION_GROUP_DEBRIS)
  322.  
  323.         local phys = self:GetPhysicsObject()
  324.             phys:SetMass(20 * self:GetSize())
  325.             phys:SetMaterial("default_silent")
  326.         self.phys = phys
  327.     end
  328.    
  329.     local P = {}
  330.    
  331.     P.maxangular = 1
  332.     P.maxspeed = 1000000
  333.    
  334.     P.maxspeeddamp = 1
  335.     P.maxangulardamp = 1000000
  336.    
  337.     P.secondstoarrive = 2
  338.     P.dampfactor = 0.9
  339.     P.teleportdistance = 0
  340.  
  341.     function ENT:PhysicsUpdate(phys)
  342.         self.vel = phys:GetVelocity()
  343.         self.len2d = self.vel:Length2D()
  344.        
  345.         local owner = self:GetOwner()
  346.         local vel = vector_origin * 1
  347.        
  348.         local damp = 0
  349.        
  350.         if self:GetOnGround() then
  351.        
  352.             if self.len2d < 5 * self:GetSize() then
  353.                 damp = 1
  354.             else
  355.                 damp = 0.08
  356.             end
  357.            
  358.             if owner:IsValid() then
  359.                 if owner:KeyDown(IN_FORWARD) then
  360.                     local dir = self.last_dir or self.vel:GetNormalized()
  361.                     vel = vel + dir * self:GetSize() * 3
  362.                    
  363.                     damp = 0.05
  364.                    
  365.                    
  366.                     if owner:KeyDown(IN_MOVELEFT) then
  367.                         vel = vel + owner:EyeAngles():Right() * -self:GetSize() * 3
  368.                     elseif owner:KeyDown(IN_MOVERIGHT) then
  369.                         vel = vel + owner:EyeAngles():Right() * self:GetSize() * 3
  370.                     end
  371.                    
  372.                     if owner:KeyDown(IN_SPEED) then
  373.                         vel = vel * 2
  374.                     elseif owner:KeyDown(IN_WALK) then
  375.                         vel = vel * 0.5
  376.                     end
  377.                    
  378.                     if owner:KeyPressed(IN_JUMP) then
  379.                         vel.z = vel.z + self:GetSize() * 3
  380.                         vel = vel * self:GetSize() * 5
  381.                     end
  382.                 elseif self.len2d > 0 then
  383.                     self.last_dir = owner:GetAimVector()
  384.                 end
  385.             else
  386.                 if me and me:IsValid() then                
  387.                     local pos = me:GetPos()
  388.                    
  389.                     if pos:Distance(phys:GetPos()) > 150 then
  390.                         damp = 0.5 / self:GetSize()
  391.                        
  392.                         vel = pos - phys:GetPos()
  393.                         vel = vel + Vector(math.Rand(-1,1), math.Rand(-1,1), 0) *  200 / self:GetSize()
  394.                     else
  395.                         if math.random() > 0.995 then
  396.                             vel = vel + Vector(math.Rand(-1,1), math.Rand(-1,1), 0) *  100 * self:GetSize()
  397.                         end
  398.                        
  399.                         damp = 0.1
  400.                     end
  401.                 end
  402.             end
  403.            
  404.             phys:AddVelocity(vel / 2)
  405.             phys:AddVelocity(phys:GetVelocity() * -damp)
  406.         else
  407.             if me and me:IsValid() then                
  408.                 local pos = me:GetPos()            
  409.                
  410.                 vel = (pos - phys:GetPos()):GetNormalized() * 100
  411.                 vel = vel + VectorRand() * 20
  412.                
  413.                 damp = 0.01
  414.            
  415.                 phys:AddVelocity(vel / 2)
  416.                 phys:AddVelocity(phys:GetVelocity() * -damp)
  417.             else
  418.                
  419.                 local ext_dir = vector_origin * 1
  420.  
  421.                 if owner:IsValid() then
  422.                     if owner:KeyPressed(IN_JUMP) then
  423.                         vel.z = vel.z + self:GetSize() * 30
  424.                     end
  425.                    
  426.                     ext_dir = owner:GetAimVector() * self:GetSize() * 20
  427.                 end        
  428.                
  429.                 local ang = self.vel:Angle()
  430.                 ang.p = math.NormalizeAngle(ang.p) / 90
  431.            
  432.                 local dir = (self.vel * Vector(0.05, 0.05, -0.1))
  433.                 dir.z = dir.z * (-ang.p)
  434.                
  435.                 dir = dir + ext_dir
  436.                
  437.                 phys:AddVelocity((dir * 0.9) / 2)
  438.             end
  439.         end
  440.     end
  441.    
  442.     function ENT:OwnerEnter(owner)
  443.         local old_owner = self:GetOwner()
  444.        
  445.         if not old_owner:IsValid() then
  446.            
  447.             if owner:IsPlayer() then
  448.                 owner:SetViewOffset(Vector(0, 0, 0))
  449.             end
  450.            
  451.             owner:SetPos(self:GetPos())
  452.            
  453.             owner:SetOwner(self)
  454.             self:SetOwner(owner)
  455.            
  456.             owner:SetAngles(Angle(0, 0, 0))
  457.         end
  458.     end
  459.    
  460.     function ENT:DropOwner()
  461.         local owner = self:GetOwner()
  462.        
  463.         if owner:IsValid() then
  464.             if owner:IsPlayer() then
  465.                 owner:SetViewOffset(Vector(0, 0, 64))
  466.             end
  467.            
  468.             owner:SetOwner(NULL)
  469.             self:SetOwner(NULL)
  470.            
  471.             timer.Simple(0.1, function()
  472.                 if owner:IsValid() and self:IsValid() then
  473.                     owner:SetPos(self:GetPos() + Vector() * self:GetSize() * 5)
  474.                 end
  475.             end)
  476.         end
  477.     end
  478.    
  479.     function ENT:Use(owner)
  480.         if me and me ~= owner then return end
  481.        
  482.         if owner:GetOwner().IsSeagullMount then return end
  483.        
  484.         if (self.last_use or 0) < CurTime() then
  485.             self:OwnerEnter(owner)
  486.             self.last_use = CurTime() + 0.5
  487.         end
  488.     end
  489.    
  490.     hook.Add("KeyRelease", ENT.ClassName, function(ply, key)       
  491.         local ent = ply:GetOwner()
  492.        
  493.         if ent.IsSeagullMount and key == IN_USE then
  494.             if ent:IsValid() then
  495.                 if (ent.last_use or 0) < CurTime() then
  496.                     ent:DropOwner()
  497.                     ent.last_use = CurTime() + 0.5
  498.                 end
  499.             end
  500.         end
  501.     end)
  502.  
  503.     function ENT:OnTakeDamage(dmg)
  504.         print(self, dmg:GetAttacker(), dmg:GetDamage())
  505.     end
  506.  
  507.     function ENT:Die()
  508.         self:Remove()
  509.         self:PlaySound("Impact")
  510.     end
  511.  
  512.     function ENT:OnRemove()
  513.         self:DropOwner()
  514.     end
  515. end
  516.  
  517. hook.Add("Move", ENT.ClassName, function(ply, mov)
  518.     local ent = ply:GetOwner()
  519.    
  520.     if ent.IsSeagullMount then
  521.         ply:SetViewOffset(vector_origin)
  522.        
  523.         mov:SetVelocity(vector_origin)
  524.         mov:SetOrigin(ent:GetPlayerPosition())
  525.        
  526.         ent:PhysWake()
  527.            
  528.         return true
  529.     end
  530. end)
  531.  
  532. easylua.EndEntity()
Advertisement
Add Comment
Please, Sign In to add comment