Advertisement
rerere284

classes.lua

Dec 20th, 2020
672
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 20.83 KB | None | 0 0
  1. local ret = {}
  2.  
  3. local prim = require("drawingPrimitives")
  4.  
  5. local tools = require("debugFunctions")
  6.  
  7.  
  8.  
  9. local function checkTypes(check, ...)
  10.     --input is ({tocheck, tocheck, tocheck...}, type, type, type...)
  11.     local types = {...}
  12.     for i=1, math.max(#check, #types) do
  13.         --if a type was inputted and a check is not that type
  14.         if types[i] and type(check[i]) ~= types[i] then
  15.             if type(check[i]) == "table" and check[i].isClass then
  16.                 if not check[i]:isClass(types[i]) then
  17.                     return false
  18.                 end
  19.             else
  20.                 return false
  21.             end
  22.         end
  23.     end
  24.     return true
  25. end
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
  32.  
  33. local Object = {funcs = setmetatable({}, {ClassName = "Object"}), ClassName = "Object"}
  34. getmetatable(Object.funcs).__parent = Object
  35.  
  36. function Object:inherit(classname)
  37.     local cls = {ClassName = classname}
  38.     setmetatable(cls, {__index = self})
  39.     cls.funcs = {}
  40.     setmetatable(cls.funcs, {
  41.         __index = self.funcs, --if an instance doesn't have a func, look in parent's funcs
  42.         __parent = cls,
  43.         ClassName = classname --so that thing.ClassName works
  44.     })
  45.     return cls
  46. end
  47.  
  48. function Object:new(...)
  49.     local obj = {}
  50.     setmetatable(obj, {__index = self.funcs})
  51.     obj.data = {}
  52.     if obj.init then obj:init(...) end
  53.     return obj
  54. end
  55.  
  56. function Object:getParentClass()
  57.     local t = getmetatable(self)
  58.     if not t then return nil end
  59.     return getmetatable(self).__index
  60. end
  61.  
  62. function Object:isClass(name)
  63.     if self.ClassName == name then
  64.         return true
  65.     end
  66.     local p = self:getParentClass()
  67.     if p then
  68.         return p:isClass(name)
  69.     else--went up the tree the whole way
  70.         return false
  71.     end
  72. end
  73.  
  74. function Object.funcs:getClass()
  75.     return getmetatable(self.funcs).__parent
  76. end
  77.  
  78. function Object.funcs:isClass(classname, lookinsubclass)
  79.     --getmetatable(self).__index is funcs
  80.     local c = getmetatable(getmetatable(self).__index).__parent
  81.     --if not type(c.ClassName) == "string" then
  82.     --    return false --also handles ClassName == nil
  83.     --else
  84.     if c.ClassName == classname then
  85.         return true
  86.     elseif lookinsubclass and c.isClass then
  87.         return c:isClass(classname)
  88.     end
  89.     return false
  90. end
  91.  
  92. function Object.funcs:find(classname, lookinsubclass)--TODO: look up lua iterator
  93.     local ret = {}
  94.     for k,v in pairs(self) do
  95.         if v.isClass ~= nil and v:isClass(classname, lookinsubclass) then
  96.             table.insert(ret, v)
  97.         end
  98.     end
  99.     return ret
  100. end
  101.  
  102. function Object.funcs:drawOut(k) --draw the outside
  103.     if self.data.drawOut then
  104.         self.data.drawOut(self, k)
  105.     end
  106. end
  107.  
  108. function Object.funcs:drawIn(k) --draw the inisde
  109.     if self.data.drawIn then
  110.         self.data.drawIn(self, k)
  111.     end
  112.     for _, k in pairs(self:getVisibleChildren()) do
  113.         --draw the outside of the children
  114.         local child = self[k]
  115.         local cType = type(child)
  116.         if cType == "table" and getmetatable(child) then
  117.             self[k]:drawOut(self[k], k)
  118.         else
  119.             if not self.data.pimitiveMeta then
  120.                 self.data.primitiveMeta = {}
  121.             end
  122.             if not self.data.primitiveMeta[k] then
  123.                 self.data.primitiveMeta[k] = {}
  124.                 self.data.primitiveMeta[k].X = math.random(0, 100)/100
  125.                 self.data.primitiveMeta[k].Y = math.random(0, 100)/100
  126.             end
  127.            
  128.             prim.drawOut(child, self.data.primitiveMeta[k])
  129.         end
  130.     end
  131. end
  132.  
  133. function Object.funcs:drawIcon(x, y, s, k) --draw the icon
  134.     if self.data.drawIcon then
  135.         self.data.drawIcon(self, x, y, s, k)
  136.     end
  137. end
  138.  
  139. function Object.funcs:keyIsVisible(k)
  140.     if type(k) == "string" then
  141.         if k == "data" then
  142.             return false
  143.         end
  144.     end
  145.     return true
  146. end
  147.  
  148. function Object.funcs:getVisibleChildren()
  149.     local ret = {}
  150.     for k, v in pairs(self) do
  151.         if self:keyIsVisible(k) then
  152.             table.insert(ret,k)
  153.         end
  154.     end
  155.     return ret
  156. end
  157.  
  158. function Object.funcs:countVisibleChildren()
  159.     local c = 0
  160.     for k, v in pairs(self) do
  161.         if self:keyIsVisible(k) then
  162.             c = c + 1
  163.         end
  164.     end
  165.     return c
  166. end
  167.  
  168. function Object.funcs:update(...)
  169.     if self.data.updateChilds then
  170.         for i=1,#self.data.updateChilds do
  171.             self.data.updateChilds[i]:update(...)
  172.         end
  173.     end
  174.     if self.data.onUpdate then
  175.         self.data.onUpdate(self, ...)
  176.     end
  177. end
  178.  
  179. function Object.funcs:afterUpdate(...)
  180.     if self.data.updateChilds then
  181.         for i=1,#self.data.updateChilds do
  182.             if self.data.updateChilds[i].afterUpdate then
  183.                 self.data.updateChilds[i]:afterUpdate(...)
  184.             end
  185.         end
  186.     end
  187.     if self.data.afterUpdate then
  188.         self.data.afterUpdate(self, ...)
  189.     end
  190. end
  191.  
  192. function Object.funcs:addUpdateChild(child)
  193.     if not self.data.updateChilds then
  194.         self.data.updateChilds = {}
  195.     end
  196.     table.insert(self.data.updateChilds, child)
  197. end
  198.  
  199. function Object.funcs:placeIn(B)
  200.     if self.Parent then
  201.         for k,v in pairs(self.Parent) do
  202.             if v == self then
  203.                 --might have issues doing this during pairs()
  204.                 table.remove(self.Parent, V)
  205.                 break
  206.             end
  207.         end
  208.         --[[ --if the above has issues use this
  209.         local toDel = nil
  210.         for k,v in pairs(self.Parent) do
  211.             if v == self then
  212.                 if type(k) == "number" then
  213.                     toDel = k
  214.                 else
  215.                     self.Parent[k] = nil
  216.                 end
  217.                 break
  218.             end
  219.         end
  220.         if toDel then table.remove(self.Parent, toDel) end
  221.         ]]
  222.     end
  223.    
  224.     if B then
  225.         table.insert(B, self)
  226.         self.Parent = B
  227.     else
  228.         self.Parent = nil
  229.     end
  230. end
  231.  
  232. Object.funcs.putIn = Object.funcs.placeIn
  233.  
  234. ret.Object = Object
  235.  
  236.  
  237.  
  238.  
  239.  
  240. local Button = Object:inherit("Button")
  241.  
  242. function Button.funcs:init(btn, pressfunc, updatefunc)
  243.     self.data.lastValue = false
  244.     self.data.toWatch = btn
  245.     self.data.onPress = pressfunc
  246.     self.data.onUpdate = updatefunc
  247. end
  248.  
  249. function Button.funcs:update(...)
  250.     if self.data.updateChilds then
  251.         for i=1,#self.data.updateChilds do
  252.             self.data.updateChilds[i]:update(...)
  253.         end
  254.     end
  255.     local value = love.keyboard.isDown(self.data.toWatch)
  256.     if value ~= self.data.lastValue and self.data.onPress then
  257.         self.data.onPress(self, value)
  258.     elseif self.data.onUpdate then
  259.         self.data.onUpdate(self, value)
  260.     end
  261.     self.data.lastValue = value
  262. end
  263.  
  264. ret.Button = Button
  265.  
  266.  
  267.  
  268.  
  269.  
  270. local Movable = Object:inherit("Movable")
  271.  
  272. function Movable.funcs:init(...)
  273.     --onCollide,  onContinuedCollision,  onCollisionEnd
  274.     local args = { ... }
  275.     self.data.Velocity = {0, 0}
  276.     self.data.StaticFriction = 0.2
  277.     self.data.KineticFriction = 0.9
  278.     self.data.Hardness = 1.0
  279.     self.data.Push = {0, 0}--used internally during collisions
  280.     self.data.Pushes = 0
  281.     self.data.Tier = 1
  282.     self.data.Targets = {default = true}
  283.     self.data.TargetTags = {all = true, default = true}
  284.     self.data.Colliding = {}--things currently colliding with
  285.     if args[1] and args[2] then
  286.         self.data.Position = {args[1], args[2]}
  287.     else
  288.         self.data.Position = {0, 0}
  289.     end
  290. end
  291.  
  292. function Movable.funcs:update(...)
  293.     --move based on velocity
  294.     self.data.Position[1] = self.data.Position[1] + self.data.Velocity[1]
  295.     self.data.Position[2] = self.data.Position[2] + self.data.Velocity[2]
  296.    
  297.     --gather directions I am being pushed in by collisions
  298.     local t = self.data.Tier
  299.     local cols = self:find("Collider", true)
  300.     local area = self.Parent and self.Parent:find("Movable", true)
  301.     if self.Parent and area then
  302.         for i=1,#cols do
  303.             for j=1,#area do--for each Movable in where my parent is, that is not me, and also is a target
  304.                 if area[j] ~= self and self:isTarget(area[j]) then
  305.                     if not area[j].data.Tier > t then
  306.                         local collided = false
  307.                         local cols2 = area[j]:find("Collider", true)
  308.                         for k=1,#cols2 do                           --for each of its colliders
  309.                             if cols[i]:isColliding(cols2[k]) then
  310.                                 --push = push + collider:getPush(otherCollider)
  311.                                 local p = self.data.Pushes
  312.                                 local newPush = cols[i]:getPush(cols2[k])
  313.                                 local w = self.data.Push[3]
  314.                                 self.data.Push[1] = ((self.data.Push[1]*p)  +  (newPush[1]*w))/(p+w)
  315.                                 self.data.Push[2] = ((self.data.Push[2]*p)  +  (newPush[2]*w))/(p+w)
  316.                                 self.data.Pushes = p + w
  317.                                
  318.                                 collided = true
  319.                             end
  320.                         end
  321.                         --deal with callbacks
  322.                         if collided and self.data.onCollide then
  323.                             if self.data.Colliding[area[j]] then
  324.                                 if self.data.onContinuedCollision then self.data.onContinuedCollision(area[j]) end
  325.                             else
  326.                                 if self.data.onCollide then self.data.onCollide(area[j]) end
  327.                                 self.data.Colliding[area[j]] = true
  328.                             end
  329.                         elseif self.data.Colliding[area[j]] then --if I WAS colliding with it...
  330.                             if self.data.onCollisionEnd then self.data.onCollisionEnd(area[j]) end
  331.                             self.data.Colliding[area[j]] = nil
  332.                         end
  333.                     end
  334.                 end
  335.             end
  336.         end
  337.     end
  338.    
  339.     --https://www.gamedev.net/forums/topic/55270-dragfriction/
  340.     --https://www.dummies.com/education/science/physics/static-friction-along-ramps/
  341.     --http://www.asawicki.info/Mirror/Car%20Physics%20for%20Games/Car%20Physics%20for%20Games.html
  342.     if math.abs(self.data.Velocity[1]) > self.data.StaticFriction then
  343.         self.data.Velocity[1] = self.data.Velocity[1] * 0.9
  344.     else
  345.         self.data.Velocity[1] = 0
  346.     end
  347.     if math.abs(self.data.Velocity[2]) > self.data.StaticFriction then
  348.         self.data.Velocity[2] = self.data.Velocity[2] * 0.9
  349.     else
  350.         self.data.Velocity[2] = 0
  351.     end
  352.    
  353.     Object.funcs.update(self, ...)
  354. end
  355.  
  356. function Movable.funcs:afterUpdate(...)
  357.     Object.funcs.afterUpdate(self, ...)
  358.    
  359.     --move based on push
  360.     self.data.Position[1] = self.data.Position[1] + self.data.Push[1]
  361.     self.data.Position[2] = self.data.Position[2] + self.data.Push[2]
  362.    
  363.     --reset push
  364.     self.data.Push = {0, 0}
  365.     self.data.Pushes = 0
  366. end
  367.  
  368. function Movable.funcs:isTarget(mov)
  369.     for k,v in pairs(self.data.Targets) do
  370.         if mov.data.TargetTags[k] then
  371.             return true
  372.         end
  373.     end
  374.     return false
  375. end
  376.  
  377. function Movable.funcs:isTouching(mov)
  378.     if type(mov) == "table" and mov.isClass and mov.isClass("Movable", true) then
  379.         if mov ~= self and self:isTarget(mov) then
  380.             if not mov.data.Tier > self.data.Tier then
  381.                 local cols = self:find("Collider", true)
  382.                 local cols2 = mov:find("Collider", true)
  383.                 local collided = false
  384.                 for i=1,#cols do--for each of my colliders
  385.                     for j=1,#cols2 do--for each of its colliders
  386.                         if cols[i]:isColliding(cols2[j]) then
  387.                             return true
  388.                         end
  389.                     end
  390.                 end
  391.             end
  392.         end
  393.     end
  394.     return false
  395. end
  396.  
  397. function Movable.funcs:addTag(t)
  398.     self.data.TargetTags["default"] = nil
  399.     if type(t) == "table" then
  400.         for k,v in pairs(t) do
  401.             if type(v) == "string" then
  402.                 self.data.TargetTags[v] = true
  403.             elseif type(k) ~= "number" then
  404.                 self.data.TargetTags[k] = true
  405.             end
  406.         end
  407.     else
  408.         self.data.TargetTags[t] = true
  409.     end
  410. end
  411. function Movable.funcs:removeTag(t)
  412.     if type(t) == "table" then
  413.         for k,v in pairs(t) do
  414.             if type(v) == "string" then
  415.                 self.data.TargetTags[v] = nil
  416.             elseif type(k) ~= "number" then
  417.                 self.data.TargetTags[k] = nil
  418.             end
  419.         end
  420.     else
  421.         self.data.TargetTags[t] = nil
  422.     end
  423.    
  424.     --if the only entry left is "all" then re-add "default"
  425.     local next = next
  426.     local i1, v1 = next(t)
  427.     if i1 == "all" and next(t, i1) == nil then
  428.         self.data.TargetTags["default"] = true
  429.     end
  430. end
  431.  
  432. function Movable.funcs:addTarget(t)
  433.     self.data.Targets["default"] = nil
  434.     if type(t) == "table" then
  435.         for k,v in pairs(t) do
  436.             if type(v) == "string" then
  437.                 self.data.Targets[v] = true
  438.             elseif type(k) ~= "number" then
  439.                 self.data.Targets[k] = true
  440.             end
  441.         end
  442.     else
  443.         self.data.Targets[t] = true
  444.     end
  445. end
  446. function Movable.funcs:removeTarget(t)
  447.     if type(t) == "table" then
  448.         for k,v in pairs(t) do
  449.             if type(v) == "string" then
  450.                 self.data.Targets[v] = nil
  451.             elseif type(k) ~= "number" then
  452.                 self.data.Targets[k] = nil
  453.             end
  454.         end
  455.     else
  456.         self.data.Targets[t] = nil
  457.     end
  458. end
  459.  
  460. ret.Movable = Movable
  461.  
  462.  
  463.  
  464.  
  465.  
  466.  
  467. local Collider = Object:inherit("Collider")
  468.  
  469. function Collider.funcs:init(...)
  470.     local args = { ... }
  471.     if args[1] and args[2] then
  472.         self.data.Position = {args[1], args[2]}
  473.         self.data.Hardness = args[3]
  474.     else
  475.         self.data.Position = {0, 0}
  476.         self.data.Hardness = args[1]
  477.     end
  478. end
  479.  
  480. ret.Collider = Collider
  481.  
  482.  
  483.  
  484.  
  485.  
  486. local CircleCol = Collider:inherit("CircleCol")
  487.  
  488. function CircleCol.funcs:init(...)
  489.     --radius, posx, posy
  490.     --radius
  491.     local args = { ... }
  492.     if checkTypes(inp, "number", "number", "number") then
  493.         self.data.Position = {args[2], args[3]}
  494.         self.data.Radius = args[1]
  495.     else
  496.         self.data.Position = {0, 0}
  497.         self.data.Radius = args[1]
  498.     end
  499.     self.data.dx = math.random(0, 100)/100
  500.     self.data.dy = math.random(0, 100)/100
  501. end
  502.  
  503. function CircleCol.funcs:isColliding(otherCol)
  504.     if otherCol:isClass("CircleCol") then
  505.         --another circle! time to check collision
  506.         local x1 = self.data.Position[1]
  507.         local y1 = self.data.Position[2]
  508.        
  509.         local x2 = otherCol.Position[1]
  510.         local y2 = otherCol.Position[2]
  511.        
  512.         local a = x1 - x2
  513.         local b = y1 - y2
  514.         local dist = sqrt((a*a) + (b*b))
  515.        
  516.         local r1 = self.data.Radius
  517.         local r2 = otherCol.data.Radius
  518.        
  519.         return dist < r1 + r2
  520.     else --if it a different type of collider, ignore it
  521.         return false
  522.     end
  523. end
  524.  
  525. function CircleCol.funcs:getPush(otherCol)
  526.     if otherCol:isClass("CircleCol") and self.Parent and otherCol.Parent then
  527.         local x1 = self.data.Position[1]
  528.         local y1 = self.data.Position[2]
  529.        
  530.         local x2 = otherCol.Position[1]
  531.         local y2 = otherCol.Position[2]
  532.        
  533.         local a = x1 - x2
  534.         local b = y1 - y2
  535.         local dist = sqrt((a*a) + (b*b))
  536.        
  537.         local r1 = self.data.Radius
  538.         local r2 = otherCol.data.Radius
  539.        
  540.         local psh = ((r1+r2)-dist)/2
  541.         if otherCol.Parent.data.Tier > self.Parent.data.Tier then
  542.             psh = psh * 2
  543.         end
  544.        
  545.         local px = (a / dist)*psh*otherCol.Parent.data.Hardness
  546.         local py = (b / dist)*psh*otherCol.Parent.data.Hardness
  547.         return {px, py, otherCol.Parent.data.Hardness^2}--note:weight value is a bit arbitrary
  548.     else --if it a different type of collider, ignore it
  549.         return {0,0,0}
  550.     end
  551. end
  552.  
  553. ret.CircleCol = CircleCol
  554.  
  555.  
  556.  
  557.  
  558.  
  559. local RectCol = Collider:inherit("RectCol")
  560.  
  561. function RectCol.funcs:init(...)
  562.     --sx, sy, posx, posy
  563.     --sx, sy
  564.     local args = { ... }
  565.     if checkTypes(inp, "number", "number", "number", "number") then
  566.         self.data.Position = {args[3], args[4]}
  567.         self.data.SizeX = args[1]
  568.         self.data.SizeY = args[2]
  569.     else
  570.         self.data.Position = {0, 0}
  571.         self.data.SizeX = args[1]
  572.         self.data.SizeY = args[2]
  573.     end
  574.     self.data.dx = math.random(0, 100)/100
  575.     self.data.dy = math.random(0, 100)/100
  576. end
  577.  
  578. function RectCol.funcs:isColliding(otherCol)
  579.     if otherCol:isClass("RectCol") then
  580.         --another rectangle! time to check collision
  581.         local x1 = self.data.Position[1]
  582.         local y1 = self.data.Position[2]
  583.        
  584.         local x2 = otherCol.Position[1]
  585.         local y2 = otherCol.Position[2]
  586.        
  587.         local sx1 = self.data.SizeX
  588.         local sx2 = otherCol.data.SizeX
  589.        
  590.         local sy1 = self.data.SizeY
  591.         local sy2 = otherCol.data.SizeY
  592.        
  593.         return ( abs(x1-x2) <= (sx1+sx2)/2 ) and ( abs(y1-y2) <= (sy1+sy2)/2 )
  594.     else --if it a different type of collider, ignore it
  595.         return false
  596.     end
  597. end
  598.  
  599. function RectCol.funcs:getPush(otherCol)
  600.     if otherCol:isClass("RectCol") and self.Parent then
  601.         local x1 = self.data.Position[1]
  602.         local y1 = self.data.Position[2]
  603.        
  604.         local x2 = otherCol.Position[1]
  605.         local y2 = otherCol.Position[2]
  606.        
  607.         local sx1 = self.data.SizeX
  608.         local sx2 = otherCol.data.SizeX
  609.        
  610.         local sy1 = self.data.SizeY
  611.         local sy2 = otherCol.data.SizeY
  612.        
  613.         local px, py = 0, 0
  614.         if  abs(x1-x2) / (sx1+sx2)  >  abs(y1-y2) / (sy1+sy2)  then
  615.             --pushing on x
  616.             px = (((sx1+sx2)/2) - abs(x1-x2))/2
  617.         else
  618.             --pushing on y
  619.             py = (((sy1+sy2)/2) - abs(y1-y2))/2
  620.         end
  621.        
  622.         if otherCol.Parent.data.Tier > self.Parent.data.Tier then
  623.             px = px * 2
  624.             py = py * 2
  625.         end
  626.        
  627.         return {px, py, self.Parent.data.Hardness^2}--note:weight value is a bit arbitrary
  628.     else --if it a different type of collider, ignore it
  629.         return {0,0,0}
  630.     end
  631. end
  632.  
  633. ret.RectCol = RectCol
  634.  
  635. --[[classes to add:
  636.  
  637. movable ✓
  638.         update() ✓
  639.             move based on velocity ✓
  640.             find all of my colliders ✓
  641.             only take the ones that are set to not be zones(?) ✓
  642.             check which ones are colliding ✓
  643.                 collider:update() ✓
  644.                 for each Movable in where my parent is, that is not my parent ✓
  645.                     for each of its colliders ✓
  646.                         collider:isColliding(otherCollider) ✓
  647.                         if so, ✓
  648.                             push = push + collider:getPush(otherCollider) ✓
  649.         afterUpdate() ✓
  650.             pos = pos + push ✓
  651.  
  652. collider ✓
  653.         percent isSoft ✓
  654.  
  655. circle collider ✓
  656.         isColliding(collider) ✓
  657.         getPush(collider) ✓
  658.  
  659. rectangle collider ✓
  660.         isColliding(collider) ✓
  661.         getPush(collider) ✓
  662. ]]
  663. --[[other things to change/consider:
  664.  
  665. ]]
  666.  
  667.  
  668.  
  669.  
  670.  
  671. local TextDisplay = Movable:inherit("TextDisplay")
  672.  
  673. function TextDisplay.funcs:init(text, ...)
  674.     Movable.funcs.init(self, ...)
  675.     self.data.text = text
  676.     self.data.fade = 0
  677.     self.data.fadeSpeed = 1/0.2
  678.     self.data.visible = false
  679.    
  680.     self.data.drawIcon = function(self, x, y, s, k)
  681.         love.graphics.setColor(1,1,1)
  682.         love.graphics.print(self.data.text, x + s/10, y + s/2)
  683.     end
  684. end
  685.  
  686. function TextDisplay.funcs:drawOut(k)
  687.     if self.data.drawOut then
  688.         self.data.drawOut(self, k)
  689.     else
  690.         local p = self.data.Position
  691.         love.graphics.setColor(1,1,1,self.data.fade)
  692.         love.graphics.print(self.data.text, p[1], p[2])
  693.         --love.graphics.setColor(1,1,1)
  694.         --love.graphics.print(self.data.fade, 30, 30)
  695.         --love.graphics.print(self.data.visible and "true" or "false", 30, 40)
  696.         --tools.showPos(p[1], p[2])
  697.     end
  698. end
  699.  
  700. function TextDisplay.funcs:update(...)
  701.     Object.funcs.update(self, ...)
  702.     local args = { ... }
  703.     local d = self.data
  704.     if d.visible then
  705.         if d.fade < 1 then
  706.             d.fade = d.fade + (d.fadeSpeed*args[1])
  707.             if d.fade > 1 then
  708.                 d.fade = 1
  709.             end
  710.         end
  711.     else
  712.         if d.fade > 0 then
  713.             d.fade = d.fade - (d.fadeSpeed*args[1])
  714.             if d.fade < 0 then
  715.                 d.fade = 0
  716.             end
  717.         end
  718.     end
  719. end
  720.  
  721. ret.TextDisplay = TextDisplay
  722.  
  723.  
  724.  
  725.  
  726.  
  727.  
  728.  
  729.  
  730.  
  731.  
  732.  
  733.  
  734. return ret
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement