How to save a BoolValue in a DataStore System - lua

I'm trying to make a system that saves a value so that if the player has that value then he gains the powers of that particular item but I'm not able to make that happen. There are no errors in the output and the powers are not forwarded to the player, how can I make the Data store system work to save this boolean value? There are probably errors in my code. The code is below.
local DataStoreService = game:GetService("DataStoreService") -- pegar serviço
local DataStore = DataStoreService:GetDataStore("PlrData") -- setar as informações onde serão guardadas
local FrutaSalva = DataStoreService:GetDataStore("Fruit")
local ReplicatedS = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService") -- runservice
game.Players.PlayerAdded:Connect(function(Plr) -- se o player entrar
local data = Instance.new("Folder", Plr) -- criar pasta no player que guarda valores
data.Name = "Data"
local exp = Instance.new("IntValue", data) -- valor
exp.Name = "Exp"
exp.Value = 1
local levels = Instance.new("IntValue", data)-- valor
levels.Name = "Level"
levels.Value = 1
local Points = Instance.new("IntValue", data)
Points.Name = "Points"
Points.Value = 3
local expneed = Instance.new("IntValue", data)-- valor
expneed.Name = "ExpNeeded"
expneed.Value = 100
local strenght = Instance.new("IntValue", data)-- valor
strenght.Value = 1
strenght.Name = "Strenght"
local Health = Instance.new("IntValue", data)-- valor
Health.Value = 100
Health.Name = "Health"
local char = Plr.Character or Plr.CharacterAdded:Wait()
local charhealth = char.Humanoid.Health
local DevilFruit = Instance.new("IntValue", data)-- valor
DevilFruit.Value = 1
DevilFruit.Name = "DevilFruit"
local PlayerId = Plr.UserId -- id do jogador
local PlayerData = DataStore:GetAsync(PlayerId) -- informações do jogador são pegas e se estiverem salvas então
local FruitGet = FrutaSalva:GetAsync("PlayerId")
if PlayerData then
strenght.Value = PlayerData["Strenght"] -- coloca o valor correspondente da informação salva na informação atual
Health.Value = PlayerData["Health"] -- coloca o valor correspondente da informação salva na informação atual
DevilFruit.Value = PlayerData["DevilFruit"] -- coloca o valor correspondente da informação salva na informação atual
exp.Value = PlayerData["Exp"] -- coloca o valor correspondente da informação salva na informação atual
levels.Value = PlayerData["Level"] -- coloca o valor correspondente da informação salva na informação atual
expneed.Value = PlayerData["ExpNeeded"]
Points.Value = PlayerData["Points"]-- coloca o valor correspondente da informação salva na informação atual
end
end)
local function tab(Player) -- cria uma table com o nome de status do player
local PlrStats = {} -- table criada
for _, v in pairs(Player.Data:GetChildren()) do -- procura os valores na pasta Data no player
PlrStats[v.Name] = v.Value -- pega os valores e os coloca na table de acordo com o valor e o nome
end
return PlrStats -- não sei (pesquisar)
end
game.Players.PlayerRemoving:Connect(function(Plr) -- conecta a função ao player sair
local PlrStats = tab(Plr) -- PlrStats é a função enviada com o parametro de player
local Sucess, Result = pcall(function() -- função safe
local PlrId = Plr.UserId -- player id
DataStore:SetAsync(PlrId, PlrStats) -- seta os valores da table plrstats no id do player para salvar
end)
if not Sucess then -- erro no save alerta
print(Result)
warn("Erro no save (Preocupante)")
end
end)
game:BindToClose(function() -- qunado o jogo fechar pelo servidor salva as info
for _, Player in pairs(game.Players:GetPlayers()) do
task.wait()
local PlrStats = tab(Player) -- PlrStats é a função enviada com o parametro de player
local Sucess, Result = pcall(function() -- função safe
local PlrId = Player.UserId -- player id
DataStore:SetAsync(PlrId, PlrStats) -- seta os valores da table plrstats no id do player para salvar
end)
if not Sucess then -- erro no save alerta
print(Result)
warn("Erro no save (Preocupante)")
end
end
end)
game.Players.PlayerAdded:Connect(function(Player) -- se o xp for maior que o necessário ou igual
task.wait(0.1) -- então um nivel aumenta e o xp necessário é maior
local Level = Player.Data.Level
local Exp = Player.Data.Exp
local ExpNeed = Player.Data.ExpNeeded
local Points = Player.Data.Points
local Strenght = Player.Data.Strenght
local Health = Player.Data.Health
local DevilFruit = Player.Data:WaitForChild("DevilFruit", 12)
local Char = Player.CharacterAdded:Wait()
local Hum = Char:WaitForChild("Humanoid")
Hum.MaxHealth = Hum.MaxHealth + Health.Value
task.wait(.1)
Hum.Health = Hum.Health + Health.Value
RunService.Heartbeat:Connect(function()
if Exp.Value == 0 and ExpNeed.Value == 0 then
Exp.Value = 1
ExpNeed.Value = 100
end
if Points.Value > 300 then
Points.Value = 300
end
if Exp.Value >= ExpNeed.Value then
Exp.Value = Exp.Value - ExpNeed.Value
Level.Value += 1
ExpNeed.Value *= 1.13
Points.Value += 3
end
if Strenght.Value == 0 or DevilFruit.Value == 0 or Health.Value == 0 then
Strenght.Value = 1
DevilFruit.Value = 1
Health.Value = 1
end
if Strenght.Value > 100 or DevilFruit.Value > 100 then
Strenght.Value = 100
DevilFruit.Value = 100
end
if Health.Value > 1000 then
Health.Value = 1000
end
end)
RunService.Heartbeat:Connect(function()
if Level.Value >= 100 then
Level.Value = 100
end
end)
end)
ReplicatedS:WaitForChild("Frutas"):WaitForChild("Fruta").OnServerEvent:Connect(function(Player, Fruit)
if FrutaSalva == true then
if Player.GomuGomu.Value == true then
ReplicatedS:WaitForChild("Frutas"):WaitForChild("Poderes"):WaitForChild("GomuPowers").Parent = Player.Character
end
end
end)
game.Players.PlayerRemoving:Connect(function(Player)
local success, result = pcall(function()
FrutaSalva:SetAsync(Player.UserId, true)
end)
if success then
FrutaSalva:SetAsync(Player.UserId, true)
else print(result)
end
end)

