Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --*** this is a module for a RNG game it includes functions for choosing the animal and logic for showing a "Spin" visually ***---
- --Author: Gixnly
- -- the formatting may be off due to the way paste bin formats it, I don't actually format my code like this.
- local RS = game:GetService("ReplicatedStorage") -- refrence replicated storage
- local remotes = RS:WaitForChild("Remotes") -- refrence remotes folder
- local Animals = RS:WaitForChild("Animals") -- refrence animals folder
- local animalHandler = require(script.Parent.AnimalHandler) -- require animal handler module
- local SpinHandler = {} -- initialize table for this module.
- -- chose a random animal
- function SpinHandler.ChooseAnimal(animals)
- local animalChildren = animals:GetChildren() -- get a table of animals children
- 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)
- local totalEntries = 0 -- initialize entry variable
- -- calculate total entries for probability calculation
- for _, animal in pairs(animalChildren) do
- totalEntries += 1 / animal.Chance.Value
- end
- local randomEntry = math.random() -- generate a random number between 0 and 1
- local cumulativeEntry = 0 -- initialize cumulativeEntry variable
- local cumulativeEntryForFullRange = 0 -- initialize cumulativeEntryForFullRange variable (used in later calculations to view the cumulative ranges)
- local previousCumulativeEntry = 0 -- initialize previousCumulatievEntry Variable (used so we can see in what range the selected animal was found in)
- local previousCumulativeEntryForFullRange = 0 -- initialize previousCumulativeEntryForFullRange variable (used so we can see the cumulative ranges of each animal without having to return)
- -- Loop through each animal to show the developer the cumuative ranges of each animal
- for _, animal in pairs(animalChildren) do
- previousCumulativeEntryForFullRange = cumulativeEntryForFullRange -- store previous cumulative entry in order to show the range.
- cumulativeEntryForFullRange += 1/ animal.Chance.Value / totalEntries
- -- Calculate the cumulative entry for the current animal by dividing 1 by its chance value and then dividing it by the total entries
- -- This effectively determines the range of probabilities for each animal, ensuring that the sum of all probabilities equals 1
- print(animal.Name.."'s cumulative entry range is: ",tostring(previousCumulativeEntryForFullRange).." to "..tostring(cumulativeEntryForFullRange)) -- print the ranges for the developer to see.
- end
- print("Random number generated is: "..tostring(randomEntry)) -- print the random number for the developer to see.
- for _, animal in pairs(animalChildren) do
- previousCumulativeEntry = cumulativeEntry -- store previous cumulative entry in order to show the range.
- cumulativeEntry += 1/ animal.Chance.Value / totalEntries
- -- Calculate the cumulative entry for the current animal by dividing 1 by its chance value and then dividing it by the total entries
- -- This effectively determines the range of probabilities for each animal, ensuring that the sum of all probabilities equals 1
- print(animal.Name.."'s cumulative entry range is: ",tostring(previousCumulativeEntry).." to "..tostring(cumulativeEntry)) -- print range
- if randomEntry <= cumulativeEntry then -- if the random number falls inside the range then we select the animal that has that range
- print("Random number found in: ",animal.Name,"'s range") -- notify developer of selection
- return animal.Name -- return the animal's name to be used to find said animal in later code
- end
- end
- end
- -- choose a random animal with double the luck
- function SpinHandler.DoubleLuckChooseAnimal(animals)
- local animalChildren = animals:GetChildren() -- get a table of animals children
- 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)
- local totalEntries = 0 -- initialize entry variable
- -- calculate total entries for probability calculation
- for _, animal in pairs(animalChildren) do
- totalEntries += 1 / animal.Chance.Value
- end
- -- generate a random number twice hence giving the player double the luck
- local randomEntry1 = math.random()
- local randomEntry2 = math.random()
- -- assigning random entry to the highest of both random numbers hence giving the player a higher chance of getting a rare animal
- local randomEntry = math.max(randomEntry1, randomEntry2)
- local cumulativeEntry = 0 -- initialize cumulativeEntry variable
- local cumulativeEntryForFullRange = 0 -- initialize cumulativeEntryForFullRange variable (used in later calculations to view the cumulative ranges)
- local previousCumulativeEntry = 0 -- initialize previousCumulatievEntry Variable (used so we can see in what range the selected animal was found in)
- local previousCumulativeEntryForFullRange = 0 -- initialize previousCumulativeEntryForFullRange variable (used so we can see the cumulative ranges of each animal without having to return)
- -- Loop through each animal to show the developer the cumuative ranges of each animal
- for _, animal in pairs(animalChildren) do
- previousCumulativeEntryForFullRange = cumulativeEntryForFullRange -- store previous cumulative entry in order to show the range.
- cumulativeEntryForFullRange += 1/ animal.Chance.Value / totalEntries
- -- Calculate the cumulative entry for the current animal by dividing 1 by its chance value and then dividing it by the total entries
- -- This effectively determines the range of probabilities for each animal, ensuring that the sum of all probabilities equals 1
- print(animal.Name.."'s cumulative entry range is: ",tostring(previousCumulativeEntryForFullRange).." to "..tostring(cumulativeEntryForFullRange)) -- print the ranges for the developer to see.
- end
- print("Random number generated is: "..tostring(randomEntry)) -- print the random number for the developer to see.
- for _, animal in pairs(animalChildren) do
- previousCumulativeEntry = cumulativeEntry -- store previous cumulative entry in order to show the range.
- cumulativeEntry += 1/ animal.Chance.Value / totalEntries
- -- Calculate the cumulative entry for the current animal by dividing 1 by its chance value and then dividing it by the total entries
- -- This effectively determines the range of probabilities for each animal, ensuring that the sum of all probabilities equals 1
- print(animal.Name.."'s cumulative entry range is: ",tostring(previousCumulativeEntry).." to "..tostring(cumulativeEntry)) -- print range
- if randomEntry <= cumulativeEntry then -- if the random number falls inside the range then we select the animal that has that range
- print("Random number found in: ",animal.Name,"'s range")-- notify developer of selection
- return animal.Name -- return the animal's name to be used to find said animal in later code
- end
- end
- end
- function SpinHandler.Spin(player) -- take the player as an argument in order to access many of the players values/gui
- local db = true -- debounce in order to prevent unwanted double creation of animals or any other unwanted issue.
- local selectedAnimal = SpinHandler.ChooseAnimal(Animals) -- input the animals folder inside the choose animal function
- print(selectedAnimal.." was chosen in spin") -- immediately print the selected animals name, makes it easier to debug later code.
- local playerGui = player.PlayerGui -- get the player's gui
- local spinFrame = playerGui.SpinUI.SpinFrame -- get the spin frame
- local loopCount = 0 -- initialize loop count (used for visually spinning)
- 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)
- local skipConnection -- initialize a connection variable for the skip button of the spin frame
- local equipConnection -- initialiE a connection variable for the equip button of the spin frame
- playerGui.SpinUI.SpinButton.Visible = false -- turn the spin button invisible
- spinFrame.Visible = true -- turn the spin frame visible
- 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)
- spinFrame.AnimalUnlocked.Text = ""
- spinFrame.SkipButton.Visible = false -- make sure the skip button isnt visible
- spinFrame.EquipButton.Visible = false -- make sure the skip button isnt visible
- for i, v in pairs(playerGui.AnimalInventory:GetChildren()) do -- turn off all other gui's
- if v:IsA("GuiBase") then
- if v.Visible == true then
- v.Visible = false
- end
- end
- end
- repeat -- reapeat loop for spinning animation
- loopCount += 1 -- increment loop count
- task.wait(waitTime) -- initialize a wait in order to prevent instant text change.
- local randomAnimal = math.round(math.random(1, #Animals:GetChildren())) -- select a random animal from the animals folder
- spinFrame.AnimalUnlocked.Text = Animals:GetChildren()[randomAnimal].Name -- chance animal unlicked text to the animals name
- spinFrame.AnimalUnlocked.TextColor3 = Animals:GetChildren()[randomAnimal].Highlight.OutlineColor -- change the animal unlocked text color to the highlight color of the animal
- spinFrame.AnimalChance.Text = "" -- again making sure the chance text is not visible (an empty string)
- remotes.SpinningForAnimal:FireClient(player) -- fire a remote on the client to play a "tick" sound for each rotation
- -- Gradually increase wait time to slow down the loop if we have passed the half way point of the loop
- if loopCount >= 15 then
- waitTime = waitTime + 0.05
- end
- until loopCount >= 30 -- stop loop once loopCount has reached or surpassed 30.
- spinFrame.AnimalUnlocked.Text = selectedAnimal -- show the animal unlocked text as the selected animal
- spinFrame.AnimalUnlocked.TextColor3 = Animals[selectedAnimal].Highlight.OutlineColor -- change the color to the highlight color of the animal
- local chance = Animals:FindFirstChild(selectedAnimal).Chance.Value -- get the chance value of the animal
- 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
- spinFrame.AnimalChance.Text = "1 in "..tostring(0) -- chance the animal chance text to the text seen.
- else -- if chance isnt at mad cow's level then simply put the animal chance text to "1 in "..the animals chance
- spinFrame.AnimalChance.Text = "1 in "..tostring(chance)
- end
- spinFrame.AnimalChance.TextColor3 = Animals[selectedAnimal].Highlight.OutlineColor -- chance the animal chance text color to the animals highlight color
- spinFrame.SkipButton.Visible = true -- turn the skip equip buttons visible
- spinFrame.EquipButton.Visible = true
- skipConnection = spinFrame.SkipButton.MouseButton1Click:Once(function() -- initialize a "Once" connection to the click event of the skip button
- print("skip button pressed") -- debug print statements for the developer
- if not player.PlayerAnimals:FindFirstChild(selectedAnimal) and db then -- check if the player's "player animals" already has the selected animal
- db = false -- put db to false to prevent cloning
- -- since the player passed the if statment that means they must not have the animal selected
- local animalString = Instance.new("StringValue",player.PlayerAnimals) -- create a string value and add it to the player's player animals
- animalString.Name = selectedAnimal -- set the string name to the selected animal and also set its value to the selected animal
- animalString.Value = selectedAnimal
- task.delay(1,function() -- delay resetting the debounce
- db = true
- end)
- end
- task.wait() -- small wait before turning the skip and equip buttons invisible
- spinFrame.SkipButton.Visible = false
- spinFrame.EquipButton.Visible = false
- spinFrame.Visible = false -- turn the spin frame invisible
- task.wait(0.5) -- wait half a second before turning the spin button visible
- playerGui.SpinUI.SpinButton.Visible = true
- for i, v in pairs(playerGui.AnimalInventory:GetChildren()) do -- turn all the guis that arent the specific guis named from invisble to visible
- if v:IsA("GuiBase") then
- if v.Visible == false and v.Name ~= "AnimalsFrame" or v.Name ~= "UnequipButton" then
- v.Visible = true
- end
- 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
- v.Visible = false
- end
- end
- end
- skipConnection:Disconnect() -- disconnect the connection
- skipConnection = nil -- set connection to nil
- selectedAnimal = nil -- set selected animal to nil to prevent unwanted behaviour
- print("skip button disconnected selected animal disconnected") -- print statement for the developer
- return -- immediately return out of the function
- end)
- equipConnection = spinFrame.EquipButton.MouseButton1Click:Once(function() -- initialize a 'Once connection for the equip button click event'
- print("equip button pressed") -- print statement for the developer
- 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
- if not player.PlayerAnimals:FindFirstChild(selectedAnimal) and db then -- if the selected animal was not already in the player's player animals
- db = false -- set db to false to prevent cloning
- -- if the animal wasnt found that indeed means the player does not have it already.
- local animalString = Instance.new("StringValue",player.PlayerAnimals) -- create string value and parent it to the player's player animals
- animalString.Name = selectedAnimal -- set the string's name and value to the selected animal
- animalString.Value = selectedAnimal
- animalHandler.EquipAnimal(player,player.Character,selectedAnimal) -- equip the animal using the animals handler module
- task.delay(1,function() -- delay resetting the debounce
- db = true
- end)
- elseif db then
- db = false -- set db to false to prevent double equips
- animalHandler.EquipAnimal(player,player.Character,selectedAnimal) -- equip animal because they already have it
- task.delay(1,function()-- delay resetting the debounce
- db = true
- end)
- end
- print(spinFrame:GetChildren()," spin frame children, from equip button") -- debung print statement for the developer
- task.wait() -- small wait
- spinFrame.Visible = false -- turn spin frame invisible
- task.wait(0.5) -- wait half a second before turning the spin button visible
- playerGui.SpinUI.SpinButton.Visible = true
- equipConnection:Disconnect() -- disconnect both the skip and equip connections
- skipConnection:Disconnect()
- equipConnection = nil -- set connections to nil and set selected animal to nil
- skipConnection = nil
- selectedAnimal = nil
- print("equip button disconnected selected animal disconnected") -- print statement for the develop
- return -- return out of function
- end)
- end
- return SpinHandler -- return spin handler
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement