Reputation: 4561
I have programmed a 'punishbox' (to punish a player for rulebreaking) for my Crysis Wars server mod but for some reason I keep getting this error:
[Warning] [Lua Error] scripts/functions.lua:340: attempt to perform arithmetic on global 'tme' (a nil value)
But the thing is, tme
is actually a number value between 0 and 15. The below code basically sets up the 'punishbox' and checks if it's still valid for the player or not. As you can see, tme
is actually a value (if it was not, the code would not run at all). Am I doing something wrong here?
As this is a specific situation, I can't find that much on the internet. tme
is referenced from time
, which is forwarded to the function by a chat command and is definitely a number.
Also, is there any simpler way of doing this?
Code:
function XPunishPlayer(Name, time, reason)
if (time > 5) then
System.LogAlways("[SYSTEM] Punished by administrator: "..Name:GetName().."");
end
if (not Msg) then
local tme = math.floor(time*60);
Msg = true;
XMessageChatToPlayer(Name, "[!punish] You were punished for "..time.." minutes: "..reason.."");
g_gameRules.game:RenamePlayer(Name.id, "[PUNISH]"..Name:GetName().."");
XMessageChatToPlayer(Name, "[!punish] You can use !pm to dispute this punishment.");
g_gameRules:KillPlayer(Name);
end
Script.SetTimer( 1000,function()
local tme = tme+1;
XPunishPlayer(Name, time, reason);
Name.actor:SetNanoSuitEnergy(0);
local punish = math.floor(timeleft-1);
g_gameRules.onClient:ClStepWorking(g_gameRules.game:GetChannelId(Name.id), tme);
if (tme == math.floor(time*60)) then
g_gameRules.onClient:ClStepWorking(g_gameRules.game:GetChannelId(Name.id), false);
XMessageChatToPlayer(Name, "[!punish] Released from the punishbox.");
XMessageInfoToAll("Unpunished "..Name:GetName()..", was punished for "..time.." minutes: "..reason.." (Server Administration)");
return;
end
end);
end
Upvotes: 3
Views: 1142
Reputation: 10512
Your tme
is defined in an if block, in Lua every block creates its own closure, and so the value of tme
is local to that block.
You can either make it a global variable by simply removing the local
keyword (this is usually not a good idea) or define it before the block like this:
function XPunishPlayer(Name, time, reason)
if (time > 5) then
System.LogAlways("[SYSTEM] Punished by administrator: "..Name:GetName().."");
end
local tme;
if (not Msg) then
tme = math.floor(time*60);
[...]
end
Script.SetTimer( 1000,function()
tme = tme-1;
[...]
end);
end
I am also quite sure the second local tme
inside your SetTimer
would have given you another headache...
Upvotes: 2