Advertisement
g14ndev

Spin Handler Module

Apr 4th, 2024 (edited)
235
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 15.17 KB | Gaming | 0 0
  1. --*** this is a module for a RNG game it includes functions for choosing the animal and logic for showing a "Spin" visually ***---
  2. --Author: Gixnly
  3. -- the formatting may be off due to the way paste bin formats it, I don't actually format my code like this.
  4.  
  5.  
  6. local RS = game:GetService("ReplicatedStorage") -- refrence replicated storage
  7. local remotes = RS:WaitForChild("Remotes") -- refrence remotes folder
  8. local Animals = RS:WaitForChild("Animals") -- refrence animals folder
  9. local animalHandler = require(script.Parent.AnimalHandler) -- require animal handler module
  10.  
  11.  
  12. local SpinHandler = {} -- initialize table for this module.
  13.  
  14. -- chose a random animal
  15. function SpinHandler.ChooseAnimal(animals)
  16.     local animalChildren = animals:GetChildren() -- get a table of animals children
  17.     table.sort(animalChildren, function(a, b) return a.Chance.Value < b.Chance.Value end) -- sort the table based on the children's chance value (lowest to highest)
  18.     local totalEntries = 0 -- initialize entry variable
  19.     -- calculate total entries  for probability calculation
  20.     for _, animal in pairs(animalChildren) do
  21.         totalEntries += 1 / animal.Chance.Value
  22.     end
  23.     local randomEntry = math.random() -- generate a random number between 0 and 1
  24.     local cumulativeEntry = 0 -- initialize cumulativeEntry variable
  25.     local cumulativeEntryForFullRange = 0 -- initialize cumulativeEntryForFullRange variable (used in later calculations to view the cumulative ranges)
  26.     local previousCumulativeEntry = 0 -- initialize previousCumulatievEntry Variable (used so we can see in what range the selected animal was found in)
  27.     local previousCumulativeEntryForFullRange = 0 -- initialize previousCumulativeEntryForFullRange variable (used so we can see the cumulative ranges of each animal without having to return)
  28.     -- Loop through each animal to show the developer the cumuative ranges of each animal
  29.     for _, animal in pairs(animalChildren) do
  30.         previousCumulativeEntryForFullRange = cumulativeEntryForFullRange -- store previous cumulative entry in order to show the range.
  31.         cumulativeEntryForFullRange += 1/ animal.Chance.Value / totalEntries
  32.         -- Calculate the cumulative entry for the current animal by dividing 1 by its chance value and then dividing it by the total entries
  33.         -- This effectively determines the range of probabilities for each animal, ensuring that the sum of all probabilities equals 1
  34.         print(animal.Name.."'s cumulative entry range is: ",tostring(previousCumulativeEntryForFullRange).." to "..tostring(cumulativeEntryForFullRange)) -- print the ranges for the developer to see.
  35.     end
  36.  
  37.     print("Random number generated is: "..tostring(randomEntry)) -- print the random number for the developer to see.
  38.     for _, animal in pairs(animalChildren) do
  39.         previousCumulativeEntry = cumulativeEntry -- store previous cumulative entry in order to show the range.
  40.         cumulativeEntry += 1/ animal.Chance.Value / totalEntries
  41.         -- Calculate the cumulative entry for the current animal by dividing 1 by its chance value and then dividing it by the total entries
  42.         -- This effectively determines the range of probabilities for each animal, ensuring that the sum of all probabilities equals 1
  43.         print(animal.Name.."'s cumulative entry range is: ",tostring(previousCumulativeEntry).." to "..tostring(cumulativeEntry)) -- print range
  44.         if randomEntry <= cumulativeEntry then -- if the random number falls inside the range then we select the animal that has that range
  45.             print("Random number found in: ",animal.Name,"'s range") -- notify developer of selection
  46.             return animal.Name -- return the animal's name to be used to find said animal in later code
  47.         end
  48.     end
  49.  
  50. end
  51.  
  52.  
  53.  
  54.  
  55. -- choose a random animal with double the luck
  56. function SpinHandler.DoubleLuckChooseAnimal(animals)
  57.     local animalChildren = animals:GetChildren() -- get a table of animals children
  58.     table.sort(animalChildren, function(a, b) return a.Chance.Value < b.Chance.Value end) -- sort the table based on the children's chance value (lowest to highest)
  59.     local totalEntries = 0 -- initialize entry variable
  60.     -- calculate total entries  for probability calculation
  61.     for _, animal in pairs(animalChildren) do
  62.         totalEntries += 1 / animal.Chance.Value
  63.     end
  64.     -- generate a random number twice hence giving the player double the luck
  65.     local randomEntry1 = math.random()
  66.     local randomEntry2 = math.random()
  67.     -- assigning random entry to the highest of both random numbers hence giving the player a higher chance of getting a rare animal
  68.     local randomEntry = math.max(randomEntry1, randomEntry2)
  69.     local cumulativeEntry = 0 -- initialize cumulativeEntry variable
  70.     local cumulativeEntryForFullRange = 0 -- initialize cumulativeEntryForFullRange variable (used in later calculations to view the cumulative ranges)
  71.     local previousCumulativeEntry = 0 -- initialize previousCumulatievEntry Variable (used so we can see in what range the selected animal was found in)
  72.     local previousCumulativeEntryForFullRange = 0 -- initialize previousCumulativeEntryForFullRange variable (used so we can see the cumulative ranges of each animal without having to return)
  73.     -- Loop through each animal to show the developer the cumuative ranges of each animal
  74.     for _, animal in pairs(animalChildren) do
  75.         previousCumulativeEntryForFullRange = cumulativeEntryForFullRange -- store previous cumulative entry in order to show the range.
  76.         cumulativeEntryForFullRange += 1/ animal.Chance.Value / totalEntries
  77.         -- Calculate the cumulative entry for the current animal by dividing 1 by its chance value and then dividing it by the total entries
  78.         -- This effectively determines the range of probabilities for each animal, ensuring that the sum of all probabilities equals 1
  79.         print(animal.Name.."'s cumulative entry range is: ",tostring(previousCumulativeEntryForFullRange).." to "..tostring(cumulativeEntryForFullRange)) -- print the ranges for the developer to see.
  80.     end
  81.  
  82.     print("Random number generated is: "..tostring(randomEntry)) -- print the random number for the developer to see.
  83.     for _, animal in pairs(animalChildren) do
  84.         previousCumulativeEntry = cumulativeEntry -- store previous cumulative entry in order to show the range.
  85.         cumulativeEntry += 1/ animal.Chance.Value / totalEntries
  86.         -- Calculate the cumulative entry for the current animal by dividing 1 by its chance value and then dividing it by the total entries
  87.         -- This effectively determines the range of probabilities for each animal, ensuring that the sum of all probabilities equals 1
  88.         print(animal.Name.."'s cumulative entry range is: ",tostring(previousCumulativeEntry).." to "..tostring(cumulativeEntry)) -- print range
  89.         if randomEntry <= cumulativeEntry then -- if the random number falls inside the range then we select the animal that has that range
  90.             print("Random number found in: ",animal.Name,"'s range")-- notify developer of selection
  91.             return animal.Name -- return the animal's name to be used to find said animal in later code
  92.         end
  93.     end
  94. end
  95.  
  96. function SpinHandler.Spin(player) -- take the player as an argument in order to access many of the players values/gui
  97.     local db = true -- debounce in order to prevent unwanted double creation of animals or any other unwanted issue.
  98.     local selectedAnimal = SpinHandler.ChooseAnimal(Animals) -- input the animals folder inside the choose animal function
  99.     print(selectedAnimal.." was chosen in spin") -- immediately print the selected animals name, makes it easier to debug later code.
  100.     local playerGui = player.PlayerGui -- get the player's gui
  101.     local spinFrame = playerGui.SpinUI.SpinFrame -- get the spin frame
  102.     local loopCount = 0 -- initialize loop count (used for visually spinning)
  103.     local waitTime = 0.15 -- wait time inbetween spins (the spin animation loops through the animals table and shows random animals until finally showing the chosen one)
  104.     local skipConnection -- initialize a connection variable for the skip button of the spin frame
  105.     local equipConnection -- initialiE a connection variable for the equip button of the spin frame
  106.     playerGui.SpinUI.SpinButton.Visible = false -- turn the spin button invisible
  107.  
  108.     spinFrame.Visible = true -- turn the spin frame visible
  109.     spinFrame.AnimalChance.Text = "" -- immediatley put the animal chance text and animal unlocked text to empty strings (they have placeholder text so the developer could edit the ui easily)
  110.     spinFrame.AnimalUnlocked.Text = ""
  111.     spinFrame.SkipButton.Visible = false -- make sure the skip button isnt visible
  112.     spinFrame.EquipButton.Visible = false -- make sure the skip button isnt visible
  113.     for i, v in pairs(playerGui.AnimalInventory:GetChildren()) do -- turn off all other gui's
  114.         if v:IsA("GuiBase") then
  115.             if v.Visible == true then
  116.                 v.Visible = false
  117.             end
  118.  
  119.         end
  120.     end
  121.  
  122.     repeat -- reapeat loop for spinning animation
  123.  
  124.         loopCount += 1 -- increment loop count
  125.         task.wait(waitTime) -- initialize a wait in order to prevent instant text change.
  126.         local randomAnimal = math.round(math.random(1, #Animals:GetChildren())) -- select a random animal from the animals folder
  127.         spinFrame.AnimalUnlocked.Text = Animals:GetChildren()[randomAnimal].Name -- chance animal unlicked text to the animals name
  128.         spinFrame.AnimalUnlocked.TextColor3 = Animals:GetChildren()[randomAnimal].Highlight.OutlineColor -- change the animal unlocked text color to the highlight color of the animal
  129.         spinFrame.AnimalChance.Text = "" -- again making sure the chance text is not visible (an empty string)
  130.         remotes.SpinningForAnimal:FireClient(player) -- fire a remote on the client to play a "tick" sound for each rotation
  131.  
  132.         -- Gradually increase wait time to slow down the loop if we have passed the half way point of the loop
  133.         if loopCount >= 15 then
  134.             waitTime = waitTime + 0.05
  135.         end
  136.     until loopCount >= 30 -- stop loop once loopCount has reached or surpassed 30.
  137.  
  138.     spinFrame.AnimalUnlocked.Text = selectedAnimal -- show the animal unlocked text as the selected animal
  139.     spinFrame.AnimalUnlocked.TextColor3 = Animals[selectedAnimal].Highlight.OutlineColor -- change the color to the highlight color of the animal
  140.  
  141.     local chance =  Animals:FindFirstChild(selectedAnimal).Chance.Value -- get the chance value of the animal
  142.  
  143.     if chance >= Animals["Mad Cow"].Chance.Value then -- this is specifically for a animal that has a "one in zero" chance since we programattically cannot have a 0 chance we make it close to 0 by having a large number
  144.         spinFrame.AnimalChance.Text = "1 in "..tostring(0) -- chance the animal chance text to the text seen.
  145.     else -- if chance isnt at mad cow's level then simply put the animal chance text to "1 in "..the animals chance
  146.         spinFrame.AnimalChance.Text = "1 in "..tostring(chance)
  147.     end
  148.     spinFrame.AnimalChance.TextColor3 = Animals[selectedAnimal].Highlight.OutlineColor -- chance the animal chance text color to the animals highlight color
  149.     spinFrame.SkipButton.Visible = true -- turn the skip equip buttons visible
  150.     spinFrame.EquipButton.Visible = true
  151.  
  152.  
  153.     skipConnection = spinFrame.SkipButton.MouseButton1Click:Once(function() -- initialize a "Once" connection to the click event of the skip button
  154.         print("skip button pressed") -- debug print statements for the developer
  155.         if not player.PlayerAnimals:FindFirstChild(selectedAnimal) and db then -- check if the player's "player animals" already has the selected animal
  156.             db = false -- put db to false to prevent cloning
  157.             -- since the player passed the if statment that means they must not have the animal selected
  158.             local animalString = Instance.new("StringValue",player.PlayerAnimals) -- create a string value and add it to the player's player animals
  159.             animalString.Name = selectedAnimal -- set the string name to the selected animal and also set its value to the selected animal
  160.             animalString.Value = selectedAnimal
  161.  
  162.             task.delay(1,function() -- delay resetting the debounce
  163.                 db = true
  164.             end)
  165.  
  166.         end
  167.         task.wait() -- small wait before turning the skip and equip buttons invisible
  168.         spinFrame.SkipButton.Visible = false
  169.         spinFrame.EquipButton.Visible = false
  170.         spinFrame.Visible = false -- turn the spin frame invisible
  171.         task.wait(0.5) -- wait half a second before turning the spin button visible
  172.         playerGui.SpinUI.SpinButton.Visible = true
  173.         for i, v in pairs(playerGui.AnimalInventory:GetChildren()) do -- turn all the guis that arent the specific guis named from invisble to visible
  174.             if v:IsA("GuiBase")  then
  175.  
  176.                 if v.Visible == false and v.Name ~= "AnimalsFrame" or v.Name ~= "UnequipButton"  then
  177.                     v.Visible = true
  178.                 end
  179.                 if v.Visible == true and v.Name ~= "InventoryButton" then -- a debug if statement in order to prevent the guis from still being visible and to also only turn the inventory button visible
  180.                     v.Visible = false
  181.                 end
  182.  
  183.             end
  184.         end
  185.         skipConnection:Disconnect() -- disconnect the connection
  186.         skipConnection = nil -- set connection to nil
  187.         selectedAnimal = nil -- set selected animal to nil to prevent unwanted behaviour
  188.         print("skip button disconnected selected animal disconnected") -- print statement for the developer
  189.         return -- immediately return out of the function
  190.     end)
  191.  
  192.  
  193.     equipConnection = spinFrame.EquipButton.MouseButton1Click:Once(function() -- initialize a 'Once connection for the equip button click event'
  194.         print("equip button pressed") -- print statement for the developer
  195.         if typeof(selectedAnimal) == "nil" then print("selected animal was attempted to be fired again.") return end -- if selected animal is nil (aka we already skipped and for some reason the equip button was clicked after we skipped) then immediatley return
  196.         if not player.PlayerAnimals:FindFirstChild(selectedAnimal) and db then -- if the selected animal was not already in the player's player animals
  197.             db = false -- set db to false to prevent cloning
  198.             -- if the animal wasnt found that indeed means the player does not have it already.
  199.             local animalString = Instance.new("StringValue",player.PlayerAnimals) -- create string value and parent it to the player's player animals
  200.             animalString.Name = selectedAnimal -- set the string's name and value to the selected animal
  201.             animalString.Value = selectedAnimal
  202.  
  203.             animalHandler.EquipAnimal(player,player.Character,selectedAnimal) -- equip the animal using the animals handler module
  204.             task.delay(1,function() -- delay resetting the debounce
  205.                 db = true
  206.             end)
  207.  
  208.         elseif db then
  209.             db = false -- set db to false to prevent double equips
  210.             animalHandler.EquipAnimal(player,player.Character,selectedAnimal) -- equip animal because they already have it
  211.             task.delay(1,function()-- delay resetting the debounce
  212.                 db = true
  213.             end)
  214.  
  215.         end
  216.         print(spinFrame:GetChildren()," spin frame children, from equip button") -- debung print statement for the developer
  217.         task.wait() -- small wait
  218.         spinFrame.Visible = false -- turn spin frame invisible
  219.         task.wait(0.5) -- wait half a second before turning the spin button visible
  220.         playerGui.SpinUI.SpinButton.Visible = true
  221.         equipConnection:Disconnect() -- disconnect both the skip and equip connections
  222.         skipConnection:Disconnect()
  223.         equipConnection = nil -- set connections to nil and set selected animal to nil
  224.         skipConnection = nil
  225.         selectedAnimal = nil
  226.         print("equip button disconnected selected animal disconnected") -- print statement for the develop
  227.         return -- return out of function
  228.  
  229.     end)
  230. end
  231.  
  232. return SpinHandler -- return spin handler
  233.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement