Standardize storing globals in Data
This commit is contained in:
parent
d176d5b10b
commit
a5fe63e8c3
|
@ -2,6 +2,8 @@ local Shop = {}
|
|||
|
||||
local Textbox = require "action.textbox"
|
||||
|
||||
local Data = require "data.data"
|
||||
|
||||
local Input = require "util.input"
|
||||
local Memory = require "util.memory"
|
||||
local Menu = require "util.menu"
|
||||
|
@ -9,13 +11,11 @@ local Player = require "util.player"
|
|||
|
||||
local Inventory = require "storage.inventory"
|
||||
|
||||
local yellow = YELLOW
|
||||
|
||||
function Shop.transaction(options)
|
||||
local item, itemMenu, menuIdx, quantityMenu
|
||||
if options.sell then
|
||||
menuIdx = 1
|
||||
itemMenu = yellow and 28 or 29
|
||||
itemMenu = Data.yellow and 28 or 29
|
||||
quantityMenu = 158
|
||||
for i,sit in ipairs(options.sell) do
|
||||
local idx = Inventory.indexOf(sit.name)
|
||||
|
@ -29,7 +29,7 @@ function Shop.transaction(options)
|
|||
end
|
||||
if not item and options.buy then
|
||||
menuIdx = 0
|
||||
itemMenu = yellow and 122 or 123
|
||||
itemMenu = Data.yellow and 122 or 123
|
||||
quantityMenu = 161
|
||||
for i,bit in ipairs(options.buy) do
|
||||
local needed = (bit.amount or 1) - Inventory.count(bit.name)
|
||||
|
@ -48,7 +48,7 @@ function Shop.transaction(options)
|
|||
Input.press("B")
|
||||
elseif Player.isFacing(options.direction or "Left") then
|
||||
if Menu.isOpened() then
|
||||
local mainMenu = yellow and 245 or 32
|
||||
local mainMenu = Data.yellow and 245 or 32
|
||||
if Menu.isCurrently(mainMenu, "shop") then
|
||||
Menu.select(menuIdx, true, false, "shop")
|
||||
elseif Menu.getCol() == 15 then
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
local Walk = {}
|
||||
|
||||
local Data = require "data.data"
|
||||
|
||||
local Control = require "ai.control"
|
||||
local paths = require("data."..GAME_NAME..".paths")
|
||||
local paths = require("data."..Data.gameName..".paths")
|
||||
|
||||
local Input = require "util.input"
|
||||
local Memory = require "util.memory"
|
||||
|
|
|
@ -7,6 +7,8 @@ local Battle = require "action.battle"
|
|||
local Textbox = require "action.textbox"
|
||||
local Walk = require "action.walk"
|
||||
|
||||
local Data = require "data.data"
|
||||
|
||||
local Bridge = require "util.bridge"
|
||||
local Input = require "util.input"
|
||||
local Memory = require "util.memory"
|
||||
|
@ -15,11 +17,9 @@ local Player = require "util.player"
|
|||
local Shop = require "action.shop"
|
||||
local Utils = require "util.utils"
|
||||
|
||||
local Data = require "data.data"
|
||||
local Inventory = require "storage.inventory"
|
||||
local Pokemon = require "storage.pokemon"
|
||||
|
||||
local yellow = YELLOW
|
||||
local splitNumber, splitTime = 0, 0
|
||||
local resetting
|
||||
|
||||
|
@ -449,13 +449,13 @@ function Strategies.completeCans()
|
|||
local suffix = "!"
|
||||
if status.tries <= 1 then
|
||||
prefix = "PERFECT"
|
||||
elseif status.tries <= (yellow and 2 or 3) then
|
||||
elseif status.tries <= (Data.yellow and 2 or 3) then
|
||||
prefix = "Amazing"
|
||||
elseif status.tries <= (yellow and 4 or 6) then
|
||||
elseif status.tries <= (Data.yellow and 4 or 6) then
|
||||
prefix = "Great"
|
||||
elseif status.tries <= (yellow and 6 or 9) then
|
||||
elseif status.tries <= (Data.yellow and 6 or 9) then
|
||||
prefix = "Good"
|
||||
elseif status.tries <= (yellow and 10 or 22) then
|
||||
elseif status.tries <= (Data.yellow and 10 or 22) then
|
||||
prefix = "Ugh"
|
||||
suffix = "."
|
||||
else -- TODO trashcans WR
|
||||
|
@ -677,7 +677,7 @@ Strategies.functions = {
|
|||
|
||||
skill = function(data)
|
||||
if completedSkillFor(data) then
|
||||
if yellow then
|
||||
if Data.yellow then
|
||||
if not Menu.hasTextbox() then
|
||||
return true
|
||||
end
|
||||
|
@ -690,7 +690,7 @@ Strategies.functions = {
|
|||
elseif not data.dir or Player.face(data.dir) then
|
||||
if Pokemon.use(data.move) then
|
||||
status.tries = status.tries + 1
|
||||
elseif yellow and Menu.hasTextbox() then
|
||||
elseif Data.yellow and Menu.hasTextbox() then
|
||||
if Textbox.handle() then
|
||||
return true
|
||||
end
|
||||
|
@ -715,7 +715,7 @@ Strategies.functions = {
|
|||
}
|
||||
|
||||
local main = Memory.value("menu", "main")
|
||||
if main == (yellow and 144 or 228) then
|
||||
if main == (Data.yellow and 144 or 228) then
|
||||
local currentCity = Memory.value("game", "fly")
|
||||
local destination = cities[data.dest]
|
||||
local press
|
||||
|
@ -846,7 +846,7 @@ Strategies.functions = {
|
|||
elseif Battle.isActive() then
|
||||
status.canProgress = false
|
||||
Battle.automate()
|
||||
elseif main == (yellow and 23 or 123) then
|
||||
elseif main == (Data.yellow and 23 or 123) then
|
||||
status.canProgress = true
|
||||
Input.press("B")
|
||||
elseif Textbox.handle() then
|
||||
|
@ -911,7 +911,7 @@ Strategies.functions = {
|
|||
return true
|
||||
end
|
||||
elseif Menu.pause() then
|
||||
if yellow then
|
||||
if Data.yellow then
|
||||
if Inventory.contains("potion") and Pokemon.info("nidoran", "hp") < 15 then
|
||||
Inventory.use("potion", "nidoran")
|
||||
return false
|
||||
|
@ -1075,7 +1075,7 @@ Strategies.functions = {
|
|||
end
|
||||
local moonEncounters = Data.run.encounters_moon
|
||||
if moonEncounters then
|
||||
local catchPokemon = yellow and "sandshrew" or "paras"
|
||||
local catchPokemon = Data.yellow and "sandshrew" or "paras"
|
||||
local capsName = Utils.capitalize(catchPokemon)
|
||||
local parasStatus
|
||||
local conjunction = "but"
|
||||
|
@ -1120,7 +1120,7 @@ Strategies.functions = {
|
|||
if Pokemon.info("nidoking", "level") ~= 20 then
|
||||
return true
|
||||
end
|
||||
if yellow then
|
||||
if Data.yellow then
|
||||
p("RCE", Pokemon.getExp())
|
||||
end
|
||||
if Pokemon.getExp() > 5550 then
|
||||
|
@ -1138,7 +1138,7 @@ Strategies.functions = {
|
|||
end
|
||||
end
|
||||
if not status.close then
|
||||
local replacementMove = yellow and "tackle" or "leer"
|
||||
local replacementMove = Data.yellow and "tackle" or "leer"
|
||||
status.close = strategyFunctions.teach({move="thrash", item="rare_candy", replace=replacementMove})
|
||||
status.updateStats = true
|
||||
elseif Menu.close() then
|
||||
|
@ -1168,7 +1168,7 @@ Strategies.functions = {
|
|||
return false
|
||||
end
|
||||
if column == 5 then
|
||||
local replacementMove = yellow and "tackle" or "leer"
|
||||
local replacementMove = Data.yellow and "tackle" or "leer"
|
||||
local replaceIndex = Pokemon.moveIndex(replacementMove, "nidoking")
|
||||
if replaceIndex then
|
||||
Menu.select(replaceIndex - 1, true)
|
||||
|
@ -1197,7 +1197,7 @@ Strategies.functions = {
|
|||
|
||||
lassEther = function()
|
||||
if Strategies.initialize() then
|
||||
if yellow then
|
||||
if Data.yellow then
|
||||
if not Strategies.vaporeon or not Strategies.needs1Carbos() then
|
||||
return true
|
||||
end
|
||||
|
@ -1298,7 +1298,7 @@ Strategies.functions = {
|
|||
end,
|
||||
|
||||
shopRepels = function()
|
||||
local repelCount = yellow and 10 or 9
|
||||
local repelCount = Data.yellow and 10 or 9
|
||||
return Shop.transaction {
|
||||
direction = "Up",
|
||||
buy = {{name="super_repel", index=3, amount=repelCount}}
|
||||
|
@ -1450,7 +1450,7 @@ Strategies.functions = {
|
|||
Strategies.setYolo("safari_carbos")
|
||||
status.carbos = Inventory.count("carbos")
|
||||
end
|
||||
local minDV = yellow and 9 or 7
|
||||
local minDV = Data.yellow and 9 or 7
|
||||
if stats.nidoran.speedDV >= minDV then
|
||||
return true
|
||||
end
|
||||
|
@ -1528,7 +1528,7 @@ Strategies.functions = {
|
|||
if Strategies.initialize() then
|
||||
status.startCount = Inventory.count("carbos")
|
||||
end
|
||||
local minDV = yellow and 11 or 10
|
||||
local minDV = Data.yellow and 11 or 10
|
||||
if stats.nidoran.speedDV >= minDV then
|
||||
px, py = 21, 20
|
||||
else
|
||||
|
@ -1643,16 +1643,16 @@ Strategies.functions = {
|
|||
if status.finishTime then
|
||||
if not status.frames then
|
||||
status.frames = 0
|
||||
local victoryMessage = "Beat Pokemon "..Utils.capitalize(GAME_NAME).." in "..status.finishTime
|
||||
local victoryMessage = "Beat Pokemon "..Utils.capitalize(Data.gameName).." in "..status.finishTime
|
||||
if not Strategies.overMinute("champion") then
|
||||
victoryMessage = victoryMessage..", a new PB!"
|
||||
end
|
||||
Strategies.tweetProgress(victoryMessage)
|
||||
if Data.run.seed then
|
||||
Data.run.frames = Utils.frames()
|
||||
Data.setFrames()
|
||||
print("v"..VERSION..": "..Data.run.frames.." frames, with seed "..Data.run.seed)
|
||||
|
||||
if (yellow or not INTERNAL or RESET_FOR_TIME) and not Strategies.replay then
|
||||
if (Data.yellow or not INTERNAL or RESET_FOR_TIME) and not Strategies.replay then
|
||||
print("Please save this seed number to share, if you would like proof of your run!")
|
||||
print("A screenshot has been saved to the Gameboy\\Screenshots folder in BizHawk.")
|
||||
gui.cleartext()
|
||||
|
@ -1661,7 +1661,7 @@ Strategies.functions = {
|
|||
gui.text(0, 14, "Name: "..Textbox.getNamePlaintext())
|
||||
gui.text(0, 21, "Reset for time: "..tostring(RESET_FOR_TIME))
|
||||
gui.text(0, 28, "Time: "..Utils.elapsedTime())
|
||||
gui.text(0, 35, "Frames: "..Utils.frames())
|
||||
gui.text(0, 35, "Frames: "..Data.frames())
|
||||
client.setscreenshotosd(true)
|
||||
client.screenshot()
|
||||
client.setscreenshotosd(false)
|
||||
|
@ -1689,14 +1689,14 @@ strategyFunctions = Strategies.functions
|
|||
function Strategies.execute(data)
|
||||
local strategyFunction = strategyFunctions[data.s]
|
||||
if not strategyFunction then
|
||||
p("INVALID STRATEGY", data.s, GAME_NAME)
|
||||
p("INVALID STRATEGY", data.s, Data.gameName)
|
||||
return true
|
||||
end
|
||||
if strategyFunction(data) then
|
||||
status = {tries=0}
|
||||
Strategies.status = status
|
||||
Strategies.completeGameStrategy()
|
||||
if yellow then
|
||||
if Data.yellow then
|
||||
-- print(data.s)
|
||||
end
|
||||
if resetting then
|
||||
|
|
|
@ -3,6 +3,8 @@ local Strategies = require "ai.strategies"
|
|||
local Combat = require "ai.combat"
|
||||
local Control = require "ai.control"
|
||||
|
||||
local Data = require "data.data"
|
||||
|
||||
local Battle = require "action.battle"
|
||||
local Shop = require "action.shop"
|
||||
local Textbox = require "action.textbox"
|
||||
|
@ -96,7 +98,7 @@ local function nidoranDSum(enabled)
|
|||
end
|
||||
if status.path then
|
||||
status.pathIndex = 1
|
||||
status.startTime = Utils.frames() + 118
|
||||
status.startTime = Data.frames() + 118
|
||||
else
|
||||
status.path = 0
|
||||
end
|
||||
|
@ -107,7 +109,7 @@ local function nidoranDSum(enabled)
|
|||
local encounterlessSteps = Memory.value("game", "encounterless")
|
||||
if enabled and status.path ~= 0 then
|
||||
local duration = status.path[status.pathIndex]
|
||||
local currentTime = Utils.frames()
|
||||
local currentTime = Data.frames()
|
||||
if (currentTime - status.startTime) / 60 > duration then
|
||||
status.startTime = currentTime
|
||||
if status.pathIndex >= #status.path then
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
local Data
|
||||
|
||||
local Bridge = require "util.bridge"
|
||||
local Utils = require "util.utils"
|
||||
local Pokemon = require "storage.pokemon"
|
||||
|
||||
local version = 0
|
||||
if VERSION then
|
||||
local vIndex = 2
|
||||
|
@ -13,22 +9,51 @@ if VERSION then
|
|||
end
|
||||
end
|
||||
|
||||
local yellowVersion = memory.getcurrentmemorydomainsize() > 30000
|
||||
|
||||
Data = {
|
||||
run = {},
|
||||
|
||||
yellow = yellowVersion,
|
||||
gameName = yellowVersion and "yellow" or "red",
|
||||
versionNumber = version,
|
||||
}
|
||||
|
||||
-- PRIVATE
|
||||
|
||||
local function increment(amount)
|
||||
if not amount then
|
||||
return 1
|
||||
end
|
||||
return amount + 1
|
||||
end
|
||||
|
||||
-- HELPERS
|
||||
|
||||
function Data.frames()
|
||||
local totalFrames = Memory.value("time", "hours") * 60
|
||||
totalFrames = (totalFrames + Memory.value("time", "minutes")) * 60
|
||||
totalFrames = (totalFrames + Memory.value("time", "seconds")) * 60
|
||||
totalFrames = totalFrames + Memory.value("time", "frames")
|
||||
return totalFrames
|
||||
end
|
||||
|
||||
function Data.setFrames()
|
||||
Data.run.frames = Data.frames()
|
||||
end
|
||||
|
||||
function Data.increment(key)
|
||||
local incremented = Utils.increment(Data.run[key])
|
||||
local incremented = increment(Data.run[key])
|
||||
Data.run[key] = incremented
|
||||
return incremented
|
||||
end
|
||||
|
||||
-- REPORT
|
||||
|
||||
function Data.reset(reason, areaName, map, px, py)
|
||||
if STREAMING_MODE then
|
||||
local report = Data.run
|
||||
report.cutter = Pokemon.inParty("paras", "oddish", "sandshrew", "charmander")
|
||||
report.cutter = require("storage.pokemon").inParty("paras", "oddish", "sandshrew", "charmander")
|
||||
|
||||
for key,value in pairs(report) do
|
||||
if value == true or value == false then
|
||||
|
@ -37,6 +62,8 @@ function Data.reset(reason, areaName, map, px, py)
|
|||
end
|
||||
|
||||
report.version = Data.versionNumber
|
||||
report.gameName = Data.gameName
|
||||
|
||||
report.reset_area = areaName
|
||||
report.reset_map = map
|
||||
report.reset_x = px
|
||||
|
@ -44,10 +71,10 @@ function Data.reset(reason, areaName, map, px, py)
|
|||
report.reset_reason = reason
|
||||
|
||||
if not report.frames then
|
||||
report.frames = Utils.frames()
|
||||
Data.setFrames()
|
||||
end
|
||||
|
||||
Bridge.report(report)
|
||||
require("util.bridge").report(report)
|
||||
end
|
||||
Data.run = {}
|
||||
end
|
||||
|
|
9
main.lua
9
main.lua
|
@ -9,18 +9,18 @@ local PAINT_ON = true -- Display contextual information while the bot runs
|
|||
-- START CODE (hard hats on)
|
||||
|
||||
VERSION = "1.4.5"
|
||||
YELLOW = memory.getcurrentmemorydomainsize() > 30000
|
||||
GAME_NAME = YELLOW and "yellow" or "red"
|
||||
|
||||
local START_WAIT = 99
|
||||
|
||||
local Data = require "data.data"
|
||||
|
||||
local Battle = require "action.battle"
|
||||
local Textbox = require "action.textbox"
|
||||
local Walk = require "action.walk"
|
||||
|
||||
local Combat = require "ai.combat"
|
||||
local Control = require "ai.control"
|
||||
local Strategies = require("ai."..GAME_NAME..".strategies")
|
||||
local Strategies = require("ai."..Data.gameName..".strategies")
|
||||
|
||||
local Bridge = require "util.bridge"
|
||||
local Input = require "util.input"
|
||||
|
@ -30,7 +30,6 @@ local Paint = require "util.paint"
|
|||
local Utils = require "util.utils"
|
||||
local Settings = require "util.settings"
|
||||
|
||||
local Data = require "data.data"
|
||||
local Pokemon = require "storage.pokemon"
|
||||
|
||||
local hasAlreadyStartedPlaying = false
|
||||
|
@ -63,7 +62,7 @@ end
|
|||
|
||||
-- EXECUTE
|
||||
|
||||
p("Welcome to PokeBot "..GAME_NAME.." version "..VERSION, true)
|
||||
p("Welcome to PokeBot "..Data.gameName.." version "..VERSION, true)
|
||||
|
||||
Control.init()
|
||||
|
||||
|
|
|
@ -7,8 +7,6 @@ local Utils = require "util.utils"
|
|||
|
||||
local Pokemon = require "storage.pokemon"
|
||||
|
||||
local yellow = YELLOW
|
||||
|
||||
local items = {
|
||||
pokeball = 4,
|
||||
bicycle = 6,
|
||||
|
@ -181,7 +179,7 @@ end
|
|||
function Inventory.use(item, poke, midfight)
|
||||
if midfight then
|
||||
local battleMenu = Memory.value("battle", "menu")
|
||||
if battleMenu == 94 then
|
||||
if Menu.onBattleSelect(battleMenu) then
|
||||
local rowSelected = Memory.value("menu", "row")
|
||||
if Menu.getCol() == 9 then
|
||||
if rowSelected == 0 then
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
local Pokemon = {}
|
||||
|
||||
local Data = require "data.data"
|
||||
|
||||
local Bridge = require "util.bridge"
|
||||
local Input = require "util.input"
|
||||
local Memory = require "util.memory"
|
||||
local Menu = require "util.menu"
|
||||
|
||||
local yellow = YELLOW
|
||||
|
||||
local pokeIDs = {
|
||||
rhydon = 1,
|
||||
kangaskhan = 2,
|
||||
|
@ -139,7 +139,7 @@ Pokemon.indexOf = indexOf
|
|||
local function fieldMoveIndex(move)
|
||||
local moveIndex = 0
|
||||
local menuSize = Memory.value("menu", "size")
|
||||
if yellow then
|
||||
if Data.yellow then
|
||||
if move == "cut" then
|
||||
if Pokemon.inParty("charmander") then
|
||||
moveIndex = 1
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
local Memory = {}
|
||||
|
||||
local Data = require "data.data"
|
||||
|
||||
local memoryNames = {
|
||||
setting = {
|
||||
text_speed = 0x0D3D,
|
||||
|
@ -119,10 +121,8 @@ local doubleNames = {
|
|||
},
|
||||
}
|
||||
|
||||
local yellow = YELLOW
|
||||
|
||||
local function raw(address, forYellow)
|
||||
if yellow and not forYellow and address > 0x0F12 and address < 0x1F00 then
|
||||
if Data.yellow and not forYellow and address > 0x0F12 and address < 0x1F00 then
|
||||
address = address - 1
|
||||
end
|
||||
return memory.readbyte(address)
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
local Menu = {}
|
||||
|
||||
local Data = require "data.data"
|
||||
|
||||
local Input = require "util.input"
|
||||
local Memory = require "util.memory"
|
||||
|
||||
local yellow = GAME_NAME == "yellow"
|
||||
local yellow = Data.yellow
|
||||
|
||||
local sliding = false
|
||||
local alternateStart = 0
|
||||
|
|
|
@ -2,10 +2,11 @@ local Player = {}
|
|||
|
||||
local Textbox = require "action.textbox"
|
||||
|
||||
local Data = require "data.data"
|
||||
|
||||
local Input = require "util.input"
|
||||
local Memory = require "util.memory"
|
||||
|
||||
local yellow = YELLOW
|
||||
local facingDirections = {Up=8, Right=1, Left=2, Down=4}
|
||||
local fast = false
|
||||
|
||||
|
@ -25,7 +26,7 @@ end
|
|||
function Player.interact(direction, extended)
|
||||
if Player.face(direction) then
|
||||
local speed = extended and 3 or 2
|
||||
if yellow and instant then
|
||||
if Data.yellow and instant then
|
||||
fast = not fast
|
||||
speed = fast and 1 or 2
|
||||
end
|
||||
|
|
|
@ -3,26 +3,24 @@ local Settings = {}
|
|||
local Textbox = require "action.textbox"
|
||||
local Strategies = require "ai.strategies"
|
||||
|
||||
local Data = require "data.data"
|
||||
|
||||
local Bridge = require "util.bridge"
|
||||
local Input = require "util.input"
|
||||
local Memory = require "util.memory"
|
||||
local Menu = require "util.menu"
|
||||
|
||||
local Data = require "data.data"
|
||||
|
||||
local START_WAIT = 99
|
||||
|
||||
local yellow = YELLOW
|
||||
|
||||
local settings_menu
|
||||
if yellow then
|
||||
if Data.yellow then
|
||||
settings_menu = 93
|
||||
else
|
||||
settings_menu = 94
|
||||
end
|
||||
|
||||
local desired = {}
|
||||
if yellow then
|
||||
if Data.yellow then
|
||||
desired.text_speed = 1
|
||||
desired.battle_animation = 128
|
||||
desired.battle_style = 64
|
||||
|
@ -33,7 +31,7 @@ else
|
|||
end
|
||||
|
||||
local function isEnabled(name)
|
||||
if yellow then
|
||||
if Data.yellow then
|
||||
local matching = {
|
||||
text_speed = 0xF,
|
||||
battle_animation = 128,
|
||||
|
@ -62,7 +60,7 @@ end
|
|||
|
||||
function Settings.startNewAdventure(startWait)
|
||||
local startMenu, withBattleStyle
|
||||
if yellow then
|
||||
if Data.yellow then
|
||||
startMenu = Memory.raw(0x0F95) == 0
|
||||
withBattleStyle = "battle_style"
|
||||
else
|
||||
|
|
|
@ -4,8 +4,6 @@ local Memory = require "util.memory"
|
|||
|
||||
local EMP = 1
|
||||
|
||||
local yellow = YELLOW
|
||||
|
||||
-- GLOBAL
|
||||
|
||||
function p(...)
|
||||
|
@ -79,13 +77,6 @@ function Utils.nextCircularIndex(index, direction, totalCount)
|
|||
return nextIndex
|
||||
end
|
||||
|
||||
function Utils.increment(amount)
|
||||
if not amount then
|
||||
return 1
|
||||
end
|
||||
return amount + 1
|
||||
end
|
||||
|
||||
function Utils.append(string, appendage, separator)
|
||||
if not string then
|
||||
return appendage
|
||||
|
@ -172,12 +163,4 @@ function Utils.elapsedTime()
|
|||
return hours..":"..clockSegment(mins)..":"..clockSegment(secs)
|
||||
end
|
||||
|
||||
function Utils.frames()
|
||||
local totalFrames = Memory.value("time", "hours") * 60
|
||||
totalFrames = (totalFrames + Memory.value("time", "minutes")) * 60
|
||||
totalFrames = (totalFrames + Memory.value("time", "seconds")) * 60
|
||||
totalFrames = totalFrames + Memory.value("time", "frames")
|
||||
return totalFrames
|
||||
end
|
||||
|
||||
return Utils
|
||||
|
|
Loading…
Reference in New Issue