-
Notifications
You must be signed in to change notification settings - Fork 8
/
ReplayManager.gd
157 lines (137 loc) · 3.74 KB
/
ReplayManager.gd
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
extends Node
var frames = {
1: {},
2: {},
"finished": false,
"emotes": {
1: {},
2: {},
}
}
var playback = false setget set_playback
var resimulating = false
var play_full = false
var resim_tick = null
var replaying_ingame = false
func set_playback(p):
playback = p
func init():
frames = {
1: {},
2: {},
"finished": false,
"emotes": {
1: {},
2: {},
}
}
func frame_ids():
return [1, 2]
func cut_replay(last_frame):
for id in frame_ids():
for frame in frames[id].keys():
if frame > last_frame:
frames[id].erase(frame)
func get_last_action_tick(id):
var frame_numbers: Array = frames[id].keys()
frame_numbers.sort()
return frame_numbers[-1]
func get_last_action(id):
var frame_numbers: Array = frames[id].keys()
frame_numbers.sort()
if frame_numbers:
return frames[id][frame_numbers[-1]]
return null
func emote(message, player_id, tick):
if !playback:
frames.emotes[player_id][tick] = message
func undo(cut=true):
if resimulating:
return
var last_frame = 0
var last_id = 1
for id in frame_ids():
for frame in frames[id].keys():
if frame > last_frame:
last_frame = frame
last_id = id
var other_id = 1 if last_id == 2 else 2
if cut:
frames[last_id].erase(last_frame)
frames[other_id].erase(last_frame)
resimulating = true
playback = true
resim_tick = (last_frame - 2) if cut else -1
func generate_mp_replay_name(p1: String, p2: String):
return p1 + "_v_" + p2 + "_" + generate_replay_name()
func generate_replay_name():
var time = Time.get_datetime_dict_from_system()
var strings = [str(time.year), str(time.month), str(time.day), str(time.hour), str(time.minute)]
var string = ""
for s in strings:
string += s
string += "-"
string += str(time.second)
return string
func save_replay_mp(match_data, p1, p2):
save_replay(match_data, generate_mp_replay_name(p1, p2), true)
func save_replay(match_data: Dictionary, file_name="", autosave=false):
if file_name == "":
file_name = generate_replay_name()
file_name = Utils.filter_filename(file_name)
var data = match_data.duplicate(true)
data["frames"] = frames
data["version"] = Global.VERSION
var dir = Directory.new()
if !dir.dir_exists("user://replay"):
dir.make_dir("user://replay")
if !dir.dir_exists("user://replay/autosave"):
dir.make_dir("user://replay/autosave")
var file = File.new()
# OS.shell_open(str("file://", "user://"))
print(file_name)
file.open("user://replay/"+("autosave/" if autosave else "")+file_name+".replay", File.WRITE)
file.store_var(data, true)
file.close()
return file_name + ".replay"
func load_replays(autosave=true):
var dir = Directory.new()
var files = []
var _directories = []
if !dir.dir_exists("user://replay"):
dir.make_dir("user://replay")
if !dir.dir_exists("user://replay/autosave"):
dir.make_dir("user://replay/autosave")
dir.open("user://replay")
dir.list_dir_begin(false, true)
# print(dir.get_current_dir())
Global.add_dir_contents(dir, files, _directories, autosave)
var replay_paths = {}
for path in files:
var replay_file = File.new()
# replay_file.open(path, File.READ)
# var match_data = replay_file.get_var()
var modified = replay_file.get_modified_time(path)
var data = {
"path": path,
"modified": modified,
# "version": match_data.version if match_data.has("version") else null
}
if ".replay" in path:
replay_paths[path.get_file().get_basename()] = data
replay_file.close()
return replay_paths
func load_replay(path):
var file = File.new()
file.open(path, File.READ)
var data: Dictionary = file.get_var()
frames = data.frames
var match_data = data.duplicate(true)
match_data.erase("frames")
return match_data
func force_ints(dict):
for key in dict:
if dict[key] is float:
dict[key] = int(dict[key])
if dict[key] is Dictionary:
force_ints(dict[key])