Expected table. got nil error? - lua

In the following code
for k, smoke in pairs(self.smokes) do
smoke.time = smoke.time - dt
if smoke.time <= 0 then
table.remove( self.smokes, k )
end
end
It's telling me that self.smokes is a nil value, although later in the code I declare
function ent:Smoke()
table.insert( self.smokes, {time = 3, x = self.x, y = self.y} )
end
Anyone know my error? Thanks guys!

Because the function ent:Smoke is run later in the code.
Place it up at the top and it will work.

Perhaps you want this:
function ent:Smoke()
self.smokes = {time = 3, x = self.x, y = self.y}
end
And you would need to change the other code too:
if self.smokes then
self.smokes.time = self.smokes.time - dt
if self.smoke.time <= 0 then
self.smokes = nil
end
end
The function table.insert() is for inserting into array type tables.

Related

Computercraft program printing new line instead of updating previous line

I increment y (the y index of the monitor) by one each time I print a line to advance the y value (basically a newline). I'm running into an issue however, when I have done mon_1.setCursorPos(x, y+1) it updates the previous line as it should, however when I do y = y+1 mon_1.setCursorPos(x, y) it prints a new line without updating the previous line. Any suggestions?
Here's the full code
--Define some colors
color_fuel = 16
color_ok = 2243
color_error = 224455
color_blank = 0
color_active = 2240
--Tables
reactors={}
max_energy={}
produced={}
percent_capacity={}
--Globals
x = 1
y = 1
i = 0
--Lamps
lamp_1 = peripheral.wrap("colorful_lamp_0")
lamp_2 = peripheral.wrap("colorful_lamp_1")
lamp_3 = peripheral.wrap("colorful_lamp_2")
--Monitors
mon_1 = peripheral.wrap("monitor_3")
--Cap banks
cap_1 = peripheral.wrap("capacitor_bank_2")
--Helper functions
function flash_fuel_lamp()
lamp_2.setLampColor(color_blank)
sleep(0.01)
lamp_2.setLampColor(color_error)
for i = 10,1,-1 do
lamp_1.setLampColor(color_fuel)
sleep(1)
lamp_1.setLampColor(color_blank)
sleep(1)
end
lamp_1.setLampColor(color_fuel)
end
function clear_lamps()
lamp_1.setLampColor(color_blank)
lamp_2.setLampColor(color_blank)
lamp_3.setLampColor(color_blank)
end
--Boot Sequence
--Set lamps to black and clear screen
clear_lamps()
mon_1.clear()
--Turn on the reactors and set the status light to green
for k,v in pairs(peripheral.getNames()) do
if(string.find(v, "BigReactors")) then
reactors[i] = peripheral.wrap(v)
i = i + 1
else
--print("Other Peripheral Detected")
end
end
for k,v in pairs(reactors) do
v.setActive(true)
end
lamp_2.setLampColor(color_ok)
lamp_3.setLampColor(color_active)
--Main loop
for key,value in pairs(max_energy) do
mon_1.setCursorPos(x, y)
mon_1.write("Reactor " .. key .. " Max Energy: " .. value)
y = y + 1
end
while true do
--Check the fuel level
if(redstone.getAnalogInput("bottom") == 0) then
lamp_3.setLampColor(color_blank)
for k,v in pairs(reactors) do
v.setActive(false)
end
flash_fuel_lamp()
end
for k,v in pairs(reactors) do
if(v.getActive() == false) then
lamp_3.setLampColor(color_blank)
end
--Calculate the energies
max_energy[k] = v.getEnergyStored()
produced[k] = v.getEnergyProducedLastTick()
percent_capacity[k] = (max_energy[k] / produced[k]) * 100
end
--[[max_energy = reactor.getEnergyStored()
energy_produced = reactor.getEnergyProducedLastTick()
percent_capacity = (max_energy / energy_produced) * 100]]
max_energy_cap = cap_1.getMaxEnergyStored()
energy_stored = cap_1.getEnergyStored()
percent_capacity_cap = (energy_stored / max_energy_cap) * 100
y=y+1
mon_1.setCursorPos(x, y)
for key,value in pairs(percent_capacity) do
for k,v in pairs(reactors) do
mon_1.write("Reactor " .. k .. " Percent Capacity: " .. value)
y=y+1
mon_1.setCursorPos(x, y)
mon_1.write("Capacitor output per tick: " .. cap_1.getAverageOutputPerTick())
y=y+1
mon_1.setCursorPos(x, y)
mon_1.write("Capacitor input per tick: " .. cap_1.getAverageInputPerTick())
y=y+1
mon_1.setCursorPos(x, y)
end
end
sleep(0.01)
end```
So I think that you might be forgetting that when you do mon_1.setCursorPos(x, y+1) you're not incrementing the y variable, you're only passing a higher value to the called function, while with y = y+1 mon_1.setCursorPos(x, y) you are incrementing y.
This explains why the previous line is not being updated when incrementing y, since the nested for-loops at the bottom of your code use that y variable as well.

Having problems with TIC-80

heyo! i'm trying to do a simple TIC-80 (basically lüa) script, but i'm getting an error.
error started appearing after i added the lastfaced() function. honestly idk what i did wrong.
here's the code:
--width and height vars
w=240
h=136
-- Last faced var
lf='r'
--Player X and Y, W, H, ID vars
p = {
id=0,
x=w/2,
y=h/2,
w=16,
h=16,
draw = function()
spr(p.id, p.x, p.y, 1, 1)
end
}
--movement function here
function lastfaced()
if btn(2) then
lf='l'
elseif btn(3) then
lf='r'
elseif lf="l" then
p.id=4
elseif lf="r" then
p.id=0
end
end
function TIC()
cls(12)
move()
p.draw()
lastfaced()
end
and here's the error:
[string "..."]:49: 'then' expected near '='
can anyone help?
Ehm, when you want to compare you must use == for it to work, one = will not work...
function lastfaced()
if btn(2) then
lf='l'
elseif btn(3) then
lf='r'
elseif lf="l" then
p.id==4
elseif lf=="r" then
p.id=0
end
end

Lua Acessing table values within nested table

I'm trying to test certain variables on a grid made out of nested tables. However no matter what I try it wont give me the values stored within the variables only the data type or a nil value
y = {}
for _y = 0,16 do
for _x = 0,16 do
x = {}
x.x = _x
x.y = _y
x.v = flr(rnd(2))
if x.x < 1 or x.x > 14 then
x.v = 3
end
if x.v == 0 then
x.v = "."
elseif x.v ==1 then
x.v = ","
else
x.v = "0"
end
add(y,x)
end
end
I've tried accessing the value using
print(t[1][3])
But this only prints back a nil value, how would I code this to show whats stored within the value within these two tables?
You have the nesting as follows:
y = {x_1, x_2, x_3, ...}
where, each of x_i is of the form:
x = {
x = p,
y = q,
v = r
}
so, you will have the indexing for each x element as y[i], and each y[i] contains 3 attributes:
print(y[1].x)
will give you x_1.x
You want to create a 2-dimensional table, but only create a 1-dimensional one.
Fix your code to look somewhat like this
y = {}
for _y=1,16 do
y[_y] = {}
for _x=1,16 do
y[_y][_x]= "your data"
end
end

Why won't __add work?

So I am trying to learn about metatables in lua, so i decided to follow some tutorials. I was trying out the __add part of metatables. But for some reason i kept on getting an error (attempt to perform arithmetic on field (nil)
aTable = {}
--Assign the values for the normal table
for x = 1, 10 do
aTable[x] = x
end
-- metatable
mt = {__add = function(table1, table2)
sumTable = {}
for i = 0, #table1 do
sumTable[i] = table1[i] + table2[i]
end
return sumTable
end}
setmetatable(aTable, mt)
newTable = {}
newTable = aTable + aTable
for x = 1, #newTable do
print(newTable[x])
end
At this point i am confused.Help would be appreciated
In the __add-function it should be:
for i = 1, #table1 do
since you didn't set table[0] initially, but started at index 1 (which is indeed recommended for lua-pseudoarrays, many operations rely on it)
#Ctx is correct that the problem is that differing indices in the array initialization and adding functions. But the best way to fix it is to modify your __add function to handle 'holes' in the arrays passed, by checking for nil entries in them.
for i = 0, #table1 do
if (table1[i] and table2[i]) then
sumTable[i] = table1[i] + table2[i]
end
end
Another thing that's missing: You don't set the same metatable on the result, which means that while things like aTable+aTable, aTable+aTable+aTable etc. will work, aTable+aTable+(aTable+aTable) will fail.
Corrected and cleaned version:
-- metatable
mt = {
__add = function( table1, table2 )
sumTable = {}
for i = 1, #table1 do
sumTable[i] = table1[i] + table2[i]
end
return setmetatable( sumTable, mt )
end,
}
aTable = setmetatable( {}, mt )
--Assign the values for the normal table
for x = 1, 10 do aTable[x] = x end
newTable = aTable + aTable
for x = 1, #newTable do print( newTable[x] ) end
-- and a test for what would have failed:
yetAnotherTable = newTable + newTable
for x = 1, #yetAnotherTable do print( yetAnotherTable[x] ) end

Love2D Lua framework - Converting an unorganised rendering table into a map structure

I'm turning a 2D rendered map which is unorganised into a string table, EG from:
"Render = {{Image,50,60,2}}"
Where Image is the image (I'm using Love2D Lua framework)
50 is the X axis
60 is the Y axis
2 is the Image ID (This is what will be in the actual table.)
But there's like 100 of these, all unorganised and stuff, and I need to oragnise them into a structured map.
Here's the odd bit: When I morph it into an organised string.. It.. Kinda rotates the table on a 90* angle anticlockwise.
Saying I want the result of
{
{7,6,5},
{6,5,4},
}
I would get:
{
{5,4},
{6,5},
{7,6},
}
Obviously no error since it technically works, just rotates wrongly. Here's the relevant code:
function OrganiseRenderIntoMap()
MapString = ""
Map2 = {}
MaxSoFarX = 0
MaxSoFarY = 0
for _,v in pairs(Render) do
if v[2] > MaxSoFarX then
MaxSoFarX = v[2]
elseif v[3] > MaxSoFarY then
MaxSoFarY = v[3]
end
end
for currx = 0, MaxSoFarX, 32 do
Map2[currx] = {}
MapString = MapString.."{"
for curry = 0, MaxSoFarY, 32 do
MapString = MapString..GetRenderPos(currx,curry)..","
Map2[currx][curry] = GetRenderPos(currx,curry)
end
MapString = MapString.."},\n"
end
return MapString
end
function GetRenderPos(locx,locy)
for _,v in pairs(Render) do
if v[2] == locx and v[3] == locy then
return v[4]
end
end
end
Give a look at my LÖVE tile tutorial. Section 1d-Strings speaks about how to handle the "switched x and y" problem.

Resources