1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
class_name GhostData
extends Resource
var time: float
var checkpoints: Array
var snapped_checkpoints: Array
# i hope this is performant
var snaps: Array# it doesnt let me type it
var snap_count := 0
func snapshot(obj: Car):
snaps.append(CarVars.create(obj))
snap_count += 1
## returns a CarVars array
func load_snap(i: int) -> PackedFloat32Array:
return snaps[i]
func save(path: String) -> void:
GhostData._save_file(path, {checkpoints = checkpoints, snapped_checkpoints = snapped_checkpoints, time = time, snaps = snaps, snap_count = snap_count})
func mkarr(size: int) -> Array:
var arr := []
arr.resize(size)
arr.fill(-1)
return arr
func _init(num_checkpoints := 0, laps := 0) -> void:
for i in laps:
checkpoints.append(mkarr(num_checkpoints + 1))
snapped_checkpoints.append(mkarr(num_checkpoints + 1))
func clear() -> void:
for lap in checkpoints:
lap.fill(-1)
snaps.clear()
time = 0
snap_count = 0
func collect(lap: int, cp: int, now: float) -> void:
checkpoints[lap][cp] = now
snapped_checkpoints[lap][cp] = snap_count
if lap == len(checkpoints) - 1 && cp == -1:
time = now
func has_collected(lap: int, cp: int) -> bool:
return checkpoints[lap][cp] != -1
func get_time(lap: int, cp: int) -> float:
return checkpoints[lap][cp]
static func from_d(d: Dictionary) -> GhostData:
var obj := GhostData.new()
obj.time = d.time
obj.checkpoints = d.checkpoints
obj.snapped_checkpoints = d.snapped_checkpoints
obj.snap_count = d.snap_count
obj.snaps = d.snaps
return obj
## Saves a basic dictionary to a path.
static func _save_file(path: String, data: Dictionary) -> void:
if !DirAccess.dir_exists_absolute(path.get_base_dir()):
DirAccess.make_dir_recursive_absolute(path.get_base_dir())
var file := FileAccess.open_compressed(path, FileAccess.WRITE, FileAccess.COMPRESSION_ZSTD)
if file == null:
push_error(FileAccess.get_open_error())
file.store_buffer(var_to_bytes(data))
## Loads a basic dictionary out of a file.
static func _load_file(path: String) -> Dictionary:
if FileAccess.file_exists(path):
var file := FileAccess.open_compressed(path, FileAccess.READ, FileAccess.COMPRESSION_ZSTD)
var text := file.get_buffer(file.get_length())
var dict := {}
if text:
dict = bytes_to_var(text)
return dict
_save_file(path, {}) # create file if it doesn't exist
return {}
## Creates a [GhostData] from a file
static func _load(path: String) -> GhostData:
var res := _load_file(path)
if res.is_empty():
return null
return GhostData.from_d(res)
|