Related

How to create a DataStore?

local DataStoreService = game:GetService('DataStoreService')
local playerData = DataStoreService:GetDataStore('PlayerData')
-- Erstellt Leaderboard
local function onPlayerJoin(player)
local leaderstats = Instance.new('Folder')
leaderstats.Name = 'leaderstats'
leaderstats.Parent = player
local clicks = Instance.new('IntValue')
clicks.Name = 'Clicks'
clicks.Value = 0
clicks.Parent = leaderstats
local rebirths = Instance.new('IntValue')
rebirths.Name = 'Rebirths'
rebirths.Value = 0
rebirths.Parent = leaderstats
-- Wenn ein Nutzer verlassen hat das die daten gespeichert wurden
local playerUserId = 'Player_'..player.UserId
local data = playerData:GetAsync(playerUserId)
if data then
clicks.Value = data['Clicks']
rebirths.Value = data['Rebirths']
else -- Wenn user das erste mal joint das value 0 ist
clicks.Value = 0
rebirths.Value = 0
end
end
local function create_table(player)
local player_stats = {}
for _, stat in pairs(player.leaderstats:GetChildren()) do
player_stats[stat.Name] = stat.Value
end
return player_stats
end
local function onPlayerExit(player)
local player_stats = create_table(player)
local success, err = pcall(function ()
local playerUserId = 'Player_'..player.UserId
playerData:SetAsync(playerUserId, player_stats)
end)
if not success then
warn('Could not save data')
end
end
game.Players.PlayerAdded:Connect(onPlayerJoin)
game.Players.PlayerRemoving:Connect(onPlayerExit)
I tried to make a DataStore that stores the values of the leaderboard into a data that returns everytime if i rejoin. But it doesnt work and idk why. Im kinda new into lua programming but u guys can help me :D thanks.

Points returning to the player

