bad argument #1 to 'random' (number expected, got nil) - lua

Problem using math.random maybe?
Here's the code:
local combat = createCombatObject()
setCombatParam(combat, COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE)
setCombatParam(combat, COMBAT_PARAM_AGGRESSIVE, false)
function onGetFormulaValues(cid, level, maglevel)
local min = (((level/5)+(maglevel*1) +1))
local max = (((level/5)+(maglevel*2) +3))
return min, max
end
setCombatCallback(combat, CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues")
local condition = createConditionObject(CONDITION_REGENERATION)
setConditionParam(condition, CONDITION_PARAM_SUBID, 1)
setConditionParam(condition, CONDITION_PARAM_BUFF, true)
setConditionParam(condition, CONDITION_PARAM_TICKS, 1 * 60 * 1000)
setConditionParam(condition, CONDITION_PARAM_HEALTHGAIN, math.max(math.random(min, max)))
setConditionParam(condition, CONDITION_PARAM_HEALTHTICKS, 1000)
setCombatCondition(combat, condition)
function onCastSpell(cid, var)
return doCombat(cid, combat, var)
end
Its says the errors is in line 17, which is the math.random one. I have very little knowledge in Lua and this code I got from a forum, that the person posted in 2012, so I can't ask them.

Related

/Lua/ How to do this (idk how to call that lol)

I need to make a trolleybus number, which won't repeat for game. For example, there is a number "101" and there musn't be more "101". How to do that? I have a code, but I know, he won't work and I won't test it lol
function giveNumber()
local number = math.random(100, 199)
local takedNumbers = {}
local i = 0
local massiv = i+1
script.Parent.pered.SurfaceGui.TextLabel.Text = number
script.Parent.zad.SurfaceGui.TextLabel.Text = number
script.Parent.levo.SurfaceGui.TextLabel.Text = number
script.Parent.pravo.SurfaceGui.TextLabel.Text = number
takedNumbers[massiv] = {number}
end
script.Parent.Script:giveNumber() // what I wrote here? idk...
if number == takedNumbers[massiv] then
giveNumber()
end
i didn't test it, because I think it won't work because this code is something bad
I think this will serve your needs.
In the function generateUniqueNumber, the script loops until it found a number that is not yet in the array. (in other words, that it hasn't given out yet)
Once it found that number, it will insert it into the table to remember that it has given it out, and then it will return the number.
Then on the bottom of the script we just give the numbers to the buses :-)
--[[
Goal: Give all buses a unique number
]]
-- Variables
local takenNumbers = {};
-- This function returns a random number in the range [100, 199] that has not been taken yet
function generateUniqueNumber()
local foundNumber = false;
while not foundNumber do
randomNumber = math.random(100, 199);
if not table.find(takenNumbers, randomNumber) then
table.insert(takenNumbers, randomNumber);
return randomNumber;
end
end
end
-- This function sets the number of the bus
script.Parent.pered.SurfaceGui.TextLabel.Text = tostring(generateUniqueNumber());
script.Parent.zad.SurfaceGui.TextLabel.Text = tostring(generateUniqueNumber());
script.Parent.levo.SurfaceGui.TextLabel.Text = tostring(generateUniqueNumber());
script.Parent.pravo.SurfaceGui.TextLabel.Text = tostring(generateUniqueNumber());
2 things:
I didn't test this code as Roblox is not installed on the pc I'm currently on.
Please try formatting your code nicely next time. It greatly improves the readability! For example, you can use this website:
https://codebeautify.org/lua-beautifier
Simpler
Fill a table with free numbers...
local freenumbers = {}
for i = 1, 99 do freenumbers[i] = i + 100 end
...for every new takennumbers use table.remove() on freenumbers
local takennumbers = {}
if #freenumbers > 0 then
takennumbers[#takennumbers + 1] = table.remove(freenumbers, math.random(1, #freenumbers))
end

How can you turn a number like 1k into 1000 in lua?

I am currently working on a game in Roblox studio, and I'm wondering How can you turn a number like 1k into 1000 in lua?
A quick solution would be a lookup table with all postfixes, for example something like this:
local postfixes = {
["n"] = 10^(-6),
["m"] = 10^(-3),
["k"] = 10^3,
["M"] = 10^6,
["G"] = 10^9,
}
local function convert(n)
local postfix = n:sub(-1)
if postfixes[postfix] then
return tonumber(n:sub(1, -2)) * postfixes[postfix]
elseif tonumber(n) then
return tonumber(n)
else
error("invalid postfix")
end
end
print(convert("1k"))
print(convert("23M"))
print(convert("7n"))
print(convert("7x"))
1000.0
23000000.0
7e-06
invalid postfix

WoW Lua error; attempt to call a global(a nil value)

I'm new to Lua and was following the tutorial on https://wowwiki.fandom.com/wiki/AddOn_tutorial but i just cant get it to work; i have copied the code but i get the error message "attempt to call a global 'functionname' (a nil value)" on both the SetMapToCurrentZone() and the GetPlayerMapPosition("player") functions.
This is the entire Lua file;
local zone = nil
local TimeSinceLastUpdate = 0
local function UpdateCoordinates(self, elapsed)
if zone ~= GetRealZoneText() then
zone = GetRealZoneText()
SetMapToCurrentZone()
end
TimeSinceLastUpdate = TimeSinceLastUpdate + elapsed
if TimeSinceLastUpdate > .5 then
TimeSinceLastUpdate = 0
local posX, posY = GetPlayerMapPosition("player");
local x = math.floor(posX * 10000)/100
local y = math.floor(posY*10000)/100
eCoordinatesFontString:SetText("|c98FB98ff("..x..", "..y..")")
end
end
function eCoordinates_OnLoad(self, event,...)
self:RegisterEvent("ADDON_LOADED")
end
function eCoordinates_OnEvent(self, event, ...)
if event == "ADDON_LOADED" and ... == "eCoordinates" then
self:UnregisterEvent("ADDON_LOADED")
eCoordinates:SetSize(100, 50)
eCoordinates:SetPoint("TOP", "Minimap", "BOTTOM", 5, -5)
eCoordinates:SetScript("OnUpdate", UpdateCoordinates)
local coordsFont = eCoordinates:CreateFontString("eCoordinatesFontString", "ARTWORK", "GameFontNormal")
coordsFont:SetPoint("CENTER", "eCoordinates", "CENTER", 0, 0)
coordsFont:Show()
eCoordinates:Show()
end
end
How do i fix it?
These functions have been renamed and moved to a wrapper object in 8.0, to C_Map.GetBestMapForUnit (requiring "player" as parameter to yield the same result) and C_Map.GetPlayerMapPosition respectively.
You can probably expect more functions that are called later to throw the same error, their lines just couldn't be reached before. I can check the whole code example when I'm at a desktop again, but you may simply look up these functions on Wowpedia, especially other map-related functions.
I suggest using Wowpedia over Wowwiki, it's a personal preference/impression, the former seems to receive more constant updates.
(The two seem to be merging again now, after splitting 10 years ago)

Is there a way to make a countdown to a specific date in Lua?

So I am just tinkering with Lua after hearing that it was more versatile than python, so I tried to make a countdown to one year, in the form of DDD:HR:MN:SC. If anyone could give me an example it would be much appreciated!
Following code should exactly do what you want:
local function sleep(s)
local t = os.clock() + s
repeat until os.clock() > t
end
local function getDiff(t)
return os.difftime(t, os.time())
end
local function dispTime(t)
local d = math.floor(t / 86400)
local h = math.floor((t % 86400) / 3600)
local m = math.floor((t % 3600) / 60)
local s = math.floor((t % 60))
return string.format("%d:%02d:%02d:%02d", d, h, m, s)
end
local function countdown(tTbl)
local diff = getDiff(os.time(tTbl))
repeat
print(dispTime(diff))
-- os.execute('echo ' .. dispTime(diff))
sleep(1)
diff = getDiff(os.time(tTbl))
until (diff <= 0)
end
countdown{
day = 24,
month = 12,
year = 2019,
hour = 0,
min = 0,
sec = 0
}
You can use os.date to retreive the current date as a table, then just build the difference by subtracting component-wise like this:
local function print_remaining(target)
local current = os.date("*t")
print(string.format("%i years, %i months and %i days",
target.year-current.year,
target.month-current.month,
target.day-current.day
))
end
local function countdown(target)
while true do
print_remaining(target)
os.execute('sleep 1')
end
end
countdown {year = 2019, month=12, day=25}
If you want it to be cooler, of course you'd have to adjust what components are shown depending on how much time is left.
Inspired by #csaars answer, I changed a few things and ended up with this
local function split(full, step, ...)
if step then
return math.floor(full % step), split(math.floor(full / step), ...)
else
return full
end
end
local function countdown(target)
local s, m, h, d = split(os.difftime(os.time(target), os.time()), 60, 60, 24)
print(string.format("%i days, %i:%i:%i", d, h, m, s))
if os.execute('sleep 1') then
return countdown(target)
end
end
countdown {year = 2019, month=12, day=25}
The plit function is a bit more complex than it needs to be for this example, but I thought it'd be a nice chance to showcase how nicely some things can be expressed with variadic recursive functions in Lua.
Just make sure that the countdown isn't past January 19, 2038. Unix Time won't work past that. Integer Overflow is the problem.
To obtain detailed information about the date, use the function os.date with the string argument "*t". This call returns a table containing information such as minute, day, year, etc.
Using this, you could write a simple function that retrieves the current date and formats it however you prefer. In this example, I went with the yyyy/mm/dd format.
function format_date()
local function tbl = os.date("*t")
local date = string.format("%d/%d/%d", t.year, t.month, t.day)
return date
end
print(format_date())
> 2019/11/19
The function os.time returns the time in seconds since the beginning of the current epoch. This could be another way to produce a countdown timer.
Here is a link to a page about the Lua OS library.

How to initialize table size in lua

What is the most efficient way to convert number to table? Or is it possible to make a table without loops?
local t = 10 -- given number
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} -- result
Update: the t variable is mutable number and I want to for each the value.
t = 3
function foreach(f, t)
for i, v in ipairs(t) do
f(v)
end
end
foreach(print, t)
1
2
3
I need a just the quickest way of new Array(n) in Lua. Or doesn't make any sense?
Maybe you don't know how to answer #Sebastian's question. Here are a few alternatives to get you thinking.
Since your table has only computed elements, you could omit the storage and just perform the calculation on every read access (index operation).
local function newArray(size)
local t = {}
setmetatable(t, {
__index = function (_, i)
return i >= 1 and i <= size and i or nil end})
return t
end
t10 = newArray(10)
for i = 0, 11 do -- ipairs won't work as expected with such a table
print(i, t10[i])
end
t10[2] = "stored values override __index"
print(t10[2])
Of course, you could also replace the table with just an identity function that returns the value, or even just an identity expression. But, maybe you have an unexpressed requirement for a table or you need ipairs to iterate over the sequence.
Speaking of iterators,
local function seq_itor(first, last)
local i = first - 1
return function ()
i = i + 1
if i <= last then return i end
end
end
for i in seq_itor(1, 10) do
print(i)
end
The simplest way to do that would be to define a function:
function newArray(size)
local t = {}
for i = 1, size do
t[i] = i
end
return t
end

Resources