在Lua中,一个变量意外地为nil。

我为我的 Crysis Wars 服务器模组编写了一个“惩罚盒子”(用来惩罚违规玩家),但出现了错误。

[警告] [Lua 错误] scripts/functions.lua:340: 尝试对全局变量 'tme' 进行算术运算,而 'tme' 是一个空值

但事实上,tme 是一个 0 到 15 的数字值。下面的代码主要设置 'punishbox' 并检查它是否对玩家仍然有效。你可以看到,tme 其实是一个值(如果不是,代码就会根本不执行)。我在这里做错了什么吗?

由于这是一个具体的情况,我在互联网上找不到太多信息。tme 是从 time 中引用的,它通过聊天命令转发到函数,并且肯定是一个数字。

此外,有没有更简单的方法?

代码:

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
点赞
用户1244588
用户1244588

您的 tme 是在 if 块中定义的,在 Lua 中,每个块都会创建自己的闭包,因此 tme 的值对该块是本地的。

您可以通过简单地删除 local 关键字将其变为全局变量(这通常不是一个好主意)或者在块之前定义它,就像这样:

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

我也很确定您在 SetTimer 中第二个 local tme 会给您带来另一个头疼...

2013-05-28 09:23:00