I was making a game, with a status system that includes some points to give away. I used roblox's DataStore service, but I'm having a problem with my game. After a player spends his points, distributing them in the stats he wants, after he leaves the game and re-enters those same points back to him with the same value, this can cause a point doubling glitch, which makes the unfair game, which I don't want. I think there is an error in my code, what can I do to fix it?
Code below:
local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("PlrData")
local RunService = game:GetService("RunService")
game.Players.PlayerAdded:Connect(function(Plr)
local data = Instance.new("Folder", Plr)
data.Name = "Data"
local exp = Instance.new("IntValue", data)
exp.Name = "Exp"
exp.Value = 1
local levels = Instance.new("IntValue", data)
levels.Name = "Level"
levels.Value = 1
local Points = Instance.new("IntValue", data)
Points.Name = "Points"
Points.Value = 3
local expneed = Instance.new("IntValue", data)
expneed.Name = "ExpNeeded"
expneed.Value = 100
local strenght = Instance.new("IntValue", data)
strenght.Value = 1
strenght.Name = "Strenght"
local Health = Instance.new("IntValue", data)
Health.Value = 100
Health.Name = "Health"
local char = Plr.Character or Plr.CharacterAdded:Wait()
local charhealth = char.Humanoid.Health
local DF = Instance.new("IntValue", data)
DF.Value = 1
DF.Name = "DF"
local PlayerId = Plr.UserId
local PlayerData = DataStore:GetAsync(PlayerId)
if PlayerData then
strenght.Value = PlayerData["Strenght"]
Health.Value = PlayerData["Health"]
DF.Value = PlayerData["DF"]
exp.Value = PlayerData["Exp"]
levels.Value = PlayerData["Level"]
expneed.Value = PlayerData["ExpNeeded"]
Points.Value = PlayerData["Points"]
charhealth = PlayerData["Health"]
end
end)
local function tab(Player)
local PlrStats = {}
for _, v in pairs(Player.Data:GetChildren()) do
PlrStats[v.Name] = v.Value
end
return PlrStats
end
game.Players.PlayerRemoving:Connect(function(Plr)
local PlrStats = tab(Plr)
local Sucess, Result = pcall(function()
local PlrId = Plr.UserId
DataStore:SetAsync(PlrId, PlrStats)
end)
if not Sucess then
print(Result)
warn("Error save")
end
end)
game:BindToClose(function()
for _, Player in pairs(game.Players:GetPlayers()) do
task.wait()
local PlrStats = tab(Player)
local Sucess, Result = pcall(function()
local PlrId = Player.UserId
DataStore:SetAsync(PlrId, PlrStats)
end)
if not Sucess then
print(Result)
warn("Error")
end
end
end)
game.Players.PlayerAdded:Connect(function(Player)
task.wait(0.1)
local Level = Player.Data.Level
local Exp = Player.Data.Exp
local ExpNeed = Player.Data.ExpNeeded
local Points = Player.Data.Points
local Strenght = Player.Data.Strenght
local Health = Player.Data.Health
local DF = Player.Data:WaitForChild("DF")
RunService.Heartbeat:Connect(function()
if Exp.Value == 0 and ExpNeed.Value == 0 then
Exp.Value = 1
ExpNeed.Value = 100
end
if Points.Value > 300 then
Points.Value = 300
end
if Exp.Value >= ExpNeed.Value then
Exp.Value = Exp.Value - ExpNeed.Value
Level.Value += 1
ExpNeed.Value *= 1.13
Points.Value += 3
end
if Strenght.Value == 0 or DF.Value == 0 or Health.Value == 0 then
Strenght.Value = 1
DF.Value = 1
Health.Value = 1
end
if Strenght.Value > 100 or DF.Value > 100 then
Strenght.Value = 100
DF.Value = 100
end
if Health.Value > 1000 then
Health.Value = 1000
end
end)
RunService.Heartbeat:Connect(function()
if Level.Value >= 100 then
Level.Value = 100
end
end)
end)

Problems with score function in corona sdk (lua)

