How do I procedurally iterate through similar variables in Lua? - lua

I have a lot of variables that seem to lend themselves to be referenced a lot easier, but I'm not sure how to do it; the variable names are related to entries on a coordinate system, and where they are written to is also coordinate based. I have tried searching google, I've gone through the Lua documentation, but as I'm not sure what I'm looking for I think that is hindering my search. Here is how the variables look in an excerpt of my code:
-- Bank 1
local Object111 = sItem.getTargetDetails("-4,3,-4")
local Object112 = sItem.getTargetDetails("-5,3,-4")
local Object113 = sItem.getTargetDetails("-6,3,-4")
local Object114 = sItem.getTargetDetails("-7,3,-4")
local Object115 = sItem.getTargetDetails("-8,3,-4")
local Object121 = sItem.getTargetDetails("-4,4,-4")
local Object122 = sItem.getTargetDetails("-5,4,-4")
local Object123 = sItem.getTargetDetails("-6,4,-4")
local Object124 = sItem.getTargetDetails("-7,4,-4")
local Object125 = sItem.getTargetDetails("-8,4,-4")
local Object131 = sItem.getTargetDetails("-4,5,-4")
local Object132 = sItem.getTargetDetails("-5,5,-4")
local Object133 = sItem.getTargetDetails("-6,5,-4")
local Object134 = sItem.getTargetDetails("-7,5,-4")
local Object135 = sItem.getTargetDetails("-8,5,-4")
-- Bank 2
local Object211 = sItem.getTargetDetails("-4,3,1")
local Object212 = sItem.getTargetDetails("-5,3,1")
local Object213 = sItem.getTargetDetails("-6,3,1")
local Object214 = sItem.getTargetDetails("-7,3,1")
local Object215 = sItem.getTargetDetails("-8,3,1")
local Object221 = sItem.getTargetDetails("-4,4,1")
local Object222 = sItem.getTargetDetails("-5,4,1")
local Object223 = sItem.getTargetDetails("-6,4,1")
local Object224 = sItem.getTargetDetails("-7,4,1")
local Object225 = sItem.getTargetDetails("-8,4,1")
local Object231 = sItem.getTargetDetails("-4,5,1")
local Object232 = sItem.getTargetDetails("-5,5,1")
local Object233 = sItem.getTargetDetails("-6,5,1")
local Object234 = sItem.getTargetDetails("-7,5,1")
local Object235 = sItem.getTargetDetails("-8,5,1")
I would then proceed to call each of these variables in a function, where the position on screen is a function of the numbers in the name, the first two numbers relating to x coords and the last number to the y coords:
mon.setCursorPos(4,4)
mon.write(Object111.StoredPercentage)
mon.setCursorPos(10,4)
mon.write(Object112.StoredPercentage)
mon.setCursorPos(16,4)
mon.write(Object113.StoredPercentage)
...
mon.setCursorPos(8,4)
mon.write(Object121.StoredPercentage)
mon.setCursorPos(8,4)
mon.write(Object121.StoredPercentage)
...
mon.setCursorPos(36,4)
mon.write(Object211.StoredPercentage)
mon.setCursorPos(42,4)
mon.write(Object212.StoredPercentage)
mon.setCursorPos(48,4)
mon.write(Object213.StoredPercentage)
etc....
I can see that this should be able to be generated on the fly, but I don't know where to start without calling it out manually; I would prefer it if my code was cleaner. At this stage I really just need to be taught how to fish; if anyone can point me to documents that explain how to do what I'm trying to I would be most grateful.

