我尝试为 Gmod amd 修复一些旧的 Basewars 脚本,我尝试修复一些东西,但我不知道我在那里缺少什么。基本上它是关于银行脚本的。这家银行最初可以存储 20 亿美元。我想将该存储量扩展到 1 万亿。
所以基本上 Basewars 游戏模式允许玩家拥有高达 10^18 $ = 1 Quintillion 的大量资金。我查看了https://wiki.garrysmod.com/page/Category:number
所以基本上lua使用双精度浮点格式。所以 lua 使用 32 位来存储数字,这意味着数字可以在 -2,147,483,647 到 2,147,483,647 的范围内。
Basewars 游戏模式使用函数来计算 10^18 = 1 Quintillion
function BaseWars.NumberFormat(num)
local t = BaseWars.LANG.Numbers
for i = 1, #t do
local Div = t[i][1]
local Str = t[i][2]
if num >= Div or num <= -Div then
return string.Comma(math.Round(num / Div, 1)) .. " " .. Str
end
end
return string.Comma(math.Round(num, 1))
end
游戏模式正在使用该派系来转换金额。这是 BaseWars.LANG.Numbers:
BaseWars.LANG = {}
BaseWars.LANG.__LANGUAGELOOK = {}
BaseWars.LANG.__LANGUAGELOOK.ENGLISH = {
Numbers = {
[5] = {10^6, "Million"},
[4] = {10^9, "Billion"},
[3] = {10^12, "Trillion"},
[2] = {10^15, "Quadtillion"},
[1] = {10^18, "Quintillion"},
},
CURFORMER = CURRENCY .. "%s",
CURRENCY = CURRENCY,
}
所以我知道这个函数确实有效,但我不明白,变量 num 怎么可能那么高!为什么我知道它的作用?
这是我尝试过的,它操纵了高达 1 万亿的容量,但此时我操纵了另一个问题,我不知道我做错了什么!
这是原始的:
ENT.Capacity = 2000000000 --Max money in the bank. Can be bugs if it is more than 2000000000 (2 bil)
ENT.Money = 0
ENT.MaxPaper = 0
local Clamp = math.Clamp
function ENT:GSAT(slot, name, min, max)
self:NetworkVar("Int", slot, name)
local getVar = function(minMax)
if self[minMax] and isfunction(self[minMax]) then return self[minMax](self) end
if self[minMax] and isnumber(self[minMax]) then return self[minMax] end
return minMax or 0
end
self["Add" .. name] = function(_, var)
local Val = self["Get" .. name](self) + var
if min and max then
Val = Clamp(tonumber(Val) or 0, getVar(min), getVar(max))
end
self["Set" .. name](self, Val)
end
self["Take" .. name] = function(_, var)
local Val = self["Get" .. name](self) - var
if min and max then
Val = Clamp(tonumber(Val) or 0, getVar(min), getVar(max))
end
self["Set" .. name](self, Val)
end
end
function ENT:StableNetwork()
self:GSAT(2, "Capacity")
self:GSAT(3, "Money", 0, "GetCapacity")
self:GSAT(4, "Paper", 0, "MaxPaper")
self:GSAT(5, "Level", 0, "MaxLevel")
end
function ENT:ThinkFunc() --This Funtion is to auto collect all the Money of Printers
for k, v in pairs( ents.FindByClass( "bw_printer_*" ) ) do
if v:CPPIGetOwner() == self:CPPIGetOwner() then
if self:GetMoney() < self.Capacity then
local allmoney = v:GetMoney()
v:TakeMoney(allmoney)
self:AddMoney(allmoney)
end
end
end
for k, v in pairs( ents.FindByClass( "bw_base_moneyprinter" ) ) do
if v:CPPIGetOwner() == self:CPPIGetOwner() then
if self:GetMoney() < self.Capacity then
local allmoney = v:GetMoney()
v:TakeMoney(allmoney)
self:AddMoney(allmoney)
end
end
end
end
if CLIENT then
local Cp = self:GetCapacity()
local money = tonumber(self:GetMoney()) or 0
local cap = tonumber(Cp) or 0
local moneyPercentage = math.Round( money / cap * 100 ,1)
draw.DrawText( moneyPercentage .."%" , fontName .. ".Huge", w - 4-430, 71+610, self.FontColor, TEXT_ALIGN_CENTER)
local currentMoney = BaseWars.LANG.CURRENCY .. BaseWars.NumberFormat(money)
local maxMoney = BaseWars.LANG.CURRENCY .. BaseWars.NumberFormat(cap)
local font = fontName .. ".Big"
if #currentMoney > 16 then
font = fontName .. ".MedBig"
end
if #currentMoney > 20 then
font = fontName .. ".Med"
end
local fh = draw.GetFontHeight(font)
local StrW,StrH = surface.GetTextSize("")
local moneyW,moneyH = surface.GetTextSize(currentMoney)
draw.DrawText(currentMoney.. " / " .. BaseWars.LANG.CURRENCY .. BaseWars.NumberFormat(cap) , font,
w/2 - StrW/2-225 , (font == fontName .. ".Big" and 106 or 105 + fh / 4)+675, self.FontColor, TEXT_ALIGN_CENTER)
end
这是我所做的更改:
删除行:local cap = tonumber(Cp) or 0
添加本地上限 = 10^15 if self:GetMoney() < cap then
ENT.Capacity = 2000000000 --Max money in the bank. Can be bugs if it is more than 2000000000 (2 bil)
local cap = 10^15
ENT.Money = 0
ENT.MaxPaper = 0
local Clamp = math.Clamp
function ENT:GSAT(slot, name, min, max)
self:NetworkVar("Int", slot, name)
local getVar = function(minMax)
if self[minMax] and isfunction(self[minMax]) then return self[minMax](self) end
if self[minMax] and isnumber(self[minMax]) then return self[minMax] end
return minMax or 0
end
self["Add" .. name] = function(_, var)
local Val = self["Get" .. name](self) + var
if min and max then
Val = Clamp(tonumber(Val) or 0, getVar(min), getVar(max))
end
self["Set" .. name](self, Val)
end
self["Take" .. name] = function(_, var)
local Val = self["Get" .. name](self) - var
if min and max then
Val = Clamp(tonumber(Val) or 0, getVar(min), getVar(max))
end
self["Set" .. name](self, Val)
end
end
function ENT:StableNetwork()
self:GSAT(2, "Capacity")
self:GSAT(3, "Money", 0, "GetCapacity")
self:GSAT(4, "Paper", 0, "MaxPaper")
self:GSAT(5, "Level", 0, "MaxLevel")
end
function ENT:ThinkFunc() --This Funtion is to auto collect all the Money of Printers
for k, v in pairs( ents.FindByClass( "bw_printer_*" ) ) do
if v:CPPIGetOwner() == self:CPPIGetOwner() then
if self:GetMoney() < cap then
local allmoney = v:GetMoney()
v:TakeMoney(allmoney)
self:AddMoney(allmoney)
end
end
end
for k, v in pairs( ents.FindByClass( "bw_base_moneyprinter" ) ) do
if v:CPPIGetOwner() == self:CPPIGetOwner() then
if self:GetMoney() < cap then
local allmoney = v:GetMoney()
v:TakeMoney(allmoney)
self:AddMoney(allmoney)
end
end
end
end
if CLIENT then
local Cp = self:GetCapacity()
local money = tonumber(self:GetMoney()) or 0
local moneyPercentage = math.Round( money / cap * 100 ,1)
draw.DrawText( moneyPercentage .."%" , fontName .. ".Huge", w - 4-430, 71+610, self.FontColor, TEXT_ALIGN_CENTER)
local currentMoney = BaseWars.LANG.CURRENCY .. BaseWars.NumberFormat(money)
local maxMoney = BaseWars.LANG.CURRENCY .. BaseWars.NumberFormat(cap)
local font = fontName .. ".Big"
if #currentMoney > 16 then
font = fontName .. ".MedBig"
end
if #currentMoney > 20 then
font = fontName .. ".Med"
end
local fh = draw.GetFontHeight(font)
local StrW,StrH = surface.GetTextSize("")
local moneyW,moneyH = surface.GetTextSize(currentMoney)
draw.DrawText(currentMoney.. " / " .. BaseWars.LANG.CURRENCY .. BaseWars.NumberFormat(cap) , font,
w/2 - StrW/2-225 , (font == fontName .. ".Big" and 106 or 105 + fh / 4)+675, self.FontColor, TEXT_ALIGN_CENTER)
end
所以现在如果你看一下游戏,它看起来像这样:现在我有一个问题,当它收钱时,它会达到 20 亿,如果我尝试改变
local money = tonumber(self:GetMoney()) or 0
至
local money =self:GetMoney()
我直接 -21 亿
或者我尝试更改最小最大值:
function ENT:GSAT(slot, name, min, max)
self:NetworkVar("Int", slot, name)
local getVar = function(minMax)
if self[minMax] and isfunction(self[minMax]) then return self[minMax](self) end
if self[minMax] and isnumber(self[minMax]) then return self[minMax] end
return minMax or 0
end
self["Add" .. name] = function(_, var)
local Val = self["Get" .. name](self) + var
if min and max then
Val = Clamp(tonumber(Val) or 0, getVar(min), 10^15)
end
self["Set" .. name](self, Val)
end
self["Take" .. name] = function(_, var)
local Val = self["Get" .. name](self) - var
if min and max then
Val = Clamp(tonumber(Val) or 0, getVar(min), 10^15)
end
self["Set" .. name](self, Val)
end
end
基本上这些行:
Val = Clamp(tonumber(Val) or 0, getVar(min), 10^15)
如果我运行游戏,银行将只收取最多 2 比尔的钱,然后它会变成 -21 亿美元。那时我不知道为什么以及什么时候某个值会出现问题,就像它自己设置为 -21 亿一样。math.Round 会创建此错误还是 funktion return 仅返回完整整数?
谢谢任何帮助