Dude, awesome work! I’m kinda late, but I’m a combat / attack scripter, and I was looking to learn new things. This post is amazing man, thank you for this.
2 Likes
Hello, I need help for a similar system but with different boxes that have a certain cost and when you buy them I put the roulette and then it gives you a random item. I would like someone to help me. I don’t have to pay but I would appreciate the help (I am a designer and builder that’s why I don’t know how to program)
But what has to go in wich script? I have no idea
Late Response but I tried this and it cuts off after the first 5 boxes. I modified some of the code to match what my game should be like.
LocalScript:
-- << SERVICES >>
local players = game:GetService("Players")
local rs = game:GetService("ReplicatedStorage")
local contentProvider = game:GetService("ContentProvider")
local tweenService = game:GetService("TweenService")
local runService = game:GetService("RunService")
-- << VARIABLES >>
local player = players.LocalPlayer
local gui = player.PlayerGui.Main
local spinnerMain = gui.SpinFrame
local crates = spinnerMain.Crates
local holder = crates.Holder
local template = crates.Template
local templateX = template.AbsoluteSize.X
local crateGapX = 10
local crateTotalGapX = templateX + crateGapX
local line = spinnerMain.Line
local contents = require(rs.SpinningModule)
local itemTypes = contents:GetItems()
local spin = rs:FindFirstChild("Spin")
local spinDeb = true
local assetsToLoad = {}
local direction
local spinButton = script.Parent:WaitForChild("Spin")
local spins = player:WaitForChild("leaderstats"):WaitForChild("Spins")
-- << SETUP >>
--Setup crates
template.Visible = true
for i = 1, contents.Boxes do
local pos = i-1
local crate = template:Clone()
crate.Name = "Crate"..i
if string.lower(string.sub(contents.SpinDirection,1,1)) == "r" then
direction = "Right"
crate.Position = crate.Position + UDim2.new(0, crateTotalGapX*pos, 0, 0)
else
direction = "Left"
crate.Position = crate.Position + UDim2.new(1, -(templateX+10)-(crateTotalGapX*pos), 0, 0)
end
crate.Parent = holder
end
template.Visible = false
--Preload items
coroutine.wrap(function()
for rarityPos, group in pairs(itemTypes) do
for i, item in pairs(group.Items) do
local decal = Instance.new("Decal")
decal.Texture = "rbxassetid://"..item.ImageId
table.insert(assetsToLoad, decal)
end
end
contentProvider:PreloadAsync(assetsToLoad)
for i,v in pairs(assetsToLoad) do
if v:IsA("Decal") then
v:Destroy()
end
end
end)()
function SpinFunction(spinDetails)
--Variables
local items = spinDetails.Items
local winningCrateId = spinDetails.WinningCrateId
local winningItem = spinDetails.WinningItem
local cratesRemaining = {}
holder.Position = UDim2.new(0,0,0,0)
for i, item in pairs (items) do
local crate = holder["Crate"..i]
local rarityGroup = itemTypes[item.GroupIndex].Rarity
crate.About.ItemName.Text = item.Name
crate.About.ItemRarity.Text = rarityGroup.Name
crate.ImageLabel.Image = "rbxassetid://"..item.ImageId
crate.About.BackgroundColor3 = rarityGroup.Color
if i <= winningCrateId+1 then
table.insert(cratesRemaining, crate)
end
end
--Calculate distance to travel
local endCrate = holder["Crate"..winningCrateId]
local startX = crates.AbsolutePosition.X + crates.AbsoluteSize.X/2
local endX = endCrate.AbsolutePosition.X + endCrate.AbsoluteSize.X/2
local xDifference = endX - startX
local yDifference = endCrate.AbsolutePosition.Y - holder.AbsolutePosition.Y
local templateXBound = templateX/2.5
local randomDepth = 1000
local landOffset = 0--math.random(-templateXBound+randomDepth, templateXBound+randomDepth)-randomDepth
local landPosition = holder.Position - UDim2.new(0, xDifference, 0, 0) --startCrate.Position - endCrate.Position
--Setup tween
local tweenTime = math.random(7, 8)
local tweenInfo = TweenInfo.new(tweenTime, contents.SpinEasingStyle, contents.SpinEasingDirection)
local tween = tweenService:Create(holder, tweenInfo, {Position = landPosition})
--[[local tweenTime = math.random(7,8)
local tweenInfo = TweenInfo.new(tweenTime, contents.SpinEasingStyle, contents.SpinEasingDirection)
local tween = tweenService:Create(holder, tweenInfo, {Position = landPosition})]]
--SpinClick sounds
local lineX = line.AbsolutePosition.X
coroutine.wrap(function()
repeat runService.RenderStepped:Wait()
local cratesRemainingInt = #cratesRemaining
local nextCrate = cratesRemaining[1]
if nextCrate then
local nextCrateX = nextCrate.AbsolutePosition.X
if (direction == "Right" and nextCrateX <= lineX) or (direction == "Left" and nextCrateX >= lineX) then
table.remove(cratesRemaining, 1)
local sound = nextCrate.SpinClick
sound:Play()
end
end
until cratesRemainingInt <= 1
end)()
spinnerMain.Visible = true
--Run tween
tween:Play()
tween.Completed:Wait()
--Display reward
local winningItem = items[winningCrateId]
local rewardColor
local rarityGroup = itemTypes[winningItem.GroupIndex].Rarity
end
spinButton.MouseButton1Click:Connect(function()
if spinDeb then
spinDeb = false
if spins.Value > 0 then
spinButton.Visible = false
local details, errMsg = spin:InvokeServer()
if details then
SpinFunction(details)
else
warn(errMsg)
end
else
spinButton.Text = "Not enough spins!"
task.wait(1)
spinButton.Text = "SPIN"
end
spinButton.Visible = true
spinDeb = true
end
end)
ModuleScript:
local spinModule = {}
spinModule["Boxes"] = 45
spinModule["SpinEasingStyle"] = Enum.EasingStyle.Quint;
spinModule["SpinEasingDirection"] = Enum.EasingDirection.Out;
spinModule["SpinDirection"] = "Right";
function spinModule:GetItems()
local itemTypes = {
{
Rarity = {Name = "Common", Chance = 0.5, Color = Color3.fromRGB(0,85,127)};
Items = {
{Name = "Nothing", ImageId = 2419083546};
}
},
{
Rarity = {Name = "Mythical" ,Chance = 0.5, Color = Color3.fromRGB(170,0,225)};
Items = {
{Name = "Secret", ImageId = 2987584671};
}
};
};
for groupIndex, group in pairs(itemTypes) do
for i, item in pairs(group.Items) do
item.GroupIndex = groupIndex
end
end
return itemTypes
end
return spinModule
ServerScript:
--// SERVICES \\--
local rp = game:GetService("ReplicatedStorage")
--// INSTANCES \\--
local spinFunc = rp:WaitForChild("Spin")
local contents = require(rp.SpinningModule)
local chanceDepth = 100000000
local itemTypes = contents:GetItems()
--//[SCRIPT]\\--
function spinFunc.OnServerInvoke(player)
if player.leaderstats.Spins.Value < 1 then
return
end
local modifiedItemTypes = contents:GetItems()
local items = {}
for i = 1, contents.Boxes do
local cumulativeChance = 0
local rarityGroup
local randomChance = math.random(1,chanceDepth)/chanceDepth
for groupIndex, group in pairs(modifiedItemTypes) do
local chance = group.Rarity.Chance
cumulativeChance = cumulativeChance + chance
if randomChance <= cumulativeChance and #group.Items > 0 then
rarityGroup = group
break
end
end
local newItemsGroup = rarityGroup.Items
local newItemPos = math.random(1,#newItemsGroup)
local newItem = newItemsGroup[newItemPos]
table.insert(items, newItem)
end
player.leaderstats.Spins.Value -= 1
local winningCrateId = contents.Boxes - 5
local winningItem = items[winningCrateId]
print(items, winningCrateId, winningItem)
return {
["Items"] = items;
["WinningCrateId"] = winningCrateId;
["WinningItem"] = winningItem;
}
end