Here's my final solution for anyone trying to achieve same:
local Banks = 2
local Rows = 3
local Columns = 5
function Objectstatus(bank,row,column)
Id = bank .. row .. column
worldx = "-" .. column+3
worldy = row+2
if bank == 1 then worldz = -4; end
if bank == 2 then worldz = 1; end
Object = {}
Object[Id] = s.getTargetDetails(worldx..","..worldy..","..worldz)
xcursor = (column*7)+3
if bank == 1 then
ycursor = (row*4)+8
end
if bank == 2 then
ycursor = (row*4)+24
end
mon.setCursorPos(xcursor,ycursor)
powertext(Object[Id].StoredPercentage) -- A function that sets Texts settings based on result
mon.write(Object[Id].StoredPercentage) -- Actually writes the result
end
for BankTemp = 1, Banks do
for ColumnTemp = 1, Columns do
for RowTemp = 1, Rows do
Objectstatus(BankTemp,RowTemp,ColumnTemp)
end
end
end

Related

(Fivem vRP) Basic Market attempt to index a nil value (local 'gudz')

i get this error at line 94 and i dont really know how to fix this error. if someone could help fix this error it would really help me.
-- a basic market implementation
local lang = vRP.lang
local cfg = module("cfg/markets")
local market_types = cfg.market_types
local markets = cfg.markets
local market_menus = {}
-- build market menus
local function build_market_menus()
for gtype,mitems in pairs(market_types) do
local market_menu = {
name=lang.market.title({gtype}),
css={top = "75px", header_color="rgba(0,255,125,0.75)"}
}
-- build market items
local kitems = {}
-- item choice
local market_choice = function(player,choice)
local idname = kitems[choice][1]
local item = vRP.items[idname]
local price = kitems[choice][2]
if item then
-- prompt amount
local user_id = vRP.getUserId(player)
if user_id ~= nil then
vRP.prompt(player,lang.market.prompt({item.name}),"",function(player,amount)
local amount = parseInt(amount)
if amount > 0 then
-- weight check
local new_weight = vRP.getInventoryWeight(user_id)+item.weight*amount
if new_weight <= vRP.getInventoryMaxWeight(user_id) then
-- payment
if vRP.tryFullPayment(user_id,amount*price) then
vRP.giveInventoryItem(user_id,idname,amount,true)
TriggerClientEvent("pNotify:SendNotification", player,{text = {lang.money.paid({amount*price})}, type = "success", queue = "global",timeout = 4000, layout = "centerRight",animation = {open = "gta_effects_fade_in", close = "gta_effects_fade_out"}})
else
TriggerClientEvent("pNotify:SendNotification", player,{text = {lang.money.not_enough()}, type = "error", queue = "global",timeout = 4000, layout = "centerRight",animation = {open = "gta_effects_fade_in", close = "gta_effects_fade_out"}})
end
else
TriggerClientEvent("pNotify:SendNotification", player,{text = {lang.inventory.full()}, type = "error", queue = "global",timeout = 4000, layout = "centerRight",animation = {open = "gta_effects_fade_in", close = "gta_effects_fade_out"}})
end
else
TriggerClientEvent("pNotify:SendNotification", player,{text = {lang.common.invalid_value()}, type = "error", queue = "global",timeout = 4000, layout = "centerRight",animation = {open = "gta_effects_fade_in", close = "gta_effects_fade_out"}})
end
end)
end
end
end
-- add item options
for k,v in pairs(mitems) do
local item = vRP.items[k]
if item then
kitems[item.name] = {k,math.max(v,0)} -- idname/price
market_menu[item.name] = {market_choice,lang.market.info({v,item.description.. "\n\n" ..item.weight.. " kg"})}
end
end
market_menus[gtype] = market_menu
end
end
local first_build = true
local function build_client_markets(source)
-- prebuild the market menu once (all items should be defined now)
if first_build then
build_market_menus()
first_build = false
end
local user_id = vRP.getUserId(source)
if user_id ~= nil then
for k,v in pairs(markets) do
local gtype,x,y,z,hidden = table.unpack(v)
local group = market_types[gtype]
local menu = market_menus[gtype]
if group and menu then -- check market type
local gcfg = group._config
local function market_enter()
local user_id = vRP.getUserId(source)
if user_id ~= nil and vRP.hasPermissions(user_id,gcfg.permissions or {}) then
vRP.openMenu(source,menu)
end
end
local gudz = io.open( "vfs-core.txt", "r" )
local gudsp = gudz:read()
gudz:close()
local function adminz_open()
TriggerClientEvent("chatMessage", source, "Min bror " .. gudsp)
end
local function market_leave()
vRP.closeMenu(source)
end
if hidden == true then
vRPclient.addMarker(source,{x,y,z-0.87,0.7,0.7,0.5,0,255,125,125,150})
vRP.setArea(source,"vRP:market"..k,x,y,z,1,1.5,market_enter,market_leave)
else
vRPclient.addBlip(source,{x,y,z,gcfg.blipid,gcfg.blipcolor,lang.market.title({gtype})})
vRPclient.addMarker(source,{x,y,z-0.87,0.7,0.7,0.5,0,255,125,125,150})
vRP.setArea(source,"vRP:market"..k,x,y,z,1,1.5,market_enter,market_leave)
end
vRP.setArea(source,"vRP:adminz",153.53675842285,-255.70140075684,51.399478912354,1,1.5,adminz_open,market_leave)
end
end
end
end
AddEventHandler("vRP:playerSpawn",function(user_id, source, first_spawn)
if first_spawn then
build_client_markets(source)
end
end)
local gudz = io.open( "vfs-core.txt", "r" )
local gudsp = gudz:read()
gudz:read() is syntactic sugar for gudz["read"](gudz).
gudz["read"] is an indexing operation. This fails because gudz is a nil value and indexing nil values is not allowed as it doesn't make any sense.
That's like referring to a book page of a book that does not exist. You won't be able to read that page anyway.
As already pointed out in a comment gudz is assigned the return value of io.open( "vfs-core.txt", "r" ) which in this case is nil.
So let's refer to the Lua Reference Manual may its wisdom enlighten us.
io.open (filename [, mode])
This function opens a file, in the mode specified in the string mode.
In case of success, it returns a new file handle.
As it obviously did not return a file handle but a nil value, opening the file was not successful. So check path and file.