Good evening,
I have a problem with the score function in my videogame.
I need it for a university exam.
in practice, in the video game the little man has to "save" the animals from the burning forest and jump over the sotacles.
when he goes on an animal the score increases, only that the score doubles and, after he has saved the first animal, the other elements invert the typical direction of travel. it almost seems that the little man pushes him in the opposite direction.
What could be the problem?
here the codes with the score function and the generation of the elements
local function updateScore()
scoreDisplay=display.newText(sceneGroup, "Score:", display.contentCenterX, display.contentCenterY-150, native.systemFont, 30)
scoreDisplay:setFillColor(black)
score = score + 1
scoreDisplay.text="Score:" .. score
end
-- Funzione per la creazione degli ostacoli e animali
local function createElement( event )
-- In base al numero cambia l'elemento caricato
local obstacle = math.random(4)
-- Ostacolo fiamma
if(obstacle == 1) then
element = display.newImageRect(sceneGroup,"img/flame.png", 80, 80);
element.myName = "obstacle"
-- L'elemento generato viene posizionato in modo casuale, ma entro i margini dello schermo
element.x = 1080
element.y = 100;
-- Aggiungiamo un corpo statico alla fiamma
physics.addBody(element, "dynamic", { bounce=0.0 })
-- Ostacolo roccia
elseif(obstacle == 2) then
element = display.newImageRect(sceneGroup,"img/rock.png", 70, 50);
element.myName = "obstacle"
element.x = 1080
element.y = 100;
-- Aggiungiamo un corpo statico alla roccia
physics.addBody(element, "dynamic", { bounce=0.0 })
-- Animale
elseif (obstacle == 3) then
element = display.newImageRect(sceneGroup,"img/rabbit.png", 80, 80);
element.myName = "animal"
element.x = 1080
element.y = 100;
-- Aggiungiamo un corpo statico al coniglio
physics.addBody(element, "dynamic", { bounce=0.0 })
elseif (obstacle==4) then
element = display.newImageRect(sceneGroup,"img/koala.png", 200, 120);
element.myName = "animal"
element.x = 1080
element.y = 100;
-- Aggiungiamo un corpo statico al koala
physics.addBody(element, "dynamic", { bounce=0.0 })
end
table.insert(elements, element)
return element
end
-- funzione che elimina gli ostacoli non attivi e ne crea di nuovi
-- e viene chiamato ogni secondo
and here the collision function
--funzione che implementa le collisioni
local function onCollision(self,event)
if (event.phase=="began") then
-- self rappresenta l'oggetto badGuy
-- event.other rappresenta l'altro ogetto
-- coinvolto nell'urto
if event.other.myName=="ground" and event.contact.isTouching==true then
self.action="run"
end
if ((event.other.myName=="animal" and self.myName=="boy") or (event.other.myName=="animal" and self.myName=="boy")) then
if(event.contact.isTouching==true) then
updateScore()
end
event.contact.isTouching=false
transition.fadeOut( event.other, { time = 30 } )
print("score")
end
end
--se la collisione avviene tra boy, la fiamma e la roccia
if ((event.other.myName=="obstacle" and self.myName=="boy") or (event.other.myName=="boy" and self.myName=="obstacle")) then
physics.pause()
display.remove(boy)
boy = nil
--rimozione suono in sottofondo
audio.stop(playSound)
playSound=nil
--liberazione memoria
audio.dispose(playSound)
--rimozione listener dello sfondo
Runtime:removeEventListener("enterFrame", bosco1)
Runtime:removeEventListener("enterFrame", bosco2)
--rimozione listener terreno
Runtime:removeEventListener("enterFrame", terreno1)
Runtime:removeEventListener("enterFrame", terreno2)
--rimozione listener collisioni
Runtime:removeEventListener("enterFrame", onCollision)
--Rimozione listener per il tap di boy
Runtime:removeEventListener("tap", boyJump)
--stoppamente generazione nuovi elementi
timer.cancel(gameLoopTimer)
composer.gotoScene("restart",{ time=800, effect="crossFade" } )
end
end
who can help me? thanks!

Lua / corona sdk physics.addBody()

When my ball hits but 30 targets 30 new returns except I have an error message lua:76: physics.addBody() cannot be called when the world is locked and in the middle of number crunching, such as during a collision event why ?
function CreeNiveau()
print("Crée le Niveau 1 ")
local lig,col ,x,y
local largeurColonne = (display.actualContentWidth/(5+1))
x = display.screenOriginX + largeurColonne
y = display.screenOriginY + 100
-- si une cible et toucher la Remove et donne des point
local function onToucheCible(self, event)
if event.phase == "began" then
audio.play(sonBump)
self:removeSelf()
AjouteScore(25)
nbCible = nbCible - 1
print("Nombre de cible restent", nbCible)
if nbCible == 0 then
Recible()
end
end
end
for lig = 1,6 do
for col = 1, 5 do
local cible = display.newCircle(x,y, 8)
-- couleur des cible
cible:setFillColor(1,math.random(),math.random())
physics.addBody( cible, "static", { density = 1, friction = 0.3, bounce = 0.6, radius = 8})
cible.collision = onToucheCible
cible:addEventListener("collision")
globaleview:insert(cible)
x = x + largeurColonne
end
y = y + 50
x = display.screenOriginX + largeurColonne
end
You probably use physics functions/APIs in collision listener. Use timer.performWithDelay to delay execution of Recible function:
local function onToucheCible( self, event )
if event.phase == "began" then
audio.play( sonBump )
self:removeSelf()
AjouteScore( 25 )
nbCible = nbCible - 1
print("Nombre de cible restent", nbCible)
if nbCible == 0 then
timer.performWithDelay( 50, Recible )
end
end
end
Read more:
physics.addBody() cannot be called
physics.addBody cannot be called when the world is locked and in the middle of number crunching such as during a collision event

Lua - Error Attempt to perform arithmetic on field '?' -- This occurs at the end of the for loop

