CapsAdmin

Untitled

May 24th, 2012
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 15.76 KB | None | 0 0
  1. local ENT = {}
  2.  
  3. ENT.Type = "anim"
  4. ENT.Base = "base_anim"
  5.  
  6. ENT.ClassName = "fairy"
  7.  
  8. if CLIENT then
  9.  
  10.     ENT.Size = 1
  11.  
  12.     function ENT:VectorRandSphere()
  13.         return Angle(math.Rand(-180,180),math.Rand(-180,180),math.Rand(-180,180)):Up()
  14.     end
  15.  
  16.     function ENT:SetFairyColorEasy(hue)
  17.         self:SetFairyColor(HSVToColor(hue, 0.35, 1))
  18.     end
  19.  
  20.     function ENT:SetFairyColor(color)
  21.         self.Color = color
  22.         local h,s,v = ColorToHSV(self.Color)
  23.         self.Color2 = HSVToColor(h,0.5,1)
  24.     end
  25.  
  26.     function ENT:PlayPhrase(text)
  27.         text = text:lower()
  28.         text = text .. " "
  29.         local duration = 0
  30.         local sounds = {}
  31.  
  32.         local question = text:find("%?") ~= nil
  33.         local total_time = 0
  34.         for chunk in text:gmatch("([%a][aeiou]+[bcdfghjklmnpqrstvwxz]-)") do
  35.             local path = "alan/midna/speech"..tostring(math.max(tonumber(util.CRC(chunk))%47, 1))..".wav"
  36.             local pitch = math.random(120,125)
  37.             local len = SoundDuration(path) * (pitch / 100) - 0.05
  38.             table.insert(
  39.                 sounds,
  40.                 {
  41.                     snd = CreateSound(self, path),
  42.                     pitch = pitch,
  43.                     len = len,
  44.                 }
  45.             )
  46.             total_time = total_time + len
  47.         end
  48.  
  49.         self.AskingQuestion = question
  50.         self.SoundQueueStart = CurTime()
  51.         self.SoundQueueLength = total_time
  52.         self.SoundQueue = sounds
  53.     end
  54.  
  55.     function ENT:Ouch()
  56.         local sounds = {}
  57.  
  58.         local path = "alan/nymph/NymphHit_0"..math.random(4)..".wav"
  59.         local pitch = math.random(95,105)
  60.         local len = SoundDuration(path) * (pitch / 100) - 0.05
  61.         table.insert(
  62.             sounds,
  63.             {
  64.                 snd = CreateSound(self, path),
  65.                 pitch = pitch,
  66.                 len = len,
  67.             }
  68.         )
  69.  
  70.         self.SoundQueue = sounds
  71.         self.Hurting = true
  72.         timer.Simple(math.Rand(1,2), function() if self:IsValid() then self.Hurting = false end end)
  73.     end
  74.  
  75.     function ENT:Bounce()
  76.         local csp = CreateSound(self, "alan/bonk.wav")
  77.         csp:PlayEx(100, math.random(95,105))
  78.     end
  79.  
  80.     function ENT:Laugh()
  81.         local sounds = {}
  82.  
  83.         local path = "alan/nymph/NymphGiggle_0"..math.random(9)..".wav"
  84.         local pitch = math.random(95,105)
  85.         local len = SoundDuration(path) * (pitch / 100) - 0.05
  86.         table.insert(
  87.             sounds,
  88.             {
  89.                 snd = CreateSound(self, path),
  90.                 pitch = pitch,
  91.                 len = len,
  92.             }
  93.         )
  94.         table.insert(sounds, {path = path, snd = CreateSound(self, path), pitch = math.random(95,105)})
  95.  
  96.         self.Laughing = true
  97.  
  98.         self.AskingQuestion = false
  99.         self.SoundQueue = sounds
  100.     end
  101.  
  102.     function ENT:CalcSoundQueue()
  103.         if self.SoundQueue then
  104.             self.sound_idx = self.sound_idx or 1
  105.             local data = self.SoundQueue[self.sound_idx]
  106.  
  107.  
  108.             --LocalPlayer():SetDSP(27)
  109.  
  110.             if not data then
  111.                 self.SoundQueue = nil
  112.                 self.question_pitch = 1
  113.                 self.sound_idx = 1
  114.                 --LocalPlayer():SetDSP(0)
  115.                 return
  116.             end
  117.  
  118.             if not data.len then return end -- ????
  119.  
  120.             if not data.busy then
  121.                 data.busy = true
  122.                 data.snd:PlayEx(100, data.pitch)
  123.                 data.next = CurTime() + data.len * (100 / 120)
  124.                 self.SizePulse = math.Rand(1.3,1.8)
  125.             end
  126.  
  127.             if self.AskingQuestion and self:GetPhraseFraction() > 0.7 then
  128.                 self.question_pitch = self.question_pitch or 1
  129.                 self.question_pitch = (self.question_pitch + (self.SoundQueueLength / 300) * (FrameTime() * 130)) ^ 1.056
  130.  
  131.                 data.snd:ChangePitch(data.pitch + self.question_pitch)
  132.  
  133.                 data.next = data.next - (self.question_pitch / 10000)
  134.             end
  135.  
  136.             if data.next and data.next < CurTime() then
  137.                 data.snd:Stop()
  138.                 self.sound_idx = self.sound_idx + 1
  139.             end
  140.         end
  141.     end
  142.  
  143.     local wing_mdl = Model("models/python1320/wing.mdl")
  144.     local wing_mat = "alan/wing"
  145.  
  146.     ENT.WingSpeed = 6.3
  147.     ENT.FlapLength = 50
  148.     ENT.WingSize = 0.4
  149.  
  150.     ENT.SizePulse = 1
  151.  
  152.     local ClientsideModelEx = function(mdl) local ent = ents.Create("prop_physics") ent:SetModel(mdl) return ent end
  153.  
  154.     function ENT:Initialize()
  155.         self.Emitter = ParticleEmitter(vector_origin)
  156.         self.Emitter:SetNoDraw(true)
  157.  
  158.         self.leftwing = ClientsideModelEx(wing_mdl)
  159.         self.rightwing = ClientsideModelEx(wing_mdl)
  160.         self.bleftwing = ClientsideModelEx(wing_mdl)
  161.         self.brightwing = ClientsideModelEx(wing_mdl)
  162.  
  163.         self.leftwing:SetNoDraw(true)
  164.         self.rightwing:SetNoDraw(true)
  165.         self.bleftwing:SetNoDraw(true)
  166.         self.brightwing:SetNoDraw(true)
  167.  
  168.         self.leftwing:SetMaterial(wing_mat)
  169.         self.rightwing:SetMaterial(wing_mat)
  170.         self.bleftwing:SetMaterial(wing_mat)
  171.         self.brightwing:SetMaterial(wing_mat)
  172.  
  173.         self.light = DynamicLight(self:EntIndex())
  174.  
  175.         self.flap = CreateSound(self, "alan/flap.wav")
  176.         self.float = CreateSound(self, "alan/float.wav")
  177.  
  178.         self.flap:Play()
  179.         self.float:Play()
  180.  
  181.         self.flap:ChangeVolume(0.2)
  182.  
  183.         self:SetFairyColorEasy(tonumber(util.CRC(self:EntIndex()))%360)
  184.         self.Size = (tonumber(util.CRC(self:EntIndex()))%100/100) + 0.5
  185.     end
  186.  
  187.     ENT.RenderGroup = RENDERGROUP_TRANSLUCENT
  188.  
  189.     function ENT:DrawTranslucent()
  190.         self:CalcAngles()
  191.  
  192.         self:DrawParticles()
  193.         self:DrawWings()
  194.         self:DrawSprites()
  195.     end
  196.  
  197.     function ENT:Think()
  198.         self:CalcSounds()
  199.         self:CalcLight()
  200.         self:CalcPulse()
  201.  
  202.         self.leftwing:SetModelScale(Vector(1,0.5,1)*self.Size*self.WingSize)
  203.         self.rightwing:SetModelScale(Vector(1,0.5,1)*self.Size*self.WingSize)
  204.  
  205.         self.bleftwing:SetModelScale(Vector()*(self.Size/3*self.WingSize))
  206.         self.brightwing:SetModelScale(Vector()*(self.Size/3*self.WingSize))
  207.  
  208.         self:NextThink(CurTime())
  209.         return true
  210.     end
  211.  
  212.     function ENT:CalcPulse()
  213.         self.SizePulse = math.Clamp(self.SizePulse + ((1 - self.SizePulse) * FrameTime() * 5), 1, 3)
  214.     end
  215.  
  216.     function ENT:CalcAngles()
  217.         if self.Hurting then return end
  218.  
  219.         local vel = self:GetVelocity()
  220.         if vel:Length() > 2 then
  221.             local ang = vel:Angle()
  222.             self:SetAngles(ang)
  223.             self.last_ang = ang
  224.         elseif self.last_ang then
  225.             self:SetAngles(self.last_ang)
  226.         end
  227.     end
  228.  
  229.     local function add_0(n)
  230.         return n < 10 and "0"..n or n
  231.     end
  232.  
  233.     function ENT:Say(txt)
  234.         if LocalPlayer():EyePos():Distance(self:GetPos()) > 2000 then return end
  235.  
  236.         local tbl = {}
  237.  
  238.         if self.is_dead then
  239.             table.insert( tbl, Color( 255, 30, 40 ) )
  240.             table.insert( tbl, "*DEAD* " )
  241.         end
  242.  
  243.         local time = os.date("*t")
  244.  
  245.         table.insert( tbl, Color(118, 170, 217) )
  246.         table.insert( tbl, string.format("%s:%s", add_0(time.hour), add_0(time.min)) )
  247.         table.insert( tbl, Color( 255, 255, 255 ) )
  248.         table.insert( tbl, " - " )
  249.  
  250.         table.insert(tbl, self.Color)
  251.         table.insert(tbl, "Fairy")
  252.         table.insert(tbl, color_white)
  253.         table.insert(tbl, ": " .. txt)
  254.  
  255.         chat.AddText(unpack(tbl))
  256.  
  257.         self:PlayPhrase(txt)
  258.     end
  259.  
  260.     function ENT:GetPhraseFraction()
  261.         return -(((self.SoundQueueLength - CurTime()) + self.SoundQueueStart - 1) / 2) + 1
  262.     end
  263.  
  264.     function ENT:CalcSounds()
  265.         self.speed = 6.3
  266.  
  267.         if self.Hurting then
  268.             self.flap:Stop()
  269.         else
  270.             self.flap:Play()
  271.             self.flap:ChangeVolume(0.2)
  272.         end
  273.  
  274.         local length = self:GetVelocity():Length()
  275.  
  276.         self.float:ChangePitch(length/50+100)
  277.         self.float:ChangeVolume(length/100)
  278.  
  279.         self.flap:ChangePitch((length/50+100) + self.SizePulse * 20)
  280.         self:CalcSoundQueue()
  281.     end
  282.  
  283.     function ENT:CalcLight()
  284.         if self.light then
  285.             self.light.Pos = self:GetPos()
  286.  
  287.             self.light.r = self.Color2.r
  288.             self.light.g = self.Color2.g
  289.             self.light.b = self.Color2.b
  290.  
  291.             self.light.Brightness = self.Size * 1
  292.             self.light.Size = self.Size * 512
  293.             self.light.Decay = self.Size * 32 * 5
  294.             self.light.DieTime = CurTime() + 1
  295.         end
  296.     end
  297.  
  298.     local glow = Material("sprites/light_glow02_add")
  299.     local warp = Material("particle/warp2_warp")
  300.     local eye = Material("particle/warp1_warp")
  301.     local blur = Material("sprites/heatwave")
  302.  
  303.     ENT.Blink = math.huge
  304.  
  305.     function ENT:DrawSprites()
  306.         local pos = self:GetPos()
  307.         local pulse = math.sin(CurTime()*2) * 0.5
  308.  
  309.         render.SetMaterial(warp)
  310.             render.DrawSprite(
  311.                 pos, 12 * self.Size + pulse,
  312.                 12 * self.Size + pulse,
  313.                 Color(self.Color.r, self.Color.g, self.Color.b, 100)
  314.             )
  315.  
  316.         render.SetMaterial(blur)
  317.             render.DrawSprite(
  318.                 pos, (1-self.SizePulse) * 20,
  319.                 (1-self.SizePulse) * 20,
  320.                 Color(10,10,10, 1)
  321.             )
  322.  
  323.         render.SetMaterial(glow)
  324.             render.DrawSprite(
  325.                 pos,
  326.                 50 * self.Size,
  327.                 50 * self.Size,
  328.                 Color(self.Color.r, self.Color.g, self.Color.b, 150)
  329.             )
  330.             render.DrawSprite(
  331.                 pos,
  332.                 30 * self.Size,
  333.                 30 * self.Size,
  334.                 self.Color
  335.             )
  336.  
  337.         local fade_mult = math.Clamp(-self:GetForward():Dot((self:GetPos() - LocalPlayer():EyePos()):Normalize()), 0, 1)
  338.  
  339.         if fade_mult ~= 0 then
  340.             render.SetMaterial(eye)
  341.             if self.Blink > CurTime() then
  342.                 render.DrawSprite(
  343.                     pos + (self:GetRight() * 0.8 + self:GetUp() * 0.7) * self.Size,
  344.  
  345.                     0.5 * fade_mult * self.Size,
  346.                     0.5 * fade_mult * self.Size,
  347.  
  348.                     Color(10,10,10,200 * fade_mult)
  349.                 )
  350.                 render.DrawSprite(
  351.                     pos + (self:GetRight() * -0.8 + self:GetUp() * 0.7) * self.Size,
  352.  
  353.                     0.5 * fade_mult * self.Size,
  354.                     0.5 * fade_mult * self.Size,
  355.  
  356.                     Color(10,10,10,200 * fade_mult)
  357.                 )
  358.             else
  359.                 self.Blink = math.random() < 0.99 and CurTime()-0.2 or math.huge
  360.             end
  361.             render.DrawSprite(
  362.                 pos + (self:GetRight() * -0.05 -self:GetUp() * 0.7) * self.Size,
  363.  
  364.                 0.8 * fade_mult * self.Size * self.SizePulse,
  365.                 0.8 * fade_mult * self.Size * self.SizePulse,
  366.  
  367.                 Color(10,10,10,200*fade_mult)
  368.             )
  369.  
  370.         end
  371.     end
  372.  
  373.     function ENT:DrawSunbeams()
  374.         local pos = self:GetPos():ToScreen()
  375.         if (pos.x > 0 and pos.x < ScrW()) and (pos.y > 0 and pos.y < ScrH()) then
  376.             local mult = -math.Clamp((LocalPlayer():EyePos() - self:GetPos()):LengthSqr()*0.00001, 0, 1) + 1
  377.             if mult ~= 0 then
  378.                 DrawSunbeams(0.8, mult * math.Clamp(0.1 * self.Size * self.SizePulse, 0.1, 0.3), 0.05, pos.x / ScrW(), pos.y / ScrH())
  379.             end
  380.         end
  381.     end
  382.  
  383.     function ENT:DrawParticles()
  384.         --for i=1, 3 do
  385.             local particle = self.Emitter:Add("particle/Particle_Glow_05_AddNoFog", self:GetPos() + (self:VectorRandSphere() * self.Size * 4 * math.random()))
  386.             local mult = math.Clamp((self:GetVelocity():Length() * 0.1), 0, 1)
  387.  
  388.             particle:SetDieTime(math.Rand(0.5, 2))
  389.             particle:SetColor(self.Color.r, self.Color.g, self.Color.b)
  390.  
  391.  
  392.             if self.Hurting then
  393.                 particle:SetGravity(physenv.GetGravity())
  394.                 particle:SetVelocity((self:GetVelocity() * 0.1) + (self:VectorRandSphere() * math.random(20, 30)))
  395.                 particle:SetAirResistance(math.Rand(1,3))
  396.             else
  397.                 particle:SetAirResistance(math.Rand(5,15))
  398.                 particle:SetVelocity((self:GetVelocity() * 0.1) + (self:VectorRandSphere() * math.random(2, 5)))
  399.                 particle:SetGravity(VectorRand())
  400.             end
  401.  
  402.             particle:SetStartAlpha(0)
  403.             particle:SetEndAlpha(255)
  404.  
  405.             --particle:SetEndLength(self.Size * 3)
  406.             particle:SetStartSize(math.Rand(1, self.Size*8))
  407.             particle:SetEndSize(0)
  408.  
  409.             particle:SetCollide(true)
  410.             particle:SetRoll(math.random())
  411.             particle:SetBounce(0.8)
  412.            
  413.             particle:SetCollideCallback(function(...)
  414.                 hook.Call("FairyParticleCollide", nil, self, ...)
  415.             end)
  416.         --end
  417.         self.Emitter:Draw()
  418.     end
  419.  
  420.     function ENT:DrawWings(offset)
  421.         offset = offset or 0
  422.         self.WingSpeed = (6.3 + (self.SizePulse)) * (self.Hurting and 0 or 1)
  423.  
  424.         local offsetangle = Angle(0,0,-20)
  425.  
  426.         local leftposition, leftangles = LocalToWorld(Vector(0), Angle(0,TimedSin(self.WingSpeed,-self.FlapLength,0,offset), 0) + Angle(0,290,0) + offsetangle, self:GetPos(), self:GetAngles())
  427.         local rightposition, rightangles = LocalToWorld(Vector(0), Angle(0,TimedCos(self.WingSpeed,0,self.FlapLength,offset), 0) + Angle(0,290,0) + offsetangle, self:GetPos(), self:GetAngles())
  428.  
  429.         self.leftwing:SetPos(leftposition)
  430.         self.rightwing:SetPos(rightposition)
  431.  
  432.         self.leftwing:SetAngles(leftangles)
  433.         self.rightwing:SetAngles(rightangles)
  434.  
  435.         local bleftposition, bleftangles = LocalToWorld(Vector(0), Angle(TimedSin(self.WingSpeed,-self.FlapLength,0,offset),0, 0) + Angle(20,260,60) + offsetangle, self:GetPos(), self:GetAngles())
  436.         local brightposition, brightangles = LocalToWorld(Vector(0), Angle(TimedCos(self.WingSpeed,0,self.FlapLength,offset),0, 0) + Angle(20,260,60) + offsetangle, self:GetPos(), self:GetAngles())
  437.  
  438.         self.bleftwing:SetPos(bleftposition)
  439.         self.brightwing:SetPos(brightposition)
  440.  
  441.         self.bleftwing:SetAngles(bleftangles)
  442.         self.brightwing:SetAngles(brightangles)
  443.  
  444.  
  445.         render.SuppressEngineLighting(true)
  446.         render.SetColorModulation(self.Color2.r/200, self.Color2.g/200, self.Color2.b/200)
  447.  
  448.         self.leftwing:SetupBones()
  449.         self.rightwing:SetupBones()
  450.         self.bleftwing:SetupBones()
  451.         self.brightwing:SetupBones()
  452.  
  453.         self.leftwing:DrawModel()
  454.         self.rightwing:DrawModel()
  455.         self.bleftwing:DrawModel()
  456.         self.brightwing:DrawModel()
  457.  
  458.         render.SetColorModulation(0,0,0)
  459.         render.SuppressEngineLighting(false)
  460.     end
  461.  
  462.     function ENT:OnRemove()
  463.         SafeRemoveEntity(self.leftwing)
  464.         SafeRemoveEntity(self.rightwing)
  465.         SafeRemoveEntity(self.bleftwing)
  466.         SafeRemoveEntity(self.brightwing)
  467.  
  468.         self.flap:Stop()
  469.         self.float:Stop()
  470.     end
  471.  
  472.     hook.Add("RenderScreenspaceEffects", "fairy_sunbeams", function()
  473.         if not render.SupportsPixelShaders_2_0() then error("your gpu does not support pixel shader 2.0!") end
  474.         for key, ent in pairs(ents.FindByClass("fairy")) do
  475.             ent:DrawSunbeams()
  476.         end
  477.     end)
  478.  
  479.     usermessage.Hook("fairy_func_call", function(umr)
  480.         local ent = umr:ReadEntity()
  481.         local func = umr:ReadString()
  482.         local args = glon.decode(umr:ReadString())
  483.  
  484.         if ent:IsValid() then
  485.             ent[func](ent, unpack(args))
  486.         end
  487.     end)
  488. end
  489.  
  490. if SERVER then
  491.  
  492.     function ENT:Initialize()
  493.         self:SetModel("models/dav0r/hoverball.mdl")
  494.         self:PhysicsInit(SOLID_VPHYSICS)
  495.         self:SetMoveType(MOVETYPE_VPHYSICS)
  496.         self:SetSolid(SOLID_VPHYSICS)
  497.  
  498.         self:StartMotionController()
  499.  
  500.         self:PhysWake()
  501.  
  502.         self:GetPhysicsObject():EnableGravity(false)
  503.     end
  504.  
  505.     function ENT:MoveTo(pos)
  506.         self.MovePos = pos
  507.     end
  508.  
  509.     function ENT:HasReachedTarget()
  510.         return self.MovePos and self:GetPos():Distance(self.MovePos) < 50
  511.     end
  512.  
  513.     function ENT:PhysicsSimulate(phys)
  514.         if self.STOP_THAT then return end
  515.  
  516.         if self.GravityOn then return end
  517.  
  518.         if self.MovePos and not self:HasReachedTarget() then
  519.             phys:AddVelocity(self.MovePos - phys:GetPos())
  520.             phys:AddVelocity(self:GetVelocity() * -0.4)
  521.             self.MovePos = nil
  522.         else
  523.             phys:AddVelocity(math.random() > 0.995 and VectorRand() * 100 or (phys:GetVelocity()*0.01))
  524.             phys:AddVelocity(self:GetVelocity() * -0.05)
  525.         end
  526.     end
  527.  
  528.     function ENT:CalcMove()
  529.         local pos = vector_origin
  530.         local tbl = ents.FindByClass("fairy")
  531.  
  532.         if #tbl >= 2 then
  533.  
  534.             for idx, ent in pairs(tbl) do
  535.                 pos = pos + ent:GetPos() + VectorRand()
  536.             end
  537.  
  538.             pos = pos/#tbl
  539.  
  540.             self:MoveTo(pos)
  541.         end
  542.     end
  543.    
  544.     function ENT:Think()
  545.         if self.STOP_THAT then return end
  546.  
  547.         self:PhysWake()
  548.  
  549.         self:CalcMove()
  550.     end
  551.  
  552.     function ENT:EnableGravity(time)
  553.         local phys = self:GetPhysicsObject()
  554.         phys:EnableGravity(true)
  555.         self.GravityOn = true
  556.  
  557.         timer.Simple(time, function()
  558.             if phys:IsValid() then
  559.                 phys:EnableGravity(false)
  560.                 self.GravityOn = false
  561.             end
  562.         end)
  563.     end
  564.  
  565.     function ENT:CallClientFunction(func, ...)
  566.         umsg.Start("fairy_func_call")
  567.             umsg.Entity(self)
  568.             umsg.String(func)
  569.             umsg.String(glon.encode({...}))
  570.         umsg.End()
  571.     end
  572.  
  573.     function ENT:OnTakeDamage(dmg)
  574.         if self.STOP_THAT then return end
  575.  
  576.         local phys = self:GetPhysicsObject()
  577.         phys:AddVelocity(dmg:GetDamageForce())
  578.         self:EnableGravity(math.Rand(1,2))
  579.         self:CallClientFunction("Ouch")
  580.     end
  581.  
  582.     function ENT:PhysicsCollide(data, phys)
  583.         if self.STOP_THAT then return end
  584.  
  585.         if data.Speed > 50 and data.DeltaTime > 0.2 then
  586.             self:CallClientFunction("Ouch")
  587.             self:EnableGravity(math.Rand(0.5,1))
  588.         end
  589.  
  590.         self:LaughAtMe()
  591.  
  592.         phys:SetVelocity(phys:GetVelocity():Normalize() * data.OurOldVelocity:Length() * 0.99)
  593.     end
  594.  
  595.     function ENT:OnRemove()
  596.         self:StopMotionController()
  597.  
  598.         self.STOP_THAT = true
  599.     end
  600.  
  601.     function ENT:LaughAtMe()
  602.         for key, ent in pairs(ents.FindByClass("fairy")) do
  603.             if ent ~= self and math.random() > 0.5 then
  604.                 ent:CallClientFunction("Laugh")
  605.             end
  606.         end
  607.     end
  608. end
  609.  
  610. scripted_ents.Register(ENT, ENT.ClassName, true)
Advertisement
Add Comment
Please, Sign In to add comment