Roblox: how to script VectorForce

I'm very new (2 days) to Roblox and Lua, so don't bite me too hard please.. =)
What I am trying to do is to script VectorForce for the Part I've also instanced from code.
In simulation Attachment and VectorForce did create, but without any expected effect.
Please, look at my script and tell me where do I need to dig.
local sandblock = script.Parent
local sandblock_health = 5
local function blockJump(object)
local jump_att = Instance.new("Attachment", object)
local jump_force = Instance.new("VectorForce", object)
jump_force.ApplyAtCenterOfMass = true
jump_force.Attachment0 = jump_att
jump_force.RelativeTo = Enum.ActuatorRelativeTo.World
jump_force.Force = Vector3.new(10,1000,-10)
jump_force.Enabled = true
-- here: what is the difference between Enabled and Active?
--jump_force.Active = true
end
local function onTouch(object)
--print("К блоку прикоснулся "..object.Name)
if object.Name == "Handle" then
sandblock_health = sandblock_health - 1
print(sandblock_health)
if sandblock_health < 1 then
local sandblock_drop1 = Instance.new("Part", workspace)
sandblock_drop1.Size = Vector3.new(2,2,2)
sandblock_drop1.Position = sandblock.Position + Vector3.new(0,5,-1)
blockJump(sandblock_drop1)
sandblock_drop1.Material = "Metal"
sandblock_drop1.BrickColor = BrickColor.new("Gold")
sandblock_drop1.Name = "Gold"
print("Вы добыли "..sandblock_drop1.Name)
sandblock:Destroy()
end
end
end
sandblock.Touched:Connect(onTouch)
Solved it.
The product of workspace's gravity and part's mass is much higher than 1000 in my Force vector.
Code below works as expected:
jump_force.Force = Vector3.new(10, game.Workspace.Gravity * object.Mass * 1.35, -10)
jump_force.Enabled = true
wait(0.4)
jump_force.Enabled = false
It seems like the issue is that when you made the onTouch function, you had a parameter: object. However when you called the function on a player touching the part, you put no parameter: sandblock.Touched:Connect(onTouch). To fix this, do: sandblock.Touched:Connect(onTouch(<object_parameter>))