I'm developing a program for the Ti-nspire CX CAS calculator and at the time of execution it indicates an error on line 52, this is presented at the end of the for loop in the "area" function.
Sorry for my English.
local coX = {0,2,2,0}
local coY = {0,0,2,0}
local xmax = 2
local ymax = 2
-- Matriz de coordenadas para función "on.paint(gc)"
function conCoor(x,y)
local nx = x
for i=1, #x do
table.insert(nx,i*2,y[i])
end
return nx
end
-- Valor absoluto
function math.abs(valor)
if valor < 0 then
valor = valor*(-1)
end
return valor
end
-- Inercia del polígono respecto el eje X
function inerciex(x,y)
local E = 0
local z =0
for i = 1, #x-1 do
E = (x[i+1]-x[i])*(y[i+1]+y[i])*((y[i+1])^2+(y[i])^2)
z = E + z
end
return math.abs(z/12)
end
-- Inercia del polígono respecto el eje Y
function inerciey(x,y)
local E = 0
local z =0
for i = 1, #x-1 do
E = (y[i+1]-y[i])*(x[i+1]+x[i])*((x[i+1])^2+(x[i])^2)
z = E + z
end
return math.abs(z/12)
end
-- Área del poligono
function area(x,y)
local A = 0
local z = 0
for i = 1, #x-1 do
A = (y[i]*x[i+1]-x[i]*y[i+1])
z = A + z
end -- Line 52, the line in question
return math.abs(z/2)
end
-- Centro de masa del polígono (eje x)
function centroix(x,y)
local Ac = area(x,y)
local z = 0
local cx = 0
for i = 1, #x-1 do
cx = (x[i]+x[i+1])*(x[i]*y[i+1]-x[i+1]*y[i])
z = cx + z
end
return z/(6*Ac)
end
-- Centro de masa del polígono (eje y)
function centroiy(x,y)
local Ac = area(x,y)
local z = 0
local cx = 0
for i = 1, #x-1 do
cx = (y[i]+y[i+1])*(x[i]*y[i+1]-x[i+1]*y[i])
z = cx + z
end
return z/(6*Ac)
end
-- Escala de figura
function escala(xmax,ymax)
local sc = 0
if xmax > ymax then
sc = 81/xmax
else
sc = 81/ymax
end
return math.floor(sc)
end
-- Coordenadas del origen en pantalla
function oriDispX(x,y,xmax,ymax)
return math.floor(212 + (-1)*centroix(x,y)*escala(xmax,ymax))
end
function oriDispY(x,y,xmax,ymax)
return math.floor(105 + (-1)*centroiy(x,y)*escala(xmax,ymax))
end
-- Cambio de coordenadas real
function coorCamb(x,y,xmax,ymax)
-- Escalado de coordenadas
local escx = x
local escy = y
local orix = oriDispX(escx,escy,xmax,ymax)
local oriy = oriDispY(escx,escy,xmax,ymax)
for i = 1, #escx do
escx[i] = math.floor(escx[i]*escala(xmax,ymax))
escy[i] = math.floor(escy[i]*escala(xmax,ymax))
end
-- Cambio de coordenadas
for i = 1, #escx do
escx[i] = escx[i] + orix
escy[i] = escy[i] + oriy
end
return conCoor(escx,escy)
end
function on.paint(gc)
local ox = oriDispX(coX,coY,xmax,ymax)
local oy = oriDispY(coX,coY,xmax,ymax)
local c = coorCamb(coX,coY,xmax,ymax)
gc:drawPolyLine(c)
gc:drawLine(ox-3,oy,ox+3,oy)
gc:drawLine(ox,oy-3,ox,oy+3)
gc:fillArc(ox-1,oy-1,2,2,0,360)
gc:fillArc(212-1,105-1,2,2,0,360)
gc:drawString(tostring(area(coX,coY)),10,10)
platform.window:invalidate()
end
More specifically, the error occurs here:
function area(x,y)
local A = 0
local z = 0
for i = 1, #x-1 do
A = (y[i]*x[i+1]-x[i]*y[i+1])
z = A + z
end -- Line 52, the line in question
return math.abs(z/2)
end
Your code assumes both X and Y arrays are of equal size (because you use i index for both X and Y array), or at least Y never smaller than X. i index, however, runs from 1 to the size of X array which will be invalid for Y array of smaller size.
So, if the Y array is smaller than the X array, you get that error. And, here's the proof:
function area(x,y)
local A = 0
local z = 0
for i = 1, #x-1 do
A = (y[i]*x[i+1]-x[i]*y[i+1])
z = A + z
end
return math.abs(z/2)
end
print(area({1,2,3},{4,5,6})) -- OK
print(area({1,2,3},{4,5})) -- ERROR
The solution was to initialize the variables and tables at the beginning of the whole script and then call the new values ​​using "var.recall" inside the on.paint function.

Resources