i am trying to make a battlepass system that rewards you every level up the issue is, when the player finishes a certain quest he levels up twice insted of one time i will leave the video down below
battlepass.wmv (5.3 MB)
that is what happens when the player finishes 1 quest
server script:
local dss = game:GetService("DataStoreService")
local ds = dss:GetDataStore("testing1.0.5")
local missions = {
"Play for 10 minutes",
"Walk 20000 meters",
"Kill a total of 15000 beasts",
}
local tiers = 3
--Data saving function
function saveData(plr)
local tier = plr.Tier.Value
local lastMission = plr.LastMission.Value
local currentMissions = {}
for i, mission in pairs(plr.Missions:GetChildren()) do
currentMissions[mission.Name] = mission.Value
if mission:FindFirstChild("Completed") then
currentMissions[mission.Name] = -1
end
end
local bpData = {["CurrentMissions"] = currentMissions, ["LastMission"] = lastMission, ["Tier"] = tier}
ds:SetAsync(plr.UserId .. "Battlepass", bpData)
end
game.Players.PlayerAdded:Connect(function(plr)
--Character related missions
plr.CharacterAdded:Connect(function(char)
local missionsFolder = plr:WaitForChild("Missions")
for i, mission in pairs(missionsFolder:GetChildren()) do
if not mission:FindFirstChild("Completed") then
if mission.Name == "Walk 20000 meters" then --Walk for 500 studs
spawn(function()
local lastPosition = char.HumanoidRootPart.Position * Vector3.new(1, 0, 1)
while wait() do
if not mission:FindFirstChild("Completed") then
local currentPos = char.HumanoidRootPart.Position * Vector3.new(1, 0, 1)
mission.Value += (lastPosition - currentPos).Magnitude
lastPosition = currentPos
if mission.Value >= 20000 then
local complete = Instance.new("StringValue", mission)
complete.Name = "Completed"
plr.Tier.Value += 1
break
end
end
end
end)
elseif mission.Name == "Kill a total of 15000 beasts" then --Stand still for 10 seconds
spawn(function()
while wait() do
if plr.leaderstats.Kills.Value >= 15000 then
mission.Value = 15000
break
end
mission.Value = plr.leaderstats.Kills.Value
end
if mission.Value >= 15000 then
local complete = Instance.new("StringValue", mission)
complete.Name = "Completed"
plr.Tier.Value += 1
end
end)
end
end
end
end)
--Battlepass data
local bpData = ds:GetAsync(plr.UserId .. "Battlepass") or {["CurrentMissions"] = nil, ["LastMission"] = 0, ["Tier"] = 0}
local currentMissions = bpData["CurrentMissions"]
local tier = bpData["Tier"]
local lastMission = bpData["LastMission"]
if os.time() - lastMission >= 24*60*60 then--24*60*60 then --Reset missions after 24 hours
lastMission = os.time()
currentMissions = {}
for i = 1, math.clamp(tiers - tier, 0, 3) do --Make sure the user doesn't complete more tiers than there are
local mission
repeat
mission = missions[math.random(#missions)]
until not currentMissions[mission]
currentMissions[mission] = 0
end
end
local lastValue = Instance.new("IntValue", plr)
lastValue.Name = "LastMission"
lastValue.Value = lastMission
local tierValue = Instance.new("IntValue", plr) --Current tier
tierValue.Name = "Tier"
tierValue.Value = tier
tierValue:GetPropertyChangedSignal("Value"):Connect(function() --Reward for tiers
if tierValue.Value == 1 then
local clone = game.ServerStorage:WaitForChild("Tools"):WaitForChild("Beast Head"):Clone()
clone.Parent = plr.Backpack
end
end)
local missionsFolder = Instance.new("Folder", plr) --Missions stored in here
missionsFolder.Name = "Missions"
for currentMission, progress in pairs(currentMissions) do
local missionValue = Instance.new("NumberValue", missionsFolder)
missionValue.Name = currentMission
missionValue.Value = progress
if progress >= 0 then
--Play for 10 minutes
if currentMission == "Play for 10 minutes" then
spawn(function()
local timeJoined = os.time()
while wait() do
local timePlayed = progress + math.floor((os.time() - timeJoined)/60)
if plr and timePlayed < 10 then
plr.Missions["Play for 10 minutes"].Value = timePlayed
else
plr.Missions["Play for 10 minutes"].Value = 10
break
end
end
if plr then
tierValue += 1
local complete = Instance.new("StringValue", missionValue)
complete.Name = "Completed"
end
end)
end
else
local complete = Instance.new("StringValue", missionValue)
complete.Name = "Completed"
missionValue.Value = string.gsub(currentMission, "%D", "")
end
end
end)
--Save data using function
game.Players.PlayerRemoving:Connect(saveData)
game:BindToClose(function()
for i, plr in pairs(game.Players:GetPlayers()) do
saveData(plr)
end
end)
local script:
--Open and close GUI
local open = false
script.Parent.Position = UDim2.new(0.319, 0,0.975, 0)
script.Parent.MouseButton1Click:Connect(function()
open = not open
if open then
script.Parent:TweenPosition(UDim2.new(0.319, 0,0.975, 0), "InOut", "Quint", 0.5)
else
script.Parent:TweenPosition(UDim2.new(0.319, 0,0.686, 0), "InOut", "Quint", 0.5)
end
end)
--Tiers UI
local maxTiers = 3
local tier = game.Players.LocalPlayer:WaitForChild("Tier")
script.Parent.BattlepassFrame.TierNumber.Text = "LEVEL: " .. tier.Value
for i = 1, maxTiers do --Set up scrolling frame with tier rewards
local newTier = script.RewardFrame:Clone()
newTier.Name = i
newTier.TierNumber.Text = "LEVEL: " .. i
if i == 1 then
newTier.RewardName.Text = "BEAST HEAD"
newTier.RewardImage.Image = "rbxassetid://90177088"
elseif i == 2 then
newTier.RewardName.Text = "AK-47"
newTier.RewardImage.Image = "rbxassetid://11127408662"
elseif i == 3 then
newTier.RewardName.Text = "REVOLVER"
newTier.RewardImage.Image = "rbxassetid://7587568389"
end
if i <= tier.Value then
newTier.NotClaimedImage:Destroy()
end
newTier.Parent = script.Parent.BattlepassFrame.RewardsScroller
script.Parent.BattlepassFrame.RewardsScroller.CanvasSize = UDim2.new(0, script.Parent.BattlepassFrame.RewardsScroller.UIListLayout.AbsoluteContentSize.X, 0, 0)
end
tier:GetPropertyChangedSignal("Value"):Connect(function() --Update UI when tier changes
script.Parent.BattlepassFrame.TierNumber.Text = "LEVEL: " .. tier.Value
for i, tierReward in pairs(script.Parent.BattlepassFrame.RewardsScroller:GetChildren()) do
if tonumber(tierReward.Name) and tonumber(tierReward.Name) <= tier.Value then
if tierReward:FindFirstChild("NotClaimedImage") then tierReward.NotClaimedImage:Destroy() end
end
end
end)
--Missions UI
local missionsFolder = game.Players.LocalPlayer:WaitForChild("Missions")
for i, mission in pairs(missionsFolder:GetChildren()) do
local missionAmount = string.gsub(mission.Name, "%D", "")
local missionFrame = script.Parent.BattlepassFrame.MissionsFrame["Mission" .. i]
missionFrame.Task.Text = mission.Name
missionFrame.ProgressBarBG.Progress.Text = math.floor(mission.Value) .. "/" .. missionAmount
missionFrame.ProgressBarBG.Bar.Size = UDim2.new(math.clamp(mission.Value / missionAmount, 0, 1), 0, 1, 0)
mission:GetPropertyChangedSignal("Value"):Connect(function()
missionFrame.ProgressBarBG.Progress.Text = math.floor(mission.Value) .. "/" .. missionAmount
missionFrame.ProgressBarBG.Bar.Size = UDim2.new(math.clamp(mission.Value / missionAmount, 0, 1), 0, 1, 0)
end)
end
if #missionsFolder:GetChildren() < 1 then --Make sure the right amount of missions is shown
script.Parent.BattlepassFrame.MissionsFrame:ClearAllChildren()
elseif #missionsFolder:GetChildren() < 2 then
script.Parent.BattlepassFrame.MissionsFrame.Mission2:Destroy()
script.Parent.BattlepassFrame.MissionsFrame.Mission3:Destroy()
elseif #missionsFolder:GetChildren() < 3 then
script.Parent.BattlepassFrame.MissionsFrame.Mission3:Destroy()
end