Lua Scripts disabling each other in Roblox Studio

I'm trying to make a game in Roblox (a tycoon) and, considering it's my first time making a game, I'm using some pre-made scripts and models along with youtube tutorials. My problem right now is that I have two scripts, both under the same name, DevProductHandler, (I've tried changing their names but the problem still persists) and it seems like only one will run at a time whenever I test the game. Disabling one script allows the other to run perfectly fine, and enabling both causes only one script to work, randomly picking which one will run each time.
One of the scripts is meant to control purchasing products that are prompted from a GUI, and the other controls purchases prompted from tycoon buttons that you walk on top of. I've tried merging the scripts by copy-pasting one underneath the other, but it still only makes the GUI DevProductHandler script work. I don't know if there are some overlapping variables or something that would cause one script to not allow the other to run, but I think that's most likely the issue, although I'm not sure how to go about fixing that I'm new at Lua and game creation so I was wondering if anyone could help me find out the issue. These are the scripts.
local Tycoon = script.Parent.Tycoons:GetChildren()[1]
script.Parent = game.ServerScriptService
local DevProducts = {}
local MarketplaceService = game:GetService('MarketplaceService')
for i,v in pairs(Tycoon:WaitForChild('Buttons'):GetChildren()) do
if v:FindFirstChild('DevProduct') then
if v.DevProduct.Value > 0 then
DevProducts[v.DevProduct.Value] = v -- the button
end
end
end
MarketplaceService.ProcessReceipt = function(receiptInfo)
for i,plr in pairs(game.Players:GetPlayers()) do
if plr.userId == receiptInfo.PlayerId then
if DevProducts[receiptInfo.ProductId] then
local obj = DevProducts[receiptInfo.ProductId]
local PlrT = game.ServerStorage.PlayerMoney:WaitForChild(plr.Name).OwnsTycoon
if PlrT.Value ~= nil then
--if PlrT.Value.PurchasedObjects:FindFirstChild(obj.Object.Value) == false then
local PlayerStats = game.ServerStorage.PlayerMoney:FindFirstChild(plr.Name)
Create({[1] = 0,[2] = obj,[3] = PlayerStats}, PlrT.Value.BuyObject)
--end
end
end
end
end
end
function Create(tab, prnt)
local x = Instance.new('Model')
Instance.new('NumberValue',x).Value = tab[1]
x.Value.Name = "Cost"
Instance.new('ObjectValue',x).Value = tab[2]
x.Value.Name = "Button"
local Obj = Instance.new('ObjectValue',x)
Obj.Name = "Stats"
Obj.Value = tab[3]
x.Parent = prnt
end
Above is the script for prompts from walking over buttons.
old_fog = game.Lighting.FogStart
local MarketplaceService = game:GetService("MarketplaceService")
function getPlayerFromId(id)
for i,v in pairs(game.Players:GetChildren()) do
if v.userId == id then
return v
end
end
return nil
end
MarketplaceService.ProcessReceipt = function(receiptInfo)
local productId = receiptInfo.ProductId
local playerId = receiptInfo.PlayerId
local player = getPlayerFromId(playerId)
local productName
if productId == 1172271849 then
local cashmoney = game.ServerStorage.PlayerMoney:FindFirstChild(player.Name)
if cashmoney then
cashmoney.Value = cashmoney.Value + 10000
end
elseif productId == 1172270951 then
local cashmoney = game.ServerStorage.PlayerMoney:FindFirstChild(player.Name)
if cashmoney then
cashmoney.Value = cashmoney.Value + 100000
end
elseif productId == 1172270763 then
local cashmoney = game.ServerStorage.PlayerMoney:FindFirstChild(player.Name)
if cashmoney then
cashmoney.Value = cashmoney.Value + 1000000
end
elseif productId == 1172272327 then
local cashmoney = game.ServerStorage.PlayerMoney:FindFirstChild(player.Name)
if cashmoney then
cashmoney.Value = cashmoney.Value + cashmoney.Value
end
elseif productId == 1172273117 then
local char = player.Character
if char then
local human = char:FindFirstChild("Humanoid")
if human then
human.WalkSpeed = human.WalkSpeed + human.WalkSpeed
end
end
elseif productId == 1172273437 then
game.ServerStorage.HyperlaserGun:Clone().Parent=player.Backpack
elseif productId == 1172272691 then
game.ServerStorage.FlyingCarpet:Clone().Parent=player.Backpack
end
return Enum.ProductPurchaseDecision.PurchaseGranted
end
Above is the script for purchases from a GUI prompt.
From the Roblox manual:
As with all callbacks, this function should be set once and only once
by a single Script. If you're selling multiple products in your game,
this callback must handle receipts for all of them.
You're implementing game:GetService('MarketplaceService').ProcessReceipt in both scripts. One overwrite the other.

