Add importing and exporting replays

This commit is contained in:
Squishy (C6H12O6+NaCl+H2O)
2024-05-29 00:09:48 +07:00
parent d7726c1854
commit 9679378b1b
7 changed files with 99 additions and 14 deletions

View File

@@ -15,7 +15,7 @@ function GameMode:new(player_name, input_file, replay_grade)
if player_name == nil then self.training = true else self.training = false end
if input_file ~= nil then
input_file = love.filesystem.newFile(REPLAY_DIR..input_file, 'r'):read()
input_file = love.filesystem.read(REPLAY_DIR..input_file)
input_file = lualzw.decompress(input_file)
local seed = self:getInputPieceSeq(input_file)
self.replay_inputs = self:getReplayInputs(input_file)

View File

@@ -2,6 +2,10 @@
FONT_tromi = love.graphics.newFont('res/fonts/monofonto rg.otf', 28)
FONT_big = love.graphics.newFont('res/fonts/monofonto rg.otf', 56)
FONT_tromi:setFallbacks(love.graphics.newFont('res/fonts/icon.otf', 28))
FONT_big :setFallbacks(love.graphics.newFont('res/fonts/icon.otf', 56))
CHAR = require("char")
local font_height = FONT_tromi:getHeight() * 0.5
local font_big_height = FONT_big:getHeight() * 0.5

View File

@@ -52,9 +52,11 @@ function love.load()
require "game.vctrl" -- VCTRL
function SCENE.update()
SCENE.update = function() end
SCENE = SETTINGS.firstTime and InputConfigScene(true) or TitleScene()
end
function SCENE.render()
SCENE.render = function() end
love.graphics.draw(LOADING_IMAGE_FILE,0,0,0,0.5)
end

View File

@@ -35,6 +35,7 @@ function SCENE:onInputPress(e) end
function SCENE:onInputRelease(e) end
GameScene = require "scene.game"
TrainingScene = require "scene.training"
NameEntryScene = require "scene.name_entry"
KeyConfigScene = require "scene.key_config"
@@ -44,7 +45,7 @@ TouchConfigPreviewScene = require "scene.touch_config_preview"
InputConfigScene = require "scene.input_config"
ReplaySelectScene = require "scene.replay"
TrainingScene = require "scene.training"
ReplayTestScene = require"scene.replay_test"
FullscreenScene = require "scene.fullscreen"
MusicToggleScene = require "scene.music_toggle"

View File

@@ -70,7 +70,7 @@ function ConfigScene:new(first_time)
updateButtonList(self)
secret_code_used = false
secret_code_input = {} -- When it matches 79338732 then we will automatically set the special keybind
secret_code_input = {} -- When it matches 88663366 then we will automatically set the special keybind
self.menu_state = 1
if first_time then
@@ -88,10 +88,10 @@ function ConfigScene:render()
if SETTINGS.tvMode then
drawText("TV mode is ON now! Check keybind below", 80, 40, 1000)
drawText("Which controls do you want to configure?", 80, 70, 1000)
drawText(
"2 - Up 1 - Rotate left 5 - Confirm selection\n"..
"8 - Right 3 - Rotate right 0 - Back\n"..
"4 - Left 7 - Rotate left 2\n"..
drawText(
"2 - Up 1 - Rotate left 5 - Confirm selection\n"..
"8 - Right 3 - Rotate right 0 - Back\n"..
"4 - Left 7 - Rotate left 2\n"..
"6 - Down 9 - Rotate right 2", 80, 350, 1000
)
else
@@ -128,7 +128,7 @@ function ConfigScene:onInputMove(e)
end
---@param key string
local function checkSecretCodeInput(self, key)
local function checkSecretCodeInput(key)
if secret_code_used then return end
if key:sub(1, 2) == "kp" then
table.insert(secret_code_input, key:sub(3,3))
@@ -160,7 +160,7 @@ local function checkSecretCodeInput(self, key)
SETTINGS.firstTime = false
SETTINGS.tvMode = true
secret_code_used = true
updateButtonList(self)
updateButtonList(SCENE)
elseif current_code == "........" then
SETTINGS.input.keys = {}
SETTINGS.tvMode = false
@@ -183,7 +183,7 @@ function ConfigScene:onInputPress(e)
) then
SCENE = TitleScene()
end
checkSecretCodeInput(self, e.key or "")
checkSecretCodeInput(e.key or "")
end
function ConfigScene:onInputRelease(e)
if e.type == "touch" or e.type == "mouse" then

View File

