# Hurry Curry! - a game about cooking # Copyright (C) 2025 Hurry Curry! contributors # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, version 3 of the License only. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # extends Node @export var record: bool = false @export var replay: bool = false @export_file var recording_path: String = "" @onready var camera: Camera3D = $".." var time = 0. var keyframes = [] # Array<[float, Transform3D]> func _ready() -> void: if record and replay: return push_error("concurrent ecord and replay is not supported") if replay: load_recording() func _exit_tree() -> void: if record: save_recording() func load_recording(): print("Loading replay...") var file := FileAccess.open(recording_path, FileAccess.READ) var text := file.get_as_text() keyframes.clear() for line in text.split("\n"): if line == "": continue var toks = line.split(",") var time2 = float(toks[0]) var transform = parse_transform(toks[1]) var fov = float(toks[2]) keyframes.push_back([time2, transform, fov]) print("Done") func save_recording(): print("Saving replay...") var file := FileAccess.open(recording_path, FileAccess.WRITE) var out = "" for k in keyframes: out += "%f,%s,%f\n" % [k[0], serialize_transform(k[1]), k[2]] file.store_string(out) print("Done") func serialize_transform(t: Transform3D) -> String: return "%f|%f|%f|%f|%f|%f|%f|%f|%f|%f|%f|%f" % [ t.basis.x.x, t.basis.y.x, t.basis.z.x, t.origin.x, t.basis.x.y, t.basis.y.y, t.basis.z.y, t.origin.y, t.basis.x.z, t.basis.y.z, t.basis.z.z, t.origin.z, ] func parse_transform(s: String) -> Transform3D: var c := s.split("|") var t := Transform3D.IDENTITY t.basis.x.x = float(c[0]) t.basis.y.x = float(c[1]) t.basis.z.x = float(c[2]) t.origin.x = float(c[3]) t.basis.x.y = float(c[4]) t.basis.y.y = float(c[5]) t.basis.z.y = float(c[6]) t.origin.y = float(c[7]) t.basis.x.z = float(c[8]) t.basis.y.z = float(c[9]) t.basis.z.z = float(c[10]) t.origin.z = float(c[11]) return t func _process(dt: float): if Global.game_paused: return time += dt if record: keyframes.push_back([time, camera.global_transform, camera.fov]) if replay: var index = keyframes.bsearch_custom([time], func (a, b): return a[0] < b[0]) if index >= keyframes.size(): return var from = keyframes[max(0, index - 1)] var to = keyframes[index] var t = (time - from[0]) / (to[0] - from[0]) camera.global_transform = from[1].interpolate_with(to[1], t) camera.fov = from[2] * (1. - t) + to[2] * t