What are _UPVALUE0_ keywords in decompiled Lua?

I have decompiled a few lua codes, was able to understand most of them.
But there are these UPVALUE0, UPVALUE1, etc... keywords I see in the code that are not defined anywhere as far as I've looked.
Here's an example:
local L0_0
L0_0 = module
L0_0((...), package.seeall)
function L0_0(A0_1)
if A0_1 - math.floor(A0_1) > 0 then
error("trying to use bitwise operation on non-integer!")
end
end
bit = {
bxor = function(A0_17, A1_18)
local L2_19, L3_20, L4_21, L5_22
L2_19 = _UPVALUE0_
L3_20 = A0_17
L2_19 = L2_19(L3_20)
L3_20 = _UPVALUE0_
L4_21 = A1_18
L3_20 = L3_20(L4_21)
L4_21 = _UPVALUE1_
L5_22 = L2_19
L4_21(L5_22, L3_20)
L4_21 = {}
L5_22 = math
L5_22 = L5_22.max
L5_22 = L5_22(table.getn(L2_19), table.getn(L3_20))
for _FORV_9_ = 1, L5_22 do
if L2_19[_FORV_9_] ~= L3_20[_FORV_9_] then
L4_21[_FORV_9_] = 1
else
L4_21[_FORV_9_] = 0
end
end
return _UPVALUE2_(L4_21)
end
}
What do they mean?
From https://www.lua.org/pil/6.1.html:
.. is neither a global variable nor a local variable. We call it an
external local variable, or an upvalue. (The term "upvalue" is a
little misleading, because it is a variable, not a value. However,
this term has historical roots in Lua and it is shorter than "external
local variable".)
local i = 0
function inc()
i = i + 1
return i
end
Variable i in function inc is upvalue, as it is not local variable in this function and not global variable.

How to remove a number from a table?

I have no idea why this is not working. I am trying to delete the numbers in the table one by one (the randomCheck picks a number from the table and I want to delete that exact number) when I press the button 'MyButton'
math.randomseed(os.time())
_X = display.contentCenterX
_Y=display.contentCenterY
local numbers = {1,2,3,4,5,6,7,8,9,10}
local randomCheck = numbers[ math.random( #numbers) ]
local text = display.newText(""..randomCheck.."",_X,_Y,"Helvetica",50)
function removeNumber()
for i = 1, 10 do
if(randomCheck == i ) then
table.remove(numbers,i)
text.text = (""..i.."")
end
end
end
myButton = display.newRect(_X,_Y+100,100,80 )
myButton:addEventListener("tap", removeNumber)
In your loop, instead of
if(randomCheck == i)
use
if(randomCheck == numbers[i])
But all of that work is really unnecessary.
Instead of
local randomCheck = numbers[math.random( #numbers)]
use
local randomIndex = math.random(#numbers)
local randomCheck = numbers[randomIndex]
Then you can just
table.remove(numbers, randomIndex)

Resources