@@ -27,6 +27,18 @@ local buttonList = {
codeWhenPressed = function() SCENE:onInputPress {input = "menu_back"} end,
codeWhenReleased = function() SCENE:onInputRelease{input = "menu_back"} end
},
BUTTON.new{
text = CHAR.icon.export.."\nCOPY", font = FONT_big,
x = 345, y = 320, w = 80, h = 80,
codeWhenPressed = function() SCENE:onInputPress {input = "rotate_left"} end,
codeWhenReleased = function() SCENE:onInputRelease{input = "rotate_left"} end
},
BUTTON.new{
text = CHAR.icon.import.."\nPASTE", font = FONT_big,
x = 505, y = 320, w = 80, h = 80,
codeWhenPressed = function() SCENE:onInputPress {input = "rotate_right"} end,
codeWhenReleased = function() SCENE:onInputRelease{input = "rotate_right"} end
},
}
function ReplaySelectScene:new()
@@ -135,7 +147,7 @@ function ReplaySelectScene:onInputPress(e)
if e.type == "touch" or e.type == "mouse" then
BUTTON.press(buttonList, e.x, e.y, e.id)
elseif e.input == "menu_decide" or e.input == "rotate_left" or e.scancode == "return" then
elseif e.input == "menu_decide" or e.scancode == "return" then
if self.replays[1] == nil then SCENE = TitleScene(); return
else
local line_components = {}
@@ -146,15 +158,30 @@ function ReplaySelectScene:onInputPress(e)
local player_grade = string.gsub(line_components[2], " ", "")
SCENE = GameScene(player_name, selected_replay, player_grade)
end
-- elseif e.input == "rotate_right" then -- Will add in future, not now
-- love.system.setClipboardText(love.data.encode("string", "base64", love.filesystem.read('saves/replays/'..selected_replay)))
elseif e.input == "rotate_left" then -- Export
local plain_replay_data = love.data.encode("string", "base64", love.filesystem.read(REPLAY_DIR..selected_replay))
love.system.setClipboardText(("BEGINNING_OF_TROMI_REPLAY|%s|%s|END_OF_TROMI_REPLAY"):format(selected_replay, plain_replay_data))
elseif e.input == "rotate_right" then -- Import
local input_data = love.system.getClipboardText()
if input_data:find("BEGINNING_OF_TROMI_REPLAY|", 1, true) == 1 and input_data:find("|END_OF_TROMI_REPLAY", 1, true) == #input_data - 19 then
local data_part = input_data:sub(27, #input_data - 20)
local separator_pos = data_part:find("|", 1, true)
local replay_name = data_part:sub(1, separator_pos - 1)
local replay_path = REPLAY_DIR..replay_name
local replay_data = love.data.decode("string", "base64", data_part:sub(separator_pos + 1))
love.filesystem.write(replay_path, replay_data)
SCENE = ReplayTestScene(replay_name)
else
SCENE = ReplayTestScene()
end
elseif e.input == "up" or e.scancode == "up" then
if self.replays[1] == nil then SCENE = TitleScene(); return end
self.direction = 'up'
elseif e.input == "down" or e.scancode == "down" then
if self.replays[1] == nil then SCENE = TitleScene(); return end
self.direction = 'down'
elseif e.input == "menu_back" or e.input == "rotate_right" or e.scancode == "backspace" or e.scancode == "delete" then
elseif e.input == "menu_back" or e.scancode == "backspace" or e.scancode == "delete" then
SCENE = TitleScene()
end
end

51
scene/replay_test.lua Normal file
View File

@@ -0,0 +1,51 @@
local ReplayTestScene = SCENE:extend()
local GAME
local error_message
local valid_data
function ReplayTestScene:new(input_file)
if not input_file then
valid_data = false
return
else
valid_data = true
end
self.input_file = input_file
GAME = require("game.gamemode")
local okay, err = pcall(function()
GAME:new("TRO", input_file, "19k")
GAME:initialize(require"game.rotation")
end)
if not okay then
-- TODO
error_message = err
love.filesystem.remove(REPLAY_DIR..self.input_file)
end
end
function ReplayTestScene:render()
MainBackground()
if valid_data then
if error_message then
drawText("Replay test failed! Data corrupted!", 80, 40, 1000)
drawText("Press any key to go back. Anyway here is the error info:", 80, 70, 1000)
drawText(error_message, 80, 100, 560)
else
drawText("Replay test finished!", 80, 40, 1000)
drawText("Your replay was imported. Press any key to go back.", 80, 70, 1000)
end
else
drawText("Replay test failed! Not Tromi's replay data", 80, 40, 1000)
drawText("Press any key to go back, and check your device's clipboard again!", 80, 100, 1000)
end
end
function ReplayTestScene:onInputRelease()
SCENE = ReplayTestScene()
end
return ReplayTestScene